mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-03 19:13:43 +02:00
More Rust plumbing...
This commit is contained in:
parent
8d0d479662
commit
927344f197
7 changed files with 401 additions and 184 deletions
113
core/zerotier.h
113
core/zerotier.h
|
@ -23,10 +23,12 @@
|
|||
#include <WS2tcpip.h>
|
||||
#include <Windows.h>
|
||||
#else
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -266,7 +268,7 @@ extern "C" {
|
|||
enum ZT_IdentityType
|
||||
{
|
||||
ZT_IDENTITY_TYPE_C25519 = 0, /* C25519/Ed25519 */
|
||||
ZT_IDENTITY_TYPE_P384 = 1 /* Combined C25519/NIST-P-384 key */
|
||||
ZT_IDENTITY_TYPE_P384 = 1 /* Combined C25519/NIST-P-384 key */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -651,12 +653,12 @@ typedef struct
|
|||
*/
|
||||
enum ZT_CredentialType
|
||||
{
|
||||
ZT_CREDENTIAL_TYPE_NULL = 0,
|
||||
ZT_CREDENTIAL_TYPE_COM = 1,
|
||||
ZT_CREDENTIAL_TYPE_CAPABILITY = 2,
|
||||
ZT_CREDENTIAL_TYPE_TAG = 3,
|
||||
ZT_CREDENTIAL_TYPE_COO = 4,
|
||||
ZT_CREDENTIAL_TYPE_REVOCATION = 6
|
||||
ZT_CREDENTIAL_TYPE_NULL = 0,
|
||||
ZT_CREDENTIAL_TYPE_COM = 1,
|
||||
ZT_CREDENTIAL_TYPE_CAPABILITY = 2,
|
||||
ZT_CREDENTIAL_TYPE_TAG = 3,
|
||||
ZT_CREDENTIAL_TYPE_COO = 4,
|
||||
ZT_CREDENTIAL_TYPE_REVOCATION = 6
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -667,15 +669,15 @@ enum ZT_CredentialType
|
|||
*/
|
||||
enum ZT_EndpointType
|
||||
{
|
||||
ZT_ENDPOINT_TYPE_NIL = 0, /* Nil/empty endpoint */
|
||||
ZT_ENDPOINT_TYPE_ZEROTIER = 1, /* ZeroTier relaying (address+fingerprint) */
|
||||
ZT_ENDPOINT_TYPE_ETHERNET = 2, /* Ethernet with ethertype 0x9993 */
|
||||
ZT_ENDPOINT_TYPE_WIFI_DIRECT = 3, /* Ethernet using WiFi direct */
|
||||
ZT_ENDPOINT_TYPE_BLUETOOTH = 4, /* Bluetooth (same address type as Ethernet) */
|
||||
ZT_ENDPOINT_TYPE_IP = 5, /* Naked IP (protocol 193) */
|
||||
ZT_ENDPOINT_TYPE_IP_UDP = 6, /* IP/UDP */
|
||||
ZT_ENDPOINT_TYPE_IP_TCP = 7, /* IP/TCP */
|
||||
ZT_ENDPOINT_TYPE_IP_HTTP = 8 /* IP/HTTP encapsulation */
|
||||
ZT_ENDPOINT_TYPE_NIL = 0, /* Nil/empty endpoint */
|
||||
ZT_ENDPOINT_TYPE_ZEROTIER = 1, /* ZeroTier relaying (address+fingerprint) */
|
||||
ZT_ENDPOINT_TYPE_ETHERNET = 2, /* Ethernet with ethertype 0x9993 */
|
||||
ZT_ENDPOINT_TYPE_WIFI_DIRECT = 3, /* Ethernet using WiFi direct */
|
||||
ZT_ENDPOINT_TYPE_BLUETOOTH = 4, /* Bluetooth (same address type as Ethernet) */
|
||||
ZT_ENDPOINT_TYPE_IP = 5, /* Naked IP (protocol 193) */
|
||||
ZT_ENDPOINT_TYPE_IP_UDP = 6, /* IP/UDP */
|
||||
ZT_ENDPOINT_TYPE_IP_TCP = 7, /* IP/TCP */
|
||||
ZT_ENDPOINT_TYPE_IP_HTTP = 8 /* IP/HTTP encapsulation */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -705,15 +707,15 @@ enum ZT_EndpointType
|
|||
*/
|
||||
enum ZT_TraceEventType
|
||||
{
|
||||
ZT_TRACE_UNEXPECTED_ERROR = 0,
|
||||
ZT_TRACE_UNEXPECTED_ERROR = 0,
|
||||
ZT_TRACE_VL1_RESETTING_PATHS_IN_SCOPE = 1,
|
||||
ZT_TRACE_VL1_TRYING_NEW_PATH = 2,
|
||||
ZT_TRACE_VL1_LEARNED_NEW_PATH = 3,
|
||||
ZT_TRACE_VL1_INCOMING_PACKET_DROPPED = 4,
|
||||
ZT_TRACE_VL2_OUTGOING_FRAME_DROPPED = 100,
|
||||
ZT_TRACE_VL2_INCOMING_FRAME_DROPPED = 101,
|
||||
ZT_TRACE_VL1_TRYING_NEW_PATH = 2,
|
||||
ZT_TRACE_VL1_LEARNED_NEW_PATH = 3,
|
||||
ZT_TRACE_VL1_INCOMING_PACKET_DROPPED = 4,
|
||||
ZT_TRACE_VL2_OUTGOING_FRAME_DROPPED = 100,
|
||||
ZT_TRACE_VL2_INCOMING_FRAME_DROPPED = 101,
|
||||
ZT_TRACE_VL2_NETWORK_CONFIG_REQUESTED = 102,
|
||||
ZT_TRACE_VL2_NETWORK_FILTER = 103
|
||||
ZT_TRACE_VL2_NETWORK_FILTER = 103
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -721,15 +723,15 @@ enum ZT_TraceEventType
|
|||
*/
|
||||
enum ZT_TracePacketDropReason
|
||||
{
|
||||
ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED = 0,
|
||||
ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD = 1,
|
||||
ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET = 2,
|
||||
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED = 3,
|
||||
ZT_TRACE_PACKET_DROP_REASON_RATE_LIMIT_EXCEEDED = 4,
|
||||
ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT = 5,
|
||||
ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED = 0,
|
||||
ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD = 1,
|
||||
ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET = 2,
|
||||
ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED = 3,
|
||||
ZT_TRACE_PACKET_DROP_REASON_RATE_LIMIT_EXCEEDED = 4,
|
||||
ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT = 5,
|
||||
ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA = 6,
|
||||
ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB = 7,
|
||||
ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED = 8
|
||||
ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB = 7,
|
||||
ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED = 8
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -737,14 +739,14 @@ enum ZT_TracePacketDropReason
|
|||
*/
|
||||
enum ZT_TraceFrameDropReason
|
||||
{
|
||||
ZT_TRACE_FRAME_DROP_REASON_UNSPECIFIED = 0,
|
||||
ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_REMOTE = 1,
|
||||
ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_LOCAL = 2,
|
||||
ZT_TRACE_FRAME_DROP_REASON_MULTICAST_DISABLED = 3,
|
||||
ZT_TRACE_FRAME_DROP_REASON_BROADCAST_DISABLED = 4,
|
||||
ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED = 5,
|
||||
ZT_TRACE_FRAME_DROP_REASON_UNSPECIFIED = 0,
|
||||
ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_REMOTE = 1,
|
||||
ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_LOCAL = 2,
|
||||
ZT_TRACE_FRAME_DROP_REASON_MULTICAST_DISABLED = 3,
|
||||
ZT_TRACE_FRAME_DROP_REASON_BROADCAST_DISABLED = 4,
|
||||
ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED = 5,
|
||||
ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED_AT_BRIDGE_REPLICATION = 6,
|
||||
ZT_TRACE_FRAME_DROP_REASON_PERMISSION_DENIED = 7
|
||||
ZT_TRACE_FRAME_DROP_REASON_PERMISSION_DENIED = 7
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -753,9 +755,9 @@ enum ZT_TraceFrameDropReason
|
|||
enum ZT_TraceCredentialRejectionReason
|
||||
{
|
||||
ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED = 1,
|
||||
ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED = 2,
|
||||
ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST = 3,
|
||||
ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID = 4
|
||||
ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED = 2,
|
||||
ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST = 3,
|
||||
ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID = 4
|
||||
};
|
||||
|
||||
#define ZT_TRACE_FIELD_TYPE "t"
|
||||
|
@ -1176,11 +1178,13 @@ typedef struct
|
|||
/**
|
||||
* Union containing the value of this rule -- which field is used depends on 't'
|
||||
*/
|
||||
union {
|
||||
union
|
||||
{
|
||||
/**
|
||||
* IPv6 address in big-endian / network byte order and netmask bits
|
||||
*/
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint8_t ip[16];
|
||||
uint8_t mask;
|
||||
} ipv6;
|
||||
|
@ -1188,7 +1192,8 @@ typedef struct
|
|||
/**
|
||||
* IPv4 address in big-endian / network byte order
|
||||
*/
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint32_t ip;
|
||||
uint8_t mask;
|
||||
} ipv4;
|
||||
|
@ -1200,7 +1205,8 @@ typedef struct
|
|||
* the range is +/- INT32_MAX. It's packed this way so it fits in 16
|
||||
* bytes and doesn't enlarge the overall size of this union.
|
||||
*/
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint64_t start; /* integer range start */
|
||||
uint32_t end; /* end of integer range (relative to start, inclusive, 0 for equality w/start) */
|
||||
uint16_t idx; /* index in packet of integer */
|
||||
|
@ -1260,7 +1266,8 @@ typedef struct
|
|||
/**
|
||||
* IP type of service a.k.a. DSCP field
|
||||
*/
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint8_t mask;
|
||||
uint8_t value[2];
|
||||
} ipTos;
|
||||
|
@ -1273,7 +1280,8 @@ typedef struct
|
|||
/**
|
||||
* ICMP type and code
|
||||
*/
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint8_t type; /* ICMP type, always matched */
|
||||
uint8_t code; /* ICMP code if matched */
|
||||
uint8_t flags; /* flag 0x01 means also match code, otherwise only match type */
|
||||
|
@ -1282,7 +1290,8 @@ typedef struct
|
|||
/**
|
||||
* For tag-related rules
|
||||
*/
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint32_t id;
|
||||
uint32_t value;
|
||||
} tag;
|
||||
|
@ -1290,7 +1299,8 @@ typedef struct
|
|||
/**
|
||||
* Destinations for TEE and REDIRECT
|
||||
*/
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
uint64_t address;
|
||||
uint32_t flags;
|
||||
uint16_t length;
|
||||
|
@ -1458,6 +1468,7 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
void (*freeFunction)(const void *);
|
||||
|
||||
ZT_VirtualNetworkConfig *networks;
|
||||
unsigned long networkCount;
|
||||
} ZT_VirtualNetworkList;
|
||||
|
@ -1488,7 +1499,8 @@ typedef struct
|
|||
*/
|
||||
enum ZT_EndpointType type;
|
||||
|
||||
union {
|
||||
union
|
||||
{
|
||||
/**
|
||||
* Socket address generic buffer
|
||||
*/
|
||||
|
@ -1651,6 +1663,7 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
void (*freeFunction)(const void *);
|
||||
|
||||
ZT_Peer *peers;
|
||||
unsigned long peerCount;
|
||||
} ZT_PeerList;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
use std::ffi::CStr;
|
||||
use std::intrinsics::write_bytes;
|
||||
use std::mem::{MaybeUninit, zeroed};
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
use std::ffi::CStr;
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Maximum length of a string in a certificate (mostly for the certificate name fields).
|
||||
pub const CERTIFICATE_MAX_STRING_LENGTH: u32 = ztcore::ZT_CERTIFICATE_MAX_STRING_LENGTH;
|
||||
|
@ -20,6 +24,76 @@ pub const CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE: u32 = ztcore::ZT_CERTIFICA
|
|||
/// Length of a private key corresponding to a NIST P-384 unique ID.
|
||||
pub const CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE: u32 = ztcore::ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct CertificateSerialNo(pub [u8; 48]);
|
||||
|
||||
impl CertificateSerialNo {
|
||||
pub fn new_from_string(s: &str) -> Result<CertificateSerialNo, ResultCode> {
|
||||
let b = hex::decode(s);
|
||||
if b.is_err() {
|
||||
return Err(ResultCode::ErrorBadParameter);
|
||||
}
|
||||
return Ok(CertificateSerialNo::from(b.unwrap()));
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for CertificateSerialNo {
|
||||
fn from(v: Vec<u8>) -> CertificateSerialNo {
|
||||
let mut l = v.len();
|
||||
if l > 48 {
|
||||
l = 48;
|
||||
}
|
||||
unsafe {
|
||||
let mut r: [u8; 48] = MaybeUninit::uninit().assume_init();
|
||||
copy_nonoverlapping(v.as_ptr(), r.as_mut_ptr(), l);
|
||||
while l < 48 {
|
||||
r[l] = 0;
|
||||
l += 1;
|
||||
}
|
||||
return CertificateSerialNo(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for CertificateSerialNo {
|
||||
fn to_string(&self) -> String {
|
||||
hex::encode(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for CertificateSerialNo {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
}
|
||||
}
|
||||
|
||||
struct CertificateSerialNoVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for CertificateSerialNoVisitor {
|
||||
type Value = CertificateSerialNo;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("CertificateSerialNoVisitor value in string form")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> where E: serde::de::Error {
|
||||
let id = CertificateSerialNo::new_from_string(s);
|
||||
if id.is_err() {
|
||||
return Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self));
|
||||
}
|
||||
return Ok(id.ok().unwrap() as Self::Value);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for CertificateSerialNo {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
|
||||
deserializer.deserialize_str(CertificateSerialNoVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Type of certificate subject unique ID
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum CertificateUniqueIdType {
|
||||
|
@ -73,6 +147,8 @@ impl<'de> serde::Deserialize<'de> for CertificateUniqueIdType {
|
|||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Reasons a certificate may be rejected.
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum CertificateError {
|
||||
|
@ -138,8 +214,8 @@ pub struct CertificateIdentity {
|
|||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct CertificateSubjectUniqueIdSecret {
|
||||
pub public: Box<[u8]>,
|
||||
pub private: Box<[u8]>,
|
||||
pub public: Vec<u8>,
|
||||
pub private: Vec<u8>,
|
||||
pub type_: CertificateUniqueIdType
|
||||
}
|
||||
|
||||
|
@ -147,29 +223,29 @@ pub struct CertificateSubjectUniqueIdSecret {
|
|||
#[derive(Serialize, Deserialize)]
|
||||
pub struct CertificateSubject {
|
||||
pub timestamp: i64,
|
||||
pub identities: Box<[CertificateIdentity]>,
|
||||
pub networks: Box<[CertificateNetwork]>,
|
||||
pub certificates: Box<[Box<[u8]>]>,
|
||||
pub updateURLs: Box<[String]>,
|
||||
pub identities: Vec<CertificateIdentity>,
|
||||
pub networks: Vec<CertificateNetwork>,
|
||||
pub certificates: Vec<CertificateSerialNo>,
|
||||
pub updateURLs: Vec<String>,
|
||||
pub name: CertificateName,
|
||||
pub uniqueId: Box<[u8]>,
|
||||
pub uniqueIdProofSignature: Box<[u8]>
|
||||
pub uniqueId: Vec<u8>,
|
||||
pub uniqueIdProofSignature: Vec<u8>
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Certificate {
|
||||
pub serialNo: Box<[u8]>,
|
||||
pub serialNo: CertificateSerialNo,
|
||||
pub flags: u64,
|
||||
pub timestamp: i64,
|
||||
pub validity: [i64; 2],
|
||||
pub subject: CertificateSubject,
|
||||
pub issuer: Identity,
|
||||
pub issuerName: CertificateName,
|
||||
pub extendedAttributes: Box<[u8]>,
|
||||
pub extendedAttributes: Vec<u8>,
|
||||
pub maxPathLength: u32,
|
||||
pub crl: Box<[Box<[u8]>]>,
|
||||
pub signature: Box<[u8]>
|
||||
pub crl: Vec<CertificateSerialNo>,
|
||||
pub signature: Vec<u8>
|
||||
}
|
||||
|
||||
impl CertificateName {
|
||||
|
@ -208,8 +284,8 @@ impl CertificateNetwork {
|
|||
impl CertificateIdentity {
|
||||
pub(crate) fn new_from_capi(ci: &ztcore::ZT_Certificate_Identity) -> CertificateIdentity {
|
||||
CertificateIdentity{
|
||||
identity: Identity::new_from_capi(ci.identity, false),
|
||||
locator: Locator::new_from_capi(ci.locator, false)
|
||||
identity: Identity::new_from_capi(ci.identity, false).clone(),
|
||||
locator: Locator::new_from_capi(ci.locator, false).clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,11 +306,11 @@ impl CertificateSubject {
|
|||
}
|
||||
|
||||
let ccertificates: &[*const u8] = std::slice::from_raw_parts(cs.certificates, cs.certificateCount as usize);
|
||||
let mut certificates: Vec<Box<[u8]>> = Vec::new();
|
||||
let mut certificates: Vec<CertificateSerialNo> = Vec::new();
|
||||
let mut ctmp: [u8; 48] = [0; 48];
|
||||
for i in ccertificates.iter() {
|
||||
copy_nonoverlapping(*i, ctmp.as_mut_ptr(), 48);
|
||||
certificates.push(Box::from(ctmp));
|
||||
certificates.push(CertificateSerialNo(ctmp));
|
||||
}
|
||||
|
||||
let cupdate_urls: &[*const c_char] = std::slice::from_raw_parts(cs.updateURLs, cs.updateURLCount as usize);
|
||||
|
@ -245,13 +321,13 @@ impl CertificateSubject {
|
|||
|
||||
return CertificateSubject{
|
||||
timestamp: cs.timestamp,
|
||||
identities: identities.into_boxed_slice(),
|
||||
networks: networks.into_boxed_slice(),
|
||||
certificates: certificates.into_boxed_slice(),
|
||||
updateURLs: update_urls.into_boxed_slice(),
|
||||
identities: identities,
|
||||
networks: networks,
|
||||
certificates: certificates,
|
||||
updateURLs: update_urls,
|
||||
name: CertificateName::new_from_capi(&cs.name),
|
||||
uniqueId: Box::from(std::slice::from_raw_parts(cs.uniqueId, cs.uniqueIdSize as usize).clone()),
|
||||
uniqueIdProofSignature: Box::from(std::slice::from_raw_parts(cs.uniqueIdProofSignature, cs.uniqueIdProofSignatureSize as usize).clone())
|
||||
uniqueId: Vec::from(std::slice::from_raw_parts(cs.uniqueId, cs.uniqueIdSize as usize)),
|
||||
uniqueIdProofSignature: Vec::from(std::slice::from_raw_parts(cs.uniqueIdProofSignature, cs.uniqueIdProofSignatureSize as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -260,34 +336,26 @@ impl CertificateSubject {
|
|||
impl Certificate {
|
||||
pub(crate) fn new_from_capi(c: &ztcore::ZT_Certificate) -> Certificate {
|
||||
unsafe {
|
||||
let cextended_attributes: &[u8] = std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize);
|
||||
let mut extended_attributes: Vec<u8> = Vec::new();
|
||||
extended_attributes.extend(cextended_attributes.iter());
|
||||
|
||||
let ccrl: &[*const u8] = std::slice::from_raw_parts(c.crl, c.crlCount as usize);
|
||||
let mut crl: Vec<Box<[u8]>> = Vec::new();
|
||||
let mut crl: Vec<CertificateSerialNo> = Vec::new();
|
||||
let mut ctmp: [u8; 48] = [0; 48];
|
||||
for i in ccrl.iter() {
|
||||
copy_nonoverlapping(*i, ctmp.as_mut_ptr(), 48);
|
||||
crl.push(Box::from(ctmp));
|
||||
crl.push(CertificateSerialNo(ctmp));
|
||||
}
|
||||
|
||||
let csignature: &[u8] = std::slice::from_raw_parts(c.signature, c.signatureSize as usize);
|
||||
let mut signature: Vec<u8> = Vec::new();
|
||||
signature.extend(csignature.iter());
|
||||
|
||||
return Certificate{
|
||||
serialNo: Box::from(c.serialNo),
|
||||
serialNo: CertificateSerialNo(c.serialNo),
|
||||
flags: c.flags,
|
||||
timestamp: c.timestamp,
|
||||
validity: c.validity,
|
||||
subject: CertificateSubject::new_from_capi(&c.subject),
|
||||
issuer: Identity::new_from_capi(c.issuer, false),
|
||||
issuerName: CertificateName::new_from_capi(&c.issuerName),
|
||||
extendedAttributes: extended_attributes.into_boxed_slice(),
|
||||
extendedAttributes: Vec::from(std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize)),
|
||||
maxPathLength: c.maxPathLength as u32,
|
||||
crl: crl.into_boxed_slice(),
|
||||
signature: signature.into_boxed_slice()
|
||||
crl: crl,
|
||||
signature: Vec::from(std::slice::from_raw_parts(c.signature, c.signatureSize as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -296,31 +364,26 @@ impl Certificate {
|
|||
impl CertificateSubjectUniqueIdSecret {
|
||||
pub fn new(t: CertificateUniqueIdType) -> Self {
|
||||
unsafe {
|
||||
let mut unique_id: Vec<u8> = Vec::new();
|
||||
let mut unique_id_private: Vec<u8> = Vec::new();
|
||||
unique_id.resize(128, 0);
|
||||
unique_id_private.resize(128, 0);
|
||||
let mut unique_id_size: c_int = 128;
|
||||
let mut unique_id_private_size: c_int = 128;
|
||||
let mut unique_id: [u8; 128] = zeroed();
|
||||
let mut unique_id_private: [u8; 128] = zeroed();
|
||||
let mut unique_id_size: c_int = unique_id.len() as c_int;
|
||||
let mut unique_id_private_size: c_int = unique_id_private.len() as c_int;
|
||||
let ct: ztcore::ZT_CertificateUniqueIdType = num_traits::ToPrimitive::to_u32(&t).unwrap();
|
||||
if ztcore::ZT_Certificate_newSubjectUniqueId(ct, unique_id.as_mut_ptr() as *mut c_void, &mut unique_id_size as *mut c_int, unique_id_private.as_mut_ptr() as *mut c_void, &mut unique_id_private_size as *mut c_int) != 0 {
|
||||
panic!("fatal internal error: ZT_Certificate_newSubjectUniqueId failed.");
|
||||
}
|
||||
unique_id.resize(unique_id_size as usize, 0);
|
||||
unique_id_private.resize(unique_id_private_size as usize, 0);
|
||||
return CertificateSubjectUniqueIdSecret{
|
||||
public: unique_id.into_boxed_slice(),
|
||||
private: unique_id_private.into_boxed_slice(),
|
||||
public: Vec::from(&unique_id[0..unique_id_size as usize]),
|
||||
private: Vec::from(&unique_id_private[0..unique_id_private_size as usize]),
|
||||
type_: num_traits::FromPrimitive::from_u32(ct as u32).unwrap()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
implement_json_serializable!(CertificateName);
|
||||
implement_json_serializable!(CertificateNetwork);
|
||||
implement_json_serializable!(CertificateIdentity);
|
||||
implement_json_serializable!(CertificateSubject);
|
||||
implement_json_serializable!(Certificate);
|
||||
implement_json_serializable!(CertificateSubjectUniqueIdSecret);
|
||||
implement_to_from_json!(CertificateName);
|
||||
implement_to_from_json!(CertificateNetwork);
|
||||
implement_to_from_json!(CertificateIdentity);
|
||||
implement_to_from_json!(CertificateSubject);
|
||||
implement_to_from_json!(Certificate);
|
||||
implement_to_from_json!(CertificateSubjectUniqueIdSecret);
|
||||
|
|
|
@ -12,6 +12,7 @@ mod node;
|
|||
mod mac;
|
||||
mod buffer;
|
||||
mod portableatomici64;
|
||||
mod virtualnetworkconfig;
|
||||
|
||||
pub use identity::{Identity, IdentityType};
|
||||
pub use address::Address;
|
||||
|
@ -26,6 +27,7 @@ pub use node::Node;
|
|||
pub use mac::MAC;
|
||||
pub use buffer::Buffer;
|
||||
pub use portableatomici64::PortableAtomicI64;
|
||||
pub use virtualnetworkconfig::*;
|
||||
|
||||
use bindings::capi as ztcore;
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
|
@ -151,67 +153,6 @@ pub enum Event {
|
|||
UserMessage = ztcore::ZT_Event_ZT_EVENT_USER_MESSAGE as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkStatus {
|
||||
RequestingConfiguration = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION as isize,
|
||||
Ok = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_OK as isize,
|
||||
AccessDenied = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_ACCESS_DENIED as isize,
|
||||
NotFound = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_NOT_FOUND as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkType {
|
||||
Private = ztcore::ZT_VirtualNetworkType_ZT_NETWORK_TYPE_PRIVATE as isize,
|
||||
Public = ztcore::ZT_VirtualNetworkType_ZT_NETWORK_TYPE_PUBLIC as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkRuleType {
|
||||
ActionDrop = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_DROP as isize,
|
||||
ActionAccept = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_ACCEPT as isize,
|
||||
ActionTee = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_TEE as isize,
|
||||
ActionWatch = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_WATCH as isize,
|
||||
ActionRedirect = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_REDIRECT as isize,
|
||||
ActionBreak = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_BREAK as isize,
|
||||
ActionPriority = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_PRIORITY as isize,
|
||||
MatchSourceZeroTierAddress = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS as isize,
|
||||
MatchDestinationZeroTierAddress = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS as isize,
|
||||
MatchVlanId = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_VLAN_ID as isize,
|
||||
MatchVlanPcp = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_VLAN_PCP as isize,
|
||||
MatchVlanDei = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_VLAN_DEI as isize,
|
||||
MatchMacSource = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_MAC_SOURCE as isize,
|
||||
MatchMacDestination = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_MAC_DEST as isize,
|
||||
MatchIpv4Source = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IPV4_SOURCE as isize,
|
||||
MatchIpv4Destination = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IPV4_DEST as isize,
|
||||
MatchIpv6Source = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IPV6_SOURCE as isize,
|
||||
MatchIpv6Destination = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IPV6_DEST as isize,
|
||||
MatchIpTos = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IP_TOS as isize,
|
||||
MatchIpProtocol = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IP_PROTOCOL as isize,
|
||||
MatchEtherType = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_ETHERTYPE as isize,
|
||||
MatchIcmp = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_ICMP as isize,
|
||||
MatchIpSourcePortRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE as isize,
|
||||
MatchIpDestinationSourceRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE as isize,
|
||||
MatchCharacteristics = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_CHARACTERISTICS as isize,
|
||||
MatchFrameSizeRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE as isize,
|
||||
MatchRandom = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_RANDOM as isize,
|
||||
MatchTagsDifference = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE as isize,
|
||||
MatchTagsBitwiseAnd = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND as isize,
|
||||
MatchTagsBitwiseOr = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR as isize,
|
||||
MatchTagsBitwiseXor = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR as isize,
|
||||
MatchTagsEqual = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_EQUAL as isize,
|
||||
MatchTagSender = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAG_SENDER as isize,
|
||||
MatchTagReceiver = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAG_RECEIVER as isize,
|
||||
MatchIntegerRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_INTEGER_RANGE as isize,
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkConfigOperation {
|
||||
Up = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP as isize,
|
||||
ConfigUpdate = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE as isize,
|
||||
Down = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN as isize,
|
||||
Destroy = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY as isize
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum StateObjectType {
|
||||
IdentityPublic = ztcore::ZT_StateObjectType_ZT_STATE_OBJECT_IDENTITY_PUBLIC as isize,
|
||||
|
@ -242,7 +183,7 @@ pub fn now() -> i64 {
|
|||
}
|
||||
|
||||
#[macro_export(crate)]
|
||||
macro_rules! implement_json_serializable {
|
||||
macro_rules! implement_to_from_json {
|
||||
($struct_name:ident) => {
|
||||
impl $struct_name {
|
||||
pub fn new_from_json(json: &str) -> Result<$struct_name, String> {
|
||||
|
|
|
@ -59,6 +59,12 @@ impl Drop for Locator {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for Locator {
|
||||
fn clone(&self) -> Locator {
|
||||
Locator::new_from_string(self.to_string().as_str()).ok().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Locator {
|
||||
fn to_string(&self) -> String {
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
|
|
|
@ -1,19 +1,33 @@
|
|||
pub struct NetworkId(pub u64);
|
||||
|
||||
impl NetworkId {
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn new_from_string(s: &str) -> NetworkId {
|
||||
return NetworkId(u64::from_str_radix(s, 16).unwrap_or(0));
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for NetworkId {
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn to_string(&self) -> String {
|
||||
format!("{:0>16x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for NetworkId {
|
||||
#[inline(always)]
|
||||
fn from(n: u64) -> Self {
|
||||
NetworkId(n)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for NetworkId {
|
||||
#[inline(always)]
|
||||
fn from(s: &str) -> Self {
|
||||
NetworkId::new_from_string(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for NetworkId {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
use std::cell::Cell;
|
||||
use std::ffi::CStr;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::mem::transmute;
|
||||
use std::os::raw::{c_int, c_uint, c_ulong, c_void};
|
||||
use std::ptr::null_mut;
|
||||
use std::sync::*;
|
||||
use std::sync::atomic::*;
|
||||
use std::time::Duration;
|
||||
use std::mem::transmute;
|
||||
use std::intrinsics::arith_offset;
|
||||
use std::ffi::CStr;
|
||||
|
||||
use num_traits::FromPrimitive;
|
||||
use socket2::SockAddr;
|
||||
|
@ -15,6 +14,8 @@ use socket2::SockAddr;
|
|||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
|
||||
const NODE_BACKGROUND_MIN_DELAY: i64 = 250;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub struct NodeStatus {
|
||||
pub address: Address,
|
||||
|
@ -206,10 +207,10 @@ impl Node {
|
|||
}
|
||||
let mut next_delay = next_task_deadline - current_time;
|
||||
|
||||
if next_delay < 50 {
|
||||
next_delay = 50;
|
||||
} else if next_delay > 500 {
|
||||
next_delay = 500;
|
||||
if next_delay < 5 {
|
||||
next_delay = 5;
|
||||
} else if next_delay > NODE_BACKGROUND_MIN_DELAY {
|
||||
next_delay = NODE_BACKGROUND_MIN_DELAY;
|
||||
}
|
||||
next_delay
|
||||
}
|
||||
|
@ -292,8 +293,8 @@ impl Node {
|
|||
return NodeStatus {
|
||||
address: Address(ns.address),
|
||||
identity: Identity::new_from_capi(&*ns.identity, false).clone(),
|
||||
publicIdentity: String::from(CStr::from_ptr(ns.publicIdentity)),
|
||||
secretIdentity: String::from(CStr::from_ptr(ns.secretIdentity)),
|
||||
publicIdentity: String::from(CStr::from_ptr(ns.publicIdentity).to_str().unwrap()),
|
||||
secretIdentity: String::from(CStr::from_ptr(ns.secretIdentity).to_str().unwrap()),
|
||||
online: ns.online != 0
|
||||
}
|
||||
}
|
||||
|
@ -304,14 +305,47 @@ impl Node {
|
|||
unsafe {
|
||||
let pl = ztcore::ZT_Node_peers(self.capi.get());
|
||||
if !pl.is_null() {
|
||||
p.reserve(pl.peerCount as usize);
|
||||
for i in 0..(pl.peerCount as isize) {
|
||||
p.push(Peer::new_from_capi(&*arith_offset(pl.peers, i)));
|
||||
let peer_count = (*pl).peerCount as usize;
|
||||
p.reserve(peer_count);
|
||||
for i in 0..peer_count as isize {
|
||||
p.push(Peer::new_from_capi(&*(*pl).peers.offset(i)));
|
||||
}
|
||||
ztcore::ZT_freeQueryResult(pl as *const c_void);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
p
|
||||
}
|
||||
|
||||
pub fn networks(&self) -> Vec<VirtualNetworkConfig> {
|
||||
let mut n: Vec<VirtualNetworkConfig> = Vec::new();
|
||||
unsafe {
|
||||
let nl = ztcore::ZT_Node_networks(self.capi.get());
|
||||
if !nl.is_null() {
|
||||
let net_count = (*nl).networkCount as usize;
|
||||
n.reserve(net_count);
|
||||
for i in 0..net_count as isize {
|
||||
n.push(VirtualNetworkConfig::new_from_capi(&*(*nl).networks.offset(i)));
|
||||
}
|
||||
ztcore::ZT_freeQueryResult(nl as *const c_void);
|
||||
}
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
pub fn certificates(&self) -> Vec<(Certificate, u32)> {
|
||||
let mut c: Vec<(Certificate, u32)> = Vec::new();
|
||||
unsafe {
|
||||
let cl = ztcore::ZT_Node_listCertificates(self.capi.get());
|
||||
if !cl.is_null() {
|
||||
let cert_count = (*cl).certCount as usize;
|
||||
c.reserve(cert_count);
|
||||
for i in 0..cert_count as isize {
|
||||
c.push((Certificate::new_from_capi(&**(*cl).certs.offset(i)), *(*cl).localTrust.offset(i)));
|
||||
}
|
||||
ztcore::ZT_freeQueryResult(cl as *const c_void);
|
||||
}
|
||||
}
|
||||
c
|
||||
}
|
||||
}
|
||||
|
||||
|
|
146
rust-zerotier-core/src/virtualnetworkconfig.rs
Normal file
146
rust-zerotier-core/src/virtualnetworkconfig.rs
Normal file
|
@ -0,0 +1,146 @@
|
|||
use std::ffi::CStr;
|
||||
use std::mem::{size_of, transmute, zeroed};
|
||||
use std::os::raw::{c_void, c_char};
|
||||
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::FromPrimitive;
|
||||
use socket2::SockAddr;
|
||||
|
||||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkType {
|
||||
Private = ztcore::ZT_VirtualNetworkType_ZT_NETWORK_TYPE_PRIVATE as isize,
|
||||
Public = ztcore::ZT_VirtualNetworkType_ZT_NETWORK_TYPE_PUBLIC as isize
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkRuleType {
|
||||
ActionDrop = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_DROP as isize,
|
||||
ActionAccept = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_ACCEPT as isize,
|
||||
ActionTee = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_TEE as isize,
|
||||
ActionWatch = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_WATCH as isize,
|
||||
ActionRedirect = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_REDIRECT as isize,
|
||||
ActionBreak = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_BREAK as isize,
|
||||
ActionPriority = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_ACTION_PRIORITY as isize,
|
||||
MatchSourceZeroTierAddress = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS as isize,
|
||||
MatchDestinationZeroTierAddress = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS as isize,
|
||||
MatchVlanId = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_VLAN_ID as isize,
|
||||
MatchVlanPcp = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_VLAN_PCP as isize,
|
||||
MatchVlanDei = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_VLAN_DEI as isize,
|
||||
MatchMacSource = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_MAC_SOURCE as isize,
|
||||
MatchMacDestination = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_MAC_DEST as isize,
|
||||
MatchIpv4Source = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IPV4_SOURCE as isize,
|
||||
MatchIpv4Destination = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IPV4_DEST as isize,
|
||||
MatchIpv6Source = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IPV6_SOURCE as isize,
|
||||
MatchIpv6Destination = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IPV6_DEST as isize,
|
||||
MatchIpTos = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IP_TOS as isize,
|
||||
MatchIpProtocol = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IP_PROTOCOL as isize,
|
||||
MatchEtherType = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_ETHERTYPE as isize,
|
||||
MatchIcmp = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_ICMP as isize,
|
||||
MatchIpSourcePortRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE as isize,
|
||||
MatchIpDestinationSourceRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE as isize,
|
||||
MatchCharacteristics = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_CHARACTERISTICS as isize,
|
||||
MatchFrameSizeRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE as isize,
|
||||
MatchRandom = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_RANDOM as isize,
|
||||
MatchTagsDifference = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE as isize,
|
||||
MatchTagsBitwiseAnd = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND as isize,
|
||||
MatchTagsBitwiseOr = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR as isize,
|
||||
MatchTagsBitwiseXor = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR as isize,
|
||||
MatchTagsEqual = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAGS_EQUAL as isize,
|
||||
MatchTagSender = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAG_SENDER as isize,
|
||||
MatchTagReceiver = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_TAG_RECEIVER as isize,
|
||||
MatchIntegerRange = ztcore::ZT_VirtualNetworkRuleType_ZT_NETWORK_RULE_MATCH_INTEGER_RANGE as isize
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkConfigOperation {
|
||||
Up = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP as isize,
|
||||
ConfigUpdate = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE as isize,
|
||||
Down = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN as isize,
|
||||
Destroy = ztcore::ZT_VirtualNetworkConfigOperation_ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY as isize
|
||||
}
|
||||
|
||||
#[derive(FromPrimitive,ToPrimitive)]
|
||||
pub enum VirtualNetworkStatus {
|
||||
RequestingConfiguration = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION as isize,
|
||||
Ok = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_OK as isize,
|
||||
AccessDenied = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_ACCESS_DENIED as isize,
|
||||
NotFound = ztcore::ZT_VirtualNetworkStatus_ZT_NETWORK_STATUS_NOT_FOUND as isize
|
||||
}
|
||||
|
||||
pub struct VirtualNetworkRoute {
|
||||
pub target: Option<SockAddr>,
|
||||
pub via: Option<SockAddr>,
|
||||
pub flags: u16,
|
||||
pub metric: u16
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub struct VirtualNetworkConfig {
|
||||
pub nwid: NetworkId,
|
||||
pub mac: MAC,
|
||||
pub name: String,
|
||||
pub status: VirtualNetworkStatus,
|
||||
pub type_: VirtualNetworkType,
|
||||
pub mtu: u32,
|
||||
pub bridge: bool,
|
||||
pub broadcastEnabled: bool,
|
||||
pub netconfRevision: u64,
|
||||
pub assignedAddresses: Vec<SockAddr>,
|
||||
pub routes: Vec<VirtualNetworkRoute>
|
||||
}
|
||||
|
||||
const SIZEOF_SOCKADDR_IN: ztcore::socklen_t = size_of::<ztcore::sockaddr_in>() as ztcore::socklen_t;
|
||||
const SIZEOF_SOCKADDR_IN6: ztcore::socklen_t = size_of::<ztcore::sockaddr_in6>() as ztcore::socklen_t;
|
||||
|
||||
/// Obtain a socket2::SockAddr from a C struct sockaddr_storage as used in the ZeroTier core.
|
||||
pub(crate) fn sockaddr_from_capi(ss: &ztcore::sockaddr_storage) -> Option<SockAddr> {
|
||||
match ss.ss_family as u32 {
|
||||
ztcore::AF_INET => { unsafe { Some(SockAddr::from_raw_parts(transmute(ss as *const ztcore::sockaddr_storage), transmute(SIZEOF_SOCKADDR_IN))) } },
|
||||
ztcore::AF_INET6 => { unsafe { Some(SockAddr::from_raw_parts(transmute(ss as *const ztcore::sockaddr_storage), transmute(SIZEOF_SOCKADDR_IN6))) } },
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualNetworkConfig {
|
||||
pub(crate) fn new_from_capi(vnc: &ztcore::ZT_VirtualNetworkConfig) -> VirtualNetworkConfig {
|
||||
unsafe {
|
||||
let mut aa: Vec<SockAddr> = Vec::new();
|
||||
let saptr = vnc.assignedAddresses.as_ptr();
|
||||
for i in 0..vnc.assignedAddressCount as isize {
|
||||
let sa = sockaddr_from_capi(&*saptr.offset(i));
|
||||
if sa.is_some() {
|
||||
aa.push(sa.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
let mut rts: Vec<VirtualNetworkRoute> = Vec::new();
|
||||
let rtptr = vnc.routes.as_ptr();
|
||||
for i in 0..vnc.routeCount as isize {
|
||||
let r = *rtptr.offset(i);
|
||||
rts.push(VirtualNetworkRoute{
|
||||
target: sockaddr_from_capi(&r.target),
|
||||
via: sockaddr_from_capi(&r.via),
|
||||
flags: r.flags,
|
||||
metric: r.metric
|
||||
})
|
||||
}
|
||||
|
||||
return VirtualNetworkConfig{
|
||||
nwid: NetworkId(vnc.nwid),
|
||||
mac: MAC(vnc.mac),
|
||||
name: String::from(CStr::from_ptr(vnc.name.as_ptr() as *const c_char).to_str().unwrap_or("")),
|
||||
status: FromPrimitive::from_u32(vnc.status as u32).unwrap(),
|
||||
type_: FromPrimitive::from_u32(vnc.type_ as u32).unwrap(),
|
||||
mtu: vnc.mtu as u32,
|
||||
bridge: vnc.bridge != 0,
|
||||
broadcastEnabled: vnc.broadcastEnabled != 0,
|
||||
netconfRevision: vnc.netconfRevision as u64,
|
||||
assignedAddresses: aa,
|
||||
routes: rts
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue