Skip to content

Commit

Permalink
Tx.Network: updated dynamic type maps for Snmp Traps
Browse files Browse the repository at this point in the history
  • Loading branch information
Tuatan committed Dec 1, 2016
1 parent 4d5489e commit 2248a5a
Show file tree
Hide file tree
Showing 5 changed files with 506 additions and 569 deletions.
2 changes: 1 addition & 1 deletion Source/Tx.Network/Properties/Tx.Network.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<id>Tx.Network</id>
<title>Tx.Network</title>
<!-- Automatically updated by build, keeping fixed dev build number here in case of local build -->
<version>{version}-beta6</version>
<version>{version}-beta7</version>
<description>Parsing of Network related file and wire formats, such as .pcap and .pcapng, UDP datagrams, Syslog and SNMP messages.</description>
<authors>Microsoft</authors>
<copyright>Copyright © Microsoft. All Rights Reserved</copyright>
Expand Down
32 changes: 11 additions & 21 deletions Source/Tx.Network/Snmp/Dynamic/SnmpTrapTypeMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@
using System.Reactive;

using Tx.Network;
/*

public class SnmpTrapTypeMap : IPartitionableTypeMap<IEnvelope, ObjectIdentifier>
{
private readonly TrapTypeMap trapTypeMap = new TrapTypeMap();

private SnmpDatagram udpDatagram;
private SnmpDatagram snmpDatagram;

public IEqualityComparer<ObjectIdentifier> Comparer
{
get { return this.trapTypeMap.Comparer; }
}
public IEqualityComparer<ObjectIdentifier> Comparer => this.trapTypeMap.Comparer;

public ObjectIdentifier GetTypeKey(Type outputType)
{
Expand All @@ -26,33 +23,27 @@ public Func<IEnvelope, object> GetTransform(Type outputType)
{
var transform = this.trapTypeMap.GetTransform(outputType);

return transform != null ? _ => transform(this.udpDatagram) : (Func<IEnvelope, object>)null;
return transform != null ? _ => transform(this.snmpDatagram) : (Func<IEnvelope, object>)null;
}

public Func<IEnvelope, DateTimeOffset> TimeFunction
{
get
{
return GetTime;
}
}
public Func<IEnvelope, DateTimeOffset> TimeFunction => GetTime;

public ObjectIdentifier GetInputKey(IEnvelope envelope)
{
this.udpDatagram = envelope.PayloadInstance as SnmpDatagram;
this.snmpDatagram = envelope.PayloadInstance as SnmpDatagram;

if (this.udpDatagram == null && string.Equals(envelope.Protocol, Protocol.SnmpTrap, StringComparison.OrdinalIgnoreCase))
if (this.snmpDatagram == null && string.Equals(envelope.Protocol, Protocol.SnmpTrap, StringComparison.OrdinalIgnoreCase))
{
this.udpDatagram = envelope.Payload.AsByteArraySegment()
.ToSnmpDatagram(envelope.ReceivedTime, "");
this.snmpDatagram = envelope.Payload.AsByteArraySegment()
.ToSnmpDatagram(envelope.ReceivedTime, "0.0.0.0");
}

if (this.udpDatagram == null)
if (this.snmpDatagram == null)
{
return default(ObjectIdentifier);
}

return this.trapTypeMap.GetInputKey(this.udpDatagram);
return this.trapTypeMap.GetInputKey(this.snmpDatagram);
}

private static DateTimeOffset GetTime(IEnvelope envelope)
Expand All @@ -62,5 +53,4 @@ private static DateTimeOffset GetTime(IEnvelope envelope)
return time;
}
}
*/
}
61 changes: 25 additions & 36 deletions Source/Tx.Network/Snmp/Dynamic/TrapTypeMap.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

