protected void InitializeDriver() { FILTER_INFO filterInfo; driver = NtTdiApi.OpenFilterDriverW(NtTdiApi.NTTDIDR_DRIVER_NAMEW); if (driver == 0) { throw new Exception("Cannot open driver"); } uint driverVersion = NtTdiApi.GetDriverVersion(driver); if (driverVersion != NtTdiApi.NTTDIDR_DRIVER_VERSION) { throw new Exception("Unsupported driver version"); } buffer = Marshal.AllocHGlobal(new IntPtr(bufferSize)); if (buffer == IntPtr.Zero) { throw new Exception(string.Format("Cannot allocate {0} bytes", bufferSize)); } NtTdiApi.SetLoggingState(driver, 1); filterInfo = new FILTER_INFO(1, NtTdiApi.EVENT_MASK_FULL, NtTdiApi.FLT_ACTION_LOG, 0, 0x00000000, 0x00000000, 0, 0xFFFF, PROTOCOL.PROTOCOL_ANY, 0, 0xFFF); NtTdiApi.RemoveAllFilters(driver); if (!NtTdiApi.AddStaticFilter(driver, filterInfo)) { throw new Exception("Cannot set filter"); } }
/// <summary> /// Stops the traffic monitoring /// </summary> public void PauseListening() { listening = false; ThreadPool.QueueUserWorkItem((a) => { lock (serializer) { foreach (var packet in packetBuffer) { serializer.SerializePacket(packet); } } }); Marshal.FreeHGlobal(buffer); NtTdiApi.SetLoggingState(driver, 0); NtTdiApi.PurgeLog(driver); NtTdiApi.RemoveAllFilters(driver); this.DownloadSpeed = 0; this.UploadSpeed = 0; }
/// <summary> /// Starts capturing the packets /// </summary> public void StartListening() { InitializeDriver(); double downloaded = 0; double uploaded = 0; //get speed information every second Timer t = new Timer(1000); t.Elapsed += new ElapsedEventHandler((e, o) => { if (downloaded != 0) { this.DownloadSpeed = downloaded / 1000; NotifyPropertyChanged("DownloadSpeed"); downloaded = 0; } if (uploaded != 0) { this.UploadSpeed = uploaded / 1000; NotifyPropertyChanged("UploadSpeed"); uploaded = 0; } }); t.Start(); int i = 0, j = 0, error = 0; uint bytesProcessed = 0; LOG_INFO logInfo; string protocol; while (listening) { uint bytesRead = bufferSize; if (NtTdiApi.ReadLogEx(driver, buffer, ref bytesRead)) { i++; bytesProcessed = 0; for (j = 0; bytesProcessed < bytesRead; j++) { IntPtr currentPtr = new IntPtr(buffer.ToInt32() + bytesProcessed); logInfo = (LOG_INFO)Marshal.PtrToStructure(currentPtr, typeof(LOG_INFO)); if (logInfo.m_LocalAddress.m_Ip != 0 && logInfo.m_RemoteAddress.m_Ip != 0) { Packet p = new Packet(logInfo); OnPacketReceived(p); packetBuffer.Add(p); if (packetBuffer.Count == PACKET_BUFFER_SIZE) { var packetsToSave = new Packet[PACKET_BUFFER_SIZE]; packetBuffer.CopyTo(packetsToSave); packetBuffer.Clear(); ThreadPool.QueueUserWorkItem((a) => { lock (serializer) { foreach (var packet in packetsToSave) { serializer.SerializePacket(packet); } } }); } totalPackets++; NotifyPropertyChanged("TotalPackets"); if (p.PacketDirection == PacketDirection.Downloading) { totalDownloaded += p.Size; downloaded += (ulong)p.Size; NotifyPropertyChanged("TotalDownloaded"); } else if (p.PacketDirection == PacketDirection.Uploading) { totalUploaded += p.Size; uploaded += (ulong)p.Size; NotifyPropertyChanged("TotalUploaded"); } } bytesProcessed += Convert.ToUInt32(Marshal.SizeOf(typeof(LOG_INFO))) + logInfo.m_DataLength; } } else { error = Marshal.GetLastWin32Error(); if (error == 122 /*ERROR_INSUFFICIENT_BUFFER*/) { bufferSize += 0x1000; buffer = Marshal.ReAllocHGlobal(buffer, new IntPtr(bufferSize)); if (buffer == IntPtr.Zero) { throw new Exception(string.Format("Cannot allocate {0} bytes! abort", bufferSize)); } } if (NtTdiApi.GetWaitEvent(driver)) { NtTdiApi.WaitForData(driver, 0xFFFFFFFF); //INFINITE } else { Thread.Sleep(1000); } } } }