Skip to content

Commit

Permalink
refactor ip packets representation
Browse files Browse the repository at this point in the history
  • Loading branch information
pythops committed Sep 19, 2024
1 parent 79876b1 commit cd61fc1
Show file tree
Hide file tree
Showing 6 changed files with 360 additions and 285 deletions.
124 changes: 83 additions & 41 deletions oryx-common/src/ip.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,56 @@
use core::{fmt::Display, net::IpAddr};
use core::fmt::Display;

use network_types::{icmp::IcmpHdr, tcp::TcpHdr, udp::UdpHdr};
use core::net::{Ipv4Addr, Ipv6Addr};

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub enum IpPacket {
V4(Ipv4Packet),
V6(Ipv6Packet),
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Ipv4Packet {
pub src_ip: Ipv4Addr,
pub dst_ip: Ipv4Addr,
pub proto: IpProto,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Ipv6Packet {
pub src_ip: Ipv6Addr,
pub dst_ip: Ipv6Addr,
pub proto: IpProto,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub enum IpProto {
Tcp(TcpPacket),
Udp(UdpPacket),
Icmp(IcmpPacket),
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TcpPacket {
pub dst_port: u16,
pub src_port: u16,
pub dst_ip: IpAddr,
pub src_ip: IpAddr,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct UdpPacket {
pub dst_port: u16,
pub src_port: u16,
pub dst_ip: IpAddr,
pub src_ip: IpAddr,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct IcmpPacket {
pub icmp_type: IcmpType,
pub dst_ip: IpAddr,
pub src_ip: IpAddr,
}

#[repr(C)]
Expand All @@ -52,42 +77,59 @@ impl Display for IcmpType {
}
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub enum IpPacket {
Tcp(TcpPacket),
Udp(UdpPacket),
Icmp(IcmpPacket),
}

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

impl Display for IpPacket {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
IpPacket::Tcp(p) => {
write!(
f,
"{} {} {} {} TCP",
p.src_ip, p.src_port, p.dst_ip, p.dst_port
)
}
IpPacket::Udp(p) => {
write!(
f,
"{} {} {} {} UDP",
p.src_ip, p.src_port, p.dst_ip, p.dst_port
)
}
IpPacket::Icmp(p) => {
write!(f, "{} {} ICMP", p.src_ip, p.dst_ip)
}
IpPacket::V4(ipv4_packet) => match ipv4_packet.proto {
IpProto::Tcp(tcp_packet) => {
write!(
f,
"{} {} {} {} TCP",
ipv4_packet.src_ip,
tcp_packet.src_port,
ipv4_packet.dst_ip,
tcp_packet.dst_port
)
}
IpProto::Udp(udp_packet) => {
write!(
f,
"{} {} {} {} UDP",
ipv4_packet.src_ip,
udp_packet.src_port,
ipv4_packet.dst_ip,
udp_packet.dst_port
)
}
IpProto::Icmp(_) => {
write!(f, "{} {} ICMP", ipv4_packet.src_ip, ipv4_packet.dst_ip)
}
},
IpPacket::V6(ipv6_packet) => match ipv6_packet.proto {
IpProto::Tcp(tcp_packet) => {
write!(
f,
"{} {} {} {} TCP",
ipv6_packet.src_ip,
tcp_packet.src_port,
ipv6_packet.dst_ip,
tcp_packet.dst_port
)
}
IpProto::Udp(udp_packet) => {
write!(
f,
"{} {} {} {} UDP",
ipv6_packet.src_ip,
udp_packet.src_port,
ipv6_packet.dst_ip,
udp_packet.dst_port
)
}
IpProto::Icmp(_) => {
write!(f, "{} {} ICMP", ipv6_packet.src_ip, ipv6_packet.dst_ip)
}
},
}
}
}
142 changes: 68 additions & 74 deletions oryx-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
#![no_std]

use core::{
fmt::Display,
mem,
net::{IpAddr, Ipv4Addr},
};
use core::{fmt::Display, mem, net::Ipv4Addr};

use arp::{ArpPacket, ArpType, MacAddr};
use ip::{IcmpPacket, IcmpType, IpPacket, ProtoHdr, TcpPacket, UdpPacket};
use network_types::{arp::ArpHdr, ip::IpHdr};
use ip::{IcmpPacket, IcmpType, IpPacket, IpProto, Ipv4Packet, Ipv6Packet, TcpPacket, UdpPacket};
use network_types::{arp::ArpHdr, icmp::IcmpHdr, ip::IpHdr, tcp::TcpHdr, udp::UdpHdr};

pub mod arp;
pub mod ip;
pub mod protocols;

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

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

impl RawPacket {
pub const LEN: usize = mem::size_of::<RawPacket>();
}
Expand Down Expand Up @@ -49,74 +53,64 @@ impl From<[u8; RawPacket::LEN]> for AppPacket {
let raw_packet = value.as_ptr() as *const RawPacket;
match unsafe { &*raw_packet } {
RawPacket::Ip(packet, proto) => match packet {
IpHdr::V4(ipv4_packet) => match proto {
ProtoHdr::Tcp(header) => {
let tcp_packet = TcpPacket {
src_ip: IpAddr::V4(Ipv4Addr::from(u32::from_be(ipv4_packet.src_addr))),
src_port: u16::from_be(header.source),
dst_ip: IpAddr::V4(Ipv4Addr::from(u32::from_be(ipv4_packet.dst_addr))),
dst_port: u16::from_be(header.dest),
};
AppPacket::Ip(IpPacket::Tcp(tcp_packet))
}
ProtoHdr::Udp(header) => {
let udp_packet = UdpPacket {
src_ip: IpAddr::V4(Ipv4Addr::from(u32::from_be(ipv4_packet.src_addr))),
src_port: u16::from_be(header.source),
dst_ip: IpAddr::V4(Ipv4Addr::from(u32::from_be(ipv4_packet.dst_addr))),
dst_port: u16::from_be(header.dest),
};
Self::Ip(IpPacket::Udp(udp_packet))
}
ProtoHdr::Icmp(header) => {
let icmp_type = match header.type_ {
0 => IcmpType::EchoRequest,
1 => IcmpType::EchoReply,
_ => IcmpType::DestinationUnreachable,
};
IpHdr::V4(ipv4_packet) => {
let src_ip = Ipv4Addr::from(u32::from_be(ipv4_packet.src_addr));
let dst_ip = Ipv4Addr::from(u32::from_be(ipv4_packet.dst_addr));

let proto = match proto {
ProtoHdr::Tcp(tcp_header) => IpProto::Tcp(TcpPacket {
src_port: u16::from_be(tcp_header.source),
dst_port: u16::from_be(tcp_header.dest),
}),
ProtoHdr::Udp(udp_header) => IpProto::Udp(UdpPacket {
src_port: u16::from_be(udp_header.source),
dst_port: u16::from_be(udp_header.dest),
}),
ProtoHdr::Icmp(header) => {
let icmp_type = match header.type_ {
0 => IcmpType::EchoRequest,
1 => IcmpType::EchoReply,
_ => IcmpType::DestinationUnreachable,
};
IpProto::Icmp(IcmpPacket { icmp_type })
}
};

AppPacket::Ip(IpPacket::V4(Ipv4Packet {
src_ip,
dst_ip,
proto,
}))
}
IpHdr::V6(ipv6_packet) => {
let src_ip = ipv6_packet.src_addr();
let dst_ip = ipv6_packet.dst_addr();

let icmp_packet = IcmpPacket {
src_ip: IpAddr::V4(Ipv4Addr::from(u32::from_be(ipv4_packet.src_addr))),
dst_ip: IpAddr::V4(Ipv4Addr::from(u32::from_be(ipv4_packet.dst_addr))),
icmp_type,
};
Self::Ip(IpPacket::Icmp(icmp_packet))
}
},
IpHdr::V6(ipv6_packet) => match proto {
ProtoHdr::Tcp(header) => {
let tcp_packet = TcpPacket {
src_ip: IpAddr::V6(ipv6_packet.src_addr()),
src_port: u16::from_be(header.source),
dst_ip: IpAddr::V6(ipv6_packet.dst_addr()),
dst_port: u16::from_be(header.dest),
};
Self::Ip(IpPacket::Tcp(tcp_packet))
}
ProtoHdr::Udp(header) => {
let udp_packet = UdpPacket {
src_ip: IpAddr::V6(ipv6_packet.src_addr()),
src_port: u16::from_be(header.source),
dst_ip: IpAddr::V6(ipv6_packet.dst_addr()),
dst_port: u16::from_be(header.dest),
};
Self::Ip(IpPacket::Udp(udp_packet))
}
ProtoHdr::Icmp(header) => {
let icmp_type = match header.type_ {
0 => IcmpType::EchoRequest,
1 => IcmpType::EchoReply,
_ => IcmpType::DestinationUnreachable,
};
let proto = match proto {
ProtoHdr::Tcp(tcp_header) => IpProto::Tcp(TcpPacket {
src_port: u16::from_be(tcp_header.source),
dst_port: u16::from_be(tcp_header.dest),
}),
ProtoHdr::Udp(udp_header) => IpProto::Udp(UdpPacket {
src_port: u16::from_be(udp_header.source),
dst_port: u16::from_be(udp_header.dest),
}),
ProtoHdr::Icmp(header) => {
let icmp_type = match header.type_ {
0 => IcmpType::EchoRequest,
1 => IcmpType::EchoReply,
_ => IcmpType::DestinationUnreachable,
};
IpProto::Icmp(IcmpPacket { icmp_type })
}
};

let icmp_packet = IcmpPacket {
src_ip: IpAddr::V6(ipv6_packet.src_addr()),
dst_ip: IpAddr::V6(ipv6_packet.dst_addr()),
icmp_type,
};
Self::Ip(IpPacket::Icmp(icmp_packet))
}
},
AppPacket::Ip(IpPacket::V6(Ipv6Packet {
src_ip,
dst_ip,
proto,
}))
}
},
RawPacket::Arp(packet) => {
let arp_type = match u16::from_be(packet.oper) {
Expand Down
3 changes: 1 addition & 2 deletions oryx-ebpf/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ use network_types::{
udp::UdpHdr,
};
use oryx_common::{
ip::ProtoHdr,
protocols::{LinkProtocol, NetworkProtocol, Protocol, TransportProtocol},
RawPacket,
ProtoHdr, RawPacket,
};

#[map]
Expand Down
Loading

0 comments on commit cd61fc1

Please sign in to comment.