in nfm-controller/src/kubernetes/remote_nat_resolver.rs [131:176]
fn parse_and_save_conntrack_line(&mut self, line: &str) -> Option<()> {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() < 14 {
// safety check
return Some(());
}
if parts[2] != "tcp" {
return Some(());
};
if parts[10].starts_with('[') {
// ipv4 2 tcp 6 118 SYN_SENT src=172.19.107.118 dst=2.2.2.2 sport=33424 dport=80 [UNREPLIED] src=2.2.2.2 dst=172.19.107.118 sport=80 dport=33424 mark=0 use=1
return Some(()); // means this isnt an established connection no need to track
}
let ip_version = parts[0].to_string();
let local_ip_that_sends_the_packet = parts[6].split('=').nth(1)?.to_string();
let local_port_that_sends_the_packet = parts[8].split('=').nth(1)?.parse().ok()?;
let remote_ip_we_think_we_send_to = parts[7].split('=').nth(1)?.to_string();
let remote_ip_that_hits_the_wire = parts[10].split('=').nth(1)?.to_string();
let remote_port_that_hits_the_wire = parts[12].split('=').nth(1)?.parse().ok()?;
if remote_ip_we_think_we_send_to != remote_ip_that_hits_the_wire {
let (local_ip, remote_ip) = match ip_version.as_str() {
"ipv4" => (
Self::string_to_ipv4(&local_ip_that_sends_the_packet).unwrap(),
Self::string_to_ipv4(&remote_ip_that_hits_the_wire).unwrap(),
),
"ipv6" => (
Self::string_to_ipv6(&local_ip_that_sends_the_packet).unwrap(),
Self::string_to_ipv6(&remote_ip_that_hits_the_wire).unwrap(),
),
_ => return None,
};
self.insert(
RemoteNatLookupEntry {
local_ip,
local_port: local_port_that_sends_the_packet,
},
RemoteNatEntry {
remote_ip_actual: remote_ip,
remote_port_actual: remote_port_that_hits_the_wire,
},
);
self.remote_nat_entries_detected += 1;
}
Some(())
}