//------------------------------------ REFLECTED FROM -------------------------- /** * Creates a ReflectedFromAddressAttribute of the specified type and with * the specified address and port * @param address the address value of the address attribute * @return the newly created address attribute. */ public static ReflectedFromAttribute CreateReflectedFromAttribute( StunAddress address) { ReflectedFromAttribute attribute = new ReflectedFromAttribute(); attribute.SetAddress(address); return(attribute); }
/** * Decodes the specified binary array and returns the corresponding * attribute object. * @param bytes the binary array that should be decoded. * @param offset the index where the message starts. * @param length the number of bytes that the message is long. * @return An object representing the attribute encoded in bytes or null if * the attribute was not recognized. * @throws StunException if bytes does is not a valid STUN attribute. */ public static Attribute decode(byte[] bytes, int offset, int length) { if(bytes == null || bytes.Length < Attribute.HEADER_LENGTH) throw new StunException(StunException.ILLEGAL_ARGUMENT, "Could not decode the specified binary array."); //Discover attribute type int attributeTypec = (int)(((bytes[offset]<<8)&0xff00)|(bytes[offset + 1] & 0xff)); int attributeType = (int) attributeTypec; int attributeLengthc = (int)(((bytes[offset + 2]<<8)&0xff00)|(bytes[offset + 3]&0xff)); int attributeLength = (int) attributeLengthc; if(attributeLength > bytes.Length - offset ) { throw new StunException(StunException.ILLEGAL_ARGUMENT, "The indicated attribute length ("+attributeLength+") " +"does not match the length of the passed binary array"); } Attribute decodedAttribute = null; switch(attributeType) { case Attribute.CHANGE_REQUEST: decodedAttribute = new ChangeRequestAttribute(); break; case Attribute.CHANGED_ADDRESS: decodedAttribute = new ChangedAddressAttribute(); break; case Attribute.MAPPED_ADDRESS: decodedAttribute = new MappedAddressAttribute(); break; case Attribute.ERROR_CODE: decodedAttribute = new ErrorCodeAttribute(); break; case Attribute.MESSAGE_INTEGRITY: throw new StunException( "The MESSAGE-INTEGRITY Attribute is not yet implemented."); case Attribute.PASSWORD: throw new StunException( "The PASSWORD Attribute is not yet implemented."); case Attribute.REFLECTED_FROM: decodedAttribute = new ReflectedFromAttribute(); break; case Attribute.RESPONSE_ADDRESS: decodedAttribute = new ResponseAddressAttribute(); break; case Attribute.SOURCE_ADDRESS: decodedAttribute = new SourceAddressAttribute(); break; case Attribute.UNKNOWN_ATTRIBUTES: decodedAttribute = new UnknownAttributesAttribute(); break; case Attribute.USERNAME: throw new StunException( "The USERNAME Attribute is not yet implemented."); //According to rfc3489 we should silently ignore unknown attributes. default: decodedAttribute = new UnknownAttributesAttribute(); break; //return null; } decodedAttribute.SetAttributeType(attributeType); decodedAttribute.DecodeAttributeBody(bytes, (Attribute.HEADER_LENGTH + offset), attributeLength); return decodedAttribute; }
//------------------------------------ REFLECTED FROM -------------------------- /** * Creates a ReflectedFromAddressAttribute of the specified type and with * the specified address and port * @param address the address value of the address attribute * @return the newly created address attribute. */ public static ReflectedFromAttribute CreateReflectedFromAttribute( StunAddress address) { ReflectedFromAttribute attribute = new ReflectedFromAttribute(); attribute.SetAddress(address); return attribute; }
/** * Decodes the specified binary array and returns the corresponding * attribute object. * @param bytes the binary array that should be decoded. * @param offset the index where the message starts. * @param length the number of bytes that the message is long. * @return An object representing the attribute encoded in bytes or null if * the attribute was not recognized. * @throws StunException if bytes does is not a valid STUN attribute. */ public static Attribute decode(byte[] bytes, int offset, int length) { if (bytes == null || bytes.Length < Attribute.HEADER_LENGTH) { throw new StunException(StunException.ILLEGAL_ARGUMENT, "Could not decode the specified binary array."); } //Discover attribute type int attributeTypec = (int)(((bytes[offset] << 8) & 0xff00) | (bytes[offset + 1] & 0xff)); int attributeType = (int)attributeTypec; int attributeLengthc = (int)(((bytes[offset + 2] << 8) & 0xff00) | (bytes[offset + 3] & 0xff)); int attributeLength = (int)attributeLengthc; if (attributeLength > bytes.Length - offset) { throw new StunException(StunException.ILLEGAL_ARGUMENT, "The indicated attribute length (" + attributeLength + ") " + "does not match the length of the passed binary array"); } Attribute decodedAttribute = null; switch (attributeType) { case Attribute.CHANGE_REQUEST: decodedAttribute = new ChangeRequestAttribute(); break; case Attribute.CHANGED_ADDRESS: decodedAttribute = new ChangedAddressAttribute(); break; case Attribute.MAPPED_ADDRESS: decodedAttribute = new MappedAddressAttribute(); break; case Attribute.ERROR_CODE: decodedAttribute = new ErrorCodeAttribute(); break; case Attribute.MESSAGE_INTEGRITY: throw new StunException( "The MESSAGE-INTEGRITY Attribute is not yet implemented."); case Attribute.PASSWORD: throw new StunException( "The PASSWORD Attribute is not yet implemented."); case Attribute.REFLECTED_FROM: decodedAttribute = new ReflectedFromAttribute(); break; case Attribute.RESPONSE_ADDRESS: decodedAttribute = new ResponseAddressAttribute(); break; case Attribute.SOURCE_ADDRESS: decodedAttribute = new SourceAddressAttribute(); break; case Attribute.UNKNOWN_ATTRIBUTES: decodedAttribute = new UnknownAttributesAttribute(); break; case Attribute.USERNAME: throw new StunException( "The USERNAME Attribute is not yet implemented."); //According to rfc3489 we should silently ignore unknown attributes. default: decodedAttribute = new UnknownAttributesAttribute(); break; //return null; } decodedAttribute.SetAttributeType(attributeType); decodedAttribute.DecodeAttributeBody(bytes, (Attribute.HEADER_LENGTH + offset), attributeLength); return(decodedAttribute); }