Get the network interface with the most traffic within a sample period using Pcap.net

55 views Asked by At

I'm trying to use the Pcap.net package to analyze the amount of traffic in bits per second across multiple network interfaces over a small sample period (e.g. 10 seconds). Then I would like to calculate the average of the total bytes per seconds from the results, and then indicate which interface has the most traffic by highighting the associated listBox item.

I'm working with this example from the package github: Statistics Example

I need to do this for each interface simultaneously, so I am launching a method that ultimately calls the PacketSampleStatistics class in a separate thread for each interface.

My problem is that once I'm in the method that uses the PacketSampleStatistics class, I don't know how to identify the interface by its index anymore, and therefore I can't tie it to the listbox item.

I populate the listbox and launch a new thread for each interface like so:

public Form1()
{
    InitializeComponent();
    // Retrieve the device list from the local machine

    IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;

    if (allDevices.Count == 0)
    {
        Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
        return;
    }

    // Print the list
    for (int i = 0; i != allDevices.Count; ++i)
    {
        LivePacketDevice device = allDevices[i];
        Console.Write((i + 1) + ". " + device.Name);
        int pcapInt = i + 1;
        if (device.Description != null)
        {
            Console.WriteLine(" (" + device.Description + ")");
            listBox1.Items.Add((pcapInt) + ". " + device.Description);
        }
        else
            Console.WriteLine(" (No description available)");
    }


    foreach (var netInts in listBox1.Items)
    {
        int curIndex = 1 + listBox1.Items.IndexOf(netInts);
        Console.WriteLine(curIndex);
        Thread getStats = new Thread(() => GetNetStatistics(curIndex));
        Console.WriteLine("Interface index: " + curIndex);
        getStats.Start();
    }
}

This creates a new thread for each network interface and it writes the bits per second to the console by starting a method called GetNetStatistics. This method then starts the StatisticsHandler which uses the PacketSampleStatistics class to write the bits per second for each interface to the console in its own thread, which is working.

I tried invoking a delegate to update objects on my main form, which works if I'm doing this for only one network interface/one thread at a time. But I need to be able to do this for every network interface at the same time.

My commented out code at the end of the PacketSampleStatistics class shows my attempts to figure this out.

private void StatisticsHandler(PacketSampleStatistics statistics)
{

    // Current sample time
    DateTime currentTimestamp = statistics.Timestamp;

    // Previous sample time
    DateTime previousTimestamp = _lastTimestamp;

    // Set _lastTimestamp for the next iteration
    _lastTimestamp = currentTimestamp;

    // If there wasn't a previous sample than skip this iteration (it's the first iteration)
    if (previousTimestamp == DateTime.MinValue)
        return;

    // Calculate the delay from the last sample
    double delayInSeconds = (currentTimestamp - previousTimestamp).TotalSeconds;

    // Calculate bits per second
    double bitsPerSecond = Math.Truncate(statistics.AcceptedBytes * 8 / delayInSeconds);

    // Calculate packets per second
    double packetsPerSecond = statistics.AcceptedPackets / delayInSeconds;

    // Print timestamp and samples
    Console.WriteLine(statistics.Timestamp + " BPS: " + bitsPerSecond + " PPS: " + packetsPerSecond);

    //invoke delegate to update main form
    //MethodInvoker inv = delegate
    //{
        //bytesSecond.Text = bitsPerSecond.ToString();
        //listBox1.Items[0] = listBox1.Items[0] + bitsPerSecond.ToString();
    //};
    //this.Invoke(inv);

}
1

There are 1 answers

0
brickner On

It seems like the method that handles PacketSampleStatistics should be a member of a class that is initialized with the interface id.