示例#1
0
        /// <summary>
        /// Parses STUN message from raw data packet.
        /// </summary>
        /// <param name="data">Raw STUN message.</param>
        internal void Parse(byte[] data)
        {
            /* RFC 3489 11.1.
             *  All STUN messages consist of a 20 byte header:
             *
             *  0                   1                   2                   3
             *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |      STUN Message Type        |         Message Length        |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                          Transaction ID
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |
             | The message length is the count, in bytes, of the size of the
             | message, not including the 20 byte header.
             */

            if (data.Length < 20)
            {
                throw new ArgumentException("Invalid STUN message value !");
            }

            int offset = 0;

            //--- message header --------------------------------------------------

            // STUN Message Type
            int messageType = (data[offset++] << 8 | data[offset++]);

            if (messageType == (int)StunMessageType.BindingErrorResponse)
            {
                m_Type = StunMessageType.BindingErrorResponse;
            }
            else if (messageType == (int)StunMessageType.BindingRequest)
            {
                m_Type = StunMessageType.BindingRequest;
            }
            else if (messageType == (int)StunMessageType.BindingResponse)
            {
                m_Type = StunMessageType.BindingResponse;
            }
            else if (messageType == (int)StunMessageType.SharedSecretErrorResponse)
            {
                m_Type = StunMessageType.SharedSecretErrorResponse;
            }
            else if (messageType == (int)StunMessageType.SharedSecretRequest)
            {
                m_Type = StunMessageType.SharedSecretRequest;
            }
            else if (messageType == (int)StunMessageType.SharedSecretResponse)
            {
                m_Type = StunMessageType.SharedSecretResponse;
            }
            else
            {
                throw new ArgumentException("Invalid STUN message type value !");
            }

            // Message Length
            int messageLength = (data[offset++] << 8 | data[offset++]);

            // Transaction ID
            byte[] guid = new byte[16];
            Array.Copy(data, offset, guid, 0, 16);
            m_pTransactionID = new Guid(guid);
            offset          += 16;

            //--- Message attributes ---------------------------------------------
            while ((offset - 20) < messageLength)
            {
                ParseAttribute(data, ref offset);
            }
        }
示例#2
0
 static Boolean IsResponse(StunMessageType type)
 {
     return(((UInt16)type & 0x0100) != 0);
 }