Skip to content

Commit 8ca6d14

Browse files
nand-norpythops
andauthored
Add frame information to packet info popup (#47)
Co-authored-by: Badr <contact@pythops.com>
1 parent 8dd4e4a commit 8ca6d14

File tree

20 files changed

+335
-180
lines changed

20 files changed

+335
-180
lines changed

oryx-common/src/lib.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,46 @@
22

33
use core::mem;
44

5-
use network_types::{arp::ArpHdr, icmp::IcmpHdr, ip::IpHdr, tcp::TcpHdr, udp::UdpHdr};
5+
use network_types::{arp::ArpHdr, eth::EthHdr, icmp::IcmpHdr, ip::IpHdr, tcp::TcpHdr, udp::UdpHdr};
66

77
pub mod protocols;
88

99
pub const MAX_FIREWALL_RULES: u32 = 32;
1010
pub const MAX_RULES_PORT: usize = 32;
1111

12+
#[repr(C)]
13+
#[derive(Clone)]
14+
pub struct RawFrame {
15+
pub header: EthHdr,
16+
pub payload: RawPacket,
17+
}
18+
19+
impl RawFrame {
20+
pub const LEN: usize = mem::size_of::<RawFrame>();
21+
}
22+
1223
#[repr(C)]
1324
pub enum RawPacket {
1425
Ip(IpHdr, ProtoHdr),
1526
Arp(ArpHdr),
1627
}
1728

29+
impl Clone for RawPacket {
30+
fn clone(&self) -> Self {
31+
match self {
32+
Self::Ip(ip_hdr, proto_hdr) => match ip_hdr {
33+
IpHdr::V4(ipv4_hdr) => Self::Ip(IpHdr::V4(*ipv4_hdr), *proto_hdr),
34+
IpHdr::V6(ipv6_hdr) => Self::Ip(IpHdr::V6(*ipv6_hdr), *proto_hdr),
35+
},
36+
Self::Arp(arp_hdr) => Self::Arp(*arp_hdr),
37+
}
38+
}
39+
}
40+
1841
#[repr(C)]
1942
#[derive(Copy, Clone)]
2043
pub enum ProtoHdr {
2144
Tcp(TcpHdr),
2245
Udp(UdpHdr),
2346
Icmp(IcmpHdr),
2447
}
25-
26-
impl RawPacket {
27-
pub const LEN: usize = mem::size_of::<RawPacket>();
28-
}

oryx-ebpf/src/main.rs

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ use network_types::{
1818
};
1919
use oryx_common::{
2020
protocols::{LinkProtocol, NetworkProtocol, Protocol, TransportProtocol},
21-
ProtoHdr, RawPacket, MAX_FIREWALL_RULES, MAX_RULES_PORT,
21+
ProtoHdr, RawFrame, RawPacket, MAX_FIREWALL_RULES, MAX_RULES_PORT,
2222
};
2323

2424
#[map]
25-
static DATA: RingBuf = RingBuf::with_byte_size(4096 * RawPacket::LEN as u32, 0);
25+
static DATA: RingBuf = RingBuf::with_byte_size(4096 * RawFrame::LEN as u32, 0);
2626

2727
#[map]
2828
static NETWORK_FILTERS: Array<u32> = Array::with_max_entries(8, 0);
@@ -56,9 +56,9 @@ pub fn oryx(ctx: TcContext) -> i32 {
5656
}
5757

5858
#[inline]
59-
fn submit(packet: RawPacket) {
60-
if let Some(mut buf) = DATA.reserve::<RawPacket>(0) {
61-
unsafe { (*buf.as_mut_ptr()) = packet };
59+
fn submit(frame: RawFrame) {
60+
if let Some(mut buf) = DATA.reserve::<RawFrame>(0) {
61+
unsafe { (*buf.as_mut_ptr()) = frame };
6262
buf.submit(0);
6363
}
6464
}
@@ -183,10 +183,13 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
183183
return Ok(TC_ACT_PIPE);
184184
}
185185

186-
submit(RawPacket::Ip(
187-
IpHdr::V4(header),
188-
ProtoHdr::Tcp(unsafe { *tcphdr }),
189-
));
186+
submit(RawFrame {
187+
header: ethhdr,
188+
payload: RawPacket::Ip(
189+
IpHdr::V4(header),
190+
ProtoHdr::Tcp(unsafe { *tcphdr }),
191+
),
192+
});
190193
}
191194
IpProto::Udp => {
192195
let udphdr: *const UdpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
@@ -207,20 +210,26 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
207210
return Ok(TC_ACT_PIPE);
208211
}
209212

210-
submit(RawPacket::Ip(
211-
IpHdr::V4(header),
212-
ProtoHdr::Udp(unsafe { *udphdr }),
213-
));
213+
submit(RawFrame {
214+
header: ethhdr,
215+
payload: RawPacket::Ip(
216+
IpHdr::V4(header),
217+
ProtoHdr::Udp(unsafe { *udphdr }),
218+
),
219+
});
214220
}
215221
IpProto::Icmp => {
216222
if filter_packet(Protocol::Network(NetworkProtocol::Icmp)) {
217223
return Ok(TC_ACT_PIPE);
218224
}
219225
let icmphdr: *const IcmpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
220-
submit(RawPacket::Ip(
221-
IpHdr::V4(header),
222-
ProtoHdr::Icmp(unsafe { *icmphdr }),
223-
));
226+
submit(RawFrame {
227+
header: ethhdr,
228+
payload: RawPacket::Ip(
229+
IpHdr::V4(header),
230+
ProtoHdr::Icmp(unsafe { *icmphdr }),
231+
),
232+
});
224233
}
225234
_ => {}
226235
}
@@ -252,10 +261,13 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
252261
{
253262
return Ok(TC_ACT_PIPE);
254263
}
255-
submit(RawPacket::Ip(
256-
IpHdr::V6(header),
257-
ProtoHdr::Tcp(unsafe { *tcphdr }),
258-
));
264+
submit(RawFrame {
265+
header: ethhdr,
266+
payload: RawPacket::Ip(
267+
IpHdr::V6(header),
268+
ProtoHdr::Tcp(unsafe { *tcphdr }),
269+
),
270+
});
259271
}
260272
IpProto::Udp => {
261273
let udphdr: *const UdpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
@@ -275,20 +287,26 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
275287
{
276288
return Ok(TC_ACT_PIPE);
277289
}
278-
submit(RawPacket::Ip(
279-
IpHdr::V6(header),
280-
ProtoHdr::Udp(unsafe { *udphdr }),
281-
));
290+
submit(RawFrame {
291+
header: ethhdr,
292+
payload: RawPacket::Ip(
293+
IpHdr::V6(header),
294+
ProtoHdr::Udp(unsafe { *udphdr }),
295+
),
296+
});
282297
}
283298
IpProto::Icmp => {
284299
if filter_packet(Protocol::Network(NetworkProtocol::Icmp)) {
285300
return Ok(TC_ACT_PIPE);
286301
}
287302
let icmphdr: *const IcmpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
288-
submit(RawPacket::Ip(
289-
IpHdr::V6(header),
290-
ProtoHdr::Icmp(unsafe { *icmphdr }),
291-
));
303+
submit(RawFrame {
304+
header: ethhdr,
305+
payload: RawPacket::Ip(
306+
IpHdr::V6(header),
307+
ProtoHdr::Icmp(unsafe { *icmphdr }),
308+
),
309+
});
292310
}
293311
_ => {}
294312
}
@@ -298,7 +316,10 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
298316
return Ok(TC_ACT_PIPE);
299317
}
300318
let header: ArpHdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
301-
submit(RawPacket::Arp(header));
319+
submit(RawFrame {
320+
header: ethhdr,
321+
payload: RawPacket::Arp(header),
322+
});
302323
}
303324
_ => {}
304325
};

