Пример #1
0
        /* NOTE: this function processes incoming frames and stores flags/data; the TcpStateMachine function processes stored flags, advances the state machine as necessary, and sends out responses */
        internal void OnPacketReceived(UInt32 sourceIPAddress, UInt32 destinationIPAddress, byte[] buffer, Int32 index, Int32 count)
        {
            if (_isDisposed)
            {
                return;
            }

            if (count < TCP_HEADER_MIN_LENGTH)
            {
                return;
            }

            UInt16 packetHeaderChecksum = (UInt16)((((UInt16)buffer[index + 16]) << 8) + buffer[index + 17]);

            // calculate checksum to verify packet integrity.
            UInt16 calculateChecksum;

            lock (_tcpPseudoHeaderBufferLockObject)
            {
                // create temporary pseudo header
                _tcpPseudoHeaderBuffer[0]  = (byte)((sourceIPAddress >> 24) & 0xFF);
                _tcpPseudoHeaderBuffer[1]  = (byte)((sourceIPAddress >> 16) & 0xFF);
                _tcpPseudoHeaderBuffer[2]  = (byte)((sourceIPAddress >> 8) & 0xFF);
                _tcpPseudoHeaderBuffer[3]  = (byte)(sourceIPAddress & 0xFF);
                _tcpPseudoHeaderBuffer[4]  = (byte)((destinationIPAddress >> 24) & 0xFF);
                _tcpPseudoHeaderBuffer[5]  = (byte)((destinationIPAddress >> 16) & 0xFF);
                _tcpPseudoHeaderBuffer[6]  = (byte)((destinationIPAddress >> 8) & 0xFF);
                _tcpPseudoHeaderBuffer[7]  = (byte)(destinationIPAddress & 0xFF);
                _tcpPseudoHeaderBuffer[8]  = 0;                                // ZERO
                _tcpPseudoHeaderBuffer[9]  = (byte)IPv4Layer.ProtocolType.Tcp; // Protocol Number
                _tcpPseudoHeaderBuffer[10] = (byte)((count >> 8) & 0xFF);
                _tcpPseudoHeaderBuffer[11] = (byte)(count & 0xFF);

                // calculate checksum over entire pseudo-header, TCP header and data
                _checksumBufferArray[0] = _tcpPseudoHeaderBuffer;
                _checksumOffsetArray[0] = 0;
                _checksumCountArray[0]  = TCP_PSEUDO_HEADER_LENGTH;
                _checksumBufferArray[1] = buffer;
                _checksumOffsetArray[1] = index;
                _checksumCountArray[1]  = count;
                calculateChecksum       = Utility.CalculateInternetChecksum(_checksumBufferArray, _checksumOffsetArray, _checksumCountArray, 2);
            }
            if (calculateChecksum != 0x0000)
            {
                return; // drop packet
            }
            // find the source and destination port #s for our packet (looking into the packet)
            UInt16 sourceIPPort      = (UInt16)((((UInt16)buffer[index + 0]) << 8) + buffer[index + 1]);
            UInt16 destinationIPPort = (UInt16)((((UInt16)buffer[index + 2]) << 8) + buffer[index + 3]);

            TcpSocket socket = null;

            for (int i = 0; i < IPv4Layer.MAX_SIMULTANEOUS_SOCKETS; i++)
            {
                if ((IPv4Layer._sockets[i] != null) &&
                    (IPv4Layer._sockets[i].ProtocolType == IPv4Layer.ProtocolType.Tcp) &&
                    (IPv4Layer._sockets[i].SourceIPAddress == destinationIPAddress) &&
                    (IPv4Layer._sockets[i].SourceIPPort == destinationIPPort) &&
                    (IPv4Layer._sockets[i].DestinationIPAddress == sourceIPAddress) &&
                    (IPv4Layer._sockets[i].DestinationIPPort == sourceIPPort))
                {
                    socket = (TcpSocket)IPv4Layer._sockets[i];
                    socket.OnPacketReceived(sourceIPAddress, destinationIPAddress, buffer, index, count);
                    break;
                }
            }

            /* TODO: if this packet is a request to connect to a listening port, pass it along now */
            if (socket == null)
            {
                for (int i = 0; i < IPv4Layer.MAX_SIMULTANEOUS_SOCKETS; i++)
                {
                    if ((IPv4Layer._sockets[i] != null) &&
                        (IPv4Layer._sockets[i].ProtocolType == IPv4Layer.ProtocolType.Tcp) &&
                        (IPv4Layer._sockets[i].SourceIPAddress == destinationIPAddress) &&
                        (IPv4Layer._sockets[i].SourceIPPort == destinationIPPort) &&
                        (((TcpSocket)IPv4Layer._sockets[i]).IsListening == true)
                        )
                    {
                        socket = (TcpSocket)IPv4Layer._sockets[i];
                        socket.OnPacketReceived(sourceIPAddress, destinationIPAddress, buffer, index, count);
                        break;
                    }
                }
            }

            /* if this packet is otherwise invalid, respond a TCP "RESET" packet */
            if (socket == null)
            {
                /* send a TCP "RESET" packet */
                UInt32 sequenceNumber =
                    ((UInt32)buffer[index + 4] << 24) +
                    ((UInt32)buffer[index + 5] << 16) +
                    ((UInt32)buffer[index + 6] << 8) +
                    (UInt32)buffer[index + 7];

                UInt32 acknowledgmentNumber =
                    ((UInt32)buffer[index + 8] << 24) +
                    ((UInt32)buffer[index + 9] << 16) +
                    ((UInt32)buffer[index + 10] << 8) +
                    (UInt32)buffer[index + 11];

                SendTcpSegment(destinationIPAddress, sourceIPAddress, destinationIPPort, sourceIPPort,
                               acknowledgmentNumber, sequenceNumber, 0, false, false, true, false, false, null, new byte[] { }, 0, 0, Int64.MaxValue);
            }
        }