use alloc::string::String;
use alloc::vec::Vec;
use core::net::IpAddr;
pub mod l2;
pub mod l3;
pub mod l4;
pub mod l7;
pub mod snmp {
#[doc(inline)]
pub use super::l7::snmp::*;
}
#[doc(inline)]
pub use l2::*;
#[doc(inline)]
pub use l3::*;
#[doc(inline)]
pub use l4::*;
#[doc(inline)]
pub use l7::*;
pub type IpAddress = core::net::IpAddr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Spanned<T> {
pub node: T,
pub span: (usize, usize),
}
impl<T> Spanned<T> {
pub fn new(node: T, span: (usize, usize)) -> Self {
Self { node, span }
}
}
impl<T> core::ops::Deref for Spanned<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.node
}
}
#[doc(alias = "HOST")]
#[doc(alias = "IP")]
#[doc(alias = "MAC")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HostDef<'a> {
pub name: &'a str,
pub ip: Option<IpAddr>,
pub mac: Option<[u8; 6]>,
pub span: (usize, usize),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Direction {
LeftToRight, RightToLeft, }
pub type ArrowDirection = Direction;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Protocol {
Tcp,
Udp,
Sctp,
Snmp1,
Snmp2,
Snmp3,
Arp,
Vlan,
Qinq,
Lldp,
Stp,
Lacp,
Eapol,
Mpls,
Icmp,
Ndp,
Igmp,
Mld,
Gre,
Vxlan,
Geneve,
Ipsec,
Esp,
Ah,
Ikev2,
Wireguard,
Ospf,
Bgp,
Rip,
Vrrp,
Hsrp,
Pim,
Bfd,
Openflow,
Dns,
Mdns,
Dhcp,
Ntp,
Ptp,
Radius,
Tacacs,
Syslog,
Netflow,
Ipfix,
Sflow,
Tftp,
Ftp,
Ssh,
Telnet,
Http,
Http2,
Grpc,
Websocket,
Tls,
Quic,
Stun,
Sip,
Rtp,
Rtsp,
Smtp,
Imap,
Pop3,
Kerberos,
Ldap,
Smb,
Nfs,
Redis,
Memcached,
Mysql,
Postgres,
Mqtt,
Coap,
Amqp,
Ssdp,
Whois,
Modbus,
Bacnet,
Dnp3,
S7comm,
Ethernetip,
Opcua,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProtocolSpec<'a> {
Tcp,
Udp,
Sctp(SctpParams),
Snmp1(Snmp1Spec<'a>),
Snmp2(Snmp2Spec<'a>),
Snmp3(Snmp3Spec<'a>),
Arp(ArpSpec<'a>),
Vlan(VlanSpec),
Qinq(QinqSpec),
Lldp(LldpSpec<'a>),
Stp(StpSpec<'a>),
Lacp(LacpSpec<'a>),
Eapol(EapolSpec<'a>),
Mpls(MplsSpec),
Icmp(IcmpSpec<'a>),
Ndp(NdpSpec<'a>),
Igmp(IgmpSpec<'a>),
Mld(MldSpec<'a>),
Gre(GreSpec<'a>),
Vxlan(VxlanSpec<'a>),
Geneve(GeneveSpec<'a>),
Ipsec(IpsecSpec<'a>),
Esp(IpsecSpec<'a>),
Ah(AhSpec<'a>),
Ikev2(Ikev2Spec<'a>),
Wireguard(WireguardSpec<'a>),
Ospf(OspfSpec<'a>),
Bgp(BgpSpec<'a>),
Rip(RipSpec<'a>),
Vrrp(VrrpSpec<'a>),
Hsrp(HsrpSpec<'a>),
Pim(PimSpec<'a>),
Bfd(BfdSpec<'a>),
Openflow(OpenflowSpec<'a>),
Dns(DnsSpec<'a>),
Mdns(DnsSpec<'a>),
Dhcp(DhcpSpec<'a>),
Ntp(NtpSpec<'a>),
Ptp(PtpSpec<'a>),
Radius(RadiusSpec<'a>),
Tacacs(TacacsSpec<'a>),
Syslog(SyslogSpec<'a>),
Netflow(NetflowSpec<'a>),
Ipfix(IpfixSpec<'a>),
Sflow(SflowSpec<'a>),
Tftp(TftpSpec<'a>),
Ftp(FtpSpec<'a>),
Ssh(SshSpec<'a>),
Telnet(TelnetSpec<'a>),
Http(HttpSpec<'a>),
Http2(Http2Spec<'a>),
Grpc(GrpcSpec<'a>),
Websocket(WebsocketSpec<'a>),
Tls(TlsSpec<'a>),
Quic(QuicSpec<'a>),
Stun(StunSpec<'a>),
Sip(SipSpec<'a>),
Rtp(RtpSpec<'a>),
Rtsp(RtspSpec<'a>),
Smtp(SmtpSpec<'a>),
Imap(ImapSpec<'a>),
Pop3(Pop3Spec<'a>),
Kerberos(KerberosSpec<'a>),
Ldap(LdapSpec<'a>),
Smb(SmbSpec<'a>),
Nfs(NfsSpec<'a>),
Redis(RedisSpec<'a>),
Memcached(MemcachedSpec<'a>),
Mysql(MysqlSpec<'a>),
Postgres(PostgresSpec<'a>),
Mqtt(MqttSpec<'a>),
Coap(CoapSpec<'a>),
Amqp(AmqpSpec<'a>),
Ssdp(SsdpSpec<'a>),
Whois(WhoisSpec<'a>),
Modbus(ModbusSpec<'a>),
Bacnet(BacnetSpec<'a>),
Dnp3(Dnp3Spec<'a>),
S7comm(S7commSpec<'a>),
Ethernetip(EthernetipSpec<'a>),
Opcua(OpcuaSpec<'a>),
Raw(Vec<u8>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FrameStatement<'a> {
pub caller: Spanned<&'a str>,
pub dir: Direction,
pub arrow: ArrowDirection,
pub callee: Spanned<&'a str>,
pub protocol: Protocol,
pub protocol_spec: Option<ProtocolSpec<'a>>,
pub l2: L2Modifiers,
pub l3: L3Modifiers,
pub l4: L4Modifiers,
pub payload: Option<String>,
pub hex_payload: Option<Vec<u8>>,
pub wait: Option<u64>,
pub span: (usize, usize),
pub raw_vlan: Option<(u32, (usize, usize))>,
pub raw_dscp: Option<(u32, (usize, usize))>,
pub raw_ecn: Option<(u32, (usize, usize))>,
pub raw_ttl: Option<(u32, (usize, usize))>,
pub raw_flowlabel: Option<(u32, (usize, usize))>,
pub raw_gentrap_span: Option<(usize, usize)>,
pub duplicate_modifiers: Vec<(String, (usize, usize))>,
pub src_port: Option<u16>,
pub dst_port: Option<u16>,
pub flags: Vec<TcpFlag>,
pub seq: Option<u32>,
pub ack_num: Option<u32>,
pub win: Option<u16>,
pub urgent: Option<u16>,
pub community: Option<&'a str>,
pub user: Option<&'a str>,
pub oid: Option<&'a str>,
pub sys_up_time: Option<u32>,
pub pdu_type: Option<SnmpPduType>,
pub enterprise: Option<&'a str>,
pub agent_ip: Option<IpAddr>,
pub gen_trap: Option<u32>,
pub spec_trap: Option<u32>,
pub engine_id: Option<&'a str>,
pub engine_boots: Option<u32>,
pub engine_time: Option<u32>,
pub context_name: Option<&'a str>,
pub auth: Option<(SnmpAuthType, &'a str)>,
pub priv_param: Option<(SnmpPrivType, &'a str)>,
pub varbinds: Vec<VarBindAst<'a>>,
pub non_repeaters: Option<u32>,
pub max_repetitions: Option<u32>,
pub req_id: Option<u32>,
}
impl<'a> FrameStatement<'a> {
pub fn effective_payload(&self) -> Option<&[u8]> {
if let Some(hex) = &self.hex_payload {
Some(hex.as_slice())
} else {
self.payload.as_deref().map(str::as_bytes)
}
}
}
#[doc(alias = "FLOW")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FlowDef<'a> {
pub name: &'a str,
pub params: Vec<&'a str>,
pub statements: Vec<FrameStatement<'a>>,
pub span: (usize, usize),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Argument<'a> {
Variable(&'a str),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TemplateInvocation<'a> {
pub name: &'a str,
pub args: Vec<Argument<'a>>,
pub span: (usize, usize),
}
#[doc(alias = "COMPILE")]
#[doc(alias = "LOOP")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RunStatement<'a> {
Invocation(TemplateInvocation<'a>),
Frame(alloc::boxed::Box<FrameStatement<'a>>),
Loop(u32, Vec<TemplateInvocation<'a>>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Program<'a> {
pub hosts: Vec<HostDef<'a>>,
pub flows: Vec<FlowDef<'a>>,
pub compile_block: Vec<RunStatement<'a>>,
}