| % Regression tests for Scapy |
| |
| # More information at http://www.secdev.org/projects/UTscapy/ |
| |
| ############ |
| ############ |
| + Information on Scapy |
| |
| = Setup |
| def expect_exception(e, c): |
| try: |
| c() |
| return False |
| except e: |
| return True |
| |
| = Get conf |
| ~ conf command |
| * Dump the current configuration |
| conf |
| |
| IP().src |
| conf.loopback_name |
| |
| = Test module version detection |
| ~ conf |
| |
| class FakeModule(object): |
| __version__ = "v1.12" |
| |
| class FakeModule2(object): |
| __version__ = "5.143.3.12" |
| |
| class FakeModule3(object): |
| __version__ = "v2.4.2.dev42" |
| |
| 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)) |
| |
| assert _version_checker(FakeModule3, (2, 4, 2)) |
| |
| = 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() |
| |
| = Test automatic doc generation |
| ~ command |
| |
| dat = rfc(IP, ret=True).split("\n") |
| assert dat[0].replace(" ", "").strip() == "0123" |
| assert "0123456789" in dat[1].replace(" ", "") |
| for l in dat: |
| # only upper case and +- |
| assert re.match(r"[A-Z+-]*", l) |
| |
| # Add a space before each + to avoid conflicts with UTscapy ! |
| # They will be stripped below |
| result = """ |
| 0 1 2 3 |
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| |VERSION| IHL | TOS | LEN | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | ID |FLAGS| FRAG | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | TTL | PROTO | CHKSUM | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | SRC | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | DST | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | OPTIONS | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| |
| Fig. IP |
| """.strip() |
| result = [x.strip() for x in result.split("\n")] |
| output = [x.strip() for x in rfc(IP, ret=True).strip().split("\n")] |
| assert result == output |
| |
| = Check that all contrib modules are well-configured |
| ~ command |
| list_contrib(_debug=True) |
| |
| = Configuration |
| ~ conf |
| conf.debug_dissector = True |
| |
| = Configuration conf.use_* LINUX |
| ~ linux |
| |
| try: |
| conf.use_bpf = True |
| assert False |
| except: |
| True |
| |
| assert not conf.use_bpf |
| |
| if not conf.use_pcap: |
| a = six.moves.builtins.__dict__ |
| conf.interactive = True |
| conf.use_pcap = True |
| assert a["get_if_list"] == scapy.arch.pcapdnet.get_if_list |
| conf.use_pcap = False |
| assert a["get_if_list"] == scapy.arch.linux.get_if_list |
| conf.interactive = False |
| |
| = Configuration conf.use_* WINDOWS |
| ~ windows |
| |
| try: |
| conf.use_bpf = True |
| assert False |
| except: |
| True |
| |
| assert not conf.use_bpf |
| |
| = Test layer filtering |
| ~ filter |
| |
| pkt = NetflowHeader()/NetflowHeaderV5()/NetflowRecordV5() |
| |
| conf.layers.filter([NetflowHeader, NetflowHeaderV5]) |
| assert NetflowRecordV5 not in NetflowHeader(bytes(pkt)) |
| |
| conf.layers.unfilter() |
| assert NetflowRecordV5 in NetflowHeader(bytes(pkt)) |
| |
| |
| ########### |
| ########### |
| = 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 |
| data["ipv4_metric"] = 1 |
| data["ipv6_metric"] = 1 |
| data["mac"] = "00:00:00:00:00:00" |
| data["ips"] = ["127.0.0.1", "::1"] |
| data["pcap_name"] = "\\Device\\NPF_" + data["guid"] |
| data["flags"] = 0 |
| return NetworkInterface(data) |
| else: |
| return "dummy0" |
| |
| get_if_raw_addr(get_dummy_interface()) |
| |
| get_if_list() |
| |
| get_working_if() |
| |
| get_if_raw_addr6(conf.iface) |
| |
| = Test read_routes6() - default output |
| |
| routes6 = read_routes6() |
| if WINDOWS: |
| from scapy.arch.windows import _route_add_loopback |
| _route_add_loopback(routes6, True) |
| |
| routes6 |
| |
| # Expected results: |
| # - one route if there is only the loopback interface |
| # - one route if IPv6 is supported but disabled on network interfaces |
| # - three routes if there is a network interface |
| # - on OpenBSD, only two routes on lo0 are expected |
| |
| if routes6: |
| iflist = get_if_list() |
| if WINDOWS: |
| from scapy.arch.windows import _route_add_loopback |
| _route_add_loopback(ipv6=True, iflist=iflist) |
| if OPENBSD: |
| len(routes6) >= 2 |
| elif iflist == [conf.loopback_name]: |
| len(routes6) == 1 |
| elif len(iflist) >= 2: |
| len(routes6) >= 1 |
| else: |
| False |
| else: |
| # IPv6 seems disabled. Force a route to ::1 |
| conf.route6.routes.append(("::1", 128, "::", conf.loopback_name, ["::1"], 1)) |
| conf.route6.ipv6_ifaces = set([conf.loopback_name]) |
| True |
| |
| = Test read_routes6() - check mandatory routes |
| |
| conf.route6 |
| |
| # Doesn't pass on Travis Bionic XXX |
| if len(routes6) > 2 and not WINDOWS: |
| assert(sum(1 for r in routes6 if r[0] == "::1" and r[4] == ["::1"]) >= 1) |
| if not OPENBSD and len(iflist) >= 2: |
| assert sum(1 for r in routes6 if r[0] == "fe80::" and r[1] == 64) >= 1 |
| try: |
| assert sum(1 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") == (conf.loopback_name, "::", "::") |
| assert sum(1 for r in routes6 if r[1] == 128 and r[4] == ["::1"]) >= 1 |
| else: |
| True |
| |
| = Test ifchange() |
| conf.route6.ifchange(conf.loopback_name, "::1/128") |
| if WINDOWS: |
| conf.netcache.in6_neighbor["::1"] = "ff:ff:ff:ff:ff:ff" # Restore fake cache |
| |
| True |
| |
| = Packet.route() |
| assert (Ether() / ARP()).route()[0] is not None |
| assert (Ether() / ARP()).payload.route()[0] is not None |
| assert (ARP(ptype=0, pdst="hello. this isn't a valid IP")).route()[0] is None |
| |
| |
| = plain_str test |
| |
| data = b"\xffsweet\xef celestia\xab" |
| if not six.PY2: |
| # Only Python 3 has to deal with Str/Bytes conversion, |
| # as we don't use Python 2's unicode |
| if sys.version_info[0:2] <= (3, 4): |
| # Python3.4 can only ignore unknown special characters |
| assert plain_str(data) == "sweet celestia" |
| else: |
| # Python >3.4 can replace them with a backslash representation |
| assert plain_str(data) == "\\xffsweet\\xef celestia\\xab" |
| else: |
| assert plain_str(data) == "\xffsweet\xef celestia\xab" |
| |
| ############ |
| ############ |
| + compat.py |
| |
| = test bytes_hex/hex_bytes |
| |
| monty_data = b"Stop! Who approaches the Bridge of Death must answer me these questions three, 'ere the other side he see." |
| hex_data = bytes_hex(monty_data) |
| assert hex_data == b'53746f70212057686f20617070726f61636865732074686520427269646765206f66204465617468206d75737420616e73776572206d65207468657365207175657374696f6e732074687265652c202765726520746865206f746865722073696465206865207365652e' |
| assert hex_bytes(hex_data) == monty_data |
| |
| = test gzip_decompress/gzip_compress |
| |
| from scapy.compat import gzip_compress, gzip_decompress |
| |
| gziped_data = b"\x1f\x8b\x08\x00N\xf5\xd7\\\x02\xff\x1d\x8b9\x0e\x800\x0c\x04\xbf\xb2T4\x88G ~@A\x1d\x91\x85\xa4H\x1cl#\xbe\xcf\xd1\xac4\x9a\xd9\xc5\xa5uX\x93 \xb4\xa6\x12\xb6D\x83'b\xd2\x1c\x0fBv\xcc\x0c\x9eP.s\x84j7\x15\x85_b\xc4y\xd1<K\xfd.J\x0e\xe8\xa9\xbf\x83\xbc\xa3\xb0\x1c\x89\x97\x8c\x1c\x1fc\xbeS\\j\x00\x00\x00" |
| assert gzip_decompress(gziped_data) == monty_data |
| |
| data = b"sweet celestia" |
| assert gzip_decompress(gzip_compress(data)) == data |
| |
| = orb/chb |
| |
| assert orb(b"\x01"[0]) == 1 |
| assert chb(1) == b"\x01" |
| |
| ############ |
| ############ |
| + 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") |
| finally: |
| sys.ps1 = ">>> " |
| |
| interact_emulator() # Default |
| |
| try: |
| interact_emulator(extra_args=["-?"]) # Failing |
| assert False |
| except: |
| pass |
| |
| interact_emulator(extra_args=["-d"]) # Extended |
| |
| = Test explore() with GUI mode |
| ~ command |
| |
| import mock |
| |
| def test_explore_gui(is_layer, layer): |
| prompt_toolkit_mocked_module = Bunch( |
| shortcuts=Bunch( |
| dialogs=Bunch( |
| radiolist_dialog=(lambda *args, **kargs: layer), |
| button_dialog=(lambda *args, **kargs: "layers" if is_layer else "contribs") |
| ) |
| ), |
| 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 |
| |
| conf.interactive = True |
| 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 load_contrib failure |
| try: |
| load_contrib("doesnotexist") |
| assert False |
| except: |
| pass |
| |
| = 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 strand function |
| assert strand("AC", "BC") == b'@C' |
| |
| = 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 |
| ~ netaccess |
| |
| 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")) |
| |
| assert conf.manufdb.lookup("00:00:0F:01:02:03") == ('Next', 'Next, Inc.') |
| assert "00:00:0F" in conf.manufdb.reverse_lookup("Next") |
| |
| = Test multiple wireshark's manuf formats |
| ~ manufdb |
| |
| new_format = """ |
| # comment |
| 00:00:00 JokyIsland Joky Insland Corp SA |
| 00:01:12 SecdevCorp Secdev Corporation SA LLC |
| EE:05:01 Scapy Scapy CO LTD & CIE |
| FF:00:11 NoName |
| """ |
| old_format = """ |
| # comment |
| 00:00:00 JokyIsland # Joky Insland Corp SA |
| 00:01:12 SecdevCorp # Secdev Corporation SA LLC |
| EE:05:01 Scapy # Scapy CO LTD & CIE |
| FF:00:11 NoName |
| """ |
| |
| manuf1 = get_temp_file() |
| manuf2 = get_temp_file() |
| |
| with open(manuf1, "w") as w: |
| w.write(old_format) |
| |
| with open(manuf2, "w") as w: |
| w.write(new_format) |
| |
| a = load_manuf(manuf1) |
| b = load_manuf(manuf2) |
| |
| a.lookup("00:00:00") == ('JokyIsland', 'Joky Insland Corp SA'), |
| a.lookup("FF:00:11:00:00:00") == ('NoName', 'NoName') |
| a.reverse_lookup("Scapy") == {'EE:05:01': ('Scapy', 'Scapy CO LTD & CIE')} |
| a.reverse_lookup("Secdevcorp") == {'00:01:12': ('SecdevCorp', 'Secdev Corporation SA LLC')} |
| |
| |
| b.lookup("00:00:00") == ('JokyIsland', 'Joky Insland Corp SA'), |
| b.lookup("FF:00:11:00:00:00") == ('NoName', 'NoName') |
| b.reverse_lookup("Scapy") == {'EE:05:01': ('Scapy', 'Scapy CO LTD & CIE')} |
| b.reverse_lookup("Secdevcorp") == {'00:01:12': ('SecdevCorp', 'Secdev Corporation SA LLC')} |
| |
| scapy_delete_temp_files() |
| |
| = Test load_services |
| |
| data_services = """ |
| cvsup 5999/udp # CVSup |
| x11 6000-6063/tcp # X Window System |
| x11 6000-6063/udp # X Window System |
| ndl-ahp-svc 6064/tcp # NDL-AHP-SVC |
| """ |
| |
| services = get_temp_file() |
| with open(services, "w") as w: |
| w.write(data_services) |
| |
| tcp, udp = load_services(services) |
| assert tcp[6002] == "x11" |
| assert tcp.ndl_ahp_svc == 6064 |
| assert tcp.x11 in range(6000, 6093) |
| assert udp[6002] == "x11" |
| assert udp.x11 in range(6000, 6093) |
| assert udp.cvsup == 5999 |
| |
| scapy_delete_temp_files() |
| |
| = Test ARPingResult output |
| ~ manufdb |
| |
| ar = ARPingResult([(None, Ether(src='70:ee:50:50:ee:70')/ARP(psrc='192.168.0.1'))]) |
| with ContextManagerCaptureOutput() as cmco: |
| ar.show() |
| result_ar = cmco.get_output() |
| |
| assert result_ar.startswith(" 70:ee:50:50:ee:70 Netatmo 192.168.0.1") |
| |
| = 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>>>> </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')) |
| |
| ret = autorun_get_text_interactive_session("scapy_undefined") |
| assert "NameError" in ret[0] |
| |
| = 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 config file functions failures |
| |
| from scapy.main import _probe_config_file |
| assert _probe_config_file("filethatdoesnotexistnorwillever.tsppajfsrdrr") is None |
| |
| = Test CacheInstance repr |
| |
| conf.netcache |
| |
| = Test pyx detection functions |
| |
| from scapy.extlib import _test_pyx |
| assert _test_pyx() == False |
| |
| = Test matplotlib detection functions |
| |
| from mock import MagicMock, patch |
| |
| bck_scapy_ext_lib = sys.modules.get("scapy.extlib", None) |
| del(sys.modules["scapy.extlib"]) |
| |
| mock_matplotlib = MagicMock() |
| mock_matplotlib.get_backend.return_value = "inline" |
| mock_matplotlib.pyplot = MagicMock() |
| mock_matplotlib.pyplot.plt = None |
| with patch.dict("sys.modules", **{ "matplotlib": mock_matplotlib, "matplotlib.lines": mock_matplotlib}): |
| from scapy.extlib import MATPLOTLIB, MATPLOTLIB_INLINED, MATPLOTLIB_DEFAULT_PLOT_KARGS, Line2D |
| assert MATPLOTLIB == 1 |
| assert MATPLOTLIB_INLINED == 1 |
| assert "marker" in MATPLOTLIB_DEFAULT_PLOT_KARGS |
| |
| mock_matplotlib.get_backend.return_value = "ko" |
| with patch.dict("sys.modules", **{ "matplotlib": mock_matplotlib, "matplotlib.lines": mock_matplotlib}): |
| from scapy.extlib import MATPLOTLIB, MATPLOTLIB_INLINED, MATPLOTLIB_DEFAULT_PLOT_KARGS |
| assert MATPLOTLIB == 1 |
| assert MATPLOTLIB_INLINED == 0 |
| assert "marker" in MATPLOTLIB_DEFAULT_PLOT_KARGS |
| |
| if bck_scapy_ext_lib: |
| sys.modules["scapy.extlib"] = bck_scapy_ext_lib |
| |
| |
| ############ |
| ############ |
| + 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 |
| |
| r = fuzz(IP(tos=2)/ICMP()) |
| assert r.tos == 2 |
| z = r.ttl |
| assert r.ttl != z |
| assert r.ttl != z |
| |
| |
| = fuzz a Packet with MultipleTypeField |
| |
| fuzz(ARP(pdst="127.0.0.1")) |
| fuzz(IP()/ARP(pdst='10.0.0.254')) |
| |
| = 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 conditional 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 |
| |
| = answers - Net |
| ~ netaccess |
| |
| 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) |
| |
| = conf.checkIPsrc |
| |
| conf_checkIPsrc = conf.checkIPsrc |
| conf.checkIPsrc = 0 |
| query = IP(id=42676, src='10.128.0.7', dst='192.168.0.1')/ICMP(id=26) |
| answer = IP(src='192.168.48.19', dst='10.128.0.7')/ICMP(type=11)/IPerror(id=42676, src='192.168.51.23', dst='192.168.0.1')/ICMPerror(id=26) |
| assert answer.answers(query) |
| conf.checkIPsrc = conf_checkIPsrc |
| |
| |
| ############ |
| ############ |
| + 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 |
| |
| = Dot11FCS parent matching |
| |
| pkt = Ether()/IP()/Dot11FCS() |
| assert pkt[Dot11] |
| |
| = Dot11FCS - test FCS with FCSField |
| |
| data = b'\x00\x00 \x00\xae@\x00\xa0 \x08\x00\xa0 \x08\x00\x00\x10\x02\x85\t\xa0\x00\xe2\x00d\x00\x00\x00\x00\x00\x00\x01\xa0@:\x01\x00\xc0\xca\xa4}PLfA\xac\xe4\xb3\x00\xc0\xca\xa4}P\x00\x03\x00 \x08 \x00\x00\x00\x00\x0f)\x1d\xd4\xd49\x1f>4\xeb' |
| pkt = RadioTap(data) |
| w_payload = hex_bytes('00002000ae4000a0200800a02008000010028509a000e2006400000000000001a0403a0100c0caa47d504c6641ace4b300c0caa47d50000300200820000000000f291dd4d4391f3e34eb') |
| assert raw(pkt) == w_payload |
| |
| = Dot11FCS computation |
| |
| pkt = RadioTap() / Dot11FCS() / Dot11Beacon() |
| assert raw(pkt) == b'\x00\x00\t\x00\x02\x00\x00\x00\x10\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00e\xd9=\xb9' |
| |
| = WEP tests |
| ~ wifi crypto Dot11 LLC SNAP IP TCP |
| conf.wepkey = "" |
| bck_conf_crypto_valid = conf.crypto_valid |
| p = Dot11WEP(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') |
| assert isinstance(p, Dot11WEP) |
| conf.crypto_valid = bck_conf_crypto_valid |
| |
| 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.ChannelPlusFrequency == 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 MCS dissection |
| data = b"\x00\x00\x0b\x00\x00\x00\x08\x00?,\x05" |
| r = RadioTap(data) |
| r.show() |
| assert r.present.MCS |
| assert r.knownMCS.MCS_bandwidth |
| assert r.knownMCS.MCS_index |
| assert r.knownMCS.guard_interval |
| assert r.knownMCS.HT_format |
| assert r.knownMCS.FEC_type |
| assert r.knownMCS.STBC_streams |
| assert not r.knownMCS.Ness |
| assert not r.knownMCS.Ness_MSB |
| assert r.MCS_bandwidth == 0 |
| assert r.guard_interval == 1 |
| assert r.HT_format == 1 |
| assert r.FEC_type == 0 |
| assert r.STBC_streams == 1 |
| assert r.MCS_index == 5 |
| assert r.Ness_LSB == 0 |
| |
| = RadioTap RX/TX Flags dissection |
| data = b'\x00\x00\x0c\x00\x00\xc0\x00\x00\x02\x00\x1f\x00' |
| r = RadioTap(data) |
| r.show() |
| assert r.present.TXFlags |
| assert r.TXFlags.TX_FAIL |
| assert r.TXFlags.CTS |
| assert r.TXFlags.RTS |
| assert r.TXFlags.NOACK |
| assert r.TXFlags.NOSEQ |
| assert r.present.RXFlags |
| assert r.RXFlags.BAD_PLCP |
| |
| = RadioTap, other fields |
| |
| data = b'\x00\x00 \x00\xae@\x00\xa0 \x08\x00\xa0 \x08\x00\x00\x10\x02\x85\t\xa0\x00\xe2\x00d\x00\x00\x00\x00\x00\x00\x01\xa0@:\x01\x00\xc0\xca\xa4}PLfA\xac\xe4\xb3\x00\xc04\xeb\xca\xa4}P\x00 \x08 \x00\x00\x00\x00\x0f)\x1d\xd4\xd49\x00\x03\x1f>' |
| r = RadioTap(data) |
| assert Dot11TKIP in r |
| assert r[Dot11] |
| assert r.dBm_AntSignal == -30 |
| assert r.Lock_Quality == 100 |
| assert r.RXFlags == 0 |
| |
| = 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.TXFlags |
| assert radiotap.present.b18 |
| assert radiotap.present == 163844 |
| assert radiotap.guess_payload_class("") == Dot11 |
| |
| = 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) |
| |
| = PMKIDListPacket - Check computation of nb_pmkids |
| assert PMKIDListPacket(raw(PMKIDListPacket())).nb_pmkids == 0 |
| assert PMKIDListPacket(raw(PMKIDListPacket(pmkid_list=["AZEDFREZSDERFGTY"]))).nb_pmkids == 1 |
| assert PMKIDListPacket(raw(PMKIDListPacket(pmkid_list=["0123456789ABDEFX", "AZEDFREZSDERFGTY"]))).nb_pmkids == 2 |
| |
| = Dot11EltRSN - Check computation of nb_pairwise_cipher_suites and nb_akm_suites |
| assert Dot11EltRSN(raw(Dot11EltRSN())).nb_pairwise_cipher_suites == 1 |
| assert Dot11EltRSN(raw(Dot11EltRSN(pairwise_cipher_suites=[RSNCipherSuite(cipher="TKIP")]))).nb_pairwise_cipher_suites == 1 |
| assert Dot11EltRSN(raw(Dot11EltRSN(pairwise_cipher_suites=[RSNCipherSuite(cipher="TKIP"), RSNCipherSuite(cipher="CCMP")]))).nb_pairwise_cipher_suites == 2 |
| assert Dot11EltRSN(raw(Dot11EltRSN())).nb_akm_suites == 1 |
| assert Dot11EltRSN(raw(Dot11EltRSN(akm_suites=[AKMSuite(suite="PSK")]))).nb_akm_suites == 1 |
| assert Dot11EltRSN(raw(Dot11EltRSN(akm_suites=[AKMSuite(suite="PSK"), AKMSuite(suite="802.1X")]))).nb_akm_suites == 2 |
| |
| = Dot11EltMicrosoftWPA - Check computation of nb_pairwise_cipher_suites and nb_akm_suites |
| assert Dot11EltMicrosoftWPA(raw(Dot11EltMicrosoftWPA())).nb_pairwise_cipher_suites == 1 |
| assert Dot11EltMicrosoftWPA(raw(Dot11EltMicrosoftWPA(pairwise_cipher_suites=[RSNCipherSuite(cipher="TKIP")]))).nb_pairwise_cipher_suites == 1 |
| assert Dot11EltMicrosoftWPA(raw(Dot11EltMicrosoftWPA(pairwise_cipher_suites=[RSNCipherSuite(cipher="TKIP"), RSNCipherSuite(cipher="CCMP")]))).nb_pairwise_cipher_suites == 2 |
| assert Dot11EltMicrosoftWPA(raw(Dot11EltMicrosoftWPA())).nb_akm_suites == 1 |
| assert Dot11EltMicrosoftWPA(raw(Dot11EltMicrosoftWPA(akm_suites=[AKMSuite(suite="PSK")]))).nb_akm_suites == 1 |
| assert Dot11EltMicrosoftWPA(raw(Dot11EltMicrosoftWPA(akm_suites=[AKMSuite(suite="PSK"), AKMSuite(suite="802.1X")]))).nb_akm_suites == 2 |
| |
| ############ |
| ############ |
| + 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 |
| |
| = Basic SNMPvarbind build |
| ~ SNMP ASN1 |
| x = SNMPvarbind(oid=ASN1_OID("1.3.6.1.2.1.1.4.0"), value=RandBin()) |
| x = SNMPvarbind(raw(x)) |
| assert isinstance(x.value, ASN1_STRING) |
| |
| = Failing SNMPvarbind dissection |
| ~ SNMP ASN1 |
| try: |
| SNMP('0a\x02\x01\x00\x04\x06public\xa3T\x02\x02D\xd0\x02\x01\x00\x02\x01\x000H0F\x06\x08+\x06\x01\x02\x01\x01\x05\x00\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D\x00\x03\x01\x02D') |
| assert False |
| except BER_Decoding_Error: |
| pass |
| |
| = 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 |
| a = RandASN1Object() |
| random.seed(0x2807) |
| o = bytes(a) |
| o |
| assert o in [ |
| b'\x02\x02\xfe\x92', |
| b'A\x02\x07q', |
| b'\x15\x10E55WW2a7yrh9XEck', |
| b'C\x02\xfe\x92', |
| b'\x1e\x023V' |
| ] |
| |
| = ASN1 - ASN1_BIT_STRING |
| a = ASN1_BIT_STRING("test", readable=True) |
| a |
| assert a.val == '01110100011001010111001101110100' |
| assert raw(a) == b'\x03\x05\x00test' |
| |
| a = ASN1_BIT_STRING(b"\xff"*16, readable=True) |
| a |
| assert a.val == "1" * 128 |
| assert raw(a) == b'\x03\x11\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' |
| |
| = 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) in ["<ASN1_DECODING_ERROR['error']{{<ASN1_BIT_STRING[0]=b'\\x00' (7 unused bits)>}}>", |
| "<ASN1_DECODING_ERROR['error']{{<ASN1_BIT_STRING[0]=\x00 (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()) |
| |
| = SSID is parsed properly even with the presence of RSN Information |
| ~ SSID RSN Information |
| # A regression test for https://github.com/secdev/scapy/pull/2685. |
| # https://github.com/secdev/scapy/issues/2683 describes a packet with |
| # RSN Information that isn't parsed properly, |
| # causing the SSID to be overridden. |
| # This test checks the SSID is parsed properly. |
| print(os.path.dirname(__file__)) |
| filename = os.path.abspath( |
| os.path.join( |
| os.path.dirname(__file__), |
| "..", |
| "test", |
| "pcaps", |
| "bad_rsn_parsing_overrides_ssid.pcap" |
| )) |
| frame = rdpcap(filename)[0] |
| beacon = frame.getlayer(5) |
| ssid = beacon.network_stats()['ssid'] |
| assert ssid == "ROUTE-821E295" |
| |
| |
| ############ |
| ############ |
| + Network tests |
| |
| * Those tests need network access |
| |
| = 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) |
| |
| p = Ether()/IP(dst="8.8.8.8")/ICMP() |
| from decimal import Decimal |
| p.time = Decimal(p.time) |
| tmp = sendp(p, return_packets=True, realtime=True) |
| assert(len(tmp) == 1) |
| |
| retry_test(_test) |
| |
| = Latency check: localhost ICMP |
| ~ netaccess linux latency |
| |
| sock = conf.L3socket |
| conf.L3socket = L3RawSocket |
| |
| def _test(): |
| req = IP(dst="127.0.0.1")/ICMP() |
| ans = sr1(req) |
| assert (ans.time - req.sent_time) >= 0 |
| assert (ans.time - req.sent_time) <= 1e-3 |
| |
| retry_test(_test) |
| |
| conf.L3socket = sock |
| |
| = 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 as_resolvers |
| * 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) |
| |
| riswhois_data = b"route: 8.8.8.0/24\ndescr: Google\norigin: AS15169\nnotify: radb-contact@google.com\nmnt-by: MAINT-AS15169\nchanged: radb-contact@google.com 20150728\nsource: RADB\n\nroute: 8.0.0.0/9\ndescr: Proxy-registered route object\norigin: AS3356\nremarks: auto-generated route object\nremarks: this next line gives the robot something to recognize\nremarks: L'enfer, c'est les autres\nremarks: \nremarks: This route object is for a Level 3 customer route\nremarks: which is being exported under this origin AS.\nremarks: \nremarks: This route object was created because no existing\nremarks: route object with the same origin was found, and\nremarks: since some Level 3 peers filter based on these objects\nremarks: this route may be rejected if this object is not created.\nremarks: \nremarks: Please contact routing@Level3.net if you have any\nremarks: questions regarding this object.\nmnt-by: LEVEL3-MNT\nchanged: roy@Level3.net 20060203\nsource: LEVEL3\n\n\n" |
| |
| ret = AS_resolver_riswhois()._parse_whois(riswhois_data) |
| assert ret == ('AS15169', 'Google') |
| |
| 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) |
| |
| = AS resolver - socket error |
| ~ IP |
| * This test checks that a failing resolver will not crash a script |
| |
| class MockAS_resolver(object): |
| def resolve(self, *ips): |
| raise socket.error |
| |
| asrm = AS_resolver_multi(MockAS_resolver()) |
| assert len(asrm.resolve(["8.8.8.8", "8.8.4.4"])) == 0 |
| |
| = sendpfast |
| |
| old_interactive = conf.interactive |
| conf.interactive = False |
| try: |
| sendpfast([]) |
| assert False |
| except Exception: |
| assert True |
| |
| conf.interactive = old_interactive |
| assert True |
| |
| ############ |
| ############ |
| + Generator 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 |
| |
| = Implicit logic 3 |
| |
| # In case there's a single option: __iter__ should return self |
| a = Ether()/IP(src="127.0.0.1", dst="127.0.0.1")/ICMP() |
| for i in a: |
| i.sent_time = 1 |
| |
| assert a.sent_time == 1 |
| |
| # In case they are several, self should never be returned |
| a = Ether()/IP(src="127.0.0.1", dst="127.0.0.1")/ICMP(seq=(0, 5)) |
| for i in a: |
| i.sent_time = 1 |
| |
| assert a.sent_time is None |
| |
| |
| ############ |
| ############ |
| + 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 debug_match |
| ~ netaccess IP ICMP |
| def _test(): |
| old_debug_match = conf.debug_match |
| conf.debug_match = True |
| old_debug_dissector = conf.debug_dissector |
| conf.debug_dissector = False |
| ans, unans = sr(IP(dst="www.google.fr") / ICMP(), timeout=2) |
| conf.debug_match = old_debug_match |
| conf.debug_dissector = old_debug_dissector |
| assert ans and not unans |
| |
| 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 multi |
| ~ 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, multi=1) |
| conf.debug_dissector = old_debug_dissector |
| len(ans) == 1 and len(unans) == 1 |
| |
| retry_test(_test) |
| |
| = Traceroute function |
| ~ netaccess tcpdump |
| * Let's test traceroute |
| ans, unans = traceroute("www.slashdot.org") |
| 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 tcpdump |
| * 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 tcpdump |
| 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 SuperSocket.select |
| ~ select |
| |
| import mock |
| |
| @mock.patch("scapy.supersocket.select") |
| def _test_select(select): |
| def f(a, b, c, d): |
| raise IOError(0) |
| select.side_effect = f |
| try: |
| SuperSocket.select([]) |
| return False |
| except: |
| return True |
| |
| assert _test_select() |
| |
| = 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") |
| |
| = Automaton graph |
| ~ automaton |
| |
| class HelloWorld(Automaton): |
| @ATMT.state(initial=1) |
| def BEGIN(self): |
| pass |
| @ATMT.condition(BEGIN) |
| def wait_for_nothing(self): |
| raise self.END() |
| @ATMT.action(wait_for_nothing) |
| def on_nothing(self): |
| pass |
| @ATMT.state(final=1) |
| def END(self): |
| pass |
| |
| graph = HelloWorld.build_graph() |
| assert graph.startswith("digraph") |
| assert '"BEGIN" -> "END"' in graph |
| |
| = TCP_client automaton |
| ~ automaton netaccess needs_root |
| * This test retries on failure because it may fail quite easily |
| |
| # This test doesn't pass on Travis BSD, and will be skipped |
| |
| SECDEV_IP4 = "203.178.141.194" |
| |
| if LINUX: |
| import os |
| IPTABLE_RULE = "iptables -%c INPUT -s %s -p tcp --sport 80 -j DROP" |
| # Drop packets from SECDEV_IP4 |
| assert(os.system(IPTABLE_RULE % ('A', SECDEV_IP4)) == 0) |
| |
| load_layer("http") |
| |
| def _tcp_client_test(): |
| req = HTTP()/HTTPRequest( |
| Accept_Encoding=b'gzip, deflate', |
| Cache_Control=b'no-cache', |
| Pragma=b'no-cache', |
| Connection=b'keep-alive', |
| Host=b'www.kame.net', |
| ) |
| t = TCP_client.tcplink(HTTP, SECDEV_IP4, 80) |
| response = t.sr1(req, timeout=3) |
| t.close() |
| assert response.Http_Version == b'HTTP/1.1' |
| assert response.Status_Code == b'200' |
| assert response.Reason_Phrase == b'OK' |
| |
| def _http_request_test(): |
| response = http_request("www.kame.net", path="/", iptables=LINUX) |
| assert response.Http_Version == b'HTTP/1.1' |
| assert response.Status_Code == b'200' |
| assert response.Reason_Phrase == b'OK' |
| |
| # This test doesn't pass on Travis BSD |
| if not BSD: |
| try: |
| retry_test(_tcp_client_test) |
| finally: |
| if LINUX: |
| # Remove the iptables rule |
| assert(os.system(IPTABLE_RULE % ('D', SECDEV_IP4)) == 0) |
| retry_test(_http_request_test) |
| |
| ############ |
| ############ |
| + 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 |
| |
| = PPPoE |
| ~ ppp pppoe |
| p=Ether(b'\xff\xff\xff\xff\xff\xff\x08\x00\x27\xf3<5\x88c\x11\x09\x00\x00\x00\x0c\x01\x01\x00\x00\x01\x03\x00\x04\x01\x02\x03\x04\x00\x00\x00\x00') |
| p |
| assert(p[Ether].type==0x8863) |
| assert(PPPoED in p) |
| assert(p[PPPoED].version==1) |
| assert(p[PPPoED].type==1) |
| assert(p[PPPoED].code==0x09) |
| assert(PPPoED_Tags in p) |
| q=p[PPPoED_Tags] |
| assert(q.tag_list is not None) |
| r=q.tag_list |
| assert(r[0].tag_type==0x0101) |
| assert(r[1].tag_type==0x0103) |
| assert(r[1].tag_len==4) |
| assert(r[1].tag_value==b'\x01\x02\x03\x04') |
| assert(r[2].tag_type==0x0000) |
| |
| |
| = 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 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(dport=1234, sport=1234)/Raw(load="somedata"))) |
| a.nh == 6 and a.plen == 28 and isinstance(a.payload, TCP) and a.payload.chksum == 0xcc9d 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 |
| |
| = IPv6 ma_addr coverage on hashret |
| IPv6(dst="ff00::1:ff28:9c5a", src="::").hashret() == b';' |
| |
| ########### 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\x00\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(p[IPv6ExtHdrSegmentRouting].lastentry == 0 and len(p[IPv6ExtHdrSegmentRouting].addresses) == 1 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\x02\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(p[IPv6ExtHdrSegmentRouting].lastentry == 2 and len(p[IPv6ExtHdrSegmentRouting].addresses) == 3 and len(p[IPv6ExtHdrSegmentRouting].tlv_objects) == 0) |
| |
| = IPv6ExtHdrSegmentRouting Class - TLVs list - build & dissect |
| |
| s = raw(IPv6()/IPv6ExtHdrSegmentRouting(tlv_objects=[IPv6ExtHdrSegmentRoutingTLV()])/TCP()) |
| assert(s == b'`\x00\x00\x00\x004+@\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\x03\x04\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\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(p[IPv6ExtHdrSegmentRouting].lastentry == 0) |
| assert(len(p[IPv6ExtHdrSegmentRouting].addresses) == 1 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\x02\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(p[IPv6ExtHdrSegmentRouting].lastentry == 2) |
| 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' \x01\r\xb8\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 - Hashret |
| (IPv6(src="::1", dst="::1")/IPv6ExtHdrHopByHop()).hashret() == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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') |
| assert 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 |
| assert a.hashret() == b":" |
| |
| |
| ############ |
| ############ |
| + 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') |
| assert a.code==0x11 and a.res==3758096385 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_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@\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() |
| |
| random.seed(0x2807) |
| p = IPv6(src="::", dst="::")/ICMPv6NIQueryIPv4(data="freebsd") |
| h = p.hashret() |
| h |
| assert h in [ |
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:g\x02f1\xbd?\xb3\xc4', |
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x88\xccb\x19~\x9e\xe3a', |
| b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:$#\xb5\xb7\xd0\xbf \xe2' |
| ] |
| |
| |
| ############ |
| ############ |
| + 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 |
| |
| = IPv6 - IPv6ExtHdrFragment hashret |
| a=IPv6()/IPv6ExtHdrFragment(b'\xff\xee\xff\xfb\x11\x11\x11\x11') |
| a.hashret() == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff' |
| |
| |
| ############ |
| ############ |
| + 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 |
| |
| = fragment6 - test against a long TCP packet with a 1280 MTU without fragment header |
| l=fragment6(IPv6()/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 packets with L2 header |
| l=defragment6(fragment6(Ether()/IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*2000), 1280)) |
| Ether in l |
| |
| |
| = 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.ipv6_ifaces = set(['lo', 'eth0']) |
| 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, "::", conf.loopback_name, ["::1"], 1)) |
| True |
| |
| = Route6 - Route6.make_route |
| |
| r6 = Route6() |
| r6.make_route("2001:db8::1", dev=conf.loopback_name) in [ |
| ("2001:db8::1", 128, "::", conf.loopback_name, [], 1), |
| ("2001:db8::1", 128, "::", conf.loopback_name, ["::1"], 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 |
| assert _ICMPv6Error().hashret() == b'' |
| |
| = Windows: reset routes properly |
| |
| if WINDOWS: |
| from scapy.arch.windows import _route_add_loopback |
| _route_add_loopback() |
| |
| ############ |
| ############ |
| + 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 answers |
| |
| 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 DUID_UUID |
| |
| = DUID_UUID basic instantiation |
| a=DUID_UUID() |
| |
| = DUID_UUID basic build |
| raw(DUID_UUID()) == b"\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
| |
| = DUID_UUID build with specific values |
| raw(DUID_UUID(uuid="272adcca-138c-4e8d-b3f4-634e953128cf")) == \ |
| b"\x00\x04'*\xdc\xca\x13\x8cN\x8d\xb3\xf4cN\x951(\xcf" |
| |
| = DUID_UUID basic dissection |
| a=DUID_UUID(raw(DUID_UUID())) |
| a.type == 4 and str(a.uuid) == "00000000-0000-0000-0000-000000000000" |
| |
| = DUID_UUID with specific values |
| a=DUID_UUID(b"\x00\x04'*\xdc\xca\x13\x8cN\x8d\xb3\xf4cN\x951(\xcf") |
| a.type == 4 and str(a.uuid) == "272adcca-138c-4e8d-b3f4-634e953128cf" |
| |
| |
| ############ |
| ############ |
| + 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 == [] |
| |
| = 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[0].load == 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) |
| |
| = DHCP6OptIA_NA - Instantiation with a list of different opts: IA Address and Status Code (optlen automatic computation) |
| raw(DHCP6OptIA_NA(iaid=0x22222222, T1=0x33333333, T2=0x44444444, ianaopts=[DHCP6OptIAAddress(), DHCP6OptStatusCode(statuscode=0xff, statusmsg="Hello")])) == b'\x00\x03\x003""""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\r\x00\x07\x00\xffHello' |
| |
| |
| ############ |
| ############ |
| + 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) |
| |
| = DHCP6OptIA_TA - Instantiation with a list of different opts: IA Address and Status Code (optlen automatic computation) |
| raw(DHCP6OptIA_TA(iaid=0x22222222, iataopts=[DHCP6OptIAAddress(), DHCP6OptStatusCode(statuscode=0xff, statusmsg="Hello")])) == b'\x00\x04\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\x00\r\x00\x07\x00\xffHello' |
| |
| |
| ############ |
| ############ |
| + 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' |
| |
| = DHCP6OptIA_PD - Instantiation with a list of different opts: IA Address and Status Code (optlen automatic computation) |
| raw(DHCP6OptIA_PD(iaid=0x22222222, T1=0x33333333, T2=0x44444444, iapdopt=[DHCP6OptIAAddress(), DHCP6OptStatusCode(statuscode=0xff, statusmsg="Hello")])) == b'\x00\x19\x003""""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\r\x00\x07\x00\xffHello' |
| |
| #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\x01\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\x12\x04toto\x07example\x03org\x00' |
| |
| = 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\x01\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\x12\x04toto\x07example\x03org\x00' |
| |
| = DHCP6OptNISPDomain - Dissection with one domain name |
| a = DHCP6OptNISPDomain(b'\x00\x1e\x00\x12\x04toto\x07example\x03org\x00') |
| a.optcode == 30 and a.optlen == 18 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\x02\x00\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\x02\x01\x00" and raw(DHCP6OptClientFQDN(flags="O")) == b"\x00'\x00\x02\x02\x00" and raw(DHCP6OptClientFQDN(flags="N")) == b"\x00'\x00\x02\x04\x00" and raw(DHCP6OptClientFQDN(flags="SON")) == b"\x00'\x00\x02\x07\x00" and raw(DHCP6OptClientFQDN(flags="ON")) == b"\x00'\x00\x02\x06\x00" |
| |
| = DHCP6OptClientFQDN - Instantiation with one fqdn |
| raw(DHCP6OptClientFQDN(fqdn="toto.example.org")) == b"\x00'\x00\x13\x00\x04toto\x07example\x03org\x00" |
| |
| = 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 PANA Auth Agent |
| |
| = DHCP6OptPanaAuthAgent - Basic Instantiation |
| raw(DHCP6OptPanaAuthAgent()) == b'\x00(\x00\x00' |
| |
| = DHCP6OptPanaAuthAgent - Basic Dissection |
| a = DHCP6OptPanaAuthAgent(b"\x00(\x00\x00") |
| a.optcode == 40 and a.optlen == 0 and a.paaaddr == [] |
| |
| = DHCP6OptPanaAuthAgent - Instantiation with specific values (1 address) |
| raw(DHCP6OptPanaAuthAgent(paaaddr=["2001:db8::1"])) == b'\x00(\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' |
| |
| = DHCP6OptPanaAuthAgent - Dissection with specific values (1 address) |
| a = DHCP6OptPanaAuthAgent(b'\x00(\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01') |
| a.optcode == 40 and a.optlen == 16 and len(a.paaaddr) == 1 and a.paaaddr[0] == "2001:db8::1" |
| |
| = DHCP6OptPanaAuthAgent - Instantiation with specific values (2 addresses) |
| raw(DHCP6OptPanaAuthAgent(paaaddr=["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' |
| |
| = DHCP6OptPanaAuthAgent - Dissection with specific values (2 addresses) |
| a = DHCP6OptPanaAuthAgent(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 == 40 and a.optlen == 32 and len(a.paaaddr) == 2 and a.paaaddr[0] == "2001:db8::1" and a.paaaddr[1] == "2001:db8::2" |
| |
| |
| ############ |
| ############ |
| + Test DHCP6 Option - New POSIX Time Zone |
| |
| = DHCP6OptNewPOSIXTimeZone - Basic Instantiation |
| raw(DHCP6OptNewPOSIXTimeZone()) == b'\x00)\x00\x00' |
| |
| = DHCP6OptNewPOSIXTimeZone - Basic Dissection |
| a = DHCP6OptNewPOSIXTimeZone(b'\x00)\x00\x00') |
| a.optcode == 41 and a.optlen == 0 and a.optdata == b"" |
| |
| = DHCP6OptNewPOSIXTimeZone - Instantiation with specific values |
| raw(DHCP6OptNewPOSIXTimeZone(optdata="EST5EDT4,M3.2.0/02:00,M11.1.0/02:00")) == b'\x00)\x00#EST5EDT4,M3.2.0/02:00,M11.1.0/02:00' |
| |
| = DHCP6OptNewPOSIXTimeZone - Dissection with specific values |
| a = DHCP6OptNewPOSIXTimeZone(b'\x00)\x00#EST5EDT4,M3.2.0/02:00,M11.1.0/02:00') |
| a.optcode == 41 and a.optlen == 35 and a.optdata == b"EST5EDT4,M3.2.0/02:00,M11.1.0/02:00" |
| |
| |
| ############ |
| ############ |
| + Test DHCP6 Option - New TZDB Time Zone |
| |
| = DHCP6OptNewTZDBTimeZone - Basic Instantiation |
| raw(DHCP6OptNewTZDBTimeZone()) == b'\x00*\x00\x00' |
| |
| = DHCP6OptNewTZDBTimeZone - Basic Dissection |
| a = DHCP6OptNewTZDBTimeZone(b'\x00*\x00\x00') |
| a.optcode == 42 and a.optlen == 0 and a.optdata == b"" |
| |
| = DHCP6OptNewTZDBTimeZone - Instantiation with specific values |
| raw(DHCP6OptNewTZDBTimeZone(optdata="Europe/Zurich")) == b'\x00*\x00\rEurope/Zurich' |
| |
| = DHCP6OptNewTZDBTimeZone - Dissection with specific values |
| a = DHCP6OptNewTZDBTimeZone(b'\x00*\x00\rEurope/Zurich') |
| a.optcode == 42 and a.optlen == 13 and a.optdata == b"Europe/Zurich" |
| |
| |
| ############ |
| ############ |
| + 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 LQ Client Link |
| |
| = DHCP6OptLQClientLink - Basic Instantiation |
| raw(DHCP6OptLQClientLink()) == b'\x000\x00\x00' |
| |
| = DHCP6OptLQClientLink - Basic Dissection |
| a = DHCP6OptLQClientLink(b"\x000\x00\x00") |
| a.optcode == 48 and a.optlen == 0 and a.linkaddress == [] |
| |
| = DHCP6OptLQClientLink - Instantiation with specific values (1 address) |
| raw(DHCP6OptLQClientLink(linkaddress=["2001:db8::1"])) == b'\x000\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' |
| |
| = DHCP6OptLQClientLink - Dissection with specific values (1 address) |
| a = DHCP6OptLQClientLink(b'\x000\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01') |
| a.optcode == 48 and a.optlen == 16 and len(a.linkaddress) == 1 and a.linkaddress[0] == "2001:db8::1" |
| |
| = DHCP6OptLQClientLink - Instantiation with specific values (2 addresses) |
| raw(DHCP6OptLQClientLink(linkaddress=["2001:db8::1", "2001:db8::2"])) == b'\x000\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' |
| |
| = DHCP6OptLQClientLink - Dissection with specific values (2 addresses) |
| a = DHCP6OptLQClientLink(b'\x000\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 == 48 and a.optlen == 32 and len(a.linkaddress) == 2 and a.linkaddress[0] == "2001:db8::1" and a.linkaddress[1] == "2001:db8::2" |
| |
| ############ |
| ############ |
| + Test DHCP6 Option - Boot File URL |
| |
| = DHCP6OptBootFileUrl - Basic Instantiation |
| raw(DHCP6OptBootFileUrl()) == b'\x00;\x00\x00' |
| |
| = DHCP6OptBootFileUrl - Basic Dissection |
| a = DHCP6OptBootFileUrl(b'\x00;\x00\x00') |
| a.optcode == 59 and a.optlen == 0 and a.optdata == b"" |
| |
| = DHCP6OptBootFileUrl - Instantiation with specific values |
| raw(DHCP6OptBootFileUrl(optdata="http://wp.pl/file")) == b'\x00;\x00\x11http://wp.pl/file' |
| |
| = DHCP6OptBootFileUrl - Dissection with specific values |
| a = DHCP6OptBootFileUrl(b'\x00;\x00\x11http://wp.pl/file') |
| a.optcode == 59 and a.optlen == 17 and a.optdata == b"http://wp.pl/file" |
| |
| |
| ############ |
| ############ |
| + Test DHCP6 Option - Client Arch Type |
| |
| = DHCP6OptClientArchType - Basic Instantiation |
| raw(DHCP6OptClientArchType()) |
| raw(DHCP6OptClientArchType()) == b'\x00=\x00\x00' |
| |
| = DHCP6OptClientArchType - Basic Dissection |
| a = DHCP6OptClientArchType(b'\x00=\x00\x00') |
| a.optcode == 61 and a.optlen == 0 and a.archtypes == [] |
| |
| = DHCP6OptClientArchType - Instantiation with specific value as just int |
| raw(DHCP6OptClientArchType(archtypes=7)) == b'\x00=\x00\x02\x00\x07' |
| |
| = DHCP6OptClientArchType - Instantiation with specific value as single item list of int |
| raw(DHCP6OptClientArchType(archtypes=[7])) == b'\x00=\x00\x02\x00\x07' |
| |
| = DHCP6OptClientArchType - Dissection with specific 1 value list |
| a = DHCP6OptClientArchType(b'\x00=\x00\x02\x00\x07') |
| a.optcode == 61 and a.optlen == 2 and a.archtypes == [7] |
| |
| = DHCP6OptClientArchType - Instantiation with specific value as 2 item list of int |
| raw(DHCP6OptClientArchType(archtypes=[7, 9])) == b'\x00=\x00\x04\x00\x07\x00\x09' |
| |
| = DHCP6OptClientArchType - Dissection with specific 2 values list |
| a = DHCP6OptClientArchType(b'\x00=\x00\x04\x00\x07\x00\x09') |
| a.optcode == 61 and a.optlen == 4 and a.archtypes == [7, 9] |
| |
| |
| ############ |
| ############ |
| + Test DHCP6 Option - Client Network Inter Id |
| |
| = DHCP6OptClientNetworkInterId - Basic Instantiation |
| raw(DHCP6OptClientNetworkInterId()) |
| raw(DHCP6OptClientNetworkInterId()) == b'\x00>\x00\x03\x00\x00\x00' |
| |
| = DHCP6OptClientNetworkInterId - Basic Dissection |
| a = DHCP6OptClientNetworkInterId(b'\x00>\x00\x03\x00\x00\x00') |
| a.optcode == 62 and a.optlen == 3 and a.iitype == 0 and a.iimajor == 0 and a.iiminor == 0 |
| |
| = DHCP6OptClientNetworkInterId - Instantiation with specific values |
| raw(DHCP6OptClientNetworkInterId(iitype=1, iimajor=2, iiminor=3)) == b'\x00>\x00\x03\x01\x02\x03' |
| |
| = DHCP6OptClientNetworkInterId - Dissection with specific values |
| a = DHCP6OptClientNetworkInterId(b'\x00>\x00\x03\x01\x02\x03') |
| a.optcode == 62 and a.optlen == 3 and a.iitype == 1 and a.iimajor == 2 and a.iiminor == 3 |
| |
| |
| ############ |
| ############ |
| + Test DHCP6 Option - ERP Domain |
| |
| = DHCP6OptERPDomain - Basic Instantiation |
| raw(DHCP6OptERPDomain()) == b'\x00A\x00\x00' |
| |
| = DHCP6OptERPDomain - Basic Dissection |
| a = DHCP6OptERPDomain(b'\x00A\x00\x00') |
| a.optcode == 65 and a.optlen == 0 and a.erpdomain == [] |
| |
| = DHCP6OptERPDomain - Instantiation with specific values (1 domain) |
| raw(DHCP6OptERPDomain(erpdomain=["toto.example.com."])) == b'\x00A\x00\x12\x04toto\x07example\x03com\x00' |
| |
| = DHCP6OptERPDomain - Dissection with specific values (1 domain) |
| a = DHCP6OptERPDomain(b'\x00A\x00\x12\x04toto\x07example\x03com\x00') |
| a.optcode == 65 and a.optlen == 18 and len(a.erpdomain) == 1 and a.erpdomain[0] == "toto.example.com." |
| |
| = DHCP6OptERPDomain - Instantiation with specific values (2 domains) |
| raw(DHCP6OptERPDomain(erpdomain=["toto.example.com.", "titi.example.com."])) == b'\x00A\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00' |
| |
| = DHCP6OptERPDomain - Dissection with specific values (2 domains) |
| a = DHCP6OptERPDomain(b'\x00A\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00') |
| a.optcode == 65 and a.optlen == 36 and len(a.erpdomain) == 2 and a.erpdomain[0] == "toto.example.com." and a.erpdomain[1] == "titi.example.com." |
| |
| |
| ############ |
| ############ |
| + Test DHCP6 Option - Relay Supplied Option |
| |
| = DHCP6OptRelaySuppliedOpt - Basic Instantiation |
| raw(DHCP6OptRelaySuppliedOpt()) == b'\x00B\x00\x00' |
| |
| = DHCP6OptRelaySuppliedOpt - Basic Dissection |
| a = DHCP6OptRelaySuppliedOpt(b'\x00B\x00\x00') |
| a.optcode == 66 and a.optlen == 0 and a.relaysupplied == [] |
| |
| = DHCP6OptRelaySuppliedOpt - Instantiation with specific values |
| raw(DHCP6OptRelaySuppliedOpt(relaysupplied=DHCP6OptERPDomain(erpdomain=["toto.example.com."]))) == b'\x00B\x00\x16\x00A\x00\x12\x04toto\x07example\x03com\x00' |
| |
| = DHCP6OptRelaySuppliedOpt - Dissection with specific values |
| a = DHCP6OptRelaySuppliedOpt(b'\x00B\x00\x16\x00A\x00\x12\x04toto\x07example\x03com\x00') |
| a.optcode == 66 and a.optlen == 22 and len(a.relaysupplied) == 1 and isinstance(a.relaysupplied[0], DHCP6OptERPDomain) and a.relaysupplied[0].erpdomain[0] == "toto.example.com." |
| |
| |
| ############ |
| ############ |
| + 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') |
| a.optcode == 13 and a.optlen == 0 and isinstance(a.message, DHCP6) |
| |
| = DHCP6OptRelayMsg - Embedded DHCP6 packet Instantiation |
| raw(DHCP6OptRelayMsg(message=DHCP6_Solicit())) == b'\x00\t\x00\x04\x01\x00\x00\x00' |
| |
| = DHCP6OptRelayMsg - Embedded DHCP6 packet Dissection |
| 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\xa8\xd6\x00\x00\x80\x00\x03\x04@\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 == 0xa8d6 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@@\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 |
| ~ netflow |
| |
| = 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' |
| |
| raw(NetflowHeader()/NetflowHeaderV5()/NetflowRecordV5(dst="192.168.0.1")/NetflowRecordV5(dst="172.16.0.1")) == 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\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\x7f\x00\x00\x01\xac\x10\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 |
| ~ netflow |
| |
| = 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[0] |
| assert NetflowFlowsetV9 in nfv9_fl |
| assert len(nfv9_fl.templates[0].template_fields) == 21 |
| assert nfv9_fl.templates[0].template_fields[1].fieldType == 12 |
| |
| nfv9_ds = a[3] |
| 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[1] |
| 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[4] |
| assert NetflowDataflowsetV9 in nfv9_options_ds |
| assert isinstance(nfv9_options_ds.records[0], NetflowOptionsRecordScopeV9) |
| assert nfv9_options_ds.records[0].IN_BYTES == b'\x01\x00\x00\x00' |
| assert nfv9_options_ds.records[1].SAMPLING_INTERVAL == 12 |
| assert nfv9_options_ds.records[1].SAMPLING_ALGORITHM == 0x2 |
| |
| = 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)) |
| flowset1 = nfv9_defrag[0].getlayer(NetflowFlowsetV9, 1) |
| assert flowset1.templates[0].template_fields[0].fieldType == 8 |
| assert flowset1.templates[0].template_fields[0].fieldLength == 4 |
| assert flowset1.templates[0].template_fields[5].fieldType == 2 |
| assert flowset1.templates[0].template_fields[5].fieldLength == 8 |
| flowset2 = nfv9_defrag[0].getlayer(NetflowFlowsetV9, 2) |
| assert flowset2.templates[0].template_fields[0].fieldType == 27 |
| assert flowset2.templates[0].template_fields[0].fieldLength == 16 |
| assert flowset2.templates[0].template_fields[5].fieldType == 1 |
| assert flowset2.templates[0].template_fields[5].fieldLength == 8 |
| assert nfv9_defrag[0].getlayer(NetflowFlowsetV9, 2) |
| 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" |
| |
| = NetflowV9 - build and dissection |
| ~ netflow |
| |
| header = Ether()/IP()/UDP() |
| netflow_header = NetflowHeader()/NetflowHeaderV9() |
| |
| flowset = NetflowFlowsetV9( |
| templates=[NetflowTemplateV9( |
| template_fields=[ |
| NetflowTemplateFieldV9(fieldType=1, fieldLength=1), # IN_BYTES |
| NetflowTemplateFieldV9(fieldType=2, fieldLength=4), # IN_PKTS |
| NetflowTemplateFieldV9(fieldType=4), # PROTOCOL |
| NetflowTemplateFieldV9(fieldType=8), # IPV4_SRC_ADDR |
| NetflowTemplateFieldV9(fieldType=12), # IPV4_DST_ADDR |
| ], |
| templateID=256, |
| fieldCount=5) |
| ], |
| flowSetID=0 |
| ) |
| recordClass = GetNetflowRecordV9(flowset) |
| dataFS = NetflowDataflowsetV9( |
| templateID=256, |
| records=[ # Some random data. |
| recordClass( |
| IN_BYTES=b"\x12", |
| IN_PKTS=b"\0\0\0\0", |
| PROTOCOL=6, |
| IPV4_SRC_ADDR="192.168.0.10", |
| IPV4_DST_ADDR="192.168.0.11" |
| ), |
| ], |
| ) |
| |
| pkt = netflow_header / flowset / dataFS |
| assert raw(pkt) == b'\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x01\x00\x00\x05\x00\x01\x00\x01\x00\x02\x00\x04\x00\x04\x00\x01\x00\x08\x00\x04\x00\x0c\x00\x04\x01\x00\x00\x14\x12\x00\x00\x00\x00\x06\xc0\xa8\x00\n\xc0\xa8\x00\x0b\x00\x00' |
| |
| pkt = header / netflow_header / flowset / dataFS |
| pkt = netflowv9_defragment(Ether(raw(pkt)))[0] |
| |
| assert NetflowDataflowsetV9 in pkt |
| assert len(pkt[NetflowDataflowsetV9].records) == 1 |
| assert pkt[NetflowDataflowsetV9].records[0].IPV4_DST_ADDR == "192.168.0.11" |
| |
| = NetflowV9 - advanced build |
| ~ netflow |
| |
| atm_time = 1547927349.328283 |
| |
| header = Ether(src="00:00:00:00:00:00", dst="aa:aa:aa:aa:aa:aa")/IP(dst="127.0.0.1", src="127.0.0.1")/UDP()/NetflowHeader()/NetflowHeaderV9(unixSecs=atm_time) |
| flowset = NetflowFlowsetV9(templates=[NetflowTemplateV9(template_fields=[NetflowTemplateFieldV9(fieldType=8, fieldLength=4),NetflowTemplateFieldV9(fieldType=12, fieldLength=4),NetflowTemplateFieldV9(fieldType=5, fieldLength=1),NetflowTemplateFieldV9(fieldType=4, fieldLength=1),NetflowTemplateFieldV9(fieldType=7, fieldLength=2),NetflowTemplateFieldV9(fieldType=11, fieldLength=2),NetflowTemplateFieldV9(fieldType=32, fieldLength=2),NetflowTemplateFieldV9(fieldType=10, fieldLength=4),NetflowTemplateFieldV9(fieldType=16, fieldLength=4),NetflowTemplateFieldV9(fieldType=17, fieldLength=4),NetflowTemplateFieldV9(fieldType=18, fieldLength=4),NetflowTemplateFieldV9(fieldType=14, fieldLength=4),NetflowTemplateFieldV9(fieldType=1, fieldLength=4),NetflowTemplateFieldV9(fieldType=2, fieldLength=4),NetflowTemplateFieldV9(fieldType=22, fieldLength=4),NetflowTemplateFieldV9(fieldType=21, fieldLength=4),NetflowTemplateFieldV9(fieldType=15, fieldLength=4),NetflowTemplateFieldV9(fieldType=9, fieldLength=1),NetflowTemplateFieldV9(fieldType=13, fieldLength=1),NetflowTemplateFieldV9(fieldType=6, fieldLength=1),NetflowTemplateFieldV9(fieldType=60, fieldLength=1)], templateID=424, fieldCount=21)], flowSetID=0, length=92) |
| dataflowset = NetflowDataflowsetV9(records=[NetflowRecordV9(fieldValue=b'\x14\x00\x00\xfd\x1e\x00\x00\xfd\x00\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x03 \x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x02\xfb\x00\x15a|\x00\x00\x07\x0f$\x95x\xed$\x99\x91<\ndg\x01 \x00\x04')], templateID=424) |
| |
| pkt = netflowv9_defragment(list(header/flowset/dataflowset))[0] |
| assert pkt.records[0].IPV4_NEXT_HOP == "10.100.103.1" |
| assert pkt.records[0].OUTPUT_SNMP == b'\x00\x00\x02\xfb' |
| |
| assert raw(pkt) == b'\xaa\xaa\xaa\xaa\xaa\xaa\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00\xcc\x00\x01\x00\x00@\x11|\x1e\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x07\x08\x07\x00\xb8\x86\xe7\x00\t\x00\x02\x00\x00\x00\x00\\C\x7f5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x01\xa8\x00\x15\x00\x08\x00\x04\x00\x0c\x00\x04\x00\x05\x00\x01\x00\x04\x00\x01\x00\x07\x00\x02\x00\x0b\x00\x02\x00 \x00\x02\x00\n\x00\x04\x00\x10\x00\x04\x00\x11\x00\x04\x00\x12\x00\x04\x00\x0e\x00\x04\x00\x01\x00\x04\x00\x02\x00\x04\x00\x16\x00\x04\x00\x15\x00\x04\x00\x0f\x00\x04\x00\t\x00\x01\x00\r\x00\x01\x00\x06\x00\x01\x00<\x00\x01\x01\xa8\x00@\x14\x00\x00\xfd\x1e\x00\x00\xfd\x00\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x03 \x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x02\xfb\x00\x15a|\x00\x00\x07\x0f$\x95x\xed$\x99\x91<\ndg\x01 \x00\x04' |
| |
| = NetflowV9 - padding #GH2257 |
| |
| dat = hex_bytes("fb200807007840a10009000277efe9c450c843f900362202000000000001001801000004000800010000002a00040029000400000101004477ef819077ef81900000003c00000001009300930ac900640ac9033b060009ee0b3500000ac9033b131302000000000000260bdc69aa6480996649a000000000") |
| pkt = UDP(dat) |
| assert pkt[NetflowOptionsFlowsetV9].pad == b"\x00\x00" |
| pkt[NetflowOptionsFlowsetV9].pad = None |
| assert raw(pkt) == dat |
| |
| |
| ############ |
| ############ |
| + Netflow v10 (aka IPFix) |
| ~ netflow |
| |
| = IPFix dissection |
| |
| import os |
| tmp = "/test/pcaps/ipfix.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 = sniff(offline=filename, session=NetflowSession) |
| |
| # Templates |
| pkt1 = a[0] |
| assert NetflowHeaderV10 in pkt1 |
| assert len(pkt1[NetflowFlowsetV9].templates) == 1 |
| assert len(pkt1[NetflowFlowsetV9].templates[0].template_fields) == 23 |
| flds = pkt1[NetflowFlowsetV9].templates[0].template_fields |
| assert (flds[0].fieldType == 8 and flds[0].fieldLength == 4) |
| assert (flds[4].fieldType == 7 and flds[4].fieldLength == 2) |
| |
| # Data |
| pkt2 = a[2] |
| assert NetflowHeaderV10 in pkt2 |
| assert len(pkt2.records) == 1 |
| assert pkt2.records[0].IPV4_SRC_ADDR == "70.1.115.1" |
| assert pkt2.records[0].flowStartMilliseconds == 1480449931519 |
| |
| # Options |
| pkt3 = a[1] |
| assert NetflowOptionsFlowset10 in pkt3 |
| assert pkt3.scope_field_count == 1 |
| assert pkt3.field_count == 3 |
| assert len(pkt3[NetflowOptionsFlowset10].scopes) == 1 |
| assert len(pkt3[NetflowOptionsFlowset10].options) == 2 |
| assert pkt3.scopes[0].scopeFieldType == 5 |
| assert pkt3.scopes[0].scopeFieldlength == 2 |
| assert pkt3[NetflowOptionsFlowset10].options[0].optionFieldType == 36 |
| |
| # Templates with enterprise-specific Information Elements. |
| s=b'\x01\x07\x00\x12\x01\n\x00\x04\x84\x0c\x00\x02\x00\x00\x00\t\x01\n\x00&\x00\x0b\x00\x02\x00\x07\x00\x02\x00\x04\x00\x01\x00\x0c\x00\x04\x00\x08\x00\x04\x00\xea\x00\x02\x01\n\x00\x01\x84\x10\x00\x06\x00\x00\x00\t\x84\x0e\x00\x06\x00\x00\x00\t\x84\x0f\x00\x06\x00\x00\x00\t\x00\x01\x00\x04\x00\x02\x00\x04\x00\xf3\x00\x02\x00\x06\x00\x01\x01\n\x00#' |
| pkt4 = NetflowTemplateV9(s) |
| assert len(pkt4.template_fields) == pkt4.fieldCount |
| assert sum([template.fieldLength for template in pkt4.template_fields]) == 124 |
| |
| = NetflowV10/IPFIX - build |
| |
| netflow_header = NetflowHeader()/NetflowHeaderV10() |
| |
| flowset = NetflowFlowsetV9( |
| templates=[NetflowTemplateV9( |
| template_fields=[ |
| NetflowTemplateFieldV9(fieldType=1, fieldLength=1), # IN_BYTES |
| NetflowTemplateFieldV9(fieldType=2, fieldLength=4), # IN_PKTS |
| NetflowTemplateFieldV9(fieldType=4), # PROTOCOL |
| NetflowTemplateFieldV9(fieldType=8), # IPV4_SRC_ADDR |
| NetflowTemplateFieldV9(fieldType=12), # IPV4_DST_ADDR |
| ], |
| templateID=256, |
| fieldCount=5) |
| ], |
| flowSetID=0 |
| ) |
| recordClass = GetNetflowRecordV9(flowset) |
| dataFS = NetflowDataflowsetV9( |
| templateID=256, |
| records=[ # Some random data. |
| recordClass( |
| IN_BYTES=b"\x12", |
| IN_PKTS=b"\0\0\0\0", |
| PROTOCOL=6, |
| IPV4_SRC_ADDR="192.168.0.10", |
| IPV4_DST_ADDR="192.168.0.11" |
| ), |
| ], |
| ) |
| |
| pkt = netflow_header / flowset / dataFS |
| assert raw(pkt) == b'\x00\n\x00>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x01\x00\x00\x05\x00\x01\x00\x01\x00\x02\x00\x04\x00\x04\x00\x01\x00\x08\x00\x04\x00\x0c\x00\x04\x01\x00\x00\x14\x12\x00\x00\x00\x00\x06\xc0\xa8\x00\n\xc0\xa8\x00\x0b\x00\x00' |
| |
| |
| |
| ############ |
| ############ |
| + 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') |
| pcapngdefaults = BytesIO(base64_bytes(b'Cg0NChwAAABNPCsaAQAAAP//////////HAAAAAEAAAAgAAAAEgEAAP//AAAJAAEACUeZiQAAAAAgAAAAAQAAACAAAAASAQAA//8AAAkAAQAJAAAAAAAAACAAAAABAAAAIAAAABIBAAD//wAACQABAAkAAAAAAAAAIAAAAAEAAAAgAAAAEgEAAP//AAAJAAEACQAAAAAAAAAgAAAABgAAAIQBAAADAAAApO/bFdgJaeBiAQAAYgEAAFVVVVVVVVXV////////IMbr4D7PCABFAAFIlQkAAEAR5JwAAAAA/////wBEAEMBNJDsAQEGAFSpVwIACoAAAAAAAAAAAAAAAAAAAAAAACDG6+A+zwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjglNjNQEB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsOs+bAAAhAEAAAYAAACAAQAAAwAAAKTv2xXIDYznYAEAAGABAABVVVVVVVVV1QEAXn//+iDG6+A+zwgARQABRgGPAAAEEal3qf5wqO////rhbgdsATJi0U5PVElGWSAqIEhUVFAvMS4xDQpIT1NUOiAyMzkuMjU1LjI1NS4yNTA6MTkwMA0KQ0FDSEUtQ09OVFJPTDogbWF4LWFnZT0xODAwDQpMT0NBVElPTjogaHR0cDovLzE2OS4yNTQuMTEyLjE2ODo1NTAwMC9ucmMvZGRkLnhtbA0KTlQ6IHV1aWQ6NEQ0NTQ5MzAtMDIwMC0xMDAwLTgwMDEtMjBDNkVCRTAzRUNGDQpOVFM6IHNzZHA6YWxpdmUNClNFUlZFUjogRnJlZUJTRC84LjAgVVBuUC8xLjAgUGFuYXNvbmljLU1JTC1ETE5BLVNWLzEuMA0KVVNOOiB1dWlkOjRENDU0OTMwLTAyMDAtMTAwMC04MDAxLTIwQzZFQkUwM0VDRg0KDQpcQcvWgAEAAAYAAAC4AQAAAwAAAKTv2xV4Ao3nlQEAAJUBAABVVVVVVVVV1QEAXn//+iDG6+A+zwgARQABewGQAAAEEalBqf5wqO////rhbgdsAWfu+k5PVElGWSAqIEhUVFAvMS4xDQpIT1NUOiAyMzkuMjU1LjI1NS4yNTA6MTkwMA0KQ0FDSEUtQ09OVFJPTDogbWF4LWFnZT0xODAwDQpMT0NBVElPTjogaHR0cDovLzE2OS4yNTQuMTEyLjE2ODo1NTAwMC9ucmMvZGRkLnhtbA0KTlQ6IHVybjpwYW5hc29uaWMtY29tOmRldmljZTpwMDBSZW1vdGVDb250cm9sbGVyOjENCk5UUzogc3NkcDphbGl2ZQ0KU0VSVkVSOiBGcmVlQlNELzguMCBVUG5QLzEuMCBQYW5hc29uaWMtTUlMLURMTkEtU1YvMS4wDQpVU046IHV1aWQ6NEQ0NTQ5MzAtMDIwMC0xMDAwLTgwMDEtMjBDNkVCRTAzRUNGOjp1cm46cGFuYXNvbmljLWNvbTpkZXZpY2U6cDAwUmVtb3RlQ29udHJvbGxlcjoxDQoNCrLVKmoAAAC4AQAABgAAAHgBAAADAAAApO/bFVjbjedXAQAAVwEAAFVVVVVVVVXVAQBef//6IMbr4D7PCABFAAE9AZEAAAQRqX6p/nCo7///+uFuB2wBKaZATk9USUZZICogSFRUUC8xLjENCkhPU1Q6IDIzOS4yNTUuMjU1LjI1MDoxOTAwDQpDQUNIRS1DT05UUk9MOiBtYXgtYWdlPTE4MDANCkxPQ0FUSU9OOiBodHRwOi8vMTY5LjI1NC4xMTIuMTY4OjU1MDAwL25yYy9kZGQueG1sDQpOVDogdXBucDpyb290ZGV2aWNlDQpOVFM6IHNzZHA6YWxpdmUNClNFUlZFUjogRnJlZUJTRC84LjAgVVBuUC8xLjAgUGFuYXNvbmljLU1JTC1ETE5BLVNWLzEuMA0KVVNOOiB1dWlkOjRENDU0OTMwLTAyMDAtMTAwMC04MDAxLTIwQzZFQkUwM0VDRjo6dXBucDpyb290ZGV2aWNlDQoNCjagXoUAeAEAAAYAAAC0AQAAAwAAAKTv2xXYw47nkwEAAJMBAABVVVVVVVVV1QEAXn//+iDG6+A+zwgARQABeQGSAAAEEalBqf5wqO////rhbgdsAWWV4E5PVElGWSAqIEhUVFAvMS4xDQpIT1NUOiAyMzkuMjU1LjI1NS4yNTA6MTkwMA0KQ0FDSEUtQ09OVFJPTDogbWF4LWFnZT0xODAwDQpMT0NBVElPTjogaHR0cDovLzE2OS4yNTQuMTEyLjE2ODo1NTAwMC9ucmMvZGRkLnhtbA0KTlQ6IHVybjpwYW5hc29uaWMtY29tOnNlcnZpY2U6cDAwTmV0d29ya0NvbnRyb2w6MQ0KTlRTOiBzc2RwOmFsaXZlDQpTRVJWRVI6IEZyZWVCU0QvOC4wIFVQblAvMS4wIFBhbmFzb25pYy1NSUwtRExOQS1TVi8xLjANClVTTjogdXVpZDo0RDQ1NDkzMC0wMjAwLTEwMDAtODAwMS0yMEM2RUJFMDNFQ0Y6OnVybjpwYW5hc29uaWMtY29tOnNlcnZpY2U6cDAwTmV0d29ya0NvbnRyb2w6MQ0KDQovXKFrALQBAAAGAAAAqAEAAAMAAACk79sVuJKP54cBAACHAQAAVVVVVVVVVdUBAF5///ogxuvgPs8IAEUAAW0BkwAABBGpTKn+cKjv///64W4HbAFZRNJOT1RJRlkgKiBIVFRQLzEuMQ0KSE9TVDogMjM5LjI1NS4yNTUuMjUwOjE5MDANCkNBQ0hFLUNPTlRST0w6IG1heC1hZ2U9MTgwMA0KTE9DQVRJT046IGh0dHA6Ly8xNjkuMjU0LjExMi4xNjg6NTUwMDAvbnJjL2RkZC54bWwNCk5UOiB1cm46ZGlhbC1tdWx0aXNjcmVlbi1vcmc6c2VydmljZTpkaWFsOjENCk5UUzogc3NkcDphbGl2ZQ0KU0VSVkVSOiBGcmVlQlNELzguMCBVUG5QLzEuMCBQYW5hc29uaWMtTUlMLURMTkEtU1YvMS4wDQpVU046IHV1aWQ6NEQ0NTQ5MzAtMDIwMC0xMDAwLTgwMDEtMjBDNkVCRTAzRUNGOjp1cm46ZGlhbC1tdWx0aXNjcmVlbi1vcmc6c2VydmljZTpkaWFsOjENCg0KLn5A6QCoAQAA')) |
| |
| = Read a pcap file |
| pktpcap = rdpcap(pcapfile) |
| |
| = Read a pcapng file |
| pktpcapng = rdpcap(pcapngfile) |
| assert pktpcapng[0].time == 1454163407.666223 |
| |
| = Read a pcap file with nanosecond precision |
| pktpcapnano = rdpcap(pcapnanofile) |
| assert pktpcapnano[0].time == 1454163407.666223049 |
| |
| = Read a pcapng file with nanosecond precision and default tsresol |
| pktpcapngdefaults = rdpcap(pcapngdefaults) |
| assert pktpcapngdefaults[0].time == 1575115986.114775512 |
| assert Ether in pktpcapngdefaults[0] |
| |
| = 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 [float(p.time) for p in pktpcap] == [float(p.time) for p in pktpcapng] == [float(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 offline sniff() with Packets and tcpdump |
| ~ tcpdump |
| |
| l = sniff(offline=IP()/UDP(sport=(10000, 10001)), filter="udp") |
| assert len(l) == 2 |
| assert(all(UDP in p for p in l)) |
| |
| l = sniff(offline=[p for p in IP()/UDP(sport=(10000, 10001))], filter="udp") |
| assert len(l) == 2 |
| assert(all(UDP in p for p in l)) |
| |
| l = sniff(offline=IP()/UDP(sport=(10000, 10001)), filter="tcp") |
| assert len(l) == 0 |
| |
| = Check offline sniff with lfilter |
| assert len(sniff(offline=[IP()/UDP(), IP()/TCP()], lfilter=lambda x: TCP in x)) == 1 |
| |
| = Check offline sniff() without a tcpdump binary |
| ~ tcpdump |
| import mock |
| |
| conf_prog_tcpdump = conf.prog.tcpdump |
| conf.prog.tcpdump = "tcpdump_fake" |
| |
| def _test_sniff_notcpdump(): |
| try: |
| sniff(offline="fake.pcap", filter="tcp") |
| assert False |
| except: |
| assert True |
| |
| _test_sniff_notcpdump() |
| conf.prog.tcpdump = conf_prog_tcpdump |
| |
| = Check wrpcap(nano=True) |
| fdesc, filename = tempfile.mkstemp() |
| fdesc = os.fdopen(fdesc, "wb") |
| pktpcapnano[0].time += Decimal('1E-9') |
| wrpcap(fdesc, pktpcapnano, nano=True) |
| fdesc.close() |
| pktpcapnanoread = rdpcap(filename) |
| assert pktpcapnanoread[0].time == pktpcapnano[0].time |
| 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 PcapWriter on null write |
| |
| f = BytesIO() |
| w = PcapWriter(f) |
| w.write([]) |
| assert len(f.getvalue()) == 0 |
| |
| # Stop being closed for reals, but we still want to have the header written |
| with mock.patch.object(f, 'close') as cf: |
| w.close() |
| |
| cf.assert_called_once_with() |
| assert len(f.getvalue()) != 0 |
| |
| = Check PcapWriter sets correct linktype after null write |
| |
| f = BytesIO() |
| w = PcapWriter(f) |
| w.write([]) |
| assert len(f.getvalue()) == 0 |
| w.write(Ether()/IP()/ICMP()) |
| assert len(f.getvalue()) != 0 |
| |
| # Stop being closed for reals, but we still want to have the header written |
| with mock.patch.object(f, 'close') as cf: |
| w.close() |
| |
| cf.assert_called_once_with() |
| f.seek(0) or None |
| assert len(f.getvalue()) != 0 |
| |
| r = PcapReader(f) |
| f.seek(0) or None |
| assert r.LLcls is Ether |
| assert r.linktype == DLT_EN10MB |
| |
| l = [ p for p in RawPcapReader(f) ] |
| assert len(l) == 1 |
| |
| = Check tcpdump() |
| ~ tcpdump |
| from io import BytesIO |
| * 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\x00\x01\x00\x00\x000}$]\xff\\\t\x006\x00\x00\x006\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\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\x000}$]\x87i\t\x00*\x00\x00\x00*\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00\x1c\x00\x01\x00\x00@\x11|\xce\x7f\x00\x00\x01\x7f\x00\x00\x01\x005\x005\x00\x08\x01r0}$]\xfbp\t\x00*\x00\x00\x00*\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\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=['-nn']).split(b'\n') |
| print(data) |
| assert b'127.0.0.1.20 > 127.0.0.1.80:' in data[0] |
| assert b'127.0.0.1.53 > 127.0.0.1.53:' in data[1] |
| assert b'127.0.0.1 > 127.0.0.1:' in data[2] |
| |
| * Non existing tcpdump binary |
| |
| import mock |
| |
| conf_prog_tcpdump = conf.prog.tcpdump |
| conf.prog.tcpdump = "tcpdump_fake" |
| |
| def _test_tcpdump_notcpdump(): |
| try: |
| tcpdump(IP()/TCP()) |
| assert False |
| except: |
| assert True |
| |
| _test_tcpdump_notcpdump() |
| conf.prog.tcpdump = conf_prog_tcpdump |
| |
| # Also check with use_tempfile=True (for non-OSX platforms) |
| pcapfile.seek(0) or None |
| tempfile_count = len(conf.temp_files) |
| data = tcpdump(pcapfile, dump=True, args=['-nn'], use_tempfile=True).split(b'\n') |
| print(data) |
| assert b'127.0.0.1.20 > 127.0.0.1.80:' in data[0] |
| assert b'127.0.0.1.53 > 127.0.0.1.53:' in data[1] |
| assert b'127.0.0.1 > 127.0.0.1:' in data[2] |
| # We should have another tempfile tracked. |
| assert len(conf.temp_files) > tempfile_count |
| |
| # Check with a simple packet |
| data = tcpdump([Ether()/IP()/ICMP()], dump=True, args=['-nn']).split(b'\n') |
| print(data) |
| assert b'127.0.0.1 > 127.0.0.1: ICMP' in data[0].upper() |
| |
| = Check tcpdump() command with linktype |
| ~ tcpdump |
| |
| f = BytesIO() |
| pkt = Ether()/IP()/ICMP() |
| |
| with mock.patch('subprocess.Popen', return_value=Bunch( |
| stdin=f, wait=lambda: None)) as popen: |
| # Prevent closing the BytesIO |
| with mock.patch.object(f, 'close'): |
| tcpdump([pkt], linktype="DLT_EN3MB", use_tempfile=False) |
| |
| popen.assert_called_once_with( |
| [conf.prog.tcpdump, '-y', 'EN3MB', '-r', '-'], |
| stdin=subprocess.PIPE, stdout=None, stderr=None) |
| |
| print(bytes_hex(f.getvalue())) |
| assert raw(pkt) in f.getvalue() |
| f.close() |
| del f, pkt |
| |
| = Check tcpdump() command with linktype and args |
| ~ tcpdump |
| |
| f = BytesIO() |
| pkt = Ether()/IP()/ICMP() |
| |
| with mock.patch('subprocess.Popen', return_value=Bunch( |
| stdin=f, wait=lambda: None)) as popen: |
| # Prevent closing the BytesIO |
| with mock.patch.object(f, 'close'): |
| tcpdump([pkt], linktype=scapy.data.DLT_EN10MB, use_tempfile=False) |
| |
| popen.assert_called_once_with( |
| [conf.prog.tcpdump, '-y', 'EN10MB', '-r', '-'], |
| stdin=subprocess.PIPE, stdout=None, stderr=None) |
| |
| print(bytes_hex(f.getvalue())) |
| assert raw(pkt) in f.getvalue() |
| f.close() |
| del f, pkt |
| |
| = Check tcpdump() command rejects non-string input for prog |
| |
| pkt = Ether()/IP()/ICMP() |
| |
| try: |
| tcpdump([pkt], prog=+17607067425, args=['-nn']) |
| except ValueError as e: |
| if hasattr(e, 'args'): |
| assert 'prog' in e.args[0] |
| else: |
| assert 'prog' in e.message |
| else: |
| assert False, 'expected exception' |
| |
| = 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') |
| # tshark doesn't need workarounds on OSX |
| tempfile_count = len(conf.temp_files) |
| 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)] |
| assert len(conf.temp_files) == tempfile_count |
| |
| = Check tdecode command directly for tshark |
| ~ tshark |
| |
| pkts = [ |
| Ether()/IP(src='192.0.2.1', dst='192.0.2.2')/ICMP(type='echo-request')/Raw(b'X'*100), |
| Ether()/IP(src='192.0.2.2', dst='192.0.2.1')/ICMP(type='echo-reply')/Raw(b'X'*100), |
| ] |
| |
| # tshark doesn't need workarounds on OSX |
| tempfile_count = len(conf.temp_files) |
| |
| r = tdecode(pkts, dump=True) |
| r |
| assert b'Src: 192.0.2.1' in r |
| assert b'Src: 192.0.2.2' in r |
| assert b'Dst: 192.0.2.2' in r |
| assert b'Dst: 192.0.2.1' in r |
| assert b'Echo (ping) request' in r |
| assert b'Echo (ping) reply' in r |
| assert b'ICMP' in r |
| assert len(conf.temp_files) == tempfile_count |
| |
| = Check tdecode with linktype |
| ~ tshark |
| |
| # These are the same as the ping packets above |
| pkts = [ |
| b'\xff\xff\xff\xff\xff\xff\xac"\x0b\xc5j\xdb\x08\x00E\x00\x00\x80\x00\x01\x00\x00@\x01\xf6x\xc0\x00\x02\x01\xc0\x00\x02\x02\x08\x00\xb6\xbe\x00\x00\x00\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', |
| b'\xff\xff\xff\xff\xff\xff\xac"\x0b\xc5j\xdb\x08\x00E\x00\x00\x80\x00\x01\x00\x00@\x01\xf6x\xc0\x00\x02\x02\xc0\x00\x02\x01\x00\x00\xbe\xbe\x00\x00\x00\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', |
| ] |
| |
| # tshark doesn't need workarounds on OSX |
| tempfile_count = len(conf.temp_files) |
| |
| r = tdecode(pkts, dump=True, linktype=DLT_EN10MB) |
| assert b'Src: 192.0.2.1' in r |
| assert b'Src: 192.0.2.2' in r |
| assert b'Dst: 192.0.2.2' in r |
| assert b'Dst: 192.0.2.1' in r |
| assert b'Echo (ping) request' in r |
| assert b'Echo (ping) reply' in r |
| assert b'ICMP' in r |
| assert len(conf.temp_files) == tempfile_count |
| |
| |
| = Run scapy's tshark command |
| ~ netaccess |
| tshark(count=1, timeout=3) |
| |
| = Check wireshark() |
| ~ wireshark |
| |
| f = BytesIO() |
| pkt = Ether()/IP()/ICMP() |
| |
| with mock.patch('subprocess.Popen', return_value=Bunch(stdin=f)) as popen: |
| # Prevent closing the BytesIO |
| with mock.patch.object(f, 'close'): |
| wireshark([pkt]) |
| |
| popen.assert_called_once_with( |
| [conf.prog.wireshark, '-ki', '-'], |
| stdin=subprocess.PIPE, stdout=None, stderr=None) |
| |
| print(bytes_hex(f.getvalue())) |
| assert raw(pkt) in f.getvalue() |
| f.close() |
| del f, pkt |
| |
| = 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) |
| |
| = Check wrpcap() with SndRcvList |
| |
| import tempfile |
| filename = tempfile.mktemp(suffix=".pcap") |
| wrpcap(filename, SndRcvList(res=[(Ether()/IP(), Ether()/IP())])) |
| assert len(rdpcap(filename)) == 2 |
| os.remove(filename) |
| |
| = Check wrpcap() with different packets types |
| |
| import mock |
| import os |
| import tempfile |
| |
| with mock.patch("scapy.utils.warning") as warning: |
| filename = tempfile.mktemp() |
| wrpcap(filename, [IP(), Ether(), IP(), IP()]) |
| os.remove(filename) |
| assert any("Inconsistent" in arg for arg in warning.call_args[0]) |
| |
| ############ |
| ############ |
| + Sessions |
| |
| = IPSession - dissect fragmented IP packets on-the-flow |
| packet = IP()/("data"*1000) |
| frags = fragment(packet) |
| tmp_file = get_temp_file() |
| wrpcap(tmp_file, frags) |
| |
| dissected_packets = [] |
| def callback(pkt): |
| dissected_packets.append(pkt) |
| |
| sniff(offline=tmp_file, session=IPSession, prn=callback) |
| assert len(dissected_packets) == 1 |
| assert raw(dissected_packets[0]) == raw(packet) |
| |
| = NetflowSession - dissect packet NetflowV9 packets on-the-flow |
| |
| 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 |
| |
| dissected_packets = [] |
| def callback(pkt): |
| dissected_packets.append(pkt) |
| |
| sniff(offline=filename, session=NetflowSession, prn=callback) |
| records = dissected_packets[3][NetflowDataflowsetV9].records |
| assert len(records) == 24 |
| assert records[0].IPV4_SRC_ADDR == '20.0.1.174' |
| assert records[0].IPV4_NEXT_HOP == '10.100.103.1' |
| |
| = StringBuffer |
| |
| buffer = StringBuffer() |
| assert not buffer |
| |
| buffer.append(b"kie", 5) |
| buffer.append(b"e", 11) |
| buffer.append(b"pi", 2) |
| buffer.append(b"pi", 9) |
| buffer.append(b"n", 4) |
| |
| assert bytes_hex(bytes(buffer)) == b'0070696e6b696500706965' |
| assert len(buffer) == 11 |
| assert buffer |
| |
| = TCPSession - dissect HTTP 1.0 chunked image |
| ~ http |
| |
| load_layer("http") |
| |
| import os |
| |
| tmp = "/test/pcaps/http_chunk.pcap.gz" |
| 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 = sniff(offline=filename, session=TCPSession) |
| |
| a[2].show() |
| assert HTTPRequest in a[2] |
| assert a[2].Path == b'/httpgallery/chunked/chunkedimage.aspx?0.2911017199439567' |
| assert a[2].Accept_Encoding == b'gzip, deflate' |
| assert a[2].Accept == b'image/webp,image/apng,image/*,*/*;q=0.8' |
| assert a[2].Http_Version == b'HTTP/1.1' |
| assert a[2].Referer == b'http://www.httpwatch.com/httpgallery/chunked/' |
| |
| a[29].show() |
| assert HTTPResponse in a[29] |
| assert a[29].Transfer_Encoding == b"chunked" |
| assert a[29].Content_Type == b'image/jpeg; charset=utf-8' |
| assert a[29].Http_Version == b'HTTP/1.1' |
| assert a[29].Status_Code == b"200" |
| assert a[29].Reason_Phrase == b"OK" |
| assert len(a[29].load) == 33653 |
| # According to wireshark: |
| wireshark_data = b'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' |
| assert a[29].load == base64_bytes(wireshark_data) |
| |
| # This a valid JPEG image: try it out |
| # open("image.jpg", "wb").write(a[29].load) |
| |
| = TCPSession - dissect HTTP 1.0 html page with Content_Length |
| ~ http |
| |
| load_layer("http") |
| |
| import os |
| |
| # Packet from |
| # https://community.cisco.com/t5/networking-documents/http-packet-captures/ta-p/3121453 |
| tmp = "/test/pcaps/http_content_length.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 |
| |
| expected_data = b"""<!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>Google</title><script>window.google={kEI:"TiU7TKv1IdO6jAfQmdX4AQ",kEXPI:"17259,18168,23756,24692,24878,24879,25233,25335,25402,25529",kCSI:{e:"17259,18168,23756,24692,24878,24879,25233,25335,25402,25529",ei:"TiU7TKv1IdO6jAfQmdX4AQ",expi:"17259,18168,23756,24692,24878,24879,25233,25335,25402,25529"},ml:function(){},kHL:"en",time:function(){return(new Date).getTime()},log:function(b,d,c){var a=new Image,e=google,g=e.lc,f=e.li;a.onerror=(a.onload=(a.onabort=function(){delete g[f]}));g[f]=a;c=c||"/gen_204?atyp=i&ct="+b+"&cad="+d+"&zx="+google.time();a.src=c;e.li=f+1},lc:[],li:0,Toolbelt:{}};\nwindow.google.sn="webhp";window.google.timers={load:{t:{start:(new Date).getTime()}}};try{window.google.pt=window.external&&window.external.pageT;}catch(u){}window.google.jsrt_kill=1;\nvar _gjwl=location;function _gjuc(){var b=_gjwl.href.indexOf("#");if(b>=0){var a=_gjwl.href.substring(b+1);if(/(^|&)q=/.test(a)&&a.indexOf("#")==-1&&!/(^|&)cad=h($|&)/.test(a)){_gjwl.replace("/search?"+a.replace(/(^|&)fp=[^&]*/g,"")+"&cad=h");return 1}}return 0}function _gjp(){!(window._gjwl.hash&&window._gjuc())&&setTimeout(_gjp,500)};\nwindow._gjp && _gjp()</script><style id=gstyle>body{margin:0}#gog{padding:3px 10px 0}td{line-height:.8em;}.gac_m td{line-height:17px;}form{margin-bottom:20px;}body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}.fl a:link{color:#77c}em{font-weight:bold;font-style:normal}.lst{font:17px arial,sans-serif;margin-bottom:.2em;vertical-align:bottom;}input{font-family:inherit}.lsb,.gac_sb{font-size:15px;height:1.85em!important;margin:.2em;padding:0 6px;width:auto;overflow:visible;}#gog{background:#fff;}#gbar,#guser{font-size:13px;padding-top:1px !important}#gbar{float:left;height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbs,.gbm{background:#fff;left:0;position:absolute;text-align:left;visibility:hidden;z-index:1000}.gbm{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}.gb1{margin-right:.5em}.gb1,.gb3{zoom:1}.gb2{display:block;padding:.2em .5em;}.gb2,.gb3{text-decoration:none;border-bottom:none}a.gb1,a.gb2,a.gb3,a.gb4{color:#00c !important}a.gb2:hover{background:#36c;color:#fff !important}</style><script>google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};var e=0;if(!window.google)window.google={};window.google.crm={};window.google.cri=0;window.clk=function(f,g,h,l,m,b,n){if(document.images){e++;var a=encodeURIComponent||escape,c=new Image,i=window.google.cri++;window.google.crm[i]=c;c.onerror=(c.onload=(c.onabort=function(){delete window.google.crm[i]}));if(b&&b.substring(0,6)!="&sig2=")b="&sig2="+b;c.src=["/url?sa=T","","&cd=",a(m),"&ved=",a(n),f?"&url="+a(f.replace(/#.*/,"")).replace(/\\+/g,"%2B"):"","&ei=","TiU7TKv1IdO6jAfQmdX4AQ",b,"&nclks=",e].join("")}return true};\nwindow.gbar={qs:function(){},tg:function(e){var o={id:\'gbar\'};for(i in e)o[i]=e[i];google.x(o,function(){gbar.tg(o)})}};</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src=\'/images/nav_logo8.png\'" ><textarea id=csi style=display:none></textarea><span><iframe name=wgjf style=display:none></iframe></span><div id=xjsc></div><div id=ghead><div id=gog><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://www.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb1>Videos</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" aria-haspopup=true class=gb3><u>more</u> <small>▼</small></a><div class=gbm id=gbi><a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://www.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://translate.google.com/?hl=en&tab=wT" onclick=gbar.qs(this) class=gb2>Translate</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div><a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <div class=gb2><div class=gbd></div></div><a href="http://www.google.com/intl/en/options/" class=gb2>even more »</a> </div></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg" class=gb4>iGoogle</a> | </span><a href="/preferences?hl=en" class=gb4>Search settings</a> | <a href="https://www.google.com/accounts/Login?hl=en&continue=http://www.google.com/" class=gb4>Sign in</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div></div></div> <center><style>.pmoabs{position:absolute;right:0;top:25px;}.pmoflt,.pmoc{float:right;clear:both;}#pmocntr{behavior:url(#default#userdata);border:1px solid #ccc;}#pmocntr table{font-size:80%;}#pmolnk,#pmolnk div{background:url(/images/modules/buttons/g-button-chocobo-basic-1.gif)}#pmolnk{width:170px;}#pmolnk div{background-position:100% -400px;}#pmolnk div div{background-position:0 100%;}#pmolnk a{white-space:nowrap;background:url(/images/modules/buttons/g-button-chocobo-basic-2.gif) 100% 100% no-repeat;color:#fff;display:block;padding:8px 12px 15px 10px;text-decoration:none}.padi {padding:0 0 4px 8px}.padt {padding:0 6px 4px 6px}</style><div id=pmocntr class=pmoabs><table border=0><tr><td colspan=2><img border=0 src="/images/close_sm.gif" class=pmoc onclick="cpc()"><tr><td class=padi rowspan=2><img src="/images/chrome_48.gif"><td class=padt align=center><b>A faster way to browse the web</b><tr><td class=padt align=center dir=ltr><div id=pmolnk><div><div><a href="/aclk?sa=L&ai=CMDwaOCM7TIi0MIqv4gbPjZW5B8_W3aEB-9_olQ_v-_3lJxABIMFUULKwjvUBYLsGqgSUAU_QpGfsCCT1d4iDFinqBPHIMs6nmdIsfzDF-UtUGr_gjMc_XAzlKMJy_lPWHLjRniVP1sBkhK5rdW1q85XInEs9JuYm4Dk1ofkpAr6hdMN3EZXsHVSk7CsomsS42n4oOQUZtLJ1sLpkc5VOuvAIU17-0Egro-40RlOQGNYLTbGSHyqssz8Ahp3Ehki745351WicSNE&num=1&sig=AGiWqtz44oZT8y_vcAQLTowVZyUZctoAHA&adurl=http://www.google.com/chrome/index.html%3Fhl%3Den%26brand%3DCHNG%26utm_source%3Den-hpp%26utm_medium%3Dhpp%26utm_campaign%3Den"><b>Install Google Chrome</b></a></div></div></table></div><script>(function(){var b=\'pmocntr\',a=document.getElementById(b),c=\'d\',d=\'i\',e;function p(){a.style.display=\'none\'}try{a.load(b);e=a.getAttribute(d)||0;if(a.getAttribute(c)||e>25){p()}else{a.setAttribute(d,++e);a.save(b)}}catch(z){}window.cpc=function(){p();try{a.setAttribute(c,1);a.save(b)}catch(z){}};window.onresize=function(){if(a.offsetWidth*2+document.getElementById(\'logo\').offsetWidth>document.body.clientWidth){a.className=\'pmoflt\'}else{a.className=\'pmoabs\'}};window.lol=function(){window.onresize()}}())</script><br clear=all id=lgpd><div id=lga><img alt="Google" height=110 src="/intl/en_ALL/images/logo2.gif" width=276 id=logo onload="window.lol&&lol()"><br><br></div><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%> </td><td align=center nowrap><input name=hl type=hidden value=en><input name=source type=hidden value=hp><input autocomplete="off" maxlength=2048 name=q size=55 class=lst title="Google Search" value=""><br><input name=btnG type=submit value="Google Search" class=lsb><input name=btnI type=submit value="I'm Feeling Lucky" class=lsb></td><td nowrap width=25% align=left><font size=-2> <a href="/advanced_search?hl=en">Advanced Search</a><br> <a href="/language_tools?hl=en">Language Tools</a></font></td></tr></table></form><br><span id=footer><center id=fctr><br><font size=-1><a href="/intl/en/ads/">Advertising Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a><p id=shf0 style=display:none;behavior:url(#default#homePage)><font size=-1><a href="/aclk?sa=L&ai=Ch8SU4iQ7TMvoHp2x4gbR1rm3B8X4n3yvjpnHCs2tk5cREAEgwVRQvpyhyfj_____AWCrBaoEsgFP0AfDqi9LrsWk8xuAZxV33DBcsflfyeiFyZrQXRUyD-x2QfMpinnjfIrM5cD-YizzdL-m7VKXO6w_kRsOWsPkgD9mKu0K9qXP9FQfHQsHRp0LdDmtlbf1g0E-Md-opiHZKK6_0YlMxALdkw6sN2LZRCkOIQq8LDHViqVDnr8Rqx2bomL0aY_vO6JtJE3QZkkQJkV5ZFLB8R-H0FingtOWISs1zLoTNYlPJwUnqOPcAKF7&num=1&sig=AGiWqtxkwm32U-Ox-AEC_8qXgysR70jfpA&adurl=/mgyhp.html" onclick=xz()>Make Google my homepage</a></p><script>(function(){var a=document.getElementById("shf0"),b="http://www.google.com/";try{a.isHomePage(b)||(a.style.display="block")}catch(z){}window.xz=function(){try{a.setHomePage(b);var c=new Image;c.src="/gen_204?mgmhp=shf0&ct=c&cd="+a.isHomePage(b);window.wy=c}catch(z){}}})();</script></font><p><font size=-2>©2010 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></span> <div id=xjsd></div><div id=xjsi><script>if(google.y)google.y.first=[];if(google.y)google.y.first=[];google.dstr=[];google.rein=[];window.setTimeout(function(){var a=document.createElement("script");a.src="/extern_js/f/CgJlbhICdXMrMEU4ASwrMFo4AiwrMA44FSwrMBc4BywrMCc4BCwrMDw4AywrMFE4AiwrMAo4bUAvLCswFjgcLCswGTghLCswJTjKiAEsKzBAOBIsKzBOOAUsKzAYOAUsKzAmOAssgAIN/sfSVKzsYj5Q.js";(document.getElementById("xjsd")||document.body).appendChild(a);if(google.timers&&google.timers.load.t)google.timers.load.t.xjsls=(new Date).getTime();},0);\n;google.neegg=1;google.y.first.push(function(){google.ac.i(document.f,document.f.q,\'\',\'\',\'\',{a:1,o:1,l:1});google.History&&google.History.initialize(\'/\')});if(google.j&&google.j.en&&google.j.xi){window.setTimeout(google.j.xi,0);google.fade=null;}</script></div><script>(function(){\nvar b,d,e,f;function g(a,c){if(a.removeEventListener){a.removeEventListener("load",c,false);a.removeEventListener("error",c,false)}else{a.detachEvent("onload",c);a.detachEvent("onerror",c)}}function h(a){f=(new Date).getTime();++d;a=a||window.event;var c=a.target||a.srcElement;g(c,h)}var i=document.getElementsByTagName("img");b=i.length;d=0;for(var j=0,k;j<b;++j){k=i[j];if(k.complete||typeof k.src!="string"||!k.src)++d;else if(k.addEventListener){k.addEventListener("load",h,false);k.addEventListener("error",\nh,false)}else{k.attachEvent("onload",h);k.attachEvent("onerror",h)}}e=b-d;function l(){google.timers.load.t.ol=(new Date).getTime();google.timers.load.t.iml=f;google.kCSI.imc=d;google.kCSI.imn=b;google.kCSI.imp=e;google.report&&google.report(google.timers.load,google.kCSI)}if(window.addEventListener)window.addEventListener("load",l,false);else if(window.attachEvent)window.attachEvent("onload",l);google.timers.load.t.prt=(f=(new Date).getTime());\n})();\n</script>""" |
| |
| |
| conf.contribs["http"]["auto_compression"] = False |
| a = sniff(offline=filename, session=TCPSession) |
| pkt = a[7] |
| assert HTTP in pkt |
| assert HTTPResponse in pkt |
| assert pkt[HTTP].Content_Length == b'5012' |
| assert len(pkt[Raw].load) == 5012 |
| |
| conf.contribs["http"]["auto_compression"] = True |
| a = sniff(offline=filename, session=TCPSession) |
| pkt = a[7] |
| assert HTTP in pkt |
| assert HTTPResponse in pkt |
| print(pkt[Raw].load, expected_data) |
| assert pkt[Raw].load == expected_data |
| |
| ############ |
| ############ |
| + HTTP 1.0 |
| ~ http |
| |
| = HTTP decompression (gzip) |
| |
| conf.debug_dissector = True |
| load_layer("http") |
| |
| import os |
| import gzip |
| |
| tmp = "/test/pcaps/http_compressed.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 |
| |
| # First without auto decompression |
| |
| conf.contribs["http"]["auto_compression"] = False |
| pkts = sniff(offline=filename, session=TCPSession) |
| |
| data = b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xffEQ]o\xdb0\x0c\xfc+\x9a\x1f\x92\xa7\x9a\x96?\xe4\xb8\x892`I\x81\r\xe8\xda\xa2p1\xec\xa9P-\xd5\x16*[\x86\xa5\xd8K\x7f\xfd\xa8\x14E\x1f\x8e:R\x07\xf2D\xed\xbe\x1d\xef\x0f\xf5\xdf\x87\x1b\xd2\xf9\xde\x90\x87\xa7\x1f\xb7\xbf\x0e$\xba\x02\xf8\x93\x1d\x00\x8e\xf5\x91\xfc\xac\x7f\xdf\x92<N(\xa9\'18\xed\xb5\x1d\x84\x01\xb8\xb9\x8bH\xd4y?^\x03,\xcb\x12/Yl\xa7\x16\xeaG\x08\xadr0\xd6:\x15K/\xa3\xfd.T0*!\xf7;\xaf\xbdQ\xfb\x1d|\x9e\x1f\xd5\x17+\xcf\xc4\xf9\xb3Q<z\x11\xcd[;\xd9\xd3 \xaf\x1ak\xectM|\x98<\x8aI\r\x1e\xbb\xe9\xbe%nj\xf8:Lw8~\xd4\xff\x94\x89{\xe1;/\xda\xb8\xb1=\xa8\x19\xa5\x80\xc2\xef\xbd\x7f\xd6\x92\xd3\x82\xe6\x8c\xad0\x112\xa4\t\xa3y\xbe\x9a)_\xcd)"\xe3+\x87\xdc!w\xc8\xed$y\x9a\xe4eZV%+\xd6d\xd1\xd2w|M\xd7\xa4S\xba\xed\xfc\x85\xc2\x97\x91\xe8\xd3\x88\x90NM\xb3nT\xdcZ\xdb\x1au\xf1"e\x0f\xaf\xc6\xc1;\x04m\xc6\n\xc6h\xb9\xf5\xe7Q\xf1n\x9c5nt\xdb\x08\xcf;\xdb\xab\x91V\x9b\xed)\xe5\xdb\x13C\x14\x88\x1c\x91!*\x04M0\x94\x81\x84\n\rW\x94\x86p\xa9m\xf8ix\x1b\xec2`\x03\x14\x867\xd0\ng%\xd9\x86\xb1\x94\x15qUd,B\xd7\x10v\x1d\x16\x1f>\xe5?9\x89QV\x01\x02\x00\x00' |
| |
| pkts[2].show() |
| assert HTTPResponse in pkts[2] |
| assert pkts[2].Expires == b'Mon, 22 Apr 2019 15:23:19 GMT' |
| assert pkts[2].Content_Type == b'text/html; charset=UTF-8' |
| assert pkts[2].load == data |
| |
| # Now with auto decompression |
| |
| conf.contribs["http"]["auto_compression"] = True |
| pkts = sniff(offline=filename, session=TCPSession) |
| |
| pkts[2].show() |
| assert HTTPResponse in pkts[2] |
| assert pkts[2].load == b'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title></title></head><body style="background-color: transparent"><img src=\'https://pixel.mathtag.com/event/img?mt_id=151466&mt_adid=106144&v1=&v2=&v3=&s1=&s2=&s3=&ord=2047279765\' width=\'1\' height=\'1\' /><img src="https://adservice.google.com/ddm/fls/z/src=3656617;type=hpvisit;cat=homep198;u2=;u6=;u5=;u4=;u3=;u9=;u10=;u7=;u13=;u14=;u11=;u17=;u18=unknown;u20=;ord=1956603866265.9536"/></body></html>' |
| |
| = HTTP decompression (brotli) |
| |
| conf.debug_dissector = True |
| load_layer("http") |
| |
| import os |
| import brotli |
| |
| tmp = "/test/pcaps/http_compressed-brotli.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 |
| |
| # First without auto decompression |
| |
| conf.contribs["http"]["auto_compression"] = False |
| pkts = sniff(offline=filename, session=TCPSession) |
| |
| data = b'\x1f\x41\x00\xe0\xc5\x6d\xec\x77\x56\xf7\xb5\x8b\x1c\x52\x10\x48\xe0\x90\x03\xf6\x6f\x97\x30\xd0\x40\x24\xb8\x01\x9b\xdb\xa0\xf4\x5c\x92\x4c\xc4\x6f\x89\x58\xf7\x4b\xf7\x4b\x6f\x8c\x2e\x2c\x28\x64\x06\x1d\x03' |
| |
| pkts[0].show() |
| assert HTTPResponse in pkts[0] |
| assert pkts[0].Content_Encoding == b'br' |
| assert pkts[0].Content_Type == b'text/plain' |
| assert pkts[0].load == data |
| |
| # Now with auto decompression |
| |
| conf.contribs["http"]["auto_compression"] = True |
| pkts = sniff(offline=filename, session=TCPSession) |
| |
| pkts[0].show() |
| assert HTTPResponse in pkts[0] |
| assert pkts[0].load == b'This is a test file for testing brotli decompression in Wireshark\n' |
| |
| = HTTP PSH bug fix |
| |
| tmp = "/test/pcaps/http_tcp_psh.pcap.gz" |
| 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 |
| |
| pkts = sniff(offline=filename, session=TCPSession) |
| |
| assert len(pkts) == 15 |
| # Verify a split header exists in the packet |
| assert pkts[5].User_Agent == b'example_user_agent' |
| |
| # Verify all of the response data exists in the packet |
| assert int(pkts[7][HTTP].Content_Length.decode()) == len(pkts[7][Raw].load) |
| |
| = HTTP build |
| |
| pkt = TCP()/HTTP()/HTTPRequest(Method=b'GET', Path=b'/download', Http_Version=b'HTTP/1.1', Accept=b'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', Accept_Encoding=b'gzip, deflate', Accept_Language=b'en-US,en;q=0.5', Cache_Control=b'max-age=0', Connection=b'keep-alive', Host=b'scapy.net', User_Agent=b'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0') |
| raw_pkt = raw(pkt) |
| raw_pkt |
| assert raw_pkt == b'\x00P\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x00\x00\x00\x00GET /download HTTP/1.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-US,en;q=0.5\r\nCache-Control: max-age=0\r\nConnection: keep-alive\r\nHost: scapy.net\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0\r\n\r\n' |
| |
| = HTTP 1.1 -> HTTP 2.0 Upgrade (h2c) |
| ~ Test h2c |
| |
| conf.debug_dissector = True |
| load_layer("http") |
| from scapy.contrib.http2 import H2Frame |
| |
| import os |
| |
| tmp = "/test/pcaps/http2_h2c.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 |
| |
| pkts = sniff(offline=filename, session=TCPSession) |
| |
| assert HTTPResponse in pkts[1] |
| assert pkts[1].Connection == b"Upgrade" |
| assert H2Frame in pkts[1] |
| assert pkts[1][H2Frame].settings[0].id == 3 |
| |
| for i in range(3, 10): |
| assert HTTP not in pkts[i] |
| assert H2Frame in pkts[i] |
| |
| ############ |
| ############ |
| + 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 |
| |
| = fragment() with non-multiple-of-8 MTU |
| paylen = 1400 + 1 |
| frags1 = fragment(IP() / ("X" * paylen), paylen) |
| assert len(frags1) == 1 |
| frags2 = fragment(IP() / ("X" * (paylen + 1)), paylen) |
| assert len(frags2) == 2 |
| assert len(frags2[0]) == 20 + paylen - paylen % 8 |
| assert len(frags2[1]) == 20 + 1 + paylen % 8 |
| |
| = 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)) |
| |
| = defragment() uses timestamp of last fragment |
| payloadlen, fragsize = 100, 8 |
| assert fragsize % 8 == 0 |
| packet = Ether()/IP()/("X" * payloadlen) |
| frags = fragment(packet, fragsize) |
| for i,frag in enumerate(frags): |
| frag.time -= 100 + i |
| |
| last_time = max(frag.time for frag in frags) |
| defrags = defragment(frags) |
| assert defrags[0].time == last_time |
| nonfrag, defrags, badfrag = defrag(frags) |
| assert defrags[0].time == last_time |
| |
| = defragment() - Missing fragments |
| |
| pkts = fragment(IP(dst="10.0.0.5")/ICMP()/("X"*1500)) |
| assert len(defragment(pkts[1:])) == 1 |
| |
| = 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 |
| |
| = 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: wrong offset |
| TCP(raw(TCP(dataofs=11)/b"o")) |
| |
| = 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 options: invalid data offset |
| data = b'\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x80\x02 \x00\x1b\xb8\x00\x00\x02\x04\x05\xb4\x04\x02\x08\x06\xf7\xa26C\x00\x00\x00\x00\x01\x03\x03\x07' |
| p = TCP(data) |
| assert TCP in p and Raw in p and len(p.options) == 3 |
| |
| = TCP options: build oversized packet |
| |
| raw(TCP(options=[('TFO', (1607681672, 2269173587)), ('AltChkSum', (81, 27688)), ('TFO', (253281879, 1218258937)), ('Timestamp', (1613741359, 4215831072)), ('Timestamp', (3856332598, 1434258666))])) |
| |
| = 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) |
| |
| = DNS frames with MX records |
| ~ dns |
| |
| frame = b'E\x00\x00\xa4\x93\x1d\x00\x00y\x11\xdc\xfc\x08\x08\x08\x08\xc0\xa8\x00w\x005\xb4\x9b\x00\x90k\x80\x00\x00\x81\x80\x00\x01\x00\x05\x00\x00\x00\x00\x06google\x03com\x00\x00\x0f\x00\x01\xc0\x0c\x00\x0f\x00\x01\x00\x00\x02B\x00\x11\x00\x1e\x04alt2\x05aspmx\x01l\xc0\x0c\xc0\x0c\x00\x0f\x00\x01\x00\x00\x02B\x00\t\x00\x14\x04alt1\xc0/\xc0\x0c\x00\x0f\x00\x01\x00\x00\x02B\x00\t\x002\x04alt4\xc0/\xc0\x0c\x00\x0f\x00\x01\x00\x00\x02B\x00\t\x00(\x04alt3\xc0/\xc0\x0c\x00\x0f\x00\x01\x00\x00\x02B\x00\x04\x00\n\xc0/' |
| pkt = IP(frame) |
| results = [x.exchange for x in pkt.an.iterpayloads()] |
| assert results == [b'alt2.aspmx.l.google.com.', b'alt1.aspmx.l.google.com.', b'alt4.aspmx.l.google.com.', b'alt3.aspmx.l.google.com.', b'aspmx.l.google.com.'] |
| |
| pkt.clear_cache() |
| assert raw(dns_compress(pkt)) == frame |
| |
| = Advanced dns_get_str tests |
| ~ dns |
| |
| assert dns_get_str(b"\x06cheese\x00blobofdata....\x06hamand\xc0\x0c", 22, _fullpacket=True)[0] == b'hamand.cheese.' |
| |
| compressed_pkt = b'\x01\x00^\x00\x00\xfb\xa0\x10\x81\xd9\xd3y\x08\x00E\x00\x01\x14\\\n@\x00\xff\x116n\xc0\xa8F\xbc\xe0\x00\x00\xfb\x14\xe9\x14\xe9\x01\x00Ho\x00\x00\x84\x00\x00\x00\x00\x04\x00\x00\x00\x03\x03188\x0270\x03168\x03192\x07in-addr\x04arpa\x00\x00\x0c\x80\x01\x00\x00\x00x\x00\x0f\x07Android\x05local\x00\x019\x017\x013\x01D\x019\x01D\x01E\x01F\x01F\x01F\x011\x018\x010\x011\x012\x01A\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x018\x01E\x01F\x03ip6\xc0#\x00\x0c\x80\x01\x00\x00\x00x\x00\x02\xc03\xc03\x00\x01\x80\x01\x00\x00\x00x\x00\x04\xc0\xa8F\xbc\xc03\x00\x1c\x80\x01\x00\x00\x00x\x00\x10\xfe\x80\x00\x00\x00\x00\x00\x00\xa2\x10\x81\xff\xfe\xd9\xd3y\xc0\x0c\x00/\x80\x01\x00\x00\x00x\x00\x06\xc0\x0c\x00\x02\x00\x08\xc0B\x00/\x80\x01\x00\x00\x00x\x00\x06\xc0B\x00\x02\x00\x08\xc03\x00/\x80\x01\x00\x00\x00x\x00\x08\xc03\x00\x04@\x00\x00\x08' |
| |
| Ether(compressed_pkt) |
| |
| = Decompression loop in dns_get_str |
| ~ dns |
| |
| assert dns_get_str(b"\x04data\xc0\x0c", 0, _fullpacket=True)[0] == b"data.data." |
| |
| = Prematured end in dns_get_str |
| ~ dns |
| |
| assert dns_get_str(b"\x06da", 0, _fullpacket=True)[0] == b"da." |
| assert dns_get_str(b"\x04data\xc0\x01", 0, _fullpacket=True)[0] == b"data." |
| |
| = Other decompression loop in dns_get_str |
| ~ dns |
| s = b'\x00\x00\x84\x00\x00\x00\x00\x02\x00\x00\x00\x06\x0bGourmandise\x04_smb\x04_tcp\x05local\x00\x00!\x80\x01\x00\x00\x00x\x00\x14\x00\x00\x00\x00\x01\xbd\x0bGourmandise\xc0"\x0bGourmandise\x0b_afpovertcp\xc0\x1d\x00!\x80\x01\x00\x00\x00x\x00\x08\x00\x00\x00\x00\x02$\xc09\xc09\x00\x1c\x80\x01\x00\x00\x00x\x00\x10\xfe\x80\x00\x00\x00\x00\x00\x00\x00s#\x99\xca\xf7\xea\xdc\xc09\x00\x01\x80\x01\x00\x00\x00x\x00\x04\xc0\xa8\x01x\xc09\x00\x1c\x80\x01\x00\x00\x00x\x00\x10*\x01\xcb\x00\x0bD\x1f\x00\x18k\xb1\x99\x90\xdf\x84.\xc0\x0c\x00/\x80\x01\x00\x00\x00x\x00\t\xc0\x0c\x00\x05\x00\x00\x80\x00@\xc0G\x00/\x80\x01\x00\x00\x00x\x00\t\xc0G\x00\x05\x00\x00\x80\x00@\xc09\x00/\x80\x01\x00\x00\x00x\x00\x08\xc09\x00\x04@\x00\x00\x08' |
| DNS(s) |
| |
| = DNS record type 16 (TXT) |
| |
| p = DNS(raw(DNS(id=1,ra=1,an=DNSRR(rrname='scapy', type='TXT', rdata="niceday", ttl=1)))) |
| assert p[DNS].an.rdata == [b"niceday"] |
| |
| p = DNS(raw(DNS(id=1,ra=1,an=DNSRR(rrname='secdev', type='TXT', rdata=["sweet", "celestia"], ttl=1)))) |
| assert p[DNS].an.rdata == [b"sweet", b"celestia"] |
| assert raw(p) == b'\x00\x01\x01\x80\x00\x00\x00\x01\x00\x00\x00\x00\x06secdev\x00\x00\x10\x00\x01\x00\x00\x00\x01\x00\x0f\x05sweet\x08celestia' |
| |
| = DNS - Malformed DNS over TCP message |
| |
| try: |
| p = IP(IP(raw(IP()/TCP()/DNS(length=28))[:-13])) |
| assert False |
| except Scapy_Exception as e: |
| assert str(e) == "Malformed DNS message: too small!" |
| |
| try: |
| p = IP(raw(IP()/TCP()/DNS(length=28, qdcount=1))) |
| assert False |
| except Scapy_Exception as e: |
| assert str(e) == "Malformed DNS message: invalid length!" |
| |
| |
| = 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 |
| scapy.arch.unix.DARWIN = True |
| scapy.arch.unix.FREEBSD = False |
| scapy.arch.unix.NETBSD = False |
| scapy.arch.unix.OPENBSD = False |
| routes = read_routes() |
| assert(len(routes) == 4) |
| assert([r for r in routes if r[3] == "bridge10"]) |
| |
| |
| test_osx_netstat_truncated() |
| |
| |
| = macOS 10.13 |
| ~ 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_10_13_ipv4(mock_os, mock_get_if_addr): |
| """Test read_routes() on OS X 10.13""" |
| # 'netstat -rn -f inet' output |
| netstat_output = u""" |
| Routing tables |
| |
| Internet: |
| Destination Gateway Flags Refs Use Netif Expire |
| default 192.168.28.1 UGSc 82 0 en0 |
| 127 127.0.0.1 UCS 0 0 lo0 |
| 127.0.0.1 127.0.0.1 UH 1 878 lo0 |
| 169.254 link#5 UCS 0 0 en0 |
| 192.168.28 link#5 UCS 4 0 en0 |
| 192.168.28.1/32 link#5 UCS 2 0 en0 |
| 192.168.28.1 88:32:9c:f5:4e:ea UHLWIir 40 37 en0 1177 |
| 192.168.28.2 62:aa:56:4b:51:54 UHLWI 0 0 en0 619 |
| 192.168.28.4 38:17:ed:9a:58:28 UHLWIi 1 6 en0 428 |
| 192.168.28.18/32 link#5 UCS 1 0 en0 |
| 192.168.28.18 88:32:9c:f5:4e:eb UHLWI 0 1 lo0 |
| 192.168.28.28 04:0e:eb:11:74:a7 UHLWI 0 0 en0 576 |
| 224.0.0/4 link#5 UmCS 1 0 en0 |
| 224.0.0.251 1:0:5e:0:0:fb UHmLWI 0 0 en0 |
| 255.255.255.255/32 link#5 UCS 0 0 en0 |
| """ |
| # Mocked file descriptor |
| strio = StringIO(netstat_output) |
| mock_os.popen = mock.MagicMock(return_value=strio) |
| # Mocked get_if_addr() output |
| def se_get_if_addr(iface): |
| """Perform specific side effects""" |
| import socket |
| if iface == "en0": |
| return "192.168.28.18" |
| return "127.0.0.1" |
| mock_get_if_addr.side_effect = se_get_if_addr |
| # Test the function |
| from scapy.arch.unix import read_routes |
| scapy.arch.unix.DARWIN = False |
| scapy.arch.unix.FREEBSD = True |
| scapy.arch.unix.NETBSD = False |
| scapy.arch.unix.OPENBSD = False |
| routes = read_routes() |
| for r in routes: |
| print(r) |
| assert(len(routes) == 15) |
| default_route = [r for r in routes if r[0] == 0][0] |
| assert default_route[3] == "en0" and default_route[4] == "192.168.28.18" |
| |
| test_osx_10_13_ipv4() |
| |
| |
| = macOS 10.15 |
| ~ 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_10_15_ipv4(mock_os, mock_get_if_addr): |
| """Test read_routes() on OS X 10.15""" |
| # 'netstat -rn -f inet' output |
| netstat_output = u""" |
| Routing tables |
| |
| Internet: |
| Destination Gateway Flags Netif Expire |
| default 192.168.122.1 UGSc en0 |
| 127 127.0.0.1 UCS lo0 |
| 127.0.0.1 127.0.0.1 UH lo0 |
| 169.254 link#8 UCS en0 ! |
| 192.168.122 link#8 UCS en0 ! |
| 192.168.122.1/32 link#8 UCS en0 ! |
| 192.168.122.1 52:54:0:c0:b7:af UHLWIir en0 1169 |
| 192.168.122.63/32 link#8 UCS en0 ! |
| 224.0.0/4 link#8 UmCS en0 ! |
| 224.0.0.251 1:0:5e:0:0:fb UHmLWI en0 |
| 255.255.255.255/32 link#8 UCS en0 ! |
| """ |
| # Mocked file descriptor |
| strio = StringIO(netstat_output) |
| mock_os.popen = mock.MagicMock(return_value=strio) |
| # Mocked get_if_addr() output |
| def se_get_if_addr(iface): |
| """Perform specific side effects""" |
| import socket |
| if iface == "en0": |
| return "192.168.122.42" |
| return "127.0.0.1" |
| mock_get_if_addr.side_effect = se_get_if_addr |
| # Test the function |
| from scapy.arch.unix import read_routes |
| scapy.arch.unix.DARWIN = False |
| scapy.arch.unix.FREEBSD = True |
| scapy.arch.unix.NETBSD = False |
| scapy.arch.unix.OPENBSD = False |
| routes = read_routes() |
| for r in routes: |
| print(r) |
| assert len(routes) == 11 |
| default_route = [r for r in routes if r[0] == 0][0] |
| assert default_route[3] == "en0" and default_route[4] == "192.168.122.42" |
| |
| test_osx_10_15_ipv4() |
| |
| |
| = 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 |
| return read_routes() |
| |
| routes = test_openbsd_6_3() |
| |
| 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" |
| |
| = Solaris 11.1 |
| ~ mock_read_routes_bsd |
| |
| import mock |
| from io import StringIO |
| |
| # Mocked Solaris 11.1 parsing behavior |
| |
| @mock.patch("scapy.arch.unix.SOLARIS", True) |
| @mock.patch("scapy.arch.unix.os") |
| def test_solaris_111(mock_os): |
| """Test read_routes() on Solaris 11.1""" |
| # 'netstat -rvn -f inet' output |
| netstat_output = u""" |
| IRE Table: IPv4 |
| Destination Mask Gateway Device MTU Ref Flg Out In/Fwd |
| -------------------- --------------- -------------------- ------ ----- --- --- ----- ------ |
| default 0.0.0.0 10.0.2.2 net0 1500 2 UG 5 0 |
| 10.0.2.0 255.255.255.0 10.0.2.15 net0 1500 3 U 0 0 |
| 127.0.0.1 255.255.255.255 127.0.0.1 lo0 8232 2 UH 1517 1517 |
| """ |
| # Mocked file descriptor |
| strio = StringIO(netstat_output) |
| mock_os.popen = mock.MagicMock(return_value=strio) |
| print(scapy.arch.unix.SOLARIS) |
| |
| # Test the function |
| from scapy.arch.unix import read_routes |
| return read_routes() |
| |
| routes = test_solaris_111() |
| print(routes) |
| assert len(routes) == 3 |
| assert routes[0][:4] == (0, 0, '10.0.2.2', 'net0') |
| assert routes[1][:4] == (167772672, 4294967040, '0.0.0.0', 'net0') |
| assert routes[2][:4] == (2130706433, 4294967295, '0.0.0.0', 'lo0') |
| |
| |
| ############ |
| ############ |
| + 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"] == " ".join(argv)) |
| assert(len(results_dict["warnings"]) == 3) |
| |
| = Test more recent version with flows |
| |
| data = """Actual: 1 packets (42 bytes) sent in 0.000278 seconds |
| Rated: 151079.1 Bps, 1.20 Mbps, 3597.12 pps |
| Flows: 1 flows, 3597.12 fps, 1 flow packets, 0 non-flow |
| Statistics for network device: enp0s3 |
| Successful packets: 1 |
| Failed packets: 0 |
| Truncated packets: 0 |
| Retried packets (ENOBUFS): 0 |
| Retried packets (EAGAIN): 0 |
| """ |
| |
| results_dict = _parse_tcpreplay_result(data, "", []) |
| results_dict |
| |
| expected = { |
| 'bps': 151079.1, |
| 'bytes': 42, |
| 'command': '', |
| 'failed': 0, |
| 'flow_packets': 1, |
| 'flows': 1, |
| 'fps': 3597.12, |
| 'mbps': 1.2, |
| 'non_flow': 0, |
| 'packets': 1, |
| 'pps': 3597.12, |
| 'retried_eagain': 0, |
| 'retried_enobufs': 0, |
| 'successful': 1, |
| 'time': 0.000278, |
| 'truncated': 0, |
| 'warnings': [] |
| } |
| |
| assert results_dict == expected |
| |
| ############ |
| ############ |
| + 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 sum(1 for r in routes6 if r[0] == "::1" and r[4] == ["::1"]) < 1: |
| return False |
| if sum(1 for r in routes6 if r[0] == "fe80::" and r[1] == 64) < 1: |
| return False |
| if sum(1 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 |
| |
| import mock |
| from io import StringIO |
| |
| @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 |
| scapy.arch.unix.DARWIN = False |
| scapy.arch.unix.FREEBSD = True |
| scapy.arch.unix.NETBSD = False |
| scapy.arch.unix.OPENBSD = False |
| 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 |
| |
| import mock |
| from io import StringIO |
| |
| @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 |
| |
| import mock |
| from io import StringIO |
| |
| @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 |
| |
| import mock |
| from io import StringIO |
| |
| @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() |
| scapy.arch.unix.DARWIN = False |
| scapy.arch.unix.FREEBSD = True |
| scapy.arch.unix.NETBSD = False |
| scapy.arch.unix.OPENBSD = False |
| 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 |
| |
| import mock |
| from io import StringIO |
| |
| @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 = conf.loopback_name |
| try: |
| conf.iface = 'enp3s0' |
| conf.loopback_name = '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: |
| conf.loopback_name = old_loopback |
| conf.iface = old_iface |
| conf.route.routes = old_routes |
| conf.route.invalidate_cache() |
| |
| |
| = Mocked IPv6 routes calls |
| |
| old_iface = conf.iface |
| old_loopback = conf.loopback_name |
| try: |
| conf.route6.ipv6_ifaces = set(['enp3s0', 'wlan0', 'lo']) |
| conf.iface = 'enp3s0' |
| conf.loopback_name = '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: |
| conf.loopback_name = old_loopback |
| conf.iface = old_iface |
| conf.route6.resync() |
| |
| = Find a link-local address when conf.iface does not support IPv6 |
| |
| old_iface = conf.iface |
| conf.route6.ipv6_ifaces = set(['eth1', 'lo']) |
| conf.iface = "eth0" |
| conf.route6.routes = [("fe80::", 64, "::", "eth1", ["fe80::a00:28ff:fe07:1980"], 256), ("::1", 128, "::", "lo", ["::1"], 0), ("fe80::a00:28ff:fe07:1980", 128, "::", "lo", ["::1"], 0)] |
| assert(conf.route6.route("fe80::2807") == ("eth1", "fe80::a00:28ff:fe07:1980", "::")) |
| conf.iface = old_iface |
| conf.route6.resync() |
| |
| = Windows: reset routes properly |
| |
| if WINDOWS: |
| from scapy.arch.windows import _route_add_loopback |
| _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) |
| |
| = Dissect VXLAN with no NextProtocol |
| pkt = VXLAN(b'\x08\x00\x00\x00\x00"H\x00\xcaF\xae\x10\xed\x0f\x0c\x00\x00\x00\x00\x00\x08\x06\x00\x01\x08\x00\x06\x04\x00\x02\x0c\x00\x00\x00\x00\x00\x7f\xff\xff\xfe\x11"3DUf\x7f\x00\x00\x02') |
| |
| assert pkt.NextProtocol is None |
| assert Ether in pkt |
| assert ARP in pkt |
| |
| ############ |
| ############ |
| ############ |
| + 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) |
| def fileno(self): |
| return -1 |
| def close(self): |
| return |
| |
| |
| 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) |
| def fileno(self): |
| return -1 |
| def close(self): |
| return |
| |
| |
| 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) |
| def fileno(self): |
| return -1 |
| def close(self): |
| return |
| |
| |
| 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 IPv6 - build |
| s6 = raw(IPv6()/VRRPv3()) |
| s6 == b'`\x00\x00\x00\x00\x08p@\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\x011\x01d\x01\x00dj\x1f' |
| |
| = VRRP IPv6 - dissection |
| p6 = IPv6(s6) |
| VRRPv3 in p6 and p6[VRRPv3].chksum == 0x6a1f |
| |
| = 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 |
| |
| = VRRP IPv6 - chksums |
| # VRRPv3 IPv6 |
| p = Ether(src="00:00:5e:00:02:02",dst="33:33:00:00:00:12")/IPv6(src="2001:db8::1", dst="ff02::12",hlim=255)/VRRPv3(priority=254,vrid=2,version=3,adv=1,ipcount=2,addrlist=["2001:db8::2","2001:db8::3"]) |
| c = Ether(raw(p)) |
| assert c[VRRPv3].chksum == 0x481b |
| |
| ############ |
| ############ |
| + 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\x14\x00#U\xb3\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]) == RadiusAttr_User_Name) |
| 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'I\x85l\x8f\xa5\xd6\xbc\xb5\x08\xe0<\xebH\x9d\xfb?' |
| |
| = 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]) == RadiusAttr_User_Name) |
| 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) |
| |
| = RADIUS - attributes with IPv4 addresses |
| |
| r = raw(RadiusAttr_NAS_IP_Address()) |
| p = RadiusAttr_NAS_IP_Address(r) |
| assert p.type == 4 |
| |
| r = raw(RadiusAttr_Framed_IP_Address()) |
| p = RadiusAttr_Framed_IP_Address(r) |
| assert p.type == 8 |
| |
| = RadiusAttr_User_Password |
| |
| r = b'\x01\x00\x00\x1c0x10x20x30x40x50\x02\x08geheim' |
| p = Radius(r) |
| assert isinstance(p.attributes[0], RadiusAttr_User_Password) |
| |
| ############ |
| ############ |
| + 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.*") |
| sum(1 for ip in n2) == 256 |
| assert n2.__iterlen__() == 256 |
| |
| n3 = Net("192.168.0.1-5") |
| sum(1 for ip in n3) == 5 |
| assert n3.__iterlen__() == 5 |
| |
| (n1 == n3) == False |
| |
| (n3 in n2) == True |
| |
| = Net using web address |
| ~ netaccess |
| |
| 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") |
| sum(1 for o in oid) == 3 |
| assert oid.__iterlen__() == 3 |
| |
| = Net6 |
| |
| n1 = Net6("2001:db8::/127") |
| sum(1 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() |
| |
| ip = IPv6(dst="www.yahoo.com") |
| addrs = [ip.dst, IPv6(raw(ip)).dst, [p.dst for p in ip][0]] |
| assert addrs[0] == addrs[1] == addrs[2] |
| |
| = 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 |
| |
| dummy_interface = get_dummy_interface() |
| |
| conf.route.routes = [ |
| (0, 0, '172.21.230.1', dummy_interface, '172.21.230.10', 1), # 0.0.0.0 / 0.0.0.0 == 255.255.255.255 |
| (2851995648, 4294901760, '0.0.0.0', dummy_interface, '172.21.230.10', 1), # 169.254.0.0 / 255.255.0.0 == 169.254.255.255 |
| (2887116288, 4294967040, '0.0.0.0', dummy_interface, '172.21.230.10', 1), # 172.21.230.0 / 255.255.255.0 == 172.21.230.255 |
| (2887116289, 4294967295, '0.0.0.0', dummy_interface, '172.21.230.10', 1), # 172.21.230.1 / 255.255.255.255 == 172.21.230.1 |
| (3758096384, 4026531840, '0.0.0.0', dummy_interface, '172.21.230.10', 1), # 224.0.0.0 / 240.0.0.0 == 239.255.255.255 |
| (3758096635, 4294967295, '0.0.0.0', dummy_interface, '172.21.230.10', 1), # 224.0.0.251 / 255.255.255.255 == 224.0.0.251 |
| (4294967295, 4294967295, '0.0.0.0', dummy_interface, '172.21.230.10', 1), # 255.255.255.255 / 255.255.255.255 == 255.255.255.255 |
| ] |
| |
| assert sorted(conf.route.get_if_bcast(dummy_interface)) == sorted(['169.254.255.255', '172.21.230.255', '239.255.255.255']) |
| conf.route.resync() |
| |
| ############ |
| ############ |
| + Random objects |
| |
| = RandomEnumeration |
| |
| ren = RandomEnumeration(0, 7, seed=0x2807, forever=False) |
| [x for x in ren] == ([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) |
| rex = RandRegExp("[g-v]* @? [0-9]{3} . (g|v)") |
| bytes(rex) == ('vmuvr @ 906 \x9e g' if six.PY2 else b'irrtv @ 517 \xc2\xb8 v') |
| |
| rex = RandRegExp("[:digit:][:space:][:word:]") |
| assert re.match(b"\\d\\s\\w", bytes(rex)) |
| |
| = 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 |
| random.seed(0x2807) |
| rek = RandEnumKeys({'a': 1, 'b': 2, 'c': 3}, seed=0x2807) |
| rek.enum.sort() |
| r = str(rek) |
| r |
| assert(r == ('c' if six.PY2 else 'a')) |
| |
| = RandSingNum |
| random.seed(0x2807) |
| rs = RandSingNum(-28, 7)._fix() |
| rs |
| assert(rs in [2, 3]) |
| |
| = 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"] |
| |
| = Various volatiles |
| |
| random.seed(0x2807) |
| assert RandNumGamma(1, 42)._fix() in (8, 73) |
| |
| random.seed(0x2807) |
| assert RandNumGauss(1, 42) == 8 |
| |
| print("RandEnum()", RandEnum(1, 42, seed=0x2807)._fix()) |
| assert RandEnum(1, 42, seed=0x2807) == (13 if six.PY2 else 37) |
| |
| print("RandPool()", RandPool((IncrementalValue(), 42), (IncrementalValue(), 0))._fix()) |
| assert RandPool((IncrementalValue(), 42), (IncrementalValue(), 0)) == 0 |
| |
| print("DelayedEval()", DelayedEval("3 + 1")._fix()) |
| assert DelayedEval("3 + 1") == 4 |
| |
| v = IncrementalValue(restart=2) |
| assert v == 0 and v == 1 and v == 2 and v == 0 |
| |
| |
| ############ |
| ############ |
| + 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 |
| |
| |
| ############ |
| ############ |
| + 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(0x2809) |
| assert str(RandDHCPOptions(size=1)) in [r"[('NIS_server', '0.45.231.69')]", r"[('ieee802-3-encapsulation', 229)]"] |
| |
| = DHCPOptionsField |
| |
| value = [("hostname", "scapy")] |
| dhcpoptfield = DHCPOptionsField("options", "") |
| assert dhcpoptfield.i2repr("", value) == "[hostname='scapy']" |
| assert dhcpoptfield.i2repr("", ["opt", "opt2"]) == "[opt opt2]" |
| assert dhcpoptfield.i2m("", value) == b'\x0c\x05scapy' |
| assert dhcpoptfield.m2i("", b'\x0cunknown') == [b'\x0cunknown'] |
| assert dhcpoptfield.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' |
| |
| s3 = raw(IP(src="127.0.0.1")/UDP()/BOOTP(chaddr="05:04:03:02:01:00")/DHCP(options=[("time_zone",123),("uap-servers","www.example.com"),("netinfo-server-address","10.0.0.1"), |
| ("ieee802-3-encapsulation", 2),("max_dgram_reass_size", 120), ("pxelinux_path_prefix","/some/path"), "end"])) |
| assert s3 == b'E\x00\x01=\x00\x01\x00\x00@\x11{\xad\x7f\x00\x00\x01\x7f\x00\x00\x01\x00C\x00D\x01)\x04i\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\x82Sc\x02\x04\x00\x00\x00{b\x0fwww.example.comp\x04\n\x00\x00\x01$\x01\x02\x16\x02\x00x\xd2\n/some/path\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") |
| |
| p3 = IP(s3) |
| assert DHCP in p3 |
| assert p3[DHCP].options[0] == ("time_zone",123) |
| assert p3[DHCP].options[1] == ("uap-servers", b'www.example.com') |
| assert p3[DHCP].options[2] == ("netinfo-server-address", "10.0.0.1") |
| assert p3[DHCP].options[3] == ("ieee802-3-encapsulation", 2) |
| assert p3[DHCP].options[4] == ("max_dgram_reass_size", 120) |
| assert p3[DHCP].options[5] == ("pxelinux_path_prefix", b'/some/path') |
| assert p3[DHCP].options[6] == "end" |
| |
| ############ |
| ############ |
| + 802.11 |
| ~ dot11 |
| |
| = 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 |
| |
| = Dot11TKIP - dissection |
| |
| pkt = RadioTap(b'\x00\x00\x0f\x00*\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x08B\x00\x00\xff\xff\xff\xff\xff\xff\xfe\xec\xda\x1d\xa3M\x00\x04t\x14\x02BP+\x01!\x00\xa0\x01!\x00\xa0\x01!\x00\xa0\x00\x00\x00\x00\xb0\xb6sN\xbdl9S\xc3x\x9d\xa6TEp\xcd(\xebht{\xff9\x9a[\x0f~\x00\xf8&m$\x1e\xd2[dXn\x16\x8526G\x8c\x88\xc3B\xc9\xda^\xc5w\xa5 \x9a\xa0 \x08') |
| assert Dot11TKIP in pkt |
| |
| assert pkt[Dot11TKIP].TSC1 == 1 |
| assert pkt[Dot11TKIP].WEPSeed == 33 |
| assert pkt[Dot11TKIP].TSC0 == 0 |
| assert pkt[Dot11TKIP].key_id == 2 |
| assert pkt[Dot11TKIP].ext_iv == 1 |
| assert pkt[Dot11TKIP].res == 0 |
| assert pkt[Dot11TKIP].TSC2 == 1 |
| assert pkt[Dot11TKIP].TSC3 == 33 |
| assert pkt[Dot11TKIP].TSC4 == 0 |
| assert pkt[Dot11TKIP].TSC5 == 160 |
| |
| = Dot11CCMP - dissection |
| |
| pkt = RadioTap(b'\x00\x00\x0f\x00*\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x08b\x00\x00\x01\x00^\x7f\xff\xfa\x0e\xec\xda\x1d\xa3M\x00\x0eX7\xbe\xbe\x00\x8aD#\x00\xa0D#\x00\xa0\x00\x00\x00\x00c\xb7\rv/s\x88N;>\x07\x0e\xe5\xd9\xf5\xfa\xcdD\xc2he\xfc\xc5^m\xae\xf2\xfe\xf9\xb06\xce\rt\xbe\x9d(\xb5\x98\x848NU\x0f\x93\x0f]m\xa2\x96\x80{\x95\x00\xb5\x98Y!\xa3^\xfc\xda\xca.R\xf3\xd3\xf8^\xeda\x88\x82p\xc6\xb8L\x0b\x815-\x85(\xb1F\xd5K\x166dJ\xc7\x04B\xdb\xec\x8d\xb7:{\x0f\'g<\x06\xd07>\xde\xad\x08\xcb\xffr\xfa\xf4}o\xe9\xa9b\xa5)\x87\x90\xa5{\xe1\xea\x0f\x0fGf`x1\xbd\xc1\xe8\xa0\xb6(\x05gq\xf3\x99\x9e\x93\xde\'\x8e\nQ\xf7\xad\xf7\x89"\xee\xcf\xe8$\x8a\x9c\xb4\xe6\x03\xab\x9ec\xd0\xd5\x08\xca\xd2\xbb\xae\xcc\x9c$R\xbc\xcdFO?\xc3Ah\x9ch\xd4\x9b)m\xea\xbab+\'\x06I2\xb5!\xdb\x03\xbe\xb8\xb2\x86\x0f\x80\n\xbc\x85\x02\xb4T\x00\x00\xc7|\xac\xc0B\xb2\x89\xbb\xc5\xc0\x93\x858\xe3Q\xf9\t\xff4\xdb\x9a>\xe5O-e\x16\x81w!9m\xb9dZ\xaa\xaa0\x9cW\xaa\xa3\xf1\xdd\xecW\xdd\xc41D\xe6\xba\xf3SQ\x81S\xf6\xbd\xe3\xc0e\xba\xa0*\x15%\x9cz0\xa8\xa6l\x8e\x0c(\xd3\xe4\xa2\xf9\xc2:Yae#T\x8d\xef\x01\xfad\x05/\xdb\xf2!D\xde~\x0f\x99\xf6U\xf5\xbf\xd0\xaf\xbe0\xf7\xf03\xa8s`\x8d>4\x98\xb5Y\x06dXFz\x88\x82\'B\x84\xe6\xca\x05\x02\xd5G\xb6\x11\xed <\xb1\xd4\xc9\xa9\xaa\xae\xc9\xb3g\xbc\xfd+\xe7\x1aG\x92\x17\xdb\xce\xf7\x843\xce4\xc4w\x8f\x8a\x83\xf0\'\xfe\x87\x14\x95\xd3\x0bM\xbaL$\xc8\x8d\' 8\x87c 3yt\xc5\xeeN\xc9\xe1\x95\x1d\xe9\xddh\x87E\x07\xe5\x86\xc7\x82\x8a\x88\x05\xa4\x06\xb1\x0c\xddV\xd0\xf0d\xc8\xcet`\xc5C\xcb\x8f\x06]A\x92\x1a\xae5wc\x8dN\xa2\xf0}aJ\x9c\x8e\xd1\xb2[*\xffK\x0f\xf8u\xd5\x84#\xc3"\xffX\x9f\xffC\x0fb\x02n\x1b\xbaAr\x93\xe1\xb7\x1f\x8e\x1c\xfev]w\xaa\xcch\x8c{lm\xb9\x9aE\x08\x1d\xc28u\x82\xa8\xbe\xf2\xb3\x11\xdc\x90 \x83\xa7\x9c*:\x01R\xcf\xd6\xc6~\x989\x9a5\xc97\xfa\x10<x|kQ5\xa1S\x17\x1a\xc1\x83\xa03\xec\xf0h8\xfbZA\x03"&p\x99\n\x01\x9c\xa9\xd9\xff\xdf\'n$K8t\x0br_\xce^\xf3\xf4v\xff\x11\xde\xc7Wo\xe9\xaf%\x02UM\xb5l\xb9\x88=x\x87\xfamH\xb2;7|\x99C\xb6{}n_Z\xc7i\\:D\xdd\x87\xf3\\e\xdeH\x1b~9\xcb\xaeg\x99\xde4\xcf9\xe9\xc8\x8f\x87DLz\xe0\xa4\xca\x04\xa2\x93\xaf\x80g\xfb\x9d\xb8\xa8y\xb8K\xaa\x8b2\xfe\xfb\x90+\x0e\xcc_J\x13\xe5,\x12\x9a>\xe4!uEP\x968\x00*\xd0\xefE\xf8{\x1d(\xcb\xe3IR\\r\xee\x9fU\x14\ty\xe3\xdc\x96@\xf4\x8d\x17\xab\xcc\x98I\x8e\xe16\x9e\xa5+\xe0\xa8{S\x051##\x90:A') |
| assert Dot11CCMP in pkt |
| |
| assert pkt[Dot11CCMP].PN0 == 68 |
| assert pkt[Dot11CCMP].PN1 == 35 |
| assert pkt[Dot11CCMP].res0 == 0 |
| assert pkt[Dot11CCMP].key_id == 2 |
| assert pkt[Dot11CCMP].ext_iv == 1 |
| assert pkt[Dot11CCMP].res1 == 0 |
| assert pkt[Dot11CCMP].PN2 == 68 |
| assert pkt[Dot11CCMP].PN3 == 35 |
| assert pkt[Dot11CCMP].PN4 == 0 |
| assert pkt[Dot11CCMP].PN5 == 160 |
| |
| = 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)) |
| |
| = Dot11Beacon network_stats() |
| |
| data = b'\x00\x00\x12\x00.H\x00\x00\x00\x02\x8f\t\xa0\x00\x01\x01\x00\x00\x80\x00\x00\x00\xff\xff\xff\xff\xff\xffDH\xc1\xb7\xf0uDH\xc1\xb7\xf0u\x10\xb7\x00\x00\x00\x00\x00\x00\x00\x00\x90\x01\x11\x00\x00\x06SSID76\x01\n\x82\x84\x0c\x12\x18$0H`l\x03\x01\x080\x18\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x02\x01\x00\x00\x0f\xac\x02\x0c\x00\x07\tUSI\x01\x18\x00\n\x05\xe7' |
| pkt = RadioTap(data) |
| nstats = pkt[Dot11Beacon].network_stats() |
| nstats |
| assert nstats == { |
| 'channel': 8, |
| 'crypto': {'WPA2/PSK'}, |
| 'rates': [130, 132, 12, 18, 24, 36, 48, 72, 96, 108], |
| 'ssid': 'SSID76', |
| 'country': 'US', |
| 'country_desc_type': 'Indoor' |
| } |
| |
| data = b'\x00\x00\x16\x00\x0f\x00\x00\x00|P\xb1\x82\xae\x86\x05\x00\x00\x02l\t\xa0\x00\x80\x00\x00\x00\xff\xff\xff\xff\xff\xff\x02\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00:Q\xb1\x82\xae\x86\x05\x00d\x00\x11\x04\x00\x0cWPA3-Network\x01\x08\x82\x84\x8b\x96\x0c\x12\x18$\x03\x01\x01\x05\x04\x00\x02\x00\x00*\x01\x042\x040H`l0\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x08\xc0\x00;\x02Q\x00\x7f\x08\x04\x00\x00\x00\x00\x00\x00@' |
| pkt = RadioTap(data) |
| nstats = pkt[Dot11Beacon].network_stats() |
| nstats |
| assert nstats == { |
| 'ssid': 'WPA3-Network', |
| 'rates': [130, 132, 139, 150, 12, 18, 24, 36], |
| 'channel': 1, |
| 'crypto': {'WPA3/SAE'} |
| } |
| |
| |
| = Dot11EltCountry dissection |
| |
| data = b"\x00\x00&\x00/@\x00\xa0 \x08\x00\xa0 \x08\x00\x00R\xa9[#\x00\x00\x00\x00\x10\x18\x85\t\xc0\x00\xc8\x00\x00\x00\xc3\x00\xc7\x01P\x080\x00V\x9cm\xf4\xb1\xe9\xa0\xcf[\xfb%0\xa0\xcf[\xfb%0\xa0R&\x1a@\xc2\x06\x03\x00\x00f\x00!\x14\x00\x1eDisney Convention Center Guest\x01\x07\x12\x98$0H`l\x03\x01\x06\x07\x06US \x01\x0b\x1e\x0b\x05\n\x00\x8a\x8d[ \x01\x03*\x01\x00-\x1a,\x18\x1b\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x03*L\x01=\x16\x06\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\x05s\xc0\x00\x00\x00\x7f\x06\x00\x10\x00\x04\x01@\x85\x1e\x10\x00\x8f\x00\x0f\x00\xff\x03Y\x001617-AP33-SorcA\x00\n\x00\x00:\x96\x06\x00@\x96\x00\x0b\x00\xdd\x18\x00P\xf2\x02\x01\x01\x80\x00\x03\xa4\x00\x00'\xa4\x00\x00BC^\x00b2/\x00\xdd\x06\x00@\x96\x01\x01\x04\xdd\x05\x00@\x96\x03\x05\xdd\x05\x00@\x96\x0bI\xdd\x05\x00@\x96\x14\x00dZ\x97\xbf" |
| pkt = RadioTap(data) |
| assert pkt[Dot11EltCountry].info == b'US \x01\x0b\x1e' |
| assert len(pkt[Dot11EltCountry].descriptors) == 1 |
| assert pkt[Dot11EltCountry].descriptors[0].mtp == 30 |
| |
| * Country element: padding check |
| data = hex_bytes('00001a002f48000017cd9f3100000000000c3c144001e000000080000000ffffffffffff461b860bef06461b860bef06909403e0f75b0000000064001105000c4c697665626f782d3232353001088c1218243048606c0301240504020300000728504c202401172801172c01173001173401173801173c011740011764011e68011e6c011e70011e000b05000002ffff46050000000000200100c30502171717002a01002d1aef0117fffffffffeffffffff1f000001000000000018e6e719003d1624050000000000000000000000000000000000000000dd180050f2020101840003a4000027a4000042435e0062322f0030140100000fac040100000fac040100000fac020000bf0cb279c33faaff0000aaff0000c005012a00fcffdd1e002686010300dd00000025040592000601d15b5816830000000000000000dd06002686170000dd0e00268618010101024c1b860bef067f080100080200000040dd3b0050f204104a0001101044000102105700010110470010344331423836f042f546303634433142103c000103103c0001031049000600372a000120') |
| pkt = RadioTap(data) |
| assert pkt[Dot11EltCountry].pad == 0 |
| assert pkt.getlayer(Dot11Elt, ID=11) |
| |
| * Country element: Secondary padding check |
| erp_payload = b'\x1e\x2a\x01\x62' |
| country_payload = b'\x07\x06\x55\x53\x20\x01\x0b' |
| |
| bare_country = Dot11EltCountry(country_payload) |
| country_nested = Dot11EltCountry(country_payload + erp_payload) |
| |
| assert not bare_country.payload |
| assert country_nested.payload |
| assert country_nested.payload.ID == 42 |
| |
| = 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.pre_auth |
| assert Dot11Elt in rsn_ie |
| |
| pkt = RadioTap(b"\x00\x000\x00/@\x00\xa0 \x08\x00\xa0 \x08\x00\xa0 \x08\x00\x00\x00\x00\x00\x00\x0bpin;%\xedN\x10\x0cl\t\xc0\x00\xce\x00\x00\x00\xb2\x00\xbd\x01\xce\x02\x80\x00\x00\x00\xff\xff\xff\xff\xff\xff\xec\x17/\x82\x1e)\xec\x17/\x82\x1e)\x10p\x81a\xa1\x08\x00\x00\x00\x00d\x001\x04\x00\rROUTE-821E295\x01\x01\x8c\x03\x01\x01\x05\x04\x00\x02\x00\x00\x07$IL \x01\x01\x14\x02\x01\x14\x03\x01\x14\x04\x01\x14\x05\x01\x14\x06\x01\x14\x07\x01\x14\x08\x01\x14\t\x01\x14\n\x01\x14\x0b\x01\x14;\x12QQRSTstuvwxyz{}~\x7f\x80*\x01\x000\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\x8c\x00\x00\x00\x00\x0f\xac\x06-\x1a\x8d\x01\x1f\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x16\x01\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\x18\x00P\xf2\x02\x01\x01\x81\x00\x03\xa4\x00\x00'\xa4\x00\x00BT^\x00a2/\x00\x7f\x01\x04\xdd\x07\x00\xa0\xc6\x02\x02\x03\x00\xdd\x17\xec\x17/RRRRRRRRRRRRRRRRRRRRR\x9e[\xf2") |
| assert Dot11EltRSN in pkt |
| assert pkt[Dot11Beacon].network_stats() == { |
| 'ssid': 'ROUTE-821E295', |
| 'rates': [140], |
| 'channel': 1, |
| 'country': 'IL', |
| 'country_desc_type': None, |
| 'crypto': {'WPA2/PSK'} |
| } |
| assert [x.ID for x in pkt[Dot11Elt].iterpayloads()] == [0, 1, 3, 5, 7, 59, 42, 48, 45, 61, 221, 127, 221, 221] |
| assert pkt.pmkids.nb_pmkids == 0 |
| assert pkt.group_management_cipher_suite.oui == 0xfac |
| assert pkt.group_management_cipher_suite.cipher == 0x6 |
| |
| = 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(sum(1 for k in six.itervalues(conf.mib.__dict__) if "scapy" in k) == 1) |
| |
| assert(sum(1 for oid in conf.mib) > 100) |
| |
| = 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() |
| |
| = MIB - test aliases |
| ~ mib |
| |
| # https://github.com/secdev/scapy/issues/2542 |
| assert conf.mib._oidname("2.5.29.19") == "basicConstraints" |
| |
| = DADict tests |
| |
| a = DADict("test") |
| a[0] = "test_value1" |
| a["scapy"] = "test_value2" |
| |
| assert a.test_value1 == 0 |
| assert a.test_value2 == "scapy" |
| |
| with ContextManagerCaptureOutput() as cmco: |
| a._show() |
| outp = cmco.get_output() |
| |
| assert "scapy = 'test_value2'" in outp |
| assert "0 = 'test_value1'" in outp |
| |
| = Test ETHER_TYPES |
| |
| assert ETHER_TYPES.IPv4 == 2048 |
| try: |
| import warnings |
| |
| with warnings.catch_warnings(record=True) as w: |
| warnings.simplefilter("always") |
| ETHER_TYPES["BAOBAB"] = 0xffff |
| assert ETHER_TYPES.BAOBAB == 0xffff |
| assert issubclass(w[-1].category, DeprecationWarning) |
| except DeprecationWarning: |
| # -Werror is used |
| pass |
| |
| = 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) |
| |
| = BER trigger failures |
| |
| try: |
| BERcodec_INTEGER.do_dec(b"\x02\x01") |
| assert False |
| except BER_Decoding_Error: |
| pass |
| |
| ############ |
| ############ |
| + 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 |
| ~ netaccess |
| |
| @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 |
| |
| = Simple Ether() / ARP() show |
| (Ether() / ARP()).show() |
| |
| = 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) |
| |
| p = ARP(pdst='192.168.178.0/24') |
| assert "Net" in repr(p) |
| |
| |
| ############ |
| ############ |
| + 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" |
| |
| + UUIDField |
| |
| = Parsing a human-readable UUID |
| f = UUIDField('f', '01234567-89ab-cdef-0123-456789abcdef') |
| f.addfield(None, b'', f.default) == hex_bytes('0123456789abcdef0123456789abcdef') |
| |
| = Parsing a machine-encoded UUID |
| f = UUIDField('f', bytearray.fromhex('0123456789abcdef0123456789abcdef')) |
| f.addfield(None, b'', f.default) == hex_bytes('0123456789abcdef0123456789abcdef') |
| |
| = Parsing a tuple of values |
| f = UUIDField('f', (0x01234567, 0x89ab, 0xcdef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef)) |
| f.addfield(None, b'', f.default) == hex_bytes('0123456789abcdef0123456789abcdef') |
| |
| = Handle None values |
| f = UUIDField('f', None) |
| f.addfield(None, b'', f.default) == hex_bytes('00000000000000000000000000000000') |
| |
| = Get a UUID for dissection |
| from uuid import UUID |
| f = UUIDField('f', None) |
| f.getfield(None, bytearray.fromhex('0123456789abcdef0123456789abcdef01')) == (b'\x01', UUID('01234567-89ab-cdef-0123-456789abcdef')) |
| |
| = Verify little endian UUIDField |
| * The endianness of a UUIDField should be apply by block on each block in parenthesis '(01234567)-(89ab)-(cdef)-(01)(23)-(45)(67)(89)(ab)(cd)(ef)' |
| f = UUIDField('f', '01234567-89ab-cdef-0123-456789abcdef', uuid_fmt=UUIDField.FORMAT_LE) |
| f.addfield(None, b'', f.default) == hex_bytes('67452301ab89efcd0123456789abcdef') |
| |
| = Verify reversed UUIDField |
| * This should reverse the entire value as 128-bits |
| f = UUIDField('f', '01234567-89ab-cdef-0123-456789abcdef', uuid_fmt=UUIDField.FORMAT_REV) |
| f.addfield(None, b'', f.default) == hex_bytes('efcdab8967452301efcdab8967452301') |
| |
| + RandUUID |
| |
| = RandUUID setup |
| |
| RANDUUID_TEMPLATE = '01234567-89ab-*-01*-*****ef' |
| RANDUUID_FIXED = uuid.uuid4() |
| |
| = RandUUID default behaviour |
| |
| u = RandUUID()._fix() |
| u.version == 4 |
| |
| = RandUUID incorrect implicit args |
| |
| expect_exception(ValueError, lambda: RandUUID(node=0x1234, name="scapy")) |
| expect_exception(ValueError, lambda: RandUUID(node=0x1234, namespace=uuid.uuid4())) |
| expect_exception(ValueError, lambda: RandUUID(clock_seq=0x1234, name="scapy")) |
| expect_exception(ValueError, lambda: RandUUID(clock_seq=0x1234, namespace=uuid.uuid4())) |
| expect_exception(ValueError, lambda: RandUUID(name="scapy")) |
| expect_exception(ValueError, lambda: RandUUID(namespace=uuid.uuid4())) |
| |
| = RandUUID v4 UUID (correct args) |
| |
| u = RandUUID(version=4)._fix() |
| u.version == 4 |
| |
| u2 = RandUUID(version=4)._fix() |
| u2.version == 4 |
| |
| str(u) != str(u2) |
| |
| = RandUUID v4 UUID (incorrect args) |
| |
| expect_exception(ValueError, lambda: RandUUID(version=4, template=RANDUUID_TEMPLATE)) |
| expect_exception(ValueError, lambda: RandUUID(version=4, node=0x1234)) |
| expect_exception(ValueError, lambda: RandUUID(version=4, clock_seq=0x1234)) |
| expect_exception(ValueError, lambda: RandUUID(version=4, namespace=uuid.uuid4())) |
| expect_exception(ValueError, lambda: RandUUID(version=4, name="scapy")) |
| |
| = RandUUID v1 UUID |
| |
| u = RandUUID(version=1)._fix() |
| u.version == 1 |
| |
| u = RandUUID(version=1, node=0x1234)._fix() |
| u.version == 1 |
| u.node == 0x1234 |
| |
| u = RandUUID(version=1, clock_seq=0x1234)._fix() |
| u.version == 1 |
| u.clock_seq == 0x1234 |
| |
| u = RandUUID(version=1, node=0x1234, clock_seq=0x1bcd)._fix() |
| u.version == 1 |
| u.node == 0x1234 |
| u.clock_seq == 0x1bcd |
| |
| = RandUUID v1 UUID (implicit version) |
| |
| u = RandUUID(node=0x1234)._fix() |
| u.version == 1 |
| u.node == 0x1234 |
| |
| u = RandUUID(clock_seq=0x1234)._fix() |
| u.version == 1 |
| u.clock_seq == 0x1234 |
| |
| u = RandUUID(node=0x1234, clock_seq=0x1bcd)._fix() |
| u.version == 1 |
| u.node == 0x1234 |
| u.clock_seq == 0x1bcd |
| |
| = RandUUID v1 UUID (incorrect args) |
| |
| expect_exception(ValueError, lambda: RandUUID(version=1, template=RANDUUID_TEMPLATE)) |
| expect_exception(ValueError, lambda: RandUUID(version=1, namespace=uuid.uuid4())) |
| expect_exception(ValueError, lambda: RandUUID(version=1, name="scapy")) |
| |
| = RandUUID v5 UUID |
| |
| u = RandUUID(version=5, namespace=RANDUUID_FIXED, name="scapy")._fix() |
| u.version == 5 |
| |
| u2 = RandUUID(version=5, namespace=RANDUUID_FIXED, name="scapy")._fix() |
| u2.version == 5 |
| u.bytes == u2.bytes |
| |
| # implicit v5 |
| u2 = RandUUID(namespace=RANDUUID_FIXED, name="scapy")._fix() |
| u.bytes == u2.bytes |
| |
| = RandUUID v5 UUID (incorrect args) |
| |
| expect_exception(ValueError, lambda: RandUUID(version=5, template=RANDUUID_TEMPLATE)) |
| expect_exception(ValueError, lambda: RandUUID(version=5, node=0x1234)) |
| expect_exception(ValueError, lambda: RandUUID(version=5, clock_seq=0x1234)) |
| |
| = RandUUID v3 UUID |
| |
| u = RandUUID(version=3, namespace=RANDUUID_FIXED, name="scapy")._fix() |
| u.version == 3 |
| |
| u2 = RandUUID(version=3, namespace=RANDUUID_FIXED, name="scapy")._fix() |
| u2.version == 3 |
| u.bytes == u2.bytes |
| |
| # implicit v5 |
| u2 = RandUUID(namespace=RANDUUID_FIXED, name="scapy")._fix() |
| u.bytes != u2.bytes |
| |
| = RandUUID v3 UUID (incorrect args) |
| |
| expect_exception(ValueError, lambda: RandUUID(version=5, template=RANDUUID_TEMPLATE)) |
| expect_exception(ValueError, lambda: RandUUID(version=5, node=0x1234)) |
| expect_exception(ValueError, lambda: RandUUID(version=5, clock_seq=0x1234)) |
| |
| = RandUUID looks like a UUID with str |
| re.match(r'[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}', str(RandUUID()), re.I) is not None |
| |
| = RandUUID with a static part |
| * RandUUID template can contain static part such a 01234567-89ab-*-01*-*****ef |
| re.match(r'01234567-89ab-[0-9a-f]{4}-01[0-9a-f]{2}-[0-9a-f]{10}ef', str(RandUUID('01234567-89ab-*-01*-*****ef')), re.I) is not None |
| |
| = RandUUID with a range part |
| * RandUUID template can contain a part with a range of values such a 01234567-89ab-*-01*-****c0:c9ef |
| re.match(r'01234567-89ab-[0-9a-f]{4}-01[0-9a-f]{2}-[0-9a-f]{8}c[0-9]ef', str(RandUUID('01234567-89ab-*-01*-****c0:c9ef')), re.I) is not None |
| |
| ############ |
| ############ |
| + 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("scapy.utils.input") |
| 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 |
| |
| = import_hexcap(input_string) |
| 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:] |
| pkt = import_hexcap(data) |
| 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=".eps") |
| 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 |
| |
| = UTscapy HTML output |
| |
| import tempfile, os |
| from scapy.tools.UTscapy import TestCampaign, pack_html_campaigns |
| test_campaign = TestCampaign("test") |
| test_campaign.output_file = tempfile.mktemp() |
| html = pack_html_campaigns([test_campaign], None, local=True) |
| dirname = os.path.dirname(test_campaign.output_file) |
| filename_js = "%s/UTscapy.js" % dirname |
| filename_css = "%s/UTscapy.css" % dirname |
| assert os.path.isfile(filename_js) |
| assert os.path.isfile(filename_css) |
| os.remove(filename_js) |
| os.remove(filename_css) |
| |
| #= 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") |
| |
| = test get_temp_dir |
| |
| dname = get_temp_dir() |
| assert os.path.isdir(dname) |
| |
| = test fragleak functions |
| ~ netaccess linux fragleak |
| |
| import mock |
| |
| @mock.patch("scapy.layers.inet.conf.L3socket") |
| @mock.patch("scapy.layers.inet.select.select") |
| @mock.patch("scapy.layers.inet.sr1") |
| def _test_fragleak(func, sr1, select, L3socket): |
| packets = [IP(src="4.4.4.4")/ICMP()/IPerror(dst="8.8.8.8")/conf.padding_layer(load=b"greatdata")] |
| iterator = iter(packets) |
| ne = lambda *args, **kwargs: next(iterator) |
| L3socket.side_effect = lambda: Bunch(recv=ne, send=lambda x: None) |
| sr1.side_effect = ne |
| select.side_effect = lambda a, b, c, d: a+b+c |
| with ContextManagerCaptureOutput() as cmco: |
| func("8.8.8.8", count=1) |
| out = cmco.get_output() |
| return "greatdata" in out |
| |
| assert _test_fragleak(fragleak) |
| assert _test_fragleak(fragleak2) |