Skip to content

Commit

Permalink
Merge pull request #69 from thearossman/main
Browse files Browse the repository at this point in the history
Two documentation changes
  • Loading branch information
thearossman authored Oct 22, 2024
2 parents 92087d4 + bb51337 commit 4559c08
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 31 deletions.
10 changes: 10 additions & 0 deletions core/src/filter/ptree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,16 @@ impl PTree {
return;
}

if !matches!(self.filter_layer, FilterLayer::PacketContinue) && predicate.req_packet() {
// To get similar behavior, users should subscribe to individual mbufs or
// the mbuf list, then filter within the callback.
// Because (for now) all packets would need to be tracked anyway, doing this
// is equivalent performance-wise to implementing similar functionality in the
// framework.
panic!("Cannot access per-packet fields (e.g., TCP flags, length) after packet filter.\n\
Subscribe to `ZcFrame` or PacketList instead.");
}

// Predicate is already present

if node.has_descendant(predicate) {
Expand Down
16 changes: 1 addition & 15 deletions datatypes/src/static_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
//! A data type is considered "static" if it can be inferred at or before
//! the first packet in a connection and it stays constant throughout a connection.

use super::{FromSubscription, StaticData};
use super::StaticData;
use pnet::datalink::MacAddr;
use retina_core::conntrack::conn_id::FiveTuple;
use retina_core::conntrack::pdu::L4Pdu;
use retina_core::filter::SubscriptionSpec;

/// Subscribable alias for [`retina_core::FiveTuple`]
impl StaticData for FiveTuple {
Expand All @@ -32,19 +31,6 @@ impl StaticData for EtherTCI {
}
}

use proc_macro2::Span;
use quote::quote;

/// The string literal representing a matched filter.
pub type FilterStr<'a> = &'a str;

impl<'a> FromSubscription for FilterStr<'a> {
fn from_subscription(spec: &SubscriptionSpec) -> proc_macro2::TokenStream {
let str = syn::LitStr::new(&spec.filter, Span::call_site());
quote! { &#str }
}
}

/// The src/dst MAC of a connection
#[derive(Clone, Debug)]
pub struct EthAddr {
Expand Down
48 changes: 32 additions & 16 deletions datatypes/src/typedefs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
//! Newly-defined datatypes must be added to the DATATYPES map in this module.

use lazy_static::lazy_static;
use retina_core::filter::{DataType, Level};
use proc_macro2::Span;
use quote::quote;
use retina_core::filter::{DataType, Level, SubscriptionSpec};
use std::collections::HashMap;

use crate::*;

// To add a datatype, add it to the following map
// This is read by the filtergen crate.
lazy_static! {
/// To add a datatype, add it to the following map
/// This is read by the filtergen crate.
pub static ref DATATYPES: HashMap<&'static str, DataType> = {
HashMap::from([
("ConnRecord", DataType::new_default_connection("ConnRecord")),
Expand Down Expand Up @@ -84,27 +86,41 @@ lazy_static! {
// Special cases: have specific conditions in generated code
// \Note ideally these would be implemented more cleanly
lazy_static! {
// To avoid copying, the `Tracked` structure in the framework --
// built at compile time -- will track certain generic, raw datatypes
// if a subset of subscriptions require them.
//
// For example: buffering packets may be required as a pre-match action for a
// packet-level datatype; it may also be required if one or more subscriptions request
// a connection-level `PacketList`. Rather than maintaining these lists separately --
// one for filtering and one for delivery -- the tracked packets are stored once.
//
// Core ID is a special case, as it cannot be derived from connection,
// session, or packet data. It is simpler to define it as a directly tracked datatype.
/// To avoid copying, the `Tracked` structure in the framework --
/// built at compile time -- will track certain generic, raw datatypes
/// if a subset of subscriptions require them.
///
/// For example: buffering packets may be required as a pre-match action for a
/// packet-level datatype; it may also be required if one or more subscriptions request
/// a connection-level `PacketList`. Rather than maintaining these lists separately --
/// one for filtering and one for delivery -- the tracked packets are stored once.
///
/// Core ID is a special case, as it cannot be derived from connection,
/// session, or packet data. It is simpler to define it as a directly tracked datatype.
///
/// The directly tracked datatypes are: PacketList, SessionList, and CoreId
pub static ref DIRECTLY_TRACKED: HashMap<&'static str, &'static str> = HashMap::from([
("PacketList", "packets"),
("SessionList", "sessions"),
("CoreId", "core_id")
]);

// Another special case -- datatype is the matched filter as a string literal.
// \TODO ideally this would be a map to from_subscription function pointers
// See `FilterStr`
pub static ref FILTER_STR: &'static str = "FilterStr";
}

/// A list of all packets (zero-copy) seen in the connection.
/// For TCP connections, these packets will be in post-reassembly order.
pub type PacketList = Vec<Mbuf>;
/// A list of all sessions (zero-copy) parsed in the connection.
pub type SessionList = Vec<Session>;

/// The string literal representing a matched filter.
pub type FilterStr<'a> = &'a str;

impl<'a> FromSubscription for FilterStr<'a> {
fn from_subscription(spec: &SubscriptionSpec) -> proc_macro2::TokenStream {
let str = syn::LitStr::new(&spec.filter, Span::call_site());
quote! { &#str }
}
}

0 comments on commit 4559c08

Please sign in to comment.