lk-inside 0.3.1

A terminal user interface (TUI) application for interactive data analysis.
Documentation
use pnet::packet::ethernet::{EthernetPacket, EtherTypes};
use pnet::packet::ipv4::Ipv4Packet;
use pnet::packet::ipv6::Ipv6Packet;
use pnet::packet::tcp::TcpPacket;
use pnet::packet::udp::UdpPacket;
use pnet::packet::Packet;
use std::net::IpAddr;
use std::time::{SystemTime, UNIX_EPOCH};

#[derive(Debug)]
pub struct ParsedPacket {
    pub timestamp: u64,
    pub interface_name: String,
    pub source_ip: Option<IpAddr>,
    pub destination_ip: Option<IpAddr>,
    pub source_port: Option<u16>,
    pub destination_port: Option<u16>,
    pub protocol: String,
    pub packet_size: usize,
}

pub fn parse_packet(interface_name: String, packet: &[u8]) -> ParsedPacket {
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("Time went backwards")
        .as_nanos() as u64;
    let packet_size = packet.len();

    let mut parsed_packet = ParsedPacket {
        timestamp,
        interface_name,
        source_ip: None,
        destination_ip: None,
        source_port: None,
        destination_port: None,
        protocol: "Other".to_string(),
        packet_size,
    };

    if let Some(ethernet_packet) = EthernetPacket::new(packet) {
        match ethernet_packet.get_ethertype() {
            EtherTypes::Ipv4 => {
                if let Some(ipv4_packet) = Ipv4Packet::new(ethernet_packet.payload()) {
                    parsed_packet.source_ip = Some(IpAddr::V4(ipv4_packet.get_source()));
                    parsed_packet.destination_ip = Some(IpAddr::V4(ipv4_packet.get_destination()));
                    let proto = ipv4_packet.get_next_level_protocol();
                    parsed_packet.protocol = format!("{:?}", proto);

                    match proto {
                        pnet::packet::ip::IpNextHeaderProtocols::Tcp => {
                            if let Some(tcp_packet) = TcpPacket::new(ipv4_packet.payload()) {
                                parsed_packet.source_port = Some(tcp_packet.get_source());
                                parsed_packet.destination_port = Some(tcp_packet.get_destination());
                            }
                        }
                        pnet::packet::ip::IpNextHeaderProtocols::Udp => {
                            if let Some(udp_packet) = UdpPacket::new(ipv4_packet.payload()) {
                                parsed_packet.source_port = Some(udp_packet.get_source());
                                parsed_packet.destination_port = Some(udp_packet.get_destination());
                            }
                        }
                        _ => {}
                    }
                }
            }
            EtherTypes::Ipv6 => {
                if let Some(ipv6_packet) = Ipv6Packet::new(ethernet_packet.payload()) {
                    parsed_packet.source_ip = Some(IpAddr::V6(ipv6_packet.get_source()));
                    parsed_packet.destination_ip = Some(IpAddr::V6(ipv6_packet.get_destination()));
                    let proto = ipv6_packet.get_next_header();
                    parsed_packet.protocol = format!("{:?}", proto);

                    match proto {
                        pnet::packet::ip::IpNextHeaderProtocols::Tcp => {
                            if let Some(tcp_packet) = TcpPacket::new(ipv6_packet.payload()) {
                                parsed_packet.source_port = Some(tcp_packet.get_source());
                                parsed_packet.destination_port = Some(tcp_packet.get_destination());
                            }
                        }
                        pnet::packet::ip::IpNextHeaderProtocols::Udp => {
                            if let Some(udp_packet) = UdpPacket::new(ipv6_packet.payload()) {
                                parsed_packet.source_port = Some(udp_packet.get_source());
                                parsed_packet.destination_port = Some(udp_packet.get_destination());
                            }
                        }
                        _ => {}
                    }
                }
            }
            _ => {}
        }
    }

    parsed_packet
}