private void TraceTcpNatContext(NATContext context, TcpFrame frame) { if (context == null || frame == null) { return; } NATContext.StateCode state = NATContext.StateCode.TCP_RST; // 跟踪TCP协议报文状态 if (0 != (frame.Flags & TcpFlags.TCP_SYN)) { state = NATContext.StateCode.TCP_SYN; } else if (0 != (frame.Flags & TcpFlags.TCP_FIN)) { state = NATContext.StateCode.TCP_FIN; } else if (0 != (frame.Flags & TcpFlags.TCP_RST)) { state = NATContext.StateCode.TCP_RST; } else if (0 != (frame.Flags & (TcpFlags.TCP_PSH | TcpFlags.TCP_ACK))) { state = NATContext.StateCode.TCP_RECVED; } if (context.State != NATContext.StateCode.TCP_FIN && context.State != NATContext.StateCode.TCP_RST) { context.Restart().State = state; } }
public virtual NATContext PrivateInput(IPAddress sources, IPAddress destination, ushort Identification) { if (sources == null || destination == null) { return(null); } this.DoEvents(); long sources_key = Ethernet.GetAddress(sources); lock (this.m_AddressToContext) { lock (this.m_syncobj) { this.m_AddressToContext.TryGetValue(sources_key, out NATContext context); if (context == null && 0 != Identification) { context = new NATContext() { LocalEP = new IPEndPoint(this.m_nat.m_ethernetAddress, 0), AgingTimePeriod = new Stopwatch(), Sources = new IPEndPoint(sources, Identification), Destination = new IPEndPoint(destination, 0), State = NATContext.StateCode.TCP_NIL, }; this.m_AddressToContext[sources_key] = context; } return(context?.Restart()); } } }
public virtual NATContext PrivateInput(IPEndPoint sources, IPEndPoint destination, bool creational, bool autorestat = true) { if (sources == null || destination == null) { return(null); } else { this.DoEvents(); } long keySourcesContext = EndPointToLongKey(sources); lock (this.m_AddressToContext) { lock (this.m_syncobj) { this.m_SourcesToContext.TryGetValue(keySourcesContext, out NATContext context); if (context == null) { if (!creational) { return(null); } if (this.m_AddressToContext.Count >= IPEndPoint.MaxPort) { return(null); } int port = NewBindPort(this.ProtocolType); if (port > IPEndPoint.MinPort && port <= IPEndPoint.MaxPort) { IPEndPoint localEP = new IPEndPoint(this.m_nat.m_ethernetAddress, port); if (localEP != null) { context = new NATContext() { Sources = sources, Destination = destination, LocalEP = localEP, AgingTimePeriod = new Stopwatch(), State = NATContext.StateCode.TCP_NIL, }; this.m_AddressToContext[localEP.Port] = context; this.m_SourcesToContext[keySourcesContext] = context; } } } if (!autorestat) { return(context); } return(RestartContextAgingTime(context)); } } }
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)); }
private NATContext RestartContextAgingTime(NATContext context) { if (context == null) { return(context); } if (this.ProtocolType != ProtocolType.Tcp) { return(context); } if (context.State == NATContext.StateCode.TCP_RECVED || context.State == NATContext.StateCode.TCP_SYN) { return(context.Restart()); } return(context); }
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)); }
public virtual int Release(IPAddress sources) { long sources_key = Ethernet.GetAddress(sources); if (sources == null) { return(0); } NATContext context = null; lock (this.m_AddressToContext) { lock (this.m_syncobj) { this.m_AddressToContext.TryRemove(sources_key, out context); if (context == null) { return(0); } } } context.Dispose(); return(1); }
public virtual bool PublicInput(IPFrame packet) { if (packet == null) { return(false); } switch (packet.ProtocolType) { case ProtocolType.Udp: { UdpFrame frame = UdpLayer.ParseFrame(packet, true); if (frame == null) { return(false); } NATContext context = this.m_contextsUdp.PublicInput(frame.Source, frame.Destination); if (context == null) { return(false); } var convertional = new UdpFrame(frame.Source, context.Sources, frame.Payload) { Ttl = frame.Ttl, }; IPFrame ip = CopyFrameHeaderParts(UdpLayer.ToIPFrame(convertional), packet); if (ip == null) { return(false); } return(this.OnPrivateOutput(ip)); } case ProtocolType.Tcp: { TcpFrame frame = TcpLayer.ParseFrame(packet, true); if (frame == null) { return(false); } NATContext context = this.m_contextsTcp.PublicInput(frame.Source, frame.Destination); if (context == null) { return(false); } else { TraceTcpNatContext(context, frame); } var convertional = new TcpFrame(frame.Source, context.Sources, frame.Payload) { Ttl = frame.Ttl, AcknowledgeNo = frame.AcknowledgeNo, Flags = frame.Flags, SequenceNo = frame.SequenceNo, WindowSize = frame.WindowSize, Options = frame.Options, UrgentPointer = frame.UrgentPointer, }; IPFrame ip = CopyFrameHeaderParts(TcpLayer.ToIPFrame(convertional), packet); if (ip == null) { return(false); } return(this.OnPrivateOutput(ip)); } case ProtocolType.Icmp: return(this.PublicIcmpInput(packet)); default: return(false); } }