Skip to content

Commit 2212068

Browse files
authored
Show pid for egress packets (#48)
1 parent 1febbac commit 2212068

File tree

18 files changed

+447
-356
lines changed

18 files changed

+447
-356
lines changed

Cargo.lock

Lines changed: 79 additions & 82 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Release.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## v0.6 - TBA
2+
3+
- Show ethernet header infos
4+
- Show PID for egress packets
5+
16
## v0.5 - 2025-03-10
27

38
### Added

oryx-common/src/lib.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![no_std]
2+
#![feature(trivial_bounds)]
23

34
use core::mem;
45

@@ -9,8 +10,25 @@ pub mod protocols;
910
pub const MAX_FIREWALL_RULES: u32 = 32;
1011
pub const MAX_RULES_PORT: usize = 32;
1112

13+
#[derive(Clone)]
1214
#[repr(C)]
15+
pub struct RawData {
16+
pub frame: RawFrame,
17+
pub pid: Option<u32>,
18+
}
19+
20+
impl RawData {
21+
pub const LEN: usize = mem::size_of::<RawData>();
22+
}
23+
24+
impl From<[u8; RawData::LEN]> for RawData {
25+
fn from(value: [u8; RawData::LEN]) -> Self {
26+
unsafe { core::mem::transmute::<[u8; RawData::LEN], Self>(value) }
27+
}
28+
}
29+
1330
#[derive(Clone)]
31+
#[repr(C)]
1432
pub struct RawFrame {
1533
pub header: EthHdr,
1634
pub payload: RawPacket,
@@ -38,8 +56,8 @@ impl Clone for RawPacket {
3856
}
3957
}
4058

41-
#[repr(C)]
4259
#[derive(Copy, Clone)]
60+
#[repr(C)]
4361
pub enum ProtoHdr {
4462
Tcp(TcpHdr),
4563
Udp(UdpHdr),

oryx-ebpf/Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

oryx-ebpf/src/main.rs

Lines changed: 71 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use aya_ebpf::{
55
bindings::{TC_ACT_PIPE, TC_ACT_SHOT},
6+
helpers::bpf_get_current_pid_tgid,
67
macros::{classifier, map},
78
maps::{Array, HashMap, RingBuf},
89
programs::TcContext,
@@ -18,7 +19,7 @@ use network_types::{
1819
};
1920
use oryx_common::{
2021
protocols::{LinkProtocol, NetworkProtocol, Protocol, TransportProtocol},
21-
ProtoHdr, RawFrame, RawPacket, MAX_FIREWALL_RULES, MAX_RULES_PORT,
22+
ProtoHdr, RawData, RawFrame, RawPacket, MAX_FIREWALL_RULES, MAX_RULES_PORT,
2223
};
2324

2425
#[map]
@@ -56,9 +57,9 @@ pub fn oryx(ctx: TcContext) -> i32 {
5657
}
5758

5859
#[inline]
59-
fn submit(frame: RawFrame) {
60-
if let Some(mut buf) = DATA.reserve::<RawFrame>(0) {
61-
unsafe { (*buf.as_mut_ptr()) = frame };
60+
fn submit(data: RawData) {
61+
if let Some(mut buf) = DATA.reserve::<RawData>(0) {
62+
unsafe { (*buf.as_mut_ptr()) = data };
6263
buf.submit(0);
6364
}
6465
}
@@ -153,6 +154,12 @@ fn filter_packet(protocol: Protocol) -> bool {
153154
fn process(ctx: TcContext) -> Result<i32, ()> {
154155
let ethhdr: EthHdr = ctx.load(0).map_err(|_| ())?;
155156

157+
let pid = if is_ingress() {
158+
None
159+
} else {
160+
Some((bpf_get_current_pid_tgid() >> 32) as u32)
161+
};
162+
156163
match ethhdr.ether_type {
157164
EtherType::Ipv4 => {
158165
let header: Ipv4Hdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
@@ -183,12 +190,15 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
183190
return Ok(TC_ACT_PIPE);
184191
}
185192

186-
submit(RawFrame {
187-
header: ethhdr,
188-
payload: RawPacket::Ip(
189-
IpHdr::V4(header),
190-
ProtoHdr::Tcp(unsafe { *tcphdr }),
191-
),
193+
submit(RawData {
194+
frame: RawFrame {
195+
header: ethhdr,
196+
payload: RawPacket::Ip(
197+
IpHdr::V4(header),
198+
ProtoHdr::Tcp(unsafe { *tcphdr }),
199+
),
200+
},
201+
pid,
192202
});
193203
}
194204
IpProto::Udp => {
@@ -210,25 +220,31 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
210220
return Ok(TC_ACT_PIPE);
211221
}
212222

213-
submit(RawFrame {
214-
header: ethhdr,
215-
payload: RawPacket::Ip(
216-
IpHdr::V4(header),
217-
ProtoHdr::Udp(unsafe { *udphdr }),
218-
),
223+
submit(RawData {
224+
frame: RawFrame {
225+
header: ethhdr,
226+
payload: RawPacket::Ip(
227+
IpHdr::V4(header),
228+
ProtoHdr::Udp(unsafe { *udphdr }),
229+
),
230+
},
231+
pid,
219232
});
220233
}
221234
IpProto::Icmp => {
222235
if filter_packet(Protocol::Network(NetworkProtocol::Icmp)) {
223236
return Ok(TC_ACT_PIPE);
224237
}
225238
let icmphdr: *const IcmpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
226-
submit(RawFrame {
227-
header: ethhdr,
228-
payload: RawPacket::Ip(
229-
IpHdr::V4(header),
230-
ProtoHdr::Icmp(unsafe { *icmphdr }),
231-
),
239+
submit(RawData {
240+
frame: RawFrame {
241+
header: ethhdr,
242+
payload: RawPacket::Ip(
243+
IpHdr::V4(header),
244+
ProtoHdr::Icmp(unsafe { *icmphdr }),
245+
),
246+
},
247+
pid,
232248
});
233249
}
234250
_ => {}
@@ -261,12 +277,15 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
261277
{
262278
return Ok(TC_ACT_PIPE);
263279
}
264-
submit(RawFrame {
265-
header: ethhdr,
266-
payload: RawPacket::Ip(
267-
IpHdr::V6(header),
268-
ProtoHdr::Tcp(unsafe { *tcphdr }),
269-
),
280+
submit(RawData {
281+
frame: RawFrame {
282+
header: ethhdr,
283+
payload: RawPacket::Ip(
284+
IpHdr::V6(header),
285+
ProtoHdr::Tcp(unsafe { *tcphdr }),
286+
),
287+
},
288+
pid,
270289
});
271290
}
272291
IpProto::Udp => {
@@ -287,25 +306,31 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
287306
{
288307
return Ok(TC_ACT_PIPE);
289308
}
290-
submit(RawFrame {
291-
header: ethhdr,
292-
payload: RawPacket::Ip(
293-
IpHdr::V6(header),
294-
ProtoHdr::Udp(unsafe { *udphdr }),
295-
),
309+
submit(RawData {
310+
frame: RawFrame {
311+
header: ethhdr,
312+
payload: RawPacket::Ip(
313+
IpHdr::V6(header),
314+
ProtoHdr::Udp(unsafe { *udphdr }),
315+
),
316+
},
317+
pid,
296318
});
297319
}
298320
IpProto::Icmp => {
299321
if filter_packet(Protocol::Network(NetworkProtocol::Icmp)) {
300322
return Ok(TC_ACT_PIPE);
301323
}
302324
let icmphdr: *const IcmpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
303-
submit(RawFrame {
304-
header: ethhdr,
305-
payload: RawPacket::Ip(
306-
IpHdr::V6(header),
307-
ProtoHdr::Icmp(unsafe { *icmphdr }),
308-
),
325+
submit(RawData {
326+
frame: RawFrame {
327+
header: ethhdr,
328+
payload: RawPacket::Ip(
329+
IpHdr::V6(header),
330+
ProtoHdr::Icmp(unsafe { *icmphdr }),
331+
),
332+
},
333+
pid,
309334
});
310335
}
311336
_ => {}
@@ -316,9 +341,12 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
316341
return Ok(TC_ACT_PIPE);
317342
}
318343
let header: ArpHdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
319-
submit(RawFrame {
320-
header: ethhdr,
321-
payload: RawPacket::Arp(header),
344+
submit(RawData {
345+
frame: RawFrame {
346+
header: ethhdr,
347+
payload: RawPacket::Arp(header),
348+
},
349+
pid,
322350
});
323351
}
324352
_ => {}

oryx-tui/src/app.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clap::ArgMatches;
22
use itertools::Itertools;
33
use oryx_common::{
44
protocols::{LinkProtocol, NetworkProtocol, TransportProtocol},
5-
RawFrame,
5+
RawData, RawFrame,
66
};
77
use ratatui::{
88
layout::{Constraint, Direction, Layout},
@@ -49,39 +49,41 @@ pub struct App {
4949
pub help: Help,
5050
pub filter: Filter,
5151
pub start_sniffing: bool,
52-
pub frames: Arc<RwLock<Vec<AppPacket>>>,
52+
pub app_packets: Arc<RwLock<Vec<AppPacket>>>,
5353
pub notifications: Vec<Notification>,
5454
pub section: Section,
55-
pub data_channel_sender: kanal::Sender<([u8; RawFrame::LEN], TrafficDirection)>,
55+
pub data_channel_sender: kanal::Sender<([u8; RawData::LEN], TrafficDirection)>,
5656
pub is_editing: bool,
5757
pub active_popup: Option<ActivePopup>,
5858
pub start_from_cli: bool,
5959
}
6060

6161
impl App {
6262
pub fn new(cli_args: &ArgMatches) -> Self {
63-
let frames = Arc::new(RwLock::new(Vec::with_capacity(RawFrame::LEN * 1024 * 1024)));
63+
let app_packets = Arc::new(RwLock::new(Vec::with_capacity(
64+
AppPacket::LEN * 1024 * 1024,
65+
)));
6466

6567
let (sender, receiver) = kanal::unbounded();
6668

6769
let firewall_channels = IoChannels::new();
6870

6971
thread::spawn({
70-
let frames = frames.clone();
72+
let app_packets = app_packets.clone();
7173
move || loop {
72-
if let Ok((raw_frame, direction)) = receiver.recv() {
73-
let eth_frame = EthFrame::from(raw_frame);
74-
let network_packet = eth_frame.payload;
75-
let mut frames = frames.write().unwrap();
76-
if frames.len() == frames.capacity() {
77-
frames.reserve(1024 * 1024);
78-
}
74+
if let Ok((raw_data, direction)) = receiver.recv() {
75+
let data = RawData::from(raw_data);
76+
let frame = EthFrame::from(data.frame);
77+
let pid = data.pid;
78+
79+
let mut app_packets = app_packets.write().unwrap();
80+
7981
let app_packet = AppPacket {
80-
eth_header: eth_frame.header,
81-
packet: network_packet,
82+
frame,
8283
direction,
84+
pid,
8385
};
84-
frames.push(app_packet);
86+
app_packets.push(app_packet);
8587
}
8688
}
8789
});
@@ -186,9 +188,9 @@ impl App {
186188
direction,
187189
),
188190
start_sniffing: false,
189-
frames: frames.clone(),
191+
app_packets: app_packets.clone(),
190192
notifications: Vec::new(),
191-
section: Section::new(frames.clone(), firewall_channels.clone()),
193+
section: Section::new(app_packets.clone(), firewall_channels.clone()),
192194
data_channel_sender: sender,
193195
is_editing: false,
194196
active_popup: None,

0 commit comments

Comments
 (0)