skyscraper8/skyscraper8/Skyscraper/Net/BlackholeIpTrafficHandler.cs
fey 4038e65c38
All checks were successful
🚀 Pack skyscraper8 / make-zip (push) Successful in 45s
Reworked the Recorded Samples test.
2026-07-24 21:54:06 +02:00

179 lines
6.2 KiB
C#

using System.Net;
using System.Net.NetworkInformation;
using skyscraper5.Ietf.Rfc2460;
using skyscraper5.Ietf.Rfc768;
using skyscraper5.Ietf.Rfc971;
using skyscraper5.Skyscraper.Plugins;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
using skyscraper8.Skyscraper.Scraper.Storage;
namespace skyscraper8.Skyscraper.Net;
[SkyscraperPlugin]
[StorageId(3)]
[StorageName("Packet Discarder")]
public class BlackholeIpTrafficHandler : IpTrafficHandler
{
public void Dispose()
{
// TODO release managed resources here
}
public void HandleIpPacket(VirtualNetworkIdentifier pid, byte[] payload)
{
if (payload == null || payload.Length == 0)
return;
int ipVersion = (payload[0] & 0xF0) >> 4;
bool isIpv4 = ipVersion == 4;
bool isUdp = false;
int udpOffset = -1;
byte proto;
IPAddress srcAddr;
IPAddress dstAddr;
if (isIpv4)
{
InternetHeader ipv4 = new InternetHeader(payload);
isUdp = ipv4.Protocol == 17;
udpOffset = ipv4.NextHeaderOffset;
srcAddr = ipv4.SourceAddress;
dstAddr = ipv4.DestinationAddress;
proto = ipv4.Protocol;
}
else
{
bool isIpv6 = ipVersion == 6;
if (isIpv6)
{
Ipv6Header ipv6 = new Ipv6Header(payload);
isUdp = ipv6.NextHeader == 17;
udpOffset = ipv6.HeaderEndOffset;
srcAddr = ipv6.SourceAddress;
dstAddr = ipv6.DestinationAddress;
proto = ipv6.NextHeader;
}
else
{
return;
}
}
if (isUdp)
{
UserDatagram userDatagram = new UserDatagram(new Span<byte>(payload).Slice(udpOffset).ToArray());
TrackUdpContent(srcAddr, dstAddr, userDatagram.SourcePort, userDatagram.DestinationPort, userDatagram.Payload);
}
TrackIpContent(srcAddr, dstAddr, proto, payload.Length - udpOffset);
}
private void TrackIpContent(IPAddress srcAddr, IPAddress dstAddr, byte proto, int payloadLength)
{
if (_ipContents == null)
_ipContents = new Dictionary<Tuple<IPAddress, IPAddress, byte>, TrafficTracking>();
Tuple<IPAddress,IPAddress,byte> coordinate = new Tuple<IPAddress, IPAddress, byte>(srcAddr, dstAddr, proto);
if (!_ipContents.ContainsKey(coordinate))
{
TrafficTracking tracking = new TrafficTracking();
tracking.Count(payloadLength);
_ipContents.Add(coordinate, tracking);
}
else
{
_ipContents[coordinate].Count(payloadLength);
}
}
public void HandleLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination,
ushort etherType, byte[] contents)
{
Tuple<PhysicalAddress, ushort, byte, byte> coordinate = new Tuple<PhysicalAddress, ushort, byte, byte>(destination, etherType, contents[0], contents[1]);
if (_llcContents == null)
_llcContents = new Dictionary<Tuple<PhysicalAddress, ushort, byte, byte>, TrafficTracking>();
if (!_llcContents.ContainsKey(coordinate))
{
TrafficTracking tracking = new TrafficTracking();
tracking.Count(contents.Length - 2);
_llcContents.Add(coordinate, tracking);
}
else
{
_llcContents[coordinate].Count(contents.Length - 2);
}
}
private void TrackUdpContent(IPAddress src, IPAddress dst, ushort srcPort, ushort dstPort, byte[] contents)
{
if (_udpContents == null)
{
_udpContents = new Dictionary<Tuple<IPAddress, IPAddress, ushort, ushort>, TrafficTracking>();
}
Tuple<IPAddress,IPAddress,ushort,ushort> coordinate = new Tuple<IPAddress, IPAddress, ushort, ushort>(src, dst, srcPort, dstPort);
if (!_udpContents.ContainsKey(coordinate))
{
TrafficTracking tracking = new TrafficTracking();
tracking.Count(contents.Length);
_udpContents.Add(coordinate, tracking);
}
else
{
_udpContents[coordinate].Count(contents.Length);
}
}
private Dictionary<Tuple<PhysicalAddress, ushort, byte, byte>, TrafficTracking> _llcContents;
private Dictionary<Tuple<IPAddress, IPAddress, byte>, TrafficTracking> _ipContents;
private Dictionary<Tuple<IPAddress, IPAddress, ushort, ushort>, TrafficTracking> _udpContents;
public class TrafficTracking
{
public void Count(int length)
{
NumPackets++;
NumBytes += length;
}
public int NumPackets { get; set; }
public int NumBytes { get; set; }
}
public bool? TestForUdpTraffic(string srcIp, string dstIp, int stcPort, int dstPort)
{
IPAddress ipL = IPAddress.Parse(srcIp);
IPAddress ipR = IPAddress.Parse(dstIp);
ushort portL = Convert.ToUInt16(stcPort);
ushort portR = Convert.ToUInt16(dstPort);
return TestForUdpTraffic(ipL, ipR, portL, portR);
}
private bool? TestForUdpTraffic(IPAddress srcIp, IPAddress dstIp, ushort stcPort, ushort dstPort)
{
Tuple<IPAddress, IPAddress, ushort, ushort> coordinate = new Tuple<IPAddress, IPAddress, ushort, ushort>(srcIp, dstIp, stcPort, dstPort);
return _udpContents.ContainsKey(coordinate);
}
public bool TestForLlcTraffic(string mac, int ethertype, int ssap, int dsap)
{
PhysicalAddress srcMac = PhysicalAddress.Parse(mac);
ushort etherType16 = Convert.ToUInt16(ethertype);
byte ssap8 = Convert.ToByte(ssap);
byte dsap8 = Convert.ToByte(dsap);
return TestForLlcTraffic(srcMac, etherType16, ssap8, dsap8);
}
private bool TestForLlcTraffic(PhysicalAddress srcMac, ushort etherType16, byte ssap8, byte dsap8)
{
if (_llcContents == null)
return false;
Tuple<PhysicalAddress, ushort, byte, byte> coordinate = new Tuple<PhysicalAddress, ushort, byte, byte>(srcMac, etherType16, ssap8, dsap8);
return _llcContents.ContainsKey(coordinate);
}
}