public void Start() { Task.Run(() => { TCPFrame tcpFrame; while (receivedFrameQueue.TryTake(out tcpFrame, TimeSpan.FromSeconds(30))) { logger.Debug("{0} receive frame, SEQ: {1}, ACK: {2}", id, tcpFrame.SequenceNumber, tcpFrame.AcknowledgementNumber); TCPFrame responseTCPFrame; if (getNextFrame(tcpFrame, out responseTCPFrame)) { var responseIPFrame = new IPv4Frame(); responseIPFrame.SourceAddress = e.Address; responseIPFrame.DestinationAddress = s.Address; responseIPFrame.Protocol = IPProtocol.TCP; responseIPFrame.EncapsulatedFrame = responseTCPFrame; responseTCPFrame.Checksum = responseTCPFrame.CalculateChecksum(responseIPFrame.GetPseudoHeader()); logger.Debug("{0} send frame to {1}:{2} from {3}:{4}", id, responseIPFrame.DestinationAddress, responseTCPFrame.DestinationPort, responseIPFrame.SourceAddress, responseTCPFrame.SourcePort); tap.Write(responseIPFrame.FrameBytes, 0, responseIPFrame.Length); tap.Flush(); } } }); }
public void forwardFrame(IPFrame frame) { var id = RandomString(10); var udpFrame = (UDPFrame)frame.EncapsulatedFrame; var e = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("192.168.1.220"), udpFrame.DestinationPort); logger.Debug("{0} Source Port: {1}", id, udpFrame.SourcePort); logger.Debug("{0} Dest Port: {1}", id, udpFrame.DestinationPort); ProxySocket socket; var cacheKey = string.Format("{0}:{1}->{2}", udpFrame.SourcePort, udpFrame.DestinationPort, e.ToString()); if (!natTable.TryGetValue(cacheKey, out socket)) { socket = new ProxySocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.ProxyEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("192.168.1.150"), 1080); socket.ProxyType = ProxyTypes.Socks5; socket.Connect(e); Task.Run(() => { try { logger.Debug("{0} Create a new UDP Receive Task", id); var buffer = new byte[8192]; ProxySocket tmp; while (natTable.TryGetValue(cacheKey, out tmp)) { logger.Debug("start receive"); var bytesReceived = socket.Receive(buffer); logger.Debug("{0} Received packet", id); natTable.Add(cacheKey, socket); var receivedIPFrame = new IPv4Frame(); receivedIPFrame.SourceAddress = frame.DestinationAddress; receivedIPFrame.DestinationAddress = frame.SourceAddress; receivedIPFrame.Protocol = IPProtocol.UDP; var receivedUDPFrame = new UDPFrame(); receivedUDPFrame.SourcePort = udpFrame.DestinationPort; receivedUDPFrame.DestinationPort = udpFrame.SourcePort; logger.Debug("{0} RSource Port: {1}", id, receivedUDPFrame.SourcePort); logger.Debug("{0} RDest Port: {1}", id, receivedUDPFrame.DestinationPort); receivedUDPFrame.EncapsulatedFrame = new RawDataFrame(buffer, 0, bytesReceived); receivedIPFrame.EncapsulatedFrame = receivedUDPFrame; receivedUDPFrame.Checksum = receivedUDPFrame.CalculateChecksum(receivedIPFrame.GetPseudoHeader()); tap.Write(receivedIPFrame.FrameBytes, 0, receivedIPFrame.Length); tap.Flush(); logger.Debug("{0} wrote", id); } } catch (SocketException err) { logger.Error(err); } }); } natTable.Add(cacheKey, socket); socket.BeginSend(udpFrame.EncapsulatedFrame.FrameBytes, 0, udpFrame.EncapsulatedFrame.FrameBytes.Length, 0, ar => { socket.EndSend(ar); logger.Debug("{0} Sent to Dest", id); }, null); }
/// <summary> /// Returns the IP pseudo header for the given frame. /// </summary> /// <param name="fFrame">The frame to calculate the pseudo-header for.</param> /// <returns>The pseudo header of the given frame.</returns> public byte[] GetPseudoHeader(Frame fFrame) { IPFrame ipFrame; if (iIPVersion == 4) { ipFrame = new IPv4Frame(); } else if (iIPVersion == 6) { ipFrame = new IPv6Frame(); } else { throw new ArgumentException("Only IPv4 or IPv6 addresses are supportet on the moment."); } ipFrame.DestinationAddress = RemoteBinding; ipFrame.SourceAddress = LocalBinding; ipFrame.Protocol = ProtocolBinding; ipFrame.EncapsulatedFrame = fFrame; return(ipFrame.GetPseudoHeader()); }
private void GetRouter() { //Foreach WinPcapInterface of this host foreach (WinPcapInterface wpc in arWpc) { if (wpc.Description == "Microsoft") //Tim added: only use my real adapter { if (wpc.Addresses.Where(p => p.Address == new IPAddress(new byte[] { 0, 0, 0, 0 }).Address).Count() > 0) //Tim added: Only select interface that have at least one valid, non 0.0.0.0 ip address { //Create a new interface handler and start it EthernetInterface ipInterface = new EthernetInterface(wpc); ipInterface.Start(); //Then add it to the router and to our list wpcInterfaces.Add(ipInterface); rRouter.AddInterface(ipInterface); } } } //Create a TCP frame TCPFrame tcpFrame = new TCPFrame(); tcpFrame.DestinationPort = 80; tcpFrame.SourcePort = 12345; tcpFrame.AcknowledgementFlagSet = true; //Create an IP frame and put the TCP frame into it IPv4Frame ipFrame = new IPv4Frame(); ipFrame.DestinationAddress = IPAddress.Parse("192.168.0.1"); ipFrame.SourceAddress = IPAddress.Parse("192.168.1.254"); ipFrame.EncapsulatedFrame = tcpFrame; rRouter.Start(); //Tim added: //Send the frame rRouter.PushTraffic(tcpFrame); //Cleanup resources rRouter.Cleanup(); //Start the cleanup process for all interfaces foreach (EthernetInterface ipInterface in wpcInterfaces) { ipInterface.Cleanup(); } //Stop all handlers rRouter.Stop(); //Stop all interfaces foreach (EthernetInterface ipInterface in wpcInterfaces) { ipInterface.Stop(); } }
/// <summary> /// Encapsulates the given IP frame according to the binding of this socket and invokes the FrameEncapsulated event when finished. /// <remarks>This method also handles IP fragmentation</remarks> /// </summary> /// <param name="fFrame">The frame to process</param> /// <param name="bPush">A bool indicating whether the frame is delivered with a push flag</param> public override void PushDown(Frame fFrame, bool bPush) { if (iIPVersion == 4) { IPv4Frame ipv4Frame = new IPv4Frame(); ipv4Frame.DestinationAddress = RemoteBinding; ipv4Frame.SourceAddress = LocalBinding; ipv4Frame.Protocol = ProtocolBinding; ipv4Frame.Identification = (uint)rRandom.Next(Int32.MaxValue); ipv4Frame.EncapsulatedFrame = fFrame; foreach (IPFrame fFragment in IPFragmenter.FragmentV4(ipv4Frame, MaximumTransmissionUnit)) { InvokeFrameEncapsulated(fFragment, bPush); } } else if (iIPVersion == 6) { IPv6Frame ipv6Frame = new IPv6Frame(); ipv6Frame.DestinationAddress = RemoteBinding; ipv6Frame.SourceAddress = LocalBinding; ipv6Frame.Protocol = ProtocolBinding; ipv6Frame.EncapsulatedFrame = fFrame; foreach (IPFrame fFragment in IPFragmenter.FragmentV6(ipv6Frame, MaximumTransmissionUnit)) { InvokeFrameEncapsulated(fFragment, bPush); } } else { throw new ArgumentException("Only IPv4 and IPv6 addresses are supportet on the moment."); } }
/// <summary> /// Decapsulates the given IP frame if the binding of this socket matches the frame and invokes the FrameDecapsulated event when finished. /// <remarks>This mehtod also handles IP fragmentation</remarks> /// </summary> /// <param name="fFrame">The frame to process</param> /// <param name="bPush">A bool indicating whether the frame is delivered with a push flag</param> /// <returns>A bool indicating whether the given frame matched the binding of this socket</returns> public override bool PushUp(Frame fFrame, bool bPush) { if (!FrameTypes.IsIP(fFrame)) { fFrame = IPFrame.Create(fFrame.FrameBytes); } IPFrame ipFrame = (IPFrame)fFrame; if (!ipFrame.SourceAddress.Equals(RemoteBinding) || !ipFrame.DestinationAddress.Equals(LocalBinding)) { return(false); } if (ipFrame.FrameType == FrameTypes.IPv4) { IPv4Frame ipv4Frame = (IPv4Frame)ipFrame; if (ipv4Frame.Protocol != this.ProtocolBinding) { return(false); } if (ipv4Frame.EncapsulatedFrame != null) { if (ipv4Frame.PacketFlags.MoreFragments) { HandleFragment(bPush, ipv4Frame.PacketFlags.MoreFragments, ipv4Frame.Identification, ipv4Frame.FragmentOffset, ipv4Frame.EncapsulatedFrame.FrameBytes); } else { InvokeFrameDecapsulated(ipv4Frame.EncapsulatedFrame, bPush); } } return(true); } else if (ipFrame.FrameType == FrameTypes.IPv6) { ProtocolParser.ParseCompleteFrame(fFrame); Frame fPayload = null; Frame ipHeader = fFrame; while (ipHeader.EncapsulatedFrame != null && ipHeader.EncapsulatedFrame is IIPHeader) { if (((IIPHeader)ipHeader).Protocol == this.ProtocolBinding) { fPayload = ipHeader.EncapsulatedFrame; break; } } if (fPayload == null) { return(false); //Wrong payload type :( } FragmentExtensionHeader fragHeader = (FragmentExtensionHeader)ProtocolParser.GetFrameByType(fFrame, FragmentExtensionHeader.DefaultFrameType); if (fragHeader != null) { HandleFragment(bPush, fragHeader.MoreFragments, fragHeader.Identification, fragHeader.FragmentOffset, fPayload.FrameBytes); } else { InvokeFrameDecapsulated(fPayload, bPush); } } throw new ArgumentException("Only IPv4 and IPv6 frames are supported at the moment."); }