### Retrieve Network Socket Information Source: https://docs.rs/netstat2/0.11.2/netstat2/index.html This example demonstrates how to retrieve information about TCP and UDP sockets using IPv4 and IPv6. It iterates through the results, printing details for TCP connections and UDP listeners. Ensure AddressFamilyFlags and ProtocolFlags are correctly set for your needs. ```rust use netstat2::*; let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6; let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP; let sockets_info = get_sockets_info(af_flags, proto_flags)?; for si in sockets_info { match si.protocol_socket_info { ProtocolSocketInfo::Tcp(tcp_si) => println!( "TCP {}:{} -> {}:{} {:?} - {}", tcp_si.local_addr, tcp_si.local_port, tcp_si.remote_addr, tcp_si.remote_port, si.associated_pids, tcp_si.state ), ProtocolSocketInfo::Udp(udp_si) => println!( "UDP {}:{} -> *:* {:?}", udp_si.local_addr, udp_si.local_port, si.associated_pids ), } } ``` -------------------------------- ### Find TCP Socket with Many Connections Source: https://docs.rs/netstat2/0.11.2/src/netstat2/lib.rs.html Retrieves TCP socket information for the current process when multiple connections are established. This example checks if the number of sockets found is sufficient. ```rust let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let open_port = listener.local_addr().unwrap().port(); let sessions: Vec<_> = (0..128) .map(|_| TcpStream::connect(listener.local_addr().unwrap()).unwrap()) .collect(); let pid = process::id(); let af_flags = AddressFamilyFlags::all(); let proto_flags = ProtocolFlags::TCP; let sock_info = get_sockets_info(af_flags, proto_flags).unwrap(); assert!(!sock_info.is_empty()); assert!(sock_info.len() >= sessions.len() + 1); let sock = sock_info .into_iter() .find(|s| { s.associated_pids.contains(&pid) && matches!(s.protocol_socket_info, ProtocolSocketInfo::Tcp(TcpSocketInfo { local_port, ``` -------------------------------- ### Get TypeId of UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Retrieves the TypeId of the UdpSocketInfo, useful for runtime type identification. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Implement TryFrom for T Source: https://docs.rs/netstat2/0.11.2/netstat2/error/enum.Error.html Illustrates the blanket implementation of TryFrom for T, where U can be converted into T. ```rust impl TryFrom for T where U: Into, Source #### type Error = Infallible The type returned in the event of a conversion error. Source #### fn try_from(value: U) -> Result>::Error> Performs the conversion. Source ``` -------------------------------- ### CloneToUninit UdpSocketInfo (Nightly) Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Nightly-only experimental API for performing copy-assignment from self to uninitialized memory. ```rust unsafe fn clone_to_uninit(&self, dest: *mut u8) ``` -------------------------------- ### Implement TryInto for T Source: https://docs.rs/netstat2/0.11.2/netstat2/error/enum.Error.html Demonstrates the blanket implementation of TryInto for T, allowing conversion from T to U if U implements TryFrom. ```rust impl TryInto for T where U: TryFrom, Source #### type Error = >::Error The type returned in the event of a conversion error. Source #### fn try_into(self) -> Result>::Error> Performs the conversion. Source ``` -------------------------------- ### TryFrom UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Attempts to perform a conversion into UdpSocketInfo from another type. ```rust fn try_from(value: U) -> Result>::Error> ``` -------------------------------- ### Implement Into for T Source: https://docs.rs/netstat2/0.11.2/netstat2/error/enum.Error.html Demonstrates the blanket implementation of Into for T, leveraging the From for U trait. ```rust impl Into for T where U: From, Source #### fn into(self) -> U Calls `U::from(self)`. That is, this conversion is whatever the implementation of `From for U` chooses to do. Source ``` -------------------------------- ### Into UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Converts UdpSocketInfo into another type that implements From. ```rust fn into(self) -> U ``` -------------------------------- ### From UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Converts a value into UdpSocketInfo, returning the argument unchanged. ```rust fn from(t: T) -> T ``` -------------------------------- ### TryInto UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Attempts to convert UdpSocketInfo into another type that implements TryFrom. ```rust fn try_into(self) -> Result>::Error> ``` -------------------------------- ### Handle Protocol Matching Source: https://docs.rs/netstat2/0.11.2/src/netstat2/integrations/linux/netlink_iterator.rs.html Matches protocol types and returns socket information or an error if the protocol is unknown. ```rust uid: diag_msg.header.uid, }, _ => return Err(Error::UnknownProtocol(protocol)), }; Ok(sock_info) } ``` -------------------------------- ### Implement From for T Source: https://docs.rs/netstat2/0.11.2/netstat2/error/enum.Error.html A simple blanket implementation of From for T, returning the argument unchanged. ```rust impl From for T Source #### fn from(t: T) -> T Returns the argument unchanged. Source ``` -------------------------------- ### Build PID to Inode Hash Map Source: https://docs.rs/netstat2/0.11.2/src/netstat2/integrations/linux/procfs.rs.html Scans /proc to identify socket file descriptors and maps each inode to a set of PIDs. Requires filesystem read permissions for /proc. ```rust 1use std::collections::HashMap; 2use std::collections::HashSet; 3use std::fs::{read_dir, read_link}; 4 5pub fn build_hash_of_pids_by_inode() -> HashMap> { 6 let pids = read_dir("/proc/") 7 .expect("Can't read /proc/") 8 .filter_map(|d| d.ok()?.file_name().to_str()?.parse::().ok()); 9 let mut pid_by_inode = HashMap::new(); 10 for pid in pids { 11 if let Result::Ok(fds) = read_dir(format!("/proc/{}/fd", pid)) { 12 let inodes = fds.filter_map(|fd| { 13 let fd_file_name = fd.ok()?.file_name(); 14 let fd_str = fd_file_name.to_str()?; 15 let path_buf = read_link(format!("/proc/{}/fd/{}", pid, fd_str)).ok()?; 16 let link_str = path_buf.to_str()?; 17 if link_str.starts_with("socket:[") { 18 let inode_str = &link_str[8..link_str.len() - 1]; 19 inode_str.parse::().ok() 20 } else { 21 Option::None 22 } 23 }); 24 for inode in inodes { 25 pid_by_inode 26 .entry(inode) 27 .and_modify(|v: &mut HashSet| { 28 v.insert(pid); 29 }) 30 .or_insert_with(|| { 31 let mut s = HashSet::new(); 32 s.insert(pid); 33 s 34 }); 35 } 36 } 37 } 38 pid_by_inode 39} ``` -------------------------------- ### Export Linux TCP State Extensions Source: https://docs.rs/netstat2/0.11.2/src/netstat2/integrations/linux/ext/mod.rs.html Exposes the tcp_state_ext module functionality to the crate. ```rust 1mod tcp_state_ext; 2 3pub use self::tcp_state_ext::*; ``` -------------------------------- ### ProtocolFlags Iteration and Extension Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.ProtocolFlags.html Covers how to extend ProtocolFlags from iterators and how ProtocolFlags itself can be iterated. ```APIDOC ## ProtocolFlags Iteration and Extension ### Description This section describes how `ProtocolFlags` can be extended from iterators and how `ProtocolFlags` values can be converted into iterators. ### Implementations #### `impl Extend for ProtocolFlags` Allows extending a `ProtocolFlags` value with elements from an iterator, performing a bitwise OR operation. #### `impl FromIterator for ProtocolFlags` Allows creating a `ProtocolFlags` value by consuming an iterator of `ProtocolFlags`, performing a bitwise OR operation on all elements. #### `impl IntoIterator for ProtocolFlags` Enables converting a `ProtocolFlags` value into an iterator (`Iter`), yielding individual flags. ``` -------------------------------- ### ProtocolFlags Cloning and Debugging Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.ProtocolFlags.html Details on how to clone and debug ProtocolFlags values. ```APIDOC ## ProtocolFlags Cloning and Debugging ### Description This section describes the cloning and debugging capabilities for the `ProtocolFlags` type. ### Methods #### `clone(&self) -> ProtocolFlags` Returns a duplicate of the `ProtocolFlags` value. #### `clone_from(&mut self, source: &Self)` Performs copy-assignment from a source `ProtocolFlags` value. #### `fmt(&self, f: &mut Formatter<'_>) -> Result` Formats the `ProtocolFlags` value using the given formatter, typically for debugging output. ``` -------------------------------- ### netstat2 types module overview Source: https://docs.rs/netstat2/0.11.2/src/netstat2/types/mod.rs.html Overview of the exported types and sub-modules available in the netstat2 crate. ```APIDOC ## Module: netstat2::types ### Description The types module serves as the central repository for network-related data structures used throughout the netstat2 crate. ### Exported Modules - **address_family**: Definitions for socket address families. - **error**: Error handling types for network operations. - **protocol**: Definitions for network protocols. - **socket_info**: Structures representing socket state and metadata. - **tcp_state**: Enumerations for TCP connection states. ``` -------------------------------- ### Clone Into UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Uses borrowed UdpSocketInfo data to replace owned data, usually by cloning. ```rust fn clone_into(&self, target: &mut T) ``` -------------------------------- ### Test Socket Information with Flag Combinations Source: https://docs.rs/netstat2/0.11.2/src/netstat2/lib.rs.html Iterates through all possible combinations of AddressFamilyFlags and ProtocolFlags to ensure get_sockets_info returns an Ok result. ```rust #[test] fn result_is_ok_for_any_flags() { let af_flags_combs = (0..AddressFamilyFlags::all().bits() + 1) .filter_map(AddressFamilyFlags::from_bits) .collect::>(); let proto_flags_combs = (0..ProtocolFlags::all().bits() + 1) .filter_map(ProtocolFlags::from_bits) .collect::>(); for af_flags in af_flags_combs.iter() { for proto_flags in proto_flags_combs.iter() { assert!(get_sockets_info(*af_flags, *proto_flags).is_ok()); } } } ``` -------------------------------- ### Compare UdpSocketInfo for Equality Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Tests if two UdpSocketInfo values are equal, used by the equality operator (==). ```rust fn eq(&self, other: &UdpSocketInfo) -> bool ``` -------------------------------- ### Compare UdpSocketInfo for Inequality Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Tests if two UdpSocketInfo values are not equal, used by the inequality operator (!=). ```rust fn ne(&self, other: &Rhs) -> bool ``` -------------------------------- ### Test Listening UDP Socket Source: https://docs.rs/netstat2/0.11.2/src/netstat2/lib.rs.html Verifies that a local UDP socket can be bound and identified. ```rust #[test] fn listening_udp_socket_is_found() { let listener = UdpSocket::bind("127.0.0.1:0").unwrap(); let open_port = listener.local_addr().unwrap().port(); let pid = process::id(); ``` -------------------------------- ### ProtocolFlags Trait Implementations Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.ProtocolFlags.html Details on the traits implemented by ProtocolFlags, such as Binary, BitAnd, BitOr, and BitXor. ```APIDOC ## Trait Implementations for ProtocolFlags ### Binary - `fmt(f: &mut Formatter<'_>)`: Formats the value using the given formatter. ### BitAnd - `bitand(self, other: Self)`: Performs bitwise AND operation. - `Output`: `ProtocolFlags` ### BitAndAssign - `bitand_assign(&mut self, other: Self)`: Performs bitwise AND assignment. ### BitOr - `bitor(self, other: ProtocolFlags)`: Performs bitwise OR operation. - `Output`: `ProtocolFlags` ### BitOrAssign - `bitor_assign(&mut self, other: Self)`: Performs bitwise OR assignment. ### BitXor - `bitxor(self, other: Self)`: Performs bitwise XOR operation. - `Output`: `ProtocolFlags` ``` -------------------------------- ### Clone From UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Enables copy-assignment from a source UdpSocketInfo value to another. ```rust fn clone_from(&mut self, source: &Self) ``` -------------------------------- ### Define SocketInfo and ProtocolSocketInfo structures Source: https://docs.rs/netstat2/0.11.2/src/netstat2/types/socket_info.rs.html Defines the core data structures for representing network sockets, including protocol-specific details for TCP and UDP, and helper methods for accessing local address and port information. ```rust 1use crate::types::tcp_state::TcpState; 2use std::net::IpAddr; 3 4/// General socket information. 5#[derive(Clone, Debug, PartialEq)] 6pub struct SocketInfo { 7 /// Protocol-specific socket information. 8 pub protocol_socket_info: ProtocolSocketInfo, 9 /// Identifiers of processes associated with this socket. 10 pub associated_pids: Vec, 11 #[cfg(any(target_os = "linux", target_os = "android"))] 12 /// Inode number of this socket. 13 pub inode: u32, 14 #[cfg(any(target_os = "linux", target_os = "android"))] 15 /// Owner UID of this socket. 16 pub uid: u32, 17} 18 19/// Protocol-specific socket information. 20#[derive(Clone, Debug, PartialEq)] 21pub enum ProtocolSocketInfo { 22 /// TCP-specific socket information. 23 Tcp(TcpSocketInfo), 24 /// UDP-specific socket information. 25 Udp(UdpSocketInfo), 26} 27 28/// TCP-specific socket information. 29#[derive(Clone, Debug, PartialEq)] 30pub struct TcpSocketInfo { 31 pub local_addr: IpAddr, 32 pub local_port: u16, 33 pub remote_addr: IpAddr, 34 pub remote_port: u16, 35 pub state: TcpState, 36} 37 38/// UDP-specific socket information. 39#[derive(Clone, Debug, PartialEq)] 40pub struct UdpSocketInfo { 41 pub local_addr: IpAddr, 42 pub local_port: u16, 43} 44 45impl SocketInfo { 46 /// Local address of this socket. 47 pub fn local_addr(&self) -> IpAddr { 48 match &self.protocol_socket_info { 49 ProtocolSocketInfo::Tcp(s) => s.local_addr, 50 ProtocolSocketInfo::Udp(s) => s.local_addr, 51 } 52 } 53 54 /// Local port of this socket. 55 pub fn local_port(&self) -> u16 { 56 match &self.protocol_socket_info { 57 ProtocolSocketInfo::Tcp(s) => s.local_port, 58 ProtocolSocketInfo::Udp(s) => s.local_port, 59 } 60 } 61} ``` -------------------------------- ### Trait Implementations Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.ProtocolFlags.html Standard trait implementations for ProtocolFlags including equality and formatting. ```APIDOC ## PartialEq ### Description Tests for equality (==) and inequality (!=) between two ProtocolFlags instances. ### Methods - **eq(&self, other: &ProtocolFlags) -> bool** - **ne(&self, other: &Rhs) -> bool** ## Formatting ### Description Formats the ProtocolFlags value using standard formatters. ### Methods - **Octal::fmt(&self, f: &mut Formatter<'_>) -> Result** - **UpperHex::fmt(&self, f: &mut Formatter<'_>) -> Result** ``` -------------------------------- ### Trait Implementations for UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Details the trait implementations available for the UdpSocketInfo struct. ```APIDOC ## Trait Implementations for UdpSocketInfo ### impl Clone for UdpSocketInfo - **fn clone(&self) -> UdpSocketInfo**: Returns a duplicate of the value. - **fn clone_from(&mut self, source: &Self)**: Performs copy-assignment from `source`. ### impl Debug for UdpSocketInfo - **fn fmt(&self, f: &mut Formatter<'_>) -> Result**: Formats the value using the given formatter. ### impl PartialEq for UdpSocketInfo - **fn eq(&self, other: &UdpSocketInfo) -> bool**: Tests for `self` and `other` values to be equal. - **fn ne(&self, other: &Rhs) -> bool**: Tests for `!=`. ### impl StructuralPartialEq for UdpSocketInfo ### Auto Trait Implementations - **Freeze** - **RefUnwindSafe** - **Send** - **Sync** - **Unpin** - **UnsafeUnpin** - **UnwindSafe** ### Blanket Implementations - **impl Any for T** - **impl Borrow for T** - **impl BorrowMut for T** - **impl CloneToUninit for T** (Nightly-only experimental API) - **impl From for T** - **impl Into for T** - **impl ToOwned for T** - **impl TryFrom for T** - **impl TryInto for T** ``` -------------------------------- ### ProtocolFlags Formatting Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.ProtocolFlags.html Details on formatting ProtocolFlags for display, including Debug and LowerHex. ```APIDOC ## ProtocolFlags Formatting ### Description This section covers the formatting capabilities for `ProtocolFlags`, specifically for debugging and hexadecimal representation. ### Implementations #### `impl Debug for ProtocolFlags` Provides a standard way to format `ProtocolFlags` for debugging purposes using the `fmt` method. #### `impl LowerHex for ProtocolFlags` Provides a way to format `ProtocolFlags` as a lowercase hexadecimal string using the `fmt` method. ``` -------------------------------- ### UdpSocketInfo Structure Source: https://docs.rs/netstat2/0.11.2/src/netstat2/types/socket_info.rs.html Contains detailed information specific to UDP sockets. ```APIDOC ## UdpSocketInfo Structure ### Description Contains detailed information specific to UDP sockets. ### Fields - **local_addr** (IpAddr) - The local IP address of the UDP socket. - **local_port** (u16) - The local port number of the UDP socket. ``` -------------------------------- ### get_sockets_info Source: https://docs.rs/netstat2/0.11.2/netstat2/fn.get_sockets_info.html Retrieves system sockets information as a vector, short-circuiting on any encountered errors. ```APIDOC ## get_sockets_info ### Description Retrieve sockets information as a vector. Short-circuits on any error along the way. ### Parameters #### Arguments - **af_flags** (AddressFamilyFlags) - Required - Flags specifying the address families to include. - **proto_flags** (ProtocolFlags) - Required - Flags specifying the protocols to include. ### Response - **Result, Error>** - Returns a vector of SocketInfo objects on success, or an Error if the operation fails. ``` -------------------------------- ### Iterate Sockets Info Source: https://docs.rs/netstat2/0.11.2/netstat2/fn.iterate_sockets_info.html Use this function to iterate through socket information. It requires specifying address family and protocol flags. ```rust pub fn iterate_sockets_info( af_flags: AddressFamilyFlags, proto_flags: ProtocolFlags, ) -> Result>, Error> ``` -------------------------------- ### Function iterate_sockets_info Source: https://docs.rs/netstat2/0.11.2/netstat2/fn.iterate_sockets_info.html Iterates through sockets information based on provided address family and protocol flags. ```APIDOC ## Function iterate_sockets_info ### Description Iterate through sockets information. ### Signature ```rust pub fn iterate_sockets_info( af_flags: AddressFamilyFlags, proto_flags: ProtocolFlags, ) -> Result>, Error> ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (Iterator) - `Iterator>`: An iterator yielding `SocketInfo` or `Error` for each socket. #### Error Response - `Error`: An error encountered during the iteration setup. ``` -------------------------------- ### Implement Any trait for generic types Source: https://docs.rs/netstat2/0.11.2/netstat2/error/enum.Error.html Demonstrates the blanket implementation of the Any trait for any type T that is 'static. ```rust impl Any for T where T: 'static + ?Sized, Source #### fn type_id(&self) -> TypeId Gets the `TypeId` of `self`. Read more Source ``` -------------------------------- ### Clone UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Provides functionality to create a duplicate of a UdpSocketInfo value. ```rust fn clone(&self) -> UdpSocketInfo ``` -------------------------------- ### SocketInfo Structure Source: https://docs.rs/netstat2/0.11.2/src/netstat2/types/socket_info.rs.html Provides general socket information, including protocol-specific details and associated process identifiers. ```APIDOC ## SocketInfo Structure ### Description General socket information, including protocol-specific details and associated process identifiers. ### Fields - **protocol_socket_info** (ProtocolSocketInfo) - Protocol-specific socket information. - **associated_pids** (Vec) - Identifiers of processes associated with this socket. - **inode** (u32) - Inode number of this socket. (Linux/Android only) - **uid** (u32) - Owner UID of this socket. (Linux/Android only) ### Methods - **local_addr()** -> IpAddr - Returns the local address of the socket. - **local_port()** -> u16 - Returns the local port of the socket. ``` -------------------------------- ### Verify Empty Result for Empty Flags Source: https://docs.rs/netstat2/0.11.2/src/netstat2/lib.rs.html Confirms that providing empty flags to get_sockets_info results in an empty collection. ```rust #[test] fn result_is_empty_for_empty_flags() { let sockets_info = get_sockets_info(AddressFamilyFlags::empty(), ProtocolFlags::empty()).unwrap(); assert!(sockets_info.is_empty()); } } ``` -------------------------------- ### Define UdpSocketInfo Struct Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Defines the structure for UDP-specific socket information, including local IP address and port. ```rust pub struct UdpSocketInfo { pub local_addr: IpAddr, pub local_port: u16, } ``` -------------------------------- ### Test Listening TCP Socket Source: https://docs.rs/netstat2/0.11.2/src/netstat2/lib.rs.html Verifies that a local IPv4 TCP listening socket can be correctly identified by the library. ```rust #[test] fn listening_tcp_socket_is_found() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let open_port = listener.local_addr().unwrap().port(); let pid = process::id(); let af_flags = AddressFamilyFlags::all(); let proto_flags = ProtocolFlags::TCP; let sock_info = get_sockets_info(af_flags, proto_flags).unwrap(); assert!(!sock_info.is_empty()); let sock = sock_info .into_iter() .find(|s| { s.associated_pids.contains(&pid) && matches!(s.protocol_socket_info, ProtocolSocketInfo::Tcp(TcpSocketInfo { local_port, local_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), state: TcpState::Listen, .. }) if local_port == open_port) }) .unwrap(); assert_eq!( sock.protocol_socket_info, ProtocolSocketInfo::Tcp(TcpSocketInfo { local_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), local_port: open_port, remote_addr: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), remote_port: 0, state: TcpState::Listen, }) ); assert_eq!(sock.associated_pids, vec![pid]); } ``` -------------------------------- ### Iterate Sockets Info Source: https://docs.rs/netstat2/0.11.2/src/netstat2/integrations/linux/api.rs.html Provides an iterator over socket information, attaching associated PIDs to each entry. ```APIDOC ## iterate_sockets_info ### Description Iterate through sockets information, attaching associated PIDs. ### Function Signature `pub fn iterate_sockets_info(af_flags: AddressFamilyFlags, proto_flags: ProtocolFlags) -> Result>, Error>` ### Parameters #### Query Parameters - **af_flags** (AddressFamilyFlags) - Required - Flags to filter by address family (e.g., IPv4, IPv6). - **proto_flags** (ProtocolFlags) - Required - Flags to filter by protocol (e.g., TCP, UDP). ### Response #### Success Response (Iterator) - Returns an iterator where each item is a `Result`. - `SocketInfo` includes details about the socket and its associated PIDs. #### Error Response - `Error` - If there is an issue initializing the iterators. ``` -------------------------------- ### Implement ToString for generic types Source: https://docs.rs/netstat2/0.11.2/netstat2/error/enum.Error.html Shows the blanket implementation of ToString for any type T that implements Display. ```rust impl ToString for T where T: Display + ?Sized, Source #### fn to_string(&self) -> String Converts the given value to a `String`. Read more Source ``` -------------------------------- ### Test Listening IPv6 TCP Socket Source: https://docs.rs/netstat2/0.11.2/src/netstat2/lib.rs.html Verifies that a local IPv6 TCP listening socket can be correctly identified by the library. ```rust #[test] fn listening_tcp_socket_ipv6_is_found() { let listener = TcpListener::bind("::1:0").unwrap(); let open_port = listener.local_addr().unwrap().port(); let pid = process::id(); let af_flags = AddressFamilyFlags::all(); let proto_flags = ProtocolFlags::TCP; let sock_info = get_sockets_info(af_flags, proto_flags).unwrap(); assert!(!sock_info.is_empty()); let sock = sock_info .into_iter() .find(|s| { s.associated_pids.contains(&pid) && matches!(s.protocol_socket_info, ProtocolSocketInfo::Tcp(TcpSocketInfo { local_port, local_addr: IpAddr::V6(Ipv6Addr::LOCALHOST), state: TcpState::Listen, .. }) if local_port == open_port) }) .unwrap(); assert_eq!( sock.protocol_socket_info, ProtocolSocketInfo::Tcp(TcpSocketInfo { local_addr: IpAddr::V6(Ipv6Addr::LOCALHOST), local_port: open_port, remote_addr: IpAddr::V6(Ipv6Addr::UNSPECIFIED), remote_port: 0, state: TcpState::Listen, }) ); assert_eq!(sock.associated_pids, vec![pid]); } ``` -------------------------------- ### Linux Integration Module Exports Source: https://docs.rs/netstat2/0.11.2/src/netstat2/integrations/linux/mod.rs.html Defines the internal modules and re-exports the public API for the Linux integration. ```rust 1mod api; 2mod ext; 3mod netlink_iterator; 4mod procfs; 5 6pub use self::api::*; ``` -------------------------------- ### Borrow UdpSocketInfo Immutably Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Provides an immutable borrow to the UdpSocketInfo value. ```rust fn borrow(&self) -> &T ``` -------------------------------- ### Format UdpSocketInfo for Debug Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Formats the UdpSocketInfo value for debugging purposes using a given formatter. ```rust fn fmt(&self, f: &mut Formatter<'_>) -> Result ``` -------------------------------- ### ProtocolFlags Bitwise Operations Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.ProtocolFlags.html Provides methods for bitwise XOR, AND, OR, and other set operations on ProtocolFlags. ```APIDOC ## ProtocolFlags Bitwise Operations ### Description This section covers the bitwise operations available for the `ProtocolFlags` type, including XOR, AND, OR, and set manipulations. ### Methods #### `bitxor_assign(&mut self, other: Self)` Performs a bitwise exclusive-OR (`^`) operation with another `ProtocolFlags` value. #### `extend>(&mut self, iterator: T)` Performs a bitwise OR (`|`) operation with all flags from an iterator. #### `insert(&mut self, other: Self)` Performs a bitwise OR (`|`) operation to insert bits from another `ProtocolFlags` value. #### `remove(&mut self, other: Self)` Performs a bitwise AND with the complement (`&!`) to remove bits present in another `ProtocolFlags` value. #### `toggle(&mut self, other: Self)` Performs a bitwise exclusive-OR (`^`) operation to toggle bits based on another `ProtocolFlags` value. #### `set(&mut self, other: Self, value: bool)` Conditionally inserts or removes bits based on the `value` parameter. If `value` is true, `insert` is called; otherwise, `remove` is called. #### `intersection(self, other: Self) -> Self` Returns a new `ProtocolFlags` value representing the bitwise AND (`&`) of two flag values. #### `union(self, other: Self) -> Self` Returns a new `ProtocolFlags` value representing the bitwise OR (`|`) of two flag values. #### `difference(self, other: Self) -> Self` Returns a new `ProtocolFlags` value representing the intersection of the first value with the complement of the second (`&!`). #### `symmetric_difference(self, other: Self) -> Self` Returns a new `ProtocolFlags` value representing the bitwise exclusive-OR (`^`) of two flag values. #### `complement(self) -> Self` Returns a new `ProtocolFlags` value representing the bitwise negation (`!`) of the bits, truncating any unknown bits. ``` -------------------------------- ### Struct UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Represents UDP-specific socket information, including the local IP address and port. ```APIDOC ## Struct UdpSocketInfo ### Description UDP-specific socket information. ### Fields - **local_addr** (IpAddr) - The local IP address of the UDP socket. - **local_port** (u16) - The local port number of the UDP socket. ``` -------------------------------- ### SocketInfo Struct Definition Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.SocketInfo.html The primary structure representing general socket information. ```rust pub struct SocketInfo { pub protocol_socket_info: ProtocolSocketInfo, pub associated_pids: Vec, pub inode: u32, pub uid: u32, } ``` -------------------------------- ### ToOwned UdpSocketInfo Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Creates owned data from borrowed UdpSocketInfo data, typically by cloning. ```rust fn to_owned(&self) -> T ``` -------------------------------- ### Retrieve socket information using get_sockets_info Source: https://docs.rs/netstat2/0.11.2/netstat2/fn.get_sockets_info.html Returns a vector of SocketInfo objects based on the provided address family and protocol flags. This function will return an error if any step in the retrieval process fails. ```rust pub fn get_sockets_info( af_flags: AddressFamilyFlags, proto_flags: ProtocolFlags, ) -> Result, Error> ``` -------------------------------- ### Borrow UdpSocketInfo Mutably Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.UdpSocketInfo.html Provides a mutable borrow to the UdpSocketInfo value. ```rust fn borrow_mut(&mut self) -> &mut T ``` -------------------------------- ### get_sockets_info Source: https://docs.rs/netstat2/0.11.2/src/netstat2/integrations/shared_api.rs.html Retrieves system socket information as a vector based on provided address family and protocol flags. ```APIDOC ## get_sockets_info ### Description Retrieves sockets information as a vector. Short-circuits on any error along the way. ### Parameters - **af_flags** (AddressFamilyFlags) - Required - Flags specifying the address families to include. - **proto_flags** (ProtocolFlags) - Required - Flags specifying the protocols to include. ### Response - **Result, Error>** - A vector of SocketInfo objects on success, or an Error if the operation fails. ``` -------------------------------- ### NetlinkIterator Implementation for Socket Diagnostics Source: https://docs.rs/netstat2/0.11.2/src/netstat2/integrations/linux/netlink_iterator.rs.html Defines the NetlinkIterator struct and its methods for initializing a netlink socket and iterating over diagnostic responses. ```rust //! This implementation is based on the `examples/dump_ipv4.rs` from `https://github.com/rust-netlink/netlink-packet-sock-diag`. use crate::types::error::*; use crate::types::*; use std; use std::io; use std::mem::size_of; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use netlink_packet_core::{ NetlinkHeader, NetlinkMessage, NetlinkPayload, NLM_F_DUMP, NLM_F_REQUEST, }; use netlink_packet_sock_diag::inet::InetResponse; use netlink_packet_sock_diag::{ constants::*, inet::{ExtensionFlags, InetRequest, SocketId, StateFlags}, SockDiagMessage, }; use netlink_sys::{protocols::NETLINK_SOCK_DIAG, Socket, SocketAddr}; const SOCKET_BUFFER_SIZE: usize = 8192; pub struct NetlinkIterator { protocol: u8, recv_buf: [u8; SOCKET_BUFFER_SIZE], socket: Socket, offset: usize, size: usize, is_done: bool, } impl NetlinkIterator { pub fn new(family: u8, protocol: u8) -> Result { let mut socket = Socket::new(NETLINK_SOCK_DIAG)?; let _port_number = socket.bind_auto()?.port_number(); socket.connect(&SocketAddr::new(0, 0))?; let mut nl_hdr = NetlinkHeader::default(); nl_hdr.flags = NLM_F_REQUEST | NLM_F_DUMP; let mut packet = NetlinkMessage::new( nl_hdr, SockDiagMessage::InetRequest(InetRequest { family, protocol, extensions: ExtensionFlags::empty(), states: StateFlags::all(), socket_id: SocketId::new_v4(), }) .into(), ); packet.finalize(); let mut buf = vec![0; packet.buffer_len()]; packet.serialize(&mut buf[..]); socket.send(&buf[..], 0)?; Ok(NetlinkIterator { protocol, socket, recv_buf: [0u8; SOCKET_BUFFER_SIZE as usize], offset: 0, size: 0, is_done: false, }) } fn try_read_next_packet(&mut self) -> Result, Error> { if self.is_done { return Ok(None); } loop { if self.offset >= self.size { self.size = self.socket.recv(&mut &mut self.recv_buf[..], 0)?; self.offset = 0; } let bytes = &self.recv_buf[self.offset..self.size]; let rx_packet: NetlinkMessage = match NetlinkMessage::deserialize(bytes) { Ok(rx_packet) => rx_packet, Err(e) => { // Avoid endless loop in case of a deserialization failure. self.is_done = true; return Err(Error::from(e)); } }; self.offset += rx_packet.header.length as usize; match rx_packet.payload { NetlinkPayload::Noop => {} NetlinkPayload::InnerMessage(SockDiagMessage::InetResponse(response)) => { return Ok(Some(parse_diag_msg(&response, self.protocol)?)); } NetlinkPayload::Done(_) => { self.is_done = true; return Ok(None); } _ => return Ok(None), } } } } impl Iterator for NetlinkIterator { type Item = Result; fn next(&mut self) -> Option { self.try_read_next_packet().transpose() } } fn parse_diag_msg(diag_msg: &InetResponse, protocol: u8) -> Result { let src_port = diag_msg.header.socket_id.source_port; let dst_port = diag_msg.header.socket_id.destination_port; let src_ip = diag_msg.header.socket_id.source_address; let dst_ip = diag_msg.header.socket_id.destination_address; let sock_info = match protocol { IPPROTO_TCP => SocketInfo { protocol_socket_info: ProtocolSocketInfo::Tcp(TcpSocketInfo { local_addr: src_ip, local_port: src_port, remote_addr: dst_ip, remote_port: dst_port, state: TcpState::from(diag_msg.header.state), }), associated_pids: vec![], inode: diag_msg.header.inode, uid: diag_msg.header.uid, }, IPPROTO_UDP => SocketInfo { protocol_socket_info: ProtocolSocketInfo::Udp(UdpSocketInfo { local_addr: src_ip, local_port: src_port, }), associated_pids: vec![], inode: diag_msg.header.inode, ``` -------------------------------- ### Find Listening TCP Socket by PID and Port Source: https://docs.rs/netstat2/0.11.2/src/netstat2/lib.rs.html Finds a listening TCP socket associated with the current process and a specific port. It filters by localhost IPv4 address and TCP LISTEN state. ```rust let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let _ipv6_listener = TcpListener::bind("::1:0").unwrap(); let _udp_listener = UdpSocket::bind("127.0.0.1:0").unwrap(); let open_port = listener.local_addr().unwrap().port(); let connection = TcpStream::connect(listener.local_addr().unwrap()).unwrap(); let pid = process::id(); let af_flags = AddressFamilyFlags::all(); let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP; let sock_info = get_sockets_info(af_flags, proto_flags).unwrap(); assert!(!sock_info.is_empty()); let sock = sock_info .iter() .find(|s| { s.associated_pids.contains(&pid) && matches!(s.protocol_socket_info, ProtocolSocketInfo::Tcp(TcpSocketInfo { local_port, local_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), state: TcpState::Listen, .. }) if local_port == open_port) }) .unwrap(); assert_eq!( sock.protocol_socket_info, ProtocolSocketInfo::Tcp(TcpSocketInfo { local_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), local_port: open_port, remote_addr: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), remote_port: 0, state: TcpState::Listen, }) ); assert_eq!(sock.associated_pids, vec![pid]); ``` -------------------------------- ### AddressFamilyFlags Blanket Implementations Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.AddressFamilyFlags.html Details blanket implementations applicable to AddressFamilyFlags. ```APIDOC ## AddressFamilyFlags Blanket Implementations ### Description These are blanket implementations that apply to AddressFamilyFlags through generic trait bounds. ### Traits #### `Any` - `type_id(&self) -> TypeId`: Gets the `TypeId` of `self`. #### `Borrow` - `borrow(&self) -> &T`: Immutably borrows from an owned value. #### `BorrowMut` - `borrow_mut(&mut self) -> &mut T`: Mutably borrows from an owned value. #### `CloneToUninit` (Nightly-only experimental) - `clone_to_uninit(&self, dest: *mut u8)`: Performs copy-assignment from `self` to `dest`. #### `From` - `from(t: T) -> T`: Returns the argument unchanged. #### `Into` - `into(self) -> U`: Calls `U::from(self)`. #### `ToOwned` - `Owned`: The resulting type after obtaining ownership. - `to_owned(&self) -> T`: Creates owned data from borrowed data, usually by cloning. - `clone_into(&self, target: &mut T)`: Uses borrowed data to replace owned data, usually by cloning. #### `TryFrom` - `Error`: The type returned in the event of a conversion error. - `try_from(value: U) -> Result>::Error>`: Performs the conversion. #### `TryInto` - `Error`: The type returned in the event of a conversion error. - `try_into(self) -> Result>::Error>`: Performs the conversion. ``` -------------------------------- ### Retrieve socket information in Rust Source: https://docs.rs/netstat2/0.11.2/src/netstat2/integrations/shared_api.rs.html Uses get_sockets_info to collect socket data into a vector, returning an error if any step fails. ```rust 1use crate::integrations::*; 2use crate::types::error::Error; 3use crate::types::*; 4 5/// Retrieve sockets information as a vector. 6/// Short-circuits on any error along the way. 7pub fn get_sockets_info( 8 af_flags: AddressFamilyFlags, 9 proto_flags: ProtocolFlags, 10) -> Result, Error> { 11 iterate_sockets_info(af_flags, proto_flags)?.collect() 12} ``` -------------------------------- ### ProtocolFlags Struct Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.ProtocolFlags.html Details about the ProtocolFlags struct, including its constants and available methods for manipulation and querying. ```APIDOC ## Struct ProtocolFlags ### Description Set of protocols. ### Constants - `TCP`: Represents the TCP protocol flag. - `UDP`: Represents the UDP protocol flag. ### Methods - `empty()`: Returns a flags value with all bits unset. - `all()`: Returns a flags value with all known bits set. - `bits()`: Returns the underlying bits value as a u8. - `from_bits(bits: u8)`: Converts from a bits value. Returns `None` if any unknown bits are set. - `from_bits_truncate(bits: u8)`: Converts from a bits value, unsetting any unknown bits. - `from_bits_retain(bits: u8)`: Converts from a bits value exactly. - `from_name(name: &str)`: Gets a flags value with the bits of a flag with the given name set. Returns `None` if `name` is empty or doesn’t correspond to any named flag. - `is_empty()`: Returns `true` if all bits in this flags value are unset. - `is_all()`: Returns `true` if all known bits in this flags value are set. - `intersects(other: Self)`: Returns `true` if any set bits in `self` are also set in `other`. - `contains(other: Self)`: Returns `true` if all set bits in `self` are also set in `other`. - `insert(other: Self)`: Sets the bits of `other` in `self` (bitwise OR). - `remove(other: Self)`: Removes the bits of `other` from `self` (bitwise AND NOT). - `toggle(other: Self)`: Toggles the bits of `other` in `self` (bitwise XOR). - `set(other: Self, value: bool)`: Sets or removes bits based on the `value` boolean. - `intersection(other: Self)`: Returns the bitwise AND of `self` and `other`. - `union(other: Self)`: Returns the bitwise OR of `self` and `other`. - `difference(other: Self)`: Returns the bitwise AND NOT of `self` and `other`. - `symmetric_difference(other: Self)`: Returns the bitwise XOR of `self` and `other`. - `complement()`: Returns the bitwise negation of `self`, truncating unknown bits. - `iter()`: Yields a set of contained flags values, including unknown bits. - `iter_names()`: Yields a set of contained named flags values, excluding unknown bits. ``` -------------------------------- ### Find UDP Socket by PID and Port Source: https://docs.rs/netstat2/0.11.2/src/netstat2/lib.rs.html Retrieves UDP socket information for a given process ID and local port. Ensures the socket is bound to localhost IPv4. ```rust let af_flags = AddressFamilyFlags::all(); let proto_flags = ProtocolFlags::UDP; let sock_info = get_sockets_info(af_flags, proto_flags).unwrap(); assert!(!sock_info.is_empty()); let sock = sock_info .into_iter() .find(|s| { s.associated_pids.contains(&pid) && matches!(s.protocol_socket_info, ProtocolSocketInfo::Udp(UdpSocketInfo { local_port, local_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), .. }) if local_port == open_port) }) .unwrap(); assert_eq!( sock.protocol_socket_info, ProtocolSocketInfo::Udp(UdpSocketInfo { local_addr: IpAddr::V4(Ipv4Addr::LOCALHOST), local_port: open_port, }) ); assert_eq!(sock.associated_pids, vec![pid]); ``` -------------------------------- ### ProtocolFlags Flag Management Source: https://docs.rs/netstat2/0.11.2/netstat2/struct.ProtocolFlags.html APIs for managing flags within ProtocolFlags, including iteration and conversion. ```APIDOC ## ProtocolFlags Flag Management ### Description This section details the methods for managing and inspecting flags within the `ProtocolFlags` type, including conversion from and to bits, and iteration. ### Constants and Types #### `FLAGS: &'static [Flag]` Represents the set of all defined flags for `ProtocolFlags`. #### `Bits = u8` Defines the underlying integer type used for representing the bits of `ProtocolFlags`. ### Methods #### `bits(&self) -> u8` Returns the underlying `u8` bits value of the `ProtocolFlags`. #### `from_bits_retain(bits: u8) -> ProtocolFlags` Creates a `ProtocolFlags` value directly from a `u8` bits value, retaining all bits. #### `empty() -> Self` Returns a `ProtocolFlags` value with all bits unset. #### `all() -> Self` Returns a `ProtocolFlags` value with all known bits set. #### `contains_unknown_bits(&self) -> bool` Returns `true` if any bits that are not part of the defined flags are set in the `ProtocolFlags` value. #### `from_bits(bits: Self::Bits) -> Option` Attempts to create a `ProtocolFlags` value from a `u8` bits value. Returns `None` if unknown bits are present. #### `from_bits_truncate(bits: Self::Bits) -> Self` Creates a `ProtocolFlags` value from a `u8` bits value, unsetting any unknown bits. #### `from_name(name: &str) -> Option` Attempts to create a `ProtocolFlags` value by setting the flag corresponding to the given name. #### `iter(&self) -> Iter` Returns an iterator over the set flags within the `ProtocolFlags` value. #### `iter_names(&self) -> IterNames` Returns an iterator over the names of the set flags within the `ProtocolFlags` value. #### `is_empty(&self) -> bool` Returns `true` if no bits are set in the `ProtocolFlags` value. #### `is_all(&self) -> bool` Returns `true` if all known bits are set in the `ProtocolFlags` value. #### `intersects(&self, other: Self) -> bool` Returns `true` if any set bits in `self` are also set in `other`. #### `contains(&self, other: Self) -> bool` Returns `true` if all set bits in `other` are also set in `self`. #### `truncate(&mut self)` Removes any unknown bits from the `ProtocolFlags` value in place. ```