private void PacketProcessor() { DebugInformation.WriteLine("[PD] Packet processor started."); var localPacketBuffer = new List <EthernetPacket>(); var packetBytes = 0; while (started) { EthernetPacket rawPacket; // wait if there haven't been any new packets put into queue packetsAvailable.WaitOne(); // get packets from queue and add them to the local buffer while (packetBuffer.TryDequeue(out rawPacket) && rawPacket != null) { localPacketBuffer.Add(rawPacket); packetBytes += rawPacket.BytesHighPerformance.BytesLength; // add 16 bytes | TODO: find out why there are always 16 more bytes needed for each packet packetBytes += 16; } packetsAvailable.Reset(); var packetQueue = new SendQueue(packetBytes * packetRouters.Count); // loop through local packet buffer foreach (var packet in localPacketBuffer) { // skip local packets if (iface.IsLocalIPv4Packet(packet)) { continue; } // send to packet readers foreach (IPacketReader reader in packetReaders) { reader.ReadPacket(packet); } // send to packet filters, skip routing step for filtered packets lock (packetFilters) { foreach (IPacketFilter filter in packetFilters) { if (filter.Enabled && filter.FilterPacket(packet)) { continue; } } } // send to packet routers foreach (IPacketRouter router in packetRouters) { var routedPacket = router.RoutePacket(packet); if (routedPacket != null) { packetQueue.Add(routedPacket.Bytes); } } } // send out all the routed packets packetQueue.TransmitAll(iface.PcapDevice); localPacketBuffer.Clear(); packetBytes = 0; } DebugInformation.WriteLine("[PD] Packet processor stopped."); }