-/* Copyright (C) 2021 Open Information Security Foundation
+/* Copyright (C) 2021-2023 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
let name = input.ident;
let mut fields = Vec::new();
- let mut vals = Vec::new();
- let mut cstrings = Vec::new();
- let mut names = Vec::new();
+ let mut event_ids = Vec::new();
+ let mut event_cstrings = Vec::new();
+ let mut event_names = Vec::new();
match input.data {
syn::Data::Enum(ref data) => {
for (i, v) in (&data.variants).into_iter().enumerate() {
fields.push(v.ident.clone());
- let name = transform_name(&v.ident.to_string());
- let cname = format!("{}\0", name);
- names.push(name);
- cstrings.push(cname);
- vals.push(i as i32);
+ let event_name = if let Some(xname) = parse_name(&v.attrs) {
+ xname.value()
+ } else {
+ transform_name(&v.ident.to_string())
+ };
+ let cname = format!("{}\0", event_name);
+ event_names.push(event_name);
+ event_cstrings.push(cname);
+ event_ids.push(i as i32);
}
}
_ => panic!("AppLayerEvent can only be derived for enums"),
impl #crate_id::applayer::AppLayerEvent for #name {
fn from_id(id: i32) -> Option<#name> {
match id {
- #( #vals => Some(#name::#fields) ,)*
+ #( #event_ids => Some(#name::#fields) ,)*
_ => None,
}
}
fn as_i32(&self) -> i32 {
match *self {
- #( #name::#fields => #vals ,)*
+ #( #name::#fields => #event_ids ,)*
}
}
fn to_cstring(&self) -> &str {
match *self {
- #( #name::#fields => #cstrings ,)*
+ #( #name::#fields => #event_cstrings ,)*
}
}
fn from_string(s: &str) -> Option<#name> {
match s {
- #( #names => Some(#name::#fields) ,)*
+ #( #event_names => Some(#name::#fields) ,)*
_ => None
}
}
out
}
+/// Parse the event name from the "name" attribute.
+///
+/// For example:
+/// ```ignore
+/// #[derive(AppLayerEvent)]
+/// pub enum FtpEvent {
+/// #[name("request_command_too_long")]
+/// FtpEventRequestCommandTooLong,
+/// #[name("response_command_too_long")]
+/// FtpEventResponseCommandTooLong,
+/// }
+/// ```
+fn parse_name(attrs: &[syn::Attribute]) -> Option<syn::LitStr> {
+ for attr in attrs {
+ if attr.path.is_ident("name") {
+ if let Ok(val) = attr.parse_args::<syn::LitStr>() {
+ return Some(val);
+ }
+ }
+ }
+ None
+}
+
#[cfg(test)]
mod test {
use super::*;
-/* Copyright (C) 2020 Open Information Security Foundation
+/* Copyright (C) 2020-2023 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
/// MalformedData,
/// NotRequest,
/// NotResponse,
+/// #[name("reserved_z_flag_set")]
/// ZFlagSet,
/// }
///
/// The enum variants must follow the naming convention of OneTwoThree
-/// for proper conversion to the name used in rules (one_tow_three).
-#[proc_macro_derive(AppLayerEvent)]
+/// for proper conversion to the name used in rules (one_tow_three) or
+/// optionally add a name attribute.
+#[proc_macro_derive(AppLayerEvent, attributes(name))]
pub fn derive_app_layer_event(input: TokenStream) -> TokenStream {
applayerevent::derive_app_layer_event(input)
}