Skip to content

Commit

Permalink
翻录filter
Browse files Browse the repository at this point in the history
  • Loading branch information
xljiulang committed Sep 27, 2022
1 parent c84b0bc commit 397b881
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 14 deletions.
13 changes: 9 additions & 4 deletions App/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ internal class Program
{
unsafe static void Main(string[] args)
{
using var divert = new WinDivert("true", WinDivertLayer.Network);
using var packet = new WinDivertPacket();
var addr = new WinDivertAddress();
//using var divert = new WinDivert("((true) and (tcp)) and (tcp.Rst)", WinDivertLayer.Network);
// using var packet = new WinDivertPacket();
// var addr = new WinDivertAddress();

var filter = Filter.True().And(f => f.IsUdp == true).And(item => item.Tcp.Rst).ToFilter();
var filter = Filter
.True()
.And(f => !f.TcpProtocol)
.And(f => f.Ip.SrcAddr == System.Net.IPAddress.Loopback)
.And(item => item.Tcp.Rst)
.ToFilter();

//divert.Recv(packet, ref addr);
//var result = packet.GetParseResult();
Expand Down
115 changes: 110 additions & 5 deletions WindivertDotnet/Filter.ToString.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace WindivertDotnet
Expand All @@ -13,13 +15,47 @@ public static string ToFilter(this Expression<Func<IFilter, bool>> expression)
return visitor.ToString();
}

private class FilterVisitor : ExpressionVisitor
private class FilterVisitor
{
private readonly StringBuilder builder = new();


protected override Expression VisitBinary(BinaryExpression node)
public void Visit(Expression node)
{
if (node.NodeType == ExpressionType.Constant
&& node is ConstantExpression constantExpression)
{
this.VisitConstant(constantExpression);
}
else if (node.NodeType == ExpressionType.MemberAccess
&& node is MemberExpression memberExpression)
{
this.VisitMember(memberExpression);
}
else if (node.NodeType == ExpressionType.Lambda
&& node is LambdaExpression lambdaExpression)
{
this.Visit(lambdaExpression.Body);
}
else if (node is BinaryExpression binaryExpression)
{
this.VisitBinary(binaryExpression);
}
}

private void VisitBinary(BinaryExpression node)
{
if (node.Left is BinaryExpression leftBinaryExpression)
{
builder.Append("(");
this.VisitBinary(leftBinaryExpression);
builder.Append(")");
}
else
{
this.Visit(node.Left);
}


switch (node.NodeType)
{
case ExpressionType.And:
Expand All @@ -30,10 +66,79 @@ protected override Expression VisitBinary(BinaryExpression node)
case ExpressionType.Or:
case ExpressionType.OrElse:
builder.Append(" or ");
break;
break;

case ExpressionType.Equal:
builder.Append(" == ");
break;

case ExpressionType.NotEqual:
builder.Append(" != ");
break;

case ExpressionType.GreaterThan:
builder.Append(" > ");
break;

case ExpressionType.GreaterThanOrEqual:
builder.Append(" >= ");
break;

case ExpressionType.LessThan:
builder.Append(" < ");
break;

case ExpressionType.LessThanOrEqual:
builder.Append(" <= ");
break;
}

if (node.Right is BinaryExpression rightBinaryExpression)
{
builder.Append("(");
this.VisitBinary(rightBinaryExpression);
builder.Append(")");
}
else
{
this.Visit(node.Right);
}
}

private void VisitConstant(ConstantExpression node)
{
if (node.Value is bool bValue)
{
builder.Append(bValue.ToString().ToLowerInvariant());
}
else
{
builder.Append(node.Value?.ToString());
}
}

private void VisitMember(MemberExpression node)
{
var names = new Stack<string>();
VisitMember(node, names);
var name = string.Join('.', names);
builder.Append(name);
}

return base.VisitBinary(node);
private static void VisitMember(MemberExpression node, Stack<string> names)
{
var name = node.Member.Name;
var filterName = node.Member.GetCustomAttribute<IFilter.FilterNameAttribute>();
if (filterName != null)
{
name = filterName.Name;
}

names.Push(name);
if (node.Expression is MemberExpression expression)
{
VisitMember(expression, names);
}
}

public override string ToString()
Expand Down
32 changes: 27 additions & 5 deletions WindivertDotnet/IFilter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Net;
using System;
using System.Net;

namespace WindivertDotnet
{
Expand All @@ -7,24 +8,33 @@ namespace WindivertDotnet
/// </summary>
public interface IFilter
{
[FilterName("outbound")]
bool Outbound { get; }

[FilterName("inbound")]
bool Inbound { get; }

[FilterName("ip")]
IIP Ip { get; }

bool IsTcp { get; }
[FilterName("tcp")]
bool TcpProtocol { get; }

[FilterName("tcp")]
ITcp Tcp { get; }

bool IsUdp { get; }
[FilterName("udp")]
bool UdpProtocol { get; }

[FilterName("udp")]
IUdp Udp { get; }

[FilterName("ifIdx")]
int IfIdx { get; }

[FilterName("subIfIdx")]
int SubIfIdx { get; }

public interface IIP
{
int Checksum { get; }
Expand All @@ -49,7 +59,7 @@ public interface ITransfer
int SrcPort { get; }
int DstPort { get; }
}

public interface ITcp : ITransfer
{
int SeqNum { get; }
Expand All @@ -62,5 +72,17 @@ public interface IUdp : ITransfer
{
int Length { get; }
}


[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class FilterNameAttribute : Attribute
{
public string Name { get; }

public FilterNameAttribute(string name)
{
this.Name = name;
}
}
}
}

0 comments on commit 397b881

Please sign in to comment.