Example #1
0
        /// <summary>
        /// Parses the chunks from a serialised SCTP packet.
        /// </summary>
        /// <param name="buffer">The buffer holding the serialised packet.</param>
        /// <param name="offset">The position in the buffer of the packet.</param>
        /// <param name="length">The length of the serialised packet in the buffer.</param>
        /// <returns>The lsit of parsed chunks and a list of unrecognised chunks that were not de-serialised.</returns>
        private static (List <SctpChunk> chunks, List <byte[]> unrecognisedChunks) ParseChunks(byte[] buffer, int offset, int length)
        {
            List <SctpChunk> chunks             = new List <SctpChunk>();
            List <byte[]>    unrecognisedChunks = new List <byte[]>();

            int posn = offset + SctpHeader.SCTP_HEADER_LENGTH;

            bool stop = false;

            while (posn < length)
            {
                byte chunkType = buffer[posn];

                if (Enum.IsDefined(typeof(SctpChunkType), chunkType))
                {
                    var chunk = SctpChunk.Parse(buffer, posn);
                    chunks.Add(chunk);
                }
                else
                {
                    switch (SctpChunk.GetUnrecognisedChunkAction(chunkType))
                    {
                    case SctpUnrecognisedChunkActions.Stop:
                        stop = true;
                        break;

                    case SctpUnrecognisedChunkActions.StopAndReport:
                        stop = true;
                        unrecognisedChunks.Add(SctpChunk.CopyUnrecognisedChunk(buffer, posn));
                        break;

                    case SctpUnrecognisedChunkActions.Skip:
                        break;

                    case SctpUnrecognisedChunkActions.SkipAndReport:
                        unrecognisedChunks.Add(SctpChunk.CopyUnrecognisedChunk(buffer, posn));
                        break;
                    }
                }

                if (stop)
                {
                    logger.LogWarning($"SCTP unrecognised chunk type {chunkType} indicated no further chunks should be processed.");
                    break;
                }

                posn += (int)SctpChunk.GetChunkLengthFromHeader(buffer, posn, true);
            }

            return(chunks, unrecognisedChunks);
        }
Example #2
0
 /// <summary>
 /// Copies an unrecognised chunk to a byte buffer and returns it. This method is
 /// used to assist in reporting unrecognised chunk types.
 /// </summary>
 /// <param name="buffer">The buffer containing the chunk.</param>
 /// <param name="posn">The position in the buffer that the unrecognised chunk starts.</param>
 /// <returns>A new buffer containing a copy of the chunk.</returns>
 public static byte[] CopyUnrecognisedChunk(byte[] buffer, int posn)
 {
     byte[] unrecognised = new byte[SctpChunk.GetChunkLengthFromHeader(buffer, posn, true)];
     Buffer.BlockCopy(buffer, posn, unrecognised, 0, unrecognised.Length);
     return(unrecognised);
 }