mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2026-09-22 15:29:03 -07:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45e3223591 | ||
|
|
a4e021e04e |
No files matched your search
@@ -10,3 +10,30 @@ file(GLOB core_src_glob ${PROJ_DIR}/node/*.cpp)
|
||||
add_library(zerotiercore STATIC ${core_src_glob})
|
||||
|
||||
target_compile_options(zerotiercore PRIVATE ${ZT_DEFS})
|
||||
|
||||
# Build the Rust embedding tool
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/ci/scripts/embed_json
|
||||
COMMAND rustc ${CMAKE_CURRENT_SOURCE_DIR}/ci/scripts/embed_json.rs -o ${CMAKE_CURRENT_SOURCE_DIR}/ci/scripts/embed_json
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ci/scripts/embed_json.rs
|
||||
COMMENT "Building Rust JSON embedding tool"
|
||||
)
|
||||
|
||||
# Embed diagnostic_schema.json as a C string
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/diagnostic/diagnostic_schema_embed.c
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/diagnostic
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ci/scripts/embed_json ${CMAKE_CURRENT_SOURCE_DIR}/../diagnostic/diagnostic_schema.json ${CMAKE_CURRENT_SOURCE_DIR}/diagnostic/diagnostic_schema_embed.c
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../diagnostic/diagnostic_schema.json ${CMAKE_CURRENT_SOURCE_DIR}/ci/scripts/embed_json
|
||||
COMMENT "Embedding diagnostic_schema.json as C string"
|
||||
)
|
||||
|
||||
set(DIAGNOSTIC_SCHEMA_EMBED_SRC
|
||||
diagnostic/diagnostic_schema_embed.c
|
||||
diagnostic/diagnostic_schema_embed.h
|
||||
)
|
||||
|
||||
# Add the generated source to your main target (replace <your_target> with actual target name)
|
||||
target_sources(zerotiercore PRIVATE
|
||||
${DIAGNOSTIC_SCHEMA_EMBED_SRC}
|
||||
)
|
||||
@@ -195,3 +195,12 @@ Then visit [http://localhost:9993/app/app1/](http://localhost:9993/app/app1/) an
|
||||
|
||||
Requests to paths don't exist return the app root index.html, as is customary for SPAs.
|
||||
If you want, you can write some javascript that talks to the service or controller [api](https://docs.zerotier.com/service/v1).
|
||||
|
||||
## Diagnostic Output Documentation
|
||||
|
||||
The diagnostic output (used by `zerotier-cli diagnostic` and `zerotier-cli dump -j`) is documented in the [diagnostic/](diagnostic/) directory:
|
||||
|
||||
- [diagnostic_output.md](diagnostic/diagnostic_output.md): Field descriptions, example output, and integration notes
|
||||
- [diagnostic_schema.json](diagnostic/diagnostic_schema.json): JSON Schema for validation and integration
|
||||
|
||||
See these files for details on the output format and how to integrate with MCP, AI, or other automated systems.
|
||||
@@ -0,0 +1,30 @@
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print(f"Usage: {sys.argv[0]} <input.json> <output.c>")
|
||||
sys.exit(1)
|
||||
|
||||
input_path = sys.argv[1]
|
||||
output_path = sys.argv[2]
|
||||
|
||||
with open(input_path, 'r', encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
|
||||
# Optionally, minify JSON to save space
|
||||
try:
|
||||
minified = json.dumps(json.loads(data), separators=(",", ":"))
|
||||
except Exception:
|
||||
minified = data
|
||||
|
||||
c_array = ','.join(str(ord(c)) for c in minified)
|
||||
|
||||
header = "#include \"diagnostic_schema_embed.h\"\n\n"
|
||||
array_decl = f"const char ZT_DIAGNOSTIC_SCHEMA_JSON[] = \"{minified.replace('\\', '\\\\').replace('"', '\\"').replace(chr(10), '\\n').replace(chr(13), '')}\";\n"
|
||||
len_decl = f"const unsigned int ZT_DIAGNOSTIC_SCHEMA_JSON_LEN = sizeof(ZT_DIAGNOSTIC_SCHEMA_JSON) - 1;\n"
|
||||
|
||||
with open(output_path, 'w', encoding='utf-8') as out:
|
||||
out.write(header)
|
||||
out.write(array_decl)
|
||||
out.write(len_decl)
|
||||
@@ -0,0 +1,39 @@
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() != 3 {
|
||||
eprintln!("Usage: {} <input.json> <output.c>", args[0]);
|
||||
std::process::exit(1);
|
||||
}
|
||||
let input_path = &args[1];
|
||||
let output_path = &args[2];
|
||||
|
||||
let data = fs::read_to_string(input_path).expect("Failed to read input file");
|
||||
// Minify JSON
|
||||
let minified = match serde_json::from_str::<serde_json::Value>(&data) {
|
||||
Ok(json) => serde_json::to_string(&json).unwrap_or(data.clone()),
|
||||
Err(_) => data.clone(),
|
||||
};
|
||||
|
||||
let escaped = minified
|
||||
.replace('\\', "\\\\")
|
||||
.replace('"', "\\\"")
|
||||
.replace('\n', "\\n")
|
||||
.replace('\r', "");
|
||||
|
||||
let header = "#include \"diagnostic_schema_embed.h\"\n\n";
|
||||
let array_decl = format!(
|
||||
"const char ZT_DIAGNOSTIC_SCHEMA_JSON[] = \"{}\";\n",
|
||||
escaped
|
||||
);
|
||||
let len_decl = "const unsigned int ZT_DIAGNOSTIC_SCHEMA_JSON_LEN = sizeof(ZT_DIAGNOSTIC_SCHEMA_JSON) - 1;\n";
|
||||
|
||||
let mut out = fs::File::create(output_path).expect("Failed to create output file");
|
||||
out.write_all(header.as_bytes()).unwrap();
|
||||
out.write_all(array_decl.as_bytes()).unwrap();
|
||||
out.write_all(len_decl.as_bytes()).unwrap();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "diagnostic_schema_embed.h"
|
||||
|
||||
// This file will be auto-generated at build time from diagnostic/diagnostic_schema.json
|
||||
const char ZT_DIAGNOSTIC_SCHEMA_JSON[] = "PLACEHOLDER: schema will be embedded here";
|
||||
const unsigned int ZT_DIAGNOSTIC_SCHEMA_JSON_LEN = sizeof(ZT_DIAGNOSTIC_SCHEMA_JSON) - 1;
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// Embedded diagnostic_schema.json
|
||||
extern const char ZT_DIAGNOSTIC_SCHEMA_JSON[];
|
||||
extern const unsigned int ZT_DIAGNOSTIC_SCHEMA_JSON_LEN;
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
#include <sstream>
|
||||
void dumpInterfaces(std::stringstream& dump);
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "diagnostic/dump_interfaces.hpp"
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <SystemConfiguration/SystemConfiguration.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
|
||||
void dumpInterfaces(std::stringstream& dump) {
|
||||
CFArrayRef interfaces = SCNetworkInterfaceCopyAll();
|
||||
CFIndex size = CFArrayGetCount(interfaces);
|
||||
for(CFIndex i = 0; i < size; ++i) {
|
||||
SCNetworkInterfaceRef iface = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(interfaces, i);
|
||||
dump << "Interface " << i << "\n-----------\n";
|
||||
CFStringRef tmp = SCNetworkInterfaceGetBSDName(iface);
|
||||
char stringBuffer[512] = {};
|
||||
CFStringGetCString(tmp,stringBuffer, sizeof(stringBuffer), kCFStringEncodingUTF8);
|
||||
dump << "Name: " << stringBuffer << "\n";
|
||||
std::string ifName(stringBuffer);
|
||||
int mtuCur, mtuMin, mtuMax;
|
||||
SCNetworkInterfaceCopyMTU(iface, &mtuCur, &mtuMin, &mtuMax);
|
||||
dump << "MTU: " << mtuCur << "\n";
|
||||
tmp = SCNetworkInterfaceGetHardwareAddressString(iface);
|
||||
CFStringGetCString(tmp, stringBuffer, sizeof(stringBuffer), kCFStringEncodingUTF8);
|
||||
dump << "MAC: " << stringBuffer << "\n";
|
||||
tmp = SCNetworkInterfaceGetInterfaceType(iface);
|
||||
CFStringGetCString(tmp, stringBuffer, sizeof(stringBuffer), kCFStringEncodingUTF8);
|
||||
dump << "Type: " << stringBuffer << "\n";
|
||||
dump << "Addresses:" << "\n";
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
void *addr;
|
||||
getifaddrs(&ifap);
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if (strcmp(ifName.c_str(), ifa->ifa_name) == 0) {
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
struct sockaddr_in *ipv4 = (struct sockaddr_in*)ifa->ifa_addr;
|
||||
addr = &ipv4->sin_addr;
|
||||
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)ifa->ifa_addr;
|
||||
addr = &ipv6->sin6_addr;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
inet_ntop(ifa->ifa_addr->sa_family, addr, stringBuffer, sizeof(stringBuffer));
|
||||
dump << stringBuffer << "\n";
|
||||
}
|
||||
}
|
||||
dump << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "diagnostic/dump_interfaces.hpp"
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
void dumpInterfaces(std::stringstream& dump) {
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
if (getifaddrs(&ifap) != 0) {
|
||||
dump << "ERROR: getifaddrs failed\n";
|
||||
return;
|
||||
}
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if (!ifa->ifa_addr) continue;
|
||||
dump << "Interface: " << ifa->ifa_name << "\n";
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock >= 0) {
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFMTU, &ifr) == 0) {
|
||||
dump << "MTU: " << ifr.ifr_mtu << "\n";
|
||||
}
|
||||
if (ifa->ifa_addr->sa_family == AF_LINK) {
|
||||
struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifa->ifa_addr;
|
||||
unsigned char* mac = (unsigned char*)LLADDR(sdl);
|
||||
char macStr[32];
|
||||
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
dump << "MAC: " << macStr << "\n";
|
||||
}
|
||||
close(sock);
|
||||
}
|
||||
dump << "Addresses:\n";
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
char addr[INET_ADDRSTRLEN];
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)ifa->ifa_addr;
|
||||
inet_ntop(AF_INET, &(sa->sin_addr), addr, INET_ADDRSTRLEN);
|
||||
dump << addr << "\n";
|
||||
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_in6* sa6 = (struct sockaddr_in6*)ifa->ifa_addr;
|
||||
inet_ntop(AF_INET6, &(sa6->sin6_addr), addr, INET6_ADDRSTRLEN);
|
||||
dump << addr << "\n";
|
||||
}
|
||||
dump << "\n";
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "diagnostic/dump_interfaces.hpp"
|
||||
#include <sys/types.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sstream>
|
||||
|
||||
void dumpInterfaces(std::stringstream& dump) {
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
struct ifconf ifc;
|
||||
char buf[1024];
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
ioctl(sock, SIOCGIFCONF, &ifc);
|
||||
struct ifreq *it = ifc.ifc_req;
|
||||
const struct ifreq * const end = it + (ifc.ifc_len / sizeof(struct ifreq));
|
||||
for(; it != end; ++it) {
|
||||
struct ifreq ifr;
|
||||
strcpy(ifr.ifr_name, it->ifr_name);
|
||||
if(ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
|
||||
if (!(ifr.ifr_flags & IFF_LOOPBACK)) { // skip loopback
|
||||
dump << "Interface: " << ifr.ifr_name << "\n";
|
||||
if (ioctl(sock, SIOCGIFMTU, &ifr) == 0) {
|
||||
dump << "MTU: " << ifr.ifr_mtu << "\n";
|
||||
}
|
||||
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
|
||||
unsigned char mac_addr[6];
|
||||
memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6);
|
||||
char macStr[18];
|
||||
sprintf(macStr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr[0],
|
||||
mac_addr[1],
|
||||
mac_addr[2],
|
||||
mac_addr[3],
|
||||
mac_addr[4],
|
||||
mac_addr[5]);
|
||||
dump << "MAC: " << macStr << "\n";
|
||||
}
|
||||
dump << "Addresses:" << "\n";
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
void *addr;
|
||||
getifaddrs(&ifap);
|
||||
for(ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if(strcmp(ifr.ifr_name, ifa->ifa_name) == 0 && ifa->ifa_addr != NULL) {
|
||||
char stringBuffer[128];
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
struct sockaddr_in *ipv4 = (struct sockaddr_in*)ifa->ifa_addr;
|
||||
addr = &ipv4->sin_addr;
|
||||
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)ifa->ifa_addr;
|
||||
addr = &ipv6->sin6_addr;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
inet_ntop(ifa->ifa_addr->sa_family, addr, stringBuffer, sizeof(stringBuffer));
|
||||
dump << stringBuffer << "\n";
|
||||
}
|
||||
}
|
||||
dump << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "diagnostic/dump_interfaces.hpp"
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
void dumpInterfaces(std::stringstream& dump) {
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
if (getifaddrs(&ifap) != 0) {
|
||||
dump << "ERROR: getifaddrs failed\n";
|
||||
return;
|
||||
}
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if (!ifa->ifa_addr) continue;
|
||||
dump << "Interface: " << ifa->ifa_name << "\n";
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock >= 0) {
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFMTU, &ifr) == 0) {
|
||||
dump << "MTU: " << ifr.ifr_mtu << "\n";
|
||||
}
|
||||
if (ifa->ifa_addr->sa_family == AF_LINK) {
|
||||
struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifa->ifa_addr;
|
||||
unsigned char* mac = (unsigned char*)LLADDR(sdl);
|
||||
char macStr[32];
|
||||
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
dump << "MAC: " << macStr << "\n";
|
||||
}
|
||||
close(sock);
|
||||
}
|
||||
dump << "Addresses:\n";
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
char addr[INET_ADDRSTRLEN];
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)ifa->ifa_addr;
|
||||
inet_ntop(AF_INET, &(sa->sin_addr), addr, INET_ADDRSTRLEN);
|
||||
dump << addr << "\n";
|
||||
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_in6* sa6 = (struct sockaddr_in6*)ifa->ifa_addr;
|
||||
inet_ntop(AF_INET6, &(sa6->sin6_addr), addr, INET6_ADDRSTRLEN);
|
||||
dump << addr << "\n";
|
||||
}
|
||||
dump << "\n";
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "diagnostic/dump_interfaces.hpp"
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <string>
|
||||
|
||||
void dumpInterfaces(std::stringstream& dump) {
|
||||
ULONG buffLen = 16384;
|
||||
PIP_ADAPTER_ADDRESSES addresses;
|
||||
ULONG ret = 0;
|
||||
do {
|
||||
addresses = (PIP_ADAPTER_ADDRESSES)malloc(buffLen);
|
||||
ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &buffLen);
|
||||
if (ret == ERROR_BUFFER_OVERFLOW) {
|
||||
free(addresses);
|
||||
addresses = NULL;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while (ret == ERROR_BUFFER_OVERFLOW);
|
||||
int i = 0;
|
||||
if (ret == NO_ERROR) {
|
||||
PIP_ADAPTER_ADDRESSES curAddr = addresses;
|
||||
while (curAddr) {
|
||||
dump << "Interface " << i << "\n-----------\n";
|
||||
dump << "Name: " << curAddr->AdapterName << "\n";
|
||||
dump << "MTU: " << curAddr->Mtu << "\n";
|
||||
char macBuffer[64] = {};
|
||||
sprintf(macBuffer, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
curAddr->PhysicalAddress[0],
|
||||
curAddr->PhysicalAddress[1],
|
||||
curAddr->PhysicalAddress[2],
|
||||
curAddr->PhysicalAddress[3],
|
||||
curAddr->PhysicalAddress[4],
|
||||
curAddr->PhysicalAddress[5]);
|
||||
dump << "MAC: " << macBuffer << "\n";
|
||||
dump << "Type: " << curAddr->IfType << "\n";
|
||||
dump << "Addresses:" << "\n";
|
||||
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
|
||||
pUnicast = curAddr->FirstUnicastAddress;
|
||||
if (pUnicast) {
|
||||
for (int j = 0; pUnicast != NULL; ++j) {
|
||||
char buf[128] = {};
|
||||
DWORD bufLen = 128;
|
||||
LPSOCKADDR a = pUnicast->Address.lpSockaddr;
|
||||
WSAAddressToStringA(
|
||||
pUnicast->Address.lpSockaddr,
|
||||
pUnicast->Address.iSockaddrLength,
|
||||
NULL,
|
||||
buf,
|
||||
&bufLen
|
||||
);
|
||||
dump << buf << "\n";
|
||||
pUnicast = pUnicast->Next;
|
||||
}
|
||||
}
|
||||
dump << "\n";
|
||||
curAddr = curAddr->Next;
|
||||
}
|
||||
}
|
||||
if (addresses) {
|
||||
free(addresses);
|
||||
addresses = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "diagnostic/dump_sections.hpp"
|
||||
#include "node/InetAddress.hpp"
|
||||
#include "osdep/OSUtils.hpp"
|
||||
#include "osdep/Http.hpp"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
void dumpStatus(std::stringstream& dump, const ZeroTier::InetAddress& addr, std::map<std::string,std::string>& requestHeaders) {
|
||||
dump << "status" << ZT_EOL_S << "------" << ZT_EOL_S;
|
||||
std::map<std::string, std::string> responseHeaders;
|
||||
std::string responseBody;
|
||||
unsigned int scode = ZeroTier::Http::GET(1024 * 1024 * 16,60000,(const struct sockaddr *)&addr,"/status",requestHeaders,responseHeaders,responseBody);
|
||||
if (scode != 200) {
|
||||
dump << responseBody << ZT_EOL_S;
|
||||
return;
|
||||
}
|
||||
dump << responseBody << ZT_EOL_S;
|
||||
}
|
||||
|
||||
void dumpNetworks(std::stringstream& dump, const ZeroTier::InetAddress& addr, std::map<std::string,std::string>& requestHeaders) {
|
||||
dump << ZT_EOL_S << "networks" << ZT_EOL_S << "--------" << ZT_EOL_S;
|
||||
std::map<std::string, std::string> responseHeaders;
|
||||
std::string responseBody;
|
||||
unsigned int scode = ZeroTier::Http::GET(1024 * 1024 * 16,60000,(const struct sockaddr *)&addr,"/network",requestHeaders,responseHeaders,responseBody);
|
||||
if (scode != 200) {
|
||||
dump << responseBody << ZT_EOL_S;
|
||||
return;
|
||||
}
|
||||
dump << responseBody << ZT_EOL_S;
|
||||
}
|
||||
|
||||
void dumpPeers(std::stringstream& dump, const ZeroTier::InetAddress& addr, std::map<std::string,std::string>& requestHeaders) {
|
||||
dump << ZT_EOL_S << "peers" << ZT_EOL_S << "-----" << ZT_EOL_S;
|
||||
std::map<std::string, std::string> responseHeaders;
|
||||
std::string responseBody;
|
||||
unsigned int scode = ZeroTier::Http::GET(1024 * 1024 * 16,60000,(const struct sockaddr *)&addr,"/peer",requestHeaders,responseHeaders,responseBody);
|
||||
if (scode != 200) {
|
||||
dump << responseBody << ZT_EOL_S;
|
||||
return;
|
||||
}
|
||||
dump << responseBody << ZT_EOL_S;
|
||||
}
|
||||
|
||||
void dumpLocalConf(std::stringstream& dump, const std::string& homeDir) {
|
||||
dump << ZT_EOL_S << "local.conf" << ZT_EOL_S << "----------" << ZT_EOL_S;
|
||||
std::string localConf;
|
||||
ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "local.conf").c_str(), localConf);
|
||||
if (localConf.empty()) {
|
||||
dump << "None Present" << ZT_EOL_S;
|
||||
}
|
||||
else {
|
||||
dump << localConf << ZT_EOL_S;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "node/InetAddress.hpp"
|
||||
|
||||
void dumpStatus(std::stringstream& dump, const ZeroTier::InetAddress& addr, std::map<std::string,std::string>& requestHeaders);
|
||||
void dumpNetworks(std::stringstream& dump, const ZeroTier::InetAddress& addr, std::map<std::string,std::string>& requestHeaders);
|
||||
void dumpPeers(std::stringstream& dump, const ZeroTier::InetAddress& addr, std::map<std::string,std::string>& requestHeaders);
|
||||
void dumpLocalConf(std::stringstream& dump, const std::string& homeDir);
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "diagnostic/node_state_interfaces_apple.hpp"
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <SystemConfiguration/SystemConfiguration.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
void addNodeStateInterfacesJson(nlohmann::json& j) {
|
||||
try {
|
||||
std::vector<nlohmann::json> interfaces_json;
|
||||
CFArrayRef interfaces = SCNetworkInterfaceCopyAll();
|
||||
CFIndex size = CFArrayGetCount(interfaces);
|
||||
for(CFIndex i = 0; i < size; ++i) {
|
||||
SCNetworkInterfaceRef iface = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(interfaces, i);
|
||||
char stringBuffer[512] = {};
|
||||
CFStringRef tmp = SCNetworkInterfaceGetBSDName(iface);
|
||||
CFStringGetCString(tmp,stringBuffer, sizeof(stringBuffer), kCFStringEncodingUTF8);
|
||||
std::string ifName(stringBuffer);
|
||||
int mtuCur, mtuMin, mtuMax;
|
||||
SCNetworkInterfaceCopyMTU(iface, &mtuCur, &mtuMin, &mtuMax);
|
||||
nlohmann::json iface_json;
|
||||
iface_json["name"] = ifName;
|
||||
iface_json["mtu"] = mtuCur;
|
||||
tmp = SCNetworkInterfaceGetHardwareAddressString(iface);
|
||||
CFStringGetCString(tmp, stringBuffer, sizeof(stringBuffer), kCFStringEncodingUTF8);
|
||||
iface_json["mac"] = stringBuffer;
|
||||
tmp = SCNetworkInterfaceGetInterfaceType(iface);
|
||||
CFStringGetCString(tmp, stringBuffer, sizeof(stringBuffer), kCFStringEncodingUTF8);
|
||||
iface_json["type"] = stringBuffer;
|
||||
std::vector<std::string> addresses;
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
void *addr;
|
||||
getifaddrs(&ifap);
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if (strcmp(ifName.c_str(), ifa->ifa_name) == 0) {
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
struct sockaddr_in *ipv4 = (struct sockaddr_in*)ifa->ifa_addr;
|
||||
addr = &ipv4->sin_addr;
|
||||
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)ifa->ifa_addr;
|
||||
addr = &ipv6->sin6_addr;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
inet_ntop(ifa->ifa_addr->sa_family, addr, stringBuffer, sizeof(stringBuffer));
|
||||
addresses.push_back(stringBuffer);
|
||||
}
|
||||
}
|
||||
iface_json["addresses"] = addresses;
|
||||
interfaces_json.push_back(iface_json);
|
||||
}
|
||||
j["network_interfaces"] = interfaces_json;
|
||||
} catch (const std::exception& e) {
|
||||
j["network_interfaces"] = std::string("Exception: ") + e.what();
|
||||
} catch (...) {
|
||||
j["network_interfaces"] = "Unknown error retrieving interfaces";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
void addNodeStateInterfacesJson(nlohmann::json& j);
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "diagnostic/node_state_interfaces_bsd.hpp"
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
void addNodeStateInterfacesJson(nlohmann::json& j) {
|
||||
try {
|
||||
std::vector<nlohmann::json> interfaces_json;
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
if (getifaddrs(&ifap) != 0) {
|
||||
j["network_interfaces"] = "ERROR: getifaddrs failed";
|
||||
return;
|
||||
}
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if (!ifa->ifa_addr) continue;
|
||||
nlohmann::json iface_json;
|
||||
iface_json["name"] = ifa->ifa_name;
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock >= 0) {
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ);
|
||||
if (ioctl(sock, SIOCGIFMTU, &ifr) == 0) {
|
||||
iface_json["mtu"] = ifr.ifr_mtu;
|
||||
}
|
||||
if (ifa->ifa_addr->sa_family == AF_LINK) {
|
||||
struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifa->ifa_addr;
|
||||
unsigned char* mac = (unsigned char*)LLADDR(sdl);
|
||||
char macStr[32];
|
||||
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
iface_json["mac"] = macStr;
|
||||
}
|
||||
close(sock);
|
||||
}
|
||||
std::vector<std::string> addresses;
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
char addr[INET_ADDRSTRLEN];
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)ifa->ifa_addr;
|
||||
inet_ntop(AF_INET, &(sa->sin_addr), addr, INET_ADDRSTRLEN);
|
||||
addresses.push_back(addr);
|
||||
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_in6* sa6 = (struct sockaddr_in6*)ifa->ifa_addr;
|
||||
inet_ntop(AF_INET6, &(sa6->sin6_addr), addr, INET6_ADDRSTRLEN);
|
||||
addresses.push_back(addr);
|
||||
}
|
||||
iface_json["addresses"] = addresses;
|
||||
interfaces_json.push_back(iface_json);
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
j["network_interfaces"] = interfaces_json;
|
||||
} catch (const std::exception& e) {
|
||||
j["network_interfaces"] = std::string("Exception: ") + e.what();
|
||||
} catch (...) {
|
||||
j["network_interfaces"] = "Unknown error retrieving interfaces";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
void addNodeStateInterfacesJson(nlohmann::json& j);
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "diagnostic/node_state_interfaces_linux.hpp"
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
void addNodeStateInterfacesJson(nlohmann::json& j) {
|
||||
try {
|
||||
std::vector<nlohmann::json> interfaces_json;
|
||||
struct ifreq ifr;
|
||||
struct ifconf ifc;
|
||||
char buf[1024];
|
||||
char stringBuffer[128];
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
ioctl(sock, SIOCGIFCONF, &ifc);
|
||||
struct ifreq *it = ifc.ifc_req;
|
||||
const struct ifreq * const end = it + (ifc.ifc_len / sizeof(struct ifreq));
|
||||
for(; it != end; ++it) {
|
||||
strcpy(ifr.ifr_name, it->ifr_name);
|
||||
if(ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
|
||||
if (!(ifr.ifr_flags & IFF_LOOPBACK)) { // skip loopback
|
||||
nlohmann::json iface_json;
|
||||
iface_json["name"] = ifr.ifr_name;
|
||||
if (ioctl(sock, SIOCGIFMTU, &ifr) == 0) {
|
||||
iface_json["mtu"] = ifr.ifr_mtu;
|
||||
}
|
||||
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
|
||||
unsigned char mac_addr[6];
|
||||
memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6);
|
||||
char macStr[18];
|
||||
sprintf(macStr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr[0],
|
||||
mac_addr[1],
|
||||
mac_addr[2],
|
||||
mac_addr[3],
|
||||
mac_addr[4],
|
||||
mac_addr[5]);
|
||||
iface_json["mac"] = macStr;
|
||||
}
|
||||
std::vector<std::string> addresses;
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
void *addr;
|
||||
getifaddrs(&ifap);
|
||||
for(ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||
if(strcmp(ifr.ifr_name, ifa->ifa_name) == 0 && ifa->ifa_addr != NULL) {
|
||||
if(ifa->ifa_addr->sa_family == AF_INET) {
|
||||
struct sockaddr_in *ipv4 = (struct sockaddr_in*)ifa->ifa_addr;
|
||||
addr = &ipv4->sin_addr;
|
||||
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)ifa->ifa_addr;
|
||||
addr = &ipv6->sin6_addr;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
inet_ntop(ifa->ifa_addr->sa_family, addr, stringBuffer, sizeof(stringBuffer));
|
||||
addresses.push_back(stringBuffer);
|
||||
}
|
||||
}
|
||||
iface_json["addresses"] = addresses;
|
||||
interfaces_json.push_back(iface_json);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
j["network_interfaces"] = interfaces_json;
|
||||
} catch (const std::exception& e) {
|
||||
j["network_interfaces"] = std::string("Exception: ") + e.what();
|
||||
} catch (...) {
|
||||
j["network_interfaces"] = "Unknown error retrieving interfaces";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
void addNodeStateInterfacesJson(nlohmann::json& j);
|
||||
Loaded 20 of 34 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user