use iptables; use regex::Regex; use std::collections::HashSet; use std::io; #[derive(PartialEq,Eq,Debug,Hash)] pub struct Port { proto: String, number: u16, } #[derive(Debug)] pub struct FirewallError(String); impl From for FirewallError { fn from(error: iptables::error::IPTError) -> Self { FirewallError(error.to_string()) } } pub fn setup(ipt: &iptables::IPTables) -> Result<(), FirewallError> { ipt.new_chain("filter", "DIPLONAT")?; ipt.insert("filter", "INPUT", "-j DIPLONAT", 1)?; Ok(()) } pub fn open_ports(ipt: &iptables::IPTables, ports: Vec) -> Result<(), FirewallError> { for p in ports { ipt.append("filter", "DIPLONAT", &format!("-p {} --dport {} -j ACCEPT", p.proto, p.number))?; } Ok(()) } pub fn get_opened_ports(ipt: &iptables::IPTables) -> Result, FirewallError> { let mut opened_ports: HashSet = HashSet::new(); let list = ipt.list("filter", "DIPLONAT")?; let re = Regex::new(r"\-A.*? \-p (\w+).*\-\-dport (\d+).*?\-j ACCEPT").unwrap(); for i in list { let caps = re.captures(&i); match caps { Some(c) => { let raw_proto = c.get(1).unwrap(); let raw_port = c.get(2).unwrap(); let proto = String::from(raw_proto.as_str()); let number = String::from(raw_port.as_str()).parse::().unwrap(); opened_ports.insert( Port { proto, number } ); }, _ => {} } } Ok(opened_ports) } pub fn cleanup(ipt: &iptables::IPTables) -> Result<(), FirewallError> { ipt.flush_chain("filter", "DIPLONAT")?; ipt.delete("filter", "INPUT", "-j DIPLONAT")?; ipt.delete_chain("filter", "DIPLONAT")?; Ok(()) } /* fn main() { let ipt = iptables::new(false).unwrap(); setup(&ipt); let mut test: HashSet = HashSet::new(); test.insert(Port { proto: String::from("tcp"), number: 443 }); let a = get_opened_ports(&ipt); let l = test.difference(&a).collect::>(); println!("{:?}", l); } */