public TcpClient(IPv4Address dest, UInt16 port) { IPv4Address source = TCPIPStack.FindNetwork(dest); if( source == null ) { throw new ArgumentException("Destination host unreachable", "dest"); } this.connection = new TCPConnection(dest, port, source, NextLocalPort++, 0x5656, TCPConnection.State.SYN_SENT); this.connection.client = this; TCPIPStack.tcpSockets.Add(connection); TCPPacket packet = new TCPPacket(connection, connection.LocalSequenceNumber, 0, 0x02, 8192); TCPIP.IPv4OutgoingBuffer.AddPacket(packet); }
/// <summary> /// Send a raw byte buffer to the remote host /// </summary> /// <param name="data">Byte buffer with data to send</param> public void SendData(byte[] data) { if (data.Length < mss) { TCPPacket packet = new TCPPacket(connection.LocalIP, connection.RemoteIP, connection.LocalPort, connection.RemotePort, connection.LocalSequenceNumber, connection.RemoteSequenceNumber, 0x18, 8192, data); TCPIP.IPv4OutgoingBuffer.AddPacket(packet); connection.LocalSequenceNumber += (uint)data.Length; return; } int remaining_bytes = data.Length; int data_idx = 0; byte[] new_buffer; byte tcp_flags = 0x10; while (remaining_bytes > 0) { if (remaining_bytes > mss) { new_buffer = new byte[mss]; } else { new_buffer = new byte[remaining_bytes]; tcp_flags = 0x18; } for (int b = 0; b < new_buffer.Length; b++) { new_buffer[b] = data[data_idx]; data_idx++; remaining_bytes--; } TCPPacket packet = new TCPPacket(connection.LocalIP, connection.RemoteIP, connection.LocalPort, connection.RemotePort, connection.LocalSequenceNumber, connection.RemoteSequenceNumber, tcp_flags, 8192, new_buffer); TCPIP.IPv4OutgoingBuffer.AddPacket(packet); connection.LocalSequenceNumber += (uint)new_buffer.Length; } }
private static void IPv4_TCPHandler(byte[] packetData) { TCP.TCPPacket tcp_packet = new TCP.TCPPacket(packetData); if (tcp_packet.Syn == true) { if (tcpListeners.ContainsKey(tcp_packet.DestinationPort) == true) { TCP.TCPConnection connection = new TCP.TCPConnection(tcp_packet.SourceIP, tcp_packet.SourcePort, tcp_packet.DestinationIP, tcp_packet.DestinationPort, tcp_packet.SequenceNumber, TCP.TCPConnection.State.SYN_RECVD); tcpSockets.Add(connection); TCP.TCPPacket syn_ack = new TCP.TCPPacket(connection, connection.LocalSequenceNumber, ++connection.RemoteSequenceNumber, 0x12, 8192, 2); syn_ack.AddMSSOption(1360); syn_ack.AddSACKOption(); TCPIP.IPv4OutgoingBuffer.AddPacket(syn_ack); return; } } TCP.TCPConnection active_connection = null; for (int c = 0; c < tcpSockets.Count; c++) { if ((tcpSockets[c].RemoteIP.CompareTo(tcp_packet.SourceIP) == 0) && (tcpSockets[c].RemotePort == tcp_packet.SourcePort) && (tcpSockets[c].LocalPort == tcp_packet.DestinationPort)) { active_connection = tcpSockets[c]; break; } } if (active_connection == null) { TCP.TCPPacket reset_packet = new TCP.TCPPacket(tcp_packet.DestinationIP, tcp_packet.SourceIP, tcp_packet.DestinationPort, tcp_packet.SourcePort, 0, (tcp_packet.SequenceNumber + 1), 0x14, 8192); TCPIP.IPv4OutgoingBuffer.AddPacket(reset_packet); return; } if (active_connection.ConnectionState == TCP.TCPConnection.State.SYN_RECVD) { if ((tcp_packet.Ack == true) && ((active_connection.LocalSequenceNumber + 1) == tcp_packet.AckNumber)) { active_connection.LocalSequenceNumber++; active_connection.ConnectionState = TCP.TCPConnection.State.ESTABLISHED; ClientConnected connectCallback = tcpListeners[tcp_packet.DestinationPort]; connectCallback(new TcpClient(active_connection)); } } else if (active_connection.ConnectionState == TCP.TCPConnection.State.SYN_SENT) { if ((tcp_packet.Syn == true) && (tcp_packet.Ack == true) && ((active_connection.LocalSequenceNumber + 1) == tcp_packet.AckNumber)) { active_connection.LocalSequenceNumber++; active_connection.RemoteSequenceNumber = tcp_packet.SequenceNumber + 1; active_connection.ConnectionState = TCP.TCPConnection.State.ESTABLISHED; TCP.TCPPacket ack = new TCP.TCPPacket(active_connection, active_connection.LocalSequenceNumber, active_connection.RemoteSequenceNumber, 0x10, 8192); TCPIP.IPv4OutgoingBuffer.AddPacket(ack); } } else if (active_connection.ConnectionState == TCP.TCPConnection.State.ESTABLISHED) { if (tcp_packet.Ack == true) { //active_connection.LocalSequenceNumber = tcp_packet.AckNumber; } if (tcp_packet.TCP_DataLength > 0) { active_connection.RemoteSequenceNumber += tcp_packet.TCP_DataLength; TCP.TCPPacket ack = new TCP.TCPPacket(active_connection, active_connection.LocalSequenceNumber, active_connection.RemoteSequenceNumber, 0x10, 8192); TCPIP.IPv4OutgoingBuffer.AddPacket(ack); active_connection.client.dataReceived(tcp_packet.TCP_Data); } if (tcp_packet.Fin == true) { active_connection.client.disconnect(); } } }
/// <summary> /// Close down an active connection /// </summary> public void Close() { TCPPacket packet = new TCPPacket(connection, connection.LocalSequenceNumber, connection.RemoteSequenceNumber + 1, 0x11, 8192); TCPIP.IPv4OutgoingBuffer.AddPacket(packet); connection.ConnectionState = TCPConnection.State.TIMEWAIT; }
private static void IPv4_TCPHandler(byte[] packetData) { TCP.TCPPacket tcp_packet = new TCP.TCPPacket(packetData); if (tcp_packet.Syn == true) { if (tcpListeners.ContainsKey(tcp_packet.DestinationPort) == true) { TCP.TCPConnection connection = new TCP.TCPConnection(tcp_packet.SourceIP, tcp_packet.SourcePort, tcp_packet.DestinationIP, tcp_packet.DestinationPort, tcp_packet.SequenceNumber, TCP.TCPConnection.State.SYN_RECVD); tcpSockets.Add(connection); TCP.TCPPacket syn_ack = new TCP.TCPPacket(connection, connection.LocalSequenceNumber, ++connection.RemoteSequenceNumber, 0x12, 8192, 2); syn_ack.AddMSSOption(1360); syn_ack.AddSACKOption(); TCPIP.IPv4OutgoingBuffer.AddPacket(syn_ack); return; } } TCP.TCPConnection active_connection = null; for (int c = 0; c < tcpSockets.Count; c++) { if ((tcpSockets[c].RemoteIP.CompareTo(tcp_packet.SourceIP) == 0) && (tcpSockets[c].RemotePort == tcp_packet.SourcePort) && (tcpSockets[c].LocalPort == tcp_packet.DestinationPort)) { active_connection = tcpSockets[c]; break; } } if (active_connection == null) { TCP.TCPPacket reset_packet = new TCP.TCPPacket(tcp_packet.DestinationIP, tcp_packet.SourceIP, tcp_packet.DestinationPort, tcp_packet.SourcePort, 0, (tcp_packet.SequenceNumber + 1), 0x14, 8192); TCPIP.IPv4OutgoingBuffer.AddPacket(reset_packet); return; } if (active_connection.ConnectionState == TCP.TCPConnection.State.SYN_RECVD) { if ((tcp_packet.Ack == true) && ((active_connection.LocalSequenceNumber + 1) == tcp_packet.AckNumber)) { active_connection.LocalSequenceNumber++; active_connection.ConnectionState = TCP.TCPConnection.State.ESTABLISHED; ClientConnected connectCallback = tcpListeners[tcp_packet.DestinationPort]; connectCallback(new TcpClient(active_connection)); } } else if (active_connection.ConnectionState == TCP.TCPConnection.State.SYN_SENT) { if ((tcp_packet.Syn == true) && (tcp_packet.Ack == true) && ((active_connection.LocalSequenceNumber + 1) == tcp_packet.AckNumber)) { active_connection.LocalSequenceNumber++; active_connection.RemoteSequenceNumber = tcp_packet.SequenceNumber + 1; active_connection.ConnectionState = TCP.TCPConnection.State.ESTABLISHED; TCP.TCPPacket ack = new TCP.TCPPacket(active_connection, active_connection.LocalSequenceNumber, active_connection.RemoteSequenceNumber, 0x10, 8192); TCPIP.IPv4OutgoingBuffer.AddPacket(ack); } } else if (active_connection.ConnectionState == TCP.TCPConnection.State.ESTABLISHED) { if (tcp_packet.Ack == true) { //active_connection.LocalSequenceNumber = tcp_packet.AckNumber; } if (tcp_packet.TCP_DataLength > 0) { active_connection.RemoteSequenceNumber += tcp_packet.TCP_DataLength; TCP.TCPPacket ack = new TCP.TCPPacket(active_connection, active_connection.LocalSequenceNumber, active_connection.RemoteSequenceNumber, 0x10, 8192); TCPIP.IPv4OutgoingBuffer.AddPacket(ack); active_connection.client.dataReceived(tcp_packet.TCP_Data); } if (tcp_packet.Fin == true) { active_connection.client.disconnect(); } } }