oryx-tui/src/app.rs

Lines changed: 17 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-
RawPacket,
5+
RawFrame,
66
};
77
use ratatui::{
88
layout::{Constraint, Direction, Layout},
@@ -19,7 +19,7 @@ use std::{
1919
use crate::{
2020
filter::Filter,
2121
help::Help,
22-
packet::{direction::TrafficDirection, NetworkPacket},
22+
packet::{direction::TrafficDirection, EthFrame},
2323
};
2424
use crate::{filter::IoChannels, notification::Notification};
2525
use crate::{packet::AppPacket, section::Section};
@@ -39,7 +39,7 @@ pub enum ActivePopup {
3939

4040
#[derive(Debug)]
4141
pub struct DataEventHandler {
42-
pub sender: kanal::Sender<[u8; RawPacket::LEN]>,
42+
pub sender: kanal::Sender<[u8; RawFrame::LEN]>,
4343
pub handler: thread::JoinHandle<()>,
4444
}
4545

@@ -49,39 +49,39 @@ pub struct App {
4949
pub help: Help,
5050
pub filter: Filter,
5151
pub start_sniffing: bool,
52-
pub packets: Arc<RwLock<Vec<AppPacket>>>,
52+
pub frames: Arc<RwLock<Vec<AppPacket>>>,
5353
pub notifications: Vec<Notification>,
5454
pub section: Section,
55-
pub data_channel_sender: kanal::Sender<([u8; RawPacket::LEN], TrafficDirection)>,
55+
pub data_channel_sender: kanal::Sender<([u8; RawFrame::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 packets = Arc::new(RwLock::new(Vec::with_capacity(
64-
RawPacket::LEN * 1024 * 1024,
65-
)));
63+
let frames = Arc::new(RwLock::new(Vec::with_capacity(RawFrame::LEN * 1024 * 1024)));
6664

6765
let (sender, receiver) = kanal::unbounded();
6866

6967
let firewall_channels = IoChannels::new();
7068

7169
thread::spawn({
72-
let packets = packets.clone();
70+
let frames = frames.clone();
7371
move || loop {
74-
if let Ok((raw_packet, direction)) = receiver.recv() {
75-
let network_packet = NetworkPacket::from(raw_packet);
76-
let mut packets = packets.write().unwrap();
77-
if packets.len() == packets.capacity() {
78-
packets.reserve(1024 * 1024);
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);
7978
}
8079
let app_packet = AppPacket {
80+
eth_header: eth_frame.header,
8181
packet: network_packet,
8282
direction,
8383
};
84-
packets.push(app_packet);
84+
frames.push(app_packet);
8585
}
8686
}
8787
});
@@ -186,9 +186,9 @@ impl App {
186186
direction,
187187
),
188188
start_sniffing: false,
189-
packets: packets.clone(),
189+
frames: frames.clone(),
190190
notifications: Vec::new(),
191-
section: Section::new(packets.clone(), firewall_channels.clone()),
191+
section: Section::new(frames.clone(), firewall_channels.clone()),
192192
data_channel_sender: sender,
193193
is_editing: false,
194194
active_popup: None,

oryx-tui/src/ebpf/egress.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use aya::{
1313
EbpfLoader,
1414
};
1515
use log::error;
16-
use oryx_common::{protocols::Protocol, RawPacket, MAX_RULES_PORT};
16+
use oryx_common::{protocols::Protocol, RawFrame, MAX_RULES_PORT};
1717

1818
use crate::{
1919
event::Event,
@@ -32,7 +32,7 @@ use super::{
3232
pub fn load_egress(
3333
iface: String,
3434
notification_sender: kanal::Sender<Event>,
35-
data_sender: kanal::Sender<([u8; RawPacket::LEN], TrafficDirection)>,
35+
data_sender: kanal::Sender<([u8; RawFrame::LEN], TrafficDirection)>,
3636
filter_channel_receiver: kanal::Receiver<FilterChannelSignal>,
3737
firewall_egress_receiver: kanal::Receiver<FirewallSignal>,
3838
terminate: Arc<AtomicBool>,
@@ -219,8 +219,8 @@ pub fn load_egress(
219219
if terminate.load(std::sync::atomic::Ordering::Relaxed) {
220220
break;
221221
}
222-
let packet: [u8; RawPacket::LEN] = item.to_owned().try_into().unwrap();
223-
data_sender.send((packet, TrafficDirection::Egress)).ok();
222+
let frame: [u8; RawFrame::LEN] = item.to_owned().try_into().unwrap();
223+
data_sender.send((frame, TrafficDirection::Egress)).ok();
224224
}
225225
}
226226
}

oryx-tui/src/ebpf/ingress.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use aya::{
1313
EbpfLoader,
1414
};
1515
use log::error;
16-
use oryx_common::{protocols::Protocol, RawPacket, MAX_RULES_PORT};
16+
use oryx_common::{protocols::Protocol, RawFrame, MAX_RULES_PORT};
1717

1818
use crate::{
1919
event::Event,
@@ -32,7 +32,7 @@ use super::{
3232
pub fn load_ingress(
3333
iface: String,
3434
notification_sender: kanal::Sender<Event>,
35-
data_sender: kanal::Sender<([u8; RawPacket::LEN], TrafficDirection)>,
35+
data_sender: kanal::Sender<([u8; RawFrame::LEN], TrafficDirection)>,
3636
filter_channel_receiver: kanal::Receiver<FilterChannelSignal>,
3737
firewall_ingress_receiver: kanal::Receiver<FirewallSignal>,
3838
terminate: Arc<AtomicBool>,
@@ -223,8 +223,8 @@ pub fn load_ingress(
223223
if terminate.load(std::sync::atomic::Ordering::Relaxed) {
224224
break;
225225
}
226-
let packet: [u8; RawPacket::LEN] = item.to_owned().try_into().unwrap();
227-
data_sender.send((packet, TrafficDirection::Ingress)).ok();
226+
let frame: [u8; RawFrame::LEN] = item.to_owned().try_into().unwrap();
227+
data_sender.send((frame, TrafficDirection::Ingress)).ok();
228228
}
229229
}
230230
}

0 commit comments

Comments
 (0)