base commit
This commit is contained in:
32
net-logger/Cargo.toml
Normal file
32
net-logger/Cargo.toml
Normal file
@@ -0,0 +1,32 @@
|
||||
[package]
|
||||
name = "net-logger"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
aya = "0.12"
|
||||
aya-log = "0.2"
|
||||
clap = { version = "4.1", features = ["derive"] }
|
||||
net-logger-common = { path = "../net-logger-common", features = ["user"] }
|
||||
anyhow = "1"
|
||||
env_logger = "0.10"
|
||||
libc = "0.2"
|
||||
log = "0.4"
|
||||
tokio = { version = "1.25", features = [
|
||||
"macros",
|
||||
"rt",
|
||||
"rt-multi-thread",
|
||||
"net",
|
||||
"signal",
|
||||
] }
|
||||
bytes = "*"
|
||||
network-types = "0.0.6"
|
||||
elasticsearch = "8.17.0-alpha.1"
|
||||
serde_json = "*"
|
||||
serde = "*"
|
||||
chrono = "*"
|
||||
|
||||
[[bin]]
|
||||
name = "net-logger"
|
||||
path = "src/main.rs"
|
||||
252
net-logger/src/clasificator/ip_group.rs
Normal file
252
net-logger/src/clasificator/ip_group.rs
Normal file
@@ -0,0 +1,252 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::{Ipv4Addr, Ipv6Addr},
|
||||
time::SystemTime,
|
||||
};
|
||||
|
||||
use crate::utils::ip::print_proto;
|
||||
use network_types::ip::{IpProto, Ipv4Hdr};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ConectionCoreAtom {
|
||||
pub len: u128,
|
||||
pub ip4_list: Vec<IpAtom<Ipv4Addr>>,
|
||||
pub ip6_list: Vec<IpAtom<Ipv6Addr>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct IpAtom<IpType> {
|
||||
len: u128,
|
||||
ip_local: IpType,
|
||||
port_local: u16,
|
||||
ip_remote: IpType,
|
||||
port_remote: u16,
|
||||
//pub proto_len: HashMap<u8, u128>
|
||||
pub proto_len: Vec<(u8, u128)>,
|
||||
}
|
||||
|
||||
impl ConectionCoreAtom {
|
||||
pub fn new() -> Self {
|
||||
ConectionCoreAtom {
|
||||
len: 0,
|
||||
ip4_list: Vec::new(),
|
||||
ip6_list: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addv4(
|
||||
&mut self,
|
||||
source_ip: u32,
|
||||
dest_ip: u32,
|
||||
source_port: u16,
|
||||
dest_port: u16,
|
||||
protocol: IpProto,
|
||||
size: u16,
|
||||
) {
|
||||
self.len += size as u128;
|
||||
let source_ip_format = Ipv4Addr::from_bits(source_ip);
|
||||
let dest_ip_format = Ipv4Addr::from_bits(dest_ip);
|
||||
let local_ip;
|
||||
let remote_ip;
|
||||
let local_port;
|
||||
let remote_port;
|
||||
if source_ip_format.is_private() {
|
||||
local_ip = source_ip_format;
|
||||
remote_ip = dest_ip_format;
|
||||
local_port = source_port;
|
||||
remote_port = dest_port;
|
||||
} else {
|
||||
local_ip = dest_ip_format;
|
||||
remote_ip = source_ip_format;
|
||||
local_port = dest_port;
|
||||
remote_port = dest_port;
|
||||
}
|
||||
match self.check_packagev4(local_ip, remote_ip, local_port, remote_port) {
|
||||
Some(ip_atom) => {
|
||||
ip_atom.add(protocol, size as u128);
|
||||
}
|
||||
None => {
|
||||
let mut ip_atom = IpAtom::new_ip(local_ip, remote_ip, local_port, remote_port);
|
||||
ip_atom.add(protocol, size as u128);
|
||||
self.ip4_list.push(ip_atom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addv6(
|
||||
&mut self,
|
||||
source_ip: Ipv6Addr,
|
||||
dest_ip: Ipv6Addr,
|
||||
source_port: u16,
|
||||
dest_port: u16,
|
||||
protocol: IpProto,
|
||||
size: u16,
|
||||
) {
|
||||
self.len += size as u128;
|
||||
let local_ip;
|
||||
let remote_ip;
|
||||
let local_port;
|
||||
let remote_port;
|
||||
if source_ip.is_unique_local() {
|
||||
local_ip = source_ip;
|
||||
local_port = source_port;
|
||||
remote_ip = dest_ip;
|
||||
remote_port = dest_port;
|
||||
} else {
|
||||
local_ip = dest_ip;
|
||||
local_port = dest_port;
|
||||
remote_ip = source_ip;
|
||||
remote_port = source_port;
|
||||
}
|
||||
match self.check_packagev6(local_ip, remote_ip, local_port, remote_port) {
|
||||
Some(ip_atom) => {
|
||||
ip_atom.add(protocol, size as u128);
|
||||
}
|
||||
None => {
|
||||
let mut ip_atom = IpAtom::new_ip(local_ip, remote_ip, local_port, remote_port);
|
||||
ip_atom.add(protocol, size as u128);
|
||||
self.ip6_list.push(ip_atom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_packagev4(
|
||||
&mut self,
|
||||
local_ip: Ipv4Addr,
|
||||
remote_ip: Ipv4Addr,
|
||||
local_port: u16,
|
||||
remote_port: u16,
|
||||
) -> Option<&mut IpAtom<Ipv4Addr>> {
|
||||
let mut index = 0;
|
||||
loop {
|
||||
match self.ip4_list.get(index) {
|
||||
Some(ip) => {
|
||||
if ip.eq_splited(local_ip, remote_ip, local_port, remote_port) {
|
||||
return self.ip4_list.get_mut(index);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn check_packagev6(
|
||||
&mut self,
|
||||
local_ip: Ipv6Addr,
|
||||
remote_ip: Ipv6Addr,
|
||||
local_port: u16,
|
||||
remote_port: u16,
|
||||
) -> Option<&mut IpAtom<Ipv6Addr>> {
|
||||
let index = 0;
|
||||
loop {
|
||||
match self.ip6_list.get(index) {
|
||||
Some(ip) => {
|
||||
if ip.eq_splited(local_ip, remote_ip, local_port, remote_port) {
|
||||
return self.ip6_list.get_mut(index);
|
||||
}
|
||||
}
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_json(&self, timestamp: String) -> Value {
|
||||
json!({
|
||||
"@timestamp" : timestamp,
|
||||
"ips_v4" : self.ip4_list,
|
||||
"ips_v6" : self.ip6_list,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) -> Self {
|
||||
let old_len = self.len;
|
||||
self.len = 0;
|
||||
Self {
|
||||
len: old_len,
|
||||
ip4_list: self.ip4_list.drain(..).collect(),
|
||||
ip6_list: self.ip6_list.drain(..).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/*fn create_ipv4(&mut self, source_ip: u32, dest_ip: u32) {
|
||||
let source_ip_format = Ipv4Addr::from_bits(source_ip);
|
||||
let dest_ip_format = Ipv4Addr::from_bits(dest_ip);
|
||||
self.ip4_list.push(if source_ip_format.is_private() {
|
||||
IpAtom::new_ip(source_ip_format, dest_ip_format)
|
||||
} else {
|
||||
IpAtom::new_ip(dest_ip_format, source_ip_format)
|
||||
})
|
||||
}
|
||||
|
||||
fn create_ipv6(&mut self, source_ip: Ipv6Addr, dest_ip: Ipv6Addr) {
|
||||
self.ip6_list.push(if source_ip.is_unique_local() {
|
||||
IpAtom::new_ip(source_ip, dest_ip)
|
||||
} else {
|
||||
IpAtom::new_ip(dest_ip, source_ip)
|
||||
});
|
||||
}*/
|
||||
}
|
||||
|
||||
impl<IpType: Eq> IpAtom<IpType> {
|
||||
pub fn new_ip(local_ip: IpType, remote_ip: IpType, local_port: u16, remote_port: u16) -> Self {
|
||||
IpAtom {
|
||||
len: 0,
|
||||
ip_local: local_ip,
|
||||
port_local: local_port,
|
||||
ip_remote: remote_ip,
|
||||
port_remote: remote_port,
|
||||
proto_len: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
//hashmap can be less efficient
|
||||
/*pub fn add(&mut self,protocol: IpProto, size: u128) {
|
||||
self.len+=size;
|
||||
match self.proto_len.get_mut(&(protocol as u8)) {
|
||||
Some(l) => {
|
||||
*l+=size;
|
||||
},
|
||||
None => {
|
||||
self.proto_len.insert(protocol as u8,size);
|
||||
},
|
||||
};
|
||||
}*/
|
||||
|
||||
pub fn add(&mut self, protocol: IpProto, size: u128) {
|
||||
self.len += size;
|
||||
let mut index = 0;
|
||||
loop {
|
||||
match self.proto_len.get_mut(index) {
|
||||
Some(proto) => {
|
||||
if proto.0 == protocol as u8 {
|
||||
proto.1 += size;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
self.proto_len.push((protocol as u8, size));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eq_splited(
|
||||
&self,
|
||||
local_ip: IpType,
|
||||
remote_ip: IpType,
|
||||
local_port: u16,
|
||||
remote_port: u16,
|
||||
) -> bool {
|
||||
((self.ip_local == local_ip && self.port_local == local_port)
|
||||
&& (self.ip_remote == remote_ip && self.port_remote == remote_port))
|
||||
|| ((self.ip_local == remote_ip && self.port_local == remote_port)
|
||||
&& (self.ip_remote == local_ip && self.port_remote == local_port))
|
||||
}
|
||||
}
|
||||
50
net-logger/src/clasificator/ip_wrapper.rs
Normal file
50
net-logger/src/clasificator/ip_wrapper.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
|
||||
pub struct Ip4Wrapper {
|
||||
raw: Ipv4Addr,
|
||||
}
|
||||
|
||||
pub struct Ip6Wrapper {
|
||||
raw: Ipv6Addr,
|
||||
}
|
||||
|
||||
pub trait IpWrapper<IpType> {
|
||||
fn is_private(&self) -> bool;
|
||||
fn get_raw(&self) -> IpType;
|
||||
}
|
||||
|
||||
impl Ip4Wrapper {
|
||||
pub fn new(ip: u32) -> Self {
|
||||
Self {
|
||||
raw: Ipv4Addr::from_bits(ip),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ip6Wrapper {
|
||||
pub fn new(ip: Ipv6Addr) -> Self {
|
||||
Self {
|
||||
raw: ip,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IpWrapper<Ipv4Addr> for Ip4Wrapper {
|
||||
fn is_private(&self) -> bool {
|
||||
self.raw.is_private()
|
||||
}
|
||||
|
||||
fn get_raw(&self) -> Ipv4Addr {
|
||||
self.raw
|
||||
}
|
||||
}
|
||||
|
||||
impl IpWrapper<Ipv6Addr> for Ip6Wrapper {
|
||||
fn is_private(&self) -> bool {
|
||||
self.raw.is_unique_local()
|
||||
}
|
||||
|
||||
fn get_raw(&self) -> Ipv6Addr {
|
||||
self.raw
|
||||
}
|
||||
}
|
||||
3
net-logger/src/clasificator/mod.rs
Normal file
3
net-logger/src/clasificator/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod ip_group;
|
||||
mod ip_wrapper;
|
||||
pub mod store;
|
||||
96
net-logger/src/clasificator/store.rs
Normal file
96
net-logger/src/clasificator/store.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
use network_types::ip::IpProto;
|
||||
|
||||
use crate::elk::elasticsearch::ElasticConection;
|
||||
|
||||
use super::ip_group::ConectionCoreAtom;
|
||||
use std::{
|
||||
future::IntoFuture,
|
||||
net::Ipv6Addr,
|
||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
pub struct net_stats_storage {
|
||||
connections_store: ConectionCoreAtom,
|
||||
elastic_connection: ElasticConection,
|
||||
old_connections: Vec<ConectionCoreAtom>,
|
||||
last_insert: SystemTime,
|
||||
}
|
||||
|
||||
impl net_stats_storage {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
connections_store: ConectionCoreAtom::new(),
|
||||
elastic_connection: ElasticConection::new().unwrap(),
|
||||
old_connections: Vec::new(),
|
||||
last_insert: SystemTime::now(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn addv4(
|
||||
&mut self,
|
||||
source_ip: u32,
|
||||
dest_ip: u32,
|
||||
source_port: u16,
|
||||
dest_port: u16,
|
||||
protocol: IpProto,
|
||||
size: u16,
|
||||
) {
|
||||
self.store_or_not().await;
|
||||
|
||||
self.connections_store
|
||||
.addv4(source_ip, dest_ip, source_port, dest_port, protocol, size);
|
||||
}
|
||||
|
||||
pub async fn addv6(
|
||||
&mut self,
|
||||
source_ip: Ipv6Addr,
|
||||
dest_ip: Ipv6Addr,
|
||||
source_port: u16,
|
||||
dest_port: u16,
|
||||
protocol: IpProto,
|
||||
size: u16,
|
||||
) {
|
||||
self.store_or_not().await;
|
||||
|
||||
self.connections_store
|
||||
.addv6(source_ip, dest_ip, source_port, dest_port, protocol, size);
|
||||
}
|
||||
|
||||
pub async fn store_or_not(&mut self) {
|
||||
if self
|
||||
.last_insert
|
||||
.duration_since(SystemTime::now())
|
||||
.unwrap_or(Duration::from_secs(2))
|
||||
.as_secs()
|
||||
> 2
|
||||
|| self.connections_store.len > 200000
|
||||
{
|
||||
self.store_in_elastic().await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn store_in_elastic(&mut self) {
|
||||
self.old_connections.push(self.connections_store.reset());
|
||||
self.connections_store = ConectionCoreAtom::new();
|
||||
println!("entra:{}", self.old_connections.len());
|
||||
for con in &self.old_connections {
|
||||
println!(
|
||||
"datos:{}",
|
||||
chrono::offset::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true)
|
||||
);
|
||||
match self
|
||||
.elastic_connection
|
||||
.send(con.generate_json(
|
||||
chrono::offset::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true),
|
||||
))
|
||||
.await
|
||||
{
|
||||
Ok(_) => continue,
|
||||
Err(_) => {
|
||||
println!("No va");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
71
net-logger/src/elk/elasticsearch.rs
Normal file
71
net-logger/src/elk/elasticsearch.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use elasticsearch::auth::Credentials;
|
||||
use elasticsearch::http::transport::SingleNodeConnectionPool;
|
||||
use elasticsearch::http::transport::TransportBuilder;
|
||||
use elasticsearch::http::Url;
|
||||
use elasticsearch::Elasticsearch;
|
||||
use elasticsearch::IndexParts;
|
||||
use serde_json::Value;
|
||||
use std::fmt;
|
||||
|
||||
pub struct ElasticConection {
|
||||
conection: Elasticsearch,
|
||||
}
|
||||
|
||||
pub struct ElasticConErr {
|
||||
content: String,
|
||||
}
|
||||
|
||||
impl ElasticConection {
|
||||
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let url = Url::parse("http://elastic_ip:9200")?;
|
||||
let credentials = Credentials::Basic("elastic".into(), "password".into());
|
||||
let connection_pool = SingleNodeConnectionPool::new(url);
|
||||
let transport = TransportBuilder::new(connection_pool)
|
||||
.auth(credentials)
|
||||
.build()?;
|
||||
Ok(Self {
|
||||
conection: Elasticsearch::new(transport),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn send(&self, data: Value) -> Result<(), ElasticConErr> {
|
||||
println!("aquí tambi'en entra");
|
||||
let raw_response = self
|
||||
.conection
|
||||
.index(IndexParts::Index("netlogger-0.1"))
|
||||
.body(data)
|
||||
.send()
|
||||
.await;
|
||||
let response = match raw_response {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(ElasticConErr {
|
||||
content: e.to_string(),
|
||||
})
|
||||
}
|
||||
};
|
||||
let status_code = response.status_code();
|
||||
match status_code.clone().is_success() {
|
||||
true => Ok(()),
|
||||
false => {
|
||||
let err_ret = match response.text().await {
|
||||
Ok(ret) => ret,
|
||||
Err(_e) => status_code.as_str().to_string(),
|
||||
};
|
||||
Err(ElasticConErr { content: err_ret })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ElasticConErr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.content)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ElasticConErr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.content)
|
||||
}
|
||||
}
|
||||
1
net-logger/src/elk/mod.rs
Normal file
1
net-logger/src/elk/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod elasticsearch;
|
||||
159
net-logger/src/main.rs
Normal file
159
net-logger/src/main.rs
Normal file
@@ -0,0 +1,159 @@
|
||||
use anyhow::Context;
|
||||
use aya::maps::AsyncPerfEventArray;
|
||||
use aya::programs::{Xdp, XdpFlags};
|
||||
use aya::util::online_cpus;
|
||||
use aya::{include_bytes_aligned, Bpf};
|
||||
use aya_log::BpfLogger;
|
||||
use aya_log::Formatter;
|
||||
use bytes::BytesMut;
|
||||
use clap::Parser;
|
||||
use log::{debug, info, warn};
|
||||
use net_logger_common::Event;
|
||||
use network_types::eth::EtherType;
|
||||
use tokio::signal;
|
||||
mod clasificator;
|
||||
mod elk;
|
||||
mod utils;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
struct Opt {
|
||||
#[clap(short, long, default_value = "lo")]
|
||||
iface: String,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), anyhow::Error> {
|
||||
env_logger::init();
|
||||
|
||||
// Bump the memlock rlimit. This is needed for older kernels that don't use the
|
||||
// new memcg based accounting, see https://lwn.net/Articles/837122/
|
||||
let rlim = libc::rlimit {
|
||||
rlim_cur: libc::RLIM_INFINITY,
|
||||
rlim_max: libc::RLIM_INFINITY,
|
||||
};
|
||||
let ret = unsafe { libc::setrlimit(libc::RLIMIT_MEMLOCK, &rlim) };
|
||||
if ret != 0 {
|
||||
debug!("remove limit on locked memory failed, ret is: {}", ret);
|
||||
}
|
||||
|
||||
if let Err(e) = load_bpf().await {
|
||||
eprintln!("error: {:#}", e);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn load_bpf() -> Result<(), aya::BpfError> {
|
||||
// This will include your eBPF object file as raw bytes at compile-time and load it at
|
||||
// runtime. This approach is recommended for most real-world use cases. If you would
|
||||
// like to specify the eBPF program at runtime rather than at compile-time, you can
|
||||
// reach for `Bpf::load_file` instead.
|
||||
#[cfg(debug_assertions)]
|
||||
let mut bpf = Bpf::load(include_bytes_aligned!(
|
||||
"../../target/bpfel-unknown-none/debug/net-logger"
|
||||
))?;
|
||||
#[cfg(not(debug_assertions))]
|
||||
let mut bpf = Bpf::load(include_bytes_aligned!(
|
||||
"../../target/bpfel-unknown-none/release/net-logger"
|
||||
))?;
|
||||
if let Err(e) = BpfLogger::init(&mut bpf) {
|
||||
// This can happen if you remove all log statements from your eBPF program.
|
||||
warn!("failed to initialize eBPF logger: {}", e);
|
||||
}
|
||||
|
||||
proces_events_xdp(bpf).await
|
||||
}
|
||||
|
||||
async fn proces_events_xdp(mut bpf: Bpf) -> Result<(), aya::BpfError> {
|
||||
let opt = Opt::parse();
|
||||
|
||||
// This will include your eBPF object file as raw bytes at compile-time and load it at
|
||||
// runtime. This approach is recommended for most real-world use cases. If you would
|
||||
// like to specify the eBPF program at runtime rather than at compile-time, you can
|
||||
// reach for `Bpf::load_file` instead.
|
||||
|
||||
//let program : &mut SockOps = bpf.program_mut("get_package_data").unwrap().try_into().unwrap();
|
||||
//program.load().unwrap();
|
||||
let program: &mut Xdp = bpf.program_mut("net_logger").unwrap().try_into().unwrap();
|
||||
program.load().unwrap();
|
||||
program.attach(&opt.iface, XdpFlags::default())
|
||||
.context("failed to attach the XDP program with default flags - try changing XdpFlags::default() to XdpFlags::SKB_MODE").unwrap();
|
||||
let cpus = online_cpus().unwrap();
|
||||
let num_cpus = cpus.len();
|
||||
//let events_raw = bpf.map_mut("EVENTS");
|
||||
let mut events: AsyncPerfEventArray<_> = bpf
|
||||
.take_map("EVENTS")
|
||||
.context("failed to map QUERY_RING")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
for cpu in cpus {
|
||||
let mut buf = events.open(cpu, None).unwrap();
|
||||
|
||||
tokio::task::spawn(async move {
|
||||
let mut buffers = (0..num_cpus)
|
||||
.map(|_| BytesMut::with_capacity(10240))
|
||||
.collect::<Vec<_>>();
|
||||
let mut con = clasificator::store::net_stats_storage::new();
|
||||
loop {
|
||||
let events = buf.read_events(&mut buffers).await.unwrap();
|
||||
for i in 0..events.read {
|
||||
// get timestamp
|
||||
//let now = Local::now();
|
||||
|
||||
// read the event
|
||||
let buf = &mut buffers[i];
|
||||
let ptr = buf.as_ptr() as *const Event;
|
||||
let data = unsafe { ptr.read_unaligned() };
|
||||
// parse out the data
|
||||
match data.ipv {
|
||||
EtherType::Ipv4 => {
|
||||
println!("source ip:{}, source port:{}, dest ip:{}, dest port:{}, proto:{}, size: {}",
|
||||
aya_log::Ipv4Formatter::format(data.source_ipv4),
|
||||
data.source_port,
|
||||
aya_log::Ipv4Formatter::format(data.dest_ipv4),
|
||||
data.dest_port,
|
||||
utils::ip::print_proto(data.proto),
|
||||
data.len);
|
||||
con.addv4(
|
||||
data.source_ipv4,
|
||||
data.dest_ipv4,
|
||||
data.source_port,
|
||||
data.dest_port,
|
||||
data.proto,
|
||||
data.len,
|
||||
)
|
||||
.await;
|
||||
//println!("package size:{}, ips:{}", con.len, con.ip4_list.get(con.ip4_list.len()-1).unwrap().proto_len.get(0).unwrap_or(&(0,0)).1);
|
||||
}
|
||||
EtherType::Ipv6 => {
|
||||
println!("source ip:{}, source port:{}, dest ip:{}, dest port:{}, proto:{}, size: {}",
|
||||
aya_log::Ipv6Formatter::format(data.source_ipv6),
|
||||
data.source_port,
|
||||
aya_log::Ipv6Formatter::format(data.dest_ipv6),
|
||||
data.dest_port,
|
||||
utils::ip::print_proto(data.proto),
|
||||
data.len);
|
||||
con.addv6(
|
||||
data.source_ipv6,
|
||||
data.dest_ipv6,
|
||||
data.source_port,
|
||||
data.dest_port,
|
||||
data.proto,
|
||||
data.len,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
_ => println!("result not coverd"),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
info!("Waiting for Ctrl-C...");
|
||||
signal::ctrl_c().await.unwrap();
|
||||
info!("Exiting...");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
154
net-logger/src/utils/ip.rs
Normal file
154
net-logger/src/utils/ip.rs
Normal file
@@ -0,0 +1,154 @@
|
||||
use network_types::ip::IpProto;
|
||||
|
||||
pub fn print_proto(proto: IpProto) -> String {
|
||||
String::from(match proto {
|
||||
IpProto::HopOpt => "HopOpt",
|
||||
IpProto::Icmp => "Icmp",
|
||||
IpProto::Igmp => "Igmp",
|
||||
IpProto::Ggp => "Ggp",
|
||||
IpProto::Ipv4 => "Ipv4",
|
||||
IpProto::Stream => "Stream",
|
||||
IpProto::Tcp => "Tcp",
|
||||
IpProto::Cbt => "Cbt",
|
||||
IpProto::Egp => "Egp",
|
||||
IpProto::Igp => "Igp",
|
||||
IpProto::BbnRccMon => "BbnRccMon",
|
||||
IpProto::NvpII => "NvpII",
|
||||
IpProto::Pup => "Pup",
|
||||
IpProto::Argus => "Argus",
|
||||
IpProto::Emcon => "Emcon",
|
||||
IpProto::Xnet => "Xnet",
|
||||
IpProto::Chaos => "Chaos",
|
||||
IpProto::Udp => "Udp",
|
||||
IpProto::Mux => "Mux",
|
||||
IpProto::DcnMeas => "DcnMeas",
|
||||
IpProto::Hmp => "Hmp",
|
||||
IpProto::Prm => "Prm",
|
||||
IpProto::Idp => "Idp",
|
||||
IpProto::Trunk1 => "Trunk1",
|
||||
IpProto::Trunk2 => "Trunk2",
|
||||
IpProto::Leaf1 => "Leaf1",
|
||||
IpProto::Leaf2 => "Leaf2",
|
||||
IpProto::Rdp => "Rdp",
|
||||
IpProto::Irtp => "Irtp",
|
||||
IpProto::Tp4 => "Tp4",
|
||||
IpProto::Netblt => "Netblt",
|
||||
IpProto::MfeNsp => "MfeNsp",
|
||||
IpProto::MeritInp => "MeritInp",
|
||||
IpProto::Dccp => "Dccp",
|
||||
IpProto::ThirdPartyConnect => "ThirdPartyConnect",
|
||||
IpProto::Idpr => "Idpr",
|
||||
IpProto::Xtp => "Xtp",
|
||||
IpProto::Ddp => "Ddp",
|
||||
IpProto::IdprCmtp => "IdprCmtp",
|
||||
IpProto::TpPlusPlus => "TpPlusPlus",
|
||||
IpProto::Il => "Il",
|
||||
IpProto::Ipv6 => "Ipv6",
|
||||
IpProto::Sdrp => "Sdrp",
|
||||
IpProto::Ipv6Route => "Ipv6Route",
|
||||
IpProto::Ipv6Frag => "Ipv6Frag",
|
||||
IpProto::Idrp => "Idrp",
|
||||
IpProto::Rsvp => "Rsvp",
|
||||
IpProto::Gre => "Gre",
|
||||
IpProto::Dsr => "Dsr",
|
||||
IpProto::Bna => "Bna",
|
||||
IpProto::Esp => "Esp",
|
||||
IpProto::Ah => "Ah",
|
||||
IpProto::Inlsp => "Inlsp",
|
||||
IpProto::Swipe => "Swipe",
|
||||
IpProto::Narp => "Narp",
|
||||
IpProto::Mobile => "Mobile",
|
||||
IpProto::Tlsp => "Tlsp",
|
||||
IpProto::Skip => "Skip",
|
||||
IpProto::Ipv6Icmp => "Ipv6Icmp",
|
||||
IpProto::Ipv6NoNxt => "Ipv6NoNxt",
|
||||
IpProto::Ipv6Opts => "Ipv6Opts",
|
||||
IpProto::AnyHostInternal => "AnyHostInternal",
|
||||
IpProto::Cftp => "Cftp",
|
||||
IpProto::AnyLocalNetwork => "AnyLocalNetwork",
|
||||
IpProto::SatExpak => "SatExpak",
|
||||
IpProto::Kryptolan => "Kryptolan",
|
||||
IpProto::Rvd => "Rvd",
|
||||
IpProto::Ippc => "Ippc",
|
||||
IpProto::AnyDistributedFileSystem => "AnyDistributedFileSystem",
|
||||
IpProto::SatMon => "SatMon",
|
||||
IpProto::Visa => "Visa",
|
||||
IpProto::Ipcv => "Ipcv",
|
||||
IpProto::Cpnx => "Cpnx",
|
||||
IpProto::Cphb => "Cphb",
|
||||
IpProto::Wsn => "Wsn",
|
||||
IpProto::Pvp => "Pvp",
|
||||
IpProto::BrSatMon => "BrSatMon",
|
||||
IpProto::SunNd => "SunNd",
|
||||
IpProto::WbMon => "WbMon",
|
||||
IpProto::WbExpak => "WbExpak",
|
||||
IpProto::IsoIp => "IsoIp",
|
||||
IpProto::Vmtp => "Vmtp",
|
||||
IpProto::SecureVmtp => "SecureVmtp",
|
||||
IpProto::Vines => "Vines",
|
||||
IpProto::Ttp => "Ttp",
|
||||
IpProto::NsfnetIgp => "NsfnetIgp",
|
||||
IpProto::Dgp => "Dgp",
|
||||
IpProto::Tcf => "Tcf",
|
||||
IpProto::Eigrp => "Eigrp",
|
||||
IpProto::Ospfigp => "Ospfigp",
|
||||
IpProto::SpriteRpc => "SpriteRpc",
|
||||
IpProto::Larp => "Larp",
|
||||
IpProto::Mtp => "Mtp",
|
||||
IpProto::Ax25 => "Ax25",
|
||||
IpProto::Ipip => "Ipip",
|
||||
IpProto::Micp => "Micp",
|
||||
IpProto::SccSp => "SccSp",
|
||||
IpProto::Etherip => "Etherip",
|
||||
IpProto::Encap => "Encap",
|
||||
IpProto::AnyPrivateEncryptionScheme => "AnyPrivateEncryptionScheme",
|
||||
IpProto::Gmtp => "Gmtp",
|
||||
IpProto::Ifmp => "Ifmp",
|
||||
IpProto::Pnni => "Pnni",
|
||||
IpProto::Pim => "Pim",
|
||||
IpProto::Aris => "Aris",
|
||||
IpProto::Scps => "Scps",
|
||||
IpProto::Qnx => "Qnx",
|
||||
IpProto::ActiveNetworks => "ActiveNetworks",
|
||||
IpProto::IpComp => "IpComp",
|
||||
IpProto::Snp => "Snp",
|
||||
IpProto::CompaqPeer => "CompaqPeer",
|
||||
IpProto::IpxInIp => "IpxInIp",
|
||||
IpProto::Vrrp => "Vrrp",
|
||||
IpProto::Pgm => "Pgm",
|
||||
IpProto::AnyZeroHopProtocol => "AnyZeroHopProtocol",
|
||||
IpProto::L2tp => "L2tp",
|
||||
IpProto::Ddx => "Ddx",
|
||||
IpProto::Iatp => "Iatp",
|
||||
IpProto::Stp => "Stp",
|
||||
IpProto::Srp => "Srp",
|
||||
IpProto::Uti => "Uti",
|
||||
IpProto::Smp => "Smp",
|
||||
IpProto::Sm => "Sm",
|
||||
IpProto::Ptp => "Ptp",
|
||||
IpProto::IsisOverIpv4 => "IsisOverIpv4",
|
||||
IpProto::Fire => "Fire",
|
||||
IpProto::Crtp => "Crtp",
|
||||
IpProto::Crudp => "Crudp",
|
||||
IpProto::Sscopmce => "Sscopmce",
|
||||
IpProto::Iplt => "Iplt",
|
||||
IpProto::Sps => "Sps",
|
||||
IpProto::Pipe => "Pipe",
|
||||
IpProto::Sctp => "Sctp",
|
||||
IpProto::Fc => "Fc",
|
||||
IpProto::RsvpE2eIgnore => "RsvpE2eIgnore",
|
||||
IpProto::MobilityHeader => "MobilityHeader",
|
||||
IpProto::UdpLite => "UdpLite",
|
||||
IpProto::Mpls => "Mpls",
|
||||
IpProto::Manet => "Manet",
|
||||
IpProto::Hip => "Hip",
|
||||
IpProto::Shim6 => "Shim6",
|
||||
IpProto::Wesp => "Wesp",
|
||||
IpProto::Rohc => "Rohc",
|
||||
IpProto::EthernetInIpv4 => "EthernetInIpv4",
|
||||
IpProto::Aggfrag => "Aggfrag",
|
||||
IpProto::Test1 => "Test1",
|
||||
IpProto::Test2 => "Test2",
|
||||
IpProto::Reserved => "Reserved",
|
||||
})
|
||||
}
|
||||
1
net-logger/src/utils/mod.rs
Normal file
1
net-logger/src/utils/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod ip;
|
||||
Reference in New Issue
Block a user