2011-09-11 22 views
6

我一直在關注http://www.codeproject.com/KB/IP/sharppcap.aspx的指導,爲我實現一個簡單的數據包嗅探器來自動驗證身份,我設法進入了過濾部分,並且必須對教程代碼進行一些調整以使其可以正常工作,但我現在陷入了困境。無法從SharpPcap.RawCapture轉換到PacketDotNet.Packet

我收到的錯誤是;

的最好重載方法匹配 'PacketDotNet.TcpPacket.GetEncapsulated(PacketDotNet.Packet)' 具有一些無效參數

參數1:不能從 'SharpPcap.RawCapture' 轉換爲 'PacketDotNet.Packet'

但我還沒有做任何引用PacketDotNet我自我(到目前爲止一切都是SharpPcap)。

我已經包含了迄今爲止的完整代碼,問題出在device_OnPacketArrival()函數中。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using PacketDotNet; 
using SharpPcap; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string ver = SharpPcap.Version.VersionString; 
      Console.WriteLine("SharpPcap {0}, Example1.IfList.cs", ver); 

      // Retrieve the device list 
      CaptureDeviceList devices = CaptureDeviceList.Instance; 

      // If no devices were found print an error 
      if (devices.Count < 1) 
      { 
       Console.WriteLine("No devices were found on this machine"); 
       return; 
      } 

      // Extract a device from the list 
      ICaptureDevice device = devices[0]; 

      // Register our handler function to the 
      // 'packet arrival' event 
      device.OnPacketArrival += 
       new SharpPcap.PacketArrivalEventHandler(device_OnPacketArrival); 

      // Open the device for capturing 
      int readTimeoutMilliseconds = 1000; 
      device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds); 

      // tcpdump filter to capture only TCP/IP packets 
      string filter = "ip and tcp"; 
      device.Filter = filter; 

      Console.WriteLine(); 
      Console.WriteLine("-- The following tcpdump filter will be applied: \"{0}\"", 
       filter); 
      Console.WriteLine("-- Listening on {0}, hit 'Enter' to stop...", 
       device.Description); 

      // Start capturing packets indefinitely 
      device.Capture(); 

      // Close the pcap device 
      // (Note: this line will never be called since 
      // we're capturing indefinitely 
      device.Close(); 
     } 
     private static void device_OnPacketArrival(object sender, CaptureEventArgs e) 
     { 
      var tcp = TcpPacket.GetEncapsulated(e.Packet); 
     } 
    } 
} 

回答

6

甲SharpPcap.RawPacket用於保存所捕獲通過網絡適配器的原始數據,但PacketDotNet需要GetEncapsulated()方法將工作之前解析所述分組。你所需要的步驟將是這樣的:

var packet = PacketDotNet.Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data); 

然後你可以通過它packet提取通過GetEncapsulated()方法封裝TcpPacket

SharpPcap源代碼下載https://sourceforge.net/projects/sharppcap/中的示例12顯示了語法以及如何修改數據包。

請記住,PacketType.GetEncapsulated()正在返回對該數據包部分的引用,因此修改它將會更改原始數據包。

+0

它似乎沒有.Packet.Parse類,最接近Parse的是TcpPacket.ParsePacket(),但我有點不確定你從哪裏得到LinkLayer(在這種情況下rawPacket的引用是什麼,我希望它是e.Packet,但我不是100%確定的) – Clorith

+0

用正確的方法名稱更新了我的答案。 –

+0

現在引用例12,它們只有1個參數,但我仍然收到錯誤; 「方法沒有重載」ParsePacket'需要1個參數「,現在這一切都非常混亂。 – Clorith

0

或者,您可以使用Pcap.Net,它只有一個Packet類,您可以動態分析它以獲取它可能包含的任何內容,而無需執行任何數據包轉換。

你只是得到一個包對象,做(例如):

uint sequenceNumber = packet.Ethernet.IpV4.Tcp.SequenceNumber; 

無需投它或知道它是事先什麼樣的包,所有的解析過程是動態的。

0

作爲克里斯摩根的答案更新(因爲我發現自己今天這樣做),getEncapsulated()現在已經過時,而應該使用packet.Extract()來提取封裝的數據包。