Пример #1
0
        private unsafe void OnMessageReceived(int receivedLength)
        {
            if (receivedLength < (IPHeader.MinimumIPHeaderSize + TCPHeader.MinimumTCPHeaderSize))
                return;

            fixed(byte *pBuffer = m_buffer)
            {
                var ipHeader = IPHeader.ParseIPHeader(pBuffer);

                if (ipHeader.Protocol != IPProtocol.TCP)
                {
                    return;
                }

                if (m_filterAddress)
                {
                    if (ipHeader.DestinationAddress != m_address ||
                        ipHeader.SourceAddress != m_address)
                    {
                        return;
                    }
                }

                var tcpHeader = TCPHeader.ParseTCPHeader(&pBuffer[ipHeader.Length]);

                if (tcpHeader.SourcePort == m_port || tcpHeader.DestinationPort == m_port)
                {
                    var offset = ipHeader.Length + tcpHeader.Length;

                    var length = receivedLength - offset;

                    ProcessReceivedMessage(ipHeader, tcpHeader, pBuffer, offset, length);
                }
            }
        }
 private PacketDirection GetDirection(IPHeader ipHeader, TCPHeader tcpHeader)
 {
     if (m_filterAddress)
     {
         if (ipHeader.DestinationAddress.Equals(m_address) && tcpHeader.DestinationPort == m_port)
         {
             return(PacketDirection.Outgoing);
         }
         else if (ipHeader.SourceAddress.Equals(m_address) && tcpHeader.SourcePort == m_port)
         {
             return(PacketDirection.Incoming);
         }
     }
     else
     {
         if (tcpHeader.DestinationPort == m_port)
         {
             return(PacketDirection.Outgoing);
         }
         else if (tcpHeader.SourcePort == m_port)
         {
             return(PacketDirection.Incoming);
         }
     }
     return(PacketDirection.Unknown);
 }
 public W2PacketEventArgs(PacketHeader packetHeader, PacketDirection direction, IPHeader ipHeader,
                          TCPHeader tcpHeader, byte[] buffer)
 {
     PacketHeader = packetHeader;
     Direction    = direction;
     IPHeader     = ipHeader;
     TCPHeader    = tcpHeader;
     Buffer       = buffer;
 }
Пример #4
0
        /// <summary>
        /// Parses a buffer containing the TCP Header data.
        /// </summary>
        /// <param name="buffer">The unsafe pointer to the first element of the buffer.</param>
        /// <returns>A new TCPHeader object.</returns>
        public static unsafe TCPHeader ParseTCPHeader(byte *buffer)
        {
            var tcpHeader = new TCPHeader();

            tcpHeader.SourcePort           = (ushort)IPAddress.NetworkToHostOrder(*(short *)&buffer[0]);
            tcpHeader.DestinationPort      = (ushort)IPAddress.NetworkToHostOrder(*(short *)&buffer[2]);
            tcpHeader.SequenceNumber       = (uint)IPAddress.NetworkToHostOrder(*(int *)&buffer[4]);
            tcpHeader.AcknowledgmentNumber = (uint)IPAddress.NetworkToHostOrder(*(int *)&buffer[8]);
            var dataOffsetAndFlags = (ushort)IPAddress.NetworkToHostOrder(*(short *)&buffer[12]);

            tcpHeader.Window        = (ushort)IPAddress.NetworkToHostOrder(*(short *)&buffer[14]);
            tcpHeader.Checksum      = (ushort)IPAddress.NetworkToHostOrder(*(short *)&buffer[16]);
            tcpHeader.UrgentPointer = (ushort)IPAddress.NetworkToHostOrder(*(short *)&buffer[18]);

            tcpHeader.Length = ((dataOffsetAndFlags >> 12) * 4);

            var flags = dataOffsetAndFlags & 0x3F;

            if ((flags & 0x01) != 0)
            {
                tcpHeader.Flags |= TCPFlags.FIN;
            }
            if ((flags & 0x02) != 0)
            {
                tcpHeader.Flags |= TCPFlags.SYN;
            }
            if ((flags & 0x04) != 0)
            {
                tcpHeader.Flags |= TCPFlags.RST;
            }
            if ((flags & 0x08) != 0)
            {
                tcpHeader.Flags |= TCPFlags.PSH;
            }
            if ((flags & 0x10) != 0)
            {
                tcpHeader.Flags |= TCPFlags.ACK;
            }
            if ((flags & 0x20) != 0)
            {
                tcpHeader.Flags |= TCPFlags.URG;
            }

            return(tcpHeader);
        }
