Skip to content

Add frame information to packet info popup #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions oryx-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,46 @@

use core::mem;

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

pub mod protocols;

pub const MAX_FIREWALL_RULES: u32 = 32;
pub const MAX_RULES_PORT: usize = 32;

#[repr(C)]
#[derive(Clone)]
pub struct RawFrame {
pub header: EthHdr,
pub payload: RawPacket,
}

impl RawFrame {
pub const LEN: usize = mem::size_of::<RawFrame>();
}

#[repr(C)]
pub enum RawPacket {
Ip(IpHdr, ProtoHdr),
Arp(ArpHdr),
}

impl Clone for RawPacket {
fn clone(&self) -> Self {
match self {
Self::Ip(ip_hdr, proto_hdr) => match ip_hdr {
IpHdr::V4(ipv4_hdr) => Self::Ip(IpHdr::V4(*ipv4_hdr), *proto_hdr),
IpHdr::V6(ipv6_hdr) => Self::Ip(IpHdr::V6(*ipv6_hdr), *proto_hdr),
},
Self::Arp(arp_hdr) => Self::Arp(*arp_hdr),
}
}
}

#[repr(C)]
#[derive(Copy, Clone)]
pub enum ProtoHdr {
Tcp(TcpHdr),
Udp(UdpHdr),
Icmp(IcmpHdr),
}

impl RawPacket {
pub const LEN: usize = mem::size_of::<RawPacket>();
}
79 changes: 50 additions & 29 deletions oryx-ebpf/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ use network_types::{
};
use oryx_common::{
protocols::{LinkProtocol, NetworkProtocol, Protocol, TransportProtocol},
ProtoHdr, RawPacket, MAX_FIREWALL_RULES, MAX_RULES_PORT,
ProtoHdr, RawFrame, RawPacket, MAX_FIREWALL_RULES, MAX_RULES_PORT,
};

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

#[map]
static NETWORK_FILTERS: Array<u32> = Array::with_max_entries(8, 0);
Expand Down Expand Up @@ -56,8 +56,8 @@ pub fn oryx(ctx: TcContext) -> i32 {
}

