Реализация фрагментации IP для пакета TCP/UDP в Pcap.Net
Я пытаюсь реализовать фрагментацию IP с помощью Pcap.Net. Это просто для пакетов, которые уже созданы, поскольку полезная нагрузка L3 просто разбита на части. У меня есть код, который делает это. Возвращает список фрагментов пакета для отправки в сеть.
private static List<Packet> FragmentPacket(Packet packet)
{
EthernetLayer ethernetLayer = (EthernetLayer)packet.Ethernet.ExtractLayer();
IpV4Layer ipV4Layer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
PayloadLayer payload = (PayloadLayer)packet.Ethernet.IpV4.Payload.ExtractLayer();
// implement IP fragmentation
int totalLength = payload.Length;
int fragmentLength = 1480;
int fragmentOffset = 0;
IpV4FragmentationOptions FragOptions;
List<Packet> fragmentsList = new List<Packet>();
while (fragmentOffset < totalLength)
{
if (fragmentOffset + fragmentLength >= totalLength)
{
//last fragment
FragOptions = IpV4FragmentationOptions.None;
fragmentLength = totalLength - fragmentOffset;
}
else
{
//more fragments to go
FragOptions = IpV4FragmentationOptions.MoreFragments;
}
IpV4Layer newipV4Layer =
new IpV4Layer
{
Source = ipV4Layer.Source,
CurrentDestination = ipV4Layer.CurrentDestination,
Fragmentation = new IpV4Fragmentation(FragOptions, (ushort)fragmentOffset),
HeaderChecksum = null, // Will be filled automatically.
Identification = 123,
Options = IpV4Options.None,
Protocol = ipV4Layer.Protocol,
Ttl = ipV4Layer.Ttl, // 128,
TypeOfService = ipV4Layer.TypeOfService,
};
byte[] newBuffer = payload.Data.ToArray();
PayloadLayer fragmentedPayload = new PayloadLayer { Data = new Datagram(newBuffer, fragmentOffset, fragmentLength) };
PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, fragmentedPayload);
fragmentsList.Add(builder.Build(DateTime.Now));
fragmentOffset = fragmentOffset + fragmentedPayload.Length;
}
return fragmentsList;
}
Но то, что я на самом деле делаю, это:
1) получение большого пакета через интерфейс Loopback (обычно он больше, чем MTU физического интерфейса)
2) разбирать его, модифицировать IP-адреса
3) создание нового пакета и отправка его через интерфейс Ethernet
К сожалению, если полезная нагрузка IP больше, чем MTU, происходит исключение, так как пакет должен быть фрагментирован перед отправкой.
Поскольку я меняю IP-адрес, то для пакетов TCP/UDP контрольная сумма L4 должна быть пересчитана, и этот пересчет должен учитывать заголовок L3. Поэтому необходимо построить часть полезной нагрузки L3+L4+ (чтобы правильно рассчитать контрольную сумму L4), а затем разбить полезную нагрузку L4 + на части, чтобы соответствовать MTU L3.
Я пришел к решению, в котором я создаю новый пакет (который больше, чем MTU), а затем проталкиваю его через функцию выше, чтобы разбить его на части, и затем я отправляю его, используя:
foreach (Packet newpacket in packetList) коммуникатор.SendPacket(newpacket);
Это, однако, требует создания одного и того же пакета дважды, и я пытаюсь найти способ в Pcap.Net частично построить пакет (включая пересчет контрольной суммы L4) и в то же время разделить его на фрагменты, чтобы соответствовать MTU.
Я не знаю, как (и если это возможно в Pcap.Net) подготовить полезную нагрузку L3, которая будет состоять из полезной нагрузки tcpLayer/udpLayer + L4, так как контрольная сумма TCP вычисляется во время сборки, а затем, наконец, собирать остальную часть пакета. Если бы это было возможно, мне просто нужно было бы собрать пакет, разделив его на части одновременно.