use std::net::{IpAddr, Ipv4Addr};
use anyhow::Result;
pub fn check_admin_privileges() -> bool {
#[cfg(unix)]
{
unsafe { libc::geteuid() == 0 }
}
#[cfg(windows)]
{
true }
#[cfg(not(any(unix, windows)))]
{
false
}
}
pub fn parse_hostname(hostname: &str) -> Result<IpAddr> {
if let Ok(ip) = hostname.parse::<IpAddr>() {
return Ok(ip);
}
use std::net::ToSocketAddrs;
let socket_addrs: Vec<_> = format!("{}:0", hostname)
.to_socket_addrs()
.map_err(|e| anyhow::anyhow!("DNS resolution failed for '{}': {}", hostname, e))?
.collect();
if let Some(addr) = socket_addrs.first() {
Ok(addr.ip())
} else {
Err(anyhow::anyhow!("Could not resolve hostname: {}", hostname))
}
}
pub fn cidr_to_ip_range(network: &str) -> Result<Vec<Ipv4Addr>> {
let parts: Vec<&str> = network.split('/').collect();
if parts.len() != 2 {
return Err(anyhow::anyhow!("Invalid CIDR format: {}", network));
}
let base_ip: Ipv4Addr = parts[0].parse()
.map_err(|e| anyhow::anyhow!("Invalid IP address: {}", e))?;
let prefix_len: u32 = parts[1].parse()
.map_err(|e| anyhow::anyhow!("Invalid prefix length: {}", e))?;
if prefix_len > 32 {
return Err(anyhow::anyhow!("Prefix length must be <= 32"));
}
let base_u32 = u32::from(base_ip);
let host_bits = 32 - prefix_len;
let host_count = if host_bits == 0 { 1 } else { 1u32 << host_bits };
let mask = if host_bits == 0 { 0xFFFFFFFF } else { !((1u32 << host_bits) - 1) };
let network_base = base_u32 & mask;
let mut ips = Vec::new();
for i in 0..host_count {
let ip_u32 = network_base + i;
ips.push(Ipv4Addr::from(ip_u32));
}
Ok(ips)
}
pub fn calculate_icmp_checksum(data: &[u8]) -> u16 {
let mut sum: u32 = 0;
for chunk in data.chunks_exact(2) {
let word = u16::from_be_bytes([chunk[0], chunk[1]]) as u32;
sum += word;
}
if data.len() % 2 != 0 {
sum += data[data.len() - 1] as u32;
}
while sum >> 16 != 0 {
sum = (sum & 0xFFFF) + (sum >> 16);
}
!sum as u16
}
pub fn get_timestamp_ms() -> u64 {
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
pub fn format_hex(bytes: &[u8]) -> String {
bytes.iter()
.map(|b| format!("{:02x}", b))
.collect::<Vec<_>>()
.join(":")
}
pub fn get_process_id() -> u16 {
std::process::id() as u16
}