#[inline]
fn submit(packet: RawPacket) {
if let Some(mut buf) = DATA.reserve::<RawPacket>(0) {
fn submit(packet: RawFrame) {
if let Some(mut buf) = DATA.reserve::<RawFrame>(0) {
unsafe { (*buf.as_mut_ptr()) = packet };
buf.submit(0);
}
Expand Down Expand Up @@ -183,10 +183,13 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
return Ok(TC_ACT_PIPE);
}

submit(RawPacket::Ip(
IpHdr::V4(header),
ProtoHdr::Tcp(unsafe { *tcphdr }),
));
submit(RawFrame {
header: ethhdr,
payload: RawPacket::Ip(
IpHdr::V4(header),
ProtoHdr::Tcp(unsafe { *tcphdr }),
),
});
}
IpProto::Udp => {
let udphdr: *const UdpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
Expand All @@ -207,20 +210,26 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
return Ok(TC_ACT_PIPE);
}

submit(RawPacket::Ip(
IpHdr::V4(header),
ProtoHdr::Udp(unsafe { *udphdr }),
));
submit(RawFrame {
header: ethhdr,
payload: RawPacket::Ip(
IpHdr::V4(header),
ProtoHdr::Udp(unsafe { *udphdr }),
),
});
}
IpProto::Icmp => {
if filter_packet(Protocol::Network(NetworkProtocol::Icmp)) {
return Ok(TC_ACT_PIPE);
}
let icmphdr: *const IcmpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
submit(RawPacket::Ip(
IpHdr::V4(header),
ProtoHdr::Icmp(unsafe { *icmphdr }),
));
submit(RawFrame {
header: ethhdr,
payload: RawPacket::Ip(
IpHdr::V4(header),
ProtoHdr::Icmp(unsafe { *icmphdr }),
),
});
}
_ => {}
}
Expand Down Expand Up @@ -252,10 +261,13 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
{
return Ok(TC_ACT_PIPE);
}
submit(RawPacket::Ip(
IpHdr::V6(header),
ProtoHdr::Tcp(unsafe { *tcphdr }),
));
submit(RawFrame {
header: ethhdr,
payload: RawPacket::Ip(
IpHdr::V6(header),
ProtoHdr::Tcp(unsafe { *tcphdr }),
),
});
}
IpProto::Udp => {
let udphdr: *const UdpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
Expand All @@ -275,20 +287,26 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
{
return Ok(TC_ACT_PIPE);
}
submit(RawPacket::Ip(
IpHdr::V6(header),
ProtoHdr::Udp(unsafe { *udphdr }),
));
submit(RawFrame {
header: ethhdr,
payload: RawPacket::Ip(
IpHdr::V6(header),
ProtoHdr::Udp(unsafe { *udphdr }),
),
});
}
IpProto::Icmp => {
if filter_packet(Protocol::Network(NetworkProtocol::Icmp)) {
return Ok(TC_ACT_PIPE);
}
let icmphdr: *const IcmpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
submit(RawPacket::Ip(
IpHdr::V6(header),
ProtoHdr::Icmp(unsafe { *icmphdr }),
));
submit(RawFrame {
header: ethhdr,
payload: RawPacket::Ip(
IpHdr::V6(header),
ProtoHdr::Icmp(unsafe { *icmphdr }),
),
});
}
_ => {}
}
Expand All @@ -298,7 +316,10 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
return Ok(TC_ACT_PIPE);
}
let header: ArpHdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
submit(RawPacket::Arp(header));
submit(RawFrame {
header: ethhdr,
payload: RawPacket::Arp(header),
});
}
_ => {}
};
Expand Down
18 changes: 9 additions & 9 deletions oryx-tui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use clap::ArgMatches;
use itertools::Itertools;
use oryx_common::{
protocols::{LinkProtocol, NetworkProtocol, TransportProtocol},
RawPacket,
RawFrame,
};
use ratatui::{
layout::{Constraint, Direction, Layout},
Expand All @@ -19,7 +19,7 @@ use std::{
use crate::{
filter::Filter,
help::Help,
packet::{direction::TrafficDirection, NetworkPacket},
packet::{direction::TrafficDirection, EthFrame},
};
use crate::{filter::IoChannels, notification::Notification};
use crate::{packet::AppPacket, section::Section};
Expand All @@ -39,7 +39,7 @@ pub enum ActivePopup {

#[derive(Debug)]
pub struct DataEventHandler {
pub sender: kanal::Sender<[u8; RawPacket::LEN]>,
pub sender: kanal::Sender<[u8; RawFrame::LEN]>,
pub handler: thread::JoinHandle<()>,
}

Expand All @@ -52,17 +52,15 @@ pub struct App {
pub packets: Arc<RwLock<Vec<AppPacket>>>,
pub notifications: Vec<Notification>,
pub section: Section,
pub data_channel_sender: kanal::Sender<([u8; RawPacket::LEN], TrafficDirection)>,
pub data_channel_sender: kanal::Sender<([u8; RawFrame::LEN], TrafficDirection)>,
pub is_editing: bool,
pub active_popup: Option<ActivePopup>,
pub start_from_cli: bool,
}

impl App {
pub fn new(cli_args: &ArgMatches) -> Self {
let packets = Arc::new(RwLock::new(Vec::with_capacity(
RawPacket::LEN * 1024 * 1024,
)));
let packets = Arc::new(RwLock::new(Vec::with_capacity(RawFrame::LEN * 1024 * 1024)));

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

Expand All @@ -71,13 +69,15 @@ impl App {
thread::spawn({
let packets = packets.clone();
move || loop {
if let Ok((raw_packet, direction)) = receiver.recv() {
let network_packet = NetworkPacket::from(raw_packet);
if let Ok((raw_frame, direction)) = receiver.recv() {
let eth_frame = EthFrame::from(raw_frame);
let network_packet = eth_frame.payload;
let mut packets = packets.write().unwrap();
if packets.len() == packets.capacity() {
packets.reserve(1024 * 1024);
}
let app_packet = AppPacket {
eth_header: eth_frame.header,
packet: network_packet,
direction,
};
Expand Down
8 changes: 4 additions & 4 deletions oryx-tui/src/ebpf/egress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use aya::{
EbpfLoader,
};
use log::error;
use oryx_common::{protocols::Protocol, RawPacket, MAX_RULES_PORT};
use oryx_common::{protocols::Protocol, RawFrame, MAX_RULES_PORT};

use crate::{
event::Event,
Expand All @@ -32,7 +32,7 @@ use super::{
pub fn load_egress(
iface: String,
notification_sender: kanal::Sender<Event>,
data_sender: kanal::Sender<([u8; RawPacket::LEN], TrafficDirection)>,
data_sender: kanal::Sender<([u8; RawFrame::LEN], TrafficDirection)>,
filter_channel_receiver: kanal::Receiver<FilterChannelSignal>,
firewall_egress_receiver: kanal::Receiver<FirewallSignal>,
terminate: Arc<AtomicBool>,
Expand Down Expand Up @@ -219,8 +219,8 @@ pub fn load_egress(
if terminate.load(std::sync::atomic::Ordering::Relaxed) {
break;
}
let packet: [u8; RawPacket::LEN] = item.to_owned().try_into().unwrap();
data_sender.send((packet, TrafficDirection::Egress)).ok();
let frame: [u8; RawFrame::LEN] = item.to_owned().try_into().unwrap();
data_sender.send((frame, TrafficDirection::Egress)).ok();
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions oryx-tui/src/ebpf/ingress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use aya::{
EbpfLoader,
};
use log::error;
use oryx_common::{protocols::Protocol, RawPacket, MAX_RULES_PORT};
use oryx_common::{protocols::Protocol, RawFrame, MAX_RULES_PORT};

use crate::{
event::Event,
Expand All @@ -32,7 +32,7 @@ use super::{
pub fn load_ingress(
iface: String,
notification_sender: kanal::Sender<Event>,
data_sender: kanal::Sender<([u8; RawPacket::LEN], TrafficDirection)>,
data_sender: kanal::Sender<([u8; RawFrame::LEN], TrafficDirection)>,
filter_channel_receiver: kanal::Receiver<FilterChannelSignal>,
firewall_ingress_receiver: kanal::Receiver<FirewallSignal>,
terminate: Arc<AtomicBool>,
Expand Down Expand Up @@ -223,8 +223,8 @@ pub fn load_ingress(
if terminate.load(std::sync::atomic::Ordering::Relaxed) {
break;
}
let packet: [u8; RawPacket::LEN] = item.to_owned().try_into().unwrap();
data_sender.send((packet, TrafficDirection::Ingress)).ok();
let frame: [u8; RawFrame::LEN] = item.to_owned().try_into().unwrap();
data_sender.send((frame, TrafficDirection::Ingress)).ok();
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions oryx-tui/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use oryx_common::{
LinkProtocol, NetworkProtocol, Protocol, TransportProtocol, NB_LINK_PROTOCOL,
NB_NETWORK_PROTOCOL, NB_TRANSPORT_PROTOCOL,
},
RawPacket,
RawFrame,
};
use ratatui::{
layout::{Alignment, Constraint, Direction, Flex, Layout, Margin, Rect},
Expand Down Expand Up @@ -159,7 +159,7 @@ impl Filter {
pub fn start(
&mut self,
notification_sender: kanal::Sender<Event>,
data_sender: kanal::Sender<([u8; RawPacket::LEN], TrafficDirection)>,
data_sender: kanal::Sender<([u8; RawFrame::LEN], TrafficDirection)>,
) -> AppResult<()> {
let iface = self.interface.selected_interface.name.clone();

Expand Down Expand Up @@ -645,12 +645,12 @@ impl Filter {
.map(|filter| {
if self.transport.applied_protocols.contains(filter) {
Span::styled(
format!(" {} ", filter),
format!(" {filter} "),
Style::default().light_green(),
)
} else {
Span::styled(
format!(" {} ", filter),
format!(" {filter} "),
Style::default().light_red(),
)
}
Expand All @@ -666,12 +666,12 @@ impl Filter {
.map(|filter| {
if self.network.applied_protocols.contains(filter) {
Span::styled(
format!(" {} ", filter),
format!(" {filter} "),
Style::default().light_green(),
)
} else {
Span::styled(
format!(" {} ", filter),
format!(" {filter} "),
Style::default().light_red(),
)
}
Expand All @@ -687,12 +687,12 @@ impl Filter {
.map(|filter| {
if self.link.applied_protocols.contains(filter) {
Span::styled(
format!(" {} ", filter),
format!(" {filter} "),
Style::default().light_green(),
)
} else {
Span::styled(
format!(" {} ", filter),
format!(" {filter} "),
Style::default().light_red(),
)
}
Expand All @@ -708,12 +708,12 @@ impl Filter {
.map(|filter| {
if self.traffic_direction.applied_direction.contains(filter) {
Span::styled(
format!("󰞁 {} ", filter),
format!("󰞁 {filter} "),
Style::default().light_green(),
)
} else {
Span::styled(
format!("󰿝 {} ", filter),
format!("󰿝 {filter} "),
Style::default().light_red(),
)
}
Expand Down
Loading