Пример #1
0
        /// <summary>
        /// FIN wait1 handler
        /// </summary>
        /// <param name="con"></param>
        /// <param name="buffer"></param>
        private unsafe static void finWaitOneHandler(TCPConnection con, byte *buffer)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            /**
             * ACK received?
             */
            if ((header->Flags & (FLAG_ACK)) > 0)
            {
                con.State = TCPConnectionState.FIN_WAIT2;

                con.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);
            }
            else if ((header->Flags & (FLAG_FIN)) > 0)
            {
                con.SequenceNumber = Byte.ReverseBytes(Byte.ReverseBytes(con.SequenceNumber) + 1);

                con.State = TCPConnectionState.CLOSING;

                con.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);

                SendPacket(con.IP, con.SequenceNumber, con.AcknowledgeNumber, con.InPort, con.DestPort, FLAG_FIN, null, 0);
            }
            else
            {
                // Failed?
            }
        }
Пример #2
0
        /// <summary>
        /// Finish header and create checksum
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="header"></param>
        /// <param name="sourceIp"></param>
        /// <param name="packetLength"></param>
        /// <param name="dataLength"></param>
        /// <returns></returns>
        private static unsafe bool FinishHeader(NetPacketDesc *packet, TCPHeader *header, byte[] sourceIp, int packetLength, int dataLength)
        {
            // Welp!
            if (packetLength % 4 != 0)
            {
                return(false);
            }

            header->Length = (byte)((packetLength / 4) << 4);

            ushort size = (ushort)packetLength;

            size += (ushort)sizeof(TCPChecksum);

            // Let's introduce some junk (i love that :))
            TCPChecksum *checksumHeader = (TCPChecksum *)(packet->buffer + packet->start - sizeof(TCPChecksum));

            Memory.Memcpy(checksumHeader->SrcIP, Network.Settings->IP, 4);
            Memory.Memcpy(checksumHeader->DstIP, Util.ObjectToVoidPtr(sourceIp), 4);

            checksumHeader->Protocol = PROTOCOL_TCP;
            checksumHeader->Reserved = 0;
            checksumHeader->Length   = Byte.ReverseBytes((ushort)((ushort)packetLength + dataLength));

            byte *ptr = packet->buffer + packet->start - sizeof(TCPChecksum);

            header->Checksum = NetworkTools.Checksum(ptr, size + dataLength);

            return(true);
        }
Пример #3
0
        /// <summary>
        /// Reset connection
        /// </summary>
        /// <param name="con"></param>
        private unsafe static void Reset(TCPConnection con, byte *buffer)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            con.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);

            SendPacket(con.IP, con.SequenceNumber, con.AcknowledgeNumber, con.InPort, con.DestPort, FLAG_RST | FLAG_ACK, null, 0);

            con.State = TCPConnectionState.CLOSED;
        }
Пример #4
0
        /// <summary>
        /// TCP packet handler
        /// </summary>
        /// <param name="xid">Identification ID</param>
        /// <param name="buffer">Buffer pointer</param>
        /// <param name="size">Packet size</param>
        private static unsafe void handler(byte[] sourceIp, byte *buffer, uint size)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            ushort dest = Byte.ReverseBytes(header->DestPort);

            if (m_connections[dest] != null)
            {
                handleConnection(m_connections[dest], sourceIp, buffer, size);
            }
        }
Пример #5
0
        /// <summary>
        /// Add header to packet
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="srcPort"></param>
        /// <param name="dstPort"></param>
        /// <param name="flags"></param>
        /// <param name="seqNum"></param>
        /// <param name="ackNum"></param>
        /// <param name="winSize"></param>
        /// <returns></returns>
        private static unsafe TCPHeader *addHeader(NetPacketDesc *packet, ushort srcPort, ushort dstPort, byte flags, uint seqNum, uint ackNum, ushort winSize)
        {
            packet->start -= (short)sizeof(TCPHeader);

            // Generate stub header
            TCPHeader *header = (TCPHeader *)(packet->buffer + packet->start);

            header->SourcePort  = Byte.ReverseBytes(srcPort);
            header->DestPort    = Byte.ReverseBytes(dstPort);
            header->Flags       = flags;
            header->Urgent      = 0;
            header->WindowSize  = Byte.ReverseBytes(winSize);
            header->Acknowledge = ackNum;
            header->Sequence    = seqNum;
            header->Checksum    = 0;

            return(header);
        }
Пример #6
0
        /// <summary>
        /// Established handler
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="sourceIP"></param>
        /// <param name="buffer"></param>
        /// <param name="size"></param>
        private static unsafe void LastAckHandler(TCPConnection connection, byte[] sourceIP, byte *buffer, uint size)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            /**
             *
             * Possible flags:
             *   - PUSH
             *   - FIN
             */

            if ((header->Flags & FLAG_ACK) > 0)
            {
                connection.State = TCPConnectionState.TIME_WAIT;
            }
            else
            {
            }
        }
