sharppcap
sharppcap copied to clipboard
Example of WinDivert packet modification
Would it be possible to get an example of modifying packets using the new WinDivert implementation?
var device = new WinDivertDevice();
// WINDIVERT_FLAG_DROP will cause the original packet to be dropped
// you can inject it back (after modifications) using `device.SendPacket()`
device.Flags = WINDIVERT_FLAG_DROP;
device.Open();
// You can use any Libpcap example as reference for receiving
Thank you. I'm still having a bit of trouble getting this up and running. I'm new to C# so hopefully the below isn't a rookie error. I copied the test code for sending a test packet from here: https://github.com/chmorgan/sharppcap/blob/master/Test/WinDivert/WinDivertDeviceTest.cs
public void TestSend()
{
var dst = IPAddress.Parse("8.8.8.8");
var nic = IpHelper.GetBestInterface(dst);
Assert.NotNull(nic, "No internet connected interface found");
var src = nic.GetIPProperties().UnicastAddresses
.Select(addr => addr.Address)
.FirstOrDefault(addr => addr.AddressFamily == AddressFamily.InterNetwork);
var ifIndex = nic.GetIPProperties().GetIPv4Properties().Index;
Console.WriteLine($"Using NIC {nic.Name} [{ifIndex}]");
Console.WriteLine($"Sending from {src} to {dst}");
using var device = new WinDivertDevice();
device.Open();
var udp = new UdpPacket(5000, 5000);
udp.PayloadData = new byte[100];
var ip = IPv4Packet.RandomPacket();
ip.PayloadPacket = udp;
ip.SourceAddress = src;
ip.DestinationAddress = dst;
device.SendPacket(ip);
}
I receive this error:
So I changed using var device = new WinDivertDevice();
to var device = new WinDivertDevice();
as you specified which doesn't throw up any errors.
But when I run the code it throws the following:
you have the 32bit driver and the application is 64 bit or the other way around.
Thank you. After setting the Debug CPU option to x64 it helped. I also had to launch Visual Studio Code as Administrator and ensure WinDivert.lib and WinDivert64.sys are in the apps base directory as well as the WinDivert.dll
I'm still having trouble with this. My end goal is to modify the packet interface index number and source IP address but I don't seem to be able to re-inject a packet. Below is what I've cobbled together. It drops the packets but the device.SendPacket does not seem to be reinserting them. I assume that's how it's supposed to work? If I get it working I'll put a PR in with the example to save others time down the track.
using System;
using SharpPcap;
using SharpPcap.WinDivert;
namespace ConsoleApp1
{
/// <summary>
/// Example showing packet manipulation with WinDivert
/// </summary>
public class Program
{
public static ulong WINDIVERT_FLAG_DROP { get; private set; }
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main() {
// 1. Make sure Visual Studio Code has been launched as Administrator
// 2. Make sure WinDivert.dll, WinDivert.lib and WinDivert64.sys are in the base folder of the build
// To get base folder of the build uncomment the below line:
// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
// 3. Debug mode CPU needs to be set to x64
var device = new WinDivertDevice();
device.Flags = WINDIVERT_FLAG_DROP;
device.Open();
device.OnPacketArrival += (s, e) =>
{
var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
// Eventually I'll modify the packet source IP address and interface index number here somehow
device.SendPacket(packet);
};
device.StartCapture();
Console.WriteLine("-- Listening on {0}, hit 'Enter' to stop...", device.Description);
// Wait for 'Enter' from the user.
Console.ReadLine();
device.StopCapture();
}
}
}
@brendanosborne sharppcap 5.4.0 auto detects the interface index and the direction from the destination IP, using GetBestInterfaceEx.
Current master of sharppcap allows setting the interface index and packet flags using WinDivertCapture
class.
Some things to consider:
- You have to update the IP and TCP/UDP checksum if you change the IP or port number, or set the correct
WinDivertPacketFlags
inWinDivertCapture
- You have to indicate if you are rerouting the packet to another interface with
InterfaceIndex
, you also have to change it to an Outbound packet usingWinDivertPacketFlags
inWinDivertCapture
- WinDivert will fail to send packet on an interface if the ARP/NDP lookup fails.
I was having a similar issue until I explicitly cleared the flags as mentioned here: https://github.com/dotpcap/sharppcap/issues/289#issuecomment-864414718
Apparently there is base behavior when no flags are set, which, oddly, is not the default:
-
device.Flags = 0;
- Matching packets: dropped and diverted
- Non-matching packets: continue as normal
-
device.Flags = 1; // WINDIVERT_FLAG_SNIFF (default)
- All packets: copied and diverted
-
device.Flags = 2; // WINDIVERT_FLAG_DROP
- All packets: dropped
The first behavior is what I was looking for...not sure if that's what OP wanted, but hopefully this helps someone in my situation.
@Tornadocraver the default behavior of sharppcap is intentionally different, we opted to make the default behavior of all devices to sniff-only regardless of the driver.