Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
0
        protected virtual bool PublicIcmpInput(IPFrame packet)
        {
            IcmpFrame frame = IcmpLayer.ParseFrame(packet, true); // NDIS5/6内核层已检查过所以无需要重复计算ICMP报文CHECKSUM

            if (frame == null)
            {
                return(false);
            }
            bool success = false;                                                 // 不知道这样的数据报文应该发向那个主机时广播到还允许NAT穿透ICMP报文的多个主机(但仅限对于ICMP/NAT)

            foreach (NATContext secondary in this.m_contextsIcmp.GetAllContext()) // 稳定可靠NAT不丢帧(但可能造成虚拟NAT层压力过载)
            {
                success |= this.PublicIcmpNATOutput(secondary, frame, packet);
            }
            return(success);
        }
Ejemplo n.º 3
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));
        }