/// <summary> /// Applies all known rules sequentially to the given frame, until a rule matches /// </summary> /// <param name="fInputFrame">The frame to analyze</param> protected override void HandleTraffic(Frame fInputFrame) { IP.IPFrame ipv4Frame = GetIPv4Frame(fInputFrame); UDP.UDPFrame udpFrame = GetUDPFrame(fInputFrame); TCP.TCPFrame tcpFrame = GetTCPFrame(fInputFrame); Ethernet.EthernetFrame ethFrame = GetEthernetFrame(fInputFrame); lock (tsrRules) { foreach (TrafficSplitterRule tsr in tsrRules) { if (tsr.IsMatch(fInputFrame, ethFrame, ipv4Frame, udpFrame, tcpFrame)) { if (tsr.Action == TrafficSplitterActions.SendToA) { NotifyA(fInputFrame); return; } else if (tsr.Action == TrafficSplitterActions.SendToB) { NotifyB(fInputFrame); return; } else if (tsr.Action == TrafficSplitterActions.Drop) { //Drop PushDroppedFrame(fInputFrame); return; } } } } NotifyA(fInputFrame); }
/// <summary> /// Handles RIPv1 updates /// </summary> /// <param name="udpFrame"></param> /// <param name="ipFrame"></param> /// <returns>Bool indicating if something changed</returns> private bool HandleRIPV1(UDP.UDPFrame udpFrame, IP.IPFrame ipFrame) { RIPFrame fRIPFrame; bool bChanged = false; if (ipFrame.SourceAddress.Equals(IPAddress.Broadcast)) // Check Addr { if (udpFrame.DestinationPort == iRIPPort) // Check Port { fRIPFrame = new RIPFrame(udpFrame.EncapsulatedFrame.FrameBytes); if (fRIPFrame.Version == 1) { foreach (RIPUpdate ru in fRIPFrame.GetUpdates()) { if (ru.AddressFamilyIdentifier == RIPEntryAddressFamily.IPv4) { bChanged |= UpdateEntry(ipFrame.SourceAddress, ru.Address, IPAddressAnalysis.GetClassfullSubnetMask(ru.Address), (int)ru.Metric); } } } } } return(bChanged); }
public override bool PushUp(Frame fFrame, bool bPush) { TCPFrame tcpFrame = (TCPFrame)ProtocolParser.GetFrameByType(fFrame, TCPFrame.DefaultFrameType); IP.IPFrame ipFrame = (IPFrame)ProtocolParser.GetFrameByType(fFrame, IPv4Frame.DefaultFrameType); if (ipFrame == null) { ipFrame = (IPFrame)ProtocolParser.GetFrameByType(fFrame, IPv6Frame.DefaultFrameType); } if (ipFrame == null || tcpFrame == null) { return(false); } if (ipFrame.SourceAddress.Equals(ipSocket.RemoteBinding) && ipFrame.DestinationAddress.Equals(ipSocket.LocalBinding) && tcpFrame.SourcePort == tcpSocket.RemoteBinding && tcpFrame.DestinationPort == tcpSocket.LocalBinding) { return(ipSocket.PushUp(ipFrame, bPush)); } else { return(false); } }
/// <summary> /// Analyzes the input frame for new information. /// </summary> /// <param name="fInputFrame">The frame to analyze</param> protected override void HandleTraffic(Frame fInputFrame) { ARPFrame arpFrame = GetARPFrame(fInputFrame); Ethernet.EthernetFrame ethFrame = GetEthernetFrame(fInputFrame); IP.IPFrame ipFrame = GetIPv4Frame(fInputFrame); if (arpFrame != null) { if (arpFrame.Operation == ARPOperation.Request) { ProcessAdresses(arpFrame.SourceIP, arpFrame.SourceMAC); } if (arpFrame.Operation == ARPOperation.Reply) { ProcessAdresses(arpFrame.SourceIP, arpFrame.SourceMAC); } } if (ethFrame != null && ipFrame != null) { ProcessAdresses(ipFrame.SourceAddress, null); ProcessAdresses(ipFrame.DestinationAddress, null); } }
/// <summary> /// Checks the incoming traffic for RIP updates. /// </summary> /// <param name="fInputFrame">The frame to handle.</param> protected override void HandleTraffic(Frame fInputFrame) { IRouter rtRouterToManage = this.RouterToManage; TrafficDescriptionFrame tdf = (TrafficDescriptionFrame)GetFrameByType(fInputFrame, FrameTypes.TrafficDescriptionFrame); if (!bShutdownPending) { UDP.UDPFrame udpFrame = GetUDPFrame(fInputFrame); IP.IPFrame ipFrame = GetIPv4Frame(fInputFrame); if (udpFrame != null && ipFrame != null && rtRouterToManage != null && udpFrame.EncapsulatedFrame != null) { if (iVersion == 1) { if (HandleRIPV1(udpFrame, ipFrame)) { DistributeUpdate(tdf.SourceInterface); } } else if (iVersion == 2) { if (HandleRIPV2(udpFrame, ipFrame)) { DistributeUpdate(tdf.SourceInterface); } } } } }
private bool RoutingNeeded(Frame fInputFrame) { IP.IPFrame fIpFrame = GetIPFrame(fInputFrame); if (fIpFrame == null) { return(false); } else if (lLocalAdresses.Contains(fIpFrame.DestinationAddress)) { return(false); } return(true); }
/// <summary> /// Tries to extract a DHCP frame from this frame and forwards it to the HandleDHCPFrame method /// </summary> /// <param name="fInputFrame">The frame to handle</param> protected override void HandleTraffic(Frame fInputFrame) { if (bShuttingDown) { return; //Shutdown pending. } UDP.UDPFrame udpFrame = GetUDPFrame(fInputFrame); TrafficDescriptionFrame tdf = (TrafficDescriptionFrame)GetFrameByType(fInputFrame, FrameTypes.TrafficDescriptionFrame); IP.IPFrame ipFrame = GetIPFrame(fInputFrame); DHCP.DHCPFrame dhcpFrame = (DHCP.DHCPFrame)GetFrameByType(fInputFrame, FrameTypes.DHCP); if (dhcpFrame != null && ipFrame != null && udpFrame != null && tdf != null) { HandleDHCPFrame(dhcpFrame, udpFrame, ipFrame, tdf, fInputFrame); } }
/// <summary> /// Corrupts the frame /// </summary> /// <param name="f">The frame to corrupt</param> protected override void CaseHappening(Frame f) { if (iMaxErrorCount > 0) { IP.IPFrame fIPFrame = (IP.IPFrame)ProtocolParser.GetFrameByType(f, IP.IPv4Frame.DefaultFrameType); if (fIPFrame == null) { fIPFrame = (IP.IPFrame)ProtocolParser.GetFrameByType(f, IP.V6.IPv6Frame.DefaultFrameType); } if (fIPFrame != null) { fIPFrame.EncapsulatedFrame = new RawDataFrame(DoErrors(fIPFrame.EncapsulatedFrame.FrameBytes)); } } this.Next.Push(f); }
/// <summary> /// Checkes whether this rule matches a given frame. /// </summary> /// <param name="frame">The original frame</param> /// <param name="ethFrame">The Ethernet part of the frame</param> /// <param name="ipv4Frame">The IPv4 part of the frame</param> /// <param name="udpFrame">The UDP part of the frame</param> /// <param name="tcpFrame">The TCP part of the frame</param> /// <returns>A bool indicating whether this rule matches a given frame.</returns> public virtual bool IsMatch(Frame frame, Ethernet.EthernetFrame ethFrame, IP.IPFrame ipFrame, UDP.UDPFrame udpFrame, TCP.TCPFrame tcpFrame) { lock (lChildRules) { if (lChildRules.Count == 0) { return(true); //Nothing to validate } foreach (TrafficSplitterRule tsrRule in lChildRules) { if (tsrRule.IsMatch(frame, ethFrame, ipFrame, udpFrame, tcpFrame)) { return(true); } } } return(false); }
/// <summary> /// Handles RIPv2 Frames /// </summary> /// <param name="udpFrame"></param> /// <param name="ipFrame"></param> /// <returns>Bool indicating if something changed</returns> private bool HandleRIPV2(UDP.UDPFrame udpFrame, IP.IPFrame ipFrame) { RIPFrame fRIPFrame; bool bChanged = false; if (ipFrame.SourceAddress.Equals(IPAddress.Broadcast)) { HandleRIPV1(udpFrame, ipFrame); // RIPv1? Fallback! } else if (ipFrame.DestinationAddress.Equals(ipaRIPv2Address)) // Check Addr { if (udpFrame.DestinationPort == iRIPPort) //Check Port { fRIPFrame = new RIPFrame(udpFrame.EncapsulatedFrame.FrameBytes); if (fRIPFrame.Version == 2) { foreach (RIPUpdate ru in fRIPFrame.GetUpdates()) { if (ru.AddressFamilyIdentifier == RIPEntryAddressFamily.IPv4) { if (!IsHoldDown(ru.Address)) { bChanged |= UpdateEntry(ipFrame.SourceAddress, ru.Address, ru.Ripv2SubnetMask, (int)ru.Metric); } } } } else { bChanged |= HandleRIPV1(udpFrame, ipFrame); } } } return(bChanged); }
protected override Frame ModifyTraffic(Frame fInputFrame) { if (!bIsShuttingDown) { IP.IPFrame ipFrame = GetIPv4Frame(fInputFrame); TCP.TCPFrame tcpFrame = GetTCPFrame(fInputFrame); if (ipFrame == null || tcpFrame == null) { return(fInputFrame); } if (IsLocal(ipFrame)) { return(fInputFrame); } if (!ShouldIntercept(ipFrame.SourceAddress, ipFrame.DestinationAddress, tcpFrame.SourcePort, tcpFrame.DestinationPort)) { return(fInputFrame); } bool bFound = false; lock (lStacks) { foreach (TCPStreamModifierStack tcpStack in lStacks) { if (tcpStack.StackAlice.PushUp(fInputFrame, false) || tcpStack.StackBob.PushUp(fInputFrame, false)) { bFound = true; break; } } if (!bFound) { //We have to create a new stack... TCPIPStack sAlice; TCPIPStack sBob; NetworkStreamModifier[] arMods; sAlice = new TCPIPStack(ipFrame.DestinationAddress, ipFrame.SourceAddress, tcpFrame.DestinationPort, tcpFrame.SourcePort); sAlice.ProtocolParser = this.ProtocolParser; sBob = new TCPIPStack(ipFrame.SourceAddress, ipFrame.DestinationAddress, tcpFrame.SourcePort, tcpFrame.DestinationPort); sBob.ProtocolParser = this.ProtocolParser; sAlice.FrameEncapsulated += new FrameProcessedEventHandler(Stack_FrameEncapsulated); sBob.FrameEncapsulated += new FrameProcessedEventHandler(Stack_FrameEncapsulated); sAlice.TCPSocket.StateChange += new EventHandler <TCPSocketEventArgs>(TCPSocket_StateChange); sBob.TCPSocket.StateChange += new EventHandler <TCPSocketEventArgs>(TCPSocket_StateChange); arMods = CreateAndLinkStreamOperators(new SocketNetworkStream(sAlice), new SocketNetworkStream(sBob)); TCPStreamModifierStack tsmsStack = new TCPStreamModifierStack(sAlice, sBob, arMods); foreach (NetworkStreamModifier sModifier in tsmsStack.Modifiers) { sModifier.Start(); //sModifier.AliceLoopClosed += new EventHandler(sModifier_AliceLoopClosed); //sModifier.BobLoopClosed += new EventHandler(sModifier_BobLoopClosed); sModifier.AliceLoopError += new ExceptionEventHandler(sModifier_AliceLoopError); sModifier.BobLoopError += new ExceptionEventHandler(sModifier_BobLoopError); } tsmsStack.StackAlice.Listen(); tsmsStack.StackAlice.PushUp(fInputFrame, false); tsmsStack.StackBob.ConnectAsync(); lStacks.Add(tsmsStack); //Notify Created InvokeExternalAsync(StackCreated, new TCPStreamModifierEventArgs(tsmsStack)); } } return(null); } return(fInputFrame); }
/// <summary> /// Handles a DHCP frame and sends responses and requests or leases addresses according to its contents /// </summary> /// <param name="dhcFrame">The DHCP frame to handle</param> /// <param name="udpFrame">The UDP frame</param> /// <param name="ipv4Frame">The IPv4 frame</param> /// <param name="tdf">The traffic description frame</param> /// <param name="fInputFrame">The original input frame</param> protected override void HandleDHCPFrame(DHCPFrame dhcFrame, UDP.UDPFrame udpFrame, IP.IPFrame ipv4Frame, TrafficDescriptionFrame tdf, Frame fInputFrame) { base.HandleDHCPFrame(dhcFrame, udpFrame, ipv4Frame, tdf, fInputFrame); EthernetFrame ethFrame = GetEthernetFrame(fInputFrame); bool bIsOffer = false; bool bIsACK = false; foreach (DHCPTLVItem tlvItem in dhcFrame.GetDHCPTLVItems()) { if (tlvItem.DHCPOptionType == DHCPOptions.DHCPMessageType) { if (dhcFrame.MessageType == DHCPType.BootReply && (DHCPMessageType)tlvItem.Data[0] == DHCPMessageType.Offer && lOpenClientTransactions.Contains(dhcFrame.TransactionID)) { bIsOffer = true; break; } if (dhcFrame.MessageType == DHCPType.BootReply && (DHCPMessageType)tlvItem.Data[0] == DHCPMessageType.ACK && lOpenClientTransactions.Contains(dhcFrame.TransactionID)) { bIsACK = true; break; } } } if (bIsOffer) { #region Client Process offer IPAddress ipaServer = ipv4Frame.SourceAddress; IPAddress myAddress = dhcFrame.OfferedAddress; DHCPFrame newDHCPFrame = new DHCPFrame(); newDHCPFrame.ClientAddress = IPAddress.Any; newDHCPFrame.ClientMac = dhcFrame.ClientMac; newDHCPFrame.Hardwarelen = 6; newDHCPFrame.HardwareType = eExNetworkLibrary.HardwareAddressType.Ethernet; newDHCPFrame.Hops = 0; newDHCPFrame.MessageType = DHCPType.BootRequest; newDHCPFrame.OfferedAddress = IPAddress.Any; newDHCPFrame.RelayAddress = IPAddress.Any; newDHCPFrame.RequestedFile = ""; newDHCPFrame.RequestedServerName = ""; newDHCPFrame.Secs = dhcFrame.Secs + 1; newDHCPFrame.ServerAddress = IPAddress.Any; newDHCPFrame.ValidIPFlag = true; newDHCPFrame.TransactionID = dhcFrame.TransactionID; DHCPTLVItem tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.DHCPMessageType; tlvItem.Data = new byte[] { (byte)DHCPMessageType.Request }; newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.ClientID; byte[] bIDData = new byte[7]; bIDData[0] = (byte)HardwareAddressType.Ethernet; dhcFrame.ClientMac.AddressBytes.CopyTo(bIDData, 1); tlvItem.Data = bIDData; newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.AddressRequest; tlvItem.Data = myAddress.GetAddressBytes(); newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.Hostname; tlvItem.Data = Encoding.ASCII.GetBytes(strHostnameToSpoof + iIPIDCounter); newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.DHCPServerID; tlvItem.Data = ipaServer.GetAddressBytes(); newDHCPFrame.AddDHCPTLVItem(tlvItem); UDP.UDPFrame newUDPFrame = new eExNetworkLibrary.UDP.UDPFrame(); newUDPFrame.DestinationPort = iDHCPOutPort; newUDPFrame.SourcePort = iDHCPInPort; newUDPFrame.EncapsulatedFrame = newDHCPFrame; IP.IPv4Frame newIPv4Frame = new eExNetworkLibrary.IP.IPv4Frame(); newIPv4Frame.Version = 4; newIPv4Frame.DestinationAddress = IPAddress.Broadcast; newIPv4Frame.SourceAddress = IPAddress.Any; newIPv4Frame.Protocol = eExNetworkLibrary.IP.IPProtocol.UDP; newIPv4Frame.EncapsulatedFrame = newUDPFrame; newIPv4Frame.Identification = (uint)IncrementIPIDCounter(); newIPv4Frame.TimeToLive = 128; ethFrame = new eExNetworkLibrary.Ethernet.EthernetFrame(); ethFrame.Destination = new MACAddress(new byte[] { 255, 255, 255, 255, 255, 255 }); ethFrame.Source = dhcFrame.ClientMac; ethFrame.EtherType = eExNetworkLibrary.EtherType.IPv4; ethFrame.EncapsulatedFrame = newIPv4Frame; TrafficDescriptionFrame tdFrame = new TrafficDescriptionFrame(null, DateTime.Now); tdFrame.EncapsulatedFrame = ethFrame; if (tdf != null && tdf.SourceInterface != null) { tdf.SourceInterface.Send(tdFrame); } #endregion } else if (bIsACK) { #region Client Process ACK if (tdf != null && tdf.SourceInterface != null) { IPInterface ipiSource = tdf.SourceInterface; DHCPPool dhPool = GetPoolForInterface(ipiSource); DHCPPoolItem dpiItem = new DHCPPoolItem(); dpiItem.Address = dhcFrame.OfferedAddress; if (dhPool.GetItemForAddress(dpiItem.Address) == null) { if (bRedirectGateway) { if (ipaGateway == null) { dpiItem.Gateway = ipiSource.IpAddresses[0]; } else { dpiItem.Gateway = ipaGateway; } } else { IPAddress ipGateway = IPAddress.Any; foreach (DHCPTLVItem tlvItem in dhcFrame.GetDHCPTLVItems()) { if (tlvItem.DHCPOptionType == DHCPOptions.Router) { ipGateway = new IPAddress(tlvItem.Data); break; } } dpiItem.DNSServer = ipGateway; } if (bRedirectDNSServer) { if (ipaDNSServer == null) { dpiItem.DNSServer = ipiSource.IpAddresses[0]; } else { dpiItem.DNSServer = ipaDNSServer; } } else { IPAddress ipDNS = IPAddress.Any; foreach (DHCPTLVItem tlvItem in dhcFrame.GetDHCPTLVItems()) { if (tlvItem.DHCPOptionType == DHCPOptions.DomainNameServer) { ipDNS = new IPAddress(tlvItem.Data); break; } } dpiItem.DNSServer = ipDNS; } IPAddress ipServer = null; foreach (DHCPTLVItem tlvItem in dhcFrame.GetDHCPTLVItems()) { if (tlvItem.DHCPOptionType == DHCPOptions.DHCPServerID) { ipServer = new IPAddress(tlvItem.Data); break; } } dpiItem.DHCPServer = ipServer; dpiItem.Netmask = ipiSource.Subnetmasks[0]; dpiItem.DHCPServerMAC = ethFrame.Source; AddPoolItem(dpiItem, dhPool, ipiSource); dictPoolItemSpoofedMAC.Add(dpiItem, dhcFrame.ClientMac); if (dictIPSpoofedMACs.ContainsKey(dpiItem.Address)) { dictIPSpoofedMACs.Remove(dpiItem.Address); } dictIPSpoofedMACs.Add(dpiItem.Address, dhcFrame.ClientMac); lServers.Add(ipv4Frame.SourceAddress); InvokeAddressStolen(new DHCPServerEventArgs(dhPool, dpiItem, ipiSource)); } } lOpenClientTransactions.Remove(dhcFrame.TransactionID); #endregion } }
private void HandleFromInternal(Frame fInputFrame, int iSourcePort, int iDestinationPort, IP.IPFrame ipFrame, TCP.TCPFrame tcpFrame, UDP.UDPFrame udpFrame) { NATEntry neEntry = GetTranslationEntry(ipFrame.SourceAddress, ipFrame.DestinationAddress, iSourcePort, iDestinationPort, ipFrame.Protocol); if (neEntry == null) { neEntry = CreateTranslationEntry(ipFrame.SourceAddress, ipFrame.DestinationAddress, iSourcePort, iDestinationPort, ipFrame.Protocol); } ipFrame.SourceAddress = neEntry.TranslatedSourceAddress; if (tcpFrame != null) { tcpFrame.SourcePort = neEntry.TranslatedSourcePort; tcpFrame.Checksum = tcpFrame.CalculateChecksum(ipFrame.GetPseudoHeader()); CheckForTCPFinish(tcpFrame, neEntry); } else if (udpFrame != null) { udpFrame.SourcePort = neEntry.TranslatedSourcePort; udpFrame.Checksum = udpFrame.CalculateChecksum(ipFrame.GetPseudoHeader()); } NotifyNextExternal(ipFrame); }
private void HandleFromExternal(Frame fInputFrame, int iSourcePort, int iDestinationPort, IP.IPFrame ipFrame, TCP.TCPFrame tcpFrame, UDP.UDPFrame udpFrame) { NATEntry neEntry = GetReTranslationEntry(ipFrame.DestinationAddress, ipFrame.SourceAddress, iDestinationPort, iSourcePort, ipFrame.Protocol); if (neEntry != null) { ipFrame.DestinationAddress = neEntry.OriginalSourceAddress; if (tcpFrame != null) { tcpFrame.DestinationPort = neEntry.OriginalSourcePort; tcpFrame.Checksum = tcpFrame.CalculateChecksum(ipFrame.GetPseudoHeader()); CheckForTCPFinish(tcpFrame, neEntry); } else if (udpFrame != null) { udpFrame.DestinationPort = neEntry.OriginalSourcePort; udpFrame.Checksum = udpFrame.CalculateChecksum(ipFrame.GetPseudoHeader()); } NotifyNextInternal(ipFrame); } else { PushDroppedFrame(fInputFrame); if (bThrowOnNonNATFrame) { throw new Exception("The external frame was discarded because there was no corresponding translation entry in the database. (Source: " + ipFrame.SourceAddress + "/" + iSourcePort + ", Destination: " + ipFrame.DestinationAddress + "/" + iDestinationPort + ", Protocol: " + ipFrame.Protocol.ToString()); } } }
/// <summary> /// Extracts a IP frame and does some NAT /// </summary> /// <param name="fInputFrame">The frame to handle</param> protected override void HandleTraffic(Frame fInputFrame) { int iSourcePort = 0; int iDestinationPort = 0; if (fInputFrame.FrameType != NATDescriptionFrame.DefaultFrameType) { throw new Exception("A frame without a NATDescription was received by the NAT handler. This must not happen and indicates a serious internal error."); } NATDescriptionFrame ndDescription = (NATDescriptionFrame)fInputFrame; fInputFrame = ndDescription.EncapsulatedFrame; IP.IPFrame ipFrame = GetIPv4Frame(fInputFrame); TCP.TCPFrame tcpFrame = GetTCPFrame(fInputFrame); UDP.UDPFrame udpFrame = null; if (tcpFrame != null) { iSourcePort = tcpFrame.SourcePort; iDestinationPort = tcpFrame.DestinationPort; } else { udpFrame = GetUDPFrame(fInputFrame); if (udpFrame != null) { iSourcePort = udpFrame.SourcePort; iDestinationPort = udpFrame.DestinationPort; } } if (ipFrame != null) { if (ndDescription.Source == NATDescriptionFrame.NATFrameSource.Internal) { //In to out if (IsInternalRange(ipFrame.SourceAddress)) { HandleFromInternal(fInputFrame, iSourcePort, iDestinationPort, ipFrame, tcpFrame, udpFrame); } else { NotifyNextExternal(fInputFrame); } } else if (ndDescription.Source == NATDescriptionFrame.NATFrameSource.External) { //Out to in if (IsExternalRange(ipFrame.DestinationAddress)) { HandleFromExternal(fInputFrame, iSourcePort, iDestinationPort, ipFrame, tcpFrame, udpFrame); } else { NotifyNextInternal(fInputFrame); } } } }
protected override void HandleTraffic(Frame fInputFrame) { if (!bIsShuttingDown) { IP.IPFrame ipFrame = GetIPFrame(fInputFrame); TCP.TCPFrame tcpFrame = GetTCPFrame(fInputFrame); if (ipFrame == null || tcpFrame == null) { return; } if (!ShouldIntercept(ipFrame.SourceAddress, ipFrame.DestinationAddress, tcpFrame.SourcePort, tcpFrame.DestinationPort)) { return; } bool bFound = false; lock (lStacks) { foreach (TCPStreamMonitorStack tcpStack in lStacks) { if (tcpStack.StackAlice.PushUp(fInputFrame, false) || tcpStack.StackBob.PushUp(fInputFrame, false)) { bFound = true; break; } } if (!bFound) { //We have to create a new stack... TCPIPListenerStack sAlice; TCPIPListenerStack sBob; NetworkStreamMonitor[] arMonitors; sBob = new TCPIPListenerStack(ipFrame.DestinationAddress, ipFrame.SourceAddress, tcpFrame.DestinationPort, tcpFrame.SourcePort); sBob.ProtocolParser = this.ProtocolParser; sAlice = new TCPIPListenerStack(ipFrame.SourceAddress, ipFrame.DestinationAddress, tcpFrame.SourcePort, tcpFrame.DestinationPort); sAlice.ProtocolParser = this.ProtocolParser; sAlice.TCPSocket.StateChange += new EventHandler <TCPListenerSocketEventArgs>(TCPSocket_StateChange); sBob.TCPSocket.StateChange += new EventHandler <TCPListenerSocketEventArgs>(TCPSocket_StateChange); arMonitors = CreateAndLinkStreamMonitors(new SocketNetworkStream(sAlice), new SocketNetworkStream(sBob)); TCPStreamMonitorStack tsmsStack = new TCPStreamMonitorStack(sAlice, sBob, arMonitors); foreach (NetworkStreamMonitor nsMonitor in tsmsStack.Monitors) { nsMonitor.Start(); nsMonitor.LoopError += new ExceptionEventHandler(nsMonitor_LoopError); nsMonitor.LoopClosed += new EventHandler(nsMonitor_LoopClosed); } tsmsStack.StackBob.Listen(); tsmsStack.StackBob.PushUp(ipFrame, false); tsmsStack.StackAlice.Connect(); lStacks.Add(tsmsStack); //Notify Created InvokeExternal(StackCreated, new TCPStreamMonitorEventArgs(tsmsStack)); } } } }