/// <summary> /// Handler for processing an unrecognised chunk parameter. /// </summary> /// <param name="chunkParameter">The Type-Length-Value (TLV) formatted chunk that was /// not recognised.</param> /// <returns>True if further parameter parsing for this chunk should be stopped. /// False to continue.</returns> public bool GotUnrecognisedParameter(SctpTlvChunkParameter chunkParameter) { bool stop = false; switch (chunkParameter.UnrecognisedAction) { case SctpUnrecognisedParameterActions.Stop: stop = true; break; case SctpUnrecognisedParameterActions.StopAndReport: stop = true; UnrecognizedPeerParameters.Add(chunkParameter); break; case SctpUnrecognisedParameterActions.Skip: break; case SctpUnrecognisedParameterActions.SkipAndReport: UnrecognizedPeerParameters.Add(chunkParameter); break; } return(stop); }
/// <summary> /// Writes the optional and variable length parameters to a Type-Length-Value (TLV) /// parameter list. /// </summary> /// <returns>A TLV parameter list holding the optional and variable length parameters.</returns> private List <SctpTlvChunkParameter> GetVariableParameters() { List <SctpTlvChunkParameter> varParams = new List <SctpTlvChunkParameter>(); // Add the optional and variable length parameters as Type-Length-Value (TLV) formatted. foreach (var address in Addresses) { ushort addrParamType = (ushort)(address.AddressFamily == AddressFamily.InterNetwork ? SctpInitChunkParameterType.IPv4Address : SctpInitChunkParameterType.IPv6Address); var addrParam = new SctpTlvChunkParameter(addrParamType, address.GetAddressBytes()); varParams.Add(addrParam); } if (CookiePreservative > 0) { varParams.Add( new SctpTlvChunkParameter((ushort)SctpInitChunkParameterType.CookiePreservative, NetConvert.GetBytes(CookiePreservative) )); } if (!string.IsNullOrEmpty(HostnameAddress)) { varParams.Add( new SctpTlvChunkParameter((ushort)SctpInitChunkParameterType.HostNameAddress, Encoding.UTF8.GetBytes(HostnameAddress) )); } if (SupportedAddressTypes.Count > 0) { byte[] paramVal = new byte[SupportedAddressTypes.Count * 2]; int paramValPosn = 0; foreach (var supAddr in SupportedAddressTypes) { NetConvert.ToBuffer((ushort)supAddr, paramVal, paramValPosn); paramValPosn += 2; } varParams.Add( new SctpTlvChunkParameter((ushort)SctpInitChunkParameterType.SupportedAddressTypes, paramVal)); } if (StateCookie != null) { varParams.Add( new SctpTlvChunkParameter((ushort)SctpInitChunkParameterType.StateCookie, StateCookie)); } foreach (var unrecognised in UnrecognizedPeerParameters) { varParams.Add( new SctpTlvChunkParameter((ushort)SctpInitChunkParameterType.UnrecognizedParameter, unrecognised.GetBytes())); } return(varParams); }
/// <summary> /// Chunks can optionally contain Type-Length-Value (TLV) parameters. This method /// parses any variable length parameters from a chunk's value. /// </summary> /// <param name="buffer">The buffer holding the serialised chunk.</param> /// <param name="posn">The position in the buffer to start parsing variable length /// parameters from.</param> /// <param name="length">The length of the TLV chunk parameters in the buffer.</param> /// <returns>A list of chunk parameters. Can be empty.</returns> public static IEnumerable <SctpTlvChunkParameter> GetParameters(byte[] buffer, int posn, int length) { int paramPosn = posn; while (paramPosn < posn + length) { var chunkParam = SctpTlvChunkParameter.ParseTlvParameter(buffer, paramPosn); yield return(chunkParam); paramPosn += chunkParam.GetParameterLength(true); } }
/// <summary> /// Parses an SCTP Type-Length-Value (TLV) chunk parameter from a buffer. /// </summary> /// <param name="buffer">The buffer holding the serialised TLV chunk parameter.</param> /// <param name="posn">The position to start parsing at.</param> /// <returns>An SCTP TLV chunk parameter instance.</returns> public static SctpTlvChunkParameter ParseTlvParameter(byte[] buffer, int posn) { if (buffer.Length < posn + SCTP_PARAMETER_HEADER_LENGTH) { throw new ApplicationException("Buffer did not contain the minimum of bytes for an SCTP TLV chunk parameter."); } var tlvParam = new SctpTlvChunkParameter(); ushort paramLen = tlvParam.ParseFirstWord(buffer, posn); if (paramLen > SCTP_PARAMETER_HEADER_LENGTH) { tlvParam.ParameterValue = new byte[paramLen - SCTP_PARAMETER_HEADER_LENGTH]; Buffer.BlockCopy(buffer, posn + SCTP_PARAMETER_HEADER_LENGTH, tlvParam.ParameterValue, 0, tlvParam.ParameterValue.Length); } return(tlvParam); }