/// <summary>
        /// Creates a new flow instance.
        /// </summary>
        /// <param name="settings">The settings.</param>
        public MultipathTracerouteFlow(MultipathTracerouteSettings settings)
        {
            // Set the identifier.
            this.Id = Guid.NewGuid();

            // Set the short identifier.
            this.id = this.Id.ToByteArray();
            this.ShortId = 0;
            for (int index = 0; index < this.id.Length - 1; index += 2)
            {
                this.ShortId ^= (ushort)((this.id[index] << 8) | this.id[index + 1]);
            }

            // Set the TTL count.
            this.TtlCount = settings.MaximumHops - settings.MinimumHops + 1;

            // Create the ICMP data.
            this.IcmpData = new MultipathTracerouteData[this.TtlCount, settings.AttemptsPerFlow];
            // Create the UDP data.
            this.UdpData = new MultipathTracerouteData[this.TtlCount, settings.AttemptsPerFlow];

            // Compute the UDP source port.
            this.UdpSourcePort = (ushort)((settings.MinimumPort + (settings.MaximumPort - settings.MinimumPort) * (ushort)((this.id[4] << 8) | this.id[5]) / 0x10000) & 0xFFFF);

            // Compute the UDP destination port.
            this.UdpDestinationPort = (ushort)((settings.MinimumPort + (settings.MaximumPort - settings.MinimumPort) * (ushort)((this.id[6] << 8) | this.id[7]) / 0x10000) & 0xFFFF);
        }
        /// <summary>
        /// Creates a new multipath traceroute with the specified settings.
        /// </summary>
        /// <param name="settings">The settings.</param>
        public MultipathTraceroute(MultipathTracerouteSettings settings, PacketCapture capture)
        {
            // Validate the settings.
            if ((settings.AttemptsPerFlow == 0) || (settings.AttemptsPerFlow > 255))
                throw new ArgumentException("The maximum attempts per flow is invalid (1..255).");
            if ((settings.FlowCount == 0) || (settings.FlowCount > 255))
                throw new ArgumentException("The maximum flow count is invalid (1..255).");
            if (settings.MinimumHops == 0)
                throw new ArgumentException("The minimum hops count is invalid (1..255).");
            if (settings.MaximumHops == 0)
                throw new ArgumentException("The maximum hops count is invalid (1..255).");
            if (settings.MinimumHops >= settings.MaximumHops)
                throw new ArgumentException("The minimum hops must be smaller than the maximum hops.");
            if (settings.MaximumUnknownHops == 0)
                throw new ArgumentException("The maximum unknown hops count is invalid (1..255).");
            if ((settings.DataLength == 0) || (settings.DataLength > 1024))
                throw new ArgumentException("The data length is invalid (1..1024).");
            if ((settings.MinimumPort < 1024) || (settings.MinimumPort > 65520))
                throw new ArgumentException("The minimum port is invalid (1024..65520).");
            if ((settings.MaximumPort < 1024) || (settings.MaximumPort > 65520))
                throw new ArgumentException("The maximum port is invalid (1024..65520).");
            if (settings.MinimumPort >= settings.MaximumPort)
                throw new ArgumentException("The minimum port must be smaller than the maximum port.");
            if (settings.DataLength < 2)
                throw new ArgumentException("The minimum data length is 2.");

            // Set the packet capture.
            this.capture = capture;

            // Set the settings.
            this.settings = settings;

            // Global parameters.
            ProtoPacketIcmp.IgnoreChecksum = true;

            // Initialize the receiving buffers.
            //for (int index = 0; index < MultipathTraceroute.bufferCount; index++)
            //{
            //	this.bufferRecv[index] = new byte[MultipathTraceroute.bufferSize];
            //	this.bufferQueue.Enqueue(index);
            //}

            // Create the timer.
            this.timer = new Timer((object state) =>
            {
                lock (this.syncResults)
                {
                    // For all results.
                    foreach (MultipathTracerouteResult result in this.results)
                    {
                        // Call the result timeout method.
                        result.Timeout();
                    }
                }
            }, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(MultipathTraceroute.requestsTimeout));
        }