mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
Update a bunch of service code in keeping with new Rust core, and remove osdep stuff in favor of the libc crate.
This commit is contained in:
parent
0c0e78da1b
commit
bf482e06ea
10 changed files with 946 additions and 129 deletions
|
@ -0,0 +1,3 @@
|
|||
mod multicastgroup;
|
||||
|
||||
pub use multicastgroup::MulticastGroup;
|
53
zerotier-network-hypervisor/src/vl2/multicastgroup.rs
Normal file
53
zerotier-network-hypervisor/src/vl2/multicastgroup.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
use crate::vl1::MAC;
|
||||
use std::cmp::Ordering;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct MulticastGroup {
|
||||
pub mac: MAC,
|
||||
pub adi: u32,
|
||||
}
|
||||
|
||||
impl From<&MAC> for MulticastGroup {
|
||||
#[inline(always)]
|
||||
fn from(mac: &MAC) -> Self {
|
||||
Self {
|
||||
mac: mac.clone(),
|
||||
adi: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MAC> for MulticastGroup {
|
||||
#[inline(always)]
|
||||
fn from(mac: MAC) -> Self {
|
||||
Self {
|
||||
mac,
|
||||
adi: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for MulticastGroup {
|
||||
#[inline(always)]
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
let o = self.mac.cmp(&other.mac);
|
||||
match o {
|
||||
Ordering::Equal => self.adi.cmp(&other.adi),
|
||||
_ => o
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for MulticastGroup {
|
||||
#[inline(always)]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
|
||||
}
|
||||
|
||||
impl Hash for MulticastGroup {
|
||||
#[inline(always)]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
state.write_u64(self.mac.to_u64());
|
||||
state.write_u32(self.adi);
|
||||
}
|
||||
}
|
465
zerotier-system-service/Cargo.lock
generated
465
zerotier-system-service/Cargo.lock
generated
|
@ -2,6 +2,14 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aes-gmac-siv"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"gcrypt",
|
||||
"openssl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
|
@ -28,6 +36,12 @@ 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 = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -43,12 +57,30 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[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.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
|
||||
[[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"
|
||||
|
@ -95,6 +127,17 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concat-arrays"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1df715824eb382e34b7afb7463b0247bf41538aeba731fba05241ecdb5dc3747"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.15.0"
|
||||
|
@ -119,6 +162,39 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cstr-argument"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bd9c8e659a473bce955ae5c35b116af38af11a7acb0b480e01f3ed348aeb40"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"digest",
|
||||
"rand_core 0.5.1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "4.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dialoguer"
|
||||
version = "0.9.0"
|
||||
|
@ -149,10 +225,33 @@ dependencies = [
|
|||
"digest",
|
||||
"hex",
|
||||
"md-5",
|
||||
"rand",
|
||||
"rand 0.8.4",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc"
|
||||
dependencies = [
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519-dalek"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"ed25519",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"sha2",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
|
@ -165,6 +264,21 @@ 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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.17"
|
||||
|
@ -259,6 +373,20 @@ dependencies = [
|
|||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcrypt"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c2ee79dcb8915fc0e9d8364e87d2215555076aa159d0a5d84ba9dba109b0d59"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cstr-argument",
|
||||
"gpg-error",
|
||||
"libc",
|
||||
"libgcrypt-sys",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
|
@ -269,15 +397,35 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[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",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gpg-error"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7073b9ac823434ae73608715086e944d694a7ce2677371b8c5253300d1f767f1"
|
||||
dependencies = [
|
||||
"libgpg-error-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -352,6 +500,15 @@ dependencies = [
|
|||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
|
@ -370,13 +527,53 @@ version = "0.2.103"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
|
||||
[[package]]
|
||||
name = "libgcrypt-sys"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62eb5d6d9cd6d8c8adf9641c95b223eb14f07a7a81c082e2d08f0bf3880214e4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"libgpg-error-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libgpg-error-sys"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb1aedf0efc5d25fdd08eb52b0759c71d02ac77fd1879b96e95211239528897"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[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",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lz4_flex"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "177c079243f6867429aca5af5053747f57e329d44f0c58bebca078cd14873ec2"
|
||||
dependencies = [
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -479,6 +676,58 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[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",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[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 = "pin-project-lite"
|
||||
version = "0.2.7"
|
||||
|
@ -491,6 +740,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.14"
|
||||
|
@ -527,6 +782,19 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
@ -534,9 +802,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
"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]]
|
||||
|
@ -546,7 +824,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
"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]]
|
||||
|
@ -555,7 +842,16 @@ version = "0.6.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"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]]
|
||||
|
@ -564,7 +860,7 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"rand_core 0.6.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -606,6 +902,12 @@ version = "1.0.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.130"
|
||||
|
@ -644,7 +946,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
|
@ -659,19 +961,31 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -686,12 +1000,24 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.80"
|
||||
|
@ -703,15 +1029,27 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"rand",
|
||||
"rand 0.8.4",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
|
@ -796,7 +1134,7 @@ version = "0.1.29"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
@ -816,6 +1154,16 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||
|
||||
[[package]]
|
||||
name = "twox-hash"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.14.0"
|
||||
|
@ -834,6 +1182,18 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "urlencoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68b90931029ab9b034b300b797048cf23723400aa757e8a2bfb9d748102f9821"
|
||||
|
||||
[[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"
|
||||
|
@ -856,6 +1216,12 @@ dependencies = [
|
|||
"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"
|
||||
|
@ -885,10 +1251,71 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.4.2"
|
||||
name = "winreg"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970"
|
||||
checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x25519-dalek"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"rand_core 0.5.1",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerotier-core-crypto"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aes-gmac-siv",
|
||||
"ed25519-dalek",
|
||||
"gcrypt",
|
||||
"rand_core 0.6.3",
|
||||
"x25519-dalek",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerotier-network-hypervisor"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"concat-arrays",
|
||||
"dashmap",
|
||||
"libc",
|
||||
"lz4_flex",
|
||||
"parking_lot",
|
||||
"urlencoding",
|
||||
"winapi",
|
||||
"zerotier-core-crypto",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerotier-system-service"
|
||||
|
@ -902,6 +1329,7 @@ dependencies = [
|
|||
"futures",
|
||||
"hyper",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"num_cpus",
|
||||
|
@ -910,4 +1338,5 @@ dependencies = [
|
|||
"socket2 0.3.19",
|
||||
"tokio",
|
||||
"winapi",
|
||||
"zerotier-network-hypervisor",
|
||||
]
|
||||
|
|
|
@ -3,7 +3,6 @@ name = "zerotier-system-service"
|
|||
version = "0.1.0"
|
||||
authors = ["Adam Ierymenko <adam.ierymenko@zerotier.com>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 'z'
|
||||
|
@ -12,6 +11,7 @@ codegen-units = 1
|
|||
panic = 'abort'
|
||||
|
||||
[dependencies]
|
||||
zerotier-network-hypervisor = { path = "../zerotier-network-hypervisor" }
|
||||
num_cpus = "^1"
|
||||
tokio = { version = "1", features = ["rt", "net", "time", "signal", "macros"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
@ -30,3 +30,6 @@ colored = "^2"
|
|||
|
||||
[target."cfg(windows)".dependencies]
|
||||
winapi = { version = "^0", features = ["handleapi", "ws2ipdef", "ws2tcpip"] }
|
||||
|
||||
[target."cfg(not(windows))".dependencies]
|
||||
libc = "^0"
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#[allow(unused_assignments)]
|
||||
#[allow(unused_mut)]
|
||||
fn main() {
|
||||
let d = env!("CARGO_MANIFEST_DIR");
|
||||
println!("cargo:rustc-link-search=native={}/../build/core", d);
|
||||
println!("cargo:rustc-link-search=native={}/../build/osdep", d);
|
||||
println!("cargo:rustc-link-lib=static=zt_core");
|
||||
println!("cargo:rustc-link-lib=static=zt_osdep");
|
||||
|
||||
let mut cpplib = "c++";
|
||||
#[cfg(target_os = "linux")] {
|
||||
cpplib = "stdc++";
|
||||
}
|
||||
println!("cargo:rustc-link-lib={}", cpplib);
|
||||
}
|
|
@ -14,9 +14,7 @@
|
|||
use std::mem::size_of;
|
||||
use std::ptr::{copy_nonoverlapping, null_mut};
|
||||
|
||||
use zerotier_core::InetAddress;
|
||||
|
||||
use crate::osdep as osdep;
|
||||
use zerotier_network_hypervisor::vl1::InetAddress;
|
||||
|
||||
fn s6_addr_as_ptr<A>(a: &A) -> *const A {
|
||||
a as *const A
|
||||
|
@ -26,19 +24,19 @@ fn s6_addr_as_ptr<A>(a: &A) -> *const A {
|
|||
#[cfg(unix)]
|
||||
pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
|
||||
unsafe {
|
||||
let mut ifa_name = [0_u8; osdep::IFNAMSIZ as usize];
|
||||
let mut ifap: *mut osdep::ifaddrs = null_mut();
|
||||
if osdep::getifaddrs((&mut ifap as *mut *mut osdep::ifaddrs).cast()) == 0 {
|
||||
let mut ifa_name = [0_u8; libc::IFNAMSIZ as usize];
|
||||
let mut ifap: *mut libc::ifaddrs = null_mut();
|
||||
if libc::getifaddrs((&mut ifap as *mut *mut libc::ifaddrs).cast()) == 0 {
|
||||
let mut i = ifap;
|
||||
while !i.is_null() {
|
||||
if !(*i).ifa_addr.is_null() {
|
||||
let mut a = InetAddress::new();
|
||||
|
||||
let sa_family = (*(*i).ifa_addr).sa_family as u8;
|
||||
if sa_family == osdep::AF_INET as u8 {
|
||||
copy_nonoverlapping((*i).ifa_addr.cast::<u8>(), (&mut a as *mut InetAddress).cast::<u8>(), size_of::<osdep::sockaddr_in>());
|
||||
} else if sa_family == osdep::AF_INET6 as u8 {
|
||||
copy_nonoverlapping((*i).ifa_addr.cast::<u8>(), (&mut a as *mut InetAddress).cast::<u8>(), size_of::<osdep::sockaddr_in6>());
|
||||
if sa_family == libc::AF_INET as u8 {
|
||||
copy_nonoverlapping((*i).ifa_addr.cast::<u8>(), (&mut a as *mut InetAddress).cast::<u8>(), size_of::<libc::sockaddr_in>());
|
||||
} else if sa_family == libc::AF_INET6 as u8 {
|
||||
copy_nonoverlapping((*i).ifa_addr.cast::<u8>(), (&mut a as *mut InetAddress).cast::<u8>(), size_of::<libc::sockaddr_in6>());
|
||||
} else {
|
||||
i = (*i).ifa_next;
|
||||
continue;
|
||||
|
@ -46,11 +44,11 @@ pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
|
|||
|
||||
let mut netmask_bits: u16 = 0;
|
||||
if !(*i).ifa_netmask.is_null() {
|
||||
if sa_family == osdep::AF_INET as u8 {
|
||||
let a = (*(*i).ifa_netmask.cast::<osdep::sockaddr_in>()).sin_addr.s_addr as u32;
|
||||
if sa_family == libc::AF_INET as u8 {
|
||||
let a = (*(*i).ifa_netmask.cast::<libc::sockaddr_in>()).sin_addr.s_addr as u32;
|
||||
netmask_bits = a.leading_ones() as u16;
|
||||
} else if sa_family == osdep::AF_INET6 as u8 {
|
||||
let a = s6_addr_as_ptr(&((*(*i).ifa_netmask.cast::<osdep::sockaddr_in6>()).sin6_addr)).cast::<u8>();
|
||||
} else if sa_family == libc::AF_INET6 as u8 {
|
||||
let a = s6_addr_as_ptr(&((*(*i).ifa_netmask.cast::<libc::sockaddr_in6>()).sin6_addr)).cast::<u8>();
|
||||
for i in 0..16 as isize {
|
||||
let b = *a.offset(i);
|
||||
if b == 0xff {
|
||||
|
@ -65,7 +63,7 @@ pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
|
|||
a.set_port(netmask_bits);
|
||||
|
||||
let mut namlen: usize = 0;
|
||||
while namlen < (osdep::IFNAMSIZ as usize) {
|
||||
while namlen < (libc::IFNAMSIZ as usize) {
|
||||
let c = *(*i).ifa_name.offset(namlen as isize);
|
||||
if c != 0 {
|
||||
ifa_name[namlen] = c as u8;
|
||||
|
@ -83,14 +81,14 @@ pub(crate) fn for_each_address<F: FnMut(&InetAddress, &str)>(mut f: F) {
|
|||
}
|
||||
i = (*i).ifa_next;
|
||||
}
|
||||
osdep::freeifaddrs(ifap.cast());
|
||||
libc::freeifaddrs(ifap.cast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use zerotier_core::InetAddress;
|
||||
use zerotier_network_hypervisor::vl1::InetAddress;
|
||||
|
||||
#[test]
|
||||
fn test_getifaddrs() {
|
||||
|
|
|
@ -92,7 +92,7 @@ Common Operations:
|
|||
Advanced Operations:
|
||||
|
||||
service Start node
|
||||
(usually not invoked directly)
|
||||
(usually run by service manager)
|
||||
|
||||
controller <command> [option]
|
||||
· list List networks on controller
|
||||
|
|
|
@ -13,36 +13,51 @@
|
|||
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use zerotier_core::{MAC, MulticastGroup};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use num_traits::AsPrimitive;
|
||||
|
||||
/// BSD based OSes support getifmaddrs().
|
||||
#[allow(unused_imports)]
|
||||
use std::os::raw::c_int;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use zerotier_network_hypervisor::vl1::MAC;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "freebsd", target_os = "darwin"))]
|
||||
pub(crate) fn get_l2_multicast_subscriptions(dev: &str) -> HashSet<MulticastGroup> {
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct ifmaddrs {
|
||||
ifma_next: *mut ifmaddrs,
|
||||
ifma_name: *mut libc::sockaddr,
|
||||
ifma_addr: *mut libc::sockaddr,
|
||||
ifma_lladdr: *mut libc::sockaddr,
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "freebsd", target_os = "darwin"))]
|
||||
extern "C" {
|
||||
fn getifmaddrs(ifmap: *mut *mut ifmaddrs) -> c_int;
|
||||
fn freeifmaddrs(ifmp: *mut ifmaddrs);
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "freebsd", target_os = "darwin"))]
|
||||
pub fn get_l2_multicast_subscriptions(dev: &str) -> HashSet<MAC> {
|
||||
let mut groups: HashSet<MulticastGroup> = HashSet::new();
|
||||
let dev = dev.as_bytes();
|
||||
unsafe {
|
||||
let mut maddrs: *mut osdep::ifmaddrs = std::ptr::null_mut();
|
||||
if osdep::getifmaddrs(&mut maddrs as *mut *mut osdep::ifmaddrs) == 0 {
|
||||
let mut maddrs: *mut ifmaddrs = std::ptr::null_mut();
|
||||
if getifmaddrs(&mut maddrs as *mut *mut ifmaddrs) == 0 {
|
||||
let mut i = maddrs;
|
||||
while !i.is_null() {
|
||||
if !(*i).ifma_name.is_null() && !(*i).ifma_addr.is_null() && (*(*i).ifma_addr).sa_family as i32 == osdep::AF_LINK as i32 {
|
||||
let in_: &osdep::sockaddr_dl = &*((*i).ifma_name.cast());
|
||||
let la: &osdep::sockaddr_dl = &*((*i).ifma_addr.cast());
|
||||
if la.sdl_alen == 6 && in_.sdl_nlen <= dev.len().as_() && crate::osdep::memcmp(dev.as_ptr().cast(), in_.sdl_data.as_ptr().cast(), in_.sdl_nlen.as_()) == 0 {
|
||||
if !(*i).ifma_name.is_null() && !(*i).ifma_addr.is_null() && (*(*i).ifma_addr).sa_family as i32 == libc::AF_LINK as i32 {
|
||||
let in_: &libc::sockaddr_dl = &*((*i).ifma_name.cast());
|
||||
let la: &libc::sockaddr_dl = &*((*i).ifma_addr.cast());
|
||||
if la.sdl_alen == 6 && in_.sdl_nlen <= dev.len().as_() && crate::libc::memcmp(dev.as_ptr().cast(), in_.sdl_data.as_ptr().cast(), in_.sdl_nlen.as_()) == 0 {
|
||||
let mi = la.sdl_nlen as usize;
|
||||
groups.insert(MulticastGroup{
|
||||
mac: MAC((la.sdl_data[mi] as u64) << 40 | (la.sdl_data[mi+1] as u64) << 32 | (la.sdl_data[mi+2] as u64) << 24 | (la.sdl_data[mi+3] as u64) << 16 | (la.sdl_data[mi+4] as u64) << 8 | la.sdl_data[mi+5] as u64),
|
||||
adi: 0,
|
||||
});
|
||||
groups.insert(MAC::from_u64((la.sdl_data[mi] as u64) << 40 | (la.sdl_data[mi+1] as u64) << 32 | (la.sdl_data[mi+2] as u64) << 24 | (la.sdl_data[mi+3] as u64) << 16 | (la.sdl_data[mi+4] as u64) << 8 | la.sdl_data[mi+5] as u64));
|
||||
}
|
||||
}
|
||||
i = (*i).ifma_next;
|
||||
}
|
||||
osdep::freeifmaddrs(maddrs);
|
||||
freeifmaddrs(maddrs);
|
||||
}
|
||||
}
|
||||
groups
|
||||
|
@ -50,7 +65,7 @@ pub(crate) fn get_l2_multicast_subscriptions(dev: &str) -> HashSet<MulticastGrou
|
|||
|
||||
/// Linux stores this stuff in /proc and it needs to be fetched from there.
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) fn get_l2_multicast_subscriptions(dev: &str) -> HashSet<MulticastGroup> {
|
||||
pub fn get_l2_multicast_subscriptions(dev: &str) -> HashSet<MAC> {
|
||||
let mut groups: HashSet<MulticastGroup> = HashSet::new();
|
||||
groups
|
||||
}
|
||||
|
|
|
@ -39,22 +39,21 @@ use std::cell::Cell;
|
|||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::ffi::CString;
|
||||
use std::ptr::{null_mut, copy_nonoverlapping};
|
||||
use std::mem::{transmute, zeroed};
|
||||
use std::os::raw::{c_int, c_uchar, c_void};
|
||||
use std::os::raw::{c_char, c_int, c_short, c_uchar, c_uint, c_void};
|
||||
use std::process::Command;
|
||||
use std::ptr::{copy_nonoverlapping, null_mut};
|
||||
use std::sync::Mutex;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use num_traits::cast::AsPrimitive;
|
||||
|
||||
use zerotier_core::{InetAddress, MAC, MulticastGroup, NetworkId};
|
||||
use zerotier_network_hypervisor::vl1::{InetAddress, MAC};
|
||||
|
||||
use crate::osdep as osdep;
|
||||
use crate::getifaddrs;
|
||||
use crate::vnic::vnic::VNIC;
|
||||
use crate::osdep::getifmaddrs;
|
||||
use zerotier_network_hypervisor::vl2::MulticastGroup;
|
||||
|
||||
const BPF_BUFFER_SIZE: usize = 131072;
|
||||
const IFCONFIG: &'static str = "/sbin/ifconfig";
|
||||
|
@ -81,7 +80,7 @@ impl Drop for MacFethDevice {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct MacFethTap {
|
||||
pub struct MacFethTap {
|
||||
network_id: u64,
|
||||
device: MacFethDevice,
|
||||
ndrv_fd: c_int,
|
||||
|
@ -104,26 +103,227 @@ lazy_static! {
|
|||
static ref MAC_FETH_BPF_DEVICES_USED: Mutex<BTreeSet<u32>> = Mutex::new(BTreeSet::new());
|
||||
}
|
||||
|
||||
/*
|
||||
struct nd_ifinfo {
|
||||
u_int32_t linkmtu; /* LinkMTU */
|
||||
u_int32_t maxmtu; /* Upper bound of LinkMTU */
|
||||
u_int32_t basereachable; /* BaseReachableTime */
|
||||
u_int32_t reachable; /* Reachable Time */
|
||||
u_int32_t retrans; /* Retrans Timer */
|
||||
u_int32_t flags; /* Flags */
|
||||
int recalctm; /* BaseReacable re-calculation timer */
|
||||
u_int8_t chlim; /* CurHopLimit */
|
||||
u_int8_t receivedra;
|
||||
};
|
||||
struct in6_ndireq {
|
||||
char ifname[IFNAMSIZ];
|
||||
struct nd_ifinfo ndi;
|
||||
};
|
||||
struct in6_addrlifetime {
|
||||
time_t ia6t_expire; /* valid lifetime expiration time */
|
||||
time_t ia6t_preferred; /* preferred lifetime expiration time */
|
||||
u_int32_t ia6t_vltime; /* valid lifetime */
|
||||
u_int32_t ia6t_pltime; /* prefix lifetime */
|
||||
};
|
||||
struct in6_ifstat {
|
||||
ifs6_in_receive; /* # of total input datagram */
|
||||
ifs6_in_hdrerr; /* # of datagrams with invalid hdr */
|
||||
ifs6_in_toobig; /* # of datagrams exceeded MTU */
|
||||
ifs6_in_noroute; /* # of datagrams with no route */
|
||||
ifs6_in_addrerr; /* # of datagrams with invalid dst */
|
||||
ifs6_in_protounknown; /* # of datagrams with unknown proto */
|
||||
/* NOTE: increment on final dst if */
|
||||
ifs6_in_truncated; /* # of truncated datagrams */
|
||||
ifs6_in_discard; /* # of discarded datagrams */
|
||||
/* NOTE: fragment timeout is not here */
|
||||
ifs6_in_deliver; /* # of datagrams delivered to ULP */
|
||||
/* NOTE: increment on final dst if */
|
||||
ifs6_out_forward; /* # of datagrams forwarded */
|
||||
/* NOTE: increment on outgoing if */
|
||||
ifs6_out_request; /* # of outgoing datagrams from ULP */
|
||||
/* NOTE: does not include forwrads */
|
||||
ifs6_out_discard; /* # of discarded datagrams */
|
||||
ifs6_out_fragok; /* # of datagrams fragmented */
|
||||
ifs6_out_fragfail; /* # of datagrams failed on fragment */
|
||||
ifs6_out_fragcreat; /* # of fragment datagrams */
|
||||
/* NOTE: this is # after fragment */
|
||||
ifs6_reass_reqd; /* # of incoming fragmented packets */
|
||||
/* NOTE: increment on final dst if */
|
||||
ifs6_reass_ok; /* # of reassembled packets */
|
||||
/* NOTE: this is # after reass */
|
||||
/* NOTE: increment on final dst if */
|
||||
ifs6_atmfrag_rcvd; /* # of atomic fragments received */
|
||||
ifs6_reass_fail; /* # of reass failures */
|
||||
/* NOTE: may not be packet count */
|
||||
/* NOTE: increment on final dst if */
|
||||
ifs6_in_mcast; /* # of inbound multicast datagrams */
|
||||
ifs6_out_mcast; /* # of outbound multicast datagrams */
|
||||
|
||||
ifs6_cantfoward_icmp6; /* # of ICMPv6 packets received for unreachable dest */
|
||||
ifs6_addr_expiry_cnt; /* # of address expiry events (excluding privacy addresses) */
|
||||
ifs6_pfx_expiry_cnt; /* # of prefix expiry events */
|
||||
ifs6_defrtr_expiry_cnt; /* # of default router expiry events */
|
||||
};
|
||||
struct in6_ifreq {
|
||||
char ifr_name[IFNAMSIZ];
|
||||
union {
|
||||
struct sockaddr_in6 ifru_addr;
|
||||
struct sockaddr_in6 ifru_dstaddr;
|
||||
int ifru_flags;
|
||||
int ifru_flags6;
|
||||
int ifru_metric;
|
||||
int ifru_intval;
|
||||
caddr_t ifru_data;
|
||||
struct in6_addrlifetime ifru_lifetime;
|
||||
struct in6_ifstat ifru_stat;
|
||||
struct icmp6_ifstat ifru_icmp6stat;
|
||||
u_int32_t ifru_scope_id[SCOPE6_ID_MAX];
|
||||
} ifr_ifru;
|
||||
};
|
||||
*/
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct icmp6_ifstat {
|
||||
ifs6_in_msg: u64,
|
||||
ifs6_in_error: u64,
|
||||
ifs6_in_dstunreach: u64,
|
||||
ifs6_in_adminprohib: u64,
|
||||
ifs6_in_timeexceed: u64,
|
||||
ifs6_in_paramprob: u64,
|
||||
ifs6_in_pkttoobig: u64,
|
||||
ifs6_in_echo: u64,
|
||||
ifs6_in_echoreply: u64,
|
||||
ifs6_in_routersolicit: u64,
|
||||
ifs6_in_routeradvert: u64,
|
||||
ifs6_in_neighborsolicit: u64,
|
||||
ifs6_in_neighboradvert: u64,
|
||||
ifs6_in_redirect: u64,
|
||||
ifs6_in_mldquery: u64,
|
||||
ifs6_in_mldreport: u64,
|
||||
ifs6_in_mlddone: u64,
|
||||
ifs6_out_msg: u64,
|
||||
ifs6_out_error: u64,
|
||||
ifs6_out_dstunreach: u64,
|
||||
ifs6_out_adminprohib: u64,
|
||||
ifs6_out_timeexceed: u64,
|
||||
ifs6_out_paramprob: u64,
|
||||
ifs6_out_pkttoobig: u64,
|
||||
ifs6_out_echo: u64,
|
||||
ifs6_out_echoreply: u64,
|
||||
ifs6_out_routersolicit: u64,
|
||||
ifs6_out_routeradvert: u64,
|
||||
ifs6_out_neighborsolicit: u64,
|
||||
ifs6_out_neighboradvert: u64,
|
||||
ifs6_out_redirect: u64,
|
||||
ifs6_out_mldquery: u64,
|
||||
ifs6_out_mldreport: u64,
|
||||
ifs6_out_mlddone: u64,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct in6_ifstat {
|
||||
ifs6_in_receive: u64,
|
||||
ifs6_in_hdrerr: u64,
|
||||
ifs6_in_toobig: u64,
|
||||
ifs6_in_noroute: u64,
|
||||
ifs6_in_addrerr: u64,
|
||||
ifs6_in_protounknown: u64,
|
||||
ifs6_in_truncated: u64,
|
||||
ifs6_in_discard: u64,
|
||||
ifs6_in_deliver: u64,
|
||||
ifs6_out_forward: u64,
|
||||
ifs6_out_request: u64,
|
||||
ifs6_out_discard: u64,
|
||||
ifs6_out_fragok: u64,
|
||||
ifs6_out_fragfail: u64,
|
||||
ifs6_out_fragcreat: u64,
|
||||
ifs6_reass_reqd: u64,
|
||||
ifs6_reass_ok: u64,
|
||||
ifs6_atmfrag_rcvd: u64,
|
||||
ifs6_reass_fail: u64,
|
||||
ifs6_in_mcast: u64,
|
||||
ifs6_out_mcast: u64,
|
||||
ifs6_cantfoward_icmp6: u64,
|
||||
ifs6_addr_expiry_cnt: u64,
|
||||
ifs6_pfx_expiry_cnt: u64,
|
||||
ifs6_defrtr_expiry_cnt: u64,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct in6_addrlifetime {
|
||||
ia6t_expire: libc::time_t,
|
||||
ia6t_preferred: libc::time_t,
|
||||
ia6t_vltime: u32,
|
||||
ia6t_pltime: u32,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
union u_ifr_ifru {
|
||||
ifru_addr: libc::sockaddr_in6,
|
||||
ifru_dstaddr: libc::sockaddr_in6,
|
||||
ifru_flags: c_int,
|
||||
ifru_flags6: c_int,
|
||||
ifru_metric: c_int,
|
||||
ifru_intval: c_int,
|
||||
ifru_data: *mut c_void,
|
||||
ifru_lifetime: in6_addrlifetime,
|
||||
ifru_stat: in6_ifstat,
|
||||
ifru_icmp6stat: icmp6_ifstat,
|
||||
ifru_scope_id: [u32; 16 /* SCOPE6_ID_MAX */],
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct in6_ifreq {
|
||||
ifr_name: [c_char; libc::IFNAMSIZ],
|
||||
ifr_ifru: u_ifr_ifru,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct nd_ifinfo {
|
||||
linkmtu: u32,
|
||||
maxmtu: u32,
|
||||
basereachable: u32,
|
||||
reachable: u32,
|
||||
retrans: u32,
|
||||
flags: u32,
|
||||
recalctm: c_int,
|
||||
chlim: u8,
|
||||
receivedra: u8,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct in6_ndireq {
|
||||
ifname: [c_char; libc::IFNAMSIZ],
|
||||
ndi: nd_ifinfo,
|
||||
}
|
||||
|
||||
fn device_ipv6_set_params(device: &String, perform_nud: bool, accept_ra: bool) -> bool {
|
||||
let dev = device.as_bytes();
|
||||
let mut ok = true;
|
||||
unsafe {
|
||||
let s = osdep::socket(osdep::AF_INET6 as c_int, osdep::SOCK_DGRAM as c_int, 0);
|
||||
let s = libc::socket(libc::AF_INET6 as c_int, libc::SOCK_DGRAM as c_int, 0);
|
||||
if s < 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut nd: osdep::in6_ndireq = zeroed();
|
||||
let mut nd: in6_ndireq = zeroed();
|
||||
copy_nonoverlapping(dev.as_ptr(), nd.ifname.as_mut_ptr().cast::<u8>(), if dev.len() > (nd.ifname.len() - 1) { nd.ifname.len() - 1 } else { dev.len() });
|
||||
if osdep::ioctl(s, osdep::c_SIOCGIFINFO_IN6, (&mut nd as *mut osdep::in6_ndireq).cast::<c_void>()) == 0 {
|
||||
if libc::ioctl(s, 76 /* SIOCGIFINFO_IN6 */, (&mut nd as *mut in6_ndireq).cast::<c_void>()) == 0 {
|
||||
let oldflags = nd.ndi.flags;
|
||||
if perform_nud {
|
||||
nd.ndi.flags |= osdep::ND6_IFF_PERFORMNUD as osdep::u_int32_t;
|
||||
nd.ndi.flags |= 0x1 /* ND6_IFF_PERFORMNUD */;
|
||||
} else {
|
||||
nd.ndi.flags &= !(osdep::ND6_IFF_PERFORMNUD as osdep::u_int32_t);
|
||||
nd.ndi.flags &= !0x1 /* !ND6_IFF_PERFORMNUD */;
|
||||
}
|
||||
if nd.ndi.flags != oldflags {
|
||||
if osdep::ioctl(s, osdep::c_SIOCSIFINFO_FLAGS, (&mut nd as *mut osdep::in6_ndireq).cast::<c_void>()) != 0 {
|
||||
if libc::ioctl(s, 87 /* SIOCSIFINFO_FLAGS */, (&mut nd as *mut in6_ndireq).cast::<c_void>()) != 0 {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
@ -131,17 +331,144 @@ fn device_ipv6_set_params(device: &String, perform_nud: bool, accept_ra: bool) -
|
|||
ok = false;
|
||||
}
|
||||
|
||||
let mut ifr: osdep::in6_ifreq = zeroed();
|
||||
let mut ifr: in6_ifreq = zeroed();
|
||||
copy_nonoverlapping(dev.as_ptr(), ifr.ifr_name.as_mut_ptr().cast::<u8>(), if dev.len() > (ifr.ifr_name.len() - 1) { ifr.ifr_name.len() - 1 } else { dev.len() });
|
||||
if osdep::ioctl(s, if accept_ra { osdep::c_SIOCAUTOCONF_START } else { osdep::c_SIOCAUTOCONF_STOP }, (&mut ifr as *mut osdep::in6_ifreq).cast::<c_void>()) != 0 {
|
||||
if libc::ioctl(s, if accept_ra { 132 /* SIOCAUTOCONF_START */ } else { 133 /* SIOCAUTOCONF_STOP */ }, (&mut ifr as *mut in6_ifreq).cast::<c_void>()) != 0 {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
osdep::close(s);
|
||||
libc::close(s);
|
||||
}
|
||||
ok
|
||||
}
|
||||
|
||||
/*
|
||||
struct ifkpi {
|
||||
unsigned int ifk_module_id;
|
||||
unsigned int ifk_type;
|
||||
union {
|
||||
void *ifk_ptr;
|
||||
int ifk_value;
|
||||
} ifk_data;
|
||||
};
|
||||
struct ifdevmtu {
|
||||
int ifdm_current;
|
||||
int ifdm_min;
|
||||
int ifdm_max;
|
||||
};
|
||||
struct ifreq {
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ IF_NAMESIZE
|
||||
#endif
|
||||
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
union {
|
||||
struct sockaddr ifru_addr;
|
||||
struct sockaddr ifru_dstaddr;
|
||||
struct sockaddr ifru_broadaddr;
|
||||
short ifru_flags;
|
||||
int ifru_metric;
|
||||
int ifru_mtu;
|
||||
int ifru_phys;
|
||||
int ifru_media;
|
||||
int ifru_intval;
|
||||
caddr_t ifru_data;
|
||||
struct ifdevmtu ifru_devmtu;
|
||||
struct ifkpi ifru_kpi;
|
||||
u_int32_t ifru_wake_flags;
|
||||
u_int32_t ifru_route_refcnt;
|
||||
int ifru_cap[2];
|
||||
u_int32_t ifru_functional_type;
|
||||
#define IFRTYPE_FUNCTIONAL_UNKNOWN 0
|
||||
#define IFRTYPE_FUNCTIONAL_LOOPBACK 1
|
||||
#define IFRTYPE_FUNCTIONAL_WIRED 2
|
||||
#define IFRTYPE_FUNCTIONAL_WIFI_INFRA 3
|
||||
#define IFRTYPE_FUNCTIONAL_WIFI_AWDL 4
|
||||
#define IFRTYPE_FUNCTIONAL_CELLULAR 5
|
||||
#define IFRTYPE_FUNCTIONAL_INTCOPROC 6
|
||||
#define IFRTYPE_FUNCTIONAL_COMPANIONLINK 7
|
||||
#define IFRTYPE_FUNCTIONAL_LAST 7
|
||||
} ifr_ifru;
|
||||
#define ifr_addr ifr_ifru.ifru_addr /* address */
|
||||
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
|
||||
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
|
||||
#ifdef __APPLE__
|
||||
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
||||
#else
|
||||
#define ifr_flags ifr_ifru.ifru_flags[0] /* flags */
|
||||
#define ifr_prevflags ifr_ifru.ifru_flags[1] /* flags */
|
||||
#endif /* __APPLE__ */
|
||||
#define ifr_metric ifr_ifru.ifru_metric /* metric */
|
||||
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
|
||||
#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
|
||||
#define ifr_media ifr_ifru.ifru_media /* physical media */
|
||||
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
|
||||
#define ifr_devmtu ifr_ifru.ifru_devmtu
|
||||
#define ifr_intval ifr_ifru.ifru_intval /* integer value */
|
||||
#define ifr_kpi ifr_ifru.ifru_kpi
|
||||
#define ifr_wake_flags ifr_ifru.ifru_wake_flags /* wake capabilities */
|
||||
#define ifr_route_refcnt ifr_ifru.ifru_route_refcnt /* route references count */
|
||||
#define ifr_reqcap ifr_ifru.ifru_cap[0] /* requested capabilities */
|
||||
#define ifr_curcap ifr_ifru.ifru_cap[1] /* current capabilities */
|
||||
};
|
||||
struct sockaddr_ndrv {
|
||||
unsigned char snd_len;
|
||||
unsigned char snd_family;
|
||||
unsigned char snd_name[IFNAMSIZ]; /* from if.h */
|
||||
};
|
||||
*/
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct ifkpi {
|
||||
ifk_module_id: c_uint,
|
||||
ifk_type: c_uint,
|
||||
ifk_data: *mut c_void,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct ifdevmtu {
|
||||
ifdm_current: c_int,
|
||||
ifdm_min: c_int,
|
||||
ifdm_max: c_int,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
union ifr_ifru {
|
||||
ifru_addr: libc::sockaddr,
|
||||
ifru_dstaddr: libc::sockaddr,
|
||||
ifru_broadaddr: libc::sockaddr,
|
||||
ifru_flags: c_short,
|
||||
ifru_metric: c_int,
|
||||
ifru_mtu: c_int,
|
||||
ifru_phys: c_int,
|
||||
ifru_media: c_int,
|
||||
ifru_intval: c_int,
|
||||
ifru_data: u64,
|
||||
ifru_devmtu: ifdevmtu,
|
||||
ifru_kpi: ifkpi,
|
||||
ifru_wake_flags: u32,
|
||||
ifru_route_refcnt: u32,
|
||||
ifru_cap: [c_int; 2],
|
||||
ifru_functional_type: u32,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct ifreq {
|
||||
ifr_name: [c_char; libc::IFNAMSIZ],
|
||||
ifr_ifru: ifr_ifru,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
struct sockaddr_ndrv {
|
||||
snd_len: c_uchar,
|
||||
snd_family: c_uchar,
|
||||
snd_name: [c_uchar; libc::IFNAMSIZ],
|
||||
}
|
||||
|
||||
impl MacFethTap {
|
||||
/// Create a new MacFethTap with a function to call for Ethernet frames.
|
||||
/// The function F should return as quickly as possible. It should pass copies
|
||||
|
@ -149,13 +476,13 @@ impl MacFethTap {
|
|||
/// given will not remain valid after it returns. Also note that F will be called
|
||||
/// from another thread that is spawned here, so all its bound references must
|
||||
/// be "Send" and "Sync" e.g. Arc<>.
|
||||
pub(crate) fn new<F: Fn(&[u8]) + Send + Sync + 'static>(nwid: &NetworkId, mac: &MAC, mtu: i32, metric: i32, eth_frame_func: F) -> Result<MacFethTap, String> {
|
||||
pub fn new<F: Fn(&[u8]) + Send + Sync + 'static>(nwid: &NetworkId, mac: &MAC, mtu: i32, metric: i32, eth_frame_func: F) -> Result<MacFethTap, String> {
|
||||
// This tracks BPF devices we are using so we don't try to reopen them, and also
|
||||
// doubles as a global lock to ensure that only one feth tap is created at once per
|
||||
// ZeroTier process per system.
|
||||
let mut bpf_devices_used = MAC_FETH_BPF_DEVICES_USED.lock().unwrap();
|
||||
|
||||
if unsafe { osdep::getuid() } != 0 {
|
||||
if unsafe { libc::getuid() } != 0 {
|
||||
return Err(String::from("ZeroTier MacFethTap must run as root"));
|
||||
}
|
||||
|
||||
|
@ -245,7 +572,7 @@ impl MacFethTap {
|
|||
} else {
|
||||
let bpf_dev = CString::new(format!("/dev/bpf{}", bpf_no)).unwrap();
|
||||
let bpf_dev = bpf_dev.as_bytes_with_nul();
|
||||
bpf_fd = unsafe { osdep::open(bpf_dev.as_ptr().cast(), osdep::O_RDWR as c_int) };
|
||||
bpf_fd = unsafe { libc::open(bpf_dev.as_ptr().cast(), libc::O_RDWR as c_int) };
|
||||
if bpf_fd >= 0 {
|
||||
break;
|
||||
}
|
||||
|
@ -262,60 +589,60 @@ impl MacFethTap {
|
|||
// Set/get buffer length to use with reads from BPF device, trying to
|
||||
// use up to BPF_BUFFER_SIZE bytes.
|
||||
let mut fl: c_int = BPF_BUFFER_SIZE as c_int;
|
||||
if unsafe { osdep::ioctl(bpf_fd as c_int, osdep::c_BIOCSBLEN, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
if unsafe { libc::ioctl(bpf_fd as c_int, 102 /* BIOCSBLEN */, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
return Err(String::from("unable to configure BPF device"));
|
||||
}
|
||||
let bpf_read_size = fl as osdep::size_t;
|
||||
let bpf_read_size = fl as libc::size_t;
|
||||
|
||||
// Set immediate mode for "live" capture.
|
||||
fl = 1;
|
||||
if unsafe { osdep::ioctl(bpf_fd as c_int, osdep::c_BIOCIMMEDIATE, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
if unsafe { libc::ioctl(bpf_fd as c_int, 112 /* BIOCIMMEDIATE */, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
return Err(String::from("unable to configure BPF device"));
|
||||
}
|
||||
|
||||
// Do not send us back packets we inject or send.
|
||||
fl = 0;
|
||||
if unsafe { osdep::ioctl(bpf_fd as c_int, osdep::c_BIOCSSEESENT, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
if unsafe { libc::ioctl(bpf_fd as c_int, 119 /* BIOCSSEESENT */, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
return Err(String::from("unable to configure BPF device"));
|
||||
}
|
||||
|
||||
// Bind BPF to secondary feth device.
|
||||
let mut bpf_ifr: osdep::ifreq = unsafe { std::mem::zeroed() };
|
||||
let mut bpf_ifr: ifreq = unsafe { std::mem::zeroed() };
|
||||
let peer_dev_name_bytes = device.peer_name.as_bytes();
|
||||
unsafe { copy_nonoverlapping(peer_dev_name_bytes.as_ptr(), bpf_ifr.ifr_name.as_mut_ptr().cast::<u8>(), if peer_dev_name_bytes.len() > (bpf_ifr.ifr_name.len() - 1) { bpf_ifr.ifr_name.len() - 1 } else { peer_dev_name_bytes.len() }); }
|
||||
if unsafe { osdep::ioctl(bpf_fd as c_int, osdep::c_BIOCSETIF, (&mut bpf_ifr as *mut osdep::ifreq).cast::<c_void>()) } != 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
if unsafe { libc::ioctl(bpf_fd as c_int, 108 /* BIOCSETIF */, (&mut bpf_ifr as *mut ifreq).cast::<c_void>()) } != 0 {
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
return Err(String::from("unable to configure BPF device"));
|
||||
}
|
||||
|
||||
// Include Ethernet header in BPF captures.
|
||||
fl = 1;
|
||||
if unsafe { osdep::ioctl(bpf_fd as c_int, osdep::c_BIOCSHDRCMPLT, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
if unsafe { libc::ioctl(bpf_fd as c_int, 117 /* BIOCSHDRCMPLT */, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
return Err(String::from("unable to configure BPF device"));
|
||||
}
|
||||
|
||||
// Set promiscuous mode so bridging can work.
|
||||
fl = 1;
|
||||
if unsafe { osdep::ioctl(bpf_fd as c_int, osdep::c_BIOCPROMISC, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
if unsafe { libc::ioctl(bpf_fd as c_int, 105 /* BIOCPROMISC */, (&mut fl as *mut c_int).cast::<c_void>()) } != 0 {
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
return Err(String::from("unable to configure BPF device"));
|
||||
}
|
||||
|
||||
// Create BPF listener thread, which calls the supplied function on each incoming packet.
|
||||
let t = std::thread::Builder::new().stack_size(zerotier_core::RECOMMENDED_THREAD_STACK_SIZE).spawn(move || {
|
||||
let mut buf: [u8; BPF_BUFFER_SIZE] = [0_u8; BPF_BUFFER_SIZE];
|
||||
let hdr_struct_size = std::mem::size_of::<osdep::bpf_hdr>() as isize;
|
||||
let hdr_struct_size = std::mem::size_of::<libc::bpf_hdr>() as isize;
|
||||
loop {
|
||||
let n = unsafe { osdep::read(bpf_fd, buf.as_mut_ptr().cast(), bpf_read_size) } as isize;
|
||||
let n = unsafe { libc::read(bpf_fd, buf.as_mut_ptr().cast(), bpf_read_size) } as isize;
|
||||
if n >= 0 {
|
||||
let mut p: isize = 0;
|
||||
while (p + hdr_struct_size) < n {
|
||||
unsafe {
|
||||
let h = buf.as_ptr().offset(p).cast::<osdep::bpf_hdr>();
|
||||
let h = buf.as_ptr().offset(p).cast::<libc::bpf_hdr>();
|
||||
let hdrlen = (*h).bh_hdrlen as isize;
|
||||
let caplen = (*h).bh_caplen as isize;
|
||||
let pktlen = hdrlen + caplen;
|
||||
|
@ -331,30 +658,30 @@ impl MacFethTap {
|
|||
}
|
||||
});
|
||||
if t.is_err() {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
return Err(String::from("unable to start thread"));
|
||||
}
|
||||
|
||||
// Create AF_NDRV socket used to inject packets. We could inject with BPF but that has
|
||||
// a hard MTU limit of 2048 so we have to use AF_NDRV instead. Performance is probably
|
||||
// the same, but it means another socket.
|
||||
let ndrv_fd = unsafe { osdep::socket(osdep::AF_NDRV as c_int, osdep::SOCK_RAW as c_int, 0) };
|
||||
let ndrv_fd = unsafe { libc::socket(27 /* AF_NDRV */, libc::SOCK_RAW, 0) };
|
||||
if ndrv_fd < 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
return Err(String::from("unable to create AF_NDRV socket"));
|
||||
}
|
||||
let mut ndrv_sa: osdep::sockaddr_ndrv = unsafe { std::mem::zeroed() };
|
||||
ndrv_sa.snd_len = std::mem::size_of::<osdep::sockaddr_ndrv>() as c_uchar;
|
||||
ndrv_sa.snd_family = osdep::AF_NDRV as c_uchar;
|
||||
let mut ndrv_sa: sockaddr_ndrv = unsafe { std::mem::zeroed() };
|
||||
ndrv_sa.snd_len = std::mem::size_of::<sockaddr_ndrv>() as c_uchar;
|
||||
ndrv_sa.snd_family = 27 /* AF_NDRV */;
|
||||
unsafe { copy_nonoverlapping(peer_dev_name_bytes.as_ptr(), ndrv_sa.snd_name.as_mut_ptr().cast::<u8>(), if peer_dev_name_bytes.len() > (bpf_ifr.ifr_name.len() - 1) { bpf_ifr.ifr_name.len() - 1 } else { peer_dev_name_bytes.len() }); }
|
||||
if unsafe { osdep::bind(ndrv_fd, (&ndrv_sa as *const osdep::sockaddr_ndrv).cast(), std::mem::size_of::<osdep::sockaddr_ndrv>() as osdep::socklen_t) } != 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
unsafe { osdep::close(ndrv_fd); }
|
||||
if unsafe { libc::bind(ndrv_fd, (&ndrv_sa as *const sockaddr_ndrv).cast(), std::mem::size_of::<sockaddr_ndrv>() as libc::socklen_t) } != 0 {
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
unsafe { libc::close(ndrv_fd); }
|
||||
return Err(String::from("unable to bind AF_NDRV socket"));
|
||||
}
|
||||
if unsafe { osdep::connect(ndrv_fd, (&ndrv_sa as *const osdep::sockaddr_ndrv).cast(), std::mem::size_of::<osdep::sockaddr_ndrv>() as osdep::socklen_t) } != 0 {
|
||||
unsafe { osdep::close(bpf_fd); }
|
||||
unsafe { osdep::close(ndrv_fd); }
|
||||
if unsafe { libc::connect(ndrv_fd, (&ndrv_sa as *const sockaddr_ndrv).cast(), std::mem::size_of::<sockaddr_ndrv>() as libc::socklen_t) } != 0 {
|
||||
unsafe { libc::close(bpf_fd); }
|
||||
unsafe { libc::close(ndrv_fd); }
|
||||
return Err(String::from("unable to connect AF_NDRV socket"));
|
||||
}
|
||||
|
||||
|
@ -417,14 +744,16 @@ impl VNIC for MacFethTap {
|
|||
ipv
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn device_name(&self) -> String {
|
||||
self.device.name.clone()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn get_multicast_groups(&self) -> HashSet<MulticastGroup> {
|
||||
crate::vnic::common::get_l2_multicast_subscriptions(self.device.name.as_str())
|
||||
let mut all_groups: HashSet<MulticastGroup> = HashSet::new();
|
||||
crate::vnic::common::get_l2_multicast_subscriptions(self.device.name.as_str()).into_iter().for_each(|mac| {
|
||||
all_groups.insert(MulticastGroup::from(&mac));
|
||||
});
|
||||
all_groups
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -433,17 +762,17 @@ impl VNIC for MacFethTap {
|
|||
let sm = source_mac.0;
|
||||
let mut hdr: [u8; 14] = [(dm >> 40) as u8, (dm >> 32) as u8, (dm >> 24) as u8, (dm >> 16) as u8, (dm >> 8) as u8, dm as u8, (sm >> 40) as u8, (sm >> 32) as u8, (sm >> 24) as u8, (sm >> 16) as u8, (sm >> 8) as u8, sm as u8, (ethertype >> 8) as u8, ethertype as u8];
|
||||
unsafe {
|
||||
let iov: [osdep::iovec; 2] = [
|
||||
osdep::iovec {
|
||||
let iov: [libc::iovec; 2] = [
|
||||
libc::iovec {
|
||||
iov_base: hdr.as_mut_ptr().cast(),
|
||||
iov_len: 14,
|
||||
},
|
||||
osdep::iovec {
|
||||
libc::iovec {
|
||||
iov_base: transmute(data), // have to "cast away const" even though data is not modified by writev()
|
||||
iov_len: len as osdep::size_t,
|
||||
iov_len: len as libc::size_t,
|
||||
},
|
||||
];
|
||||
osdep::writev(self.ndrv_fd, iov.as_ptr(), 2) == (len + 14) as osdep::ssize_t
|
||||
libc::writev(self.ndrv_fd, iov.as_ptr(), 2) == (len + 14) as libc::ssize_t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,14 +781,14 @@ impl Drop for MacFethTap {
|
|||
fn drop(&mut self) {
|
||||
if self.bpf_fd >= 0 {
|
||||
unsafe {
|
||||
osdep::shutdown(self.bpf_fd, osdep::SHUT_RDWR as c_int);
|
||||
osdep::close(self.bpf_fd);
|
||||
libc::shutdown(self.bpf_fd, libc::SHUT_RDWR);
|
||||
libc::close(self.bpf_fd);
|
||||
MAC_FETH_BPF_DEVICES_USED.lock().unwrap().remove(&self.bpf_no);
|
||||
}
|
||||
}
|
||||
if self.ndrv_fd >= 0 {
|
||||
unsafe {
|
||||
osdep::close(self.ndrv_fd);
|
||||
libc::close(self.ndrv_fd);
|
||||
}
|
||||
}
|
||||
let t = self.bpf_read_thread.replace(None);
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
use zerotier_network_hypervisor::vl2::MulticastGroup;
|
||||
|
||||
/// Virtual network interface
|
||||
pub(crate) trait VNIC {
|
||||
pub trait VNIC {
|
||||
/// Add a new IPv4 or IPv6 address to this interface, returning true on success.
|
||||
fn add_ip(&self, ip: &zerotier_core::InetAddress) -> bool;
|
||||
|
||||
|
@ -30,7 +32,7 @@ pub(crate) trait VNIC {
|
|||
/// This doesn't do any IGMP snooping. It just reports the groups the port
|
||||
/// knows about. On some OSes this may not be supported in which case it
|
||||
/// will return an empty set.
|
||||
fn get_multicast_groups(&self) -> std::collections::BTreeSet<zerotier_core::MulticastGroup>;
|
||||
fn get_multicast_groups(&self) -> std::collections::BTreeSet<MulticastGroup>;
|
||||
|
||||
/// Inject an Ethernet frame into this port.
|
||||
fn put(&self, source_mac: &zerotier_core::MAC, dest_mac: &zerotier_core::MAC, ethertype: u16, vlan_id: u16, data: *const u8, len: usize) -> bool;
|
||||
|
|
Loading…
Add table
Reference in a new issue