Search code examples
c#.netdatetimewinpcapsharppcap

How do I get IPs that sent more than X packets in less than a given time


I have a C# program that detects incoming TCP/IP packets on any given ethernet device. Every packet is processed in the following struct:

struct Packet{
   String sourceIp;
   DateTime arrivalDate;
}

If I have a List of every incoming Packets (List), how do I get those IPs that have more than X packets in less than Y seconds (say 1 second)?

I have no idea how to approach this problem, any help/tip will be highly appreciated.


Solution

  • Using Linq, it will be something like this:

      List<Packet> allPackets =
         new List<Packet>
            {
               new Packet {arrivalDate = DateTime.Parse("2000-01-01 0:00:00"), sourceIp = "a"},
               new Packet {arrivalDate = DateTime.Parse("2000-01-01 0:00:01"), sourceIp = "a"},
               new Packet {arrivalDate = DateTime.Parse("2000-01-01 0:00:01"), sourceIp = "a"},
               new Packet {arrivalDate = DateTime.Parse("2000-01-01 0:01:00"), sourceIp = "a"},
               new Packet {arrivalDate = DateTime.Parse("2000-01-01 0:00:00"), sourceIp = "b"},
               new Packet {arrivalDate = DateTime.Parse("2000-01-01 0:01:00"), sourceIp = "b"},
               new Packet {arrivalDate = DateTime.Parse("2000-01-01 0:02:00"), sourceIp = "b"},
               new Packet {arrivalDate = DateTime.Parse("2000-01-01 0:03:00"), sourceIp = "b"},
            };
      var xPackets = 2;
      var interval = TimeSpan.FromSeconds(15);
    
      // We group all the packets by ip, then within that, order the packets by date.
      var ips =
         allPackets
            .GroupBy(
               p => p.sourceIp,
               (ip, packets) => new
                                    {
                                       ip,
                                       packets = packets.OrderBy(p => p.arrivalDate).ToList()
                                    })
            .ToList();
      // Build a list of IPs with at least x packets in y interval.
      var rapidIps = new List<string>();
      foreach (var ipPacket in ips)
      {
         for (int i = 0, j = xPackets; j < ipPacket.packets.Count; i++, j++)
         {
            if (ipPacket.packets[i].arrivalDate + interval >= ipPacket.packets[j].arrivalDate)
            {
               rapidIps.Add((ipPacket.ip));
               break;
            }
    
         }
      }
    

    At the end, rapidIps contains [a].