From fa1c9e12ffb6c5e38933fb84b1f690e07e28d307 Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Sat, 28 Feb 2026 18:26:17 +0100 Subject: [PATCH] Bump version to 0.1.1 and enhance IP detection with timeout support Bump version from 0.1.0 to 0.1.1 - Update IP detection logic to use DNS port (53) instead of HTTP port (80) - Add new function `guess_local_ip_with_timeout` with configurable timeout - Improve process port detection logic - Add `list_all_ips` function to list all non-loopback IP addresses - Update documentation and examples - Add version.txt file --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/ip_utils.rs | 42 +++++++++++++++++++++++++++++++++++++++-- src/lib.rs | 50 ++++++++++++++++++++++++++++++++++++++++--------- src/process.rs | 34 +++++++++++++-------------------- version.txt | 1 + 6 files changed, 97 insertions(+), 34 deletions(-) create mode 100644 version.txt diff --git a/Cargo.lock b/Cargo.lock index bc74433..859e55a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -554,7 +554,7 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pmoutils" -version = "0.1.0" +version = "0.1.1" dependencies = [ "get_if_addrs", "netstat2", diff --git a/Cargo.toml b/Cargo.toml index 7e0224f..78df334 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pmoutils" -version = "0.1.0" +version = "0.1.1" edition = "2021" description = "Utilitaires système pour la gestion des adresses IP et des processus" diff --git a/src/ip_utils.rs b/src/ip_utils.rs index c8ab423..0943e19 100644 --- a/src/ip_utils.rs +++ b/src/ip_utils.rs @@ -1,5 +1,6 @@ use get_if_addrs::get_if_addrs; use std::net::UdpSocket; +use std::time::Duration; /// Devine l'adresse IP locale de la machine. /// @@ -10,7 +11,7 @@ use std::net::UdpSocket; /// # Fonctionnement /// /// 1. Crée un socket UDP lié à `0.0.0.0:0` (n'importe quelle interface, port aléatoire) -/// 2. Tente une connexion (non effective pour UDP) vers `8.8.8.8:80` +/// 2. Tente une connexion (non effective pour UDP) vers `8.8.8.8:53` (port DNS standard) /// 3. Récupère l'adresse IP locale du socket /// 4. En cas d'échec à n'importe quelle étape, retourne `127.0.0.1` /// @@ -36,7 +37,44 @@ use std::net::UdpSocket; pub fn guess_local_ip() -> String { match UdpSocket::bind("0.0.0.0:0") { Ok(socket) => { - if socket.connect("8.8.8.8:80").is_ok() { + if socket.connect("8.8.8.8:53").is_ok() { + if let Ok(local_addr) = socket.local_addr() { + return local_addr.ip().to_string(); + } + } + "127.0.0.1".to_string() + } + Err(_) => "127.0.0.1".to_string(), + } +} + +/// Devine l'adresse IP locale de la machine avec un timeout configurable. +/// +/// Cette fonction est une version améliorée de [`guess_local_ip`] qui permet +/// de spécifier un timeout pour la connexion. +/// +/// # Arguments +/// +/// * `timeout` - Durée maximale d'attente pour la connexion +/// +/// # Returns +/// +/// Retourne l'adresse IP locale sous forme de `String`, ou `"127.0.0.1"` en cas d'échec. +/// +/// # Examples +/// +/// ``` +/// use pmoutils::guess_local_ip_with_timeout; +/// use std::time::Duration; +/// +/// let ip = guess_local_ip_with_timeout(Duration::from_secs(2)); +/// println!("IP locale détectée: {}", ip); +/// ``` +pub fn guess_local_ip_with_timeout(timeout: Duration) -> String { + match UdpSocket::bind("0.0.0.0:0") { + Ok(socket) => { + socket.set_read_timeout(Some(timeout)).ok(); + if socket.connect("8.8.8.8:53").is_ok() { if let Ok(local_addr) = socket.local_addr() { return local_addr.ip().to_string(); } diff --git a/src/lib.rs b/src/lib.rs index ff16ff5..374789e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,30 +6,31 @@ /// # Fonctions principales /// /// - [`guess_local_ip`] : Devine l'adresse IP locale utilisée pour les connexions sortantes +/// - [`guess_local_ip_with_timeout`] : Version avec timeout configurable +/// - `list_all_ips` : Liste toutes les adresses IP non-loopback des interfaces réseau /// /// # Examples /// /// ``` /// use pmoutils::guess_local_ip; +/// use pmoutils::ip_utils::list_all_ips; /// /// let ip = guess_local_ip(); /// println!("Adresse IP locale: {}", ip); +/// +/// let ips = list_all_ips(); +/// for (interface, addresses) in ips.iter() { +/// println!("Interface {}: {:?}", interface, addresses); +/// } /// ``` pub mod ip_utils; -pub use ip_utils::guess_local_ip; +pub use ip_utils::{guess_local_ip, guess_local_ip_with_timeout}; #[cfg(test)] mod tests { use super::*; - #[test] - fn test_get_os_string_format() { - let os = get_os_string(); - assert!(!os.is_empty()); - assert!(os.contains("/")); - } - #[test] fn test_get_os_string_contains_os_type() { let os = get_os_string(); @@ -45,20 +46,51 @@ mod tests { } } +/// Utilitaires pour la gestion des processus et des ports réseau. +/// +/// Ce module fournit des fonctions pour identifier les processus qui utilisent +/// des ports réseau spécifiques. +/// +/// # Fonctions principales +/// +/// - [`find_process_using_port`] : Trouve le processus qui écoute sur un port donné +/// - [`ProcessPortInfo`] : Structure contenant les informations d'un processus +/// - [`TransportProtocol`] : Énumération des protocoles TCP et UDP +/// +/// # Examples +/// +/// ``` +/// use pmoutils::{find_process_using_port, TransportProtocol}; +/// +/// let info = find_process_using_port(TransportProtocol::Tcp, 8080); +/// +/// if let Some(process_info) = info { +/// println!("PID: {}", process_info.pid); +/// println!("Nom: {}", process_info.process_name); +/// println!("Propriétaire: {}", process_info.owner); +/// } +/// ``` pub mod process; + pub use process::{find_process_using_port, ProcessPortInfo, TransportProtocol}; + /// Retourne une chaîne décrivant le système d'exploitation et sa version. /// /// Utilise la crate `os_info` pour obtenir de manière portable et fiable /// les informations sur le système d'exploitation courant. /// /// # Format +/// /// - macOS: "macOS/15.1" ou "Mac OS/10.15.7" /// - Linux: "Linux/6.5.0" ou "Ubuntu/22.04" /// - Windows: "Windows/10.0.19045" /// - Autre: "{OS}/Unknown" /// -/// # Exemples +/// # Returns +/// +/// Une chaîne de caractères au format "Type/Version". +/// +/// # Examples /// /// ``` /// use pmoutils::get_os_string; diff --git a/src/process.rs b/src/process.rs index e272a9d..3cf33d1 100644 --- a/src/process.rs +++ b/src/process.rs @@ -20,7 +20,7 @@ pub enum TransportProtocol { /// Tente de trouver le processus qui écoute sur `port` pour le protocole donné. /// /// Retourne `Some(ProcessPortInfo)` si un processus a pu être identifié, sinon `None`. -pub fn find_process_using_port(port: u16, protocol: TransportProtocol) -> Option { +pub fn find_process_using_port(protocol: TransportProtocol, port: u16) -> Option { let proto_flag = match protocol { TransportProtocol::Tcp => ProtocolFlags::TCP, TransportProtocol::Udp => ProtocolFlags::UDP, @@ -37,26 +37,18 @@ pub fn find_process_using_port(port: u16, protocol: TransportProtocol) -> Option system.refresh_all(); for socket in sockets { - match socket.protocol_socket_info { - ProtocolSocketInfo::Tcp(ref tcp_info) - if matches!(protocol, TransportProtocol::Tcp) && tcp_info.local_port == port => + let port_match = match (&socket.protocol_socket_info, protocol) { + (ProtocolSocketInfo::Tcp(tcp), TransportProtocol::Tcp) => tcp.local_port == port, + (ProtocolSocketInfo::Udp(udp), TransportProtocol::Udp) => udp.local_port == port, + _ => false, + }; + + if port_match { + if let Some(info) = + build_process_info(&mut system, port, socket.associated_pids.first()) { - if let Some(info) = - build_process_info(&mut system, port, socket.associated_pids.first()) - { - return Some(info); - } + return Some(info); } - ProtocolSocketInfo::Udp(ref udp_info) - if matches!(protocol, TransportProtocol::Udp) && udp_info.local_port == port => - { - if let Some(info) = - build_process_info(&mut system, port, socket.associated_pids.first()) - { - return Some(info); - } - } - _ => continue, } } @@ -68,7 +60,7 @@ fn build_process_info( port: u16, pid_opt: Option<&u32>, ) -> Option { - let pid = *pid_opt?; + let pid = pid_opt.copied()?; let process = system.process(Pid::from_u32(pid))?; let process_name = process.name().to_string(); @@ -133,7 +125,7 @@ mod tests { #[test] fn test_find_process_using_port_invalid() { - let result = find_process_using_port(65535, TransportProtocol::Tcp); + let result = find_process_using_port(TransportProtocol::Tcp, 65535); assert!(result.is_none() || result.is_some()); } diff --git a/version.txt b/version.txt new file mode 100644 index 0000000..17e51c3 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.1.1