// Seen from inside private NATEntry CreateTranslationEntry(IPAddress ipaSource, IPAddress ipaDestination, int iSourcePort, int iDestinationPort, IP.IPProtocol iIPProtocol) { int iTranslatedSourcePort = 0; NATEntry eNatEntry; lock (lExternalRange) { foreach (IPAddress ipa in lExternalAddressPool) { if (iIPProtocol == IP.IPProtocol.UDP || iIPProtocol == IP.IPProtocol.TCP) { iTranslatedSourcePort = iRangeStartPort; } do { if (GetReTranslationEntry(ipa, ipaDestination, iTranslatedSourcePort, iDestinationPort, iIPProtocol) == null) { eNatEntry = new NATEntry(iIPProtocol, ipaSource, ipa, ipaDestination, iSourcePort, iTranslatedSourcePort, iDestinationPort); eNatEntry.TTL = iNATTimer; lock (lNATDatabase) { lNATDatabase.Add(eNatEntry); } InvokeExternalAsync(NATEntryCreated, new NATEventArgs(eNatEntry)); return(eNatEntry); } iTranslatedSourcePort++; }while ((iIPProtocol == IP.IPProtocol.UDP || iIPProtocol == IP.IPProtocol.TCP) && iRangeStartPort < iRangeEndPort); } } throw new Exception("A NAT entry could not be created cause the pools are exhausted. (Source: " + ipaSource + "/" + iSourcePort + ", Destination: " + ipaDestination + "/" + iDestinationPort + ", Protocol: " + iIPProtocol.ToString()); }
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> /// Compares an object to this object /// </summary> /// <param name="obj">The object to compare to this object</param> /// <returns>A bool indicating whether this object equals the given object</returns> public override bool Equals(object obj) { if (obj is NATEntry) { NATEntry e = (NATEntry)obj; return(e.iDestinationPort == this.iDestinationPort && e.iOriginalSourcePort == this.iOriginalSourcePort && e.ipaDestination == this.ipaDestination && e.ipaOriginalSource == this.ipaOriginalSource && e.ipaTranslatedSource == this.ipaTranslatedSource && e.ipProtocol == this.ipProtocol && e.iTranslatedSourcePort == this.iTranslatedSourcePort); } else { return(false); } }
private void CheckForTCPFinish(TCP.TCPFrame tcpFrame, NATEntry neEntry) { if (tcpFrame.FinishFlagSet) //TCP finish flag checking { if (neEntry.IsTCPTeardown) { neEntry.IsTCPFinished = true; } else { neEntry.IsTCPTeardown = true; } } if (neEntry.IsTCPFinished && tcpFrame.AcknowledgementFlagSet) // Deactivate when finished { lock (lNATDatabase) { lNATDatabase.Remove(neEntry); InvokeExternalAsync(NATEntryRemoved, new NATEventArgs(neEntry)); } } }
/// <summary> /// Creates a new instance of this class /// </summary> /// <param name="neEntry">The entry to associate with this event</param> public NATEventArgs(NATEntry neEntry) { this.neEntry = neEntry; }