private static void CreateRandomIpV4Payload(Random random, IpV4Layer ipV4Layer, List <ILayer> layers) { if (random.NextBool(20)) { // Finish with payload. PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100)); layers.Add(payloadLayer); return; } ipV4Layer.Protocol = null; if (random.NextBool()) { ipV4Layer.Fragmentation = IpV4Fragmentation.None; } switch (random.Next(0, 9)) { case 0: // IpV4. case 1: IpV4Layer innerIpV4Layer = random.NextIpV4Layer(); layers.Add(innerIpV4Layer); CreateRandomIpV4Payload(random, innerIpV4Layer, layers); return; case 2: // Igmp. layers.Add(random.NextIgmpLayer()); return; case 3: // Icmp. IcmpLayer icmpLayer = random.NextIcmpLayer(); layers.Add(icmpLayer); layers.AddRange(random.NextIcmpPayloadLayers(icmpLayer)); return; case 4: // Gre. GreLayer greLayer = random.NextGreLayer(); layers.Add(greLayer); CreateRandomEthernetPayload(random, greLayer, layers); return; case 5: // Udp. case 6: UdpLayer udpLayer = random.NextUdpLayer(); layers.Add(udpLayer); CreateRandomUdpPayload(random, udpLayer, layers); return; case 7: // Tcp. case 8: TcpLayer tcpLayer = random.NextTcpLayer(); layers.Add(tcpLayer); CreateRandomTcpPayload(random, tcpLayer, layers); return; default: throw new InvalidOperationException("Invalid value."); } }
public Layer3Locator(string componentId) { this.Tcp = new TcpLayer(this); this.Udp = new UdpLayer(this); this.Icmp = new IcmpLayer(this); this.IPv4 = new IPv4Layer(this); this.Netif = new Layer3Netif(this, componentId); this.Sockets = new SocketScheduler(this); }
private bool PrivateIcmpInput(IPFrame packet) { IcmpFrame frame = IcmpLayer.ParseFrame(packet, false); if (frame == null) { return(false); } NATContext context = this.m_contextsIcmp.PrivateInput(frame.Source, frame.Destination, frame.Identification); if (context == null) { return(false); } IcmpFrame convertional = null; int ttl = frame.Ttl - 1; if (ttl <= 0) { convertional = new IcmpFrame(this.m_ethernetAddress, frame.Source, IPv4Layer.ToArray(packet)) { Ttl = packet.Ttl, Type = IcmpType.ICMP_TE, Code = 0, Sequence = 0, Identification = 0, }; IPFrame replay = CopyFrameHeaderParts(IcmpLayer.ToIPFrame(convertional), packet); if (replay == null) { return(false); } return(this.OnPrivateOutput(replay)); } else { convertional = new IcmpFrame(this.m_ethernetAddress, frame.Destination, frame.Payload) { Ttl = ttl, Type = frame.Type, Code = frame.Code, Sequence = frame.Sequence, Identification = frame.Identification /*unchecked((ushort)context.Destination.Port)*/, }; } IPFrame ip = CopyFrameHeaderParts(IcmpLayer.ToIPFrame(convertional), packet); if (ip == null) { return(false); } return(this.OnPublicOutput(ip)); }
protected virtual bool PublicIcmpInput(IPFrame packet) { IcmpFrame frame = IcmpLayer.ParseFrame(packet, true); // NDIS5/6内核层已检查过所以无需要重复计算ICMP报文CHECKSUM if (frame == null) { return(false); } bool success = false; // 不知道这样的数据报文应该发向那个主机时广播到还允许NAT穿透ICMP报文的多个主机(但仅限对于ICMP/NAT) foreach (NATContext secondary in this.m_contextsIcmp.GetAllContext()) // 稳定可靠NAT不丢帧(但可能造成虚拟NAT层压力过载) { success |= this.PublicIcmpNATOutput(secondary, frame, packet); } return(success); }
private bool PublicIcmpNATOutput(NATContext context, IcmpFrame frame, IPFrame packet) { if (context == null || frame == null || packet == null) { return(false); } if (frame.Type != IcmpType.ICMP_ER) // TIME EXCEEDED { IPFrame ipAgo = IPv4Layer.ParseFrame(frame.Payload, false); IcmpFrame icmpAgo = IcmpLayer.ParseFrame(ipAgo, false); if (icmpAgo == null) // 这是一个伪造的ICMP数据报,正确报文应答必须要包含从本机发向对端主机的ICMP/IP数据报文 { return(false); } ipAgo = CopyFrameHeaderParts(IcmpLayer.ToIPFrame(new IcmpFrame(frame.Source, context.Sources.Address, icmpAgo.Payload) // 重新汇编整个ICMP/IP数据报文 { Ttl = icmpAgo.Ttl, Type = icmpAgo.Type, Code = icmpAgo.Code, Sequence = icmpAgo.Sequence, Identification = unchecked ((ushort)context.Sources.Port), // 客户端ICMP协议请求时的凭证编号 }), ipAgo); frame.Payload = IPv4Layer.ToArray(ipAgo); } var convertional = new IcmpFrame(frame.Source, context.Sources.Address, frame.Payload) { Ttl = frame.Ttl - 1, Type = frame.Type, Code = frame.Code, Sequence = frame.Sequence, Identification = frame.Identification, }; IPFrame ip = CopyFrameHeaderParts(IcmpLayer.ToIPFrame(convertional), packet); if (ip == null) { return(false); } return(this.OnPrivateOutput(ip)); }
protected override bool EqualPayload(IcmpLayer other) { return(this.EqualPayload(other as IcmpTraceRouteLayer)); }
public static IEnumerable <ILayer> NextIcmpPayloadLayers(this Random random, IcmpLayer icmpLayer) { IEnumerable <ILayer> icmpPayloadLayers = new List <ILayer>(); switch (icmpLayer.MessageType) { case IcmpMessageType.DestinationUnreachable: case IcmpMessageType.TimeExceeded: case IcmpMessageType.ParameterProblem: case IcmpMessageType.SourceQuench: case IcmpMessageType.Redirect: case IcmpMessageType.SecurityFailures: icmpPayloadLayers = IEnumerableExtensions.Concat(icmpPayloadLayers, random.NextIpV4Layer(), random.NextPayloadLayer(IcmpIpV4HeaderPlus64BitsPayloadDatagram.OriginalDatagramPayloadLength)); break; case IcmpMessageType.ConversionFailed: IpV4Layer icmpIpV4Layer = random.NextIpV4Layer(); icmpPayloadLayers = IEnumerableExtensions.Concat(icmpPayloadLayers, icmpIpV4Layer); if (icmpLayer.MessageTypeAndCode == IcmpMessageTypeAndCode.ConversionFailedUnsupportedTransportProtocol) { icmpPayloadLayers = IEnumerableExtensions.Concat(icmpPayloadLayers, random.NextPayloadLayer( IcmpConversionFailedDatagram.OriginalDatagramLengthForUnsupportedTransportProtocol - icmpIpV4Layer.Length)); } else { switch (icmpIpV4Layer.Protocol) { case IpV4Protocol.Udp: icmpPayloadLayers = IEnumerableExtensions.Concat(icmpPayloadLayers, random.NextUdpLayer(), random.NextPayloadLayer(random.Next(100))); break; case IpV4Protocol.Tcp: icmpPayloadLayers = IEnumerableExtensions.Concat(icmpPayloadLayers, random.NextTcpLayer(), random.NextPayloadLayer(random.Next(100))); break; default: icmpPayloadLayers = IEnumerableExtensions.Concat(icmpPayloadLayers, random.NextPayloadLayer(random.Next(200))); break; } } break; case IcmpMessageType.Echo: case IcmpMessageType.EchoReply: case IcmpMessageType.Timestamp: case IcmpMessageType.TimestampReply: case IcmpMessageType.InformationRequest: case IcmpMessageType.InformationReply: case IcmpMessageType.RouterAdvertisement: case IcmpMessageType.RouterSolicitation: case IcmpMessageType.AddressMaskRequest: case IcmpMessageType.AddressMaskReply: case IcmpMessageType.TraceRoute: case IcmpMessageType.DomainNameRequest: break; case IcmpMessageType.DomainNameReply: default: throw new InvalidOperationException("Invalid icmpMessageType " + icmpLayer.MessageType); } return(icmpPayloadLayers); }
private static void CreateRandomIpPayload(Random random, Layer ipLayer, List <ILayer> layers) { IpV6Layer ipV6Layer = ipLayer as IpV6Layer; if (ipV6Layer != null) { var headers = ipV6Layer.ExtensionHeaders.Headers; if (headers.Any() && headers.Last().Protocol == IpV4Protocol.EncapsulatingSecurityPayload) { return; } } if (ipV6Layer != null ? ipV6Layer.LastNextHeader != null : random.NextBool(20)) { // Finish with payload. PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100)); layers.Add(payloadLayer); return; } IpV4Layer ipV4Layer = ipLayer as IpV4Layer; if (ipV4Layer != null) { ipV4Layer.Protocol = null; if (random.NextBool()) { ipV4Layer.Fragmentation = IpV4Fragmentation.None; } } switch (random.Next(0, 11)) { case 0: // IpV4. case 1: IpV4Layer innerIpV4Layer = random.NextIpV4Layer(); layers.Add(innerIpV4Layer); CreateRandomIpPayload(random, innerIpV4Layer, layers); return; case 2: // IpV6. case 3: IpV6Layer innerIpV6Layer = random.NextIpV6Layer(random.NextBool(20)); layers.Add(innerIpV6Layer); CreateRandomIpPayload(random, innerIpV6Layer, layers); return; case 4: // Igmp. layers.Add(random.NextIgmpLayer()); return; case 5: // Icmp. IcmpLayer icmpLayer = random.NextIcmpLayer(); layers.Add(icmpLayer); layers.AddRange(random.NextIcmpPayloadLayers(icmpLayer)); return; case 6: // Gre. GreLayer greLayer = random.NextGreLayer(); layers.Add(greLayer); CreateRandomEthernetPayload(random, greLayer, layers); return; case 7: // Udp. case 8: UdpLayer udpLayer = random.NextUdpLayer(); layers.Add(udpLayer); CreateRandomUdpPayload(random, udpLayer, layers); return; case 9: // Tcp. case 10: TcpLayer tcpLayer = random.NextTcpLayer(); layers.Add(tcpLayer); CreateRandomTcpPayload(random, tcpLayer, layers); return; default: throw new InvalidOperationException("Invalid value."); } }
public static Packet BuildIcmPacket(EthernetLayer ethernetFrame, IpV4Layer IpFrame, IcmpLayer IcmpFrame) { return(new PacketBuilder(ethernetFrame, IpFrame, IcmpFrame).Build(DateTime.Now)); }
public void RunFileWithSpeed(RunSpeeds run_speed) { if (string.IsNullOrEmpty(FileName)) { return; } if (run_speed == RunSpeeds.Original) { return; } if (PacketCount == 0 || SelectedNetworkAdapter == null) { return; } // Retrieve the length of the capture file long capLength = new FileInfo(FileName).Length; int time_interval = 100; switch (run_speed) { case RunSpeeds.Original: case RunSpeeds.s100: time_interval = 100; break; case RunSpeeds.Zero: time_interval = 1; break; case RunSpeeds.s250: time_interval = 250; break; case RunSpeeds.s500: time_interval = 500; break; case RunSpeeds.s1000: time_interval = 1000; break; default: time_interval = 100; break; } DateTime time_stamp = DateTime.Now; // Open the capture file OfflinePacketDevice selectedInputDevice = new OfflinePacketDevice(FileName); using (PacketCommunicator inputCommunicator = selectedInputDevice.Open(65536, // portion of the packet to capture // 65536 guarantees that the whole packet will be captured on all the link layers PacketDeviceOpenAttributes.Promiscuous, // promiscuous mode 1000)) // read timeout { // Open the output device using (PacketCommunicator outputCommunicator = SelectedNetworkAdapter.Open(100, PacketDeviceOpenAttributes.Promiscuous, 1000)) { // Fill the buffer with the packets from the file AlteredPackets = new List <Packet>(); Packet packet; int packet_count = 0; while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok) { // Create the builder that will build our packets EthernetLayer ethernet_layer = packet.Ethernet == null ? null : (EthernetLayer)packet.Ethernet.ExtractLayer(); IpV4Layer ipv4_layer = packet.Ethernet.IpV4 == null ? null : (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer(); IcmpLayer icmp_layer = packet.Ethernet.IpV4.Icmp == null ? null : (IcmpLayer)packet.Ethernet.IpV4.Icmp.ExtractLayer(); TransportLayer transport_layer = packet.Ethernet.IpV4.Transport == null ? null : (TransportLayer)packet.Ethernet.IpV4.Transport.ExtractLayer(); PayloadLayer datagram_layer = packet.Ethernet.IpV4.Payload == null ? null : (PayloadLayer)packet.Ethernet.IpV4.Payload.ExtractLayer(); try { if (ipv4_layer.Length < 1) // Catch null Length { // Do Nothing } } catch { ipv4_layer = null; } List <ILayer> layers = new List <ILayer>(); if (IsRTP(packet)) { if (ethernet_layer != null) { layers.Add(ethernet_layer); } if (ipv4_layer != null) { layers.Add(ipv4_layer); } if (datagram_layer != null) { layers.Add(datagram_layer); } } else { if (ethernet_layer != null) { layers.Add(ethernet_layer); } if (ipv4_layer != null) { layers.Add(ipv4_layer); } if (icmp_layer != null) { layers.Add(icmp_layer); } if (transport_layer != null) { layers.Add(transport_layer); } if (datagram_layer != null && IsRTP(packet)) { layers.Add(datagram_layer); } } PacketBuilder builder = new PacketBuilder(layers); Packet altered_packet = builder.Build(time_stamp.AddMilliseconds((packet_count * time_interval) / 1000)); ProcessAlteredPacket(altered_packet); packet_count++; } // Allocate a send buffer using (PacketSendBuffer sendBuffer = new PacketSendBuffer(4294967295)) { foreach (Packet p in AlteredPackets) { sendBuffer.Enqueue(p); } // Transmit the queue Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); long startTimeMs = stopwatch.ElapsedMilliseconds; Common.ConsoleWriteLine(ConsoleText); Common.ConsoleWriteLine(ConsoleText, "File:\n " + FileName.Substring(FileName.LastIndexOf("\\") + 1)); Common.ConsoleWriteLine(ConsoleText, " Start Time: " + startTimeMs); outputCommunicator.Transmit(sendBuffer, true); long endTimeMs = stopwatch.ElapsedMilliseconds; Common.ConsoleWriteLine(ConsoleText, " End Time: " + endTimeMs); long elapsedTimeMs = endTimeMs - startTimeMs; Common.ConsoleWriteLine(ConsoleText, " Elapsed Time: " + elapsedTimeMs); double averagePacketsPerSecond = elapsedTimeMs == 0 ? double.MaxValue : (double)AlteredPackets.Count / elapsedTimeMs * 1000; Common.ConsoleWriteLine(ConsoleText, " Elapsed time: " + elapsedTimeMs + " ms"); Common.ConsoleWriteLine(ConsoleText, " Total packets generated = " + AlteredPackets.Count); Common.ConsoleWriteLine(ConsoleText, " Average packets per second = " + averagePacketsPerSecond); Common.ConsoleWriteLine(ConsoleText, ""); } } } }
public void RandomIcmpTest() { EthernetLayer ethernetLayer = new EthernetLayer { Source = new MacAddress("00:01:02:03:04:05"), Destination = new MacAddress("A0:A1:A2:A3:A4:A5") }; int seed = new Random().Next(); Console.WriteLine("Seed: " + seed); Random random = new Random(seed); for (int i = 0; i != 2000; ++i) { IpV4Layer ipV4Layer = random.NextIpV4Layer(null); ipV4Layer.HeaderChecksum = null; Layer ipLayer = random.NextBool() ? (Layer)ipV4Layer : random.NextIpV6Layer(IpV4Protocol.InternetControlMessageProtocol, false); IcmpLayer icmpLayer = random.NextIcmpLayer(); icmpLayer.Checksum = null; if (icmpLayer.MessageType == IcmpMessageType.DestinationUnreachable && icmpLayer.MessageTypeAndCode != IcmpMessageTypeAndCode.DestinationUnreachableFragmentationNeededAndDoNotFragmentSet) { ((IcmpDestinationUnreachableLayer)icmpLayer).NextHopMaximumTransmissionUnit = 0; } IEnumerable <ILayer> icmpPayloadLayers = random.NextIcmpPayloadLayers(icmpLayer); int icmpPayloadLength = icmpPayloadLayers.Select(layer => layer.Length).Sum(); switch (icmpLayer.MessageType) { case IcmpMessageType.ParameterProblem: if (icmpPayloadLength % 4 != 0) { icmpPayloadLayers = icmpPayloadLayers.Concat(new[] { new PayloadLayer { Data = random.NextDatagram(4 - icmpPayloadLength % 4) } }); } icmpPayloadLength = icmpPayloadLayers.Select(layer => layer.Length).Sum(); IcmpParameterProblemLayer icmpParameterProblemLayer = (IcmpParameterProblemLayer)icmpLayer; icmpParameterProblemLayer.Pointer = (byte)(icmpParameterProblemLayer.Pointer % icmpPayloadLength); icmpParameterProblemLayer.OriginalDatagramLength = icmpPayloadLength - icmpPayloadLayers.First().Length; break; case IcmpMessageType.SecurityFailures: ((IcmpSecurityFailuresLayer)icmpLayer).Pointer %= (ushort)icmpPayloadLength; break; } PacketBuilder packetBuilder = new PacketBuilder(new ILayer[] { ethernetLayer, ipLayer, icmpLayer }.Concat(icmpPayloadLayers)); Packet packet = packetBuilder.Build(DateTime.Now); Assert.IsTrue(packet.IsValid, "IsValid"); byte[] buffer = (byte[])packet.Buffer.Clone(); buffer.Write(ethernetLayer.Length + ipLayer.Length, random.NextDatagram(icmpLayer.Length)); Packet illegalPacket = new Packet(buffer, DateTime.Now, packet.DataLink); Assert.IsFalse(illegalPacket.IsValid, "IsInvalid"); if (illegalPacket.Ethernet.Ip.Icmp is IcmpUnknownDatagram) { byte[] icmpBuffer = new byte[illegalPacket.Ethernet.Ip.Icmp.ExtractLayer().Length]; ILayer layer = illegalPacket.Ethernet.Ip.Icmp.ExtractLayer(); layer.Write(icmpBuffer, 0, icmpBuffer.Length, null, null); layer.Finalize(icmpBuffer, 0, icmpBuffer.Length, null); MoreAssert.AreSequenceEqual(illegalPacket.Ethernet.Ip.Icmp.ToArray(), icmpBuffer); Assert.AreEqual(illegalPacket, PacketBuilder.Build(DateTime.Now, ethernetLayer, ipLayer, illegalPacket.Ethernet.Ip.Icmp.ExtractLayer())); } // Ethernet ethernetLayer.EtherType = ipLayer == ipV4Layer ? EthernetType.IpV4 : EthernetType.IpV6; Assert.AreEqual(ethernetLayer, packet.Ethernet.ExtractLayer(), "Ethernet Layer"); ethernetLayer.EtherType = EthernetType.None; // IP. if (ipLayer == ipV4Layer) { // IPv4. ipV4Layer.Protocol = IpV4Protocol.InternetControlMessageProtocol; ipV4Layer.HeaderChecksum = ((IpV4Layer)packet.Ethernet.IpV4.ExtractLayer()).HeaderChecksum; Assert.AreEqual(ipV4Layer, packet.Ethernet.IpV4.ExtractLayer()); ipV4Layer.HeaderChecksum = null; Assert.AreEqual(ipV4Layer.Length, packet.Ethernet.IpV4.HeaderLength); Assert.IsTrue(packet.Ethernet.IpV4.IsHeaderChecksumCorrect); Assert.AreEqual(ipV4Layer.Length + icmpLayer.Length + icmpPayloadLength, packet.Ethernet.IpV4.TotalLength); Assert.AreEqual(IpV4Datagram.DefaultVersion, packet.Ethernet.IpV4.Version); } else { // IPv6. Assert.AreEqual(ipLayer, packet.Ethernet.IpV6.ExtractLayer()); } // ICMP IcmpDatagram actualIcmp = packet.Ethernet.Ip.Icmp; IcmpLayer actualIcmpLayer = (IcmpLayer)actualIcmp.ExtractLayer(); icmpLayer.Checksum = actualIcmpLayer.Checksum; Assert.AreEqual(icmpLayer, actualIcmpLayer); Assert.AreEqual(icmpLayer.GetHashCode(), actualIcmpLayer.GetHashCode()); if (actualIcmpLayer.MessageType != IcmpMessageType.RouterSolicitation) { Assert.AreNotEqual(random.NextIcmpLayer(), actualIcmpLayer); IcmpLayer otherIcmpLayer = random.NextIcmpLayer(); Assert.AreNotEqual(otherIcmpLayer.GetHashCode(), actualIcmpLayer.GetHashCode()); } Assert.IsTrue(actualIcmp.IsChecksumCorrect); Assert.AreEqual(icmpLayer.MessageType, actualIcmp.MessageType); Assert.AreEqual(icmpLayer.CodeValue, actualIcmp.Code); Assert.AreEqual(icmpLayer.MessageTypeAndCode, actualIcmp.MessageTypeAndCode); Assert.AreEqual(packet.Length - ethernetLayer.Length - ipLayer.Length - IcmpDatagram.HeaderLength, actualIcmp.Payload.Length); Assert.IsNotNull(icmpLayer.ToString()); switch (packet.Ethernet.Ip.Icmp.MessageType) { case IcmpMessageType.RouterSolicitation: case IcmpMessageType.SourceQuench: case IcmpMessageType.TimeExceeded: Assert.AreEqual <uint>(0, actualIcmp.Variable); break; case IcmpMessageType.DestinationUnreachable: case IcmpMessageType.ParameterProblem: case IcmpMessageType.Redirect: case IcmpMessageType.ConversionFailed: case IcmpMessageType.Echo: case IcmpMessageType.EchoReply: case IcmpMessageType.Timestamp: case IcmpMessageType.TimestampReply: case IcmpMessageType.InformationRequest: case IcmpMessageType.InformationReply: case IcmpMessageType.RouterAdvertisement: case IcmpMessageType.AddressMaskRequest: case IcmpMessageType.AddressMaskReply: break; case IcmpMessageType.TraceRoute: Assert.AreEqual(((IcmpTraceRouteLayer)icmpLayer).ReturnHopCount == 0xFFFF, ((IcmpTraceRouteDatagram)actualIcmp).IsOutbound); break; case IcmpMessageType.DomainNameRequest: case IcmpMessageType.SecurityFailures: break; case IcmpMessageType.DomainNameReply: default: throw new InvalidOperationException("Invalid icmpMessageType " + packet.Ethernet.Ip.Icmp.MessageType); } } }
/// <summary> /// True iff the OutboundHopCount, ReturnHopCount, OutputLinkSpeed and OutputLinkMaximumTransmissionUnit fields are equal to the other layer fields. /// </summary> protected override bool EqualPayload(IcmpLayer other) { return EqualPayload(other as IcmpTraceRouteLayer); }