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)); }
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); }
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)); }