public Telnet(string ConfigString, string FriendlyName) : base(ConfigString, FriendlyName) { // L2Telnet:IP=192.168.1.1, Port=23, Adapter=SOCKET_1, ConfigFile=Config\\TEST_NET.network if (VirtualNetwork.Instance == null) { string NetworkConfigFile = Config["ConfigFile"]; VirtualNetwork.Load(NetworkConfigFile); VirtualNetwork.Instance.Start(); } else { if (!VirtualNetwork.Instance.IsRunning) { VirtualNetwork.Instance.Start(); } } Adapter = VirtualNetwork.Instance.GetAdapterByName(Config["Adapter"]); Adapter.BoardcastLocalAddress(); this._service = Adapter.TcpService; this._adapter = Adapter; this._local_port = this._service.GetAvailableLocalPort(); this._remote_ip = new IpV4Address(Config["IP"]); this._remote_port = ushort.Parse(Config["Port"]); if (Config.ContainsKey("MAC") && !string.IsNullOrEmpty(Config["MAC"])) { this._remote_mac = new MacAddress(Config["MAC"]); } if (Config.ContainsKey("RESPONSE_TELNET_CTRL") && !string.IsNullOrEmpty(Config["RESPONSE_TELNET_CTRL"])) { this._response_telnet_ctrl = bool.Parse(Config["RESPONSE_TELNET_CTRL"]); } if (Config.ContainsKey("SEND_GRATUITUS") && !string.IsNullOrEmpty(Config["SEND_GRATUITUS"])) { this._send_gratuitus_when_no_response = bool.Parse(Config["SEND_GRATUITUS"]); } _current_state = TCP_STATE.CLOSED; this._service.AddSession(this); }
override public void Close() { if (IsOpen) { VirtualNetwork.Instance.PostTraceMessage("TCP CLOSE: " + _remote_ip.ToString() + " " + _remote_port.ToString()); _connection_wait_handle.Reset(); SendTcpCtrlPacket(_last_acknowledgment_number, TcpControlBits.Fin | TcpControlBits.Acknowledgment); _current_state = TCP_STATE.FIN_WAIT_1; _connection_wait_handle.WaitOne(DISCONNECT_TIMEOUT, true); // wait for connection process finish if (_current_state == TCP_STATE.CLOSED) { VirtualNetwork.Instance.PostTraceMessage("TCP CLOSE: " + _remote_ip.ToString() + " " + _remote_port.ToString() + " - SUCCESSFUL"); } else { VirtualNetwork.Instance.PostTraceMessage("TCP CLOSE: " + _remote_ip.ToString() + " " + _remote_port.ToString() + " - FAILED"); } } }
private void TcpOpen() { VirtualNetwork.Instance.PostTraceMessage("TCP OPEN: " + _remote_ip.ToString() + " " + _remote_port.ToString()); InputBuffer = new Queue <byte>(); _connection_wait_handle.Reset(); TcpOptions tcpOptions = new TcpOptions( new TcpOptionMaximumSegmentSize(MAX_SEGMENT_SIZE), new TcpOptionWindowScale(WINDOW_SCALE) ); SendTcpCtrlPacket(0, TcpControlBits.Synchronize, tcpOptions); // ACK = false, SYNC = true, FIN = false _current_state = TCP_STATE.SYN_SENT; _connection_wait_handle.WaitOne(TCP_OPEN_TIMEOUT, true); // wait for connection process finish if (_current_state == TCP_STATE.ESTABLISHED) { VirtualNetwork.Instance.PostTraceMessage("TCP OPEN: " + _remote_ip.ToString() + " " + _remote_port.ToString() + " - SUCCESSFUL"); } else { VirtualNetwork.Instance.PostTraceMessage("TCP OPEN: " + _remote_ip.ToString() + " " + _remote_port.ToString() + " - FAILED"); } }
public void ProcessTCP(IpV4Datagram packet) { IpV4Datagram ip = packet; TcpDatagram tcp = packet.Tcp; if (ip.Source.Equals(_remote_ip) && tcp.SourcePort.Equals(_remote_port) && ip.Destination.Equals(_adapter.IP) && tcp.DestinationPort.Equals(_local_port)) { bool SYN = tcp.IsSynchronize; bool ACK = tcp.IsAcknowledgment; bool FIN = tcp.IsFin; bool PSH = tcp.IsPush; bool RST = tcp.IsReset; _remote_tcp_window_size = tcp.Window; if (_current_state == TCP_STATE.CLOSED) { SendTcpCtrlPacket(tcp.SequenceNumber + 1, TcpControlBits.Reset | TcpControlBits.Acknowledgment); } else if (_current_state == TCP_STATE.SYN_SENT && SYN && ACK) // 远程主机响应连接请求 { SendTcpCtrlPacket(tcp.SequenceNumber + 1, TcpControlBits.Acknowledgment); _current_state = TCP_STATE.ESTABLISHED; _connection_wait_handle.Set(); _service.TriggerSessionStateChange(this); } else if (FIN) // 连接被将要断开 { if (_current_state == TCP_STATE.ESTABLISHED) { _current_state = TCP_STATE.CLOSE_WAIT; } else if (_current_state == TCP_STATE.FIN_WAIT_1) { _current_state = ACK ? TCP_STATE.TIME_WAIT : TCP_STATE.CLOSING; } else if (_current_state == TCP_STATE.FIN_WAIT_2) { _current_state = TCP_STATE.TIME_WAIT; } SendTcpCtrlPacket(tcp.SequenceNumber + 1, TcpControlBits.Acknowledgment); } else if (_current_state == TCP_STATE.FIN_WAIT_1 && ACK) { _current_state = TCP_STATE.FIN_WAIT_2; } else if (_current_state == TCP_STATE.CLOSING && ACK) { _current_state = TCP_STATE.TIME_WAIT; } else if (_current_state == TCP_STATE.LAST_ACK && ACK) { // SendTcpCtrlPacket(_last_acknowledgment_number, TcpControlBits.Reset); _current_state = TCP_STATE.CLOSED; } else if (_current_state == TCP_STATE.ESTABLISHED && RST) // 连接被重置 { _current_state = TCP_STATE.CLOSED; } else if (PSH || ((ACK) && tcp.PayloadLength > 0)) // 需处理传输数据 { if (ACK && tcp.SequenceNumber == _last_acknowledgment_number - 1) // Keep Alive { SendTcpCtrlPacket(_last_acknowledgment_number, TcpControlBits.Acknowledgment); } else if (ACK && tcp.AcknowledgmentNumber >= _next_ack_num) { _current_sequence_number = _next_ack_num; lock (_ack_status_lock) { _ack_status = true; } } // 只处理顺序正确的数据包 if (tcp.SequenceNumber == _last_acknowledgment_number) { try { MemoryStream PayloadStream = tcp.Payload.ToMemoryStream(); lock (InputBufferLocker) { for (int i = 0; i < PayloadStream.Length; i++) { InputBuffer.Enqueue((byte)PayloadStream.ReadByte()); } } SendTcpCtrlPacket(tcp.SequenceNumber + (uint)tcp.PayloadLength, TcpControlBits.Acknowledgment); } catch {} } else { // 对于顺序不正确的包,告诉远端下一个包的顺序应该是多少 SendTcpCtrlPacket(_last_acknowledgment_number, TcpControlBits.Acknowledgment); } } else if (ACK && _current_state == TCP_STATE.ESTABLISHED) { if (tcp.SequenceNumber == _last_acknowledgment_number - 1) // Keep Alive { SendTcpCtrlPacket(_last_acknowledgment_number, TcpControlBits.Acknowledgment); } else if (tcp.AcknowledgmentNumber >= _next_ack_num) { _current_sequence_number = _next_ack_num; lock (_ack_status_lock) { _ack_status = true; } } } if (_current_state == TCP_STATE.CLOSE_WAIT) { SendTcpCtrlPacket(_last_acknowledgment_number, TcpControlBits.Fin | TcpControlBits.Acknowledgment); _current_state = TCP_STATE.LAST_ACK; } if (_current_state == TCP_STATE.TIME_WAIT) { Thread.Sleep(500); // SendTcpCtrlPacket(_last_acknowledgment_number, TcpControlBits.Reset); _current_state = TCP_STATE.CLOSED; _connection_wait_handle.Set(); } if (_current_state == TCP_STATE.CLOSED) { _service.TriggerSessionStateChange(this); } } }