public void ParseCoturnSTUNResponseTestMethod() { Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); byte[] stunResp = new byte[]{ 0x01, 0x01, 0x00, 0x44, 0x21, 0x12, 0xa4, 0x42, 0x6b, 0x4c, 0xf3, 0x18, 0xd0, 0xa7, 0xf5, 0x40, 0x97, 0x30, 0x3a, 0x27, 0x00, 0x20, 0x00, 0x08, 0x00, 0x01, 0x9e, 0x90, 0x1a, 0xb5, 0x08, 0xf3, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0xbf, 0x82, 0x3b, 0xa7, 0xac, 0xb1, 0x80, 0x2b, 0x00, 0x08, 0x00, 0x01, 0x0d, 0x96, 0x67, 0x1d, 0x42, 0xf3, 0x80, 0x22, 0x00, 0x1a, 0x43, 0x6f, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x34, 0x2e, 0x35, 0x2e, 0x30, 0x2e, 0x33, 0x20, 0x27, 0x64, 0x61, 0x6e, 0x20, 0x45, 0x69, 0x64, 0x65, 0x72, 0x27, 0x77, 0x75}; STUNv2Message stunMessage = STUNv2Message.ParseSTUNMessage(stunResp, stunResp.Length); STUNv2Header stunHeader = stunMessage.Header; Console.WriteLine("Request type = " + stunHeader.MessageType + "."); Console.WriteLine("Length = " + stunHeader.MessageLength + "."); Console.WriteLine("Transaction ID = " + BitConverter.ToString(stunHeader.TransactionId) + "."); foreach (STUNv2Attribute attribute in stunMessage.Attributes) { if (attribute.AttributeType == STUNv2AttributeTypesEnum.MappedAddress) { STUNv2AddressAttribute addressAttribute = new STUNv2AddressAttribute(attribute.Value); Console.WriteLine(" " + attribute.AttributeType + " " + addressAttribute.Address + ":" + addressAttribute.Port + "."); Assert.AreEqual("59.167.172.177", addressAttribute.Address.ToString()); Assert.AreEqual(49026, addressAttribute.Port); } else if (attribute.AttributeType == STUNv2AttributeTypesEnum.XORMappedAddress) { STUNv2XORAddressAttribute xorAddressAttribute = new STUNv2XORAddressAttribute(STUNv2AttributeTypesEnum.XORMappedAddress, attribute.Value); Console.WriteLine(" " + attribute.AttributeType + " " + xorAddressAttribute.Address + ":" + xorAddressAttribute.Port + "."); Assert.AreEqual("59.167.172.177", xorAddressAttribute.Address.ToString()); Assert.AreEqual(49026, xorAddressAttribute.Port); } else { Console.WriteLine(" " + attribute.AttributeType + " " + attribute.Value + "."); } } Assert.AreEqual(STUNv2MessageTypesEnum.BindingSuccessResponse, stunHeader.MessageType); }
//public void AddMessageIntegrityAttribute(string key) //{ // //MD5 md5 = new MD5CryptoServiceProvider(); // //byte[] hmacKey = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); // //HMACSHA1 hmacSHA = new HMACSHA1(hmacKey, true); // //byte[] hmac = hmacSHA.ComputeHash(ToByteBuffer()); // //if (BitConverter.IsLittleEndian) // //{ // // Array.Reverse(hmac); // //} // Attributes.Add(new STUNv2Attribute(STUNv2AttributeTypesEnum.MessageIntegrity, new byte[MESSAGE_INTEGRITY_ATTRIBUTE_HMAC_LENGTH])); //} //public void AddFingerPrintAttribute() //{ // //byte[] messageBytes = ToByteBuffer(); // //uint crc = Crc32.Compute(messageBytes) ^ FINGERPRINT_XOR; // //byte[] fingerPrint = (BitConverter.IsLittleEndian) ? BitConverter.GetBytes(NetConvert.DoReverseEndian(crc)) : BitConverter.GetBytes(crc); // Attributes.Add(new STUNv2Attribute(STUNv2AttributeTypesEnum.FingerPrint, new byte[FINGERPRINT_ATTRIBUTE_CRC32_LENGTH])); //} public void AddXORMappedAddressAttribute(IPAddress remoteAddress, int remotePort) { STUNv2XORAddressAttribute xorAddressAttribute = new STUNv2XORAddressAttribute(STUNv2AttributeTypesEnum.XORMappedAddress, remotePort, remoteAddress); Attributes.Add(xorAddressAttribute); }
//public void AddMessageIntegrityAttribute(string key) //{ // //MD5 md5 = new MD5CryptoServiceProvider(); // //byte[] hmacKey = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); // //HMACSHA1 hmacSHA = new HMACSHA1(hmacKey, true); // //byte[] hmac = hmacSHA.ComputeHash(ToByteBuffer()); // //if (BitConverter.IsLittleEndian) // //{ // // Array.Reverse(hmac); // //} // Attributes.Add(new STUNv2Attribute(STUNv2AttributeTypesEnum.MessageIntegrity, new byte[MESSAGE_INTEGRITY_ATTRIBUTE_HMAC_LENGTH])); //} //public void AddFingerPrintAttribute() //{ // //byte[] messageBytes = ToByteBuffer(); // //uint crc = Crc32.Compute(messageBytes) ^ FINGERPRINT_XOR; // //byte[] fingerPrint = (BitConverter.IsLittleEndian) ? BitConverter.GetBytes(NetConvert.DoReverseEndian(crc)) : BitConverter.GetBytes(crc); // Attributes.Add(new STUNv2Attribute(STUNv2AttributeTypesEnum.FingerPrint, new byte[FINGERPRINT_ATTRIBUTE_CRC32_LENGTH])); //} public void AddXORMappedAddressAttribute(IPAddress remoteAddress, int remotePort) { STUNv2XORAddressAttribute xorAddressAttribute = new STUNv2XORAddressAttribute(remotePort, remoteAddress); Attributes.Add(xorAddressAttribute); }
public static List <STUNv2Attribute> ParseMessageAttributes(byte[] buffer, int startIndex, int endIndex) { if (buffer != null && buffer.Length > startIndex && buffer.Length >= endIndex) { List <STUNv2Attribute> attributes = new List <STUNv2Attribute>(); int startAttIndex = startIndex; while (startAttIndex < endIndex) { UInt16 stunAttributeType = BitConverter.ToUInt16(buffer, startAttIndex); UInt16 stunAttributeLength = BitConverter.ToUInt16(buffer, startAttIndex + 2); byte[] stunAttributeValue = null; if (BitConverter.IsLittleEndian) { stunAttributeType = Utility.ReverseEndian(stunAttributeType); stunAttributeLength = Utility.ReverseEndian(stunAttributeLength); } if (stunAttributeLength > 0) { if (stunAttributeLength + startIndex + 4 > endIndex) { logger.LogWarning("The attribute length on a STUN parameter was greater than the available number of bytes."); } else { stunAttributeValue = new byte[stunAttributeLength]; Buffer.BlockCopy(buffer, startAttIndex + 4, stunAttributeValue, 0, stunAttributeLength); } } STUNv2AttributeTypesEnum attributeType = STUNv2AttributeTypes.GetSTUNAttributeTypeForId(stunAttributeType); STUNv2Attribute attribute = null; if (attributeType == STUNv2AttributeTypesEnum.ChangeRequest) { attribute = new STUNv2ChangeRequestAttribute(stunAttributeValue); } else if (attributeType == STUNv2AttributeTypesEnum.MappedAddress) { attribute = new STUNv2AddressAttribute(stunAttributeValue); } else if (attributeType == STUNv2AttributeTypesEnum.ErrorCode) { attribute = new STUNv2ErrorCodeAttribute(stunAttributeValue); } else if (attributeType == STUNv2AttributeTypesEnum.XORMappedAddress || attributeType == STUNv2AttributeTypesEnum.XORPeerAddress || attributeType == STUNv2AttributeTypesEnum.XORRelayedAddress) { attribute = new STUNv2XORAddressAttribute(attributeType, stunAttributeValue); } else { attribute = new STUNv2Attribute(attributeType, stunAttributeValue); } attributes.Add(attribute); // Attributes start on 32 bit word boundaries so where an attribute length is not a multiple of 4 it gets padded. int padding = (stunAttributeLength % 4 != 0) ? 4 - (stunAttributeLength % 4) : 0; startAttIndex = startAttIndex + 4 + stunAttributeLength + padding; } return(attributes); } else { return(null); } }
public void PutXORMappedAddressAttributeToBufferTestMethod() { Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); STUNv2XORAddressAttribute xorAddressAttribute = new STUNv2XORAddressAttribute(STUNv2AttributeTypesEnum.XORMappedAddress, 49608, IPAddress.Parse("192.168.33.125")); byte[] buffer = new byte[12]; xorAddressAttribute.ToByteBuffer(buffer, 0); Assert.AreEqual(0x00, buffer[0]); Assert.AreEqual(0x20, buffer[1]); Assert.AreEqual(0x00, buffer[2]); Assert.AreEqual(0x08, buffer[3]); Assert.AreEqual(0x00, buffer[4]); Assert.AreEqual(0x01, buffer[5]); Assert.AreEqual(0xe0, buffer[6]); Assert.AreEqual(0xda, buffer[7]); Assert.AreEqual(0xe1, buffer[8]); Assert.AreEqual(0xba, buffer[9]); Assert.AreEqual(0x85, buffer[10]); Assert.AreEqual(0x3f, buffer[11]); }
public void ParseXORMappedAddressAttributeTestMethod() { Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); byte[] stunAttribute = new byte[]{0x00, 0x01, 0xe0, 0xda, 0xe1, 0xba, 0x85, 0x3f}; STUNv2XORAddressAttribute xorAddressAttribute = new STUNv2XORAddressAttribute(STUNv2AttributeTypesEnum.XORMappedAddress, stunAttribute); Assert.AreEqual(49608, xorAddressAttribute.Port); Assert.AreEqual("192.168.33.125", xorAddressAttribute.Address.ToString()); }
public static List<STUNv2Attribute> ParseMessageAttributes(byte[] buffer, int startIndex, int endIndex) { if (buffer != null && buffer.Length > startIndex && buffer.Length >= endIndex) { List<STUNv2Attribute> attributes = new List<STUNv2Attribute>(); int startAttIndex = startIndex; while (startAttIndex < endIndex) { UInt16 stunAttributeType = BitConverter.ToUInt16(buffer, startAttIndex); UInt16 stunAttributeLength = BitConverter.ToUInt16(buffer, startAttIndex + 2); byte[] stunAttributeValue = null; if (BitConverter.IsLittleEndian) { stunAttributeType = Utility.ReverseEndian(stunAttributeType); stunAttributeLength = Utility.ReverseEndian(stunAttributeLength); } if (stunAttributeLength > 0) { if (stunAttributeLength + startIndex + 4 > endIndex) { logger.Warn("The attribute length on a STUN parameter was greater than the available number of bytes."); } else { stunAttributeValue = new byte[stunAttributeLength]; Buffer.BlockCopy(buffer, startAttIndex + 4, stunAttributeValue, 0, stunAttributeLength); } } STUNv2AttributeTypesEnum attributeType = STUNv2AttributeTypes.GetSTUNAttributeTypeForId(stunAttributeType); STUNv2Attribute attribute = null; if (attributeType == STUNv2AttributeTypesEnum.ChangeRequest) { attribute = new STUNv2ChangeRequestAttribute(stunAttributeValue); } else if (attributeType == STUNv2AttributeTypesEnum.MappedAddress) { attribute = new STUNv2AddressAttribute(stunAttributeValue); } else if (attributeType == STUNv2AttributeTypesEnum.ErrorCode) { attribute = new STUNv2ErrorCodeAttribute(stunAttributeValue); } else if (attributeType == STUNv2AttributeTypesEnum.XORMappedAddress || attributeType == STUNv2AttributeTypesEnum.XORPeerAddress || attributeType == STUNv2AttributeTypesEnum.XORRelayedAddress) { attribute = new STUNv2XORAddressAttribute(attributeType, stunAttributeValue); } else { attribute = new STUNv2Attribute(attributeType, stunAttributeValue); } attributes.Add(attribute); // Attributes start on 32 bit word boundaries so where an attribute length is not a multiple of 4 it gets padded. int padding = (stunAttributeLength % 4 != 0) ? 4 - (stunAttributeLength % 4) : 0; startAttIndex = startAttIndex + 4 + stunAttributeLength + padding; } return attributes; } else { return null; } }