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); }
internal TCPPacket(TCPConnection connection, UInt32 seqNum, UInt32 ackNum, byte tcpFlags, UInt16 winSize, byte optionCount) : this(connection.LocalIP, connection.RemoteIP, connection.LocalPort, connection.RemotePort, seqNum, ackNum, tcpFlags, winSize, null, 0, (optionCount * 4)) { }
internal TCPPacket(TCPConnection connection, UInt32 seqNum, UInt32 ackNum, byte tcpFlags, UInt16 winSize) : this(connection.LocalIP, connection.RemoteIP, connection.LocalPort, connection.RemotePort, seqNum, ackNum, tcpFlags, winSize) { }
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(); } } }
internal TcpClient(TCPConnection connection) { this.connection = connection; this.connection.client = this; }