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 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) { stunAttributeValue = new byte[stunAttributeLength]; Buffer.BlockCopy(buffer, startIndex + 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 { attribute = new STUNv2Attribute(attributeType, stunAttributeLength, stunAttributeValue); } attributes.Add(attribute); startAttIndex = startAttIndex + 4 + stunAttributeLength; } return attributes; } else { return null; } }
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; } }