Here is a project that works (I checked).
Please change the values used to create the HttpGetSender instance to whatever you need.
The tricky part is getting the sequence and confirmation numbers correctly.
using System;
using System.Collections.Generic;
using PcapDotNet.Core;
using PcapDotNet.Packets;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Http;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport;
namespace SendingHttpGet
{
internal class HttpGetSender
{
public HttpGetSender()
{
}
public MacAddress SourceMac { get; set; }
public MacAddress DestinationMac { get; set; }
public IpV4Address SourceIpV4 { get; set; }
public IpV4Address DestinationIpV4 { get; set; }
public string Host { get; set; }
public void Run(PacketDevice device)
{
using (PacketCommunicator communicator = device.Open(100,
PacketDeviceOpenAttributes.Promiscuous,
100))
{
SendSyn(communicator);
WaitForAck(communicator);
}
}
private void WaitForAck(PacketCommunicator communicator)
{
communicator.SetFilter("tcp and src " + DestinationIpV4 + " and dst " + SourceIpV4 + " and src port " + _destinationPort + " and dst port " + _sourcePort);
Packet packet;
while (true)
{
if (communicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
{
if (packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber == _expectedAckNumber)
{
_seqNumber = _expectedAckNumber;
_ackNumber = packet.Ethernet.IpV4.Tcp.SequenceNumber + 1;
SendGet(communicator);
break;
}
}
SendSyn(communicator);
}
WaitForResponse(communicator);
}
private void WaitForResponse(PacketCommunicator communicator)
{
communicator.SetFilter("tcp and src " + DestinationIpV4 + " and dst " + SourceIpV4 + " and src port " + _destinationPort + " and dst port " + _sourcePort);
Packet packet;
while (true)
{
if (communicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
{
Console.WriteLine("Expected ack number: " + _expectedAckNumber);
Console.WriteLine("Received ack number: " + packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber);
if (packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber == _expectedAckNumber)
{
break;
}
}
SendGet(communicator);
}
}
private void SendSyn(PacketCommunicator communicator)
{
EthernetLayer ethernetLayer = new EthernetLayer
{
Source = SourceMac,
Destination = DestinationMac,
};
IpV4Layer ipV4Layer = new IpV4Layer
{
Source = SourceIpV4,
CurrentDestination = DestinationIpV4,
Ttl = 128,
Fragmentation =
new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
Identification = 1234,
};
TcpLayer tcpLayer = new TcpLayer
{
SourcePort = _sourcePort,
DestinationPort = _destinationPort,
SequenceNumber = _seqNumber,
ControlBits = TcpControlBits.Synchronize,
Window = _windowSize,
};
communicator.SendPacket(PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, tcpLayer));
_expectedAckNumber = _seqNumber + 1;
}
private void SendGet(PacketCommunicator communicator)
{
EthernetLayer ethernetLayer = new EthernetLayer
{
Source = SourceMac,
Destination = DestinationMac,
};
IpV4Layer ipV4Layer = new IpV4Layer
{
Source = SourceIpV4,
CurrentDestination = DestinationIpV4,
Ttl = 128,
Fragmentation =
new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
Identification = 1235,
};
TcpLayer tcpLayer = new TcpLayer
{
SourcePort = _sourcePort,
DestinationPort = _destinationPort,
SequenceNumber = _seqNumber,
AcknowledgmentNumber = _ackNumber,
ControlBits = TcpControlBits.Acknowledgment,
Window = _windowSize,
};
HttpLayer httpLayer = new HttpRequestLayer
{
Uri = "/",
Header = new HttpHeader(HttpField.CreateField("Host", Host)),
Method = new HttpRequestMethod(HttpRequestKnownMethod.Get),
Version = HttpVersion.Version11,
};
Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV4Layer, tcpLayer, httpLayer);
communicator.SendPacket(packet);
_expectedAckNumber = (uint) (_seqNumber + packet.Ethernet.IpV4.Tcp.PayloadLength);
}
private ushort _sourcePort = (ushort) (4123 + new Random().Next() % 1000);
private ushort _destinationPort = 80;
private uint _seqNumber = (uint) new Random().Next();
private uint _expectedAckNumber;
private ushort _windowSize = 8192;
private uint _ackNumber;
}
internal class Program
{
private static void Main(string[] args)
{
IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;
if (allDevices.Count == 0)
{
Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
return;
}
for (int i = 0; i != allDevices.Count; ++i)
{
LivePacketDevice device = allDevices[i];
Console.Write((i + 1) + ". " + device.Name);
if (device.Description != null)
Console.WriteLine(" (" + device.Description + ")");
else
Console.WriteLine(" (No description available)");
}
int deviceIndex = 0;
do
{
Console.WriteLine("Enter the interface number (1-" + allDevices.Count + "):");
string deviceIndexString = Console.ReadLine();
if (!int.TryParse(deviceIndexString, out deviceIndex) ||
deviceIndex < 1 || deviceIndex > allDevices.Count)
{
deviceIndex = 0;
}
} while (deviceIndex == 0);
PacketDevice selectedDevice = allDevices[deviceIndex - 1];
HttpGetSender sender = new HttpGetSender
{
SourceMac = new MacAddress("your:host:mac:address:1:2"),
DestinationMac = new MacAddress("gateway:mac:address:1:2:3"),
SourceIpV4 = new IpV4Address("your.host.ip.address"),
DestinationIpV4 = new IpV4Address("target.host.ip.address"),
Host = "targethost.com",
};
sender.Run(selectedDevice);
}
}
}