mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
5.3 KiB
Rust
148 lines
5.3 KiB
Rust
/* Copyright (C) 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
|
|
* Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* version 2 along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
//! Utility library module for commonly used strings, hexadecimals and other elements.
|
|
|
|
use crate::jsonbuilder::HEX;
|
|
|
|
pub mod nom7 {
|
|
use nom7::bytes::streaming::{tag, take_until};
|
|
use nom7::error::{Error, ParseError};
|
|
use nom7::ErrorConvert;
|
|
use nom7::IResult;
|
|
|
|
/// Reimplementation of `take_until_and_consume` for nom 7
|
|
///
|
|
/// `take_until` does not consume the matched tag, and
|
|
/// `take_until_and_consume` was removed in nom 7. This function
|
|
/// provides an implementation (specialized for `&[u8]`).
|
|
pub fn take_until_and_consume<'a, E: ParseError<&'a [u8]>>(
|
|
t: &'a [u8],
|
|
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], &'a [u8], E> {
|
|
move |i: &'a [u8]| {
|
|
let (i, res) = take_until(t)(i)?;
|
|
let (i, _) = tag(t)(i)?;
|
|
Ok((i, res))
|
|
}
|
|
}
|
|
|
|
/// Specialized version of the nom 7 `bits` combinator
|
|
///
|
|
/// The `bits combinator has trouble inferring the transient error type
|
|
/// used by the tuple parser, because the function is generic and any
|
|
/// error type would be valid.
|
|
/// Use an explicit error type (as described in
|
|
/// https://docs.rs/nom/7.1.0/nom/bits/fn.bits.html) to solve this problem, and
|
|
/// specialize this function for `&[u8]`.
|
|
pub fn bits<'a, O, E, P>(parser: P) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], O, E>
|
|
where
|
|
E: ParseError<&'a [u8]>,
|
|
Error<(&'a [u8], usize)>: ErrorConvert<E>,
|
|
P: FnMut((&'a [u8], usize)) -> IResult<(&'a [u8], usize), O, Error<(&'a [u8], usize)>>,
|
|
{
|
|
// use full path to disambiguate nom `bits` from this current function name
|
|
nom7::bits::bits(parser)
|
|
}
|
|
}
|
|
|
|
pub mod nom8 {
|
|
use nom8::bytes::streaming::{tag, take_until};
|
|
use nom8::error::{Error, ParseError};
|
|
use nom8::ErrorConvert;
|
|
use nom8::{IResult, Parser};
|
|
|
|
/// Reimplementation of `take_until_and_consume` for nom 8
|
|
///
|
|
/// `take_until` does not consume the matched tag, and
|
|
/// `take_until_and_consume` was removed in nom 7. This function
|
|
/// provides an implementation (specialized for `&[u8]`).
|
|
pub fn take_until_and_consume<'a, E: ParseError<&'a [u8]>>(
|
|
t: &'a [u8],
|
|
) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], &'a [u8], E> {
|
|
move |i: &'a [u8]| {
|
|
let (i, res) = take_until(t).parse(i)?;
|
|
let (i, _) = tag(t).parse(i)?;
|
|
Ok((i, res))
|
|
}
|
|
}
|
|
|
|
/// Specialized version of the nom 8 `bits` combinator
|
|
///
|
|
/// The `bits combinator has trouble inferring the transient error type
|
|
/// used by the tuple parser, because the function is generic and any
|
|
/// error type would be valid.
|
|
/// Use an explicit error type (as described in
|
|
/// https://docs.rs/nom/7.1.0/nom/bits/fn.bits.html) to solve this problem, and
|
|
/// specialize this function for `&[u8]`.
|
|
pub fn bits<'a, O, E, P>(parser: P) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], O, E>
|
|
where
|
|
E: ParseError<&'a [u8]>,
|
|
Error<(&'a [u8], usize)>: ErrorConvert<E>,
|
|
P: FnMut((&'a [u8], usize)) -> IResult<(&'a [u8], usize), O, Error<(&'a [u8], usize)>>,
|
|
{
|
|
// use full path to disambiguate nom `bits` from this current function name
|
|
nom8::bits::bits(parser)
|
|
}
|
|
}
|
|
|
|
/// Convert an u8-array of data into a hexadecimal representation
|
|
pub fn to_hex(input: &[u8]) -> String {
|
|
return input
|
|
.iter()
|
|
.flat_map(|b| {
|
|
vec![
|
|
char::from(HEX[(b >> 4) as usize]),
|
|
char::from(HEX[(b & 0xf) as usize]),
|
|
]
|
|
})
|
|
.collect();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn SCToHex(output: *mut u8, out_len: usize, input: *const u8, in_len: usize) {
|
|
if out_len < 2 * in_len + 1 {
|
|
return;
|
|
}
|
|
let islice = build_slice!(input, in_len);
|
|
let oslice = std::slice::from_raw_parts_mut(output, 2 * in_len + 1);
|
|
// only used from C
|
|
for i in 0..islice.len() {
|
|
oslice[2 * i] = HEX[(islice[i] >> 4) as usize];
|
|
oslice[2 * i + 1] = HEX[(islice[i] & 0xf) as usize];
|
|
}
|
|
oslice[2 * islice.len()] = 0;
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn SCToHex_sep(
|
|
output: *mut u8, out_len: usize, sep: u8, input: *const u8, in_len: usize,
|
|
) {
|
|
if out_len < 3 * in_len {
|
|
return;
|
|
}
|
|
let islice = build_slice!(input, in_len);
|
|
let oslice = std::slice::from_raw_parts_mut(output, 3 * in_len);
|
|
// only used from C
|
|
for i in 0..islice.len() {
|
|
oslice[3 * i] = HEX[(islice[i] >> 4) as usize];
|
|
oslice[3 * i + 1] = HEX[(islice[i] & 0xf) as usize];
|
|
oslice[3 * i + 2] = sep;
|
|
}
|
|
// overwrites last separator with final null char
|
|
oslice[3 * islice.len() - 1] = 0;
|
|
}
|