~ruther/NosSmooth

35b2999f2a7df245d1cf9f565dda03d465ac3e60 — František Boháček 2 years ago 8e5e00c
feat: send packets to capture device in pcap
1 files changed, 76 insertions(+), 5 deletions(-)

M Pcap/NosSmooth.Pcap/PcapNostaleClient.cs
M Pcap/NosSmooth.Pcap/PcapNostaleClient.cs => Pcap/NosSmooth.Pcap/PcapNostaleClient.cs +76 -5
@@ 5,6 5,8 @@
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;


@@ 15,7 17,9 @@ using NosSmooth.Core.Packets;
using NosSmooth.Cryptography;
using NosSmooth.Cryptography.Extensions;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
using PacketDotNet;
using Remora.Results;
using SharpPcap;
using SharpPcap.LibPcap;

namespace NosSmooth.Pcap;


@@ 42,6 46,8 @@ public class PcapNostaleClient : BaseNostaleClient
    private bool _running;
    private LibPcapLiveDevice? _lastDevice;
    private TcpConnection _connection;
    private PhysicalAddress? _localAddress;
    private PhysicalAddress? _remoteAddress;
    private long _lastPacketIndex;

    /// <summary>


@@ 174,15 180,67 @@ public class PcapNostaleClient : BaseNostaleClient
    }

    /// <inheritdoc />
    public override Task<Result> SendPacketAsync(string packetString, CancellationToken ct = default)
    public override async Task<Result> SendPacketAsync(string packetString, CancellationToken ct = default)
    {
        throw new NotImplementedException();
        if (_lastDevice is null)
        {
            return new NotSupportedError("The device was not captured yet, cannot send packet.");
        }

        if (_lastDevice?.Loopback ?? false)
        {
            return new NotSupportedError("Loopback devices cannot send or receive packets.");
        }

        var ethPacket = new EthernetPacket(_localAddress, _remoteAddress, EthernetType.IPv4);
        var ipPacket = new IPv4Packet(new IPAddress(_connection.LocalAddr), new IPAddress(_connection.RemoteAddr));
        var tcpPacket = new TcpPacket((ushort)_connection.LocalPort, (ushort)_connection.RemotePort);
        tcpPacket.PayloadData = _crypto.ClientWorld.Encrypt(_lastPacketIndex + " " + packetString, _encoding);
        ethPacket.PayloadPacket = ipPacket;
        ipPacket.PayloadPacket = tcpPacket;

        try
        {
            _lastDevice?.SendPacket(ethPacket);
        }
        catch (Exception e)
        {
            return e;
        }

        return Result.FromSuccess();
    }

    /// <inheritdoc />
    public override Task<Result> ReceivePacketAsync(string packetString, CancellationToken ct = default)
    public override async Task<Result> ReceivePacketAsync(string packetString, CancellationToken ct = default)
    {
        throw new NotImplementedException();
        if (_lastDevice is null)
        {
            return new NotSupportedError("The device was not captured yet, cannot receive packet.");
        }

        if (_lastDevice?.Loopback ?? false)
        {
            return new NotSupportedError("Loopback devices cannot send or receive packets.");
        }

        var ethPacket = new EthernetPacket(_remoteAddress, _localAddress, EthernetType.IPv4);
        var ipPacket = new IPv4Packet(new IPAddress(_connection.RemoteAddr), new IPAddress(_connection.LocalAddr));
        var tcpPacket = new TcpPacket((ushort)_connection.RemotePort, (ushort)_connection.LocalPort);
        tcpPacket.PayloadData = _crypto.ServerWorld.Encrypt(packetString, _encoding);
        ipPacket.PayloadPacket = tcpPacket;
        ethPacket.PayloadPacket = ipPacket;

        try
        {
            _lastDevice?.SendPacket(ethPacket);
        }
        catch (Exception e)
        {
            return e;
        }

        return Result.FromSuccess();
    }

    /// <summary>


@@ 191,7 249,14 @@ public class PcapNostaleClient : BaseNostaleClient
    /// <param name="device">The device the packet was received at.</param>
    /// <param name="connection">The connection that obtained the packet.</param>
    /// <param name="payloadData">The raw payload data of the packet.</param>
    internal void OnPacketArrival(LibPcapLiveDevice? device, TcpConnection connection, byte[] payloadData)
    /// <param name="ethernetPacket">The ethernet packet containing source and destination hardware addresses.</param>
    internal void OnPacketArrival
    (
        LibPcapLiveDevice? device,
        TcpConnection connection,
        byte[] payloadData,
        EthernetPacket? ethernetPacket
    )
    {
        _lastDevice = device;



@@ 201,12 266,18 @@ public class PcapNostaleClient : BaseNostaleClient

        if (connection.LocalAddr == _connection.LocalAddr && connection.LocalPort == _connection.LocalPort)
        { // sent packet
            _localAddress = ethernetPacket?.SourceHardwareAddress;
            _remoteAddress = ethernetPacket?.DestinationHardwareAddress;

            source = PacketSource.Client;
            mayContainPacketId = true;
            data = _crypto.DecryptUnknownServerPacket(payloadData, _encoding);
        }
        else
        { // received packet
            _remoteAddress = ethernetPacket?.SourceHardwareAddress;
            _localAddress = ethernetPacket?.DestinationHardwareAddress;

            source = PacketSource.Server;
            data = _crypto.DecryptUnknownClientPacket(payloadData, _encoding);
        }

Do not follow this link