From a86fc3866056908d4ac1b67786be05d6bc2764dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Thu, 2 Feb 2023 10:13:54 +0100 Subject: [PATCH] feat: add packet filters --- .../Models/Filters/CompoundFilter.cs | 46 +++++++++++++ .../Models/Filters/ContainsFilter.cs | 36 +++++++++++ .../Models/Filters/FilterCreator.cs | 64 +++++++++++++++++++ src/PacketLogger/Models/Filters/IFilter.cs | 27 ++++++++ .../Models/Filters/PacketHeaderFilter.cs | 54 ++++++++++++++++ .../Models/Filters/SendRecvFilter.cs | 44 +++++++++++++ .../Models/Filters/StartsWithFilter.cs | 35 ++++++++++ 7 files changed, 306 insertions(+) create mode 100644 src/PacketLogger/Models/Filters/CompoundFilter.cs create mode 100644 src/PacketLogger/Models/Filters/ContainsFilter.cs create mode 100644 src/PacketLogger/Models/Filters/FilterCreator.cs create mode 100644 src/PacketLogger/Models/Filters/IFilter.cs create mode 100644 src/PacketLogger/Models/Filters/PacketHeaderFilter.cs create mode 100644 src/PacketLogger/Models/Filters/SendRecvFilter.cs create mode 100644 src/PacketLogger/Models/Filters/StartsWithFilter.cs diff --git a/src/PacketLogger/Models/Filters/CompoundFilter.cs b/src/PacketLogger/Models/Filters/CompoundFilter.cs new file mode 100644 index 0000000..fe48f5f --- /dev/null +++ b/src/PacketLogger/Models/Filters/CompoundFilter.cs @@ -0,0 +1,46 @@ +// +// CompoundFilter.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using PacketLogger.Models.Packets; + +namespace PacketLogger.Models.Filters; + +/// +/// A filter created from multiple filters joined by "OR". +/// +public class CompoundFilter : IFilter +{ + private readonly bool _negate; + private readonly IFilter[] _filters; + + /// + /// Initializes a new instance of the class. + /// + /// Whether to negate the result (false - whitelist, true - blacklist). + /// The filters to use. + public CompoundFilter(bool negate, params IFilter[] filters) + { + _negate = negate; + _filters = filters; + } + + /// + public string FilterString => "Many"; + + /// + public bool Match(PacketInfo packet) + { + foreach (var filter in _filters) + { + if (filter.Match(packet)) + { + return !_negate; + } + } + + return _negate; + } +} \ No newline at end of file diff --git a/src/PacketLogger/Models/Filters/ContainsFilter.cs b/src/PacketLogger/Models/Filters/ContainsFilter.cs new file mode 100644 index 0000000..c7e3504 --- /dev/null +++ b/src/PacketLogger/Models/Filters/ContainsFilter.cs @@ -0,0 +1,36 @@ +// +// ContainsFilter.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using PacketLogger.Models.Packets; + +namespace PacketLogger.Models.Filters; + +/// +/// Filters packets that contain the given string. +/// +public class ContainsFilter : IFilter +{ + private readonly string _contains; + + /// + /// Initializes a new instance of the class. + /// + /// The string to filter. + public ContainsFilter(string contains) + { + _contains = contains; + } + + /// + public string FilterString => _contains; + + /// + public bool Match(PacketInfo packet) + { + return packet.PacketString.Contains(_contains, StringComparison.OrdinalIgnoreCase); + } +} \ No newline at end of file diff --git a/src/PacketLogger/Models/Filters/FilterCreator.cs b/src/PacketLogger/Models/Filters/FilterCreator.cs new file mode 100644 index 0000000..e258076 --- /dev/null +++ b/src/PacketLogger/Models/Filters/FilterCreator.cs @@ -0,0 +1,64 @@ +// +// FilterCreator.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Diagnostics; + +namespace PacketLogger.Models.Filters; + +/// +/// A builder/creator of . +/// +public static class FilterCreator +{ + /// + /// A type of a filter. + /// + public enum FilterType + { + /// + /// . + /// + PacketHeader, + + /// + /// . + /// + Contains, + + /// + /// . + /// + StartsWith + } + + /// + /// Information about a filter to create. + /// + /// The type of the filter. + /// The value. + public record FilterData(FilterType Type, string Value); + + /// + /// Build a filter of the given type and value. + /// + /// The type of the filter to build. + /// The value of the filter. + /// A filter. + public static IFilter BuildFilter(FilterType type, string value) + { + switch (type) + { + case FilterType.Contains: + return new ContainsFilter(value); + case FilterType.PacketHeader: + return new PacketHeaderFilter(value); + case FilterType.StartsWith: + return new StartsWithFilter(value); + } + + throw new UnreachableException(); + } +} \ No newline at end of file diff --git a/src/PacketLogger/Models/Filters/IFilter.cs b/src/PacketLogger/Models/Filters/IFilter.cs new file mode 100644 index 0000000..da05228 --- /dev/null +++ b/src/PacketLogger/Models/Filters/IFilter.cs @@ -0,0 +1,27 @@ +// +// IFilter.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using PacketLogger.Models.Packets; + +namespace PacketLogger.Models.Filters; + +/// +/// Filter a packet. +/// +public interface IFilter +{ + /// + /// The string to filter. + /// + public string FilterString { get; } + + /// + /// Match the given packet. + /// + /// The packet info. + /// Whether to keep the packet. + public bool Match(PacketInfo packet); +} \ No newline at end of file diff --git a/src/PacketLogger/Models/Filters/PacketHeaderFilter.cs b/src/PacketLogger/Models/Filters/PacketHeaderFilter.cs new file mode 100644 index 0000000..246a990 --- /dev/null +++ b/src/PacketLogger/Models/Filters/PacketHeaderFilter.cs @@ -0,0 +1,54 @@ +// +// PacketHeaderFilter.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Reflection.Emit; +using System.Reflection.PortableExecutable; +using PacketLogger.Models.Packets; + +namespace PacketLogger.Models.Filters; + +/// +/// Filters packets that start with the given header. +/// +public class PacketHeaderFilter : IFilter +{ + private readonly string _header; + + /// + /// Initializes a new instance of the class. + /// + /// The header to filter. + public PacketHeaderFilter(string header) + { + _header = header.Trim(); + } + + /// + public string FilterString => _header; + + /// + public bool Match(PacketInfo packet) + { + var packetString = packet.PacketString; + + var split = ' '; + if (packetString.StartsWith('#')) + { + packetString = packetString.Substring(1); + split = '^'; + } + + var splitted = packetString.Split(split, 2); + + if (splitted.Length >= 1) + { + return string.Compare(splitted[0], _header, StringComparison.OrdinalIgnoreCase) == 0; + } + + return false; + } +} \ No newline at end of file diff --git a/src/PacketLogger/Models/Filters/SendRecvFilter.cs b/src/PacketLogger/Models/Filters/SendRecvFilter.cs new file mode 100644 index 0000000..c5dd385 --- /dev/null +++ b/src/PacketLogger/Models/Filters/SendRecvFilter.cs @@ -0,0 +1,44 @@ +// +// SendRecvFilter.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.PacketSerializer.Abstractions.Attributes; +using PacketLogger.Models.Packets; + +namespace PacketLogger.Models.Filters; + +/// +/// Filter using different matches for sent and received packets. +/// +public class SendRecvFilter : IFilter +{ + private readonly IFilter _sendFilter; + private readonly IFilter _recvFilter; + + /// + /// Initializes a new instance of the class. + /// + /// The filter for sent packets. + /// The filter for received packets. + public SendRecvFilter(IFilter sendFilter, IFilter recvFilter) + { + _sendFilter = sendFilter; + _recvFilter = recvFilter; + } + + /// + public string FilterString => "SendRecv"; + + /// + public bool Match(PacketInfo packet) + { + if (packet.Source == PacketSource.Server) + { + return _recvFilter.Match(packet); + } + + return _sendFilter.Match(packet); + } +} \ No newline at end of file diff --git a/src/PacketLogger/Models/Filters/StartsWithFilter.cs b/src/PacketLogger/Models/Filters/StartsWithFilter.cs new file mode 100644 index 0000000..2ecdd64 --- /dev/null +++ b/src/PacketLogger/Models/Filters/StartsWithFilter.cs @@ -0,0 +1,35 @@ +// +// StartsWithFilter.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using PacketLogger.Models.Packets; + +namespace PacketLogger.Models.Filters; + +/// +/// Filters packets that start with the given string. +/// +public class StartsWithFilter : IFilter +{ + private string _startsWith; + + /// + /// Initializes a new instance of the class. + /// + /// The string to filter. + public StartsWithFilter(string startsWith) + { + _startsWith = startsWith; + } + + /// + public string FilterString => _startsWith; + + /// + public bool Match(PacketInfo packet) + { + return packet.PacketString.StartsWith(_startsWith); + } +} \ No newline at end of file -- 2.48.1