namespace Tx.Network.Snmp.Dynamic
namespace Tx.Network.Snmp.Dynamic
{
using System;
using System.Collections.Generic;
Expand All @@ -14,66 +13,56 @@ namespace Tx.Network.Snmp.Dynamic
/// <summary>
/// TypeMap implementation for SNMP attributed classes.
/// </summary>
public sealed class TrapTypeMap : IPartitionableTypeMap<IpPacket, ObjectIdentifier>
public sealed class TrapTypeMap : IPartitionableTypeMap<SnmpDatagram, ObjectIdentifier>
{
private static readonly Regex HexStringRegex = new Regex("^[0-9A-F.-]+$", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture);

private static readonly ObjectIdentifier trapOid = new ObjectIdentifier("1.3.6.1.6.3.1.1.4.1.0");
private static readonly ObjectIdentifier TrapOid = new ObjectIdentifier("1.3.6.1.6.3.1.1.4.1.0");

public TrapTypeMap()
{
this.TimeFunction = packet => packet.ReceivedTime;
this.Comparer = EqualityComparer<ObjectIdentifier>.Default;
}

public Func<IpPacket, DateTimeOffset> TimeFunction { get; private set; }
public Func<SnmpDatagram, DateTimeOffset> TimeFunction { get; }

public IEqualityComparer<ObjectIdentifier> Comparer { get; private set; }
public IEqualityComparer<ObjectIdentifier> Comparer { get; }

public Func<IpPacket, object> GetTransform(Type outputType)
public Func<SnmpDatagram, object> GetTransform(Type outputType)
{
return CreateTransform(outputType);
}

public ObjectIdentifier GetTypeKey(Type outputType)
{
var attribute = outputType.GetAttribute<SnmpTrapAttribute>();
return attribute != null ? attribute.SnmpTrapOid : default(ObjectIdentifier);
return attribute?.SnmpTrapOid ?? default(ObjectIdentifier);
}

public ObjectIdentifier GetInputKey(IpPacket evt)
public ObjectIdentifier GetInputKey(SnmpDatagram snmpDatagram)
{
var snmpDatagram = GetSnmpDatagram(evt);

if (snmpDatagram == null || snmpDatagram.VarBinds == null)
if (snmpDatagram?.VarBinds == null)
{
return default(ObjectIdentifier);
}

VarBind trapVarBind;
return snmpDatagram.VarBinds.SearchFirstSubOidWith(trapOid, out trapVarBind)
return snmpDatagram.VarBinds.SearchFirstSubOidWith(TrapOid, out trapVarBind)
? (ObjectIdentifier)trapVarBind.Value
: default(ObjectIdentifier);
}

internal static Func<IpPacket, object> CreateTransform(Type outputTrapType)
internal static Func<SnmpDatagram, object> CreateTransform(Type outputTrapType)
{
if (outputTrapType.GetAttribute<SnmpTrapAttribute>() == null)
{
return null;
}

var parameter = Expression.Parameter(typeof(IpPacket), "ipPacket");
var getPduCall = Expression.Call(typeof(TrapTypeMap).GetMethod("GetSnmpDatagram", BindingFlags.Static | BindingFlags.NonPublic), parameter);
var receivedTimestampProperty = typeof (IpPacket).GetProperty("ReceivedTime",
var parameter = Expression.Parameter(typeof(SnmpDatagram), "snmpDatagram");
var receivedTimestampProperty = typeof (SnmpDatagram).GetProperty("ReceivedTime",
BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);

var pduVar = Expression.Variable(typeof(SnmpDatagram), "pdu");
var assignment = Expression.Assign(pduVar, getPduCall);
var pduVarBindsField = typeof(SnmpDatagram).GetField(
var pduVarBindsField = typeof(SnmpDatagram).GetProperty(
"VarBinds",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
var sourceAddressProperty = typeof(IpPacket).GetProperty(
var sourceAddressProperty = typeof(SnmpDatagram).GetProperty(
"SourceIpAddress",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

Expand All @@ -94,9 +83,9 @@ internal static Func<IpPacket, object> CreateTransform(Type outputTrapType)
p.GetCustomAttributes(typeof(NotificationObjectsAttribute), false)
.OfType<NotificationObjectsAttribute>()
.FirstOrDefault();
if (notificationObjects != null && p.PropertyType.IsAssignableFrom(pduVarBindsField.FieldType))
if (notificationObjects != null && p.PropertyType.IsAssignableFrom(pduVarBindsField.PropertyType))
{
notificationObjectsExpression = Expression.Bind(p, Expression.Field(pduVar, pduVarBindsField));
notificationObjectsExpression = Expression.Bind(p, Expression.Property(parameter, pduVarBindsField));
}

var ipAddressAttribute =
Expand All @@ -106,11 +95,10 @@ internal static Func<IpPacket, object> CreateTransform(Type outputTrapType)
if (ipAddressAttribute != null)
{
Expression ipAddress = Expression.Property(parameter, sourceAddressProperty);
if (p.PropertyType == typeof(string))
if (p.PropertyType == typeof(IPAddress))
{
ipAddress = Expression.Call(ipAddress, typeof(IPAddress).GetMethod("ToString"));
ipAddress = Expression.Call(typeof(IPAddress).GetMethod("Parse"), ipAddress);
}

ipAddressExpresion = Expression.Bind(p, ipAddress);
}

Expand All @@ -126,7 +114,7 @@ internal static Func<IpPacket, object> CreateTransform(Type outputTrapType)
continue;
}

var foundValue = Expression.Call(getVarBindMethod, Expression.Field(pduVar, pduVarBindsField), Expression.Constant(notificationObjectIdentifier.Oid), varbindVar);
var foundValue = Expression.Call(getVarBindMethod, Expression.Property(parameter, pduVarBindsField), Expression.Constant(notificationObjectIdentifier.Oid), varbindVar);

Expression convertedValue = Expression.Field(varbindVar, varbindValueField);
if (p.PropertyType.IsEnum || typeof(int).IsAssignableFrom(p.PropertyType))
Expand Down Expand Up @@ -170,18 +158,18 @@ internal static Func<IpPacket, object> CreateTransform(Type outputTrapType)
var castToObject = Expression.Convert(memberInitialization, typeof(object));

var nullCheck = Expression.Condition(
Expression.Equal(Expression.Constant(null, typeof(IpPacket)), parameter),
Expression.Equal(Expression.Constant(null, typeof(SnmpDatagram)), parameter),
Expression.Constant(null, typeof(object)), castToObject);

var codeBlock = Expression.Block(new[] { pduVar, varbindVar, }, assignment, nullCheck);
var transformExpression = Expression.Lambda<Func<IpPacket, object>>(codeBlock, parameter);
var codeBlock = Expression.Block(new[] { varbindVar, }, nullCheck);
var transformExpression = Expression.Lambda<Func<SnmpDatagram, object>>(codeBlock, parameter);

return transformExpression.Compile();
}

public static SnmpDatagram GetSnmpDatagram(IpPacket ipPacket)
{
var udpDatagram = ipPacket.ToUdpDatagram(true);
var udpDatagram = ipPacket.ToUdpDatagram();
if (udpDatagram == default(UdpDatagram))
{
return default(SnmpDatagram);
Expand All @@ -205,6 +193,7 @@ public static SnmpDatagram GetSnmpDatagram(IpPacket ipPacket)
return default(SnmpDatagram);
}

// ReSharper disable once UnusedMember.Local
private static byte[] GetRawOctetStringBytes(string octetString)
{
if (string.IsNullOrEmpty(octetString))
Expand Down
Loading

0 comments on commit 2248a5a

Please sign in to comment.