Compare commits
7 Commits
6a9567c5de
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d0f5d71ae | ||
|
|
3dc0dc0323 | ||
|
|
711de0c908 | ||
|
|
40cedfa7e1 | ||
|
|
f97d60aecb | ||
|
|
29c1c5af5c | ||
|
|
78276e8243 |
399
src/main.rs
399
src/main.rs
@@ -1,247 +1,180 @@
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::read_to_string;
|
use std::fs::ReadDir;
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::path::PathBuf;
|
||||||
|
use crate::socket::socket::*;
|
||||||
|
|
||||||
//#[derive(PartialEq)]
|
|
||||||
//struct Peer {
|
type Inode = u64;
|
||||||
// ip_address: String,
|
type Pid = u64;
|
||||||
// port: usize,
|
|
||||||
//}
|
|
||||||
|
|
||||||
mod socket;
|
mod socket;
|
||||||
|
|
||||||
//impl Peer {
|
fn get_socket_inodes_by_pid(pid : u64, socket_patt : &Regex) -> HashSet<Inode> {
|
||||||
// fn new() -> Peer {
|
let mut inodes = HashSet::<Inode>::new();
|
||||||
// Peer {
|
let mut path = String::from("/proc/");
|
||||||
// ip_address: "0.0.0.0".to_string(),
|
path.push_str(&pid.to_string());
|
||||||
// port: 0,
|
path.push_str("/fd/");
|
||||||
// }
|
let contents: ReadDir;
|
||||||
// }
|
match fs::read_dir(path) {
|
||||||
//
|
Ok(dir) => {
|
||||||
// fn build_from_hex(hex_ip: &str, hex_port: &str) -> Peer {
|
contents = dir;
|
||||||
// Peer {
|
},
|
||||||
// ip_address: Self::convert_ip_hex_dec(hex_ip),
|
Err(_) => return HashSet::<Inode>::new()
|
||||||
// port: Self::convert_port_hex_dec(hex_port),
|
};
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn convert_ip_hex_dec(ip_address: &str) -> String {
|
|
||||||
// let mut buffer: String = String::new();
|
|
||||||
// let mut ip_quads: Vec<String> = vec![];
|
|
||||||
// for (i, v) in ip_address.chars().enumerate() {
|
|
||||||
// if i % 2 == 1 {
|
|
||||||
// buffer.push(v);
|
|
||||||
// ip_quads.push(
|
|
||||||
// u64::from_str_radix(&buffer, 16)
|
|
||||||
// .expect("upsi 2")
|
|
||||||
// .to_string(),
|
|
||||||
// );
|
|
||||||
// buffer = String::new();
|
|
||||||
// } else {
|
|
||||||
// buffer.push(v);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ip_quads
|
|
||||||
// .iter()
|
|
||||||
// .rev()
|
|
||||||
// .map(|x| x.to_owned())
|
|
||||||
// .collect::<Vec<String>>()
|
|
||||||
// .join(".")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn convert_port_hex_dec(port: &str) -> usize {
|
|
||||||
// usize::from_str_radix(port, 16).expect("upsi 3")
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//#[derive(PartialEq)]
|
|
||||||
//enum SocketState{
|
|
||||||
// Listening,
|
|
||||||
// Established,
|
|
||||||
// Closed
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//#[derive(PartialEq)]
|
|
||||||
//struct Socket {
|
|
||||||
// peer_loc: Peer,
|
|
||||||
// peer_rem: Peer,
|
|
||||||
// pids: Vec<u64>,
|
|
||||||
// state : SocketState,
|
|
||||||
// user : String,
|
|
||||||
// group : String,
|
|
||||||
// inode : u64
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl Socket {
|
|
||||||
// pub fn new(ip_loc: String, port_loc: usize, ip_rem: String, port_rem: usize, pids : Vec<u64>, state : SocketState, user : String, group : String, inode : u64) -> Socket {
|
|
||||||
// Socket {
|
|
||||||
// peer_loc: Peer {
|
|
||||||
// ip_address: ip_loc,
|
|
||||||
// port: port_loc,
|
|
||||||
// },
|
|
||||||
// peer_rem: Peer {
|
|
||||||
// ip_address: ip_rem,
|
|
||||||
// port: port_rem,
|
|
||||||
// },
|
|
||||||
// pids : pids,
|
|
||||||
// state : state,
|
|
||||||
// user : user,
|
|
||||||
// group : group,
|
|
||||||
// inode : inode,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn get_tcp_file_inode(pid: u64) -> u64 {
|
|
||||||
// let mut path = String::from("/proc/");
|
|
||||||
// path.push_str(&pid.to_string());
|
|
||||||
// path.push_str("/net/tcp");
|
|
||||||
//
|
|
||||||
// let inode = fs::metadata(&path)
|
|
||||||
// .expect("Cannot read metadata")
|
|
||||||
// .ino();
|
|
||||||
// return inode;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn check_inode_seen(seen_inodes : &HashSet<u64>, pid : u64) -> bool {
|
|
||||||
// let inode = Socket::get_tcp_file_inode(pid);
|
|
||||||
// return seen_inodes.contains(&inode);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn add_inode(seen_inodes : &mut HashSet<u64>, pid: u64){
|
|
||||||
// let inode = Socket::get_tcp_file_inode(pid);
|
|
||||||
// seen_inodes.insert(inode);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//// fn get_unique_inodes() -> HashSet<u64> {
|
|
||||||
//// let mut unique_inodes = HashSet::new();
|
|
||||||
//// let pattern = Regex::new(r"^[1-4]?[0-9]{1,6}$").expect("kannst kein regex??");
|
|
||||||
//// let dirs = fs::read_dir("/proc").expect("Cannot access /proc");
|
|
||||||
//// for dir in dirs{
|
|
||||||
//// match dir {
|
|
||||||
//// Ok(dir) => {
|
|
||||||
//// if !pattern.is_match(
|
|
||||||
//// &dir.file_name()
|
|
||||||
//// .into_string()
|
|
||||||
//// .expect("Dateiname ist kein gueltiger Unicode-String")[..],
|
|
||||||
//// ) {
|
|
||||||
//// continue;
|
|
||||||
//// }
|
|
||||||
////
|
|
||||||
//// if !unique_inodes.contains(&inode){
|
|
||||||
//// println!("{}", &inode);
|
|
||||||
//// unique_inodes.insert(inode);
|
|
||||||
//// }
|
|
||||||
//// else{
|
|
||||||
//// continue;
|
|
||||||
//// }
|
|
||||||
//// },
|
|
||||||
//// Err(_) => continue,
|
|
||||||
//// };
|
|
||||||
//// }
|
|
||||||
//// unique_inodes
|
|
||||||
//// }
|
|
||||||
//
|
|
||||||
// pub fn to_string (socket : Socket) -> String {
|
|
||||||
// let mut ret_str = String::from("");
|
|
||||||
// ret_str.push_str(&socket.peer_loc.ip_address);
|
|
||||||
// ret_str.push(':');
|
|
||||||
// let loc_port_str = socket.peer_loc.port.clone().to_string();
|
|
||||||
// ret_str.push_str(if socket.peer_loc.port == 0 { "*" } else { &loc_port_str });
|
|
||||||
// ret_str.push(' ');
|
|
||||||
// ret_str.push_str(&socket.peer_rem.ip_address);
|
|
||||||
// ret_str.push(':');
|
|
||||||
// let rem_port_str = socket.peer_rem.port.clone().to_string();
|
|
||||||
// ret_str.push_str(if socket.peer_rem.port == 0 { "*" } else { &rem_port_str });
|
|
||||||
// ret_str.push('\n');
|
|
||||||
// return ret_str;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//// fn convert_line(line : String) -> HashSet<Socket>{
|
|
||||||
//// let mut sockets : HashSet<Socket>;
|
|
||||||
//// let line_vec = line.split_whitespace().collect::<Vec<&str>>();
|
|
||||||
//// conv_str.push_str(&Peer::convert_ip_hex_dec(line_vec[1].split(":").nth(0).unwrap()));
|
|
||||||
//// conv_str.push_str(":");
|
|
||||||
//// let loc_port = Peer::convert_port_hex_dec(line_vec[1].split(":").nth(1).expect("gehtnd3"));
|
|
||||||
//// let loc_port_str = loc_port.clone().to_string();
|
|
||||||
//// conv_str.push_str(if loc_port == 0 { "*" } else { &loc_port_str } );
|
|
||||||
//// conv_str.push_str(" ");
|
|
||||||
//// conv_str.push_str(&Peer::convert_ip_hex_dec(line_vec[2].split(":").nth(0).expect("gehtnd2")));
|
|
||||||
//// conv_str.push_str(":");
|
|
||||||
//// let loc_port = Peer::convert_port_hex_dec(line_vec[2].split(":").nth(1).expect("gehtnd3"));
|
|
||||||
//// let loc_port_str = loc_port.clone().to_string();
|
|
||||||
//// conv_str.push_str(if loc_port == 0 { "*" } else { &loc_port_str } );
|
|
||||||
//// conv_str.push('\n');
|
|
||||||
//// return conv_str;
|
|
||||||
//// }
|
|
||||||
//
|
|
||||||
// fn get_all_unique_socket_infos() -> String {
|
|
||||||
// let pattern = Regex::new(r"^[1-4]?[0-9]{1,6}$").expect("kannst kein regex??");
|
|
||||||
// let contents =
|
|
||||||
// fs::read_dir("/proc/").expect("upsi 4 (proc kann nicht gelesen werden, Berechtigung?)");
|
|
||||||
// let mut seen_inodes = HashSet::<u64>::new();
|
|
||||||
// let mut complete_file: String = String::new();
|
|
||||||
// for dir in contents {
|
|
||||||
// match dir {
|
|
||||||
// Ok(dir) => {
|
|
||||||
// if !pattern.is_match(
|
|
||||||
// &dir.file_name()
|
|
||||||
// .into_string()
|
|
||||||
// .expect("Dateiname ist kein gueltiger Unicode-String")[..],
|
|
||||||
// ) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// let mut path = dir.path().into_os_string().into_string().expect("gehtnd");
|
|
||||||
// path.push_str("/net/tcp");
|
|
||||||
// let pid = &path.split("/").nth(2).expect("gesplittert");
|
|
||||||
// if !Socket::check_inode_seen(&seen_inodes, pid.parse::<u64>().unwrap()) {
|
|
||||||
// Socket::add_inode(& mut seen_inodes, pid.parse::<u64>().unwrap());
|
|
||||||
// let test = &fs::read_to_string(path)
|
|
||||||
// .expect("Could not read proc/pid/net/tcp")
|
|
||||||
// .lines()
|
|
||||||
// .skip(1)
|
|
||||||
//// .map(|x| Socket::convert_line(x.to_string()))
|
|
||||||
// .map(|x| x.to_owned())
|
|
||||||
// .collect::<Vec<String>>()
|
|
||||||
// .join("\n");
|
|
||||||
// complete_file.push_str(test);
|
|
||||||
// }
|
|
||||||
// else{
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// Err(_) => continue,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// // complete_file
|
|
||||||
// complete_file
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn get_pids (complete_file : String) -> Vec<u64>{
|
|
||||||
// return Vec::<u64>::new();
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
fn get_index(line: String, index: usize) -> String {
|
for fd in contents {
|
||||||
line.split_whitespace().nth(index).expect("upsi").to_owned()
|
match fd {
|
||||||
|
Ok(fd) => {
|
||||||
|
let path_name = fs::read_link(fd.path());
|
||||||
|
let name : PathBuf;
|
||||||
|
match path_name {
|
||||||
|
Ok(link) => name = link,
|
||||||
|
Err(_) => continue,
|
||||||
|
}
|
||||||
|
let name2 = name.file_name().unwrap().to_str().unwrap();
|
||||||
|
if socket_patt.is_match(name2) {
|
||||||
|
inodes.insert(socket_patt.captures(name2).unwrap().get(1).unwrap().as_str().parse::<u64>().unwrap());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inodes
|
||||||
}
|
}
|
||||||
|
|
||||||
//fn get_local_addresses_and_ports(proc_string : &mut String){
|
fn get_tcp_file_by_pid(pid: Pid) -> String {
|
||||||
// let local_addresses : Vec<String> = Vec::new();
|
let mut path = String::from("/proc/");
|
||||||
// let tcp_file : String = get_socket_info();
|
path.push_str(&pid.to_string());
|
||||||
// tcp.lines().
|
path.push_str("/net/tcp");
|
||||||
// println!("{:?}", local_addresses);
|
fs::read_to_string(path).unwrap().lines().skip(1).map(|x| x.to_owned()).collect::<Vec<String>>().join("\n")
|
||||||
//}
|
}
|
||||||
|
|
||||||
//fn get_local_port(){
|
fn parse_tcp_file_line(line : String) -> Tcp_Socket {
|
||||||
// proc_string.lines().for_each( |x| {
|
Tcp_Socket::new(Peer::build_from_hex(&get_index(&line.clone(),1)), Peer::build_from_hex(&get_index(&line.clone(),2)), HashSet::<u64>::new(), Tcp_SocketState::new(Peer::convert_port_hex_dec(&get_index(&line.clone(), 3))), get_index(&line, 9).parse().unwrap(), String::from("nix"))
|
||||||
// local_addresses.push(i64::from_str_radix(&get_index_and_convert_to_dec(x.to_owned(), 2), 16))
|
}
|
||||||
// });
|
|
||||||
//}
|
fn get_readable_proc_pids(pid_pattern : &Regex) -> Vec<Pid> {
|
||||||
fn get_remote_address() {}
|
let mut pids = Vec::<Pid>::new();
|
||||||
fn get_remote_port() {}
|
let dirs = fs::read_dir("/proc/").expect("proc kann nicht gelesen werden, Berechtigung?");
|
||||||
|
for dir in dirs {
|
||||||
|
match dir {
|
||||||
|
Ok(dir) => {
|
||||||
|
let name = dir.file_name().into_string().unwrap();
|
||||||
|
if !pid_pattern.is_match(&name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pids.push(name.parse().unwrap())
|
||||||
|
},
|
||||||
|
Err(_) => continue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pids
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_pid_to_tcp_sockets(sockets : &mut Vec<Tcp_Socket>, inodes : HashSet<Inode>, pid : Pid) -> (){
|
||||||
|
let s2 = sockets.clone();
|
||||||
|
for (i, v) in s2.iter().enumerate(){
|
||||||
|
if inodes.contains(&v.inode) {
|
||||||
|
sockets.get_mut(i).unwrap().pids.insert(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_output(combination : Combination, sockets : &Vec<Tcp_Socket>) -> String{
|
||||||
|
let header_loc_ip = "Local Address";
|
||||||
|
let header_loc_port = "Port";
|
||||||
|
let header_rem_ip = "Remote Address";
|
||||||
|
let header_state = "State";
|
||||||
|
let header_rem_port = header_loc_port;
|
||||||
|
let header_pids = "PIDs";
|
||||||
|
let header_inode = "inode";
|
||||||
|
let mut ret_str = String::from("");
|
||||||
|
let mut max_loc_ip_len = header_loc_ip.len();
|
||||||
|
let mut max_loc_port_len = header_loc_port.len();
|
||||||
|
let mut max_rem_ip_len = header_rem_ip.len();
|
||||||
|
let mut max_rem_port_len = max_loc_port_len;
|
||||||
|
let mut max_state_len = header_state.len();
|
||||||
|
let mut max_pids_len = header_pids.len();
|
||||||
|
let mut max_inode_len = header_inode.len();
|
||||||
|
|
||||||
|
sockets.clone().iter().for_each(|x| {
|
||||||
|
let curr_loc_ip_len = x.get_loc_ip_string().len();
|
||||||
|
let curr_loc_port_len = x.get_loc_port_string().len();
|
||||||
|
let curr_rem_ip_len = x.get_rem_ip_string().len();
|
||||||
|
let curr_rem_port_len = x.get_rem_port_string().len();
|
||||||
|
let curr_state_len = x.get_state().to_string().len();
|
||||||
|
let curr_pids_len = pids_to_string(&x.pids).len();
|
||||||
|
let curr_inode_len = x.inode.to_string().len();
|
||||||
|
|
||||||
|
max_loc_ip_len = if curr_loc_ip_len > max_loc_ip_len { curr_loc_ip_len } else { max_loc_ip_len };
|
||||||
|
max_loc_port_len = if curr_loc_port_len > max_loc_port_len { curr_loc_port_len } else { max_loc_port_len };
|
||||||
|
max_rem_ip_len = if curr_rem_ip_len > max_rem_ip_len { curr_rem_ip_len } else { max_rem_ip_len };
|
||||||
|
max_rem_port_len = if curr_rem_port_len > max_rem_port_len { curr_rem_port_len } else { max_rem_port_len };
|
||||||
|
max_state_len = if curr_state_len > max_state_len { curr_state_len } else { max_state_len };
|
||||||
|
max_inode_len = if curr_inode_len > max_inode_len { curr_inode_len } else { max_inode_len };
|
||||||
|
max_pids_len = if curr_pids_len > max_pids_len { curr_pids_len } else { max_pids_len };
|
||||||
|
|
||||||
|
if combination == Combination::tnap{
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
max_loc_ip_len = max_loc_ip_len + 3;
|
||||||
|
max_rem_ip_len = max_rem_ip_len + 3;
|
||||||
|
max_pids_len = max_pids_len + 5;
|
||||||
|
|
||||||
|
match combination {
|
||||||
|
Combination::tna => {
|
||||||
|
ret_str.push_str(&format!("{:>max_state_len$} {:>max_loc_ip_len$}:{:<max_loc_port_len$} {:>max_rem_ip_len$}:{:<max_rem_port_len$}\n", header_state , header_loc_ip , header_loc_port, header_rem_ip,header_rem_port));
|
||||||
|
sockets.clone().iter().for_each(|x| {
|
||||||
|
ret_str.push_str(&format!("{:>max_state_len$} {:>max_loc_ip_len$}:{:<max_loc_port_len$} {:>max_rem_ip_len$}:{:<max_rem_port_len$}", x.get_state().to_string(), x.get_loc_ip_string(), x.get_loc_port_string(), x.get_rem_ip_string(), x.get_rem_port_string()));
|
||||||
|
ret_str.push('\n');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Combination::tnap => {
|
||||||
|
ret_str.push_str(&format!("{:<max_state_len$} {:>max_loc_ip_len$}:{:<max_loc_port_len$} {:>max_rem_ip_len$}:{:<max_rem_port_len$} {:>max_pids_len$}|{:<max_inode_len$}\n", header_state , header_loc_ip , header_loc_port, header_rem_ip,header_rem_port, header_pids, header_inode ));
|
||||||
|
sockets.clone().iter().for_each(|x| {
|
||||||
|
ret_str.push_str(&format!("{:<max_state_len$} {:>max_loc_ip_len$}:{:<max_loc_port_len$} {:>max_rem_ip_len$}:{:<max_rem_port_len$} {:>max_pids_len$}|{:<max_inode_len$}\n", x.get_state().to_string(), x.get_loc_ip_string(), x.get_loc_port_string(), x.get_rem_ip_string(), x.get_rem_port_string(), pids_to_string(&x.pids), x.inode.to_string()))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret_str
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_all_tcp_sockets(pid_pattern : &Regex, socket_patt : &Regex) -> Vec<Tcp_Socket> {
|
||||||
|
let mut sockets = Vec::<Tcp_Socket>::new();
|
||||||
|
let pids = get_readable_proc_pids(pid_pattern);
|
||||||
|
let mut inodes = HashSet::<Inode>::new();
|
||||||
|
pids.iter().for_each(|x| {
|
||||||
|
get_tcp_file_by_pid(*x).lines().for_each(|y| {
|
||||||
|
add_to_tcp_sockets(&mut sockets, parse_tcp_file_line(y.to_owned()));
|
||||||
|
});
|
||||||
|
inodes = get_socket_inodes_by_pid(*x, socket_patt);
|
||||||
|
for (i, v) in sockets.clone().iter().enumerate() {
|
||||||
|
if inodes.contains(&v.inode){
|
||||||
|
add_pid_to_tcp_sockets(&mut sockets, inodes.clone(), *x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sockets
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_to_tcp_sockets(sockets : &mut Vec<Tcp_Socket>, socket: Tcp_Socket) -> (){
|
||||||
|
if !sockets.contains(&socket) {
|
||||||
|
sockets.push(socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_index(line: &String, index: usize) -> String {
|
||||||
|
line.clone().split_whitespace().nth(index).expect("upsi").to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// let complete_file = Socket::get_all_unique_socket_infos();
|
let socket_pattern : Regex = Regex::new(r"socket:\[([0-9]+)]").expect("kannst kein regex?? xd");
|
||||||
|
let pid_pattern = Regex::new(r"^[1-4]?[0-9]{1,6}$").expect("kannst kein regex??");
|
||||||
|
let sockets = get_all_tcp_sockets(&pid_pattern, &socket_pattern);
|
||||||
|
println!("{}", format_output(Combination::tnap, &sockets));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
390
src/socket.rs
390
src/socket.rs
@@ -1,24 +1,16 @@
|
|||||||
|
pub mod socket {
|
||||||
mod Socket {
|
use std::cmp::PartialEq;
|
||||||
|
|
||||||
use regex::Regex;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::read_to_string;
|
use std::hash::{Hash, Hasher};
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
struct Peer {
|
pub struct Peer {
|
||||||
ip_address: String,
|
pub ip_address: String,
|
||||||
port: usize,
|
pub port: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Peer {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Peer {
|
impl Peer {
|
||||||
fn new() -> Peer {
|
fn new() -> Peer {
|
||||||
@@ -28,7 +20,10 @@ mod Socket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_from_hex(hex_ip: &str, hex_port: &str) -> Peer {
|
pub fn build_from_hex(hex_peer: &str) -> Peer {
|
||||||
|
let mut split = hex_peer.split(":");
|
||||||
|
let hex_ip = split.nth(0).unwrap();
|
||||||
|
let hex_port = split.nth(0).unwrap();
|
||||||
Peer {
|
Peer {
|
||||||
ip_address: Self::convert_ip_hex_dec(hex_ip),
|
ip_address: Self::convert_ip_hex_dec(hex_ip),
|
||||||
port: Self::convert_port_hex_dec(hex_port),
|
port: Self::convert_port_hex_dec(hex_port),
|
||||||
@@ -59,59 +54,143 @@ mod Socket {
|
|||||||
.join(".")
|
.join(".")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_port_hex_dec(port: &str) -> usize {
|
pub fn convert_port_hex_dec(port: &str) -> usize {
|
||||||
usize::from_str_radix(port, 16).expect("upsi 3")
|
usize::from_str_radix(port, 16).expect("upsi 3")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_ip_string(&self) -> String {
|
||||||
|
self.clone().ip_address
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
pub fn get_port_string(&self) -> String {
|
||||||
pub enum SocketState{
|
if self.port == 0 {
|
||||||
Listening,
|
String::from("*")
|
||||||
|
} else {
|
||||||
|
self.port.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Debug, Copy)]
|
||||||
|
pub enum Tcp_SocketState {
|
||||||
Established,
|
Established,
|
||||||
Closed
|
SYN_Sent,
|
||||||
|
SYN_Recv,
|
||||||
|
FIN_Wait1,
|
||||||
|
FIN_Wait2,
|
||||||
|
TIME_Wait,
|
||||||
|
Close,
|
||||||
|
Close_Wait,
|
||||||
|
Last_ACK,
|
||||||
|
Listening,
|
||||||
|
Closing,
|
||||||
|
New_SYN_Recv,
|
||||||
|
Bound_Inactive,
|
||||||
|
Max_States,
|
||||||
|
Undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
impl Tcp_SocketState {
|
||||||
pub struct Socket {
|
pub fn new(index: usize) -> Tcp_SocketState {
|
||||||
|
match index {
|
||||||
|
1 => Tcp_SocketState::Established,
|
||||||
|
2 => Tcp_SocketState::SYN_Sent,
|
||||||
|
3 => Tcp_SocketState::SYN_Recv,
|
||||||
|
4 => Tcp_SocketState::FIN_Wait1,
|
||||||
|
5 => Tcp_SocketState::FIN_Wait2,
|
||||||
|
6 => Tcp_SocketState::TIME_Wait,
|
||||||
|
7 => Tcp_SocketState::Close,
|
||||||
|
8 => Tcp_SocketState::Close_Wait,
|
||||||
|
9 => Tcp_SocketState::Last_ACK,
|
||||||
|
10 => Tcp_SocketState::Listening,
|
||||||
|
11 => Tcp_SocketState::Closing,
|
||||||
|
12 => Tcp_SocketState::New_SYN_Recv,
|
||||||
|
13 => Tcp_SocketState::Bound_Inactive,
|
||||||
|
14 => Tcp_SocketState::Max_States,
|
||||||
|
_ => Tcp_SocketState::Undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Tcp_SocketState::Established => String::from("Established"),
|
||||||
|
Tcp_SocketState::SYN_Sent => String::from("SYN_Sent"),
|
||||||
|
Tcp_SocketState::SYN_Recv => String::from("SYN_Recv"),
|
||||||
|
Tcp_SocketState::FIN_Wait1 => String::from("FIN_Wait1"),
|
||||||
|
Tcp_SocketState::FIN_Wait2 => String::from("FIN_Wait2"),
|
||||||
|
Tcp_SocketState::TIME_Wait => String::from("TIME_Wait"),
|
||||||
|
Tcp_SocketState::Close => String::from("Close"),
|
||||||
|
Tcp_SocketState::Close_Wait => String::from("Close_Wait"),
|
||||||
|
Tcp_SocketState::Last_ACK => String::from("Last_ACK"),
|
||||||
|
Tcp_SocketState::Listening => String::from("Listening"),
|
||||||
|
Tcp_SocketState::Closing => String::from("Closing"),
|
||||||
|
Tcp_SocketState::New_SYN_Recv => String::from("New_SYN_Recv"),
|
||||||
|
Tcp_SocketState::Bound_Inactive => String::from("Bound_Inactive"),
|
||||||
|
Tcp_SocketState::Max_States => String::from("Max_States"),
|
||||||
|
Tcp_SocketState::Undefined => String::from("Undefined"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pids_to_string(pids: &HashSet<u64>) -> String {
|
||||||
|
let mut ret_str = String::from("");
|
||||||
|
pids.iter().for_each(|x| {
|
||||||
|
ret_str.push_str(&x.to_string());
|
||||||
|
ret_str.push_str(", ");
|
||||||
|
});
|
||||||
|
let ret_str_len = ret_str.len();
|
||||||
|
if (ret_str_len > 2) {
|
||||||
|
ret_str.drain(ret_str.len() - 2..ret_str.len());
|
||||||
|
}
|
||||||
|
ret_str
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Tcp_Socket {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
return self.inode == other.inode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for Tcp_Socket {}
|
||||||
|
|
||||||
|
impl Hash for Tcp_Socket {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) -> () {
|
||||||
|
self.inode.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Tcp_Socket {
|
||||||
peer_loc: Peer,
|
peer_loc: Peer,
|
||||||
peer_rem: Peer,
|
peer_rem: Peer,
|
||||||
pids: Vec<u64>,
|
pub pids: HashSet<u64>,
|
||||||
state : SocketState,
|
state: Tcp_SocketState,
|
||||||
user : String,
|
pub inode: u64,
|
||||||
group : String,
|
cmdline : String,
|
||||||
inode : u64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Socket {
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
fn clone(&self) -> Self {
|
pub enum Combination {
|
||||||
Self {
|
tnap,
|
||||||
peer_loc : self.peer_loc.clone(),
|
tna,
|
||||||
peer_rem : self.peer_rem .clone(),
|
|
||||||
pids : self.pids.clone(),
|
|
||||||
state : self.state.clone(),
|
|
||||||
user : self.user.clone(),
|
|
||||||
group : self.user.clone(),
|
|
||||||
inode : self.inode.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Socket {
|
impl Tcp_Socket {
|
||||||
pub fn new(ip_loc: &str, port_loc: usize, ip_rem: &str, port_rem: usize, pids : Vec<u64>, state : SocketState, user : &str, group : &str, inode : u64) -> Socket {
|
pub fn new(
|
||||||
Socket {
|
peer_loc: Peer,
|
||||||
peer_loc: Peer {
|
peer_rem: Peer,
|
||||||
ip_address: ip_loc.to_string(),
|
pids: HashSet<u64>,
|
||||||
port: port_loc,
|
state: Tcp_SocketState,
|
||||||
},
|
inode: u64,
|
||||||
peer_rem: Peer {
|
cmdline : String,
|
||||||
ip_address: ip_rem.to_string(),
|
) -> Tcp_Socket {
|
||||||
port: port_rem,
|
Tcp_Socket {
|
||||||
},
|
peer_loc,
|
||||||
pids : pids,
|
peer_rem,
|
||||||
state : state,
|
pids,
|
||||||
user : user.to_string(),
|
state,
|
||||||
group : group.to_string(),
|
inode,
|
||||||
inode : inode,
|
cmdline,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,100 +199,147 @@ mod Socket {
|
|||||||
path.push_str(&pid.to_string());
|
path.push_str(&pid.to_string());
|
||||||
path.push_str("/net/tcp");
|
path.push_str("/net/tcp");
|
||||||
|
|
||||||
let inode = fs::metadata(&path)
|
let inode = fs::metadata(&path).expect("Cannot read metadata").ino();
|
||||||
.expect("Cannot read metadata")
|
inode
|
||||||
.ino();
|
|
||||||
return inode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_inode_seen(seen_inodes : &HashSet<u64>, pid : u64) -> bool {
|
pub fn add_pid(socket: &mut Tcp_Socket, pid: u64) -> () {
|
||||||
let inode = Socket::get_tcp_file_inode(pid);
|
socket.pids.insert(pid);
|
||||||
return seen_inodes.contains(&inode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_inode(seen_inodes : &mut HashSet<u64>, pid: u64){
|
pub fn check_inode_seen(seen_inodes: &HashSet<u64>, pid: u64) -> bool {
|
||||||
let inode = Socket::get_tcp_file_inode(pid);
|
let inode = Tcp_Socket::get_tcp_file_inode(pid);
|
||||||
|
seen_inodes.contains(&inode)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_inode(seen_inodes: &mut HashSet<u64>, pid: u64) {
|
||||||
|
let inode = Tcp_Socket::get_tcp_file_inode(pid);
|
||||||
seen_inodes.insert(inode);
|
seen_inodes.insert(inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string (self) -> String {
|
pub fn get_loc_ip_string(&self) -> String {
|
||||||
let mut ret_str = String::from("");
|
self.peer_loc.get_ip_string()
|
||||||
ret_str.push_str(&self.peer_loc.ip_address);
|
|
||||||
ret_str.push(':');
|
|
||||||
let loc_port_str = self.peer_loc.port.clone().to_string();
|
|
||||||
ret_str.push_str(if self.peer_loc.port == 0 { "*" } else { &loc_port_str });
|
|
||||||
ret_str.push(' ');
|
|
||||||
ret_str.push_str(&self.peer_rem.ip_address);
|
|
||||||
ret_str.push(':');
|
|
||||||
let rem_port_str = self.peer_rem.port.clone().to_string();
|
|
||||||
ret_str.push_str(if self.peer_rem.port == 0 { "*" } else { &rem_port_str });
|
|
||||||
ret_str.push('\n');
|
|
||||||
return ret_str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_all_unique_socket_infos() -> String {
|
pub fn get_loc_port_string(&self) -> String {
|
||||||
let pattern = Regex::new(r"^[1-4]?[0-9]{1,6}$").expect("kannst kein regex??");
|
self.peer_loc.get_port_string()
|
||||||
let contents =
|
|
||||||
fs::read_dir("/proc/").expect("upsi 4 (proc kann nicht gelesen werden, Berechtigung?)");
|
|
||||||
let mut seen_inodes = HashSet::<u64>::new();
|
|
||||||
let mut complete_file: String = String::new();
|
|
||||||
for dir in contents {
|
|
||||||
match dir {
|
|
||||||
Ok(dir) => {
|
|
||||||
if !pattern.is_match(
|
|
||||||
&dir.file_name()
|
|
||||||
.into_string()
|
|
||||||
.expect("Dateiname ist kein gueltiger Unicode-String")[..],
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mut path = dir.path().into_os_string().into_string().expect("gehtnd");
|
|
||||||
path.push_str("/net/tcp");
|
|
||||||
let pid = &path.split("/").nth(2).expect("gesplittert");
|
|
||||||
if !Socket::check_inode_seen(&seen_inodes, pid.parse::<u64>().unwrap()) {
|
|
||||||
Socket::add_inode(& mut seen_inodes, pid.parse::<u64>().unwrap());
|
|
||||||
let test = &fs::read_to_string(path)
|
|
||||||
.expect("Could not read proc/pid/net/tcp")
|
|
||||||
.lines()
|
|
||||||
.skip(1)
|
|
||||||
// .map(|x| Socket::convert_line(x.to_string()))
|
|
||||||
.map(|x| x.to_owned())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("\n");
|
|
||||||
complete_file.push_str(test);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(_) => continue,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// complete_file
|
|
||||||
complete_file
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_rem_ip_string(&self) -> String {
|
||||||
|
self.peer_rem.get_ip_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_rem_port_string(&self) -> String {
|
||||||
|
self.peer_rem.get_port_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn to_string(&self, combination: Combination) -> String {
|
||||||
|
// let mut ret_str = String::from("");
|
||||||
|
// match combination {
|
||||||
|
// Combination::tnap => {
|
||||||
|
// //state rem_ip:rem_port loc_ip:loc_port real|effective-uid real|effective-gid pids(.,.,.,.)
|
||||||
|
// ret_str.push_str(&self.clone().to_string(Combination::tna));
|
||||||
|
// ret_str.push(' ');
|
||||||
|
// ret_str.push_str(&self.user.real.to_string());
|
||||||
|
// ret_str.push('|');
|
||||||
|
// ret_str.push_str(&self.user.effective.to_string());
|
||||||
|
// ret_str.push(' ');
|
||||||
|
// ret_str.push_str(&self.group.real.to_string());
|
||||||
|
// ret_str.push('|');
|
||||||
|
// ret_str.push_str(&self.group.effective.to_string());
|
||||||
|
// ret_str.push_str(&pids_to_string(&self.clone().pids));
|
||||||
|
// ret_str
|
||||||
|
// }
|
||||||
|
// Combination::tna => {
|
||||||
|
// //state rem_ip:rem_port loc_ip:loc_port
|
||||||
|
// ret_str.push_str(&self.state.to_string());
|
||||||
|
// ret_str.push(' ');
|
||||||
|
// ret_str.push_str(&self.peer_loc.ip_address);
|
||||||
|
// ret_str.push(':');
|
||||||
|
// let loc_port_str = self.peer_loc.port.clone().to_string();
|
||||||
|
// ret_str.push_str(if self.peer_loc.port == 0 {
|
||||||
|
// "*"
|
||||||
|
// } else {
|
||||||
|
// &loc_port_str
|
||||||
|
// });
|
||||||
|
// ret_str.push(' ');
|
||||||
|
// ret_str.push_str(&self.peer_rem.ip_address);
|
||||||
|
// ret_str.push(':');
|
||||||
|
// let rem_port_str = self.peer_rem.port.clone().to_string();
|
||||||
|
// ret_str.push_str(if self.peer_rem.port == 0 {
|
||||||
|
// "*"
|
||||||
|
// } else {
|
||||||
|
// &rem_port_str
|
||||||
|
// });
|
||||||
|
// ret_str.push('\n');
|
||||||
|
// ret_str
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn get_state(&self) -> Tcp_SocketState {
|
||||||
|
self.state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::socket::socket::Combination;
|
||||||
|
|
||||||
use crate::socket::Socket::*;
|
fn init_sockets() -> Vec<socket::Tcp_Socket> {
|
||||||
|
let mut sockets = Vec::<socket::Tcp_Socket>::new();
|
||||||
fn init_sockets() -> Vec<Socket> {
|
let root_uid = socket::Id::new(0, 0, 0, 0);
|
||||||
let sockets = Vec::<Socket>::new();
|
let root_gid = root_uid.clone();
|
||||||
sockets.push(Socket::new("93.83.160.12", 21345, "0.0.0.0", 0, Vec::<u64>::new(), Socket::SocketState::Listening, "root", "root", 123123));
|
let mux_uid = socket::Id::new(1000, 1000, 1000, 1000);
|
||||||
sockets.push(Socket::new("195.201.90.97", 8843, "0.0.0.0", 443, Vec::<u64>::new(), Socket::SocketState::Established, "apache", "apache", 218389));
|
let mux_gid = mux_uid.clone();
|
||||||
sockets.push(Socket::new("255.255.255.255", 193193, "0.0.0.0", 8080, Vec::<u64>::new(), Socket::SocketState::Listening, "node", "node", 1301011));
|
let sudo_mux_uid = socket::Id::new(1000, 0, 0, 0);
|
||||||
return sockets;
|
let sudo_mux_gid = root_gid.clone();
|
||||||
|
// sockets.push(socket::Socket::new("93.83.160.12", 21345, "0.0.0.0", 0, Vec::<u64>::new(), socket::SocketState::Listening, root_uid, root_gid, 123123));
|
||||||
|
// sockets.push(socket::Socket::new("195.201.90.97", 8843, "0.0.0.0", 443, Vec::<u64>::new(), socket::SocketState::Established, mux_uid, mux_gid, 218389));
|
||||||
|
// sockets.push(socket::Socket::new("255.255.255.255", 193193, "0.0.0.0", 8080, Vec::<u64>::new(), socket::SocketState::Listening, sudo_mux_uid, sudo_mux_gid, 1301011));
|
||||||
|
sockets
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
#[cfg(test)]
|
fn test_build_from_hex() -> () {
|
||||||
pub fn test_to_string() -> (){
|
let hex_val = "0100007F";
|
||||||
|
assert_eq!(
|
||||||
|
socket::Peer::build_from_hex("0100007F:F168"),
|
||||||
|
socket::Peer {
|
||||||
|
ip_address: "127.0.0.1".to_owned(),
|
||||||
|
port: 61800
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
socket::Peer::build_from_hex("980FB23E:ACCE"),
|
||||||
|
socket::Peer {
|
||||||
|
ip_address: "62.178.15.152".to_owned(),
|
||||||
|
port: 44238
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
socket::Peer::build_from_hex("00000000:30C8"),
|
||||||
|
socket::Peer {
|
||||||
|
ip_address: "0.0.0.0".to_owned(),
|
||||||
|
port: 12488
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_to_string() -> () {
|
||||||
let sockets = init_sockets();
|
let sockets = init_sockets();
|
||||||
assert_eq!("93.83.160.12:21345 0.0.0.0:*", sockets[0].clone().to_string());
|
assert_eq!(
|
||||||
assert_eq!("195.201.90.97:8843 0.0.0.0:443", sockets[1].clone().to_string());
|
"93.83.160.12:21345 0.0.0.0:*\n",
|
||||||
assert_eq!("255.255.255.255:193193 0.0.0.0:8080", sockets[2].clone().to_string());
|
sockets[0].clone().to_string(Combination::tna)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"195.201.90.97:8843 0.0.0.0:443\n",
|
||||||
|
sockets[1].clone().to_string(Combination::tna)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"255.255.255.255:193193 0.0.0.0:8080\n",
|
||||||
|
sockets[2].clone().to_string(Combination::tna)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user