use alloc::string::String;
use alloc::vec::Vec;
use crate::ast::{Protocol, TransportProto};
use crate::reverse::{ProtocolDissection, push_if};
use super::{is_printable_ascii_str, push_str_if};
pub(crate) fn dissect_syslog(payload: &[u8], is_tcp: bool) -> Option<ProtocolDissection> {
let text = is_printable_ascii_str(payload)?;
if !text.starts_with('<') {
return None;
}
let close_idx = text.find('>').filter(|&i| i <= 4)?;
let pri = text[1..close_idx].parse::<u8>().ok()?;
let after_pri = &text[close_idx + 1..];
let mut tokens = String::from("syslog");
push_if(&mut tokens, "pri", pri, 14);
if let Some(rest) = after_pri.strip_prefix("1 ") {
let (_ts, r1) = rest.split_once(' ')?;
let (hostname, r2) = r1.split_once(' ')?;
let (app, r3) = r2.split_once(' ')?;
let (procid, r4) = r3.split_once(' ')?;
let (msgid, r5) = r4.split_once(' ')?;
let (_sd, msg) = r5.split_once(' ')?;
push_str_if(&mut tokens, "hostname", hostname, "");
push_str_if(&mut tokens, "app", app, "app");
push_str_if(&mut tokens, "procid", procid, "-");
push_str_if(&mut tokens, "msgid", msgid, "-");
push_str_if(&mut tokens, "msg", msg, "System notification");
} else {
push_str_if(
&mut tokens,
"msg",
after_pri.trim_start(),
"System notification",
);
}
Some(ProtocolDissection {
protocol: Protocol::Syslog,
tokens,
residual_payload: Vec::new(),
explicit_transport: is_tcp.then_some(TransportProto::Tcp),
})
}