Пример #7
0
        /// <summary>
        /// CLOSING handler
        /// </summary>
        /// <param name="con"></param>
        /// <param name="buffer"></param>
        private unsafe static void closingHandler(TCPConnection con, byte *buffer)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            if ((header->Flags & (FLAG_ACK)) > 0)
            {
                con.SequenceNumber = Byte.ReverseBytes(Byte.ReverseBytes(con.SequenceNumber) + 1);


                con.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);

                // AND We're DONE!
                setConnectionForWait(con);
            }
            else
            {
                // Error handling?
            }
        }
Пример #8
0
        /// <summary>
        /// FIN wait2 handler
        /// </summary>
        /// <param name="con"></param>
        /// <param name="buffer"></param>
        private unsafe static void finWaitTwoHandler(TCPConnection con, byte *buffer)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            if ((header->Flags & (FLAG_FIN)) > 0)
            {
                con.SequenceNumber = Byte.ReverseBytes(Byte.ReverseBytes(con.SequenceNumber) + 1);


                con.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);

                SendPacket(con.IP, con.SequenceNumber, con.AcknowledgeNumber, con.InPort, con.DestPort, FLAG_ACK, null, 0);

                setConnectionForWait(con);
            }
            else
            {
            }
        }
Пример #9
0
        /// <summary>
        /// Syn sent handler
        /// </summary>
        /// <param name="con"></param>
        /// <param name="buffer"></param>
        private unsafe static void SynSentHandler(TCPConnection con, byte *buffer)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            if ((header->Flags & (FLAG_SYN | FLAG_ACK)) == (FLAG_SYN | FLAG_ACK))
            {
                con.SequenceNumber = Byte.ReverseBytes(Byte.ReverseBytes(con.SequenceNumber) + 1);

                con.State = TCPConnectionState.ESTABLISHED;

                con.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);

                SendPacket(con.IP, con.SequenceNumber, Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1), con.InPort, con.DestPort, FLAG_ACK, null, 0);
            }
            else
            {
                // Failed?
            }
        }
Пример #10
0
        /// <summary>
        /// Syn received
        /// </summary>
        /// <param name="con"></param>
        /// <param name="buffer"></param>
        private unsafe static void SynReceivedHandler(TCPConnection con, byte *buffer)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            /**
             * ACK received?
             */
            if ((header->Flags & (FLAG_ACK)) > 0)
            {
                con.SequenceNumber = Byte.ReverseBytes(Byte.ReverseBytes(con.SequenceNumber) + 1);

                con.State = TCPConnectionState.ESTABLISHED;


                /**
                 * Do we need to notify we have a new connection?
                 */
                if (con.Type == TCPConnectionType.CHILD_CONNECTION)
                {
                    /**
                     * Put ACCEPT in queue
                     */
                    TCPPacketDescriptor *buf = (TCPPacketDescriptor *)Heap.Alloc(sizeof(TCPPacketDescriptor));
                    buf->Size = 4;
                    buf->Type = TCPPacketDescriptorTypes.ACCEPT;
                    buf->Data = (byte *)Heap.Alloc(4);
                    buf->xid  = con.XID;

                    for (int i = 0; i < 4; i++)
                    {
                        buf->Data[i] = con.IP[i];
                    }

                    con.BaseConnection.ReceiveQueue.Push(buf);
                }
            }
            else
            {
                // Failed?
            }
        }
Пример #11
0
        /// <summary>
        /// Send packet to TCP
        /// </summary>
        /// <param name="destIP"></param>
        /// <param name="seqNum"></param>
        /// <param name="acknumb"></param>
        /// <param name="srcPort"></param>
        /// <param name="destPort"></param>
        /// <param name="flags"></param>
        /// <param name="data"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        private static unsafe bool SendPacket(byte[] destIP, uint seqNum, uint acknumb, ushort srcPort, ushort destPort, byte flags, byte *data, int count)
        {
            NetPacketDesc *packet = NetPacket.Alloc();


            if (count > 0)
            {
                Memory.Memcpy(packet->buffer + packet->start, data, count);

                packet->end += (short)count;
            }

            TCPHeader *outHeader = addHeader(packet, srcPort, destPort, flags, seqNum, acknumb, 8192);

            FinishHeader(packet, outHeader, destIP, sizeof(TCPHeader), count);

            IPV4.Send(packet, destIP, PROTOCOL_TCP);

            NetPacket.Free(packet);

            return(true);
        }
