From b780de024607908b74055204d3e2f886dd031c79 Mon Sep 17 00:00:00 2001 From: Ryan Goodfellow Date: Fri, 3 Sep 2021 14:16:46 -0700 Subject: [PATCH] initial --- .cargo/config.toml | 8 + .gitignore | 1 + Cargo.lock | 2201 ++++++++++++++++++++++++++++++++++ Cargo.toml | 11 + README.md | 22 + icmpv6/Cargo.toml | 10 + icmpv6/src/lib.rs | 308 +++++ illumos/Cargo.toml | 22 + illumos/build.rs | 60 + illumos/src/illumos.rs | 11 + illumos/src/link.rs | 82 ++ illumos/src/main.rs | 33 + illumos/src/platform.rs | 285 +++++ illumos/wrapper.h | 20 + lab/Cargo.toml | 12 + lab/src/main.rs | 35 + platform/Cargo.toml | 11 + platform/src/error.rs | 20 + platform/src/lib.rs | 34 + rift/Cargo.toml | 19 + rift/src/admin.rs | 102 ++ rift/src/error.rs | 22 + rift/src/lib.rs | 96 ++ rift/src/link.rs | 122 ++ rift/src/rdp.rs | 69 ++ rift_protocol/Cargo.toml | 10 + rift_protocol/src/lib.rs | 45 + rust-toolchain.toml | 4 + tools/rdpx/Cargo.toml | 16 + tools/rdpx/src/main.rs | 170 +++ tools/rdpx/tests/rdp_test.rs | 79 ++ 31 files changed, 3940 insertions(+) create mode 100644 .cargo/config.toml create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 icmpv6/Cargo.toml create mode 100644 icmpv6/src/lib.rs create mode 100644 illumos/Cargo.toml create mode 100644 illumos/build.rs create mode 100644 illumos/src/illumos.rs create mode 100644 illumos/src/link.rs create mode 100644 illumos/src/main.rs create mode 100644 illumos/src/platform.rs create mode 100644 illumos/wrapper.h create mode 100644 lab/Cargo.toml create mode 100644 lab/src/main.rs create mode 100644 platform/Cargo.toml create mode 100644 platform/src/error.rs create mode 100644 platform/src/lib.rs create mode 100644 rift/Cargo.toml create mode 100644 rift/src/admin.rs create mode 100644 rift/src/error.rs create mode 100644 rift/src/lib.rs create mode 100644 rift/src/link.rs create mode 100644 rift/src/rdp.rs create mode 100644 rift_protocol/Cargo.toml create mode 100644 rift_protocol/src/lib.rs create mode 100644 rust-toolchain.toml create mode 100644 tools/rdpx/Cargo.toml create mode 100644 tools/rdpx/src/main.rs create mode 100644 tools/rdpx/tests/rdp_test.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..d7899423 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,8 @@ +[env] + +# falcon +LIBZFS_CORE_LOOKUP_WITH = "link" + +# reqwest +OPENSSL_LIB_DIR = "/usr/lib" +OPENSSL_INCLUDE_DIR = "/usr/include/openssl-1.1" diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..eb5a316c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..941382d8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2201 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" + +[[package]] +name = "async-trait" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bindgen" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453c49e5950bb0eb63bb3df640e31618846c89d5b7faa54040d76e98e0134375" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap 2.33.3", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "build-env" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1522ac6ee801a11bf9ef3f80403f4ede6eb41291fac3dde3de09989679305f25" + +[[package]] +name = "bumpalo" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cc" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" + +[[package]] +name = "cexpr" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "serde", + "time", + "winapi", +] + +[[package]] +name = "clang-sys" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cf2cc85830eae84823884db23c5306442a6c3d5bfd3beb2f2a2c829faa1816" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim 0.8.0", + "textwrap 0.11.0", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "3.0.0-beta.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim 0.10.0", + "termcolor", + "textwrap 0.14.2", + "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.0.0-beta.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "core-foundation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "cstr-argument" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20bd4e8067c20c7c3a4dea759ef91d4b18418ddb5bd8837ef6e2f2f93ca7ccbb" +dependencies = [ + "cfg-if 0.1.10", + "memchr", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "dropshot" +version = "0.5.2-dev" +source = "git+https://github.com/oxidecomputer/dropshot#28b04efe999fc6344c39d70225885a86b2de49e2" +dependencies = [ + "async-trait", + "base64", + "bytes", + "chrono", + "dropshot_endpoint", + "futures", + "hostname", + "http", + "hyper", + "indexmap", + "openapiv3", + "paste", + "percent-encoding", + "proc-macro2", + "schemars", + "serde", + "serde_json", + "serde_urlencoded", + "slog", + "slog-async", + "slog-bunyan", + "slog-json", + "slog-term", + "syn", + "tokio", + "toml", + "uuid", +] + +[[package]] +name = "dropshot_endpoint" +version = "0.5.2-dev" +source = "git+https://github.com/oxidecomputer/dropshot#28b04efe999fc6344c39d70225885a86b2de49e2" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_tokenstream", + "syn", +] + +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "encoding_rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.0", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63f713f8b2aa9e24fec85b0e290c56caee12e3b6ae0aeeda238a75b28251afd6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684cf33bb7f28497939e8c7cf17e3e4e3b8d9a0080ffa4f8ae2f515442ee855" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "fs2" +version = "0.4.3" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "futures" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" + +[[package]] +name = "futures-executor" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" + +[[package]] +name = "futures-macro" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" + +[[package]] +name = "futures-task" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" + +[[package]] +name = "futures-util" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "h2" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" + +[[package]] +name = "httpdate" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13f67199e765030fa08fe0bd581af683f0d5bc04ea09c2b1102012c5fb90e7fd" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "icmpv6" +version = "0.1.0" +dependencies = [ + "schemars", + "serde", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "illumos" +version = "0.1.0" +dependencies = [ + "bindgen", + "dropshot", + "icmpv6", + "platform", + "reqwest", + "rift", + "rift_protocol", + "slog", + "slog-async", + "slog-term", + "socket2", + "tokio", +] + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "ipnet" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" + +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "js-sys" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lab" +version = "0.1.0" +dependencies = [ + "anyhow", + "libfalcon", + "zfs-core", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" + +[[package]] +name = "libfalcon" +version = "0.1.0" +dependencies = [ + "anyhow", + "bindgen", + "fs2", + "nvpair", + "regex", + "smf", + "thiserror", + "zfs-core", + "zone", +] + +[[package]] +name = "libloading" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +dependencies = [ + "cfg-if 1.0.0", + "winapi", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mio" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "native-tls" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nom" +version = "6.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +dependencies = [ + "bitvec", + "funty", + "memchr", + "version_check", +] + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "nvpair" +version = "0.5.0" +source = "git+https://github.com/oxidecomputer/rust-libzfs#e79f612c116eb752827d0a7f581b99eab288d709" +dependencies = [ + "cstr-argument", + "foreign-types 0.5.0", + "nvpair-sys", +] + +[[package]] +name = "nvpair-sys" +version = "0.4.0" +source = "git+https://github.com/oxidecomputer/rust-libzfs#e79f612c116eb752827d0a7f581b99eab288d709" + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "openapiv3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90228d34f20d9fff3174d19b0d41e67f52711045270b540a2a2c2dc41ccb4085" +dependencies = [ + "indexmap", + "serde", + "serde_json", + "serde_yaml", +] + +[[package]] +name = "openssl" +version = "0.10.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +dependencies = [ + "bitflags", + "cfg-if 1.0.0", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-probe" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" + +[[package]] +name = "openssl-sys" +version = "0.9.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "os_str_bytes" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "paste" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "platform" +version = "0.1.0" +dependencies = [ + "icmpv6", + "rift_protocol", + "thiserror", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rdpx" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 3.0.0-beta.4", + "icmpv6", + "libfalcon", + "rift", + "ron", + "serde", + "socket2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.3", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rift" +version = "0.1.0" +dependencies = [ + "dropshot", + "icmpv6", + "platform", + "rift_protocol", + "schemars", + "serde", + "slog", + "slog-async", + "slog-term", + "thiserror", + "tokio", +] + +[[package]] +name = "rift_protocol" +version = "0.1.0" +dependencies = [ + "schemars", + "serde", +] + +[[package]] +name = "ron" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "064ea8613fb712a19faf920022ec8ddf134984f100090764a4e1d768f3827f1f" +dependencies = [ + "base64", + "bitflags", + "serde", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustversion" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi", +] + +[[package]] +name = "schemars" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "schemars_derive" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "902fdfbcf871ae8f653bddf4b2c05905ddaabc08f69d32a915787e3be0d31356" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "security-framework" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_tokenstream" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3ce95257fba42a656f558db28d56a9fac5aa6e4f29c5ef607f32f524fab0ab" +dependencies = [ + "proc-macro2", + "serde", + "syn", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad104641f3c958dab30eb3010e834c2622d1f3f4c530fef1dee20ad9485f3c09" +dependencies = [ + "dtoa", + "indexmap", + "serde", + "yaml-rust", +] + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + +[[package]] +name = "slog" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" + +[[package]] +name = "slog-async" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "766c59b252e62a34651412870ff55d8c4e6d04df19b43eecb2703e417b097ffe" +dependencies = [ + "crossbeam-channel", + "slog", + "take_mut", + "thread_local", +] + +[[package]] +name = "slog-bunyan" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924f5e8b5a1069e484f6ad80024322990e21ee8399f12ba289e48cd30bc0dda0" +dependencies = [ + "chrono", + "hostname", + "slog", + "slog-json", +] + +[[package]] +name = "slog-json" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e9b96fb6b5e80e371423b4aca6656eb537661ce8f82c2697e619f8ca85d043" +dependencies = [ + "chrono", + "serde", + "serde_json", + "slog", +] + +[[package]] +name = "slog-term" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95c1e7e5aab61ced6006149ea772770b84a0d16ce0f7885def313e4829946d76" +dependencies = [ + "atty", + "chrono", + "slog", + "term", + "thread_local", +] + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "smf" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f19d427ae89311c2770c49fdcfa14627577c499311fe8f4cc8fcfde2dd3c4e2e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "snafu" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7" +dependencies = [ + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "socket2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765f090f0e423d2b55843402a07915add955e7d60657db13707a159727326cad" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand 0.8.4", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "textwrap" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4efe6fc2395938c8155973d7be49fe8d03a843726e285e100a8a383cc0154ce" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "unicode-bidi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.3", + "serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +dependencies = [ + "cfg-if 1.0.0", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" + +[[package]] +name = "web-sys" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winreg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +dependencies = [ + "winapi", +] + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zfs-core" +version = "0.5.0" +source = "git+https://github.com/oxidecomputer/rust-libzfs#e79f612c116eb752827d0a7f581b99eab288d709" +dependencies = [ + "cstr-argument", + "foreign-types 0.5.0", + "nvpair", + "rand 0.7.3", + "snafu", + "zfs-core-sys", +] + +[[package]] +name = "zfs-core-sys" +version = "0.5.0" +source = "git+https://github.com/oxidecomputer/rust-libzfs#e79f612c116eb752827d0a7f581b99eab288d709" +dependencies = [ + "build-env", + "libc", + "nvpair-sys", + "pkg-config", +] + +[[package]] +name = "zone" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3596bbc963cd9dbaa69b02e349af4d061c56c41d211ba64150a2cedb2f722707" +dependencies = [ + "itertools", + "thiserror", + "zone_cfg_derive", +] + +[[package]] +name = "zone_cfg_derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ac2a898023d86613a7efa7a4195e4b75240009e559acb17ddd7fa876d19527" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..29e63a0e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[workspace] + +members = [ + "platform", + "rift", + "rift_protocol", + "illumos", + "lab", + "icmpv6", + "tools/rdpx" +] diff --git a/README.md b/README.md new file mode 100644 index 00000000..fd9fcafc --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +Maghemite +========= + +A modular routing stack written in Rust. + +## Protocols + +### In Progress +- RIFT + +### TODO +- BGP +- OSPF +- STATIC + +## Platforms + +### In Progress +- Illumos/Helios + +### TODO +- Sidecar/Dendrite diff --git a/icmpv6/Cargo.toml b/icmpv6/Cargo.toml new file mode 100644 index 00000000..6b1cb582 --- /dev/null +++ b/icmpv6/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "icmpv6" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = "1.0" +schemars = { version = "0.8.0", features = [ "uuid" ] } diff --git a/icmpv6/src/lib.rs b/icmpv6/src/lib.rs new file mode 100644 index 00000000..66c7dffb --- /dev/null +++ b/icmpv6/src/lib.rs @@ -0,0 +1,308 @@ +// Copyright 2021 Oxide Computer Company + +use std::net::Ipv6Addr; +use std::convert::TryInto; +use std::mem::size_of; +use serde::{Serialize, Deserialize}; +use schemars::JsonSchema; + +#[derive(Debug, Serialize, Deserialize)] +pub struct RDPMessage { + pub from: Option, + pub packet: ICMPv6Packet, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct ICMPv6Header { + pub typ: ICMPv6Type, + pub code: u8, + pub checksum: u16, +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema)] +#[repr(u8)] +pub enum ICMPv6Type { + Reserved = 0, + DestinationUnreachable = 1, + PacketTooBig = 2, + TimeExceeded = 3, + ParameterProblem = 4, + Unassigned5x99 = 5, + PrivateExperimentation100 = 100, + PrivateExperimentation101 = 101, + Unassigned102x126 = 102, + ReservedForExpansionOfICMPv6ErrorMessages = 127, + EchoRequest = 128, + EchoReply = 129, + MulticastListenerQuery = 130, + MulticastListenerReport = 131, + MulticastListenerDone = 132, + RouterSolicitation = 133, + RouterAdvertisement = 134, + NeighborSolicitation = 135, + NeighborAdvertisement = 136, + RedirectMessage = 137, + RouterRenumbering = 138, + ICMPNodeInformationQuery = 139, + ICMPNodeInformationResponse = 140, + InverseNeighborDiscoverySolicitationMessage = 141, + InverseNeighborDiscoveryAdvertisementMessage = 142, + Version2MulticastListenerReport = 143, + HomeAgentAddressDiscoveryRequestMessage = 144, + HomeAgentAddressDiscoveryReplyMessage = 145, + MobilePrefixSolicitation = 146, + MobilePrefixAdvertisement = 147, + CertificationPathSolicitationMessage = 148, + CertificationPathAdvertisementMessage = 149, + ICMPMessagesUtilizedByExperimentalMobilityProtocols = 150, + MulticastRouterAdvertisement = 151, + MulticastRouterSolicitation = 152, + MulticastRouterTermination = 153, + FMIPv6Messages = 154, + RPLControlMessage = 155, + ILNPv6LocatorUpdateMessage = 156, + DuplicateAddressRequest = 157, + DuplicateAddressConfirmation = 158, + MPLControlMessage = 159, + ExtendedEchoRequest = 160, + ExtendedEchoReply = 161, + Unassigned162x199 = 162, + PrivateExperimentation200 = 200, + PrivateExperimentation201 = 201, + ReservedForExpansionOfICMPv6InformationalMessages = 255, +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +#[repr(u8)] +pub enum NDPOptionType { + SourceLinkLayerAddress = 1, + TargetLinkLayerAddress = 2, + PrefixInformation = 3, + RedirectHeader = 4, + MTU = 5, +} + +#[derive(Debug, Serialize, Deserialize)] +#[repr(C)] +pub struct RouterSolicitation { + pub icmpv6_header: ICMPv6Header, + pub reserved: u32, + pub source_address: Option, +} + +impl RouterSolicitation { + + pub fn new(src: Option) -> Self { + + RouterSolicitation { + icmpv6_header: ICMPv6Header{ + typ: ICMPv6Type::RouterSolicitation, + code: 0, + checksum: 0, + }, + reserved: 0, + source_address: src, + } + + } + + pub fn wire(&self) -> Vec { + let mut v = vec!( + self.icmpv6_header.typ as u8, + self.icmpv6_header.code, + (self.icmpv6_header.checksum & 0x0f) as u8, + (self.icmpv6_header.checksum & 0xf0) as u8, + 0,0,0,0, //reserved + ); + + match self.source_address { + Some(addr) => { + let sz = size_of::()+size_of::(); + v.push(NDPOptionType::SourceLinkLayerAddress as u8); + v.push(sz as u8); + v.extend_from_slice(&addr.octets()); + }, + None => {}, + } + + v + } + +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct RouterAdvertisement { + pub icmpv6_header: ICMPv6Header, + pub hop_limit: u8, + pub managed_address: bool, + pub other_stateful: bool, + pub router_lifetime: u16, + pub reachable_time: u32, + pub retransmission_timer: u32, + pub source_address: Option, + pub mtu: Option, + pub prefix_info: Option, +} + +impl RouterAdvertisement { + + pub fn new( + hop_limit: u8, + managed_address: bool, + other_stateful: bool, + router_lifetime: u16, + reachable_time: u32, + retransmission_timer: u32, + src: Option, + mtu: Option, + prefix_info: Option, + ) -> Self { + + RouterAdvertisement{ + icmpv6_header: ICMPv6Header{ + typ: ICMPv6Type::RouterAdvertisement, + code: 0, + checksum: 0, + }, + hop_limit: hop_limit, + managed_address: managed_address, + other_stateful: other_stateful, + router_lifetime: router_lifetime, + reachable_time: reachable_time, + retransmission_timer: retransmission_timer, + source_address: src, + mtu: mtu, + prefix_info: prefix_info + } + } + + pub fn wire(&self) -> Vec { + let mut v = vec!( + self.icmpv6_header.typ as u8, + self.icmpv6_header.code, + (self.icmpv6_header.checksum & 0x0f) as u8, + (self.icmpv6_header.checksum & 0xf0) as u8, + self.hop_limit, + ); + + let mut mo : u8 = 0b00000000; + if self.managed_address { + mo |= 0b10000000 + } + if self.other_stateful { + mo |= 0b01000000 + } + v.push(mo); + + v.extend_from_slice(&self.router_lifetime.to_be_bytes()); + v.extend_from_slice(&self.reachable_time.to_be_bytes()); + v.extend_from_slice(&self.retransmission_timer.to_be_bytes()); + + match self.source_address { + Some(addr) => { + let sz = size_of::()+size_of::(); + v.push(NDPOptionType::SourceLinkLayerAddress as u8); + v.push(sz as u8); + v.extend_from_slice(&addr.octets()); + }, + None => {}, + } + + match self.mtu { + Some(mtu) => { + let sz = size_of::()+size_of::(); + v.push(NDPOptionType::MTU as u8); + v.push(sz as u8); + v.extend_from_slice(&mtu.to_be_bytes()); + }, + None => {}, + } + + //TODO prefix info + + v + } + +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct PrefixInfo { + pub length: u8, + pub on_link: bool, + pub autonomous: bool, + pub valid_lifetime: u32, + pub preferred_lifetime: u32, + //pub prefix: [u8; 128], TODO serializable + +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum ICMPv6Packet { + RouterSolicitation(RouterSolicitation), + RouterAdvertisement(RouterAdvertisement), +} + +pub fn parse_icmpv6(buf: &[u8]) -> Option { + + if buf.len() < 4 { + return None + } + + match buf[0] { + + 133 => Some(ICMPv6Packet::RouterSolicitation( + RouterSolicitation{ + icmpv6_header: ICMPv6Header{ + typ: ICMPv6Type::RouterSolicitation, + code: buf[1], + checksum: u16::from_be_bytes(buf[2..4] + .try_into() + .expect("slice into buf") + ), + }, + reserved: 0, + source_address: None, //TODO + }) + ), + + 134 => Some(ICMPv6Packet::RouterAdvertisement( + RouterAdvertisement{ + icmpv6_header: ICMPv6Header{ + typ: ICMPv6Type::RouterAdvertisement, + code: buf[1], + checksum: u16::from_be_bytes(buf[2..4] + .try_into() + .expect("slice into buf") + ), + }, + hop_limit: buf[4], + managed_address: 0b10000000&buf[5] != 0, + other_stateful: 0b01000000&buf[5] != 0, + router_lifetime: u16::from_be_bytes(buf[6..8] + .try_into() + .expect("slice into buf") + ), + reachable_time: u32::from_be_bytes(buf[8..12] + .try_into() + .expect("slice into buf") + ), + retransmission_timer: u32::from_be_bytes(buf[12..16] + .try_into() + .expect("slice into buf") + ), + source_address: None, //TODO + mtu: None, //TODO + prefix_info: None, //TODO + }) + ), + _ => None, + } +} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/illumos/Cargo.toml b/illumos/Cargo.toml new file mode 100644 index 00000000..6d6ffd83 --- /dev/null +++ b/illumos/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "illumos" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +platform = { path = "../platform" } +rift = { path = "../rift" } +rift_protocol = { path = "../rift_protocol" } +slog = "2.7" +slog-term = "2.7" +slog-async = "2.7" +socket2 = { version = "0.4", features = ["all"] } +icmpv6 = { path = "../icmpv6" } +tokio = { version = "1.0", features = ["full"] } +dropshot = { git = "https://github.com/oxidecomputer/dropshot" } +reqwest = { version = "0.11", features = ["blocking", "json"] } + +[build-dependencies] +bindgen = "0.59" diff --git a/illumos/build.rs b/illumos/build.rs new file mode 100644 index 00000000..feae4e83 --- /dev/null +++ b/illumos/build.rs @@ -0,0 +1,60 @@ +// Copyright 2021 Oxide Computer Company +// +// Derived from https://github.com/oxidecomputer/libscf-sys/blob/main/build.rs + +use bindgen; +use std::env; +use std::path::PathBuf; + +fn main() { + #[cfg(not(target_os = "illumos"))] + compile_error!("libdladm-sys is only supported on illumos"); + + println!("cargo:rustc-link-lib=dladm"); + println!("cargo:rustc-link-lib=ipadm"); + println!("cargo:rerun-if-changed=wrapper.h"); + + if let Err(_) = env::var("LIBCLANG_PATH") { + env::set_var("LIBCLANG_PATH", "/opt/ooce/clang-11.0/lib"); + } + + let illumos_src_path = match env::var("ILLUMOS_SRC") { + Err(_) => { + println!("illumos path not set, using system libraries"); + println!("this will not work outside ry's personal illumos build"); + println!("https://github.com/oxidecomputer/illumos-gate/tree/netapis"); + "".to_string() + } + Ok(path) => path.to_string(), + }; + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + + if illumos_src_path != "" { + let bindings = bindgen::Builder::default() + .header("wrapper.h") + .clang_arg(format!("-I{}/usr/src/uts/common", illumos_src_path)) + .clang_arg(format!( + "-I{}/usr/src/lib/libdladm/common", illumos_src_path)) + .clang_arg(format!( + "-I{}/usr/src/lib/libipadm/common", illumos_src_path)) + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .generate() + .expect("unable to generate bindings"); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("unable to write bindings"); + } else { + let bindings = bindgen::Builder::default() + .header("wrapper.h") + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .generate() + .expect("unable to generate bindings"); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("unable to write bindings"); + + } +} diff --git a/illumos/src/illumos.rs b/illumos/src/illumos.rs new file mode 100644 index 00000000..6efded1c --- /dev/null +++ b/illumos/src/illumos.rs @@ -0,0 +1,11 @@ +// Copyright 2021 Oxide Computer Company + +// import generated bindings +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(improper_ctypes)] +#![allow(dead_code)] +#![allow(deref_nullptr)] +#![allow(unaligned_references)] +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/illumos/src/link.rs b/illumos/src/link.rs new file mode 100644 index 00000000..541cff65 --- /dev/null +++ b/illumos/src/link.rs @@ -0,0 +1,82 @@ +// Copyright 2021 Oxide Computer Company + +use std::sync::{Arc, Mutex}; +use std::net::{SocketAddr, SocketAddrV6, Ipv6Addr}; +use std::sync::mpsc::Sender; +use dropshot::{ + endpoint, + ConfigDropshot, + ConfigLogging, + ConfigLoggingLevel, + ApiDescription, + HttpServerStarter, + RequestContext, + HttpResponseOk, + HttpError, + TypedBody, +}; +use rift::LINKINFO_PORT; +use rift_protocol::LinkInfo; + +struct LinkHandlerContext { + tx: Arc::>>, +} + +#[endpoint { + method = POST, + path = "linkinfo" +}] +async fn riftp_linkinfo( + ctx: Arc>, + rq: TypedBody, +) -> Result, HttpError> { + + let api_context = ctx.context(); + let tx = api_context.tx.lock().unwrap(); + + match (*tx).send(rq.into_inner()) { + Ok(_) => Ok(HttpResponseOk(())), + Err(e) => Err(HttpError::for_internal_error(format!( + "error consuming LinkInfo: {}", e + ))), + } + + +} + +pub(crate) async fn link_handler( + addr: Ipv6Addr, + tx: Arc::>>, +) -> Result<(), String> { + + let sa = SocketAddr::V6( + SocketAddrV6::new(addr, LINKINFO_PORT, 0, 0) + ); + let config_dropshot = ConfigDropshot { + bind_address: sa, + ..Default::default() + }; + + let config_logging = ConfigLogging::StderrTerminal { + level: ConfigLoggingLevel::Info, + }; + let log = config_logging + .to_logger("riftp_link_handler") + .map_err(|e| format!("config dropshot logger: {}", e))?; + + let mut api = ApiDescription::new(); + api.register(riftp_linkinfo).unwrap(); + + let api_context = LinkHandlerContext{tx: tx}; + + let server = HttpServerStarter::new( + &config_dropshot, + api, + api_context, + &log, + ).map_err(|e| format!("create dropshot link server: {}", e))? + .start(); + + server.await + +} diff --git a/illumos/src/main.rs b/illumos/src/main.rs new file mode 100644 index 00000000..510fbf0b --- /dev/null +++ b/illumos/src/main.rs @@ -0,0 +1,33 @@ +// Copyright 2021 Oxide Computer Company + +use rift::Rift; +use slog; +use slog_term; +use slog_async; +use std::sync::{Arc, Mutex}; + +mod platform; +mod illumos; +mod link; + +use slog::Drain; + +#[tokio::main] +async fn main() -> Result<(), String> { + + let decorator = slog_term::TermDecorator::new().build(); + let drain = slog_term::FullFormat::new(decorator).build().fuse(); + let drain = slog_async::Async::new(drain).build().fuse(); + + let log = slog::Logger::root(drain, slog::o!()); + + let ilu = Arc::new(Mutex::new(crate::platform::Illumos{log: log.clone()})); + let mut riftp = Rift::new(ilu, log.clone()); + match riftp.run() { + Ok(()) => slog::warn!(log, "early exit?"), + Err(e) => slog::error!(log, "rift: {}", e), + }; + + Ok(()) + +} diff --git a/illumos/src/platform.rs b/illumos/src/platform.rs new file mode 100644 index 00000000..147d7225 --- /dev/null +++ b/illumos/src/platform.rs @@ -0,0 +1,285 @@ +// Copyright 2021 Oxide Computer Company + +use std::sync::{Arc, Mutex}; +use platform::{Platform, error::Error}; +use std::mem::MaybeUninit; +use slog::{Logger, debug, error}; +use std::{ptr}; +use crate::illumos; +use socket2::{Socket, Domain, Type, Protocol, SockAddr}; +use std::net::{Ipv6Addr, SocketAddrV6}; +use icmpv6::{RouterSolicitation, RouterAdvertisement, RDPMessage}; +use std::sync::mpsc::{channel, Sender, Receiver}; +use std::thread; +use rift_protocol::LinkInfo; +use rift::{LINKINFO_PORT, RDP_MADDR}; + +pub(crate) struct Illumos { + pub(crate) log: Logger, +} + +impl Platform for Illumos { + + fn advertise_rift_router(&self) -> Result<(), Error> { + + let socket = Socket::new( + Domain::IPV6, + Type::RAW, + Some(Protocol::ICMPV6), + ).map_err(|e| Error::Platform(format!("new socket: {}", e)))?; + + // we don't want to advertise to ourself + socket + .set_multicast_loop_v6(false) + .map_err(|e| + Error::Platform(format!("diable multicast loop: {}", e)) + )?; + + let sa = SockAddr::from(SocketAddrV6::new(rift::RDP_MADDR, 0, 0, 0)); + + let ra = RouterAdvertisement::new( + 1, //hop limit + false, // managed address (dhcpv6) + false, // other stateful (stateless dhcpv6) + 0, // not a default router + 100, // consider this router reachable for 100 ms + 0, // No retrans timer specified + None, // no source address, + Some(9216), // jumbo frames ftw + None, // no prefix info + ); + let wire = ra.wire(); + + socket + .send_to(wire.as_slice(), &sa) + .map_err(|e| Error::Platform(format!("advertise send: {}", e)))?; + + Ok(()) + + } + + fn solicit_rift_routers(&self) -> Result<(), Error> { + + let socket = Socket::new( + Domain::IPV6, + Type::RAW, + Some(Protocol::ICMPV6), + ).map_err(|e| Error::Platform(format!("new socket: {}", e)))?; + + // we don't want to solicit ourself + socket + .set_multicast_loop_v6(false) + .map_err(|e| + Error::Platform(format!("diable multicast loop: {}", e)) + )?; + + let sa = SockAddr::from(SocketAddrV6::new(RDP_MADDR, 0, 0, 0)); + let rs = RouterSolicitation::new(None); + let wire = rs.wire(); + + socket + .send_to(wire.as_slice(), &sa) + .map_err(|e| Error::Platform(format!("solicit send: {}", e)))?; + + Ok(()) + + } + + fn get_rdp_channel(&self) -> Result, Error> { + + let socket = Socket::new( + Domain::IPV6, + Type::RAW, + Some(Protocol::ICMPV6), + ).map_err(|e| Error::Platform(format!("new socket: {}", e)))?; + + socket + .join_multicast_v6(&RDP_MADDR, 0) + .map_err(|e| Error::Platform(format!("join multicast: {}", e)))?; + + let (tx, rx): (Sender, Receiver) = channel(); + + let log = self.log.clone(); + + thread::spawn(move || loop { + + let mut buf: [u8; 1024] = [0;1024]; + let mut _buf = unsafe{ + &mut(*buf.as_mut_ptr().cast::<[MaybeUninit; 1024]>()) + }; + + let (sz, sender) = match socket.recv_from(_buf) { + Ok(x) => x, + Err(e) => { + error!(log, "socket recv: {}", e); + continue; + }, + }; + + let senderv6 = match sender.as_socket_ipv6() { + Some(v6) => Some(*v6.ip()), + _ => None, + }; + + let msg = match icmpv6::parse_icmpv6(&buf[..sz]) { + Some(packet) => RDPMessage{ + from: senderv6, + packet: packet, + }, + None => { continue; }, + }; + + match tx.send(msg) { + Ok(_) => {}, + Err(e) => error!(log, "rdp channel send: {}", e), + }; + + + }); + + Ok(rx) + } + + fn get_link_channel(&self, peer: Ipv6Addr) + -> Result<(Sender, Receiver), Error> { + + //ingress + let ilog = self.log.clone(); + let (_itx, irx): (Sender, Receiver) = channel(); + let itx = Arc::new(Mutex::new(_itx)); + + tokio::spawn(async move { + match crate::link::link_handler(peer, itx).await { + Ok(_) => {}, + Err(e) => error!(ilog, "failed to start link handler: {}", e), + } + }); + + //egress + let elog = self.log.clone(); + let (etx, erx): (Sender, Receiver) = channel(); + tokio::spawn(async move { loop { + + let msg = match erx.recv() { + Ok(m) => m, + Err(e) => { + error!(elog, "linkinfo egress channel rx: {}", e); + continue; + } + }; + + let client = reqwest::Client::new(); + let resp = client + .post(format!("http://{}:{}/linkinfo", peer, LINKINFO_PORT)) + .json(&msg) + .send() + .await; + + match resp { + Ok(_) => {}, + Err(e) => error!(elog, "failed to send linkinfo: {}", e), + } + + }}); + + + Ok((etx, irx)) + + } + +} + +#[allow(dead_code)] +const LIFC_DEFAULT: u32 = + illumos::LIFC_NOXMIT | illumos::LIFC_TEMPORARY | + illumos::LIFC_ALLZONES | illumos::LIFC_UNDER_IPMP; + +impl Illumos { + + #[allow(dead_code)] + fn ipadm_handle(&self) -> Result { + + let mut handle: illumos::ipadm_handle_t = ptr::null_mut(); + let status = unsafe { illumos::ipadm_open(&mut handle, 0) }; + if status != illumos::ipadm_status_t_IPADM_SUCCESS { + return Err(Error::Platform(format!("ipadm_open: {}", status))) + } + + Ok(handle) + + } + + #[allow(dead_code)] + fn get_ipv6_addrs(&self) -> Result, Error> { + debug!(self.log, "getting ipv6 addrs"); + + // get address info + let handle = self.ipadm_handle()?; + let mut addrinfo: *mut illumos::ipadm_addr_info_t = ptr::null_mut(); + let status = unsafe { illumos::ipadm_addr_info( + handle, + ptr::null(), + &mut addrinfo, + 0, + LIFC_DEFAULT as i64, + ) }; + if status != illumos::ipadm_status_t_IPADM_SUCCESS { + return Err(Error::Platform(format!("ipadm_addr_info: {}", status))) + } + + // populate results from returned addresses + let mut result: Vec = Vec::new(); + let mut addr : *mut illumos::ifaddrs = unsafe { + &mut (*addrinfo).ia_ifa + }; + loop { + if addr == ptr::null_mut() { break } + + unsafe { + // only ipv6 + if (*(*addr).ifa_addr).sa_family == illumos::AF_INET6 as u16 { + + let sin6 = (*addr).ifa_addr as *mut illumos::sockaddr_in6; + + // only link local + if (*sin6).sin6_addr._S6_un._S6_u8[0] as u8 == 0xfe && + (*sin6).sin6_addr._S6_un._S6_u8[1] as u8 == 0x80 { + + // extract address + let v6addr = Ipv6Addr::from( + (*sin6).sin6_addr._S6_un._S6_u8 + ); + + // extract name + let ifname = std::ffi::CString::from_raw( + (*addr).ifa_name + ); + let ifname_s = ifname.into_string()?; + + debug!(self.log, + "found ipv6-ll interface: {}/{}", + ifname_s.as_str(), + v6addr); + + result.push(SysIpv6Addr{ + addr: v6addr, + local_link: ifname_s, + }) + + } + } + } + + addr = unsafe { (*addr).ifa_next }; + } + + Ok(result) + } + +} + +#[derive(Debug)] +pub struct SysIpv6Addr { + pub addr: Ipv6Addr, + pub local_link: String, +} diff --git a/illumos/wrapper.h b/illumos/wrapper.h new file mode 100644 index 00000000..0d885378 --- /dev/null +++ b/illumos/wrapper.h @@ -0,0 +1,20 @@ +// Copyright 2021 Oxide Computer Company + +#include "libdladm.h" +#include "libdlaggr.h" +#include "libdlbridge.h" +#include "libdlether.h" +#include "libdlflow.h" +#include "libdlib.h" +#include "libdliptun.h" +#include "libdllink.h" +#include "libdlmgmt.h" +#include "libdlsim.h" +#include "libdlstat.h" +#include "libdlvlan.h" +#include "libdlvnic.h" +#include "libdlwlan.h" + +#include "libipadm.h" +#include "ipadm_ipmgmt.h" +#include "ipadm_ndpd.h" diff --git a/lab/Cargo.toml b/lab/Cargo.toml new file mode 100644 index 00000000..9a89fc54 --- /dev/null +++ b/lab/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "lab" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libfalcon = { path = "/home/ry/falcon/lib" } +# https://github.com/jmesmon/rust-libzfs/pull/71 +zfs-core = { git = "https://github.com/oxidecomputer/rust-libzfs" } +anyhow = "1.0" diff --git a/lab/src/main.rs b/lab/src/main.rs new file mode 100644 index 00000000..6e9a42eb --- /dev/null +++ b/lab/src/main.rs @@ -0,0 +1,35 @@ +// Copyright 2021 Oxide Computer Company + +use libfalcon::{cli::{run, RunMode}, Deployment}; +use anyhow::{Result}; + +fn main() { + + println!("{:?}", do_run()); + +} + +fn do_run() -> Result<()> { + + let mut d = Deployment::new("duo"); + + // nodes + let r0 = d.zone("r0"); + let r1 = d.zone("r1"); + + d.mount("..", "/opt/maghemite", r0)?; + d.mount("..", "/opt/maghemite", r1)?; + + // links + d.link(r0, r1); + + match run(&mut d) { + RunMode::Launch => { + d.exec(r0, "ipadm create-addr -T addrconf duo_r0_vnic0/v6")?; + d.exec(r1, "ipadm create-addr -T addrconf duo_r1_vnic0/v6")?; + Ok(()) + } + _ => Ok(()), + } + +} diff --git a/platform/Cargo.toml b/platform/Cargo.toml new file mode 100644 index 00000000..c49bd2c9 --- /dev/null +++ b/platform/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "platform" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +thiserror = "1.0" +icmpv6 = { path = "../icmpv6" } +rift_protocol = { path = "../rift_protocol" } diff --git a/platform/src/error.rs b/platform/src/error.rs new file mode 100644 index 00000000..77e1d0db --- /dev/null +++ b/platform/src/error.rs @@ -0,0 +1,20 @@ +// Copyright 2021 Oxide Computer Company + +use thiserror::Error; +use std::ffi::IntoStringError; + +#[derive(Error, Debug)] +pub enum Error { + #[error("{0} not implemented")] + NotImplemented(String), + + #[error("Platform error: {0}")] + Platform(String), +} + +impl From for Error { + fn from(e: IntoStringError) -> Error { + Error::Platform(format!("into string: {}", e)) + } +} + diff --git a/platform/src/lib.rs b/platform/src/lib.rs new file mode 100644 index 00000000..5d024d3b --- /dev/null +++ b/platform/src/lib.rs @@ -0,0 +1,34 @@ +// Copyright 2021 Oxide Computer Company + +pub mod error; + +use std::net; +use error::Error; +use icmpv6::RDPMessage; +use std::sync::mpsc::{Sender, Receiver}; +use std::net::Ipv6Addr; + +pub trait Platform { + fn solicit_rift_routers(&self) -> Result<(), Error>; + fn advertise_rift_router(&self) -> Result<(), Error>; + fn get_rdp_channel(&self) -> Result, Error>; + fn get_link_channel(&self, peer: Ipv6Addr) -> Result< + (Sender, Receiver), + Error + >; +} + +#[derive(Debug)] +pub struct NeighborRouter { + pub addr: net::Ipv6Addr, + pub local_link: String, +} + + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/rift/Cargo.toml b/rift/Cargo.toml new file mode 100644 index 00000000..9280e4a3 --- /dev/null +++ b/rift/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "rift" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dropshot = { git = "https://github.com/oxidecomputer/dropshot" } +platform = { path = "../platform" } +rift_protocol = { path = "../rift_protocol" } +icmpv6 = { path = "../icmpv6" } +thiserror = "1.0" +slog = "2.7" +slog-term = "2.7" +slog-async = "2.7" +schemars = { version = "0.8.0", features = [ "uuid" ] } +serde = "1.0" +tokio = { version = "1.0", features = ["full"] } diff --git a/rift/src/admin.rs b/rift/src/admin.rs new file mode 100644 index 00000000..4a3f1aa5 --- /dev/null +++ b/rift/src/admin.rs @@ -0,0 +1,102 @@ +// Copyright 2021 Oxide Computer Company + +use crate::{Rift, Peer}; +use std::sync::{Arc, Mutex}; +use dropshot::{ + endpoint, + ConfigDropshot, + ConfigLogging, + ConfigLoggingLevel, + ApiDescription, + HttpServerStarter, + RequestContext, + HttpResponseOk, + HttpError, +}; +use std::collections::HashSet; +use platform::Platform; +use slog::error; +use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr}; + +impl Rift

