private void ParseAttribute(byte[] data, ref int offset) { // Type AttributeType type = (AttributeType)(data[offset++] << 8 | data[offset++]); // Length int length = (data[offset++] << 8 | data[offset++]); // MAPPED-ADDRESS if (type == AttributeType.MappedAddress) { MappedAddress = ParseEndPoint(data, ref offset); } // RESPONSE-ADDRESS else if (type == AttributeType.ResponseAddress) { ResponseAddress = ParseEndPoint(data, ref offset); } // CHANGE-REQUEST else if (type == AttributeType.ChangeRequest) { offset += 3; ChangeRequest = new ChangeRequest((data[offset] & 4) != 0, (data[offset] & 2) != 0); offset++; } // SOURCE-ADDRESS else if (type == AttributeType.SourceAddress) { SourceAddress = ParseEndPoint(data, ref offset); } // CHANGED-ADDRESS else if (type == AttributeType.ChangedAddress) { ChangedAddress = ParseEndPoint(data, ref offset); } // USERNAME else if (type == AttributeType.Username) { UserName = Encoding.Default.GetString(data, offset, length); offset += length; } // PASSWORD else if (type == AttributeType.Password) { Password = Encoding.Default.GetString(data, offset, length); offset += length; } // MESSAGE-INTEGRITY else if (type == AttributeType.MessageIntegrity) { offset += length; } else if (type == AttributeType.ErrorCode) { int errorCode = (data[offset + 2] & 0x7) * 100 + (data[offset + 3] & 0xFF); ErrorCode = new ErrorCode(errorCode, Encoding.Default.GetString(data, offset + 4, length - 4)); offset += length; } else if (type == AttributeType.UnknownAttribute) { offset += length; } else if (type == AttributeType.ReflectedFrom) { ReflectedFrom = ParseEndPoint(data, ref offset); } // XorMappedAddress // XorOnly // ServerName else if (type == AttributeType.ServerName) { ServerName = Encoding.Default.GetString(data, offset, length); offset += length; } // Unknown else { offset += length; } }