public static STUNMessage ParseSTUNMessage(byte[] buffer, int bufferLength) { if (buffer != null && buffer.Length > 0 && buffer.Length >= bufferLength) { STUNMessage stunMessage = new STUNMessage(); stunMessage.Header = STUNHeader.ParseSTUNHeader(buffer); if (stunMessage.Header.MessageLength > 0) { stunMessage.Attributes = STUNAttribute.ParseMessageAttributes(buffer, STUNHeader.STUN_HEADER_LENGTH, bufferLength); } return(stunMessage); } return(null); }
public static List <STUNAttribute> ParseMessageAttributes(byte[] buffer, int startIndex, int endIndex) { if (buffer != null && buffer.Length > startIndex && buffer.Length >= endIndex) { List <STUNAttribute> attributes = new List <STUNAttribute>(); 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 (stunAttributeType == (int)STUNAttributeTypesEnum.Username && stunAttributeLength > buffer.Length - startIndex - 4) { // Received some STUN messages where the username is shorter than the claimed length. int realLength = buffer.Length - startIndex - 4; stunAttributeValue = new byte[realLength]; Buffer.BlockCopy(buffer, startIndex + 4, stunAttributeValue, 0, realLength); } else { stunAttributeValue = new byte[stunAttributeLength]; Buffer.BlockCopy(buffer, startIndex + 4, stunAttributeValue, 0, stunAttributeLength); } } STUNAttributeTypesEnum attributeType = STUNAttributeTypes.GetSTUNAttributeTypeForId(stunAttributeType); STUNAttribute attribute = null; if (attributeType == STUNAttributeTypesEnum.ChangeRequest) { attribute = new STUNChangeRequestAttribute(stunAttributeValue); } else if (attributeType == STUNAttributeTypesEnum.MappedAddress) { attribute = new STUNAddressAttribute(stunAttributeValue); } else { attribute = new STUNAttribute(attributeType, stunAttributeLength, stunAttributeValue); } attributes.Add(attribute); startAttIndex = startAttIndex + 4 + stunAttributeLength; } return(attributes); } else { return(null); } }