From 5e43bc79a4401c31531937f63858244718dc3b30 Mon Sep 17 00:00:00 2001 From: ackintosh Date: Thu, 29 Aug 2024 11:28:53 +0900 Subject: [PATCH 1/4] Add bn-pcap --- .gitignore | 3 +- pcap/Cargo.lock | 268 +++++++++++++++++++++++++++++++++++++++++++++++ pcap/Cargo.toml | 7 ++ pcap/src/main.rs | 31 ++++++ 4 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 pcap/Cargo.lock create mode 100644 pcap/Cargo.toml create mode 100644 pcap/src/main.rs 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..192ba86 --- /dev/null +++ b/pcap/Cargo.lock @@ -0,0 +1,268 @@ +# 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 = "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 = [ + "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 = "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..9f1efd5 --- /dev/null +++ b/pcap/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "bn-pcap" +version = "0.1.0" +edition = "2021" + +[dependencies] +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..9528792 --- /dev/null +++ b/pcap/src/main.rs @@ -0,0 +1,31 @@ +use pcap::Direction; + +fn main() { + // get the default Device + let device = pcap::Device::lookup() + .expect("device lookup failed") + .expect("no device available"); + println!("Using device {}", device.name); + + // 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(); + println!("link type: {link_type:?}"); + + let mut count = 0; + cap.for_each(None, |packet| { + println!("Got {:?}", packet.header); + count += 1; + if count > 10 { + panic!("ow"); + } + }) + .unwrap(); +} From e1cff4d9223c9f039eeb2b780978a9eede8f4bac Mon Sep 17 00:00:00 2001 From: ackintosh Date: Thu, 29 Aug 2024 12:00:34 +0900 Subject: [PATCH 2/4] Parse tcp --- pcap/Cargo.lock | 16 +++++++++ pcap/Cargo.toml | 1 + pcap/src/main.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 98 insertions(+), 6 deletions(-) diff --git a/pcap/Cargo.lock b/pcap/Cargo.lock index 192ba86..d4628e1 100644 --- a/pcap/Cargo.lock +++ b/pcap/Cargo.lock @@ -11,6 +11,12 @@ 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" @@ -21,6 +27,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" name = "bn-pcap" version = "0.1.0" dependencies = [ + "etherparse", "pcap", ] @@ -60,6 +67,15 @@ dependencies = [ "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" diff --git a/pcap/Cargo.toml b/pcap/Cargo.toml index 9f1efd5..f6a3691 100644 --- a/pcap/Cargo.toml +++ b/pcap/Cargo.toml @@ -4,4 +4,5 @@ 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 index 9528792..c48c740 100644 --- a/pcap/src/main.rs +++ b/pcap/src/main.rs @@ -1,4 +1,21 @@ -use pcap::Direction; +use std::net::Ipv4Addr; +use etherparse::{NetSlice, SlicedPacket, TransportSlice}; +use pcap::{Direction, Linktype, Packet}; + +#[derive(Debug)] +struct Addr { + ip: Ipv4Addr, + port: u16, +} + +#[derive(Debug)] +struct TcpData { + src: Addr, + dest: Addr, + data_offset: usize, + // flags: TcpMeta, + // ts: SystemTime, +} fn main() { // get the default Device @@ -16,16 +33,74 @@ fn main() { cap.filter("tcp", true).unwrap(); cap.direction(Direction::In).unwrap(); + let link_type = cap.get_datalink(); - println!("link type: {link_type:?}"); + if !matches!(link_type, Linktype::ETHERNET) { + panic!("Unsupported link type: {link_type:?}"); + } let mut count = 0; - cap.for_each(None, |packet| { + loop { + let packet = cap.next_packet().unwrap(); println!("Got {:?}", packet.header); - count += 1; + + let Some(tcp_data) = parse_tcp(&packet) else { + continue; + }; + println!("tcp data: {tcp_data:?}"); + if count > 10 { - panic!("ow"); + 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(TcpData { + src: Addr { + ip: src_addr, + port: src_port, + }, + dest: Addr { + ip: dest_addr, + port: dest_port, + }, + data_offset, }) - .unwrap(); +} + +fn skip_ethernet_header(data: &[u8]) -> Result<&[u8], String> { + if data.len() < 14 { + return Err("Packet too short".to_string()); + } + Ok(&data[14..]) } From 7fbe4053ce3ae72cec8de4eb98adc601e04c799e Mon Sep 17 00:00:00 2001 From: ackintosh Date: Sun, 1 Sep 2024 21:42:06 +0900 Subject: [PATCH 3/4] print_tcp --- pcap/src/main.rs | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/pcap/src/main.rs b/pcap/src/main.rs index c48c740..3e57493 100644 --- a/pcap/src/main.rs +++ b/pcap/src/main.rs @@ -1,4 +1,4 @@ -use std::net::Ipv4Addr; +use std::net::{IpAddr, Ipv4Addr}; use etherparse::{NetSlice, SlicedPacket, TransportSlice}; use pcap::{Direction, Linktype, Packet}; @@ -9,7 +9,7 @@ struct Addr { } #[derive(Debug)] -struct TcpData { +struct TcpDataInfo { src: Addr, dest: Addr, data_offset: usize, @@ -22,7 +22,9 @@ fn main() { let device = pcap::Device::lookup() .expect("device lookup failed") .expect("no device available"); - println!("Using device {}", device.name); + 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) @@ -32,7 +34,7 @@ fn main() { .unwrap(); cap.filter("tcp", true).unwrap(); - cap.direction(Direction::In).unwrap(); + // cap.direction(Direction::In).unwrap(); let link_type = cap.get_datalink(); if !matches!(link_type, Linktype::ETHERNET) { @@ -42,12 +44,19 @@ fn main() { let mut count = 0; loop { let packet = cap.next_packet().unwrap(); - println!("Got {:?}", packet.header); + // println!("Got {:?}", packet.header); - let Some(tcp_data) = parse_tcp(&packet) else { + let Some(tcp_data_info) = parse_tcp(&packet) else { continue; }; - println!("tcp data: {tcp_data:?}"); + + 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; @@ -56,7 +65,7 @@ fn main() { } } -fn parse_tcp(packet: &Packet) -> Option { +fn parse_tcp(packet: &Packet) -> Option { if packet.header.caplen < 32 { return None; } @@ -85,7 +94,7 @@ fn parse_tcp(packet: &Packet) -> Option { let link_bytes_len = 4; let data_offset = link_bytes_len + ((ipv4_slice.header().ihl() * 4) + (tcp_slice.data_offset() * 4)) as usize; - Some(TcpData { + Some(TcpDataInfo { src: Addr { ip: src_addr, port: src_port, @@ -104,3 +113,16 @@ fn skip_ethernet_header(data: &[u8]) -> Result<&[u8], 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, + ); +} From 70f4efc600b7ed6e311035502dc3fd40a9e0833d Mon Sep 17 00:00:00 2001 From: ackintosh Date: Sun, 1 Sep 2024 21:56:04 +0900 Subject: [PATCH 4/4] Add TODOs --- pcap/src/main.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pcap/src/main.rs b/pcap/src/main.rs index 3e57493..dcaa506 100644 --- a/pcap/src/main.rs +++ b/pcap/src/main.rs @@ -17,6 +17,10 @@ struct TcpDataInfo { // 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()