Esempio n. 1
0
 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;
     }
 }
Esempio n. 2
0
            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());
                    }
                }
            }
Esempio n. 3
0
            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));
                    }
                }
            }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
 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);
 }
Esempio n. 6
0
        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));
        }
Esempio n. 7
0
            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);
            }
Esempio n. 8
0
        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);
            }
        }