netstat/integrations/linux/
api.rs1use integrations::linux::netlink_iterator::*;
2use integrations::linux::procfs::*;
3use libc::*;
4use types::*;
5
6pub fn iterate_sockets_info(
8 af_flags: AddressFamilyFlags,
9 proto_flags: ProtocolFlags,
10) -> Result<impl Iterator<Item = Result<SocketInfo, Error>>, Error> {
11 let ipv4 = af_flags.contains(AddressFamilyFlags::IPV4);
12 let ipv6 = af_flags.contains(AddressFamilyFlags::IPV6);
13 let tcp = proto_flags.contains(ProtocolFlags::TCP);
14 let udp = proto_flags.contains(ProtocolFlags::UDP);
15 let mut iterators = Vec::with_capacity(4);
16 unsafe {
17 if ipv4 {
18 if tcp {
19 iterators.push(NetlinkIterator::new(AF_INET as u8, IPPROTO_TCP as u8)?);
20 }
21 if udp {
22 iterators.push(NetlinkIterator::new(AF_INET as u8, IPPROTO_UDP as u8)?);
23 }
24 }
25 if ipv6 {
26 if tcp {
27 iterators.push(NetlinkIterator::new(AF_INET6 as u8, IPPROTO_TCP as u8)?);
28 }
29 if udp {
30 iterators.push(NetlinkIterator::new(AF_INET6 as u8, IPPROTO_UDP as u8)?);
31 }
32 }
33 }
34 Ok(attach_pids(iterators.into_iter().flatten()))
35}
36
37fn attach_pids(
38 sockets_info: impl Iterator<Item = Result<SocketInfo, Error>>,
39) -> impl Iterator<Item = Result<SocketInfo, Error>> {
40 let mut pids_by_inode = build_hash_of_pids_by_inode();
41 sockets_info.map(move |r| {
42 r.map(|socket_info| SocketInfo {
43 associated_pids: pids_by_inode
44 .remove(&socket_info.inode)
45 .unwrap_or_default()
46 .iter()
47 .map(|x| *x)
48 .collect(),
49 ..socket_info
50 })
51 })
52}