diff --git a/.gitignore b/.gitignore index c7d8977..6362fb6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -network_config/genesis.ssz \ No newline at end of file +network_config/genesis.ssz +pcap/target \ No newline at end of file diff --git a/pcap/Cargo.lock b/pcap/Cargo.lock new file mode 100644 index 0000000..d4628e1 --- /dev/null +++ b/pcap/Cargo.lock @@ -0,0 +1,284 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bn-pcap" +version = "0.1.0" +dependencies = [ + "etherparse", + "pcap", +] + +[[package]] +name = "cc" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "etherparse" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21696e6dfe1057a166a042c6d27b89a46aad2ee1003e6e1e03c49d54fd3270d7" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "pcap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4d339439e5e7f8ce32d58c2b58d5e304790e66f3aa0bd391dd6a9dc676e054" +dependencies = [ + "bitflags", + "errno", + "libc", + "libloading", + "pkg-config", + "regex", + "windows-sys", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/pcap/Cargo.toml b/pcap/Cargo.toml new file mode 100644 index 0000000..f6a3691 --- /dev/null +++ b/pcap/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "bn-pcap" +version = "0.1.0" +edition = "2021" + +[dependencies] +etherparse = "0.15.0" +pcap = "2.1.0" \ No newline at end of file diff --git a/pcap/src/main.rs b/pcap/src/main.rs new file mode 100644 index 0000000..dcaa506 --- /dev/null +++ b/pcap/src/main.rs @@ -0,0 +1,132 @@ +use std::net::{IpAddr, Ipv4Addr}; +use etherparse::{NetSlice, SlicedPacket, TransportSlice}; +use pcap::{Direction, Linktype, Packet}; + +#[derive(Debug)] +struct Addr { + ip: Ipv4Addr, + port: u16, +} + +#[derive(Debug)] +struct TcpDataInfo { + src: Addr, + dest: Addr, + data_offset: usize, + // flags: TcpMeta, + // ts: SystemTime, +} + +// TODO: load private key +// TODO: Noise decryption +// https://github.com/sigp/lighthouse/blob/bcff4aa825c4d70a215e1f229a0d1798d697fb5b/beacon_node/lighthouse_network/src/service/utils.rs#L58 +// TODO: Use lighthouse codec +fn main() { + // get the default Device + let device = pcap::Device::lookup() + .expect("device lookup failed") + .expect("no device available"); + let local_addresses = device.addresses.iter().map(|addr| addr.addr).collect::>(); + println!("Using device {:?}", device); + println!("Local addresses {:?}", local_addresses); + + // Setup Capture + let mut cap = pcap::Capture::from_device(device) + .unwrap() + .immediate_mode(true) + .open() + .unwrap(); + + cap.filter("tcp", true).unwrap(); + // cap.direction(Direction::In).unwrap(); + + let link_type = cap.get_datalink(); + if !matches!(link_type, Linktype::ETHERNET) { + panic!("Unsupported link type: {link_type:?}"); + } + + let mut count = 0; + loop { + let packet = cap.next_packet().unwrap(); + // println!("Got {:?}", packet.header); + + let Some(tcp_data_info) = parse_tcp(&packet) else { + continue; + }; + + let data = &packet.data[tcp_data_info.data_offset..]; + if data.len() > 0 { + print_tcp(tcp_data_info, data, &local_addresses); + } else { + println!("empty data."); + continue; + } + + if count > 10 { + break; + } + count += 1; + } +} + +fn parse_tcp(packet: &Packet) -> Option { + if packet.header.caplen < 32 { + return None; + } + + let ipv4data = match skip_ethernet_header(packet.data) { + Ok(data) => data, + Err(e) => { + println!("error: {e}"); + return None; + } + }; + + let sliced = SlicedPacket::from_ip(ipv4data).unwrap(); + let Some(NetSlice::Ipv4(ipv4_slice)) = sliced.net else { + return None; + }; + let src_addr = ipv4_slice.header().source_addr(); + let dest_addr = ipv4_slice.header().destination_addr(); + + let TransportSlice::Tcp(tcp_slice) = sliced.transport.unwrap() else { + return None; + }; + let src_port = tcp_slice.source_port(); + let dest_port = tcp_slice.destination_port(); + + let link_bytes_len = 4; + let data_offset = link_bytes_len + ((ipv4_slice.header().ihl() * 4) + (tcp_slice.data_offset() * 4)) as usize; + + Some(TcpDataInfo { + src: Addr { + ip: src_addr, + port: src_port, + }, + dest: Addr { + ip: dest_addr, + port: dest_port, + }, + data_offset, + }) +} + +fn skip_ethernet_header(data: &[u8]) -> Result<&[u8], String> { + if data.len() < 14 { + return Err("Packet too short".to_string()); + } + Ok(&data[14..]) +} + + +fn print_tcp(tcp_data_info: TcpDataInfo, data: &[u8], local_addresses: &Vec) { + let is_sent = local_addresses.contains(&IpAddr::V4(tcp_data_info.src.ip)); + println!( + "{} {}:{} -> {}:{}", + if is_sent { "sent" } else { "recv"}, + tcp_data_info.src.ip, + tcp_data_info.src.port, + tcp_data_info.dest.ip, + tcp_data_info.dest.port, + ); +}