C# 在Pcap.NET中创建有效的TCP连接
我正在尝试创建一个到测试服务器的有效TCP连接,以模拟GET请求。希望我很接近一个解决方案 使用真实请求中的Wireshark数据,我在使用C# 在Pcap.NET中创建有效的TCP连接,c#,pcap.net,C#,Pcap.net,我正在尝试创建一个到测试服务器的有效TCP连接,以模拟GET请求。希望我很接近一个解决方案 使用真实请求中的Wireshark数据,我在使用PacketCommunicator.SendPacket()发送一个包时,成功地获得了SYN和SYN-ACK: 但是,我似乎无法使ACK出现 第一个数据包是使用以太网层、IpV4Layer和TcpLayer构建的,而后者(当前不工作)使用刚才提到的+aHttpRequestLayer 最后一个数据包TcpLayer的ControlBits设置为TcpCo
PacketCommunicator.SendPacket()发送一个包时,成功地获得了SYN
和SYN-ACK
:
但是,我似乎无法使ACK
出现
第一个数据包是使用以太网层
、IpV4Layer
和TcpLayer
构建的,而后者(当前不工作)使用刚才提到的+aHttpRequestLayer
最后一个数据包TcpLayer
的ControlBits
设置为TcpControlBits.ackknowledgement
。尽管如此,它并不像我的“真实”GET请求那样出现在WireShark中
希望我已经发布了代码的相关部分。如果没有,请告诉我。这是一份有效的草案(我已经检查过了)
请将构造HttpGetSender实例时使用的值更改为所需的值
棘手的部分是获得正确的序列号和确认号
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, // name of the device
PacketDeviceOpenAttributes.Promiscuous,
// promiscuous mode
100)) // read timeout
{
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)
{
// Ethernet Layer
EthernetLayer ethernetLayer = new EthernetLayer
{
Source = SourceMac,
Destination = DestinationMac,
};
// IPv4 Layer
IpV4Layer ipV4Layer = new IpV4Layer
{
Source = SourceIpV4,
CurrentDestination = DestinationIpV4,
Ttl = 128,
Fragmentation =
new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
Identification = 1234,
};
// TCP Layer
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)
{
// Ethernet Layer
EthernetLayer ethernetLayer = new EthernetLayer
{
Source = SourceMac,
Destination = DestinationMac,
};
// IPv4 Layer
IpV4Layer ipV4Layer = new IpV4Layer
{
Source = SourceIpV4,
CurrentDestination = DestinationIpV4,
Ttl = 128,
Fragmentation =
new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0),
Identification = 1235,
};
// TCP Layer
TcpLayer tcpLayer = new TcpLayer
{
SourcePort = _sourcePort,
DestinationPort = _destinationPort,
SequenceNumber = _seqNumber,
AcknowledgmentNumber = _ackNumber,
ControlBits = TcpControlBits.Acknowledgment,
Window = _windowSize,
};
// HTTP Layer
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)
{
// Retrieve the device list from the local machine
IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;
if (allDevices.Count == 0)
{
Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
return;
}
// Print the list
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);
// Take the selected adapter
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);
}
}
}
使用系统;
使用System.Collections.Generic;
使用PcapDotNet.Core;
使用PcapDotNet.Packets;
使用PcapDotNet.Packets.Ethernet;
使用PcapDotNet.Packets.Http;
使用PcapDotNet.Packets.IpV4;
使用PcapDotNet.Packets.Transport;
命名空间发送TTPGET
{
内部类HttpGetSender
{
公共HttpGetSender()
{
}
公共MacAddress SourceMac{get;set;}
公共MacAddress DestinationMac{get;set;}
公共IpV4Address SourceIpV4{get;set;}
公共IpV4Address DestinationIpV4{get;set;}
公共字符串主机{get;set;}
公共无效运行(打包设备)
{
使用(PacketCommunicator=device.Open)(100,//设备名称
包装设备不符合规定。杂乱无章,
//滥交模式
100))//读取超时
{
SendSyn(通信器);
WaitForAck(通讯员);
}
}
专用void WaitForAck(PacketCommunicator)
{
communicator.SetFilter(“tcp和src”+DestinationIpV4+”和dst“+SourceIpV4+”和src端口“+_destinationPort+”和dst端口“+_sourcePort”);
数据包;
while(true)
{
if(communicator.ReceivePacket(out packet)=packetcommunicator receivesult.Ok)
{
if(packet.Ethernet.IpV4.Tcp.AcknowledgementNumber==\u ExpectedAcknowledNumber)
{
_seqNumber=_预期的包装编号;
_ackNumber=packet.Ethernet.IpV4.Tcp.SequenceNumber+1;
SendGet(通信器);
打破
}
}
SendSyn(通信器);
}
WaitForResponse(通讯员);
}
专用void WaitForResponse(PacketCommunicator)
{
communicator.SetFilter(“tcp和src”+DestinationIpV4+”和dst“+SourceIpV4+”和src端口“+_destinationPort+”和dst端口“+_sourcePort”);
数据包;
while(true)
{
if(communicator.ReceivePacket(out packet)=packetcommunicator receivesult.Ok)
{
Console.WriteLine(“预期确认号:”+_预期确认号);
Console.WriteLine(“收到的确认号:”+packet.Ethernet.IpV4.Tcp.AcknowledgementNumber);
if(packet.Ethernet.IpV4.Tcp.AcknowledgementNumber==\u ExpectedAcknowledNumber)
{
打破
}
}
SendGet(通信器);
}
}
专用void SendSyn(PacketCommunicator)
{
//以太网层
EthernetLayer EthernetLayer=新的EthernetLayer
{
Source=SourceMac,
目的地=目的地MAC,
};
//IPv4层
IpV4Layer IpV4Layer=新IpV4Layer
{
Source=SourceIpV4,
CurrentDestination=DestinationIpV4,
Ttl=128,
碎裂=
新的IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment,0),
标识=1234,
};
//TCP层
TcpLayer TcpLayer=新的TcpLayer
{
SourcePort=\u SourcePort,
DestinationPort=\u DestinationPort,
SequenceNumber=_seqNumber,
ControlBits=TcpControlBits.Synchronize,
窗口=\u窗口大小,
};
SendPacket(PacketBuilder.Build(DateTime.Now、ethernetLayer、ipV4Layer、tcpLayer));
_expectedAckNumber=_seqNumber+1;
}
专用void SendGet(PacketCommunicator)
{
//以太网层
EthernetLayer EthernetLayer=新的EthernetLayer
{
所以