Пример #5
0
 protected abstract unsafe void ProcessReceivedMessage(
     IPHeader ipHeader, TCPHeader tcpHeader, byte *data, int dataOffset, int dataLength);
        protected unsafe override void ProcessReceivedMessage(
            IPHeader ipHeader, TCPHeader tcpHeader, byte *data, int dataOffset, int dataLength)
        {
            // OK, get the packet direction.
            var direction = GetDirection(ipHeader, tcpHeader);

            // OK, get the right address according to the direction.
            var address = GetAddress(direction, ipHeader);

            // Start the fight!
            if (dataLength <= 0)
            {
                return;
            }
            else if (dataLength == 4) // Hand-shake packet.
            {
                var helloPacket = *(uint *)&data[dataOffset];
                if (helloPacket == 0x1F11F311)
                {
                    return;
                }
            }
            else if (dataLength < PacketHeaderSize) // Not a valid 12-byte header.
            {
                return;
            }
            else // Data >= sizeof(PacketHeader)
            {
                if (m_isFragmenting) // Is a fragment
                {
                    // If the received length is less than the first fragment length
                    // and the total fragments can carry at least 1 full header specified message
                    if (dataLength < m_firstFragmentSize &&
                        (m_totalFragmentsSize + dataLength) >= m_fragmentHeaderSize)
                    { // Add the last fragment to the list
                        AddFragment(address, ipHeader.Id, dataOffset, dataLength);
                        // Consolidate the message into a single buffer.
                        var msgBuffer = ConsolidateFragments(address);

                        if (msgBuffer == null)
                        {
                            return;
                        }

                        var remaining     = msgBuffer.Length;
                        var currentOffset = 0;

                        fixed(byte *pMsgBuffer = msgBuffer)
                        {   // We need a do-while loop, because we may get two messages
                            // glued together by tcp-fragmentation.
                            do
                            {
                                var pSize = *(ushort *)&pMsgBuffer[currentOffset];

                                W2PacketSecurity.Decrypt(pMsgBuffer, pSize, currentOffset);

                                var pHeader = PacketHeader.Parse(&pMsgBuffer[currentOffset]);

                                remaining -= pSize;

                                // Creates a new buffer, with only the current packet.
                                // This ensures that we will not use the same underlyng buffer
                                // because this buffer will be stored by the forms...
                                byte[] packetBuffer = new byte[pSize];

                                W2MarshalHelper.BufferCopy(msgBuffer, currentOffset, packetBuffer, 0, pSize);

                                PacketReceived.Raise(this, new W2PacketEventArgs(pHeader, direction, ipHeader,
                                                                                 tcpHeader, packetBuffer));

                                currentOffset += pSize;
                            } while (remaining >= PacketHeaderSize);
                        }

                        m_isFragmenting      = false;
                        m_fragmentHeaderSize = 0;
                        m_totalFragmentsSize = 0;
                        m_fragmentedBuffers[address].Clear();
                        return;
                    }
                    else
                    {
                        AddFragment(address, ipHeader.Id, dataOffset, dataLength);
                        return;
                    }
                }

                if (dataLength == 120)
                {
                    var helloPacket = *(uint *)&data[dataOffset];
                    if (helloPacket == 0x1F11F311)
                    {
                        dataOffset += 4;
                    }
                }

                // Gets the first ushort, which is supposed to carry the size of the packet.
                var headerSize = *(ushort *)&data[dataOffset];
                // Not a valid packet size.
                if (headerSize < PacketHeaderSize || headerSize > MaxPacketSize)
                {
                    return;
                }

                if (headerSize > dataLength) // The packet will be fragmented.
                {
                    AddFragment(address, ipHeader.Id, dataOffset, dataLength);
                    m_isFragmenting      = true;
                    m_firstFragmentSize  = dataLength;
                    m_fragmentHeaderSize = headerSize;
                    return;
                }
                else // No Fragmentation...
                {
                    var remaining     = dataLength;
                    var currentOffset = dataOffset;

                    do
                    {
                        var pSize = *(ushort *)&data[currentOffset];

                        W2PacketSecurity.Decrypt(data, pSize, currentOffset);

                        var pHeader = PacketHeader.Parse(&data[currentOffset]);

                        remaining -= pSize;

                        // Creates a temp. buffer for the handler.
                        byte[] packetBuffer = new byte[pSize];

                        W2MarshalHelper.BufferCopy(m_buffer, currentOffset, packetBuffer, 0, pSize);

                        PacketReceived.Raise(this, new W2PacketEventArgs(pHeader, direction, ipHeader, tcpHeader,
                                                                         packetBuffer));

                        currentOffset += pSize;
                    } while (remaining >= PacketHeaderSize);
                }
            }
        }