Add: H3 support - incomplete
This commit is contained in:
@@ -10,8 +10,8 @@ use x509_parser::oid_registry::{
|
||||
use std::sync::Arc;
|
||||
use wtfnet_core::ErrorCode;
|
||||
use wtfnet_platform::{
|
||||
CertProvider, DnsConfigSnapshot, ListenSocket, NeighborEntry, NeighProvider, NetInterface,
|
||||
Platform, PlatformError, PortsProvider, RootCert, RouteEntry, SysProvider,
|
||||
CertProvider, ConnSocket, DnsConfigSnapshot, ListenSocket, NeighborEntry, NeighProvider,
|
||||
NetInterface, Platform, PlatformError, PortsProvider, RootCert, RouteEntry, SysProvider,
|
||||
};
|
||||
|
||||
pub fn platform() -> Platform {
|
||||
@@ -333,6 +333,33 @@ fn parse_windows_listeners() -> Result<Vec<ListenSocket>, PlatformError> {
|
||||
Ok(sockets)
|
||||
}
|
||||
|
||||
fn parse_windows_connections() -> Result<Vec<ConnSocket>, PlatformError> {
|
||||
let proc_map = load_windows_process_map();
|
||||
let output = std::process::Command::new("netstat")
|
||||
.arg("-ano")
|
||||
.output()
|
||||
.map_err(|err| PlatformError::new(ErrorCode::IoError, err.to_string()))?;
|
||||
if !output.status.success() {
|
||||
return Err(PlatformError::new(ErrorCode::IoError, "netstat -ano failed"));
|
||||
}
|
||||
|
||||
let text = String::from_utf8_lossy(&output.stdout);
|
||||
let mut sockets = Vec::new();
|
||||
|
||||
for line in text.lines() {
|
||||
let trimmed = line.trim();
|
||||
if !trimmed.starts_with("TCP") {
|
||||
continue;
|
||||
}
|
||||
if let Some(mut socket) = parse_netstat_tcp_conn_line(trimmed) {
|
||||
enrich_conn_socket(&mut socket, &proc_map);
|
||||
sockets.push(socket);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(sockets)
|
||||
}
|
||||
|
||||
fn parse_netstat_tcp_line(line: &str) -> Option<ListenSocket> {
|
||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||
if parts.len() < 5 {
|
||||
@@ -358,6 +385,32 @@ fn parse_netstat_tcp_line(line: &str) -> Option<ListenSocket> {
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_netstat_tcp_conn_line(line: &str) -> Option<ConnSocket> {
|
||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||
if parts.len() < 5 {
|
||||
return None;
|
||||
}
|
||||
let local = parts[1];
|
||||
let remote = parts[2];
|
||||
let state = parts[3];
|
||||
let pid = parts[4].parse::<u32>().ok();
|
||||
|
||||
if state == "LISTENING" {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(ConnSocket {
|
||||
proto: "tcp".to_string(),
|
||||
local_addr: local.to_string(),
|
||||
remote_addr: remote.to_string(),
|
||||
state: Some(state.to_string()),
|
||||
pid,
|
||||
ppid: None,
|
||||
process_name: None,
|
||||
process_path: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_netstat_udp_line(line: &str) -> Option<ListenSocket> {
|
||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||
if parts.len() < 4 {
|
||||
@@ -429,6 +482,17 @@ fn enrich_socket(socket: &mut ListenSocket, map: &HashMap<u32, ProcInfo>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn enrich_conn_socket(socket: &mut ConnSocket, map: &HashMap<u32, ProcInfo>) {
|
||||
let pid = match socket.pid {
|
||||
Some(pid) => pid,
|
||||
None => return,
|
||||
};
|
||||
if let Some(info) = map.get(&pid) {
|
||||
socket.process_name = info.name.clone();
|
||||
socket.process_path = info.path.clone();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ProcInfo {
|
||||
name: Option<String>,
|
||||
@@ -605,6 +669,10 @@ impl PortsProvider for WindowsPortsProvider {
|
||||
.filter(|socket| extract_port(&socket.local_addr) == Some(port))
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn connections(&self) -> Result<Vec<ConnSocket>, PlatformError> {
|
||||
parse_windows_connections()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
Reference in New Issue
Block a user