aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/packet_analyzer.rs
blob: 323abbe5e4582c0e0902e3257e1f3159cb68e2df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use bytes::Bytes;
use hex::encode;
use log::{error, trace};
use std::{borrow::Cow, path::PathBuf};
use tokio::fs::File;

use clap::Parser;
use color_eyre::eyre::Result;
use meshcore::{
    packet::Packet,
    std_identity::{Keystore, KeystoreInput},
};
use pcap_file_tokio::pcapng::PcapNgReader;
use pretty_env_logger;

#[derive(Parser)]
struct AnalyzerArguments {
    #[arg(long, short, help = "Identities file for packet decryption")]
    identities_file: PathBuf,

    #[arg(long, short, help = "Pcapng file to input packets for analysis")]
    pcap_file: PathBuf,
}

fn process_packet(data: Cow<[u8]>, keystore: &Keystore) {
    // Convert the Cow into Bytes so we can do the packet analysis.
    let bytes = Bytes::copy_from_slice(&data);

    let mut packet = Packet::from(bytes);
    packet.try_decrypt(keystore);

    println!("{}", packet);
}

#[tokio::main]
async fn main() -> Result<()> {
    pretty_env_logger::init();

    let args = AnalyzerArguments::parse();

    // Attempt to load the identities file from disk and load all the identities
    let identity_string = std::fs::read_to_string(args.identities_file)?;
    let keystore_in: KeystoreInput = toml::from_str(&identity_string)?;
    let keystore = keystore_in.compile();

    // Pcapng file for loading packets
    let pcap_file = File::open(args.pcap_file).await?;
    let mut pcap_reader = PcapNgReader::new(pcap_file).await?;

    println!(" ROUTE T | v1 | Transp Fl. |     Route Summary    | I | Pkt. Type | Summary....");

    // Iterate through the packets in the pacap
    // and print out their contents!  Wheeeee!
    while let Some(pkt) = pcap_reader.next_block().await {
        use pcap_file_tokio::pcapng::Block::*;
        match pkt {
            Ok(SectionHeader(section_header_block)) => {
                trace!("SectionHeader: {:#?}", section_header_block);
            }
            Ok(InterfaceDescription(interface_description_block)) => {
                trace!("InterfaceDescription: {:#?}", interface_description_block);
            }
            Ok(Packet(packet_block)) => {
                trace!("Packet: {:#?}", packet_block);
            }
            Ok(SimplePacket(simple_packet_block)) => {
                trace!("SimplePacket: {:#?}", simple_packet_block);
            }
            Ok(NameResolution(name_resolution_block)) => {
                trace!("NameResolution: {:#?}", name_resolution_block);
            }
            Ok(InterfaceStatistics(interface_statistics_block)) => {
                trace!("InterfaceStatistics: {:#?}", interface_statistics_block);
            }
            Ok(EnhancedPacket(enhanced_packet_block)) => {
                trace!("EnhancedPacket: {}", encode(&enhanced_packet_block.data));
                process_packet(enhanced_packet_block.data.clone(), &keystore);
            }
            Ok(SystemdJournalExport(systemd_journal_export_block)) => {
                trace!("SystemdJournalExport: {:#?}", systemd_journal_export_block);
            }
            Ok(Unknown(unknown_block)) => {
                trace!("Unknown: {:#?}", unknown_block);
            }
            Err(e) => {
                error!("Error in Pcap file! {}", e);
            }
        }
    }

    Ok(())
}