Пример #12
0
        /// <summary>
        /// Established handler
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="sourceIP"></param>
        /// <param name="buffer"></param>
        /// <param name="size"></param>
        private static unsafe void EstablishedHandler(TCPConnection connection, byte[] sourceIP, byte *buffer, uint size)
        {
            TCPHeader *header = (TCPHeader *)buffer;

            /**
             *
             * Possible flags:
             *   - PUSH
             *   - FIN
             */

            if ((header->Flags & (FLAG_FIN | FLAG_ACK)) == (FLAG_FIN | FLAG_ACK))
            {
                connection.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);

                SendPacket(connection.IP, connection.SequenceNumber, Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1), connection.InPort, connection.DestPort, FLAG_ACK, null, 0);

                setConnectionForWait(connection);
            }
            else if ((header->Flags & FLAG_FIN) > 0)
            {
                /**
                 * Todo: We need acknowledge our application here with status CLOSE_WAIT, for now we shift over to the LAST_ACK state
                 */
                connection.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);

                connection.State = TCPConnectionState.LAST_ACK;
                SendPacket(connection.IP, connection.SequenceNumber, Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1), connection.InPort, connection.DestPort, FLAG_ACK, null, 0);

                Sleep(300);

                SendPacket(connection.IP, connection.SequenceNumber, 0x00, connection.InPort, connection.DestPort, FLAG_FIN, null, 0);
            }
            if ((header->Flags & FLAG_PSH) > 0)
            {
                int sizePacket = (int)size - sizeof(TCPHeader);

                /**
                 * Push packet in Queue
                 */
                TCPPacketDescriptor *buf = (TCPPacketDescriptor *)Heap.Alloc(sizeof(TCPPacketDescriptor));
                buf->Size = sizePacket;
                buf->Type = TCPPacketDescriptorTypes.RECEIVE;
                buf->Data = (byte *)Heap.Alloc(sizePacket);
                buf->xid  = connection.XID;
                Memory.Memcpy(buf->Data, buffer + sizeof(TCPHeader), sizePacket);

                Queue queue = connection.ReceiveQueue;

                /**
                 * Is this a connection or a member?
                 */
                if (connection.Type != TCPConnectionType.CONNECTION)
                {
                    queue = connection.BaseConnection.ReceiveQueue;
                }

                queue.Push(buf);


                connection.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + (uint)sizePacket);

                SendPacket(connection.IP, connection.SequenceNumber, connection.AcknowledgeNumber, connection.InPort, connection.DestPort, FLAG_ACK, null, 0);
            }
            else
            {
            }
        }
Пример #13
0
        /// <summary>
        /// Listen state handler
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="sourceIP"></param>
        /// <param name="buffer"></param>
        /// <param name="size"></param>
        private static unsafe void HandleListen(TCPConnection connection, byte[] sourceIP, byte *buffer, uint size)
        {
            TCPHeader *header = (TCPHeader *)buffer;


            ushort srcPort = header->SourcePort;

            long id = GenerateID(sourceIP, srcPort);

            TCPConnection clientConnection = (TCPConnection)connection.Clients.GetByKey(id);

            /**
             * Do we need to create a connection or just pass it though?
             */
            if (clientConnection == null)
            {
                /**
                 * We only handle SYN packets here!
                 */
                if ((header->Flags & FLAG_SYN) == 0)
                {
                    //Close(connection);
                    return;
                }

                /**
                 * Add connection to clients list
                 */
                clientConnection = new TCPConnection();

                clientConnection.XID            = id;
                clientConnection.InPort         = connection.InPort;
                clientConnection.DestPort       = Byte.ReverseBytes(header->SourcePort);
                clientConnection.SequenceNumber = (uint)Random.Rand();

                clientConnection.State = TCPConnectionState.SYN_RECEIVED;
                clientConnection.IP    = new byte[4];
                for (int i = 0; i < 4; i++)
                {
                    clientConnection.IP[i] = sourceIP[i];
                }
                clientConnection.AcknowledgeNumber = Byte.ReverseBytes(header->Acknowledge);
                clientConnection.Type           = TCPConnectionType.CHILD_CONNECTION;
                clientConnection.Clients        = connection.Clients;
                clientConnection.BaseConnection = connection;

                connection.Clients.Add(id, clientConnection);

                /**
                 * Send SYN_ACK and transition to SYN_RECEIVED state
                 */
                clientConnection.SequenceNumber = Byte.ReverseBytes(Byte.ReverseBytes(connection.SequenceNumber) + 1);

                clientConnection.State = TCPConnectionState.SYN_RECEIVED;

                clientConnection.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1);

                SendPacket(clientConnection.IP, clientConnection.SequenceNumber, Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1), clientConnection.InPort, clientConnection.DestPort, FLAG_SYN | FLAG_ACK, null, 0);
            }
            else
            {
                handleConnection(clientConnection, sourceIP, buffer, size);
            }
        }