expert_vision

NMLB

Jan 6th, 2014
531
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 30.77 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using Microsoft.Win32;
  4. using System.Threading;
  5. using System.Runtime.InteropServices;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using PcapDotNet.Base;
  11. using PcapDotNet.Core;
  12. using PcapDotNet.Packets;
  13. using PcapDotNet.Packets.Arp;
  14. using PcapDotNet.Packets.Dns;
  15. using PcapDotNet.Packets.Ethernet;
  16. using PcapDotNet.Packets.Gre;
  17. using PcapDotNet.Packets.Http;
  18. using PcapDotNet.Packets.Icmp;
  19. using PcapDotNet.Packets.Igmp;
  20. using PcapDotNet.Packets.IpV4;
  21. using PcapDotNet.Packets.Transport;
  22.  
  23. namespace NMLB
  24. {
  25.     class MainThread
  26.     {
  27.         public static TapWorker tapWorker = null;
  28.         public static IList<PhysicalWorker> physicalWorkers = new List<PhysicalWorker>();
  29.         //[STAThread]
  30.         public static void Main(string[] args)
  31.         {
  32.             if (args.Length < 8)
  33.                 Environment.Exit(0);
  34.  
  35.             tapWorker = new TapWorker(args[0], args[1], args[2]);
  36.             Thread tapWorkerThread = new Thread(new ThreadStart(tapWorker.ReceivePackets));
  37.             tapWorkerThread.Start();
  38.             IList<Thread> physicalWorkerThreads = new List<Thread>();
  39.             int deadGateways = 0;
  40.  
  41.             for (int i = 3; i < args.Length; i = i + 5)
  42.             {
  43.                 if (args[i + 3] != "0")
  44.                 {
  45.                     physicalWorkers.Add(new PhysicalWorker(args[i], args[i + 1], args[i + 2], args[i + 3], args[i + 4]));
  46.                     physicalWorkerThreads.Add(new Thread(new ThreadStart(physicalWorkers[(i - 3) / 5 - deadGateways].ReceivePackets)));
  47.                     physicalWorkerThreads[(i - 3) / 5 - deadGateways].Start();
  48.                 }
  49.                 else
  50.                     deadGateways++;
  51.             }
  52.         }
  53.  
  54.  
  55.  
  56.  
  57.     }
  58.  
  59.     // TAP interface worker
  60.     class TapWorker
  61.     {
  62.         public static string ownProtocolAddressString = "192.168.200.1";
  63.         public static string ownHardwareAddressString = "0A:03:03:03:03:03";
  64.         public static string ifProtocolAddressString;
  65.         public static string ifHardwareAddressString;
  66.         public static IpV4Address ownProtocolAddress = new IpV4Address(ownProtocolAddressString);
  67.         public static MacAddress ownHardwareAddress = new MacAddress(ownHardwareAddressString);
  68.         public static IpV4Address ifProtocolAddress;
  69.         public static MacAddress ifHardwareAddress;
  70.         public static byte[] ownProtocolAddressByte = { 192, 168, 200, 1 };
  71.         public static byte[] ownHardwareAddressByte = { 10, 3, 3, 3, 3, 3 };
  72.         public static byte[] ifProtocolAddressByte;
  73.         public static byte[] ifHardwareAddressByte;
  74.         public static PacketCommunicator communicator;
  75.         public static FragmentationBuffer fragBuffer = new FragmentationBuffer();
  76.         public static IList<Packet> fragments = new List<Packet>();
  77.         public static int MTU = 1500;
  78.         string tapGuid;
  79.  
  80.  
  81.  
  82.         public TapWorker(string guid, string mac, string ip)
  83.         {
  84.             tapGuid = guid;
  85.             ifHardwareAddressString = mac;
  86.             ifProtocolAddressString = ip;
  87.             ifHardwareAddress = new MacAddress(ifHardwareAddressString);
  88.             ifProtocolAddress = new IpV4Address(ifProtocolAddressString);
  89.             ifHardwareAddressByte = new byte[]
  90.             {
  91.                 (byte)ifHardwareAddress.ToValue(),
  92.                 (byte)(ifHardwareAddress.ToValue() >> 8),
  93.                 (byte)(ifHardwareAddress.ToValue() >> 16),
  94.                 (byte)(ifHardwareAddress.ToValue() >> 24)
  95.             };
  96.             ifProtocolAddressByte = new byte[]
  97.             {
  98.                 (byte)ifProtocolAddress.ToValue(),
  99.                 (byte)(ifProtocolAddress.ToValue() >> 8),
  100.                 (byte)(ifProtocolAddress.ToValue() >> 16),
  101.                 (byte)(ifProtocolAddress.ToValue() >> 24)
  102.             };
  103.         }
  104.         public void SendPacket(Packet packet)
  105.         {
  106.             Console.WriteLine(packet.Ethernet.Source + " " + packet.Ethernet.Destination + " " + packet.Ethernet.IpV4.Source + " " + packet.Ethernet.IpV4.Destination + " " + packet.Ethernet.IpV4.Protocol);
  107.             communicator.SendPacket(packet);
  108.         }
  109.         public void ReceivePackets()
  110.         {
  111.             // Retrieve the device list from the local machine
  112.             IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;
  113.  
  114.             // Find the NPF device of the TAP interface
  115.             PacketDevice selectedDevice = null;
  116.             for (int i = 0; i != allDevices.Count; ++i)
  117.             {
  118.                 LivePacketDevice device = allDevices[i];
  119.                 if (device.Name.Contains(tapGuid))
  120.                 {
  121.                     selectedDevice = device;
  122.                     break;
  123.                 }
  124.             }
  125.  
  126.             if (selectedDevice == null)
  127.                 Environment.Exit(0);
  128.             communicator = selectedDevice.Open(65536, PacketDeviceOpenAttributes.MaximumResponsiveness, 1000);
  129.             {
  130.                 Console.WriteLine("Listening on " + selectedDevice.Description + "...");
  131.  
  132.                 communicator.SetFilter("(ether dst " + ownHardwareAddressString + " and (ip or arp)) or (ether dst FF:FF:FF:FF:FF:FF and arp)");
  133.  
  134.                 communicator.ReceivePackets(0, (packet) =>
  135.                 {
  136.                     if (packet.Ethernet.EtherType == EthernetType.Arp)
  137.                     {
  138.                         string TargetProtocolAddressString = packet.Ethernet.Arp.TargetProtocolAddress[0] + "." +
  139.                             packet.Ethernet.Arp.TargetProtocolAddress[1] + "." +
  140.                             packet.Ethernet.Arp.TargetProtocolAddress[2] + "." +
  141.                             packet.Ethernet.Arp.TargetProtocolAddress[3];
  142.                         if (TargetProtocolAddressString == ownProtocolAddressString && packet.Ethernet.Arp.Operation == ArpOperation.Request)
  143.                         {
  144.                             EthernetLayer ethernetLayer =
  145.                             new EthernetLayer
  146.                             {
  147.                                 Source = ownHardwareAddress,
  148.                                 Destination = packet.Ethernet.Source,
  149.                                 EtherType = EthernetType.None,
  150.                             };
  151.  
  152.                             ArpLayer arpLayer =
  153.                             new ArpLayer
  154.                             {
  155.                                 ProtocolType = EthernetType.IpV4,
  156.                                 Operation = ArpOperation.Reply,
  157.                                 SenderHardwareAddress = ownHardwareAddressByte.AsReadOnly(),
  158.                                 SenderProtocolAddress = packet.Ethernet.Arp.TargetProtocolAddress,
  159.                                 TargetHardwareAddress = packet.Ethernet.Arp.SenderHardwareAddress,
  160.                                 TargetProtocolAddress = packet.Ethernet.Arp.SenderProtocolAddress,
  161.                             };
  162.  
  163.                             PacketBuilder builder = new PacketBuilder(ethernetLayer, arpLayer);
  164.                             communicator.SendPacket(builder.Build(DateTime.Now));
  165.                         }
  166.                     }
  167.                     if (packet.Ethernet.EtherType.ToString() == "IpV4")
  168.                     {
  169.  
  170.                         if (packet.Ethernet.IpV4.Fragmentation.Options == IpV4FragmentationOptions.DoNotFragment ||
  171.                             packet.Ethernet.IpV4.Fragmentation.Options == IpV4FragmentationOptions.None && packet.Ethernet.IpV4.Fragmentation.Offset == 0)
  172.                         {
  173.                             IpV4Handler(packet);
  174.                         }
  175.                         if (packet.Ethernet.IpV4.Fragmentation.Options == IpV4FragmentationOptions.MoreFragments ||
  176.                             packet.Ethernet.IpV4.Fragmentation.Options == IpV4FragmentationOptions.None && packet.Ethernet.IpV4.Fragmentation.Offset > 0)
  177.                         {
  178.                             fragments = fragBuffer.Add(packet);
  179.                             if (fragments != null)
  180.                                 for (int i = 0; i < fragments.Count; i++)
  181.                                 {
  182.                                     IpV4Handler(fragments[i], fragments);
  183.                                 }
  184.                         }
  185.                     }
  186.  
  187.  
  188.  
  189.                 });
  190.             }
  191.  
  192.  
  193.         }
  194.  
  195.         public static void IpV4Handler(Packet packet, IList<Packet> packetList = null)
  196.         {
  197.             if (packet.Ethernet.IpV4.Length > MTU)
  198.             {
  199.                 EthernetLayer ethernetLayer =
  200.                     new EthernetLayer
  201.                     {
  202.                         Source = ownHardwareAddress,
  203.                         Destination = packet.Ethernet.Source,
  204.                         EtherType = EthernetType.None,
  205.                     };
  206.                 IpV4Layer ipV4Layer =
  207.                 new IpV4Layer
  208.                 {
  209.                     Source = packet.Ethernet.IpV4.Destination,
  210.                     CurrentDestination = packet.Ethernet.IpV4.Source,
  211.                     Fragmentation = packet.Ethernet.IpV4.Fragmentation,
  212.                     HeaderChecksum = null, // Will be filled automatically.
  213.                     Identification = 123,
  214.                     Options = packet.Ethernet.IpV4.Options,
  215.                     Protocol = packet.Ethernet.IpV4.Protocol,
  216.                     Ttl = packet.Ethernet.IpV4.Ttl,
  217.                     TypeOfService = packet.Ethernet.IpV4.TypeOfService,
  218.                 };
  219.                 IcmpDestinationUnreachableLayer payloadLayer = new IcmpDestinationUnreachableLayer
  220.                 {
  221.                     Code = IcmpCodeDestinationUnreachable.FragmentationNeededAndDoNotFragmentSet,
  222.                     NextHopMaximumTransmissionUnit = (ushort)MTU,
  223.                 };
  224.  
  225.                 PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, payloadLayer);
  226.                 communicator.SendPacket(builder.Build(DateTime.Now));
  227.                 return;
  228.             }
  229.             if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.InternetControlMessageProtocol)
  230.             {
  231.  
  232.                 if (packet.Ethernet.IpV4.Destination == ownProtocolAddress)
  233.                 {
  234.                     if ((packet.Ethernet.IpV4.Icmp.MessageType == IcmpMessageType.Echo || packet.Ethernet.IpV4.Fragmentation.Offset > 0))
  235.                     {
  236.                         EthernetLayer ethernetLayer =
  237.                         new EthernetLayer
  238.                         {
  239.                             Source = ownHardwareAddress,
  240.                             Destination = packet.Ethernet.Source,
  241.                             EtherType = EthernetType.None,
  242.                         };
  243.                         IpV4Layer ipV4Layer =
  244.                         new IpV4Layer
  245.                         {
  246.                             Source = packet.Ethernet.IpV4.Destination,
  247.                             CurrentDestination = packet.Ethernet.IpV4.Source,
  248.                             Fragmentation = packet.Ethernet.IpV4.Fragmentation,
  249.                             HeaderChecksum = null, // Will be filled automatically.
  250.                             Identification = 123,
  251.                             Options = packet.Ethernet.IpV4.Options,
  252.                             Protocol = packet.Ethernet.IpV4.Protocol,
  253.                             Ttl = packet.Ethernet.IpV4.Ttl,
  254.                             TypeOfService = packet.Ethernet.IpV4.TypeOfService,
  255.                         };
  256.                         if (packet.Ethernet.IpV4.Fragmentation.Options == IpV4FragmentationOptions.DoNotFragment ||
  257.                             packet.Ethernet.IpV4.Fragmentation.Options == IpV4FragmentationOptions.None && packet.Ethernet.IpV4.Fragmentation.Offset == 0)
  258.                         {
  259.                             byte[] icmpPacket = packet.Ethernet.IpV4.Payload.ToArray();
  260.                             icmpPacket[0] = 0;
  261.                             icmpPacket[2] = 0;
  262.                             icmpPacket[3] = 0;
  263.                             ushort checksum = IpFunctions.ComputeIpChecksum(icmpPacket);
  264.                             icmpPacket[2] = (byte)(checksum >> 8);
  265.                             icmpPacket[3] = (byte)(checksum & 0xff);
  266.                             PayloadLayer payloadLayer =
  267.                             new PayloadLayer
  268.                             {
  269.                                 Data = new Datagram(icmpPacket),
  270.                             };
  271.                             PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, payloadLayer);
  272.                             communicator.SendPacket(builder.Build(DateTime.Now));
  273.                         }
  274.                         else if (packet.Ethernet.IpV4.Fragmentation.Offset == 0 && packet.Ethernet.IpV4.Fragmentation.Options == IpV4FragmentationOptions.MoreFragments)
  275.                         {
  276.                             byte[] icmpHeader = packet.Ethernet.IpV4.Payload.ToArray();
  277.                             icmpHeader[0] = 0;
  278.                             icmpHeader[2] = 0;
  279.                             icmpHeader[3] = 0;
  280.                             int icmpPacketLength = icmpHeader.Length;
  281.                             for (int i = 1; i < packetList.Count; i++)
  282.                             {
  283.                                 icmpPacketLength += packetList[i].Ethernet.IpV4.Payload.ToArray().Length;
  284.                             }
  285.                             byte[] icmpPacket = new byte[icmpPacketLength];
  286.                             Buffer.BlockCopy(icmpHeader, 0, icmpPacket, 0, icmpHeader.Length);
  287.                             icmpPacketLength = icmpHeader.Length;
  288.                             for (int i = 1; i < packetList.Count; i++)
  289.                             {
  290.                                 Buffer.BlockCopy(packetList[i].Ethernet.IpV4.Payload.ToArray(), 0, icmpPacket, icmpPacketLength, packetList[i].Ethernet.IpV4.Payload.ToArray().Length);
  291.                                 icmpPacketLength += packetList[i].Ethernet.IpV4.Payload.ToArray().Length;
  292.                             }
  293.                             ushort checksum = IpFunctions.ComputeIpChecksum(icmpPacket);
  294.                             icmpHeader[2] = (byte)(checksum >> 8);
  295.                             icmpHeader[3] = (byte)(checksum & 0xff);
  296.                             PayloadLayer payloadLayer =
  297.                             new PayloadLayer
  298.                             {
  299.                                 Data = new Datagram(icmpHeader),
  300.                             };
  301.                             PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, payloadLayer);
  302.                             communicator.SendPacket(builder.Build(DateTime.Now));
  303.                         }
  304.                         else
  305.                         {
  306.                             PayloadLayer payloadLayer =
  307.                             new PayloadLayer
  308.                             {
  309.                                 Data = new Datagram(packet.Ethernet.IpV4.Payload.ToArray()),
  310.                             };
  311.                             PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, payloadLayer);
  312.                             communicator.SendPacket(builder.Build(DateTime.Now));
  313.                         }
  314.                     }
  315.                 }
  316.                 else if (packet.Ethernet.IpV4.Source == ifProtocolAddress)
  317.                     if ((packet.Ethernet.IpV4.Icmp.MessageType == IcmpMessageType.Echo || packet.Ethernet.IpV4.Fragmentation.Offset > 0))
  318.                     {
  319.                         {
  320.                             EthernetLayer ethernetLayer =
  321.                                 new EthernetLayer
  322.                                 {
  323.                                     Source = MainThread.physicalWorkers[0].ifHardwareAddress,
  324.                                     Destination = MainThread.physicalWorkers[0].gatewayHardwareAddress,
  325.                                     EtherType = EthernetType.None,
  326.                                 };
  327.                             IpV4Layer ipV4Layer =
  328.                             new IpV4Layer
  329.                             {
  330.                                 Source = MainThread.physicalWorkers[0].ifProtocolAddress,
  331.                                 CurrentDestination = packet.Ethernet.IpV4.Destination,
  332.                                 Fragmentation = packet.Ethernet.IpV4.Fragmentation,
  333.                                 HeaderChecksum = null, // Will be filled automatically.
  334.                                 Identification = packet.Ethernet.IpV4.Identification,
  335.                                 Options = packet.Ethernet.IpV4.Options,
  336.                                 Protocol = packet.Ethernet.IpV4.Protocol,
  337.                                 Ttl = packet.Ethernet.IpV4.Ttl,
  338.                                 TypeOfService = packet.Ethernet.IpV4.TypeOfService,
  339.                             };
  340.                             PayloadLayer payloadLayer =
  341.                             new PayloadLayer
  342.                             {
  343.                                 Data = new Datagram(packet.Ethernet.IpV4.Payload.ToArray()),
  344.                             };
  345.                             PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, payloadLayer);
  346.                             MainThread.physicalWorkers[0].SendPacket(builder.Build(DateTime.Now));
  347.  
  348.                         }
  349.                     }
  350.  
  351.  
  352.  
  353.             }
  354.             else if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Tcp || packet.Ethernet.IpV4.Protocol == IpV4Protocol.Udp)
  355.             {
  356.                 if (packet.Ethernet.IpV4.Source == ifProtocolAddress)
  357.                 {
  358.                     EthernetLayer ethernetLayer =
  359.                                 new EthernetLayer
  360.                                 {
  361.                                     Source = MainThread.physicalWorkers[0].ifHardwareAddress,
  362.                                     Destination = MainThread.physicalWorkers[0].gatewayHardwareAddress,
  363.                                     EtherType = packet.Ethernet.EtherType,
  364.                                 };
  365.                     IpV4Layer ipV4Layer =
  366.                     new IpV4Layer
  367.                     {
  368.                         Source = MainThread.physicalWorkers[0].ifProtocolAddress,
  369.                         CurrentDestination = packet.Ethernet.IpV4.Destination,
  370.                         Fragmentation = packet.Ethernet.IpV4.Fragmentation,
  371.                         HeaderChecksum = null, // Will be filled automatically.
  372.                         Identification = packet.Ethernet.IpV4.Identification,
  373.                         Options = packet.Ethernet.IpV4.Options,
  374.                         Protocol = packet.Ethernet.IpV4.Protocol,
  375.                         Ttl = packet.Ethernet.IpV4.Ttl,
  376.                         TypeOfService = packet.Ethernet.IpV4.TypeOfService,
  377.                     };
  378.                     PayloadLayer payloadLayer =
  379.                     new PayloadLayer
  380.                     {
  381.                         Data = new Datagram(packet.Ethernet.IpV4.Payload.ToArray()),
  382.                     };
  383.                     PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, payloadLayer);
  384.                     MainThread.physicalWorkers[0].SendPacket(builder.Build(DateTime.Now));
  385.                 }
  386.             }
  387.         }
  388.  
  389.  
  390.     }
  391.  
  392.     // Physical interface worker
  393.     class PhysicalWorker
  394.     {
  395.         public PacketCommunicator communicator = null;
  396.         public FragmentationBuffer fragBuffer = new FragmentationBuffer();
  397.         public IList<Packet> fragments = new List<Packet>();
  398.         public static int MTU = 1500;
  399.         public string ifProtocolAddressString;
  400.         public string ifHardwareAddressString;
  401.         public string gatewayProtocolAddressString;
  402.         public string gatewayHardwareAddressString;
  403.         public IpV4Address ifProtocolAddress;
  404.         public MacAddress ifHardwareAddress;
  405.         public IpV4Address gatewayProtocolAddress;
  406.         public MacAddress gatewayHardwareAddress;
  407.         public byte[] ifProtocolAddressByte;
  408.         public byte[] ifHardwareAddressByte;
  409.         public byte[] gatewayProtocolAddressByte;
  410.         public byte[] gatewayHardwareAddressByte;
  411.         string ifGuid;
  412.  
  413.         public PhysicalWorker(string guid, string ifMac, string ifIp, string gatewayMac, string gatewayIp)
  414.         {
  415.             ifGuid = guid;
  416.             ifHardwareAddressString = ifMac;
  417.             ifProtocolAddressString = ifIp;
  418.             gatewayHardwareAddressString = gatewayMac;
  419.             gatewayProtocolAddressString = gatewayIp;
  420.             ifHardwareAddress = new MacAddress(ifHardwareAddressString);
  421.             ifProtocolAddress = new IpV4Address(ifProtocolAddressString);
  422.             gatewayHardwareAddress = new MacAddress(gatewayHardwareAddressString);
  423.             gatewayProtocolAddress = new IpV4Address(gatewayProtocolAddressString);
  424.             ifHardwareAddressByte = new byte[]
  425.             {
  426.                 (byte)ifHardwareAddress.ToValue(),
  427.                 (byte)(ifHardwareAddress.ToValue() >> 8),
  428.                 (byte)(ifHardwareAddress.ToValue() >> 16),
  429.                 (byte)(ifHardwareAddress.ToValue() >> 24)
  430.             };
  431.             ifProtocolAddressByte = new byte[]
  432.             {
  433.                 (byte)ifProtocolAddress.ToValue(),
  434.                 (byte)(ifProtocolAddress.ToValue() >> 8),
  435.                 (byte)(ifProtocolAddress.ToValue() >> 16),
  436.                 (byte)(ifProtocolAddress.ToValue() >> 24)
  437.             };
  438.             gatewayHardwareAddressByte = new byte[]
  439.             {
  440.                 (byte)gatewayHardwareAddress.ToValue(),
  441.                 (byte)(gatewayHardwareAddress.ToValue() >> 8),
  442.                 (byte)(gatewayHardwareAddress.ToValue() >> 16),
  443.                 (byte)(gatewayHardwareAddress.ToValue() >> 24)
  444.             };
  445.             gatewayProtocolAddressByte = new byte[]
  446.             {
  447.                 (byte)gatewayProtocolAddress.ToValue(),
  448.                 (byte)(gatewayProtocolAddress.ToValue() >> 8),
  449.                 (byte)(gatewayProtocolAddress.ToValue() >> 16),
  450.                 (byte)(gatewayProtocolAddress.ToValue() >> 24)
  451.             };
  452.         }
  453.         public void SendPacket(Packet packet)
  454.         {
  455.             Console.WriteLine(packet.Ethernet.Source + " " + packet.Ethernet.Destination + " " + packet.Ethernet.IpV4.Source + " " + packet.Ethernet.IpV4.Destination + " " + packet.Ethernet.IpV4.Protocol);
  456.             communicator.SendPacket(packet);
  457.         }
  458.         public void ReceivePackets()
  459.         {
  460.             // Retrieve the device list from the local machine
  461.             IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;
  462.  
  463.             // Find the NPF device of the interface
  464.             PacketDevice selectedDevice = null;
  465.             for (int i = 0; i != allDevices.Count; ++i)
  466.             {
  467.                 LivePacketDevice device = allDevices[i];
  468.                 if (device.Name.Contains(ifGuid))
  469.                 {
  470.                     selectedDevice = device;
  471.                     break;
  472.                 }
  473.             }
  474.  
  475.             if (selectedDevice == null)
  476.                 Environment.Exit(0);
  477.             communicator = selectedDevice.Open(65536, PacketDeviceOpenAttributes.MaximumResponsiveness, 1000);
  478.             {
  479.                 Console.WriteLine("Listening on " + selectedDevice.Description + "...");
  480.  
  481.                 communicator.SetFilter("(ether dst " + ifHardwareAddressString + " and (ip or arp)) or (ether dst FF:FF:FF:FF:FF:FF and arp)");
  482.  
  483.                 communicator.ReceivePackets(0, (packet) =>
  484.                 {
  485.  
  486.  
  487.                     //if (packet.Ethernet.EtherType == EthernetType.Arp)
  488.  
  489.                     if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.InternetControlMessageProtocol)
  490.                     {
  491.  
  492.                         if (packet.Ethernet.IpV4.Destination == ifProtocolAddress)
  493.                             if ((packet.Ethernet.IpV4.Icmp.MessageType == IcmpMessageType.EchoReply || packet.Ethernet.IpV4.Fragmentation.Offset > 0))
  494.                             {
  495.                                 EthernetLayer ethernetLayer =
  496.                                 new EthernetLayer
  497.                                 {
  498.                                     Source = TapWorker.ownHardwareAddress,
  499.                                     Destination = TapWorker.ifHardwareAddress,
  500.                                     EtherType = EthernetType.None,
  501.                                 };
  502.                                 IpV4Layer ipV4Layer =
  503.                                 new IpV4Layer
  504.                                 {
  505.                                     Source = packet.Ethernet.IpV4.Source,
  506.                                     CurrentDestination = TapWorker.ifProtocolAddress,
  507.                                     Fragmentation = packet.Ethernet.IpV4.Fragmentation,
  508.                                     HeaderChecksum = null, // Will be filled automatically.
  509.                                     Identification = packet.Ethernet.IpV4.Identification,
  510.                                     Options = packet.Ethernet.IpV4.Options,
  511.                                     Protocol = packet.Ethernet.IpV4.Protocol,
  512.                                     Ttl = packet.Ethernet.IpV4.Ttl,
  513.                                     TypeOfService = packet.Ethernet.IpV4.TypeOfService,
  514.                                 };
  515.                                 PayloadLayer payloadLayer =
  516.                                 new PayloadLayer
  517.                                 {
  518.                                     Data = new Datagram(packet.Ethernet.IpV4.Payload.ToArray()),
  519.                                 };
  520.                                 PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, payloadLayer);
  521.                                 MainThread.tapWorker.SendPacket(builder.Build(DateTime.Now));
  522.                             }
  523.                     }
  524.                     else if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Tcp)
  525.                     {
  526.                         if (packet.Ethernet.IpV4.Destination == ifProtocolAddress)
  527.                         {
  528.                             EthernetLayer ethernetLayer =
  529.                                         new EthernetLayer
  530.                                         {
  531.                                             Source = TapWorker.ownHardwareAddress,
  532.                                             Destination = TapWorker.ifHardwareAddress,
  533.                                             EtherType = packet.Ethernet.EtherType,
  534.                                         };
  535.                             IpV4Layer ipV4Layer =
  536.                             new IpV4Layer
  537.                             {
  538.                                 Source = packet.Ethernet.IpV4.Source,
  539.                                 CurrentDestination = TapWorker.ifProtocolAddress,
  540.                                 Fragmentation = packet.Ethernet.IpV4.Fragmentation,
  541.                                 HeaderChecksum = null, // Will be filled automatically.
  542.                                 Identification = packet.Ethernet.IpV4.Identification,
  543.                                 Options = packet.Ethernet.IpV4.Options,
  544.                                 Protocol = packet.Ethernet.IpV4.Protocol,
  545.                                 Ttl = packet.Ethernet.IpV4.Ttl,
  546.                                 TypeOfService = packet.Ethernet.IpV4.TypeOfService,
  547.                             };
  548.                             PayloadLayer payloadLayer =
  549.                             new PayloadLayer
  550.                             {
  551.                                 Data = new Datagram(packet.Ethernet.IpV4.Payload.ToArray()),
  552.                             };
  553.                             PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, payloadLayer);
  554.                             MainThread.tapWorker.SendPacket(builder.Build(DateTime.Now));
  555.                         }
  556.                     }
  557.                 });
  558.             }
  559.         }
  560.     }
  561.  
  562.  
  563.     class FragmentationBuffer
  564.     {
  565.         struct DictKey
  566.         {
  567.             public DictKey(IpV4Address ip, ushort id)
  568.             {
  569.                 this.Ip = ip;
  570.                 this.Identification = id;
  571.             }
  572.             private IpV4Address Ip;
  573.             private ushort Identification;
  574.         }
  575.         class DictValue
  576.         {
  577.             public IList<Packet> fragments = new List<Packet>();
  578.             private int offset = 0;
  579.             private ushort lastOffset = 0;
  580.  
  581.             public bool AddPacket(Packet packet)
  582.             {
  583.                 fragments.Add(packet);
  584.                 if (packet.Ethernet.IpV4.Fragmentation.Options == IpV4FragmentationOptions.None && packet.Ethernet.IpV4.Fragmentation.Offset > 0)
  585.                     lastOffset = packet.Ethernet.IpV4.Fragmentation.Offset;
  586.                 else
  587.                     offset += packet.Ethernet.IpV4.Length - packet.Ethernet.IpV4.HeaderLength;
  588.                 if (offset == lastOffset)
  589.                     return true;
  590.                 else
  591.                     return false;
  592.             }
  593.         }
  594.         private Dictionary<DictKey, DictValue> ElementList = new Dictionary<DictKey, DictValue>();
  595.         private DictKey dictKey;
  596.         private DictValue dictValue;
  597.         private IList<Packet> fragments;
  598.  
  599.         public IList<Packet> Add(Packet packet)
  600.         {
  601.             dictKey = new DictKey(packet.Ethernet.IpV4.Source, packet.Ethernet.IpV4.Identification);
  602.             if (ElementList.TryGetValue(dictKey, out dictValue))
  603.             {
  604.                 if (dictValue.AddPacket(packet))
  605.                 {
  606.                     fragments = dictValue.fragments;
  607.                     ElementList.Remove(dictKey);
  608.                     return fragments;
  609.                 }
  610.                 else
  611.                 {
  612.                     fragments = null;
  613.                     return fragments;
  614.                 }
  615.             }
  616.             else
  617.             {
  618.                 dictValue = new DictValue();
  619.                 dictValue.AddPacket(packet);
  620.                 ElementList.Add(dictKey, dictValue);
  621.                 fragments = null;
  622.                 return fragments;
  623.             }
  624.         }
  625.     }
  626.     static class IpFunctions
  627.     {
  628.         //Calculate ICMP checksum (same as IP, TCP, UDP, etc) - rfc1071
  629.         public static ushort ComputeIpChecksum(byte[] data)
  630.         {
  631.             long sum = 0;
  632.             int count = 0;
  633.             int remaining = data.Length;
  634.  
  635.             while (remaining > 1)
  636.             {
  637.                 sum += (long)((ushort)(data[count] << 8) | data[count + 1]);
  638.                 count += 2;
  639.                 remaining -= 2;
  640.             }
  641.  
  642.             if (remaining > 0)
  643.                 sum += (long)(data[count] << 8);
  644.  
  645.             while (sum >> 16 != 0)
  646.                 sum = (sum & 0xffff) + (sum >> 16);
  647.  
  648.             sum = ~sum;
  649.             return (ushort)sum;
  650.         }
  651.     }
  652. }
Advertisement
Add Comment
Please, Sign In to add comment