-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8fdb654
Showing
16 changed files
with
596 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[alias] | ||
xtask = "run --package xtask --" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
### https://raw.github.com/github/gitignore/master/Rust.gitignore | ||
|
||
# Generated by Cargo | ||
# will have compiled files and executables | ||
debug/ | ||
target/ | ||
|
||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||
Cargo.lock | ||
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
||
.idea | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[workspace] | ||
members = ["tcbpftest", "tcbpftest-common", "xtask"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# tcbpftest | ||
|
||
## Prerequisites | ||
|
||
1. Install a rust stable toolchain: `rustup install stable` | ||
1. Install a rust nightly toolchain: `rustup install nightly` | ||
1. Install bpf-linker: `cargo install bpf-linker` | ||
|
||
## Build eBPF | ||
|
||
```bash | ||
cargo xtask build-ebpf | ||
``` | ||
|
||
To perform a release build you can use the `--release` flag. | ||
You may also change the target architecture with the `--target` flag | ||
|
||
## Build Userspace | ||
|
||
```bash | ||
cargo build | ||
``` | ||
|
||
## Run | ||
|
||
```bash | ||
sudo target/debug/tcbpftest | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "tcbpftest-common" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
[features] | ||
default = [] | ||
userspace = [ "aya" ] | ||
|
||
[dependencies] | ||
aya = { git = "https://github.com/aya-rs/aya", branch="main", optional=true } | ||
|
||
[lib] | ||
path = "src/lib.rs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![no_std] | ||
|
||
#[repr(C)] | ||
pub struct PacketLog { | ||
pub len: u32, // packet length | ||
pub src_addr: u32, // ipv4 source IP address | ||
} | ||
|
||
#[cfg(feature = "user")] | ||
unsafe impl aya::Pod for PacketLog {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[build] | ||
target-dir = "../target" | ||
target = "bpfel-unknown-none" | ||
|
||
[unstable] | ||
build-std = ["core"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[package] | ||
name = "tcbpftest-ebpf" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
[dependencies] | ||
aya-bpf = { git = "http://github.com/aya-rs/aya", branch = "main" } | ||
memoffset = "0.6.1" | ||
tcbpftest-common = { path = "../tcbpftest-common" } | ||
|
||
[[bin]] | ||
name = "tcbpftest" | ||
path = "src/main.rs" | ||
|
||
[profile.dev] | ||
panic = "abort" | ||
debug = 1 | ||
opt-level = 2 | ||
overflow-checks = false | ||
|
||
[profile.release] | ||
panic = "abort" | ||
|
||
[workspace] | ||
members = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/* automatically generated by rust-bindgen 0.59.2 */ | ||
|
||
#[repr(C)] | ||
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] | ||
pub struct __BindgenBitfieldUnit<Storage> { | ||
storage: Storage, | ||
} | ||
impl<Storage> __BindgenBitfieldUnit<Storage> { | ||
#[inline] | ||
pub const fn new(storage: Storage) -> Self { | ||
Self { storage } | ||
} | ||
} | ||
impl<Storage> __BindgenBitfieldUnit<Storage> | ||
where | ||
Storage: AsRef<[u8]> + AsMut<[u8]>, | ||
{ | ||
#[inline] | ||
pub fn get_bit(&self, index: usize) -> bool { | ||
debug_assert!(index / 8 < self.storage.as_ref().len()); | ||
let byte_index = index / 8; | ||
let byte = self.storage.as_ref()[byte_index]; | ||
let bit_index = if cfg!(target_endian = "big") { | ||
7 - (index % 8) | ||
} else { | ||
index % 8 | ||
}; | ||
let mask = 1 << bit_index; | ||
byte & mask == mask | ||
} | ||
#[inline] | ||
pub fn set_bit(&mut self, index: usize, val: bool) { | ||
debug_assert!(index / 8 < self.storage.as_ref().len()); | ||
let byte_index = index / 8; | ||
let byte = &mut self.storage.as_mut()[byte_index]; | ||
let bit_index = if cfg!(target_endian = "big") { | ||
7 - (index % 8) | ||
} else { | ||
index % 8 | ||
}; | ||
let mask = 1 << bit_index; | ||
if val { | ||
*byte |= mask; | ||
} else { | ||
*byte &= !mask; | ||
} | ||
} | ||
#[inline] | ||
pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { | ||
debug_assert!(bit_width <= 64); | ||
debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); | ||
debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); | ||
let mut val = 0; | ||
for i in 0..(bit_width as usize) { | ||
if self.get_bit(i + bit_offset) { | ||
let index = if cfg!(target_endian = "big") { | ||
bit_width as usize - 1 - i | ||
} else { | ||
i | ||
}; | ||
val |= 1 << index; | ||
} | ||
} | ||
val | ||
} | ||
#[inline] | ||
pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { | ||
debug_assert!(bit_width <= 64); | ||
debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); | ||
debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); | ||
for i in 0..(bit_width as usize) { | ||
let mask = 1 << i; | ||
let val_bit_is_set = val & mask == mask; | ||
let index = if cfg!(target_endian = "big") { | ||
bit_width as usize - 1 - i | ||
} else { | ||
i | ||
}; | ||
self.set_bit(index + bit_offset, val_bit_is_set); | ||
} | ||
} | ||
} | ||
pub type __u8 = ::aya_bpf::cty::c_uchar; | ||
pub type __u16 = ::aya_bpf::cty::c_ushort; | ||
pub type __u32 = ::aya_bpf::cty::c_uint; | ||
pub type __be16 = __u16; | ||
pub type __be32 = __u32; | ||
#[repr(C)] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct ethhdr { | ||
pub h_dest: [::aya_bpf::cty::c_uchar; 6usize], | ||
pub h_source: [::aya_bpf::cty::c_uchar; 6usize], | ||
pub h_proto: __be16, | ||
} | ||
pub type __sum16 = __u16; | ||
#[repr(C)] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct iphdr { | ||
pub _bitfield_align_1: [u8; 0], | ||
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, | ||
pub tos: __u8, | ||
pub tot_len: __be16, | ||
pub id: __be16, | ||
pub frag_off: __be16, | ||
pub ttl: __u8, | ||
pub protocol: __u8, | ||
pub check: __sum16, | ||
pub saddr: __be32, | ||
pub daddr: __be32, | ||
} | ||
impl iphdr { | ||
#[inline] | ||
pub fn ihl(&self) -> __u8 { | ||
unsafe { ::core::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u8) } | ||
} | ||
#[inline] | ||
pub fn set_ihl(&mut self, val: __u8) { | ||
unsafe { | ||
let val: u8 = ::core::mem::transmute(val); | ||
self._bitfield_1.set(0usize, 4u8, val as u64) | ||
} | ||
} | ||
#[inline] | ||
pub fn version(&self) -> __u8 { | ||
unsafe { ::core::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u8) } | ||
} | ||
#[inline] | ||
pub fn set_version(&mut self, val: __u8) { | ||
unsafe { | ||
let val: u8 = ::core::mem::transmute(val); | ||
self._bitfield_1.set(4usize, 4u8, val as u64) | ||
} | ||
} | ||
#[inline] | ||
pub fn new_bitfield_1(ihl: __u8, version: __u8) -> __BindgenBitfieldUnit<[u8; 1usize]> { | ||
let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); | ||
__bindgen_bitfield_unit.set(0usize, 4u8, { | ||
let ihl: u8 = unsafe { ::core::mem::transmute(ihl) }; | ||
ihl as u64 | ||
}); | ||
__bindgen_bitfield_unit.set(4usize, 4u8, { | ||
let version: u8 = unsafe { ::core::mem::transmute(version) }; | ||
version as u64 | ||
}); | ||
__bindgen_bitfield_unit | ||
} | ||
} | ||
|
||
impl<Storage> __BindgenBitfieldUnit<Storage> {} | ||
impl ethhdr { | ||
pub fn h_dest(&self) -> Option<[::aya_bpf::cty::c_uchar; 6usize]> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.h_dest) }.ok() | ||
} | ||
pub fn h_source(&self) -> Option<[::aya_bpf::cty::c_uchar; 6usize]> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.h_source) }.ok() | ||
} | ||
pub fn h_proto(&self) -> Option<__be16> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.h_proto) }.ok() | ||
} | ||
} | ||
impl iphdr { | ||
pub fn tos(&self) -> Option<__u8> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.tos) }.ok() | ||
} | ||
pub fn tot_len(&self) -> Option<__be16> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.tot_len) }.ok() | ||
} | ||
pub fn id(&self) -> Option<__be16> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.id) }.ok() | ||
} | ||
pub fn frag_off(&self) -> Option<__be16> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.frag_off) }.ok() | ||
} | ||
pub fn ttl(&self) -> Option<__u8> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.ttl) }.ok() | ||
} | ||
pub fn protocol(&self) -> Option<__u8> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.protocol) }.ok() | ||
} | ||
pub fn check(&self) -> Option<__sum16> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.check) }.ok() | ||
} | ||
pub fn saddr(&self) -> Option<__be32> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.saddr) }.ok() | ||
} | ||
pub fn daddr(&self) -> Option<__be32> { | ||
unsafe { ::aya_bpf::helpers::bpf_probe_read(&self.daddr) }.ok() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
use aya_bpf::{ | ||
BpfContext, | ||
macros::{map, classifier}, | ||
maps::PerfEventArray, | ||
programs::SkBuffContext, | ||
}; | ||
use aya_bpf::bindings::__sk_buff; | ||
|
||
use core::convert::TryInto; | ||
use core::mem; | ||
use memoffset::offset_of; | ||
|
||
use tcbpftest_common::PacketLog; | ||
|
||
mod bindings; | ||
use bindings::{ethhdr, iphdr}; | ||
|
||
#[panic_handler] | ||
fn panic(_info: &core::panic::PanicInfo) -> ! { | ||
unreachable!() | ||
} | ||
|
||
#[map(name = "EVENTS")] | ||
static mut EVENTS: PerfEventArray<PacketLog> = PerfEventArray::<PacketLog>::with_max_entries(1024, 0); | ||
|
||
#[classifier(name="tcbpftest")] | ||
pub fn tcbpftest(ctx: SkBuffContext) -> i32 { | ||
match unsafe { try_tcbpftest(ctx) } { | ||
Ok(ret) => ret, | ||
Err(_) => 123, | ||
} | ||
} | ||
|
||
#[inline(always)] | ||
unsafe fn ptr_at<T>(ctx: &SkBuffContext, offset: usize) -> Result<*const T, ()> { | ||
let raw_skb = ctx.as_ptr() as *const __sk_buff; | ||
let start = (*raw_skb).data as usize; | ||
let end = (*raw_skb).data_end as usize; | ||
let len = mem::size_of::<T>(); | ||
|
||
if start + offset + len > end { | ||
return Err(()); | ||
} | ||
|
||
Ok((start + offset) as *const T) | ||
} | ||
|
||
unsafe fn try_tcbpftest(ctx: SkBuffContext) -> Result<i32, i64> { | ||
let skb = ctx.as_ptr() as *const __sk_buff; | ||
let offset : usize = 8; | ||
let val = match ptr_at::<u16>(&ctx, offset) { | ||
Err(_) => return Err(123), | ||
Ok(v) => v, | ||
}; | ||
let proto_bytes = u16::from_be(*val); | ||
let log_entry = PacketLog { | ||
len: u32::from_be((*skb).len), | ||
proto: proto_bytes as u32, | ||
}; | ||
|
||
unsafe { | ||
EVENTS.output(&ctx, &log_entry, 0); | ||
} | ||
Ok(0) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[package] | ||
name = "tcbpftest" | ||
version = "0.1.0" | ||
edition = "2018" | ||
publish = false | ||
|
||
[dependencies] | ||
aya = { git = "https://github.com/aya-rs/aya", branch="main", features=["async_tokio"] } | ||
tcbpftest-common = { path = "../tcbpftest-common", features=["userspace"] } | ||
anyhow = "1.0.42" | ||
bytes = "1.1" | ||
ctrlc = "3.2" | ||
|
||
structopt = { version = "0.3"} | ||
tokio = { version = "1.5.0", features = ["macros", "rt", "rt-multi-thread", "net", "signal"] } | ||
simplelog = "0.11" | ||
log = "0.4" | ||
|
||
[[bin]] | ||
name = "tcbpftest" | ||
path = "src/main.rs" |
Oops, something went wrong.