diff --git a/include/ZeroTierDebug.h b/include/ZeroTierDebug.h index 2e9cc2c5a..22ac0cdd5 100644 --- a/include/ZeroTierDebug.h +++ b/include/ZeroTierDebug.h @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ /** * @file @@ -29,20 +24,20 @@ #include #define ZT_MSG_INFO true -#define ZT_COLOR true +#define ZT_COLOR true // Debug output colors #if defined(__APPLE__) #include "TargetConditionals.h" #endif #if defined(ZT_COLOR) && ! defined(_WIN32) && ! defined(__ANDROID__) && ! defined(TARGET_OS_IPHONE) && ! defined(TARGET_IPHONE_SIMULATOR) && ! defined(__APP_FRAMEWORK__) -#define ZT_RED "\x1B[31m" -#define ZT_GRN "\x1B[32m" -#define ZT_YEL "\x1B[33m" -#define ZT_BLU "\x1B[34m" -#define ZT_MAG "\x1B[35m" -#define ZT_CYN "\x1B[36m" -#define ZT_WHT "\x1B[37m" +#define ZT_RED "\x1B[31m" +#define ZT_GRN "\x1B[32m" +#define ZT_YEL "\x1B[33m" +#define ZT_BLU "\x1B[34m" +#define ZT_MAG "\x1B[35m" +#define ZT_CYN "\x1B[36m" +#define ZT_WHT "\x1B[37m" #define ZT_RESET "\x1B[0m" #else #define ZT_RED @@ -90,7 +85,7 @@ #else #define DEBUG_INFO(fmt, args...) #endif -#else // blank +#else // blank #if defined(_WIN32) #define DEBUG_INFO(...) #else @@ -98,4 +93,4 @@ #endif #endif -#endif // _H +#endif // _H diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 8aa701a8f..f0581a525 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ /* * This defines the external C API for ZeroTier's core network virtualization @@ -293,74 +288,74 @@ extern "C" { #define ZT_RULE_PACKET_CHARACTERISTICS_TCP_FIN 0x0000000000000001ULL // Fields in remote trace dictionaries -#define ZT_REMOTE_TRACE_FIELD__EVENT "event" -#define ZT_REMOTE_TRACE_FIELD__NODE_ID "nodeId" -#define ZT_REMOTE_TRACE_FIELD__PACKET_ID "packetId" -#define ZT_REMOTE_TRACE_FIELD__PACKET_VERB "packetVerb" -#define ZT_REMOTE_TRACE_FIELD__PACKET_TRUSTED_PATH_ID "packetTrustedPathId" +#define ZT_REMOTE_TRACE_FIELD__EVENT "event" +#define ZT_REMOTE_TRACE_FIELD__NODE_ID "nodeId" +#define ZT_REMOTE_TRACE_FIELD__PACKET_ID "packetId" +#define ZT_REMOTE_TRACE_FIELD__PACKET_VERB "packetVerb" +#define ZT_REMOTE_TRACE_FIELD__PACKET_TRUSTED_PATH_ID "packetTrustedPathId" #define ZT_REMOTE_TRACE_FIELD__PACKET_TRUSTED_PATH_APPROVED "packetTrustedPathApproved" -#define ZT_REMOTE_TRACE_FIELD__PACKET_HOPS "packetHops" -#define ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR "remoteZtAddr" -#define ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR "remotePhyAddr" -#define ZT_REMOTE_TRACE_FIELD__LOCAL_ZTADDR "localZtAddr" -#define ZT_REMOTE_TRACE_FIELD__LOCAL_PHYADDR "localPhyAddr" -#define ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET "localSocket" -#define ZT_REMOTE_TRACE_FIELD__IP_SCOPE "phyAddrIpScope" -#define ZT_REMOTE_TRACE_FIELD__NETWORK_ID "networkId" -#define ZT_REMOTE_TRACE_FIELD__SOURCE_ZTADDR "sourceZtAddr" -#define ZT_REMOTE_TRACE_FIELD__DEST_ZTADDR "destZtAddr" -#define ZT_REMOTE_TRACE_FIELD__SOURCE_MAC "sourceMac" -#define ZT_REMOTE_TRACE_FIELD__DEST_MAC "destMac" -#define ZT_REMOTE_TRACE_FIELD__ETHERTYPE "etherType" -#define ZT_REMOTE_TRACE_FIELD__VLAN_ID "vlanId" -#define ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH "frameLength" -#define ZT_REMOTE_TRACE_FIELD__FRAME_DATA "frameData" -#define ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_NOTEE "filterNoTee" -#define ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_INBOUND "filterInbound" -#define ZT_REMOTE_TRACE_FIELD__FILTER_RESULT "filterResult" -#define ZT_REMOTE_TRACE_FIELD__FILTER_BASE_RULE_LOG "filterBaseRuleLog" -#define ZT_REMOTE_TRACE_FIELD__FILTER_CAP_RULE_LOG "filterCapRuleLog" -#define ZT_REMOTE_TRACE_FIELD__FILTER_CAP_ID "filterMatchingCapId" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE "credType" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID "credId" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP "credTs" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_INFO "credInfo" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO "credIssuedTo" +#define ZT_REMOTE_TRACE_FIELD__PACKET_HOPS "packetHops" +#define ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR "remoteZtAddr" +#define ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR "remotePhyAddr" +#define ZT_REMOTE_TRACE_FIELD__LOCAL_ZTADDR "localZtAddr" +#define ZT_REMOTE_TRACE_FIELD__LOCAL_PHYADDR "localPhyAddr" +#define ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET "localSocket" +#define ZT_REMOTE_TRACE_FIELD__IP_SCOPE "phyAddrIpScope" +#define ZT_REMOTE_TRACE_FIELD__NETWORK_ID "networkId" +#define ZT_REMOTE_TRACE_FIELD__SOURCE_ZTADDR "sourceZtAddr" +#define ZT_REMOTE_TRACE_FIELD__DEST_ZTADDR "destZtAddr" +#define ZT_REMOTE_TRACE_FIELD__SOURCE_MAC "sourceMac" +#define ZT_REMOTE_TRACE_FIELD__DEST_MAC "destMac" +#define ZT_REMOTE_TRACE_FIELD__ETHERTYPE "etherType" +#define ZT_REMOTE_TRACE_FIELD__VLAN_ID "vlanId" +#define ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH "frameLength" +#define ZT_REMOTE_TRACE_FIELD__FRAME_DATA "frameData" +#define ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_NOTEE "filterNoTee" +#define ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_INBOUND "filterInbound" +#define ZT_REMOTE_TRACE_FIELD__FILTER_RESULT "filterResult" +#define ZT_REMOTE_TRACE_FIELD__FILTER_BASE_RULE_LOG "filterBaseRuleLog" +#define ZT_REMOTE_TRACE_FIELD__FILTER_CAP_RULE_LOG "filterCapRuleLog" +#define ZT_REMOTE_TRACE_FIELD__FILTER_CAP_ID "filterMatchingCapId" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE "credType" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID "credId" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP "credTs" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_INFO "credInfo" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO "credIssuedTo" #define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_REVOCATION_TARGET "credRevocationTarget" -#define ZT_REMOTE_TRACE_FIELD__REASON "reason" -#define ZT_REMOTE_TRACE_FIELD__NETWORK_CONTROLLER_ID "networkControllerId" +#define ZT_REMOTE_TRACE_FIELD__REASON "reason" +#define ZT_REMOTE_TRACE_FIELD__NETWORK_CONTROLLER_ID "networkControllerId" // Event types in remote traces -#define ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE 0x1000 -#define ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH 0x1001 -#define ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH 0x1002 -#define ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED 0x1003 -#define ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE 0x1004 -#define ZT_REMOTE_TRACE_EVENT__PACKET_INVALID 0x1005 -#define ZT_REMOTE_TRACE_EVENT__DROPPED_HELLO 0x1006 +#define ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE 0x1000 +#define ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH 0x1001 +#define ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH 0x1002 +#define ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED 0x1003 +#define ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE 0x1004 +#define ZT_REMOTE_TRACE_EVENT__PACKET_INVALID 0x1005 +#define ZT_REMOTE_TRACE_EVENT__DROPPED_HELLO 0x1006 #define ZT_REMOTE_TRACE_EVENT__OUTGOING_NETWORK_FRAME_DROPPED 0x2000 #define ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_ACCESS_DENIED 0x2001 #define ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_FRAME_DROPPED 0x2002 -#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED 0x2003 -#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED 0x2004 -#define ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT 0x2005 -#define ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE 0x2006 +#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED 0x2003 +#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED 0x2004 +#define ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT 0x2005 +#define ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE 0x2006 // Event types in remote traces in hex string form -#define ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE_S "1000" -#define ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH_S "1001" -#define ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH_S "1002" -#define ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED_S "1003" -#define ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE_S "1004" -#define ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S "1005" -#define ZT_REMOTE_TRACE_EVENT__DROPPED_HELLO_S "1006" +#define ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE_S "1000" +#define ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH_S "1001" +#define ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH_S "1002" +#define ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED_S "1003" +#define ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE_S "1004" +#define ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S "1005" +#define ZT_REMOTE_TRACE_EVENT__DROPPED_HELLO_S "1006" #define ZT_REMOTE_TRACE_EVENT__OUTGOING_NETWORK_FRAME_DROPPED_S "2000" #define ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_ACCESS_DENIED_S "2001" #define ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_FRAME_DROPPED_S "2002" -#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S "2003" -#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S "2004" -#define ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT_S "2005" -#define ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE_S "2006" +#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S "2003" +#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S "2004" +#define ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT_S "2005" +#define ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE_S "2006" /****************************************************************************/ /* Structures and other types */ @@ -375,49 +370,49 @@ extern "C" { * problem. */ enum ZT_ResultCode { - /** - * Operation completed normally - */ - ZT_RESULT_OK = 0, + /** + * Operation completed normally + */ + ZT_RESULT_OK = 0, - /** - * Call produced no error but no action was taken - */ - ZT_RESULT_OK_IGNORED = 1, + /** + * Call produced no error but no action was taken + */ + ZT_RESULT_OK_IGNORED = 1, - // Fatal errors (>=100, <1000) + // Fatal errors (>=100, <1000) - /** - * Ran out of memory - */ - ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY = 100, + /** + * Ran out of memory + */ + ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY = 100, - /** - * Data store is not writable or has failed - */ - ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED = 101, + /** + * Data store is not writable or has failed + */ + ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED = 101, - /** - * Internal error (e.g. unexpected exception indicating bug or build problem) - */ - ZT_RESULT_FATAL_ERROR_INTERNAL = 102, + /** + * Internal error (e.g. unexpected exception indicating bug or build problem) + */ + ZT_RESULT_FATAL_ERROR_INTERNAL = 102, - // Non-fatal errors (>1000) + // Non-fatal errors (>1000) - /** - * Network ID not valid - */ - ZT_RESULT_ERROR_NETWORK_NOT_FOUND = 1000, + /** + * Network ID not valid + */ + ZT_RESULT_ERROR_NETWORK_NOT_FOUND = 1000, - /** - * The requested operation is not supported on this version or build - */ - ZT_RESULT_ERROR_UNSUPPORTED_OPERATION = 1001, + /** + * The requested operation is not supported on this version or build + */ + ZT_RESULT_ERROR_UNSUPPORTED_OPERATION = 1001, - /** - * The requested operation was given a bad parameter or was called in an invalid state - */ - ZT_RESULT_ERROR_BAD_PARAMETER = 1002 + /** + * The requested operation was given a bad parameter or was called in an invalid state + */ + ZT_RESULT_ERROR_BAD_PARAMETER = 1002 }; /** @@ -430,133 +425,133 @@ enum ZT_ResultCode { * Status codes sent to status update callback when things happen */ enum ZT_Event { - /** - * Node has been initialized - * - * This is the first event generated, and is always sent. It may occur - * before Node's constructor returns. - * - * Meta-data: none - */ - ZT_EVENT_UP = 0, + /** + * Node has been initialized + * + * This is the first event generated, and is always sent. It may occur + * before Node's constructor returns. + * + * Meta-data: none + */ + ZT_EVENT_UP = 0, - /** - * Node is offline -- network does not seem to be reachable by any available strategy - * - * Meta-data: none - */ - ZT_EVENT_OFFLINE = 1, + /** + * Node is offline -- network does not seem to be reachable by any available strategy + * + * Meta-data: none + */ + ZT_EVENT_OFFLINE = 1, - /** - * Node is online -- at least one upstream node appears reachable - * - * Meta-data: none - */ - ZT_EVENT_ONLINE = 2, + /** + * Node is online -- at least one upstream node appears reachable + * + * Meta-data: none + */ + ZT_EVENT_ONLINE = 2, - /** - * Node is shutting down - * - * This is generated within Node's destructor when it is being shut down. - * It's done for convenience, since cleaning up other state in the event - * handler may appear more idiomatic. - * - * Meta-data: none - */ - ZT_EVENT_DOWN = 3, + /** + * Node is shutting down + * + * This is generated within Node's destructor when it is being shut down. + * It's done for convenience, since cleaning up other state in the event + * handler may appear more idiomatic. + * + * Meta-data: none + */ + ZT_EVENT_DOWN = 3, - /** - * Your identity has collided with another node's ZeroTier address - * - * This happens if two different public keys both hash (via the algorithm - * in Identity::generate()) to the same 40-bit ZeroTier address. - * - * This is something you should "never" see, where "never" is defined as - * once per 2^39 new node initializations / identity creations. If you do - * see it, you're going to see it very soon after a node is first - * initialized. - * - * This is reported as an event rather than a return code since it's - * detected asynchronously via error messages from authoritative nodes. - * - * If this occurs, you must shut down and delete the node, delete the - * identity.secret record/file from the data store, and restart to generate - * a new identity. If you don't do this, you will not be able to communicate - * with other nodes. - * - * We'd automate this process, but we don't think silently deleting - * private keys or changing our address without telling the calling code - * is good form. It violates the principle of least surprise. - * - * You can technically get away with not handling this, but we recommend - * doing so in a mature reliable application. Besides, handling this - * condition is a good way to make sure it never arises. It's like how - * umbrellas prevent rain and smoke detectors prevent fires. They do, right? - * - * Meta-data: none - */ - ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION = 4, + /** + * Your identity has collided with another node's ZeroTier address + * + * This happens if two different public keys both hash (via the algorithm + * in Identity::generate()) to the same 40-bit ZeroTier address. + * + * This is something you should "never" see, where "never" is defined as + * once per 2^39 new node initializations / identity creations. If you do + * see it, you're going to see it very soon after a node is first + * initialized. + * + * This is reported as an event rather than a return code since it's + * detected asynchronously via error messages from authoritative nodes. + * + * If this occurs, you must shut down and delete the node, delete the + * identity.secret record/file from the data store, and restart to generate + * a new identity. If you don't do this, you will not be able to communicate + * with other nodes. + * + * We'd automate this process, but we don't think silently deleting + * private keys or changing our address without telling the calling code + * is good form. It violates the principle of least surprise. + * + * You can technically get away with not handling this, but we recommend + * doing so in a mature reliable application. Besides, handling this + * condition is a good way to make sure it never arises. It's like how + * umbrellas prevent rain and smoke detectors prevent fires. They do, right? + * + * Meta-data: none + */ + ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION = 4, - /** - * Trace (debugging) message - * - * These events are only generated if this is a TRACE-enabled build. - * - * Meta-data: C string, TRACE message - */ - ZT_EVENT_TRACE = 5, + /** + * Trace (debugging) message + * + * These events are only generated if this is a TRACE-enabled build. + * + * Meta-data: C string, TRACE message + */ + ZT_EVENT_TRACE = 5, - /** - * VERB_USER_MESSAGE received - * - * These are generated when a VERB_USER_MESSAGE packet is received via - * ZeroTier VL1. - * - * Meta-data: ZT_UserMessage structure - */ - ZT_EVENT_USER_MESSAGE = 6, + /** + * VERB_USER_MESSAGE received + * + * These are generated when a VERB_USER_MESSAGE packet is received via + * ZeroTier VL1. + * + * Meta-data: ZT_UserMessage structure + */ + ZT_EVENT_USER_MESSAGE = 6, - /** - * Remote trace received - * - * These are generated when a VERB_REMOTE_TRACE is received. Note - * that any node can fling one of these at us. It is your responsibility - * to filter and determine if it's worth paying attention to. If it's - * not just drop it. Most nodes that are not active controllers ignore - * these, and controllers only save them if they pertain to networks - * with remote tracing enabled. - * - * Meta-data: ZT_RemoteTrace structure - */ - ZT_EVENT_REMOTE_TRACE = 7 + /** + * Remote trace received + * + * These are generated when a VERB_REMOTE_TRACE is received. Note + * that any node can fling one of these at us. It is your responsibility + * to filter and determine if it's worth paying attention to. If it's + * not just drop it. Most nodes that are not active controllers ignore + * these, and controllers only save them if they pertain to networks + * with remote tracing enabled. + * + * Meta-data: ZT_RemoteTrace structure + */ + ZT_EVENT_REMOTE_TRACE = 7 }; /** * Payload of REMOTE_TRACE event */ typedef struct { - /** - * ZeroTier address of sender - */ - uint64_t origin; + /** + * ZeroTier address of sender + */ + uint64_t origin; - /** - * Null-terminated Dictionary containing key/value pairs sent by origin - * - * This *should* be a dictionary, but the implementation only checks - * that it is a valid non-empty C-style null-terminated string. Be very - * careful to use a well-tested parser to parse this as it represents - * data received from a potentially un-trusted peer on the network. - * Invalid payloads should be dropped. - * - * The contents of data[] may be modified. - */ - char* data; + /** + * Null-terminated Dictionary containing key/value pairs sent by origin + * + * This *should* be a dictionary, but the implementation only checks + * that it is a valid non-empty C-style null-terminated string. Be very + * careful to use a well-tested parser to parse this as it represents + * data received from a potentially un-trusted peer on the network. + * Invalid payloads should be dropped. + * + * The contents of data[] may be modified. + */ + char* data; - /** - * Length of dict[] in bytes, including terminating null - */ - unsigned int len; + /** + * Length of dict[] in bytes, including terminating null + */ + unsigned int len; } ZT_RemoteTrace; /** @@ -570,54 +565,54 @@ typedef struct { * gapped.) */ typedef struct { - /** - * ZeroTier address of sender (least significant 40 bits) - */ - uint64_t origin; + /** + * ZeroTier address of sender (least significant 40 bits) + */ + uint64_t origin; - /** - * User message type ID - */ - uint64_t typeId; + /** + * User message type ID + */ + uint64_t typeId; - /** - * User message data (not including type ID) - */ - const void* data; + /** + * User message data (not including type ID) + */ + const void* data; - /** - * Length of data in bytes - */ - unsigned int length; + /** + * Length of data in bytes + */ + unsigned int length; } ZT_UserMessage; /** * Current node status */ typedef struct { - /** - * 40-bit ZeroTier address of this node - */ - uint64_t address; + /** + * 40-bit ZeroTier address of this node + */ + uint64_t address; - /** - * Public identity in string-serialized form (safe to send to others) - * - * This pointer will remain valid as long as the node exists. - */ - const char* publicIdentity; + /** + * Public identity in string-serialized form (safe to send to others) + * + * This pointer will remain valid as long as the node exists. + */ + const char* publicIdentity; - /** - * Full identity including secret key in string-serialized form - * - * This pointer will remain valid as long as the node exists. - */ - const char* secretIdentity; + /** + * Full identity including secret key in string-serialized form + * + * This pointer will remain valid as long as the node exists. + */ + const char* secretIdentity; - /** - * True if some kind of connectivity appears available - */ - int online; + /** + * True if some kind of connectivity appears available + */ + int online; } ZT_NodeStatus; /** @@ -626,70 +621,70 @@ typedef struct { * This structure is subject to change between versions. */ typedef struct { - /** - * Number of each protocol verb (possible verbs 0..31) received - */ - uint64_t inVerbCounts[32]; + /** + * Number of each protocol verb (possible verbs 0..31) received + */ + uint64_t inVerbCounts[32]; - /** - * Number of bytes for each protocol verb received - */ - uint64_t inVerbBytes[32]; + /** + * Number of bytes for each protocol verb received + */ + uint64_t inVerbBytes[32]; } ZT_NodeStatistics; /** * Virtual network status codes */ enum ZT_VirtualNetworkStatus { - /** - * Waiting for network configuration (also means revision == 0) - */ - ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION = 0, + /** + * Waiting for network configuration (also means revision == 0) + */ + ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION = 0, - /** - * Configuration received and we are authorized - */ - ZT_NETWORK_STATUS_OK = 1, + /** + * Configuration received and we are authorized + */ + ZT_NETWORK_STATUS_OK = 1, - /** - * Netconf master told us 'nope' - */ - ZT_NETWORK_STATUS_ACCESS_DENIED = 2, + /** + * Netconf master told us 'nope' + */ + ZT_NETWORK_STATUS_ACCESS_DENIED = 2, - /** - * Netconf master exists, but this virtual network does not - */ - ZT_NETWORK_STATUS_NOT_FOUND = 3, + /** + * Netconf master exists, but this virtual network does not + */ + ZT_NETWORK_STATUS_NOT_FOUND = 3, - /** - * Initialization of network failed or other internal error - */ - ZT_NETWORK_STATUS_PORT_ERROR = 4, + /** + * Initialization of network failed or other internal error + */ + ZT_NETWORK_STATUS_PORT_ERROR = 4, - /** - * ZeroTier core version too old - */ - ZT_NETWORK_STATUS_CLIENT_TOO_OLD = 5, + /** + * ZeroTier core version too old + */ + ZT_NETWORK_STATUS_CLIENT_TOO_OLD = 5, - /** - * External authentication is required (e.g. SSO) - */ - ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED = 6 + /** + * External authentication is required (e.g. SSO) + */ + ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED = 6 }; /** * Virtual network type codes */ enum ZT_VirtualNetworkType { - /** - * Private networks are authorized via certificates of membership - */ - ZT_NETWORK_TYPE_PRIVATE = 0, + /** + * Private networks are authorized via certificates of membership + */ + ZT_NETWORK_TYPE_PRIVATE = 0, - /** - * Public networks have no access control -- they'll always be AUTHORIZED - */ - ZT_NETWORK_TYPE_PUBLIC = 1 + /** + * Public networks have no access control -- they'll always be AUTHORIZED + */ + ZT_NETWORK_TYPE_PUBLIC = 1 }; /** @@ -702,83 +697,83 @@ enum ZT_VirtualNetworkType { * An ACTION with no MATCHes is always taken. */ enum ZT_VirtualNetworkRuleType { - // 0 to 15 reserved for actions + // 0 to 15 reserved for actions - /** - * Drop frame - */ - ZT_NETWORK_RULE_ACTION_DROP = 0, + /** + * Drop frame + */ + ZT_NETWORK_RULE_ACTION_DROP = 0, - /** - * Accept and pass frame - */ - ZT_NETWORK_RULE_ACTION_ACCEPT = 1, + /** + * Accept and pass frame + */ + ZT_NETWORK_RULE_ACTION_ACCEPT = 1, - /** - * Forward a copy of this frame to an observer (by ZT address) - */ - ZT_NETWORK_RULE_ACTION_TEE = 2, + /** + * Forward a copy of this frame to an observer (by ZT address) + */ + ZT_NETWORK_RULE_ACTION_TEE = 2, - /** - * Exactly like TEE but mandates ACKs from observer - */ - ZT_NETWORK_RULE_ACTION_WATCH = 3, + /** + * Exactly like TEE but mandates ACKs from observer + */ + ZT_NETWORK_RULE_ACTION_WATCH = 3, - /** - * Drop and redirect this frame to another node (by ZT address) - */ - ZT_NETWORK_RULE_ACTION_REDIRECT = 4, + /** + * Drop and redirect this frame to another node (by ZT address) + */ + ZT_NETWORK_RULE_ACTION_REDIRECT = 4, - /** - * Stop evaluating rule set (drops unless there are capabilities, etc.) - */ - ZT_NETWORK_RULE_ACTION_BREAK = 5, + /** + * Stop evaluating rule set (drops unless there are capabilities, etc.) + */ + ZT_NETWORK_RULE_ACTION_BREAK = 5, - /** - * Place a matching frame in the specified QoS bucket - */ - ZT_NETWORK_RULE_ACTION_PRIORITY = 6, + /** + * Place a matching frame in the specified QoS bucket + */ + ZT_NETWORK_RULE_ACTION_PRIORITY = 6, - /** - * Maximum ID for an ACTION, anything higher is a MATCH - */ - ZT_NETWORK_RULE_ACTION__MAX_ID = 15, + /** + * Maximum ID for an ACTION, anything higher is a MATCH + */ + ZT_NETWORK_RULE_ACTION__MAX_ID = 15, - // 16 to 63 reserved for match criteria + // 16 to 63 reserved for match criteria - ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS = 24, - ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS = 25, - ZT_NETWORK_RULE_MATCH_VLAN_ID = 26, - ZT_NETWORK_RULE_MATCH_VLAN_PCP = 27, - ZT_NETWORK_RULE_MATCH_VLAN_DEI = 28, - ZT_NETWORK_RULE_MATCH_MAC_SOURCE = 29, - ZT_NETWORK_RULE_MATCH_MAC_DEST = 30, - ZT_NETWORK_RULE_MATCH_IPV4_SOURCE = 31, - ZT_NETWORK_RULE_MATCH_IPV4_DEST = 32, - ZT_NETWORK_RULE_MATCH_IPV6_SOURCE = 33, - ZT_NETWORK_RULE_MATCH_IPV6_DEST = 34, - ZT_NETWORK_RULE_MATCH_IP_TOS = 35, - ZT_NETWORK_RULE_MATCH_IP_PROTOCOL = 36, - ZT_NETWORK_RULE_MATCH_ETHERTYPE = 37, - ZT_NETWORK_RULE_MATCH_ICMP = 38, - ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE = 39, - ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE = 40, - ZT_NETWORK_RULE_MATCH_CHARACTERISTICS = 41, - ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE = 42, - ZT_NETWORK_RULE_MATCH_RANDOM = 43, - ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE = 44, - ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND = 45, - ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR = 46, - ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR = 47, - ZT_NETWORK_RULE_MATCH_TAGS_EQUAL = 48, - ZT_NETWORK_RULE_MATCH_TAG_SENDER = 49, - ZT_NETWORK_RULE_MATCH_TAG_RECEIVER = 50, - ZT_NETWORK_RULE_MATCH_INTEGER_RANGE = 51, + ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS = 24, + ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS = 25, + ZT_NETWORK_RULE_MATCH_VLAN_ID = 26, + ZT_NETWORK_RULE_MATCH_VLAN_PCP = 27, + ZT_NETWORK_RULE_MATCH_VLAN_DEI = 28, + ZT_NETWORK_RULE_MATCH_MAC_SOURCE = 29, + ZT_NETWORK_RULE_MATCH_MAC_DEST = 30, + ZT_NETWORK_RULE_MATCH_IPV4_SOURCE = 31, + ZT_NETWORK_RULE_MATCH_IPV4_DEST = 32, + ZT_NETWORK_RULE_MATCH_IPV6_SOURCE = 33, + ZT_NETWORK_RULE_MATCH_IPV6_DEST = 34, + ZT_NETWORK_RULE_MATCH_IP_TOS = 35, + ZT_NETWORK_RULE_MATCH_IP_PROTOCOL = 36, + ZT_NETWORK_RULE_MATCH_ETHERTYPE = 37, + ZT_NETWORK_RULE_MATCH_ICMP = 38, + ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE = 39, + ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE = 40, + ZT_NETWORK_RULE_MATCH_CHARACTERISTICS = 41, + ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE = 42, + ZT_NETWORK_RULE_MATCH_RANDOM = 43, + ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE = 44, + ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND = 45, + ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR = 46, + ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR = 47, + ZT_NETWORK_RULE_MATCH_TAGS_EQUAL = 48, + ZT_NETWORK_RULE_MATCH_TAG_SENDER = 49, + ZT_NETWORK_RULE_MATCH_TAG_RECEIVER = 50, + ZT_NETWORK_RULE_MATCH_INTEGER_RANGE = 51, - /** - * Maximum ID allowed for a MATCH entry in the rules table - */ - ZT_NETWORK_RULE_MATCH__MAX_ID = 63 + /** + * Maximum ID allowed for a MATCH entry in the rules table + */ + ZT_NETWORK_RULE_MATCH__MAX_ID = 63 }; /** @@ -793,229 +788,229 @@ enum ZT_VirtualNetworkRuleType { * a wide table, yet still fast and simple to access in code. */ typedef struct { - /** - * Type and flags - * - * Bits are: NOTTTTTT - * - * N - If true, sense of match is inverted (no effect on actions) - * O - If true, result is ORed with previous instead of ANDed (no effect on actions) - * T - Rule or action type - * - * AND with 0x3f to get type, 0x80 to get NOT bit, and 0x40 to get OR bit. - */ - uint8_t t; + /** + * Type and flags + * + * Bits are: NOTTTTTT + * + * N - If true, sense of match is inverted (no effect on actions) + * O - If true, result is ORed with previous instead of ANDed (no effect on actions) + * T - Rule or action type + * + * AND with 0x3f to get type, 0x80 to get NOT bit, and 0x40 to get OR bit. + */ + uint8_t t; - /** - * Union containing the value of this rule -- which field is used depends on 't' - */ - union { - /** - * IPv6 address in big-endian / network byte order and netmask bits - */ - struct { - uint8_t ip[16]; - uint8_t mask; - } ipv6; + /** + * Union containing the value of this rule -- which field is used depends on 't' + */ + union { + /** + * IPv6 address in big-endian / network byte order and netmask bits + */ + struct { + uint8_t ip[16]; + uint8_t mask; + } ipv6; - /** - * IPv4 address in big-endian / network byte order - */ - struct { - uint32_t ip; - uint8_t mask; - } ipv4; + /** + * IPv4 address in big-endian / network byte order + */ + struct { + uint32_t ip; + uint8_t mask; + } ipv4; - /** - * Integer range match in packet payload - * - * This allows matching of ranges of integers up to 64 bits wide where - * 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 { - 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 - uint8_t format; // bits in integer (range 1-64, ((format&63)+1)) and endianness (MSB 1 for little, 0 for big) - } intRange; + /** + * Integer range match in packet payload + * + * This allows matching of ranges of integers up to 64 bits wide where + * 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 { + 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 + uint8_t format; // bits in integer (range 1-64, ((format&63)+1)) and endianness (MSB 1 for little, 0 for big) + } intRange; - /** - * Packet characteristic flags being matched - */ - uint64_t characteristics; + /** + * Packet characteristic flags being matched + */ + uint64_t characteristics; - /** - * IP port range -- start-end inclusive -- host byte order - */ - uint16_t port[2]; + /** + * IP port range -- start-end inclusive -- host byte order + */ + uint16_t port[2]; - /** - * 40-bit ZeroTier address (in least significant bits, host byte order) - */ - uint64_t zt; + /** + * 40-bit ZeroTier address (in least significant bits, host byte order) + */ + uint64_t zt; - /** - * 0 = never, UINT32_MAX = always - */ - uint32_t randomProbability; + /** + * 0 = never, UINT32_MAX = always + */ + uint32_t randomProbability; - /** - * 48-bit Ethernet MAC address in big-endian order - */ - uint8_t mac[6]; + /** + * 48-bit Ethernet MAC address in big-endian order + */ + uint8_t mac[6]; - /** - * VLAN ID in host byte order - */ - uint16_t vlanId; + /** + * VLAN ID in host byte order + */ + uint16_t vlanId; - /** - * VLAN PCP (least significant 3 bits) - */ - uint8_t vlanPcp; + /** + * VLAN PCP (least significant 3 bits) + */ + uint8_t vlanPcp; - /** - * VLAN DEI (single bit / boolean) - */ - uint8_t vlanDei; + /** + * VLAN DEI (single bit / boolean) + */ + uint8_t vlanDei; - /** - * Ethernet type in host byte order - */ - uint16_t etherType; + /** + * Ethernet type in host byte order + */ + uint16_t etherType; - /** - * IP protocol - */ - uint8_t ipProtocol; + /** + * IP protocol + */ + uint8_t ipProtocol; - /** - * IP type of service a.k.a. DSCP field - */ - struct { - uint8_t mask; - uint8_t value[2]; - } ipTos; + /** + * IP type of service a.k.a. DSCP field + */ + struct { + uint8_t mask; + uint8_t value[2]; + } ipTos; - /** - * Ethernet packet size in host byte order (start-end, inclusive) - */ - uint16_t frameSize[2]; + /** + * Ethernet packet size in host byte order (start-end, inclusive) + */ + uint16_t frameSize[2]; - /** - * ICMP type and code - */ - 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 - } icmp; + /** + * ICMP type and code + */ + 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 + } icmp; - /** - * For tag-related rules - */ - struct { - uint32_t id; - uint32_t value; - } tag; + /** + * For tag-related rules + */ + struct { + uint32_t id; + uint32_t value; + } tag; - /** - * Destinations for TEE and REDIRECT - */ - struct { - uint64_t address; - uint32_t flags; - uint16_t length; - } fwd; + /** + * Destinations for TEE and REDIRECT + */ + struct { + uint64_t address; + uint32_t flags; + uint16_t length; + } fwd; - /** - * Quality of Service (QoS) bucket we want a frame to be placed in - */ - uint8_t qosBucket; - } v; + /** + * Quality of Service (QoS) bucket we want a frame to be placed in + */ + uint8_t qosBucket; + } v; } ZT_VirtualNetworkRule; /** * A route to be pushed on a virtual network */ typedef struct { - /** - * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default - */ - struct sockaddr_storage target; + /** + * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default + */ + struct sockaddr_storage target; - /** - * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) - */ - struct sockaddr_storage via; + /** + * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) + */ + struct sockaddr_storage via; - /** - * Route flags - */ - uint16_t flags; + /** + * Route flags + */ + uint16_t flags; - /** - * Route metric (not currently used) - */ - uint16_t metric; + /** + * Route metric (not currently used) + */ + uint16_t metric; } ZT_VirtualNetworkRoute; /** * DNS configuration to be pushed on a virtual network */ typedef struct { - char domain[128]; - struct sockaddr_storage server_addr[ZT_MAX_DNS_SERVERS]; + char domain[128]; + struct sockaddr_storage server_addr[ZT_MAX_DNS_SERVERS]; } ZT_VirtualNetworkDNS; /** * An Ethernet multicast group */ typedef struct { - /** - * MAC address (least significant 48 bits) - */ - uint64_t mac; + /** + * MAC address (least significant 48 bits) + */ + uint64_t mac; - /** - * Additional distinguishing information (usually zero) - */ - unsigned long adi; + /** + * Additional distinguishing information (usually zero) + */ + unsigned long adi; } ZT_MulticastGroup; /** * Virtual network configuration update type */ enum ZT_VirtualNetworkConfigOperation { - /** - * Network is coming up (either for the first time or after service restart) - */ - ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP = 1, + /** + * Network is coming up (either for the first time or after service restart) + */ + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP = 1, - /** - * Network configuration has been updated - */ - ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE = 2, + /** + * Network configuration has been updated + */ + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE = 2, - /** - * Network is going down (not permanently) - */ - ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN = 3, + /** + * Network is going down (not permanently) + */ + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN = 3, - /** - * Network is going down permanently (leave/delete) - */ - ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4 + /** + * Network is going down permanently (leave/delete) + */ + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4 }; /** * What trust hierarchy role does this peer have? */ enum ZT_PeerRole { - ZT_PEER_ROLE_LEAF = 0, // ordinary node - ZT_PEER_ROLE_MOON = 1, // moon root - ZT_PEER_ROLE_PLANET = 2 // planetary root + ZT_PEER_ROLE_LEAF = 0, // ordinary node + ZT_PEER_ROLE_MOON = 1, // moon root + ZT_PEER_ROLE_PLANET = 2 // planetary root }; /** @@ -1027,478 +1022,478 @@ enum ZT_Vendor { ZT_VENDOR_UNSPECIFIED = 0, ZT_VENDOR_ZEROTIER = 1 }; * Platform type */ enum ZT_Platform { - ZT_PLATFORM_UNSPECIFIED = 0, - ZT_PLATFORM_LINUX = 1, - ZT_PLATFORM_WINDOWS = 2, - ZT_PLATFORM_MACOS = 3, - ZT_PLATFORM_ANDROID = 4, - ZT_PLATFORM_IOS = 5, - ZT_PLATFORM_SOLARIS_SMARTOS = 6, - ZT_PLATFORM_FREEBSD = 7, - ZT_PLATFORM_NETBSD = 8, - ZT_PLATFORM_OPENBSD = 9, - ZT_PLATFORM_RISCOS = 10, - ZT_PLATFORM_VXWORKS = 11, - ZT_PLATFORM_FREERTOS = 12, - ZT_PLATFORM_SYSBIOS = 13, - ZT_PLATFORM_HURD = 14, - ZT_PLATFORM_WEB = 15 + ZT_PLATFORM_UNSPECIFIED = 0, + ZT_PLATFORM_LINUX = 1, + ZT_PLATFORM_WINDOWS = 2, + ZT_PLATFORM_MACOS = 3, + ZT_PLATFORM_ANDROID = 4, + ZT_PLATFORM_IOS = 5, + ZT_PLATFORM_SOLARIS_SMARTOS = 6, + ZT_PLATFORM_FREEBSD = 7, + ZT_PLATFORM_NETBSD = 8, + ZT_PLATFORM_OPENBSD = 9, + ZT_PLATFORM_RISCOS = 10, + ZT_PLATFORM_VXWORKS = 11, + ZT_PLATFORM_FREERTOS = 12, + ZT_PLATFORM_SYSBIOS = 13, + ZT_PLATFORM_HURD = 14, + ZT_PLATFORM_WEB = 15 }; /** * Architecture type */ enum ZT_Architecture { - ZT_ARCHITECTURE_UNSPECIFIED = 0, - ZT_ARCHITECTURE_X86 = 1, - ZT_ARCHITECTURE_X64 = 2, - ZT_ARCHITECTURE_ARM32 = 3, - ZT_ARCHITECTURE_ARM64 = 4, - ZT_ARCHITECTURE_MIPS32 = 5, - ZT_ARCHITECTURE_MIPS64 = 6, - ZT_ARCHITECTURE_POWER32 = 7, - ZT_ARCHITECTURE_POWER64 = 8, - ZT_ARCHITECTURE_OPENRISC32 = 9, - ZT_ARCHITECTURE_OPENRISC64 = 10, - ZT_ARCHITECTURE_SPARC32 = 11, - ZT_ARCHITECTURE_SPARC64 = 12, - ZT_ARCHITECTURE_DOTNET_CLR = 13, - ZT_ARCHITECTURE_JAVA_JVM = 14, - ZT_ARCHITECTURE_WEB = 15, - ZT_ARCHITECTURE_S390X = 16, - ZT_ARCHITECTURE_LOONGARCH64 = 17 + ZT_ARCHITECTURE_UNSPECIFIED = 0, + ZT_ARCHITECTURE_X86 = 1, + ZT_ARCHITECTURE_X64 = 2, + ZT_ARCHITECTURE_ARM32 = 3, + ZT_ARCHITECTURE_ARM64 = 4, + ZT_ARCHITECTURE_MIPS32 = 5, + ZT_ARCHITECTURE_MIPS64 = 6, + ZT_ARCHITECTURE_POWER32 = 7, + ZT_ARCHITECTURE_POWER64 = 8, + ZT_ARCHITECTURE_OPENRISC32 = 9, + ZT_ARCHITECTURE_OPENRISC64 = 10, + ZT_ARCHITECTURE_SPARC32 = 11, + ZT_ARCHITECTURE_SPARC64 = 12, + ZT_ARCHITECTURE_DOTNET_CLR = 13, + ZT_ARCHITECTURE_JAVA_JVM = 14, + ZT_ARCHITECTURE_WEB = 15, + ZT_ARCHITECTURE_S390X = 16, + ZT_ARCHITECTURE_LOONGARCH64 = 17 }; /** * Virtual network configuration */ typedef struct { - /** - * 64-bit ZeroTier network ID - */ - uint64_t nwid; + /** + * 64-bit ZeroTier network ID + */ + uint64_t nwid; - /** - * Ethernet MAC (48 bits) that should be assigned to port - */ - uint64_t mac; + /** + * Ethernet MAC (48 bits) that should be assigned to port + */ + uint64_t mac; - /** - * Network name (from network configuration master) - */ - char name[ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1]; + /** + * Network name (from network configuration master) + */ + char name[ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1]; - /** - * Network configuration request status - */ - enum ZT_VirtualNetworkStatus status; + /** + * Network configuration request status + */ + enum ZT_VirtualNetworkStatus status; - /** - * Network type - */ - enum ZT_VirtualNetworkType type; + /** + * Network type + */ + enum ZT_VirtualNetworkType type; - /** - * Maximum interface MTU - */ - unsigned int mtu; + /** + * Maximum interface MTU + */ + unsigned int mtu; - /** - * If nonzero, the network this port belongs to indicates DHCP availability - * - * This is a suggestion. The underlying implementation is free to ignore it - * for security or other reasons. This is simply a netconf parameter that - * means 'DHCP is available on this network.' - */ - int dhcp; + /** + * If nonzero, the network this port belongs to indicates DHCP availability + * + * This is a suggestion. The underlying implementation is free to ignore it + * for security or other reasons. This is simply a netconf parameter that + * means 'DHCP is available on this network.' + */ + int dhcp; - /** - * If nonzero, this port is allowed to bridge to other networks - * - * This is informational. If this is false (0), bridged packets will simply - * be dropped and bridging won't work. - */ - int bridge; + /** + * If nonzero, this port is allowed to bridge to other networks + * + * This is informational. If this is false (0), bridged packets will simply + * be dropped and bridging won't work. + */ + int bridge; - /** - * If nonzero, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic - */ - int broadcastEnabled; + /** + * If nonzero, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic + */ + int broadcastEnabled; - /** - * If the network is in PORT_ERROR state, this is the (negative) error code most recently reported - */ - int portError; + /** + * If the network is in PORT_ERROR state, this is the (negative) error code most recently reported + */ + int portError; - /** - * Revision number as reported by controller or 0 if still waiting for config - */ - unsigned long netconfRevision; + /** + * Revision number as reported by controller or 0 if still waiting for config + */ + unsigned long netconfRevision; - /** - * Number of assigned addresses - */ - unsigned int assignedAddressCount; + /** + * Number of assigned addresses + */ + unsigned int assignedAddressCount; - /** - * ZeroTier-assigned addresses (in sockaddr_storage structures) - * - * For IP, the port number of the sockaddr_XX structure contains the number - * of bits in the address netmask. Only the IP address and port are used. - * Other fields like interface number can be ignored. - * - * This is only used for ZeroTier-managed address assignments sent by the - * virtual network's configuration master. - */ - struct sockaddr_storage assignedAddresses[ZT_MAX_ZT_ASSIGNED_ADDRESSES]; + /** + * ZeroTier-assigned addresses (in sockaddr_storage structures) + * + * For IP, the port number of the sockaddr_XX structure contains the number + * of bits in the address netmask. Only the IP address and port are used. + * Other fields like interface number can be ignored. + * + * This is only used for ZeroTier-managed address assignments sent by the + * virtual network's configuration master. + */ + struct sockaddr_storage assignedAddresses[ZT_MAX_ZT_ASSIGNED_ADDRESSES]; - /** - * Number of ZT-pushed routes - */ - unsigned int routeCount; + /** + * Number of ZT-pushed routes + */ + unsigned int routeCount; - /** - * Routes (excluding those implied by assigned addresses and their masks) - */ - ZT_VirtualNetworkRoute routes[ZT_MAX_NETWORK_ROUTES]; + /** + * Routes (excluding those implied by assigned addresses and their masks) + */ + ZT_VirtualNetworkRoute routes[ZT_MAX_NETWORK_ROUTES]; - /** - * Number of multicast groups subscribed - */ - unsigned int multicastSubscriptionCount; + /** + * Number of multicast groups subscribed + */ + unsigned int multicastSubscriptionCount; - /** - * Multicast groups to which this network's device is subscribed - */ - struct { - uint64_t mac; /* MAC in lower 48 bits */ - uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */ - } multicastSubscriptions[ZT_MAX_MULTICAST_SUBSCRIPTIONS]; + /** + * Multicast groups to which this network's device is subscribed + */ + struct { + uint64_t mac; /* MAC in lower 48 bits */ + uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */ + } multicastSubscriptions[ZT_MAX_MULTICAST_SUBSCRIPTIONS]; - /** - * Network specific DNS configuration - */ - ZT_VirtualNetworkDNS dns; + /** + * Network specific DNS configuration + */ + ZT_VirtualNetworkDNS dns; - /** - * sso enabled - */ - bool ssoEnabled; + /** + * sso enabled + */ + bool ssoEnabled; - /** - * SSO version - */ - uint64_t ssoVersion; + /** + * SSO version + */ + uint64_t ssoVersion; - /** - * If the status us AUTHENTICATION_REQUIRED, this may contain a URL for authentication. - */ - char authenticationURL[2048]; + /** + * If the status us AUTHENTICATION_REQUIRED, this may contain a URL for authentication. + */ + char authenticationURL[2048]; - /** - * Time that current authentication expires. only valid if ssoEnabled is true - */ - uint64_t authenticationExpiryTime; + /** + * Time that current authentication expires. only valid if ssoEnabled is true + */ + uint64_t authenticationExpiryTime; - /** - * OIDC issuer URL. - */ - char issuerURL[2048]; + /** + * OIDC issuer URL. + */ + char issuerURL[2048]; - /** - * central base URL. - */ - char centralAuthURL[2048]; + /** + * central base URL. + */ + char centralAuthURL[2048]; - /** - * sso nonce - */ - char ssoNonce[128]; + /** + * sso nonce + */ + char ssoNonce[128]; - /** - * sso state - */ - char ssoState[256]; + /** + * sso state + */ + char ssoState[256]; - /** - * oidc client id - */ - char ssoClientID[256]; + /** + * oidc client id + */ + char ssoClientID[256]; - /** - * sso provider - **/ - char ssoProvider[64]; + /** + * sso provider + **/ + char ssoProvider[64]; } ZT_VirtualNetworkConfig; /** * A list of networks */ typedef struct { - ZT_VirtualNetworkConfig* networks; - unsigned long networkCount; + ZT_VirtualNetworkConfig* networks; + unsigned long networkCount; } ZT_VirtualNetworkList; /** * Physical path configuration */ typedef struct { - /** - * If non-zero set this physical network path to be trusted to disable encryption and authentication - */ - uint64_t trustedPathId; + /** + * If non-zero set this physical network path to be trusted to disable encryption and authentication + */ + uint64_t trustedPathId; - /** - * Physical path MTU from ZT_MIN_PHYSMTU and ZT_MAX_PHYSMTU or <= 0 to use default - */ - int mtu; + /** + * Physical path MTU from ZT_MIN_PHYSMTU and ZT_MAX_PHYSMTU or <= 0 to use default + */ + int mtu; } ZT_PhysicalPathConfiguration; /** * Physical network path to a peer */ typedef struct { - /** - * Address of endpoint - */ - struct sockaddr_storage address; + /** + * Address of endpoint + */ + struct sockaddr_storage address; - /** - * Time of last send in milliseconds or 0 for never - */ - uint64_t lastSend; + /** + * Time of last send in milliseconds or 0 for never + */ + uint64_t lastSend; - /** - * Time of last receive in milliseconds or 0 for never - */ - uint64_t lastReceive; + /** + * Time of last receive in milliseconds or 0 for never + */ + uint64_t lastReceive; - /** - * Is this a trusted path? If so this will be its nonzero ID. - */ - uint64_t trustedPathId; + /** + * Is this a trusted path? If so this will be its nonzero ID. + */ + uint64_t trustedPathId; - /** - * Mean latency - */ - float latencyMean; + /** + * Mean latency + */ + float latencyMean; - /** - * Maximum observed latency - */ - float latencyMax; + /** + * Maximum observed latency + */ + float latencyMax; - /** - * Variance of latency - */ - float latencyVariance; + /** + * Variance of latency + */ + float latencyVariance; - /** - * Packet loss ratio - */ - float packetLossRatio; + /** + * Packet loss ratio + */ + float packetLossRatio; - /** - * Packet error ratio - */ - float packetErrorRatio; + /** + * Packet error ratio + */ + float packetErrorRatio; - /** - * Number of flows assigned to this path - */ - uint16_t assignedFlowCount; + /** + * Number of flows assigned to this path + */ + uint16_t assignedFlowCount; - /** - * Address scope - */ - uint8_t scope; + /** + * Address scope + */ + uint8_t scope; - /** - * Relative quality value - */ - float relativeQuality; + /** + * Relative quality value + */ + float relativeQuality; - /** - * Name of physical interface this path resides on - */ - char ifname[ZT_MAX_PHYSIFNAME]; + /** + * Name of physical interface this path resides on + */ + char ifname[ZT_MAX_PHYSIFNAME]; - /** - * Pointer to PhySocket object for this path - */ - uint64_t localSocket; + /** + * Pointer to PhySocket object for this path + */ + uint64_t localSocket; - /** - * Local port corresponding to this path's localSocket - */ - uint16_t localPort; + /** + * Local port corresponding to this path's localSocket + */ + uint16_t localPort; - /** - * Is path expired? - */ - int expired; + /** + * Is path expired? + */ + int expired; - /** - * Whether this path is currently included in the bond - */ - uint8_t bonded; + /** + * Whether this path is currently included in the bond + */ + uint8_t bonded; - /** - * Whether this path is currently eligible to be used in a bond - */ - uint8_t eligible; + /** + * Whether this path is currently eligible to be used in a bond + */ + uint8_t eligible; - /** - * The capacity of this link (as given to bonding layer) - */ - uint32_t linkSpeed; + /** + * The capacity of this link (as given to bonding layer) + */ + uint32_t linkSpeed; - /** - * Is path preferred? - */ - int preferred; + /** + * Is path preferred? + */ + int preferred; } ZT_PeerPhysicalPath; /** * Peer status result buffer */ typedef struct { - /** - * ZeroTier address (40 bits) - */ - uint64_t address; + /** + * ZeroTier address (40 bits) + */ + uint64_t address; - /** - * Remote major version or -1 if not known - */ - int versionMajor; + /** + * Remote major version or -1 if not known + */ + int versionMajor; - /** - * Remote minor version or -1 if not known - */ - int versionMinor; + /** + * Remote minor version or -1 if not known + */ + int versionMinor; - /** - * Remote revision or -1 if not known - */ - int versionRev; + /** + * Remote revision or -1 if not known + */ + int versionRev; - /** - * Last measured latency in milliseconds or -1 if unknown - */ - int latency; + /** + * Last measured latency in milliseconds or -1 if unknown + */ + int latency; - /** - * What trust hierarchy role does this device have? - */ - enum ZT_PeerRole role; + /** + * What trust hierarchy role does this device have? + */ + enum ZT_PeerRole role; - /** - * Whether a multi-link bond has formed - */ - bool isBonded; + /** + * Whether a multi-link bond has formed + */ + bool isBonded; - /** - * The bonding policy used to bond to this peer - */ - int bondingPolicy; + /** + * The bonding policy used to bond to this peer + */ + int bondingPolicy; - /** - * The number of links that comprise the bond to this peer that are considered alive - */ - int numAliveLinks; + /** + * The number of links that comprise the bond to this peer that are considered alive + */ + int numAliveLinks; - /** - * The number of links that comprise the bond to this peer - */ - int numTotalLinks; + /** + * The number of links that comprise the bond to this peer + */ + int numTotalLinks; - /** - * The user-specified bond template name - */ - char customBondName[32]; + /** + * The user-specified bond template name + */ + char customBondName[32]; - /** - * Number of paths (size of paths[]) - */ - unsigned int pathCount; + /** + * Number of paths (size of paths[]) + */ + unsigned int pathCount; - /** - * Known network paths to peer - */ - ZT_PeerPhysicalPath paths[ZT_MAX_PEER_NETWORK_PATHS]; + /** + * Known network paths to peer + */ + ZT_PeerPhysicalPath paths[ZT_MAX_PEER_NETWORK_PATHS]; } ZT_Peer; /** * List of peers */ typedef struct { - ZT_Peer* peers; - unsigned long peerCount; + ZT_Peer* peers; + unsigned long peerCount; } ZT_PeerList; /** * ZeroTier core state objects */ enum ZT_StateObjectType { - /** - * Null object -- ignored - */ - ZT_STATE_OBJECT_NULL = 0, + /** + * Null object -- ignored + */ + ZT_STATE_OBJECT_NULL = 0, - /** - * Public address and public key - * - * Object ID: this node's address if known, or 0 if unknown (first query) - * Canonical path: /identity.public - * Persistence: required - */ - ZT_STATE_OBJECT_IDENTITY_PUBLIC = 1, + /** + * Public address and public key + * + * Object ID: this node's address if known, or 0 if unknown (first query) + * Canonical path: /identity.public + * Persistence: required + */ + ZT_STATE_OBJECT_IDENTITY_PUBLIC = 1, - /** - * Full identity with secret key - * - * Object ID: this node's address if known, or 0 if unknown (first query) - * Canonical path: /identity.secret - * Persistence: required, should be stored with restricted permissions e.g. mode 0600 on *nix - */ - ZT_STATE_OBJECT_IDENTITY_SECRET = 2, + /** + * Full identity with secret key + * + * Object ID: this node's address if known, or 0 if unknown (first query) + * Canonical path: /identity.secret + * Persistence: required, should be stored with restricted permissions e.g. mode 0600 on *nix + */ + ZT_STATE_OBJECT_IDENTITY_SECRET = 2, - /** - * The planet (there is only one per... well... planet!) - * - * Object ID: world ID of planet, or 0 if unknown (first query) - * Canonical path: /planet - * Persistence: recommended - */ - ZT_STATE_OBJECT_PLANET = 3, + /** + * The planet (there is only one per... well... planet!) + * + * Object ID: world ID of planet, or 0 if unknown (first query) + * Canonical path: /planet + * Persistence: recommended + */ + ZT_STATE_OBJECT_PLANET = 3, - /** - * A moon (federated root set) - * - * Object ID: world ID of moon - * Canonical path: /moons.d/.moon (16-digit hex ID) - * Persistence: required if moon memberships should persist - */ - ZT_STATE_OBJECT_MOON = 4, + /** + * A moon (federated root set) + * + * Object ID: world ID of moon + * Canonical path: /moons.d/.moon (16-digit hex ID) + * Persistence: required if moon memberships should persist + */ + ZT_STATE_OBJECT_MOON = 4, - /** - * Peer and related state - * - * Object ID: peer address - * Canonical path: /peers.d/ (10-digit address - * Persistence: optional, can be cleared at any time - */ - ZT_STATE_OBJECT_PEER = 5, + /** + * Peer and related state + * + * Object ID: peer address + * Canonical path: /peers.d/ (10-digit address + * Persistence: optional, can be cleared at any time + */ + ZT_STATE_OBJECT_PEER = 5, - /** - * Network configuration - * - * Object ID: peer address - * Canonical path: /networks.d/.conf (16-digit hex ID) - * Persistence: required if network memberships should persist - */ - ZT_STATE_OBJECT_NETWORK_CONFIG = 6 + /** + * Network configuration + * + * Object ID: peer address + * Canonical path: /networks.d/.conf (16-digit hex ID) + * Persistence: required if network memberships should persist + */ + ZT_STATE_OBJECT_NETWORK_CONFIG = 6 }; /** @@ -1532,13 +1527,13 @@ typedef void ZT_Node; * PORT_ERROR state. */ typedef int (*ZT_VirtualNetworkConfigFunction)( - ZT_Node*, /* Node */ - void*, /* User ptr */ - void*, /* Thread ptr */ - uint64_t, /* Network ID */ - void**, /* Modifiable network user PTR */ - enum ZT_VirtualNetworkConfigOperation, /* Config operation */ - const ZT_VirtualNetworkConfig*); /* Network configuration */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + uint64_t, /* Network ID */ + void**, /* Modifiable network user PTR */ + enum ZT_VirtualNetworkConfigOperation, /* Config operation */ + const ZT_VirtualNetworkConfig*); /* Network configuration */ /** * Function to send a frame out to a virtual network port @@ -1548,17 +1543,17 @@ typedef int (*ZT_VirtualNetworkConfigFunction)( * (9) frame length. */ typedef void (*ZT_VirtualNetworkFrameFunction)( - ZT_Node*, /* Node */ - void*, /* User ptr */ - void*, /* Thread ptr */ - uint64_t, /* Network ID */ - void**, /* Modifiable network user PTR */ - uint64_t, /* Source MAC */ - uint64_t, /* Destination MAC */ - unsigned int, /* Ethernet type */ - unsigned int, /* VLAN ID (0 for none) */ - const void*, /* Frame data */ - unsigned int); /* Frame length */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + uint64_t, /* Network ID */ + void**, /* Modifiable network user PTR */ + uint64_t, /* Source MAC */ + uint64_t, /* Destination MAC */ + unsigned int, /* Ethernet type */ + unsigned int, /* VLAN ID (0 for none) */ + const void*, /* Frame data */ + unsigned int); /* Frame length */ /** * Callback for events @@ -1570,11 +1565,11 @@ typedef void (*ZT_VirtualNetworkFrameFunction)( * in the definition of ZT_Event. */ typedef void (*ZT_EventCallback)( - ZT_Node*, /* Node */ - void*, /* User ptr */ - void*, /* Thread ptr */ - enum ZT_Event, /* Event type */ - const void*); /* Event payload (if applicable) */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + enum ZT_Event, /* Event type */ + const void*); /* Event payload (if applicable) */ /** * Callback for storing and/or publishing state information @@ -1586,13 +1581,13 @@ typedef void (*ZT_EventCallback)( * deleted. */ typedef void (*ZT_StatePutFunction)( - ZT_Node*, /* Node */ - void*, /* User ptr */ - void*, /* Thread ptr */ - enum ZT_StateObjectType, /* State object type */ - const uint64_t[2], /* State object ID (if applicable) */ - const void*, /* State object data */ - int); /* Length of data or -1 to delete */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + enum ZT_StateObjectType, /* State object type */ + const uint64_t[2], /* State object ID (if applicable) */ + const void*, /* State object data */ + int); /* Length of data or -1 to delete */ /** * Callback for retrieving stored state information @@ -1602,13 +1597,13 @@ typedef void (*ZT_StatePutFunction)( * small to store it. */ typedef int (*ZT_StateGetFunction)( - ZT_Node*, /* Node */ - void*, /* User ptr */ - void*, /* Thread ptr */ - enum ZT_StateObjectType, /* State object type */ - const uint64_t[2], /* State object ID (if applicable) */ - void*, /* Buffer to store state object data */ - unsigned int); /* Length of data buffer in bytes */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + enum ZT_StateObjectType, /* State object type */ + const uint64_t[2], /* State object ID (if applicable) */ + void*, /* Buffer to store state object data */ + unsigned int); /* Length of data buffer in bytes */ /** * Function to send a ZeroTier packet out over the physical wire (L2/L3) @@ -1635,14 +1630,14 @@ typedef int (*ZT_StateGetFunction)( * delivery. It only means that the packet appears to have been sent. */ typedef int (*ZT_WirePacketSendFunction)( - ZT_Node*, /* Node */ - void*, /* User ptr */ - void*, /* Thread ptr */ - int64_t, /* Local socket */ - const struct sockaddr_storage*, /* Remote address */ - const void*, /* Packet data */ - unsigned int, /* Packet length */ - unsigned int); /* TTL or 0 to use default */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + int64_t, /* Local socket */ + const struct sockaddr_storage*, /* Remote address */ + const void*, /* Packet data */ + unsigned int, /* Packet length */ + unsigned int); /* TTL or 0 to use default */ /** * Function to check whether a path should be used for ZeroTier traffic @@ -1666,12 +1661,12 @@ typedef int (*ZT_WirePacketSendFunction)( * interface (recursion). */ typedef int (*ZT_PathCheckFunction)( - ZT_Node*, /* Node */ - void*, /* User ptr */ - void*, /* Thread ptr */ - uint64_t, /* ZeroTier address */ - int64_t, /* Local socket or -1 if unknown */ - const struct sockaddr_storage*); /* Remote address */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + uint64_t, /* ZeroTier address */ + int64_t, /* Local socket or -1 if unknown */ + const struct sockaddr_storage*); /* Remote address */ /** * Function to get physical addresses for ZeroTier peers @@ -1689,12 +1684,12 @@ typedef int (*ZT_PathCheckFunction)( * with an address. */ typedef int (*ZT_PathLookupFunction)( - ZT_Node*, /* Node */ - void*, /* User ptr */ - void*, /* Thread ptr */ - uint64_t, /* ZeroTier address (40 bits) */ - int, /* Desired ss_family or -1 for any */ - struct sockaddr_storage*); /* Result buffer */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + uint64_t, /* ZeroTier address (40 bits) */ + int, /* Desired ss_family or -1 for any */ + struct sockaddr_storage*); /* Result buffer */ /****************************************************************************/ /* C Node API */ @@ -1704,50 +1699,50 @@ typedef int (*ZT_PathLookupFunction)( * Structure for configuring ZeroTier core callback functions */ struct ZT_Node_Callbacks { - /** - * Struct version -- must currently be 0 - */ - long version; + /** + * Struct version -- must currently be 0 + */ + long version; - /** - * REQUIRED: Function to store and/or replicate state objects - */ - ZT_StatePutFunction statePutFunction; + /** + * REQUIRED: Function to store and/or replicate state objects + */ + ZT_StatePutFunction statePutFunction; - /** - * REQUIRED: Function to retrieve state objects from an object store - */ - ZT_StateGetFunction stateGetFunction; + /** + * REQUIRED: Function to retrieve state objects from an object store + */ + ZT_StateGetFunction stateGetFunction; - /** - * REQUIRED: Function to send packets over the physical wire - */ - ZT_WirePacketSendFunction wirePacketSendFunction; + /** + * REQUIRED: Function to send packets over the physical wire + */ + ZT_WirePacketSendFunction wirePacketSendFunction; - /** - * REQUIRED: Function to inject frames into a virtual network's TAP - */ - ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction; + /** + * REQUIRED: Function to inject frames into a virtual network's TAP + */ + ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction; - /** - * REQUIRED: Function to be called when virtual networks are configured or changed - */ - ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction; + /** + * REQUIRED: Function to be called when virtual networks are configured or changed + */ + ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction; - /** - * REQUIRED: Function to be called to notify external code of important events - */ - ZT_EventCallback eventCallback; + /** + * REQUIRED: Function to be called to notify external code of important events + */ + ZT_EventCallback eventCallback; - /** - * OPTIONAL: Function to check whether a given physical path should be used - */ - ZT_PathCheckFunction pathCheckFunction; + /** + * OPTIONAL: Function to check whether a given physical path should be used + */ + ZT_PathCheckFunction pathCheckFunction; - /** - * OPTIONAL: Function to get hints to physical paths to ZeroTier addresses - */ - ZT_PathLookupFunction pathLookupFunction; + /** + * OPTIONAL: Function to get hints to physical paths to ZeroTier addresses + */ + ZT_PathLookupFunction pathLookupFunction; }; /** @@ -1810,17 +1805,17 @@ ZT_Node_processWirePacket(ZT_Node* node, void* tptr, int64_t now, int64_t localS * @return OK (0) or error code if a fatal error condition has occurred */ ZT_SDK_API enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame( - ZT_Node* node, - void* tptr, - int64_t now, - uint64_t nwid, - uint64_t sourceMac, - uint64_t destMac, - unsigned int etherType, - unsigned int vlanId, - const void* frameData, - unsigned int frameLength, - volatile int64_t* nextBackgroundTaskDeadline); + ZT_Node* node, + void* tptr, + int64_t now, + uint64_t nwid, + uint64_t sourceMac, + uint64_t destMac, + unsigned int etherType, + unsigned int vlanId, + const void* frameData, + unsigned int frameLength, + volatile int64_t* nextBackgroundTaskDeadline); /** * Perform periodic background operations diff --git a/osdep/Arp.cpp b/osdep/Arp.cpp index 8b307eb58..a54b79a17 100644 --- a/osdep/Arp.cpp +++ b/osdep/Arp.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "Arp.hpp" diff --git a/osdep/Arp.hpp b/osdep/Arp.hpp index 51257ef5e..01bcf7ad5 100644 --- a/osdep/Arp.hpp +++ b/osdep/Arp.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_ARP_HPP #define ZT_ARP_HPP diff --git a/osdep/BSDEthernetTap.cpp b/osdep/BSDEthernetTap.cpp index e1e0d42e5..36e70ca7c 100644 --- a/osdep/BSDEthernetTap.cpp +++ b/osdep/BSDEthernetTap.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "BSDEthernetTap.hpp" diff --git a/osdep/BSDEthernetTap.hpp b/osdep/BSDEthernetTap.hpp index 1f382ba7e..190f3a0b4 100644 --- a/osdep/BSDEthernetTap.hpp +++ b/osdep/BSDEthernetTap.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_BSDETHERNETTAP_HPP #define ZT_BSDETHERNETTAP_HPP diff --git a/osdep/Binder.hpp b/osdep/Binder.hpp index 6bb6a0890..56ec2e0e8 100644 --- a/osdep/Binder.hpp +++ b/osdep/Binder.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_BINDER_HPP #define ZT_BINDER_HPP diff --git a/osdep/BlockingQueue.hpp b/osdep/BlockingQueue.hpp index f377aa0bf..785e5bcaf 100644 --- a/osdep/BlockingQueue.hpp +++ b/osdep/BlockingQueue.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_BLOCKINGQUEUE_HPP #define ZT_BLOCKINGQUEUE_HPP diff --git a/osdep/EthernetTap.cpp b/osdep/EthernetTap.cpp index cb242ebfe..1d35e01dc 100644 --- a/osdep/EthernetTap.cpp +++ b/osdep/EthernetTap.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "EthernetTap.hpp" @@ -20,9 +15,9 @@ #ifdef ZT_SDK -#include "../nonfree/controller/EmbeddedNetworkController.hpp" #include "../include/VirtualTap.hpp" #include "../node/Node.hpp" +#include "../nonfree/controller/EmbeddedNetworkController.hpp" #else diff --git a/osdep/EthernetTap.hpp b/osdep/EthernetTap.hpp index aaabfeb60..d213e088d 100644 --- a/osdep/EthernetTap.hpp +++ b/osdep/EthernetTap.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_ETHERNETTAP_HPP #define ZT_ETHERNETTAP_HPP diff --git a/osdep/ExtOsdep.cpp b/osdep/ExtOsdep.cpp index 47543ae4d..4efab5a6c 100644 --- a/osdep/ExtOsdep.cpp +++ b/osdep/ExtOsdep.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "ExtOsdep.hpp" diff --git a/osdep/ExtOsdep.hpp b/osdep/ExtOsdep.hpp index f16893ced..d7028902c 100644 --- a/osdep/ExtOsdep.hpp +++ b/osdep/ExtOsdep.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_EXTOSDEP_HPP #define ZT_EXTOSDEP_HPP diff --git a/osdep/Http.cpp b/osdep/Http.cpp index 4b7879e82..c3e07e915 100644 --- a/osdep/Http.cpp +++ b/osdep/Http.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "Http.hpp" diff --git a/osdep/Http.hpp b/osdep/Http.hpp index 2e4783226..da21d03a0 100644 --- a/osdep/Http.hpp +++ b/osdep/Http.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_HTTP_HPP #define ZT_HTTP_HPP diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp index 5fe37216d..efaa72959 100644 --- a/osdep/LinuxEthernetTap.cpp +++ b/osdep/LinuxEthernetTap.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wrestrict" diff --git a/osdep/LinuxEthernetTap.hpp b/osdep/LinuxEthernetTap.hpp index fe8079360..c5e593c00 100644 --- a/osdep/LinuxEthernetTap.hpp +++ b/osdep/LinuxEthernetTap.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_LINUXETHERNETTAP_HPP #define ZT_LINUXETHERNETTAP_HPP diff --git a/osdep/LinuxNetLink.cpp b/osdep/LinuxNetLink.cpp index 5e7ee5a1d..02c38c09a 100644 --- a/osdep/LinuxNetLink.cpp +++ b/osdep/LinuxNetLink.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "../node/Constants.hpp" diff --git a/osdep/LinuxNetLink.hpp b/osdep/LinuxNetLink.hpp index 6f99130ae..b5a9c38f6 100644 --- a/osdep/LinuxNetLink.hpp +++ b/osdep/LinuxNetLink.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_LINUX_NETLINK_HPP #define ZT_LINUX_NETLINK_HPP @@ -160,4 +155,4 @@ class LinuxNetLink { #endif -#endif // ZT_LINUX_NETLINK_HPPS \ No newline at end of file +#endif // ZT_LINUX_NETLINK_HPPS diff --git a/osdep/MacDNSHelper.hpp b/osdep/MacDNSHelper.hpp index 69ea58d3b..fc457eafd 100644 --- a/osdep/MacDNSHelper.hpp +++ b/osdep/MacDNSHelper.hpp @@ -1,3 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ + */ + #ifndef MAC_DNS_HELPER #define MAC_DNS_HELPER diff --git a/osdep/MacDNSHelper.mm b/osdep/MacDNSHelper.mm index 5e170e172..abfd28745 100644 --- a/osdep/MacDNSHelper.mm +++ b/osdep/MacDNSHelper.mm @@ -1,3 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ + */ + #include "MacDNSHelper.hpp" #include diff --git a/osdep/MacEthernetTap.cpp b/osdep/MacEthernetTap.cpp index 09278855b..87c05b346 100644 --- a/osdep/MacEthernetTap.cpp +++ b/osdep/MacEthernetTap.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "../node/Constants.hpp" diff --git a/osdep/MacEthernetTap.hpp b/osdep/MacEthernetTap.hpp index ac774360c..fb3831f28 100644 --- a/osdep/MacEthernetTap.hpp +++ b/osdep/MacEthernetTap.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_OSXETHERNETTAP_HPP #define ZT_OSXETHERNETTAP_HPP diff --git a/osdep/MacEthernetTapAgent.c b/osdep/MacEthernetTapAgent.c index e74c66940..91248f268 100644 --- a/osdep/MacEthernetTapAgent.c +++ b/osdep/MacEthernetTapAgent.c @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ /* * This creates a pair of feth devices with the lower numbered device diff --git a/osdep/MacEthernetTapAgent.h b/osdep/MacEthernetTapAgent.h index da6e34195..79fdfd07f 100644 --- a/osdep/MacEthernetTapAgent.h +++ b/osdep/MacEthernetTapAgent.h @@ -1,27 +1,22 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_MACETHERNETTAPAGENT_H #define ZT_MACETHERNETTAPAGENT_H -#define ZT_MACETHERNETTAPAGENT_EXIT_CODE_SUCCESS 0 -#define ZT_MACETHERNETTAPAGENT_EXIT_CODE_INVALID_REQUEST -1 +#define ZT_MACETHERNETTAPAGENT_EXIT_CODE_SUCCESS 0 +#define ZT_MACETHERNETTAPAGENT_EXIT_CODE_INVALID_REQUEST -1 #define ZT_MACETHERNETTAPAGENT_EXIT_CODE_UNABLE_TO_CREATE -2 -#define ZT_MACETHERNETTAPAGENT_EXIT_CODE_READ_ERROR -3 +#define ZT_MACETHERNETTAPAGENT_EXIT_CODE_READ_ERROR -3 -#define ZT_MACETHERNETTAPAGENT_STDIN_CMD_PACKET 0 +#define ZT_MACETHERNETTAPAGENT_STDIN_CMD_PACKET 0 #define ZT_MACETHERNETTAPAGENT_STDIN_CMD_IFCONFIG 1 -#define ZT_MACETHERNETTAPAGENT_STDIN_CMD_EXIT 2 +#define ZT_MACETHERNETTAPAGENT_STDIN_CMD_EXIT 2 #define ZT_MACETHERNETTAPAGENT_DEFAULT_SYSTEM_PATH "/Library/Application Support/ZeroTier/One/MacEthernetTapAgent" diff --git a/osdep/MacKextEthernetTap.cpp b/osdep/MacKextEthernetTap.cpp index b7fa97947..30149245f 100644 --- a/osdep/MacKextEthernetTap.cpp +++ b/osdep/MacKextEthernetTap.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "MacDNSHelper.hpp" diff --git a/osdep/MacKextEthernetTap.hpp b/osdep/MacKextEthernetTap.hpp index aac51c32f..f759d50e9 100644 --- a/osdep/MacKextEthernetTap.hpp +++ b/osdep/MacKextEthernetTap.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_MacKextEthernetTap_HPP #define ZT_MacKextEthernetTap_HPP diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp index 9d0245565..6a605b856 100644 --- a/osdep/ManagedRoute.cpp +++ b/osdep/ManagedRoute.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "../node/Constants.hpp" #include "../osdep/OSUtils.hpp" diff --git a/osdep/ManagedRoute.hpp b/osdep/ManagedRoute.hpp index e30be8263..3b4e8464e 100644 --- a/osdep/ManagedRoute.hpp +++ b/osdep/ManagedRoute.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_MANAGEDROUTE_HPP #define ZT_MANAGEDROUTE_HPP diff --git a/osdep/NeighborDiscovery.cpp b/osdep/NeighborDiscovery.cpp index dd2114a3d..ea0b89dc9 100644 --- a/osdep/NeighborDiscovery.cpp +++ b/osdep/NeighborDiscovery.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "NeighborDiscovery.hpp" diff --git a/osdep/NeighborDiscovery.hpp b/osdep/NeighborDiscovery.hpp index fe5d790b0..1d82bb9de 100644 --- a/osdep/NeighborDiscovery.hpp +++ b/osdep/NeighborDiscovery.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_NEIGHBORDISCOVERY_HPP #define ZT_NEIGHBORDISCOVERY_HPP diff --git a/osdep/NetBSDEthernetTap.cpp b/osdep/NetBSDEthernetTap.cpp index 0508246b0..666a387f6 100644 --- a/osdep/NetBSDEthernetTap.cpp +++ b/osdep/NetBSDEthernetTap.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "NetBSDEthernetTap.hpp" diff --git a/osdep/NetBSDEthernetTap.hpp b/osdep/NetBSDEthernetTap.hpp index b505cb504..2502eaa0d 100644 --- a/osdep/NetBSDEthernetTap.hpp +++ b/osdep/NetBSDEthernetTap.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_NetBSDEthernetTap_HPP #define ZT_NetBSDEthernetTap_HPP diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp index 41d144f1b..2fee8f194 100644 --- a/osdep/OSUtils.cpp +++ b/osdep/OSUtils.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "../node/Constants.hpp" #include "../node/Utils.hpp" diff --git a/osdep/OSUtils.hpp b/osdep/OSUtils.hpp index c105612f7..b122a0c94 100644 --- a/osdep/OSUtils.hpp +++ b/osdep/OSUtils.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_OSUTILS_HPP #define ZT_OSUTILS_HPP diff --git a/osdep/Phy.hpp b/osdep/Phy.hpp index 5b1a5fed9..11cbe4c05 100644 --- a/osdep/Phy.hpp +++ b/osdep/Phy.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_PHY_HPP #define ZT_PHY_HPP diff --git a/osdep/PortMapper.cpp b/osdep/PortMapper.cpp index 1b5af9fd9..3585c330a 100644 --- a/osdep/PortMapper.cpp +++ b/osdep/PortMapper.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifdef ZT_USE_MINIUPNPC diff --git a/osdep/PortMapper.hpp b/osdep/PortMapper.hpp index e65064772..34931244e 100644 --- a/osdep/PortMapper.hpp +++ b/osdep/PortMapper.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifdef ZT_USE_MINIUPNPC diff --git a/osdep/Thread.hpp b/osdep/Thread.hpp index abebd4374..46c08f481 100644 --- a/osdep/Thread.hpp +++ b/osdep/Thread.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_THREAD_HPP #define ZT_THREAD_HPP diff --git a/osdep/WinDNSHelper.cpp b/osdep/WinDNSHelper.cpp index 88b39e56d..bde52d20b 100644 --- a/osdep/WinDNSHelper.cpp +++ b/osdep/WinDNSHelper.cpp @@ -1,3 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ + */ + #include "WinDNSHelper.hpp" #include @@ -304,4 +312,4 @@ void WinDNSHelper::removeDNS(uint64_t nwid) } } -} // namespace ZeroTier \ No newline at end of file +} // namespace ZeroTier diff --git a/osdep/WinDNSHelper.hpp b/osdep/WinDNSHelper.hpp index 8a9916da1..14ca8171e 100644 --- a/osdep/WinDNSHelper.hpp +++ b/osdep/WinDNSHelper.hpp @@ -1,3 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ + */ + #ifndef WIN_DNS_HELPER_H_ #define WIN_DNS_HELPER_H_ @@ -19,4 +27,4 @@ class WinDNSHelper { } // namespace ZeroTier -#endif \ No newline at end of file +#endif diff --git a/osdep/WinFWHelper.cpp b/osdep/WinFWHelper.cpp index 5f657d60b..e52e5ad43 100644 --- a/osdep/WinFWHelper.cpp +++ b/osdep/WinFWHelper.cpp @@ -1,3 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ + */ + #include "WinFWHelper.hpp" namespace ZeroTier { @@ -154,4 +162,4 @@ void WinFWHelper::_run(std::string cmd) } } -} // namespace ZeroTier \ No newline at end of file +} // namespace ZeroTier diff --git a/osdep/WinFWHelper.hpp b/osdep/WinFWHelper.hpp index 43c41e47e..2e8e8ef79 100644 --- a/osdep/WinFWHelper.hpp +++ b/osdep/WinFWHelper.hpp @@ -1,3 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ + */ + #ifndef WIN_FW_HELPER_H_ #define WIN_FW_HELPER_H_ @@ -27,4 +35,4 @@ class WinFWHelper { } // namespace ZeroTier -#endif \ No newline at end of file +#endif diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp index 3043868ae..546af9d54 100644 --- a/osdep/WindowsEthernetTap.cpp +++ b/osdep/WindowsEthernetTap.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "WindowsEthernetTap.hpp" diff --git a/osdep/WindowsEthernetTap.hpp b/osdep/WindowsEthernetTap.hpp index fded64bc1..293457f96 100644 --- a/osdep/WindowsEthernetTap.hpp +++ b/osdep/WindowsEthernetTap.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_WINDOWSETHERNETTAP_HPP #define ZT_WINDOWSETHERNETTAP_HPP diff --git a/rule-compiler/rule-compiler.js b/rule-compiler/rule-compiler.js index 81bd5e06c..937fb958c 100644 --- a/rule-compiler/rule-compiler.js +++ b/rule-compiler/rule-compiler.js @@ -1,917 +1,1154 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ -'use strict'; +"use strict"; // Names for bits in characteristics -- 0==LSB, 63==MSB const CHARACTERISTIC_BITS = { - 'inbound': 63, - 'multicast': 62, - 'broadcast': 61, - 'ipauth': 60, - 'macauth': 59, - 'tcp_fin': 0, - 'tcp_syn': 1, - 'tcp_rst': 2, - 'tcp_psh': 3, - 'tcp_ack': 4, - 'tcp_urg': 5, - 'tcp_ece': 6, - 'tcp_cwr': 7, - 'tcp_ns': 8, - 'tcp_rs2': 9, - 'tcp_rs1': 10, - 'tcp_rs0': 11 + inbound: 63, + multicast: 62, + broadcast: 61, + ipauth: 60, + macauth: 59, + tcp_fin: 0, + tcp_syn: 1, + tcp_rst: 2, + tcp_psh: 3, + tcp_ack: 4, + tcp_urg: 5, + tcp_ece: 6, + tcp_cwr: 7, + tcp_ns: 8, + tcp_rs2: 9, + tcp_rs1: 10, + tcp_rs0: 11, }; // Shorthand names for common ethernet types const ETHERTYPES = { - 'ipv4': 0x0800, - 'arp': 0x0806, - 'wol': 0x0842, - 'rarp': 0x8035, - 'ipv6': 0x86dd, - 'atalk': 0x809b, - 'aarp': 0x80f3, - 'ipx_a': 0x8137, - 'ipx_b': 0x8138 + ipv4: 0x0800, + arp: 0x0806, + wol: 0x0842, + rarp: 0x8035, + ipv6: 0x86dd, + atalk: 0x809b, + aarp: 0x80f3, + ipx_a: 0x8137, + ipx_b: 0x8138, }; // Shorthand names for common IP protocols const IP_PROTOCOLS = { - 'icmp': 0x01, - 'icmp4': 0x01, - 'icmpv4': 0x01, - 'igmp': 0x02, - 'ipip': 0x04, - 'tcp': 0x06, - 'egp': 0x08, - 'igp': 0x09, - 'udp': 0x11, - 'rdp': 0x1b, - 'esp': 0x32, - 'ah': 0x33, - 'icmp6': 0x3a, - 'icmpv6': 0x3a, - 'l2tp': 0x73, - 'sctp': 0x84, - 'udplite': 0x88 + icmp: 0x01, + icmp4: 0x01, + icmpv4: 0x01, + igmp: 0x02, + ipip: 0x04, + tcp: 0x06, + egp: 0x08, + igp: 0x09, + udp: 0x11, + rdp: 0x1b, + esp: 0x32, + ah: 0x33, + icmp6: 0x3a, + icmpv6: 0x3a, + l2tp: 0x73, + sctp: 0x84, + udplite: 0x88, }; // Keywords that open new blocks that must be terminated by a semicolon const OPEN_BLOCK_KEYWORDS = { - 'macro': true, - 'tag': true, - 'cap': true, - 'drop': true, - 'accept': true, - 'tee': true, - 'watch': true, - 'redirect': true, - 'break': true, - 'priority': true + macro: true, + tag: true, + cap: true, + drop: true, + accept: true, + tee: true, + watch: true, + redirect: true, + break: true, + priority: true, }; // Reserved words that can't be used as tag, capability, or rule set names const RESERVED_WORDS = { - 'macro': true, - 'tag': true, - 'cap': true, - 'default': true, + macro: true, + tag: true, + cap: true, + default: true, - 'drop': true, - 'accept': true, - 'tee': true, - 'watch': true, - 'redirect': true, - 'break': true, - 'priority': true, + drop: true, + accept: true, + tee: true, + watch: true, + redirect: true, + break: true, + priority: true, - 'ztsrc': true, - 'ztdest': true, - 'vlan': true, - 'vlanpcp': true, - 'vlandei': true, - 'ethertype': true, - 'macsrc': true, - 'macdest': true, - 'ipsrc': true, - 'ipdest': true, - 'iptos': true, - 'ipprotocol': true, - 'icmp': true, - 'sport': true, - 'dport': true, - 'chr': true, - 'framesize': true, - 'random': true, - 'tand': true, - 'tor': true, - 'txor': true, - 'tdiff': true, - 'teq': true, - 'tseq': true, - 'treq': true, + ztsrc: true, + ztdest: true, + vlan: true, + vlanpcp: true, + vlandei: true, + ethertype: true, + macsrc: true, + macdest: true, + ipsrc: true, + ipdest: true, + iptos: true, + ipprotocol: true, + icmp: true, + sport: true, + dport: true, + chr: true, + framesize: true, + random: true, + tand: true, + tor: true, + txor: true, + tdiff: true, + teq: true, + tseq: true, + treq: true, - 'type': true, - 'enum': true, - 'class': true, - 'define': true, - 'import': true, - 'include': true, - 'log': true, - 'not': true, - 'xor': true, - 'or': true, - 'and': true, - 'set': true, - 'var': true, - 'let': true + type: true, + enum: true, + class: true, + define: true, + import: true, + include: true, + log: true, + not: true, + xor: true, + or: true, + and: true, + set: true, + var: true, + let: true, }; const KEYWORD_TO_API_MAP = { - 'drop': 'ACTION_DROP', - 'accept': 'ACTION_ACCEPT', - 'tee': 'ACTION_TEE', - 'watch': 'ACTION_WATCH', - 'redirect': 'ACTION_REDIRECT', - 'break': 'ACTION_BREAK', - 'priority': 'ACTION_PRIORITY', + drop: "ACTION_DROP", + accept: "ACTION_ACCEPT", + tee: "ACTION_TEE", + watch: "ACTION_WATCH", + redirect: "ACTION_REDIRECT", + break: "ACTION_BREAK", + priority: "ACTION_PRIORITY", - 'ztsrc': 'MATCH_SOURCE_ZEROTIER_ADDRESS', - 'ztdest': 'MATCH_DEST_ZEROTIER_ADDRESS', - 'vlan': 'MATCH_VLAN_ID', - 'vlanpcp': 'MATCH_VLAN_PCP', - 'vlandei': 'MATCH_VLAN_DEI', - 'ethertype': 'MATCH_ETHERTYPE', - 'macsrc': 'MATCH_MAC_SOURCE', - 'macdest': 'MATCH_MAC_DEST', - //'ipsrc': '', // special handling since we programmatically differentiate between V4 and V6 - //'ipdest': '', // special handling - 'iptos': 'MATCH_IP_TOS', - 'ipprotocol': 'MATCH_IP_PROTOCOL', - 'icmp': 'MATCH_ICMP', - 'sport': 'MATCH_IP_SOURCE_PORT_RANGE', - 'dport': 'MATCH_IP_DEST_PORT_RANGE', - 'chr': 'MATCH_CHARACTERISTICS', - 'framesize': 'MATCH_FRAME_SIZE_RANGE', - 'random': 'MATCH_RANDOM', - 'tand': 'MATCH_TAGS_BITWISE_AND', - 'tor': 'MATCH_TAGS_BITWISE_OR', - 'txor': 'MATCH_TAGS_BITWISE_XOR', - 'tdiff': 'MATCH_TAGS_DIFFERENCE', - 'teq': 'MATCH_TAGS_EQUAL', - 'tseq': 'MATCH_TAG_SENDER', - 'treq': 'MATCH_TAG_RECEIVER' + ztsrc: "MATCH_SOURCE_ZEROTIER_ADDRESS", + ztdest: "MATCH_DEST_ZEROTIER_ADDRESS", + vlan: "MATCH_VLAN_ID", + vlanpcp: "MATCH_VLAN_PCP", + vlandei: "MATCH_VLAN_DEI", + ethertype: "MATCH_ETHERTYPE", + macsrc: "MATCH_MAC_SOURCE", + macdest: "MATCH_MAC_DEST", + //'ipsrc': '', // special handling since we programmatically differentiate between V4 and V6 + //'ipdest': '', // special handling + iptos: "MATCH_IP_TOS", + ipprotocol: "MATCH_IP_PROTOCOL", + icmp: "MATCH_ICMP", + sport: "MATCH_IP_SOURCE_PORT_RANGE", + dport: "MATCH_IP_DEST_PORT_RANGE", + chr: "MATCH_CHARACTERISTICS", + framesize: "MATCH_FRAME_SIZE_RANGE", + random: "MATCH_RANDOM", + tand: "MATCH_TAGS_BITWISE_AND", + tor: "MATCH_TAGS_BITWISE_OR", + txor: "MATCH_TAGS_BITWISE_XOR", + tdiff: "MATCH_TAGS_DIFFERENCE", + teq: "MATCH_TAGS_EQUAL", + tseq: "MATCH_TAG_SENDER", + treq: "MATCH_TAG_RECEIVER", }; // Number of args for each match const MATCH_ARG_COUNTS = { - 'ztsrc': 1, - 'ztdest': 1, - 'vlan': 1, - 'vlanpcp': 1, - 'vlandei': 1, - 'ethertype': 1, - 'macsrc': 1, - 'macdest': 1, - 'ipsrc': 1, - 'ipdest': 1, - 'iptos': 2, - 'ipprotocol': 1, - 'icmp': 2, - 'sport': 1, - 'dport': 1, - 'chr': 1, - 'framesize': 1, - 'random': 1, - 'tand': 2, - 'tor': 2, - 'txor': 2, - 'tdiff': 2, - 'teq': 2, - 'tseq': 2, - 'treq': 2 + ztsrc: 1, + ztdest: 1, + vlan: 1, + vlanpcp: 1, + vlandei: 1, + ethertype: 1, + macsrc: 1, + macdest: 1, + ipsrc: 1, + ipdest: 1, + iptos: 2, + ipprotocol: 1, + icmp: 2, + sport: 1, + dport: 1, + chr: 1, + framesize: 1, + random: 1, + tand: 2, + tor: 2, + txor: 2, + tdiff: 2, + teq: 2, + tseq: 2, + treq: 2, }; // Regex of all alphanumeric characters in Unicode -const INTL_ALPHANUM_REGEX = new RegExp('[0-9A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'); +const INTL_ALPHANUM_REGEX = new RegExp( + "[0-9A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]", +); // Checks whether something is a valid capability, tag, or macro name function _isValidName(n) { - if ((typeof n !== 'string') || (n.length === 0)) return false; - if ("0123456789".indexOf(n.charAt(0)) >= 0) return false; - for (let i = 0; i < n.length; ++i) { - let c = n.charAt(i); - if ((c !== '_') && (!INTL_ALPHANUM_REGEX.test(c))) return false; - } - return true; + if (typeof n !== "string" || n.length === 0) return false; + if ("0123456789".indexOf(n.charAt(0)) >= 0) return false; + for (let i = 0; i < n.length; ++i) { + let c = n.charAt(i); + if (c !== "_" && !INTL_ALPHANUM_REGEX.test(c)) return false; + } + return true; } // Regexes for checking the basic syntactic validity of IP addresses -const IPV6_REGEX = new RegExp('(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'); -const IPV4_REGEX = new RegExp('((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])'); +const IPV6_REGEX = new RegExp( + "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))", +); +const IPV4_REGEX = new RegExp( + "((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])", +); function _parseNum(n) { - try { - if ((typeof n !== 'string') || (n.length === 0)) - return -1; - n = n.toLowerCase(); - if ((n.length > 2) && (n.substr(0, 2) === '0x')) - n = parseInt(n.substr(2), 16); - else n = parseInt(n, 10); - return (((typeof n === 'number') && (n !== null) && (!isNaN(n))) ? n : -1); - } catch (e) { - return -1; - } + try { + if (typeof n !== "string" || n.length === 0) return -1; + n = n.toLowerCase(); + if (n.length > 2 && n.substr(0, 2) === "0x") n = parseInt(n.substr(2), 16); + else n = parseInt(n, 10); + return typeof n === "number" && n !== null && !isNaN(n) ? n : -1; + } catch (e) { + return -1; + } } function _cleanMac(m) { - m = m.toLowerCase(); - var m2 = ''; - let charcount = 0; - for (let i = 0; ((i < m.length) && (m2.length < 17)); ++i) { - let c = m.charAt(i); - if ("0123456789abcdef".indexOf(c) >= 0) { - m2 += c; - charcount++; - if ((m2.length > 0) && (m2.length !== 17) && (charcount >= 2)) { - m2 += ':'; - charcount = 0; - } - } - } - return m2; + m = m.toLowerCase(); + var m2 = ""; + let charcount = 0; + for (let i = 0; i < m.length && m2.length < 17; ++i) { + let c = m.charAt(i); + if ("0123456789abcdef".indexOf(c) >= 0) { + m2 += c; + charcount++; + if (m2.length > 0 && m2.length !== 17 && charcount >= 2) { + m2 += ":"; + charcount = 0; + } + } + } + return m2; } function _cleanHex(m) { - m = m.toLowerCase(); - var m2 = ''; - for (let i = 0; i < m.length; ++i) { - let c = m.charAt(i); - if ("0123456789abcdef".indexOf(c) >= 0) - m2 += c; - } - return m2; + m = m.toLowerCase(); + var m2 = ""; + for (let i = 0; i < m.length; ++i) { + let c = m.charAt(i); + if ("0123456789abcdef".indexOf(c) >= 0) m2 += c; + } + return m2; } function _renderMatches(mtree, rules, macros, caps, tags, params) { - let not = false; - let or = false; - for (let k = 0; k < mtree.length; ++k) { - let match = (typeof mtree[k][0] === 'string') ? mtree[k][0].toLowerCase() : ''; - if ((match.length === 0) || (match === 'and')) { // AND is the default - continue; - } else if (match === 'not') { - not = true; - } else if (match === 'or') { - or = true; - } else { - let args = []; - let argCount = MATCH_ARG_COUNTS[match]; - if (!argCount) - return [mtree[k][1], mtree[k][2], 'Unrecognized match type "' + match + '".']; - for (let i = 0; i < argCount; ++i) { - if (++k >= mtree.length) - return [mtree[k - 1][1], mtree[k - 1][2], 'Missing argument(s) to match.']; - let arg = mtree[k][0]; - if ((typeof arg !== 'string') || (arg in RESERVED_WORDS) || (arg.length === 0)) - return [mtree[k - 1][1], mtree[k - 1][2], 'Missing argument(s) to match (invalid argument or argument is reserved word).']; - if (arg.charAt(0) === '$') { - let tmp = params[arg]; - if (typeof tmp === 'undefined') - return [mtree[k][1], mtree[k][2], 'Undefined variable name.']; - args.push([tmp, mtree[k][1], mtree[k][2]]); - } else { - args.push(mtree[k]); - } - } + let not = false; + let or = false; + for (let k = 0; k < mtree.length; ++k) { + let match = + typeof mtree[k][0] === "string" ? mtree[k][0].toLowerCase() : ""; + if (match.length === 0 || match === "and") { + // AND is the default + continue; + } else if (match === "not") { + not = true; + } else if (match === "or") { + or = true; + } else { + let args = []; + let argCount = MATCH_ARG_COUNTS[match]; + if (!argCount) + return [ + mtree[k][1], + mtree[k][2], + 'Unrecognized match type "' + match + '".', + ]; + for (let i = 0; i < argCount; ++i) { + if (++k >= mtree.length) + return [ + mtree[k - 1][1], + mtree[k - 1][2], + "Missing argument(s) to match.", + ]; + let arg = mtree[k][0]; + if ( + typeof arg !== "string" || + arg in RESERVED_WORDS || + arg.length === 0 + ) + return [ + mtree[k - 1][1], + mtree[k - 1][2], + "Missing argument(s) to match (invalid argument or argument is reserved word).", + ]; + if (arg.charAt(0) === "$") { + let tmp = params[arg]; + if (typeof tmp === "undefined") + return [mtree[k][1], mtree[k][2], "Undefined variable name."]; + args.push([tmp, mtree[k][1], mtree[k][2]]); + } else { + args.push(mtree[k]); + } + } - switch (match) { - case 'ztsrc': - case 'ztdest': { - let zt = _cleanHex(args[0][0]); - if (zt.length !== 10) - return [args[0][1], args[0][2], 'Invalid ZeroTier address.']; - rules.push({ - 'type': KEYWORD_TO_API_MAP[match], - 'not': not, - 'or': or, - 'zt': zt - }); - } break; + switch (match) { + case "ztsrc": + case "ztdest": + { + let zt = _cleanHex(args[0][0]); + if (zt.length !== 10) + return [args[0][1], args[0][2], "Invalid ZeroTier address."]; + rules.push({ + type: KEYWORD_TO_API_MAP[match], + not: not, + or: or, + zt: zt, + }); + } + break; - case 'vlan': - case 'vlanpcp': - case 'vlandei': - case 'ethertype': - case 'ipprotocol': { - let num = null; - switch (match) { - case 'ethertype': num = ETHERTYPES[args[0][0]]; break; - case 'ipprotocol': num = IP_PROTOCOLS[args[0][0]]; break; - } - if (typeof num !== 'number') - num = _parseNum(args[0][0]); - if ((typeof num !== 'number') || (num < 0) || (num > 0xffffffff) || (num === null)) - return [args[0][1], args[0][2], 'Invalid numeric value.']; - let r = { - 'type': KEYWORD_TO_API_MAP[match], - 'not': not, - 'or': or - }; - switch (match) { - case 'vlan': r['vlanId'] = num; break; - case 'vlanpcp': r['vlanPcp'] = num; break; - case 'vlandei': r['vlanDei'] = num; break; - case 'ethertype': r['etherType'] = num; break; - case 'ipprotocol': r['ipProtocol'] = num; break; - } - rules.push(r); - } break; + case "vlan": + case "vlanpcp": + case "vlandei": + case "ethertype": + case "ipprotocol": + { + let num = null; + switch (match) { + case "ethertype": + num = ETHERTYPES[args[0][0]]; + break; + case "ipprotocol": + num = IP_PROTOCOLS[args[0][0]]; + break; + } + if (typeof num !== "number") num = _parseNum(args[0][0]); + if ( + typeof num !== "number" || + num < 0 || + num > 0xffffffff || + num === null + ) + return [args[0][1], args[0][2], "Invalid numeric value."]; + let r = { + type: KEYWORD_TO_API_MAP[match], + not: not, + or: or, + }; + switch (match) { + case "vlan": + r["vlanId"] = num; + break; + case "vlanpcp": + r["vlanPcp"] = num; + break; + case "vlandei": + r["vlanDei"] = num; + break; + case "ethertype": + r["etherType"] = num; + break; + case "ipprotocol": + r["ipProtocol"] = num; + break; + } + rules.push(r); + } + break; - case 'random': { - let num = parseFloat(args[0][0]) || 0.0; - if (num < 0.0) num = 0.0; - if (num > 1.0) num = 1.0; - rules.push({ - 'type': KEYWORD_TO_API_MAP[match], - 'not': not, - 'or': or, - 'probability': Math.floor(4294967295 * num) - }); - } break; + case "random": + { + let num = parseFloat(args[0][0]) || 0.0; + if (num < 0.0) num = 0.0; + if (num > 1.0) num = 1.0; + rules.push({ + type: KEYWORD_TO_API_MAP[match], + not: not, + or: or, + probability: Math.floor(4294967295 * num), + }); + } + break; - case 'macsrc': - case 'macdest': { - let mac = _cleanMac(args[0][0]); - if (mac.length !== 17) - return [args[0][1], args[0][2], 'Invalid MAC address.']; - rules.push({ - 'type': KEYWORD_TO_API_MAP[match], - 'not': not, - 'or': or, - 'mac': mac - }); - } break; + case "macsrc": + case "macdest": + { + let mac = _cleanMac(args[0][0]); + if (mac.length !== 17) + return [args[0][1], args[0][2], "Invalid MAC address."]; + rules.push({ + type: KEYWORD_TO_API_MAP[match], + not: not, + or: or, + mac: mac, + }); + } + break; - case 'ipsrc': - case 'ipdest': { - let ip = args[0][0]; - let slashIdx = ip.indexOf('/'); - if (slashIdx <= 0) - return [args[0][1], args[0][2], 'Missing /bits netmask length designation in IP.']; - let ipOnly = ip.substr(0, slashIdx); - if (IPV6_REGEX.test(ipOnly)) { - rules.push({ - 'type': ((match === 'ipsrc') ? 'MATCH_IPV6_SOURCE' : 'MATCH_IPV6_DEST'), - 'not': not, - 'or': or, - 'ip': ip - }); - } else if (IPV4_REGEX.test(ipOnly)) { - rules.push({ - 'type': ((match === 'ipsrc') ? 'MATCH_IPV4_SOURCE' : 'MATCH_IPV4_DEST'), - 'not': not, - 'or': or, - 'ip': ip - }); - } else { - return [args[0][1], args[0][2], 'Invalid IP address (not valid IPv4 or IPv6).']; - } - } break; + case "ipsrc": + case "ipdest": + { + let ip = args[0][0]; + let slashIdx = ip.indexOf("/"); + if (slashIdx <= 0) + return [ + args[0][1], + args[0][2], + "Missing /bits netmask length designation in IP.", + ]; + let ipOnly = ip.substr(0, slashIdx); + if (IPV6_REGEX.test(ipOnly)) { + rules.push({ + type: + match === "ipsrc" ? "MATCH_IPV6_SOURCE" : "MATCH_IPV6_DEST", + not: not, + or: or, + ip: ip, + }); + } else if (IPV4_REGEX.test(ipOnly)) { + rules.push({ + type: + match === "ipsrc" ? "MATCH_IPV4_SOURCE" : "MATCH_IPV4_DEST", + not: not, + or: or, + ip: ip, + }); + } else { + return [ + args[0][1], + args[0][2], + "Invalid IP address (not valid IPv4 or IPv6).", + ]; + } + } + break; - case 'icmp': { - let icmpType = _parseNum(args[0][0]); - if ((icmpType < 0) || (icmpType > 0xff)) - return [args[0][1], args[0][2], 'Missing or invalid ICMP type.']; - let icmpCode = _parseNum(args[1][0]); // -1 okay, indicates don't match code - if (icmpCode > 0xff) - return [args[1][1], args[1][2], 'Invalid ICMP code (use -1 for none).']; - rules.push({ - 'type': 'MATCH_ICMP', - 'not': not, - 'or': or, - 'icmpType': icmpType, - 'icmpCode': ((icmpCode < 0) ? null : icmpCode) - }); - } break; + case "icmp": + { + let icmpType = _parseNum(args[0][0]); + if (icmpType < 0 || icmpType > 0xff) + return [args[0][1], args[0][2], "Missing or invalid ICMP type."]; + let icmpCode = _parseNum(args[1][0]); // -1 okay, indicates don't match code + if (icmpCode > 0xff) + return [ + args[1][1], + args[1][2], + "Invalid ICMP code (use -1 for none).", + ]; + rules.push({ + type: "MATCH_ICMP", + not: not, + or: or, + icmpType: icmpType, + icmpCode: icmpCode < 0 ? null : icmpCode, + }); + } + break; - case 'sport': - case 'dport': - case 'framesize': { - let arg = args[0][0]; - let fn = null; - let tn = null; - if (arg.indexOf('-') > 0) { - let asplit = arg.split('-'); - if (asplit.length !== 2) { - return [args[0][1], args[0][2], 'Invalid numeric range.']; - } else { - fn = _parseNum(asplit[0]); - tn = _parseNum(asplit[1]); - } - } else { - fn = _parseNum(arg); - tn = fn; - } - if ((fn < 0) || (fn > 0xffff) || (tn < 0) || (tn > 0xffff) || (tn < fn)) - return [args[0][1], args[0][2], 'Invalid numeric range.']; - rules.push({ - 'type': KEYWORD_TO_API_MAP[match], - 'not': not, - 'or': or, - 'start': fn, - 'end': tn - }); - } break; + case "sport": + case "dport": + case "framesize": + { + let arg = args[0][0]; + let fn = null; + let tn = null; + if (arg.indexOf("-") > 0) { + let asplit = arg.split("-"); + if (asplit.length !== 2) { + return [args[0][1], args[0][2], "Invalid numeric range."]; + } else { + fn = _parseNum(asplit[0]); + tn = _parseNum(asplit[1]); + } + } else { + fn = _parseNum(arg); + tn = fn; + } + if (fn < 0 || fn > 0xffff || tn < 0 || tn > 0xffff || tn < fn) + return [args[0][1], args[0][2], "Invalid numeric range."]; + rules.push({ + type: KEYWORD_TO_API_MAP[match], + not: not, + or: or, + start: fn, + end: tn, + }); + } + break; - case 'iptos': { - let mask = _parseNum(args[0][0]); - if ((typeof mask !== 'number') || (mask < 0) || (mask > 0xff) || (mask === null)) - return [args[0][1], args[0][2], 'Invalid mask.']; - let arg = args[1][0]; - let fn = null; - let tn = null; - if (arg.indexOf('-') > 0) { - let asplit = arg.split('-'); - if (asplit.length !== 2) { - return [args[1][1], args[1][2], 'Invalid value range.']; - } else { - fn = _parseNum(asplit[0]); - tn = _parseNum(asplit[1]); - } - } else { - fn = _parseNum(arg); - tn = fn; - } - if ((fn < 0) || (fn > 0xff) || (tn < 0) || (tn > 0xff) || (tn < fn)) - return [args[1][1], args[1][2], 'Invalid value range.']; - rules.push({ - 'type': 'MATCH_IP_TOS', - 'not': not, - 'or': or, - 'mask': mask, - 'start': fn, - 'end': tn - }); - } break; + case "iptos": + { + let mask = _parseNum(args[0][0]); + if ( + typeof mask !== "number" || + mask < 0 || + mask > 0xff || + mask === null + ) + return [args[0][1], args[0][2], "Invalid mask."]; + let arg = args[1][0]; + let fn = null; + let tn = null; + if (arg.indexOf("-") > 0) { + let asplit = arg.split("-"); + if (asplit.length !== 2) { + return [args[1][1], args[1][2], "Invalid value range."]; + } else { + fn = _parseNum(asplit[0]); + tn = _parseNum(asplit[1]); + } + } else { + fn = _parseNum(arg); + tn = fn; + } + if (fn < 0 || fn > 0xff || tn < 0 || tn > 0xff || tn < fn) + return [args[1][1], args[1][2], "Invalid value range."]; + rules.push({ + type: "MATCH_IP_TOS", + not: not, + or: or, + mask: mask, + start: fn, + end: tn, + }); + } + break; - case 'chr': { - let chrb = args[0][0].split(/[,]+/); - let maskhi = 0; - let masklo = 0; - for (let i = 0; i < chrb.length; ++i) { - if (chrb[i].length > 0) { - let tmp = CHARACTERISTIC_BITS[chrb[i]]; - let bit = (typeof tmp === 'number') ? tmp : _parseNum(chrb[i]); - if ((bit < 0) || (bit > 63)) - return [args[0][1], args[0][2], 'Invalid bit index (range 0-63) or unrecognized name.']; - if (bit >= 32) - maskhi |= Math.abs(1 << (bit - 32)); - else masklo |= Math.abs(1 << bit); - } - } - maskhi = Math.abs(maskhi).toString(16); - while (maskhi.length < 8) maskhi = '0' + maskhi; - masklo = Math.abs(masklo).toString(16); - while (masklo.length < 8) masklo = '0' + masklo; - rules.push({ - 'type': 'MATCH_CHARACTERISTICS', - 'not': not, - 'or': or, - 'mask': (maskhi + masklo) - }); - } break; + case "chr": + { + let chrb = args[0][0].split(/[,]+/); + let maskhi = 0; + let masklo = 0; + for (let i = 0; i < chrb.length; ++i) { + if (chrb[i].length > 0) { + let tmp = CHARACTERISTIC_BITS[chrb[i]]; + let bit = typeof tmp === "number" ? tmp : _parseNum(chrb[i]); + if (bit < 0 || bit > 63) + return [ + args[0][1], + args[0][2], + "Invalid bit index (range 0-63) or unrecognized name.", + ]; + if (bit >= 32) maskhi |= Math.abs(1 << (bit - 32)); + else masklo |= Math.abs(1 << bit); + } + } + maskhi = Math.abs(maskhi).toString(16); + while (maskhi.length < 8) maskhi = "0" + maskhi; + masklo = Math.abs(masklo).toString(16); + while (masklo.length < 8) masklo = "0" + masklo; + rules.push({ + type: "MATCH_CHARACTERISTICS", + not: not, + or: or, + mask: maskhi + masklo, + }); + } + break; - case 'tand': - case 'tor': - case 'txor': - case 'tdiff': - case 'teq': - case 'tseq': - case 'treq': { - let tag = tags[args[0][0]]; - let tagId = -1; - let tagValue = -1; - if (tag) { - tagId = tag.id; - tagValue = args[1][0]; - if (tagValue in tag.flags) - tagValue = tag.flags[tagValue]; - else if (tagValue in tag.enums) - tagValue = tag.enums[tagValue]; - else tagValue = _parseNum(tagValue); - } else { - tagId = _parseNum(args[0][0]); - tagValue = _parseNum(args[1][0]); - } - if ((tagId < 0) || (tagId > 0xffffffff)) - return [args[0][1], args[0][2], 'Undefined tag name and invalid tag value.']; - if ((tagValue < 0) || (tagValue > 0xffffffff)) - return [args[1][1], args[1][2], 'Invalid tag value or unrecognized flag/enum name.']; - rules.push({ - 'type': KEYWORD_TO_API_MAP[match], - 'not': not, - 'or': or, - 'id': tagId, - 'value': tagValue - }); - } break; - } + case "tand": + case "tor": + case "txor": + case "tdiff": + case "teq": + case "tseq": + case "treq": + { + let tag = tags[args[0][0]]; + let tagId = -1; + let tagValue = -1; + if (tag) { + tagId = tag.id; + tagValue = args[1][0]; + if (tagValue in tag.flags) tagValue = tag.flags[tagValue]; + else if (tagValue in tag.enums) tagValue = tag.enums[tagValue]; + else tagValue = _parseNum(tagValue); + } else { + tagId = _parseNum(args[0][0]); + tagValue = _parseNum(args[1][0]); + } + if (tagId < 0 || tagId > 0xffffffff) + return [ + args[0][1], + args[0][2], + "Undefined tag name and invalid tag value.", + ]; + if (tagValue < 0 || tagValue > 0xffffffff) + return [ + args[1][1], + args[1][2], + "Invalid tag value or unrecognized flag/enum name.", + ]; + rules.push({ + type: KEYWORD_TO_API_MAP[match], + not: not, + or: or, + id: tagId, + value: tagValue, + }); + } + break; + } - not = false; - or = false; - } - } - return null; + not = false; + or = false; + } + } + return null; } function _renderActions(rtree, rules, macros, caps, tags, params) { - for (let k = 0; k < rtree.length; ++k) { - let action = (typeof rtree[k][0] === 'string') ? rtree[k][0].toLowerCase() : ''; - if (action.length === 0) { - continue; - } else if (action === 'include') { - if ((k + 1) >= rtree.length) - return [rtree[k][1], rtree[k][2], 'Include directive is missing a macro name.']; - let macroName = rtree[k + 1][0]; - ++k; + for (let k = 0; k < rtree.length; ++k) { + let action = + typeof rtree[k][0] === "string" ? rtree[k][0].toLowerCase() : ""; + if (action.length === 0) { + continue; + } else if (action === "include") { + if (k + 1 >= rtree.length) + return [ + rtree[k][1], + rtree[k][2], + "Include directive is missing a macro name.", + ]; + let macroName = rtree[k + 1][0]; + ++k; - let macroParamArray = []; - let parenIdx = macroName.indexOf('('); - if (parenIdx > 0) { - let pns = macroName.substr(parenIdx + 1).split(/[,)]+/); - for (let k = 0; k < pns.length; ++k) { - if (pns[k].length > 0) - macroParamArray.push(pns[k]); - } - macroName = macroName.substr(0, parenIdx); - } + let macroParamArray = []; + let parenIdx = macroName.indexOf("("); + if (parenIdx > 0) { + let pns = macroName.substr(parenIdx + 1).split(/[,)]+/); + for (let k = 0; k < pns.length; ++k) { + if (pns[k].length > 0) macroParamArray.push(pns[k]); + } + macroName = macroName.substr(0, parenIdx); + } - let macro = macros[macroName]; - if (!macro) - return [rtree[k][1], rtree[k][2], 'Macro name not found.']; - let macroParams = {}; - for (let param in macro.params) { - let pidx = macro.params[param]; - if (pidx >= macroParamArray.length) - return [rtree[k][1], rtree[k][2], 'Missing one or more required macro parameter.']; - macroParams[param] = macroParamArray[pidx]; - } + let macro = macros[macroName]; + if (!macro) return [rtree[k][1], rtree[k][2], "Macro name not found."]; + let macroParams = {}; + for (let param in macro.params) { + let pidx = macro.params[param]; + if (pidx >= macroParamArray.length) + return [ + rtree[k][1], + rtree[k][2], + "Missing one or more required macro parameter.", + ]; + macroParams[param] = macroParamArray[pidx]; + } - let err = _renderActions(macro.rules, rules, macros, caps, tags, macroParams); - if (err !== null) - return err; - } else if ((action === 'drop') || (action === 'accept') || (action === 'break')) { // actions without arguments - if (((k + 1) < rtree.length) && (Array.isArray(rtree[k + 1][0]))) { - let mtree = rtree[k + 1]; ++k; - let err = _renderMatches(mtree, rules, macros, caps, tags, params); - if (err !== null) - return err; - } - rules.push({ - 'type': KEYWORD_TO_API_MAP[action] - }); - } else if ((action === 'tee') || (action === 'watch')) { // actions with arguments (ZeroTier address) - if (((k + 1) < rtree.length) && (Array.isArray(rtree[k + 1][0])) && (rtree[k + 1][0].length >= 2)) { - let mtree = rtree[k + 1]; ++k; - let maxLength = _parseNum(mtree[0][0]); - if ((maxLength < -1) || (maxLength > 0xffff)) - return [mtree[0][1], mtree[1][2], 'Tee/watch max packet length to forward invalid or out of range.']; - let target = mtree[1][0]; - if ((typeof target !== 'string') || (target.length !== 10)) - return [mtree[1][1], mtree[1][2], 'Missing or invalid ZeroTier address target for tee/watch.']; - let err = _renderMatches(mtree.slice(2), rules, macros, caps, tags, params); - if (err !== null) - return err; - rules.push({ - 'type': KEYWORD_TO_API_MAP[action], - 'address': target, - 'length': maxLength - }); - } else { - return [rtree[k][1], rtree[k][2], 'The tee and watch actions require two paremters (max length or 0 for all, target).']; - } - } else if (action === 'redirect') { - if (((k + 1) < rtree.length) && (Array.isArray(rtree[k + 1][0])) && (rtree[k + 1][0].length >= 1)) { - let mtree = rtree[k + 1]; ++k; - let target = mtree[0][0]; - if ((typeof target !== 'string') || (target.length !== 10)) - return [mtree[0][1], mtree[0][2], 'Missing or invalid ZeroTier address target for redirect.']; - let err = _renderMatches(mtree.slice(1), rules, macros, caps, tags, params); - if (err !== null) - return err; - rules.push({ - 'type': KEYWORD_TO_API_MAP[action], - 'address': target - }); - } else { - return [rtree[k][1], rtree[k][2], 'The redirect action requires a target parameter.']; - } - } else { - return [rtree[k][1], rtree[k][2], 'Unrecognized action or directive in rule set.']; - } - } + let err = _renderActions( + macro.rules, + rules, + macros, + caps, + tags, + macroParams, + ); + if (err !== null) return err; + } else if (action === "drop" || action === "accept" || action === "break") { + // actions without arguments + if (k + 1 < rtree.length && Array.isArray(rtree[k + 1][0])) { + let mtree = rtree[k + 1]; + ++k; + let err = _renderMatches(mtree, rules, macros, caps, tags, params); + if (err !== null) return err; + } + rules.push({ + type: KEYWORD_TO_API_MAP[action], + }); + } else if (action === "tee" || action === "watch") { + // actions with arguments (ZeroTier address) + if ( + k + 1 < rtree.length && + Array.isArray(rtree[k + 1][0]) && + rtree[k + 1][0].length >= 2 + ) { + let mtree = rtree[k + 1]; + ++k; + let maxLength = _parseNum(mtree[0][0]); + if (maxLength < -1 || maxLength > 0xffff) + return [ + mtree[0][1], + mtree[1][2], + "Tee/watch max packet length to forward invalid or out of range.", + ]; + let target = mtree[1][0]; + if (typeof target !== "string" || target.length !== 10) + return [ + mtree[1][1], + mtree[1][2], + "Missing or invalid ZeroTier address target for tee/watch.", + ]; + let err = _renderMatches( + mtree.slice(2), + rules, + macros, + caps, + tags, + params, + ); + if (err !== null) return err; + rules.push({ + type: KEYWORD_TO_API_MAP[action], + address: target, + length: maxLength, + }); + } else { + return [ + rtree[k][1], + rtree[k][2], + "The tee and watch actions require two paremters (max length or 0 for all, target).", + ]; + } + } else if (action === "redirect") { + if ( + k + 1 < rtree.length && + Array.isArray(rtree[k + 1][0]) && + rtree[k + 1][0].length >= 1 + ) { + let mtree = rtree[k + 1]; + ++k; + let target = mtree[0][0]; + if (typeof target !== "string" || target.length !== 10) + return [ + mtree[0][1], + mtree[0][2], + "Missing or invalid ZeroTier address target for redirect.", + ]; + let err = _renderMatches( + mtree.slice(1), + rules, + macros, + caps, + tags, + params, + ); + if (err !== null) return err; + rules.push({ + type: KEYWORD_TO_API_MAP[action], + address: target, + }); + } else { + return [ + rtree[k][1], + rtree[k][2], + "The redirect action requires a target parameter.", + ]; + } + } else { + return [ + rtree[k][1], + rtree[k][2], + "Unrecognized action or directive in rule set.", + ]; + } + } - return null; + return null; } function compile(src, rules, caps, tags) { - try { - if (typeof src !== 'string') - return [0, 0, '"src" parameter must be a string.']; + try { + if (typeof src !== "string") + return [0, 0, '"src" parameter must be a string.']; - // Pass 1: parse source into a tree of arrays of elements. Each element is a 3-item - // tuple consisting of string, line number, and character index in line to enable - // informative error messages to be returned. + // Pass 1: parse source into a tree of arrays of elements. Each element is a 3-item + // tuple consisting of string, line number, and character index in line to enable + // informative error messages to be returned. - var blockStack = [[]]; - var curr = ['', -1, -1]; - var skipRestOfLine = false; - for (let idx = 0, lineNo = 1, lineIdx = 0; idx < src.length; ++idx, ++lineIdx) { - let ch = src.charAt(idx); - if (skipRestOfLine) { - if ((ch === '\r') || (ch === '\n')) { - skipRestOfLine = false; - ++lineNo; - lineIdx = 0; - } - } else { - switch (ch) { - case '\n': - ++lineNo; - lineIdx = 0; - case '\r': - case '\t': - case ' ': - if (curr[0].length > 0) { - let endOfBlock = false; - if (curr[0].charAt(curr[0].length - 1) === ';') { - endOfBlock = true; - curr[0] = curr[0].substr(0, curr[0].length - 1); - } + var blockStack = [[]]; + var curr = ["", -1, -1]; + var skipRestOfLine = false; + for ( + let idx = 0, lineNo = 1, lineIdx = 0; + idx < src.length; + ++idx, ++lineIdx + ) { + let ch = src.charAt(idx); + if (skipRestOfLine) { + if (ch === "\r" || ch === "\n") { + skipRestOfLine = false; + ++lineNo; + lineIdx = 0; + } + } else { + switch (ch) { + case "\n": + ++lineNo; + lineIdx = 0; + case "\r": + case "\t": + case " ": + if (curr[0].length > 0) { + let endOfBlock = false; + if (curr[0].charAt(curr[0].length - 1) === ";") { + endOfBlock = true; + curr[0] = curr[0].substr(0, curr[0].length - 1); + } - if (curr[0].length > 0) { - blockStack[blockStack.length - 1].push(curr); - } - if ((endOfBlock) && (blockStack.length > 1) && (blockStack[blockStack.length - 1].length > 0)) { - blockStack[blockStack.length - 2].push(blockStack[blockStack.length - 1]); - blockStack.pop(); - } else if (curr[0] in OPEN_BLOCK_KEYWORDS) { - blockStack.push([]); - } + if (curr[0].length > 0) { + blockStack[blockStack.length - 1].push(curr); + } + if ( + endOfBlock && + blockStack.length > 1 && + blockStack[blockStack.length - 1].length > 0 + ) { + blockStack[blockStack.length - 2].push( + blockStack[blockStack.length - 1], + ); + blockStack.pop(); + } else if (curr[0] in OPEN_BLOCK_KEYWORDS) { + blockStack.push([]); + } - curr = ['', -1, -1]; - } - break; - default: - if (curr[0].length === 0) { - if (ch === '#') { - skipRestOfLine = true; - continue; - } else { - curr[1] = lineNo; - curr[2] = lineIdx; - } - } - curr[0] += ch; - break; - } - } - } + curr = ["", -1, -1]; + } + break; + default: + if (curr[0].length === 0) { + if (ch === "#") { + skipRestOfLine = true; + continue; + } else { + curr[1] = lineNo; + curr[2] = lineIdx; + } + } + curr[0] += ch; + break; + } + } + } - if (curr[0].length > 0) { - if (curr[0].charAt(curr[0].length - 1) === ';') - curr[0] = curr[0].substr(0, curr[0].length - 1); - if (curr[0].length > 0) - blockStack[blockStack.length - 1].push(curr); - } - while ((blockStack.length > 1) && (blockStack[blockStack.length - 1].length > 0)) { - blockStack[blockStack.length - 2].push(blockStack[blockStack.length - 1]); - blockStack.pop(); - } - var parsed = blockStack[0]; + if (curr[0].length > 0) { + if (curr[0].charAt(curr[0].length - 1) === ";") + curr[0] = curr[0].substr(0, curr[0].length - 1); + if (curr[0].length > 0) blockStack[blockStack.length - 1].push(curr); + } + while ( + blockStack.length > 1 && + blockStack[blockStack.length - 1].length > 0 + ) { + blockStack[blockStack.length - 2].push(blockStack[blockStack.length - 1]); + blockStack.pop(); + } + var parsed = blockStack[0]; - // Pass 2: parse tree into capabilities, tags, rule sets, and document-level rules. + // Pass 2: parse tree into capabilities, tags, rule sets, and document-level rules. - let baseRuleTree = []; - let macros = {}; - for (let i = 0; i < parsed.length; ++i) { - let keyword = (typeof parsed[i][0] === 'string') ? parsed[i][0].toLowerCase() : null; - if (keyword === 'macro') { - // Define macros + let baseRuleTree = []; + let macros = {}; + for (let i = 0; i < parsed.length; ++i) { + let keyword = + typeof parsed[i][0] === "string" ? parsed[i][0].toLowerCase() : null; + if (keyword === "macro") { + // Define macros - if (((i + 1) >= parsed.length) || (!Array.isArray(parsed[i + 1])) || (parsed[i + 1].length < 1) || (!Array.isArray(parsed[i + 1][0]))) - return [parsed[i][1], parsed[i][2], 'Macro definition is missing name.']; - let macro = parsed[++i]; - let macroName = macro[0][0].toLowerCase(); + if ( + i + 1 >= parsed.length || + !Array.isArray(parsed[i + 1]) || + parsed[i + 1].length < 1 || + !Array.isArray(parsed[i + 1][0]) + ) + return [ + parsed[i][1], + parsed[i][2], + "Macro definition is missing name.", + ]; + let macro = parsed[++i]; + let macroName = macro[0][0].toLowerCase(); - let params = {}; - let parenIdx = macroName.indexOf('('); - if (parenIdx > 0) { - let pns = macroName.substr(parenIdx + 1).split(/[,)]+/); - for (let k = 0; k < pns.length; ++k) { - if (pns[k].length > 0) - params[pns[k]] = k; - } - macroName = macroName.substr(0, parenIdx); - } + let params = {}; + let parenIdx = macroName.indexOf("("); + if (parenIdx > 0) { + let pns = macroName.substr(parenIdx + 1).split(/[,)]+/); + for (let k = 0; k < pns.length; ++k) { + if (pns[k].length > 0) params[pns[k]] = k; + } + macroName = macroName.substr(0, parenIdx); + } - if (!_isValidName(macroName)) - return [macro[0][1], macro[0][2], 'Invalid macro name.']; - if (macroName in RESERVED_WORDS) - return [macro[0][1], macro[0][2], 'Macro name is a reserved word.']; + if (!_isValidName(macroName)) + return [macro[0][1], macro[0][2], "Invalid macro name."]; + if (macroName in RESERVED_WORDS) + return [macro[0][1], macro[0][2], "Macro name is a reserved word."]; - if (macroName in macros) - return [macro[0][1], macro[0][2], 'Multiple definition of macro name.']; + if (macroName in macros) + return [ + macro[0][1], + macro[0][2], + "Multiple definition of macro name.", + ]; - macros[macroName] = { - params: params, - rules: macro.slice(1) - }; - } else if (keyword === 'tag') { - // Define tags + macros[macroName] = { + params: params, + rules: macro.slice(1), + }; + } else if (keyword === "tag") { + // Define tags - if (((i + 1) >= parsed.length) || (!Array.isArray(parsed[i + 1])) || (parsed[i + 1].length < 1) || (!Array.isArray(parsed[i + 1][0]))) - return [parsed[i][1], parsed[i][2], 'Tag definition is missing name.']; - let tag = parsed[++i]; - let tagName = tag[0][0].toLowerCase(); + if ( + i + 1 >= parsed.length || + !Array.isArray(parsed[i + 1]) || + parsed[i + 1].length < 1 || + !Array.isArray(parsed[i + 1][0]) + ) + return [ + parsed[i][1], + parsed[i][2], + "Tag definition is missing name.", + ]; + let tag = parsed[++i]; + let tagName = tag[0][0].toLowerCase(); - if (!_isValidName(tagName)) - return [tag[0][1], tag[0][2], 'Invalid tag name.']; - if (tagName in RESERVED_WORDS) - return [tag[0][1], tag[0][2], 'Tag name is a reserved word.']; + if (!_isValidName(tagName)) + return [tag[0][1], tag[0][2], "Invalid tag name."]; + if (tagName in RESERVED_WORDS) + return [tag[0][1], tag[0][2], "Tag name is a reserved word."]; - if (tagName in tags) - return [tag[0][1], tag[0][2], 'Multiple definition of tag name.']; + if (tagName in tags) + return [tag[0][1], tag[0][2], "Multiple definition of tag name."]; - let flags = {}; - let enums = {}; - let id = -1; - let dfl = null; - for (let k = 1; k < tag.length; ++k) { - let tkeyword = tag[k][0].toLowerCase(); - if (tkeyword === 'id') { - if (id >= 0) - return [tag[k][1], tag[k][2], 'Duplicate tag id definition.']; - if ((k + 1) >= tag.length) - return [tag[k][1], tag[k][2], 'Missing numeric value for ID.']; - id = _parseNum(tag[++k][0]); - if ((id < 0) || (id > 0xffffffff)) - return [tag[k][1], tag[k][2], 'Invalid or out of range tag ID.']; - } else if (tkeyword === 'default') { - if (dfl !== null) - return [tag[k][1], tag[k][2], 'Duplicate tag default directive.']; - if ((k + 1) >= tag.length) - return [tag[k][1], tag[k][2], 'Missing value for default.']; - dfl = tag[++k][0]; - } else if (tkeyword === 'flag') { - if ((k + 2) >= tag.length) - return [tag[k][1], tag[k][2], 'Missing tag flag name or bit index.']; - ++k; - let bits = tag[k][0].split(/[,]+/); - let mask = 0; - for (let j = 0; j < bits.length; ++j) { - let b = bits[j].toLowerCase(); - if (b in flags) { - mask |= flags[b]; - } else { - b = _parseNum(b); - if ((b < 0) || (b > 31)) - return [tag[k][1], tag[k][2], 'Bit index invalid, out of range, or references an undefined flag name.']; - mask |= (1 << b); - } - } - let flagName = tag[++k][0].toLowerCase(); - if (!_isValidName(flagName)) - return [tag[k][1], tag[k][2], 'Invalid or reserved flag name.']; - if (flagName in flags) - return [tag[k][1], tag[k][2], 'Duplicate flag name in tag definition.']; - flags[flagName] = mask; - } else if (tkeyword === 'enum') { - if ((k + 2) >= tag.length) - return [tag[k][1], tag[k][2], 'Missing tag enum name or value.']; - ++k; - let value = _parseNum(tag[k][0]); - if ((value < 0) || (value > 0xffffffff)) - return [tag[k][1], tag[k][2], 'Tag enum value invalid or out of range.']; - let enumName = tag[++k][0].toLowerCase(); - if (!_isValidName(enumName)) - return [tag[k][1], tag[k][2], 'Invalid or reserved tag enum name.']; - if (enumName in enums) - return [tag[k][1], tag[k][2], 'Duplicate enum name in tag definition.']; - enums[enumName] = value; - } else { - return [tag[k][1], tag[k][2], 'Unrecognized keyword in tag definition.']; - } - } - if (id < 0) - return [tag[0][1], tag[0][2], 'Tag definition is missing a numeric ID.']; + let flags = {}; + let enums = {}; + let id = -1; + let dfl = null; + for (let k = 1; k < tag.length; ++k) { + let tkeyword = tag[k][0].toLowerCase(); + if (tkeyword === "id") { + if (id >= 0) + return [tag[k][1], tag[k][2], "Duplicate tag id definition."]; + if (k + 1 >= tag.length) + return [tag[k][1], tag[k][2], "Missing numeric value for ID."]; + id = _parseNum(tag[++k][0]); + if (id < 0 || id > 0xffffffff) + return [tag[k][1], tag[k][2], "Invalid or out of range tag ID."]; + } else if (tkeyword === "default") { + if (dfl !== null) + return [tag[k][1], tag[k][2], "Duplicate tag default directive."]; + if (k + 1 >= tag.length) + return [tag[k][1], tag[k][2], "Missing value for default."]; + dfl = tag[++k][0]; + } else if (tkeyword === "flag") { + if (k + 2 >= tag.length) + return [ + tag[k][1], + tag[k][2], + "Missing tag flag name or bit index.", + ]; + ++k; + let bits = tag[k][0].split(/[,]+/); + let mask = 0; + for (let j = 0; j < bits.length; ++j) { + let b = bits[j].toLowerCase(); + if (b in flags) { + mask |= flags[b]; + } else { + b = _parseNum(b); + if (b < 0 || b > 31) + return [ + tag[k][1], + tag[k][2], + "Bit index invalid, out of range, or references an undefined flag name.", + ]; + mask |= 1 << b; + } + } + let flagName = tag[++k][0].toLowerCase(); + if (!_isValidName(flagName)) + return [tag[k][1], tag[k][2], "Invalid or reserved flag name."]; + if (flagName in flags) + return [ + tag[k][1], + tag[k][2], + "Duplicate flag name in tag definition.", + ]; + flags[flagName] = mask; + } else if (tkeyword === "enum") { + if (k + 2 >= tag.length) + return [tag[k][1], tag[k][2], "Missing tag enum name or value."]; + ++k; + let value = _parseNum(tag[k][0]); + if (value < 0 || value > 0xffffffff) + return [ + tag[k][1], + tag[k][2], + "Tag enum value invalid or out of range.", + ]; + let enumName = tag[++k][0].toLowerCase(); + if (!_isValidName(enumName)) + return [ + tag[k][1], + tag[k][2], + "Invalid or reserved tag enum name.", + ]; + if (enumName in enums) + return [ + tag[k][1], + tag[k][2], + "Duplicate enum name in tag definition.", + ]; + enums[enumName] = value; + } else { + return [ + tag[k][1], + tag[k][2], + "Unrecognized keyword in tag definition.", + ]; + } + } + if (id < 0) + return [ + tag[0][1], + tag[0][2], + "Tag definition is missing a numeric ID.", + ]; - if (typeof dfl === 'string') { - let dfl2 = enums[dfl]; - if (typeof dfl2 === 'number') { - dfl = dfl2; - } else { - dfl2 = flags[dfl]; - if (typeof dfl2 === 'number') { - dfl = dfl2; - } else { - dfl = Math.abs(parseInt(dfl) || 0) & 0xffffffff; - } - } - } else if (typeof dfl === 'number') { - dfl = Math.abs(dfl) & 0xffffffff; - } + if (typeof dfl === "string") { + let dfl2 = enums[dfl]; + if (typeof dfl2 === "number") { + dfl = dfl2; + } else { + dfl2 = flags[dfl]; + if (typeof dfl2 === "number") { + dfl = dfl2; + } else { + dfl = Math.abs(parseInt(dfl) || 0) & 0xffffffff; + } + } + } else if (typeof dfl === "number") { + dfl = Math.abs(dfl) & 0xffffffff; + } - tags[tagName] = { - 'id': id, - 'default': dfl, - 'enums': enums, - 'flags': flags - }; - } else if (keyword === 'cap') { - // Define capabilities + tags[tagName] = { + id: id, + default: dfl, + enums: enums, + flags: flags, + }; + } else if (keyword === "cap") { + // Define capabilities - if (((i + 1) >= parsed.length) || (!Array.isArray(parsed[i + 1])) || (parsed[i + 1].length < 1) || (!Array.isArray(parsed[i + 1][0]))) - return [parsed[i][1], parsed[i][2], 'Capability definition is missing name.']; - let cap = parsed[++i]; - let capName = cap[0][0].toLowerCase(); + if ( + i + 1 >= parsed.length || + !Array.isArray(parsed[i + 1]) || + parsed[i + 1].length < 1 || + !Array.isArray(parsed[i + 1][0]) + ) + return [ + parsed[i][1], + parsed[i][2], + "Capability definition is missing name.", + ]; + let cap = parsed[++i]; + let capName = cap[0][0].toLowerCase(); - if (!_isValidName(capName)) - return [cap[0][1], cap[0][2], 'Invalid capability name.']; - if (capName in RESERVED_WORDS) - return [cap[0][1], cap[0][2], 'Capability name is a reserved word.']; + if (!_isValidName(capName)) + return [cap[0][1], cap[0][2], "Invalid capability name."]; + if (capName in RESERVED_WORDS) + return [cap[0][1], cap[0][2], "Capability name is a reserved word."]; - if (capName in caps) - return [cap[0][1], cap[0][2], 'Multiple definition of capability name.']; + if (capName in caps) + return [ + cap[0][1], + cap[0][2], + "Multiple definition of capability name.", + ]; - let capRules = []; - let id = -1; - let dfl = false; - for (let k = 1; k < cap.length; ++k) { - let dn = (typeof cap[k][0] === 'string') ? cap[k][0].toLowerCase() : null; - if (dn === 'id') { - if (id >= 0) - return [cap[k][1], cap[k][2], 'Duplicate id directive in capability definition.']; - if ((k + 1) >= cap.length) - return [cap[k][1], cap[k][2], 'Missing value for ID.']; - id = _parseNum(cap[++k][0]); - if ((id < 0) || (id > 0xffffffff)) - return [cap[k - 1][1], cap[k - 1][2], 'Invalid or out of range capability ID.']; - for (let cn in caps) { - if (caps[cn].id === id) - return [cap[k - 1][1], cap[k - 1][2], 'Duplicate capability ID.']; - } - } else if (dn === 'default') { - dfl = true; - } else { - capRules.push(cap[k]); - } - } - if (id < 0) - return [cap[0][1], cap[0][2], 'Capability definition is missing a numeric ID.']; + let capRules = []; + let id = -1; + let dfl = false; + for (let k = 1; k < cap.length; ++k) { + let dn = + typeof cap[k][0] === "string" ? cap[k][0].toLowerCase() : null; + if (dn === "id") { + if (id >= 0) + return [ + cap[k][1], + cap[k][2], + "Duplicate id directive in capability definition.", + ]; + if (k + 1 >= cap.length) + return [cap[k][1], cap[k][2], "Missing value for ID."]; + id = _parseNum(cap[++k][0]); + if (id < 0 || id > 0xffffffff) + return [ + cap[k - 1][1], + cap[k - 1][2], + "Invalid or out of range capability ID.", + ]; + for (let cn in caps) { + if (caps[cn].id === id) + return [ + cap[k - 1][1], + cap[k - 1][2], + "Duplicate capability ID.", + ]; + } + } else if (dn === "default") { + dfl = true; + } else { + capRules.push(cap[k]); + } + } + if (id < 0) + return [ + cap[0][1], + cap[0][2], + "Capability definition is missing a numeric ID.", + ]; - caps[capName] = { - 'id': id, - 'default': dfl, - 'rules': capRules - }; - } else { - baseRuleTree.push(parsed[i]); - } - } + caps[capName] = { + id: id, + default: dfl, + rules: capRules, + }; + } else { + baseRuleTree.push(parsed[i]); + } + } - // Pass 3: render low-level ZeroTier rules arrays for capabilities and base. + // Pass 3: render low-level ZeroTier rules arrays for capabilities and base. - for (let capName in caps) { - let r = []; - let err = _renderActions(caps[capName].rules, r, macros, caps, tags, {}); - if (err !== null) - return err; - caps[capName].rules = r; - } + for (let capName in caps) { + let r = []; + let err = _renderActions(caps[capName].rules, r, macros, caps, tags, {}); + if (err !== null) return err; + caps[capName].rules = r; + } - let err = _renderActions(baseRuleTree, rules, macros, caps, tags, {}); - if (err !== null) - return err; + let err = _renderActions(baseRuleTree, rules, macros, caps, tags, {}); + if (err !== null) return err; - return null; - } catch (e) { - console.log(e.stack); - return [0, 0, 'Unexpected exception: ' + e.toString()]; - } + return null; + } catch (e) { + console.log(e.stack); + return [0, 0, "Unexpected exception: " + e.toString()]; + } } exports.compile = compile; diff --git a/rustybits/smeeclient/src/ext.rs b/rustybits/smeeclient/src/ext.rs index b5517d866..9db10a375 100644 --- a/rustybits/smeeclient/src/ext.rs +++ b/rustybits/smeeclient/src/ext.rs @@ -1,13 +1,9 @@ -/* - * Copyright (c)2021 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ #![allow(clippy::uninlined_format_args, clippy::missing_safety_doc)] diff --git a/rustybits/smeeclient/src/lib.rs b/rustybits/smeeclient/src/lib.rs index 649bb0632..94bf5e8ab 100644 --- a/rustybits/smeeclient/src/lib.rs +++ b/rustybits/smeeclient/src/lib.rs @@ -1,13 +1,9 @@ -/* - * Copyright (c)2023 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ pub mod ext; diff --git a/rustybits/zeroidc/src/error.rs b/rustybits/zeroidc/src/error.rs index 4495254d1..2dfa79c52 100644 --- a/rustybits/zeroidc/src/error.rs +++ b/rustybits/zeroidc/src/error.rs @@ -1,13 +1,9 @@ -/* - * Copyright (c)2022 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ use thiserror::Error; diff --git a/rustybits/zeroidc/src/ext.rs b/rustybits/zeroidc/src/ext.rs index f0ba8b4b4..8d86cda50 100644 --- a/rustybits/zeroidc/src/ext.rs +++ b/rustybits/zeroidc/src/ext.rs @@ -1,13 +1,9 @@ -/* - * Copyright (c)2021 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ use std::ffi::{CStr, CString}; diff --git a/rustybits/zeroidc/src/lib.rs b/rustybits/zeroidc/src/lib.rs index 493d90d7e..cb2e4d23f 100644 --- a/rustybits/zeroidc/src/lib.rs +++ b/rustybits/zeroidc/src/lib.rs @@ -1,13 +1,9 @@ -/* - * Copyright (c)2021 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ #![allow( diff --git a/service/OneService.cpp b/service/OneService.cpp index 41aa33838..eb76cbe35 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include #include diff --git a/service/OneService.hpp b/service/OneService.hpp index f63c70b26..f4ab72996 100644 --- a/service/OneService.hpp +++ b/service/OneService.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_ONESERVICE_HPP #define ZT_ONESERVICE_HPP diff --git a/service/SoftwareUpdater.cpp b/service/SoftwareUpdater.cpp index 978370f68..d9d47f84a 100644 --- a/service/SoftwareUpdater.cpp +++ b/service/SoftwareUpdater.cpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #include "../node/Constants.hpp" #include "../version.h" diff --git a/service/SoftwareUpdater.hpp b/service/SoftwareUpdater.hpp index 18539af44..1c39bde3a 100644 --- a/service/SoftwareUpdater.hpp +++ b/service/SoftwareUpdater.hpp @@ -1,15 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #ifndef ZT_SOFTWAREUPDATER_HPP #define ZT_SOFTWAREUPDATER_HPP diff --git a/tcp-proxy/tcp-proxy.cpp b/tcp-proxy/tcp-proxy.cpp index f763306d6..c6711cb4a 100644 --- a/tcp-proxy/tcp-proxy.cpp +++ b/tcp-proxy/tcp-proxy.cpp @@ -1,19 +1,9 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ // HACK! Will eventually use epoll() or something in Phy<> instead of select(). diff --git a/windows/ZeroTierOne/ZeroTierOneService.cpp b/windows/ZeroTierOne/ZeroTierOneService.cpp index 033a9d219..8af4eb878 100644 --- a/windows/ZeroTierOne/ZeroTierOneService.cpp +++ b/windows/ZeroTierOne/ZeroTierOneService.cpp @@ -1,50 +1,42 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #pragma region Includes #if defined(_WIN32) || defined(_WIN64) -#include -#include -#include -#include - #include "ZeroTierOneService.h" -#include "../../version.h" #include "../../include/ZeroTierOne.h" - #include "../../node/Constants.hpp" #include "../../node/Utils.hpp" #include "../../osdep/OSUtils.hpp" #include "../../service/OneService.hpp" +#include "../../version.h" -#pragma endregion // Includes +#include +#include +#include +#include + +#pragma endregion // Includes #ifdef ZT_DEBUG_SERVICE -FILE *SVCDBGfile = (FILE *)0; +FILE* SVCDBGfile = (FILE*)0; ZeroTier::Mutex SVCDBGfile_m; #endif -ZeroTierOneService::ZeroTierOneService() : - CServiceBase(ZT_SERVICE_NAME,TRUE,TRUE,FALSE), - _service((ZeroTier::OneService *)0) +ZeroTierOneService::ZeroTierOneService() : CServiceBase(ZT_SERVICE_NAME, TRUE, TRUE, FALSE), _service((ZeroTier::OneService*)0) { #ifdef ZT_DEBUG_SERVICE SVCDBGfile_m.lock(); - if (!SVCDBGfile) - SVCDBGfile = fopen(ZT_DEBUG_SERVICE,"a"); + if (! SVCDBGfile) + SVCDBGfile = fopen(ZT_DEBUG_SERVICE, "a"); SVCDBGfile_m.unlock(); #endif @@ -59,14 +51,13 @@ ZeroTierOneService::~ZeroTierOneService(void) SVCDBGfile_m.lock(); if (SVCDBGfile) { fclose(SVCDBGfile); - SVCDBGfile = (FILE *)0; + SVCDBGfile = (FILE*)0; } SVCDBGfile_m.unlock(); #endif } -void ZeroTierOneService::threadMain() - throw() +void ZeroTierOneService::threadMain() throw() { ZT_SVCDBG("ZeroTierOneService::threadMain()\r\n"); @@ -75,38 +66,41 @@ restart_node: { ZeroTier::Mutex::Lock _l(_lock); delete _service; - _service = (ZeroTier::OneService *)0; // in case newInstance() fails + _service = (ZeroTier::OneService*)0; // in case newInstance() fails _service = ZeroTier::OneService::newInstance(_path.c_str(), ZT_DEFAULT_PORT); } - switch(_service->run()) { + switch (_service->run()) { case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR: { std::string err("ZeroTier One encountered an unrecoverable error: "); err.append(_service->fatalErrorMessage()); err.append(" (restarting in 5 seconds)"); - WriteEventLogEntry(const_cast (err.c_str()),EVENTLOG_ERROR_TYPE); + WriteEventLogEntry(const_cast(err.c_str()), EVENTLOG_ERROR_TYPE); Sleep(5000); - } goto restart_node; + } + goto restart_node; case ZeroTier::OneService::ONE_IDENTITY_COLLISION: { std::string homeDir(ZeroTier::OneService::platformDefaultHomePath()); delete _service; - _service = (ZeroTier::OneService *)0; + _service = (ZeroTier::OneService*)0; std::string oldid; - ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid); + ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(), oldid); if (oldid.length()) { - ZeroTier::OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid); + ZeroTier::OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(), oldid); ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str()); ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str()); } - } goto restart_node; + } + goto restart_node; - default: // normal termination + default: // normal termination break; } - } catch ( ... ) { + } + catch (...) { // sanity check, shouldn't happen since Node::run() should catch all its own errors // could also happen if we're out of memory though! - WriteEventLogEntry("unexpected exception (out of memory?) (trying again in 5 seconds)",EVENTLOG_ERROR_TYPE); + WriteEventLogEntry("unexpected exception (out of memory?) (trying again in 5 seconds)", EVENTLOG_ERROR_TYPE); Sleep(5000); goto restart_node; } @@ -114,23 +108,25 @@ restart_node: { ZeroTier::Mutex::Lock _l(_lock); delete _service; - _service = (ZeroTier::OneService *)0; + _service = (ZeroTier::OneService*)0; } } -void ZeroTierOneService::OnStart(DWORD dwArgc, PSTR *lpszArgv) +void ZeroTierOneService::OnStart(DWORD dwArgc, PSTR* lpszArgv) { ZT_SVCDBG("ZeroTierOneService::OnStart()\r\n"); - if ((dwArgc > 1)&&(lpszArgv[1])&&(strlen(lpszArgv[1]) > 0)) { + if ((dwArgc > 1) && (lpszArgv[1]) && (strlen(lpszArgv[1]) > 0)) { this->_path = lpszArgv[1]; - } else { + } + else { this->_path = ZeroTier::OneService::platformDefaultHomePath(); } try { _thread = ZeroTier::Thread::start(this); - } catch ( ... ) { + } + catch (...) { throw (DWORD)ERROR_EXCEPTION_IN_SERVICE; } } @@ -140,7 +136,7 @@ void ZeroTierOneService::OnStop() ZT_SVCDBG("ZeroTierOneService::OnStop()\r\n"); _lock.lock(); - ZeroTier::OneService *s = _service; + ZeroTier::OneService* s = _service; _lock.unlock(); if (s) { diff --git a/windows/ZeroTierOne/ZeroTierOneService.h b/windows/ZeroTierOne/ZeroTierOneService.h index 8fe20996a..d6ccbeefe 100644 --- a/windows/ZeroTierOne/ZeroTierOneService.h +++ b/windows/ZeroTierOne/ZeroTierOneService.h @@ -1,69 +1,68 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. + * (c) ZeroTier, Inc. + * https://www.zerotier.com/ */ -/****/ #pragma once #if defined(_WIN32) || defined(_WIN64) -#include - -#include "ServiceBase.h" - -#include - #include "../../node/Mutex.hpp" #include "../../osdep/Thread.hpp" #include "../../service/OneService.hpp" +#include "ServiceBase.h" + +#include +#include // Uncomment to make debugging Windows services suck slightly less hard. -//#define ZT_DEBUG_SERVICE "C:\\ZeroTierOneServiceDebugLog.txt" +// #define ZT_DEBUG_SERVICE "C:\\ZeroTierOneServiceDebugLog.txt" #ifdef ZT_DEBUG_SERVICE -extern FILE *SVCDBGfile; +extern FILE* SVCDBGfile; extern ZeroTier::Mutex SVCDBGfile_m; -#define ZT_SVCDBG(f,...) { SVCDBGfile_m.lock(); fprintf(SVCDBGfile,f,##__VA_ARGS__); fflush(SVCDBGfile); SVCDBGfile_m.unlock(); } +#define ZT_SVCDBG(f, ...) \ + { \ + SVCDBGfile_m.lock(); \ + fprintf(SVCDBGfile, f, ##__VA_ARGS__); \ + fflush(SVCDBGfile); \ + SVCDBGfile_m.unlock(); \ + } #else -#define ZT_SVCDBG(f,...) {} +#define ZT_SVCDBG(f, ...) \ + { \ + } #endif -#define ZT_SERVICE_NAME "ZeroTierOneService" +#define ZT_SERVICE_NAME "ZeroTierOneService" #define ZT_SERVICE_DISPLAY_NAME "ZeroTier One" -#define ZT_SERVICE_START_TYPE SERVICE_AUTO_START +#define ZT_SERVICE_START_TYPE SERVICE_AUTO_START #define ZT_SERVICE_DEPENDENCIES "" -//#define ZT_SERVICE_ACCOUNT "NT AUTHORITY\\LocalService" -#define ZT_SERVICE_ACCOUNT NULL +// #define ZT_SERVICE_ACCOUNT "NT AUTHORITY\\LocalService" +#define ZT_SERVICE_ACCOUNT NULL #define ZT_SERVICE_PASSWORD NULL -class ZeroTierOneService : public CServiceBase -{ -public: - ZeroTierOneService(); - virtual ~ZeroTierOneService(void); +class ZeroTierOneService : public CServiceBase { + public: + ZeroTierOneService(); + virtual ~ZeroTierOneService(void); /** * Thread main method; do not call elsewhere */ - void threadMain() - throw(); + void threadMain() throw(); -protected: - virtual void OnStart(DWORD dwArgc, PSTR *pszArgv); + protected: + virtual void OnStart(DWORD dwArgc, PSTR* pszArgv); virtual void OnStop(); virtual void OnShutdown(); -private: + private: std::string _path; - ZeroTier::OneService *volatile _service; + ZeroTier::OneService* volatile _service; ZeroTier::Mutex _lock; ZeroTier::Thread _thread; };