{ + + pub(crate) fn admin_handler(&self) { + + let peers = self.peers.clone(); + let log = self.log.clone(); + + tokio::spawn(async move { + match handler(peers).await { + Ok(_) => {}, + Err(e) => error!(log, "failed to start adm handler {}", e), + } + }); + + } + +} + +struct RiftAdmContext { + peers: Arc::>>, +} + +#[endpoint { + method = GET, + path = "/peers", +}] +async fn adm_api_get_peers( + ctx: Arc>, +) -> Result>, HttpError> { + + let api_context = ctx.context(); + + let mut vec: Vec:: = Vec::new(); + let peers = api_context.peers.lock().unwrap(); + + for x in (*peers).iter() { + vec.push(*x); + } + + Ok(HttpResponseOk(vec)) + +} + + +async fn handler( + peers: Arc::>>, +) -> Result<(), String> { + + let addr = SocketAddr::V4( + SocketAddrV4::new(Ipv4Addr::new(127,0,0,1), 7000) + ); + let config_dropshot = ConfigDropshot { + bind_address: addr, + ..Default::default() + }; + + let config_logging = ConfigLogging::StderrTerminal { + level: ConfigLoggingLevel::Info, + }; + let log = config_logging + .to_logger("rift") + .map_err(|e| format!("config dropshot logger: {}", e))?; + + let mut api = ApiDescription::new(); + api.register(adm_api_get_peers).unwrap(); + + let api_context = RiftAdmContext{ + peers: peers.clone(), + }; + + let server = HttpServerStarter::new( + &config_dropshot, + api, + api_context, + &log, + ).map_err(|e| format!("create dropshot adm server: {}", e))? + .start(); + + server.await + +} + diff --git a/rift/src/error.rs b/rift/src/error.rs new file mode 100644 index 00000000..845860b7 --- /dev/null +++ b/rift/src/error.rs @@ -0,0 +1,22 @@ +// Copyright 2021 Oxide Computer Company + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("{0} not implemented")] + NotImplemented(String), + + #[error("Runtime error: {0}")] + Runtime(String), + + #[error("Protocol error: {0}")] + Protocol(String), + + #[error("Platform error: {0}")] + Platform(platform::error::Error), +} + +impl From for Error { + fn from(e: platform::error::Error) -> Error { Error::Platform(e) } +} diff --git a/rift/src/lib.rs b/rift/src/lib.rs new file mode 100644 index 00000000..2af8c956 --- /dev/null +++ b/rift/src/lib.rs @@ -0,0 +1,96 @@ +// Copyright 2021 Oxide Computer Company + +mod error; +mod admin; +mod rdp; +mod link; + +use std::net::Ipv6Addr; +use std::sync::{Arc, Mutex}; +use std::collections::HashSet; +use std::hash::{Hash, Hasher}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use platform::Platform; +use slog::info; +use std::sync::mpsc::{Sender, Receiver, channel}; +use link::LinkSM; + +/// The RIFT multicast address used for bootstrapping ff02::a1f7. +pub const RDP_MADDR: Ipv6Addr = Ipv6Addr::new(0xff02, 0,0,0,0,0,0, 0xa1f7); +pub const LINKINFO_PORT: u16 = 914; +pub const TOPOLOY_INFO_PORT: u16 = 915; + +#[derive(Debug, Copy, Clone, Deserialize, Serialize, JsonSchema)] +pub struct Peer { + pub remote_addr: Ipv6Addr, + pub advertisement: icmpv6::RouterAdvertisement, +} + +impl Hash for Peer { + fn hash(&self, state: &mut H) { + self.remote_addr.hash(state); + } +} + +impl PartialEq for Peer { + fn eq(&self, other: &Self) -> bool { + self.remote_addr == other.remote_addr + } +} +impl Eq for Peer {} + +pub struct Rift { + platform: Arc::>, + peers: Arc::>>, + links: Arc::>>, + log: slog::Logger, +} + +impl Rift

{ + pub fn new( + platform: Arc::>, + log: slog::Logger, + ) -> Self { + Rift{ + platform: platform, + peers: Arc::new(Mutex::new(HashSet::new())), + links: Arc::new(Mutex::new(HashSet::new())), + log: log, + } + } + + pub fn run(&mut self) -> Result<(), error::Error> { + + let (peer_tx, peer_rx): (Sender, Receiver) = channel(); + + info!(self.log, "starting link handler"); + self.link_handler(peer_rx)?; + + info!(self.log, "starting rdp handler"); + self.rdp_handler(peer_tx)?; + + info!(self.log, "starting adm handler"); + self.admin_handler(); + + info!(self.log, "entering router loop"); + self.router_loop() + + } + + fn router_loop(&self) -> Result<(), error::Error> { + + loop { + let p = self.platform.lock().unwrap(); + (*p).solicit_rift_routers()?; + (*p).advertise_rift_router()?; + std::thread::sleep( + std::time::Duration::from_secs(5), + ); + } + + #[allow(unreachable_code)] + Err(error::Error::Runtime("early exit".to_string())) + } + +} diff --git a/rift/src/link.rs b/rift/src/link.rs new file mode 100644 index 00000000..2634b6a6 --- /dev/null +++ b/rift/src/link.rs @@ -0,0 +1,122 @@ +// Copyright 2021 Oxide Computer Company + +use crate::{Rift, Peer}; +use std::sync::{Arc, Mutex}; +use platform::Platform; +use std::thread; +use slog::{info, error}; +use std::sync::mpsc::{Sender, Receiver}; +use std::hash::{Hash, Hasher}; + +pub enum AdjacencyState { + OneWay, + TwoWay, + ThreeWay, +} + +pub struct LinkSM { + state: Arc::>, +} + +struct LinkSMState { + current: AdjacencyState, + peer: Peer, +} + +impl Rift

{ + + pub(crate) fn link_handler( + &mut self, + peer_rx: Receiver, + ) -> Result<(), crate::error::Error> { + + let log = self.log.clone(); + let links = self.links.clone(); + let p = self.platform.clone(); + + thread::spawn(move || loop { + let peer = match peer_rx.recv() { + Ok(p) => p, + Err(e) => { + error!(log, "peer rx: {}", e); + continue; + } + }; + + info!(log, + "starting link state machine for peer {:#?}", + peer.remote_addr, + ); + + let mut ls = links.lock().unwrap(); + let pl = p.lock().unwrap(); + let (tx, rx) = match (*pl).get_link_channel(peer.remote_addr) { + Err(e) => { + error!(log, "get link channel for {}: {}", + peer.remote_addr, e); + continue; + }, + Ok(channels) => channels, + }; + let mut lsm = LinkSM::new(peer); + lsm.run(tx, rx); + (*ls).insert(lsm); + }); + + Ok(()) + + } + +} + +// LinkSM implementation ...................................................... + +impl LinkSM { + + fn new(peer: Peer) -> Self { + LinkSM{ + state: Arc::new(Mutex::new(LinkSMState{ + current: AdjacencyState::OneWay, + peer: peer, + })) + } + } + + fn run( + &mut self, + tx: Sender, + rx: Receiver, + ) { + + //TODO you are here + + thread::spawn(move || loop { + + let _msg = rx.recv(); + + }); + + } + +} + +// LinkSM trait implementations ............................................... + +impl Hash for LinkSM { + fn hash(&self, state: &mut H) { + let s = self.state.lock().unwrap(); + (*s).peer.hash(state); + } +} + +impl PartialEq for LinkSM { + fn eq(&self, other: &Self) -> bool { + if self == other { return true }; + + let s = self.state.lock().unwrap(); + let o = other.state.lock().unwrap(); + (*s).peer == (*o).peer + } +} +impl Eq for LinkSM {} + diff --git a/rift/src/rdp.rs b/rift/src/rdp.rs new file mode 100644 index 00000000..25075057 --- /dev/null +++ b/rift/src/rdp.rs @@ -0,0 +1,69 @@ +// Copyright 2021 Oxide Computer Company + +use crate::{Rift, Peer}; +use platform::Platform; +use std::thread; +use icmpv6::ICMPv6Packet; +use slog::{info, error, debug}; +use std::sync::mpsc::Sender; + +impl Rift

{ + + pub(crate) fn rdp_handler( + &mut self, + peer_tx: Sender, + ) -> Result<(), crate::error::Error> { + + let p = self.platform.lock().unwrap(); + + let peers = self.peers.clone(); + let rdp_rx = (*p).get_rdp_channel()?; + let log = self.log.clone(); + + thread::spawn(move || loop { + let msg = match rdp_rx.recv() { + Ok(m) => m, + Err(e) => { + error!(log, "rdp rx: {}", e); + continue; + }, + }; + + let from = match msg.from { + Some(addr) => addr, + _ => continue, + }; + + match msg.packet { + ICMPv6Packet::RouterSolicitation(rs) => { + info!(log, "got RIFT msg {:#?} from {}", rs, from); + //TODO respond to solicitations + }, + ICMPv6Packet::RouterAdvertisement(ra) => { + info!(log, "got RIFT msg {:#?} from {}", ra, from); + let mut ps = peers.lock().unwrap(); + let peer = Peer{ + remote_addr: from, + advertisement: ra, + }; + match (*ps).replace(peer) { + None => {}, + Some(_) => { + debug!(log, "peer already known {}", from); + continue + }, + }; + match peer_tx.send(peer) { + Ok(_) => {}, + Err(e) => error!(log, "send peer to handler {}", e), + }; + } + }; + + }); + + Ok(()) + + } + +} diff --git a/rift_protocol/Cargo.toml b/rift_protocol/Cargo.toml new file mode 100644 index 00000000..485ea1eb --- /dev/null +++ b/rift_protocol/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "rift_protocol" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = "1.0" +schemars = { version = "0.8.0", features = [ "uuid" ] } diff --git a/rift_protocol/src/lib.rs b/rift_protocol/src/lib.rs new file mode 100644 index 00000000..bb59af9f --- /dev/null +++ b/rift_protocol/src/lib.rs @@ -0,0 +1,45 @@ +// Copyright 2021 Oxide Computer Company + +use serde::{Serialize, Deserialize}; +use schemars::JsonSchema; + +#[derive(Debug, Serialize, Deserialize, JsonSchema)] +pub struct LinkInfo { + pub name: String, + pub local_id: u64, + pub flood_port: u16, + pub mtu: u16, + pub bandwidth: u64, + pub neighbor: Neighbor, + pub node_capabilities: NodeCapabilities, + pub link_capabilities: LinkCapabilities, + pub hold_time: u16, + pub label: u32, + pub not_ztp: bool, + pub repeater: bool, + pub backoff: bool, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct Neighbor { + pub originator: u64, + pub remote_id: u32, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct NodeCapabilities { + pub protocol_minor_version: u16, + pub flood_reduction: bool, + pub hierarchy_indication: HierarchyIndication, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct LinkCapabilities { + pub bfd: bool, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub enum HierarchyIndication { + Leaf, + ToF, +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..704bb10e --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +# for passing environment for libzfs through .cargo/config.toml +# worth it? +channel = "nightly" diff --git a/tools/rdpx/Cargo.toml b/tools/rdpx/Cargo.toml new file mode 100644 index 00000000..11f76124 --- /dev/null +++ b/tools/rdpx/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "rdpx" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0" +socket2 = { version = "0.4", features = ["all"] } +icmpv6 = { path = "../../icmpv6" } +rift = { path = "../../rift" } +clap = { version = "3.0.0-beta.4", features = ["color"] } +serde = "1.0" +ron = "0.6" +libfalcon = { path = "/home/ry/falcon/lib" } diff --git a/tools/rdpx/src/main.rs b/tools/rdpx/src/main.rs new file mode 100644 index 00000000..2f1fdc2a --- /dev/null +++ b/tools/rdpx/src/main.rs @@ -0,0 +1,170 @@ +// Copyright 2021 Oxide Computer Company + +use std::mem::MaybeUninit; +use socket2::{Socket, Domain, Type, Protocol, SockAddr}; +use anyhow::Result; +use std::net::{Ipv6Addr, SocketAddrV6}; +use std::str::FromStr; +use icmpv6::{RouterSolicitation, RouterAdvertisement, RDPMessage}; +use ron::ser::{to_string_pretty, PrettyConfig}; + +use clap::{AppSettings, Clap}; + +#[derive(Clap)] +#[clap( + version = "0.1", + author = "Ryan Goodfellow " +)] +#[clap(setting = AppSettings::ColoredHelp)] +#[clap(setting = AppSettings::InferSubcommands)] +struct Opts { + #[clap(short, long, default_value = "ff02::a1f7")] + multicast_group: String, + + #[clap(short, long, parse(from_occurrences))] + verbose: i32, + + #[clap(subcommand)] + subcmd: SubCommand, +} + +#[derive(Clap)] +enum SubCommand { + Watch(Watch), + Advertise(Advertise), + Solicit(Solicit), +} + +#[derive(Clap)] +#[clap(setting = AppSettings::ColoredHelp)] +struct Watch { + #[clap(short, long)] + count: u32, +} + +#[derive(Clap)] +#[clap(setting = AppSettings::ColoredHelp)] +struct Advertise { } + +#[derive(Clap)] +#[clap(setting = AppSettings::ColoredHelp)] +struct Solicit { } + +fn main() { + + let opts: Opts = Opts::parse(); + match opts.subcmd { + SubCommand::Watch(ref w) => { + match run_watch(&opts, &w) { + Ok(()) => {}, + Err(e) => println!("{}", e), + } + }, + SubCommand::Advertise(ref a) => { + match run_advertise(&opts, &a) { + Ok(()) => {}, + Err(e) => println!("{}", e), + } + } + SubCommand::Solicit(ref s) => { + match run_solicit(&opts, &s) { + Ok(()) => {}, + Err(e) => println!("{}", e), + } + } + } + +} + +fn run_advertise(opts: &Opts, _a: &Advertise) -> Result<()> { + + let socket = Socket::new(Domain::IPV6, Type::RAW, Some(Protocol::ICMPV6))?; + let maddr = opts.multicast_group.as_str(); + let mc = Ipv6Addr::from_str(maddr)?; + let sa = SockAddr::from(SocketAddrV6::new(mc, 0, 0, 0)); + + let ra = RouterAdvertisement::new( + 1, //hop limit + false, // managed address (dhcpv6) + false, // other stateful (stateless dhcpv6) + 0, // not a default router + 100, // consider this router reachable for 100 ms + 0, // No retrans timer specified + None, // no source address, + Some(9216), // jumbo frames ftw + None, // no prefix info + ); + let wire = ra.wire(); + + //TODO set multicast out interface + + let bytes_sent = socket.send_to(wire.as_slice(), &sa)?; + println!("sent {} bytes", bytes_sent); + + Ok(()) + +} + +fn run_solicit(opts: &Opts, _s: &Solicit) -> Result<()> { + + let socket = Socket::new(Domain::IPV6, Type::RAW, Some(Protocol::ICMPV6))?; + let maddr = opts.multicast_group.as_str(); + let mc = Ipv6Addr::from_str(maddr)?; + let sa = SockAddr::from(SocketAddrV6::new(mc, 0, 0, 0)); + + let rs = RouterSolicitation::new(None); + let wire = rs.wire(); + + //TODO set multicast out interface + + let bytes_sent = socket.send_to(wire.as_slice(), &sa)?; + println!("sent {} bytes", bytes_sent); + + Ok(()) + +} + +fn run_watch(opts: &Opts, w: &Watch) -> Result<()> { + + let socket = Socket::new(Domain::IPV6, Type::RAW, Some(Protocol::ICMPV6))?; + let maddr = opts.multicast_group.as_str(); + let mc = Ipv6Addr::from_str(maddr)?; + socket.join_multicast_v6(&mc, 0)?; + + let mut count: u32 = 0; + loop { + let mut buf: [u8; 1024] = [0;1024]; + let mut _buf = unsafe{ + &mut(*buf.as_mut_ptr().cast::<[MaybeUninit; 1024]>()) + }; + + let (sz, sender) = socket.recv_from(_buf)?; + let senderv6 = match sender.as_socket_ipv6() { + Some(v6) => Some(*v6.ip()), + _ => None, + }; + + match icmpv6::parse_icmpv6(&buf[..sz]) { + Some(packet) => { + let m = RDPMessage{ + from: senderv6, + packet: packet, + }; + let pretty = PrettyConfig::new() + .with_separate_tuple_members(true) + .with_enumerate_arrays(true); + println!("{}", to_string_pretty(&m, pretty)?); + } + None => { + println!("unrecognized packet") + } + } + count += 1; + if w.count > 0 && count >= w.count { + break; + } + } + + Ok(()) + +} diff --git a/tools/rdpx/tests/rdp_test.rs b/tools/rdpx/tests/rdp_test.rs new file mode 100644 index 00000000..32976ebf --- /dev/null +++ b/tools/rdpx/tests/rdp_test.rs @@ -0,0 +1,79 @@ +// Copyright 2021 Oxide Computer Company + +use anyhow::{anyhow, Result}; +use std::thread; +use ron::de::from_str; +use icmpv6::{RDPMessage, ICMPv6Packet}; + +#[test] +#[ignore] +fn duot_rdp() -> Result<()> { + + // create testing topology + let mut d = libfalcon::Deployment::new("duot"); + let r0 = d.zone("r0"); + let r1 = d.zone("r1"); + d.link(r0, r1); + + // mount in software + d.mount("../..", "/opt/maghemite", r0)?; + d.mount("../..", "/opt/maghemite", r1)?; + + // launch topology + d.launch()?; + + // create link local ipv6 addresses + d.exec(r0, "ipadm create-addr -T addrconf duot_r0_vnic0/v6")?; + d.exec(r1, "ipadm create-addr -T addrconf duot_r1_vnic0/v6")?; + + // wait for addresses to become ready + let mut retries = 0; + loop { + let state = + d.exec(r1, "ipadm show-addr -po state duot_r1_vnic0/v6")?; + if state == "ok" { + break; + } + retries += 1; + if retries >= 10 { + return Err(anyhow!( + "timed out waiting for duot_r1_vnic0/v6" + )); + } + thread::sleep(std::time::Duration::from_secs(1)) + } + + // start the rdpx watcher, this watches for RDP solicitations and + // advertisements. When an RDP message comes in, it's dumped to the console + // in rusty object notation (RON). The -c flag indicates to exit after one + // message is received. + let rx = d.spawn(r1, "/opt/maghemite/target/debug/rdpx watch -c 1"); + + // wait for `rdpx watch` process to start + loop { + match d.exec(r1, "pgrep rdpx") { + Ok(_) => break, + Err(_) => continue + } + } + + // run rdpx on r0 sending a solicitation + d.exec(r0, "/opt/maghemite/target/debug/rdpx solicit")?; + + // wait for the receive channel on `rdpx watch` from r1 to light up. + let out = rx.recv()??; + + // dump result for debugging + println!("OUT: {}", out); + + // ensure what we got was in fact a solicitation + let msg: RDPMessage = from_str(out.as_str())?; + match msg.packet { + ICMPv6Packet::RouterSolicitation(_) => {}, + _ => return Err(anyhow!("expected router solicitation")), + }; + + Ok(()) + +} +