Commit 3ceb8bd0 authored by Brickner_cp's avatar Brickner_cp

--no commit message

--no commit message
parent 31c3e718
...@@ -34,11 +34,17 @@ namespace WinPcapDotNet.Console ...@@ -34,11 +34,17 @@ namespace WinPcapDotNet.Console
} while (index < 0 || index >= devices.Count); } while (index < 0 || index >= devices.Count);
const string filename = @"c:\tmp.pcap"; const string filename = @"c:\tmp.pcap";
const string filter = "port 80";
IPcapDevice chosenDevice = devices[index]; IPcapDevice chosenDevice = devices[index];
System.Console.WriteLine("Start Statistics Mode");
StatisticsMode(chosenDevice, filter);
System.Console.WriteLine("Finished Statistics Mode");
System.Console.ReadKey();
System.Console.WriteLine("Start Capturing packets"); System.Console.WriteLine("Start Capturing packets");
CapturePacketsToFile(chosenDevice, "port 80", filename); CapturePacketsToFile(chosenDevice, filter, filename);
System.Console.WriteLine("Finished capturing packets"); System.Console.WriteLine("Finished capturing packets");
System.Console.ReadKey(); System.Console.ReadKey();
...@@ -52,6 +58,34 @@ namespace WinPcapDotNet.Console ...@@ -52,6 +58,34 @@ namespace WinPcapDotNet.Console
System.Console.WriteLine("Finished Transmitting packets"); System.Console.WriteLine("Finished Transmitting packets");
} }
private static void StatisticsMode(IPcapDevice device, string filter)
{
using (PcapDeviceHandler deviceHandler = device.Open())
{
deviceHandler.SetFilter(filter);
deviceHandler.Mode = DeviceHandlerMode.Statistics;
for (int i = 0; i != 100; ++i)
{
PcapStatistics statistics;
DeviceHandlerResult result = deviceHandler.GetNextStatistics(out statistics);
switch (result)
{
case DeviceHandlerResult.Ok:
break;
case DeviceHandlerResult.Timeout:
continue;
case DeviceHandlerResult.Error:
throw new InvalidOperationException("Failed reading from device");
case DeviceHandlerResult.Eof:
continue;
}
System.Console.WriteLine("Got statistics: " + statistics);
}
}
}
private static void TransmitPacketsFromFile(string filename, IPcapDevice liveDevice) private static void TransmitPacketsFromFile(string filename, IPcapDevice liveDevice)
{ {
IPcapDevice offlineDevice = new PcapOfflineDevice(filename); IPcapDevice offlineDevice = new PcapOfflineDevice(filename);
...@@ -144,10 +178,5 @@ namespace WinPcapDotNet.Console ...@@ -144,10 +178,5 @@ namespace WinPcapDotNet.Console
} }
} }
} }
private static void Test(IPcapDevice device)
{
}
} }
} }
...@@ -12,17 +12,6 @@ namespace PcapDotNet ...@@ -12,17 +12,6 @@ namespace PcapDotNet
LoopBack = 0x00000001 LoopBack = 0x00000001
}; };
[System::Flags]
public enum class PcapDeviceOpenFlags : System::Int32
{
None = 0,
PROMISCUOUS = 1, // Defines if the adapter has to go in promiscuous mode.
DATATX_UDP = 2, // Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol.
NOCAPTURE_RPCAP = 4, // Defines if the remote probe will capture its own generated traffic.
NOCAPTURE_LOCAL = 8, // Defines if the local adapter will capture its own generated traffic.
MAX_RESPONSIVENESS = 16 // This flag configures the adapter for maximum responsiveness.
};
public interface class IPcapDevice public interface class IPcapDevice
{ {
property System::String^ Name { System::String^ get(); }; property System::String^ Name { System::String^ get(); };
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
struct bpf_program; struct bpf_program;
struct pcap_pkthdr; struct pcap_pkthdr;
struct pcap_rmtauth;
struct pcap_send_queue; struct pcap_send_queue;
struct sockaddr; struct sockaddr;
struct timeval; struct timeval;
......
...@@ -4,5 +4,5 @@ using namespace PcapDotNet; ...@@ -4,5 +4,5 @@ using namespace PcapDotNet;
PcapDeviceHandler^ PcapDevice::Open() PcapDeviceHandler^ PcapDevice::Open()
{ {
return Open(65536, PcapDeviceOpenFlags::PROMISCUOUS, 1000); return Open(65536, PcapDeviceOpenFlags::Promiscuous, 1000);
} }
...@@ -8,23 +8,55 @@ ...@@ -8,23 +8,55 @@
using namespace System; using namespace System;
using namespace BPacket; using namespace BPacket;
using namespace PcapDotNet; using namespace PcapDotNet;
using namespace System::Runtime::InteropServices;
PcapDeviceHandler::PcapDeviceHandler(pcap_t* pcapDescriptor, SocketAddress^ netmask) PcapDeviceHandler::PcapDeviceHandler(const char* source, int snapLen, PcapDeviceOpenFlags flags, int readTimeout, pcap_rmtauth *auth, SocketAddress^ netmask)
{ {
// Open the device
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *pcapDescriptor = pcap_open(source, // name of the device
snapLen, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
safe_cast<int>(flags),
readTimeout, // read timeout
auth, // authentication on the remote machine
errbuf); // error buffer
if (pcapDescriptor == NULL)
{
gcnew InvalidOperationException(String::Format("Unable to open the adapter. %s is not supported by WinPcap", gcnew String(source)));
}
_pcapDescriptor = pcapDescriptor; _pcapDescriptor = pcapDescriptor;
_ipV4Netmask = dynamic_cast<IpV4SocketAddress^>(netmask); _ipV4Netmask = dynamic_cast<IpV4SocketAddress^>(netmask);
} }
DeviceHandlerResult PcapDeviceHandler::GetNextPacket([System::Runtime::InteropServices::Out] Packet^% packet) DeviceHandlerMode PcapDeviceHandler::Mode::get()
{
return _mode;
}
void PcapDeviceHandler::Mode::set(DeviceHandlerMode value)
{
if (pcap_setmode(_pcapDescriptor, safe_cast<int>(value)) < 0)
throw gcnew InvalidOperationException("Error setting the mode.");
_mode = value;
}
DeviceHandlerResult PcapDeviceHandler::GetNextPacket([Out] Packet^% packet)
{ {
packet = nullptr; if (Mode != DeviceHandlerMode::Capture)
throw gcnew InvalidOperationException("Must be in capture mode to get packets");
pcap_pkthdr* packetHeader; pcap_pkthdr* packetHeader;
const unsigned char* packetData; const unsigned char* packetData;
DeviceHandlerResult result = safe_cast<DeviceHandlerResult>(pcap_next_ex(_pcapDescriptor, &packetHeader, &packetData)); DeviceHandlerResult result = safe_cast<DeviceHandlerResult>(pcap_next_ex(_pcapDescriptor, &packetHeader, &packetData));
if (result != DeviceHandlerResult::Ok) if (result != DeviceHandlerResult::Ok)
{
packet = nullptr;
return result; return result;
}
timeval pcapTimestamp = packetHeader->ts; timeval pcapTimestamp = packetHeader->ts;
DateTime timestamp; DateTime timestamp;
...@@ -36,6 +68,33 @@ DeviceHandlerResult PcapDeviceHandler::GetNextPacket([System::Runtime::InteropSe ...@@ -36,6 +68,33 @@ DeviceHandlerResult PcapDeviceHandler::GetNextPacket([System::Runtime::InteropSe
return result; return result;
} }
DeviceHandlerResult PcapDeviceHandler::GetNextStatistics([Out] PcapStatistics^% statistics)
{
if (Mode != DeviceHandlerMode::Statistics)
throw gcnew InvalidOperationException("Must be in statistics mode to get statistics");
pcap_pkthdr* packetHeader;
const unsigned char* packetData;
DeviceHandlerResult result = safe_cast<DeviceHandlerResult>(pcap_next_ex(_pcapDescriptor, &packetHeader, &packetData));
if (result != DeviceHandlerResult::Ok)
{
statistics = nullptr;
return result;
}
timeval pcapTimestamp = packetHeader->ts;
DateTime timestamp;
Timestamp::PcapTimestampToDateTime(packetHeader->ts, timestamp);
unsigned long acceptedPackets = *reinterpret_cast<const unsigned long*>(packetData);
unsigned long acceptedBytes = *reinterpret_cast<const unsigned long*>(packetData + 8);
statistics = gcnew PcapStatistics(timestamp, acceptedPackets, acceptedBytes);
return result;
}
void PcapDeviceHandler::SendPacket(Packet^ packet) void PcapDeviceHandler::SendPacket(Packet^ packet)
{ {
pin_ptr<Byte> unamangedPacketBytes = &packet->Buffer[0]; pin_ptr<Byte> unamangedPacketBytes = &packet->Buffer[0];
......
...@@ -3,10 +3,12 @@ ...@@ -3,10 +3,12 @@
#include "PcapAddress.h" #include "PcapAddress.h"
#include "BpfFilter.h" #include "BpfFilter.h"
#include "PcapDumpFile.h" #include "PcapDumpFile.h"
#include "PcapDeviceOpenFlags.h"
#include "PcapStatistics.h"
namespace PcapDotNet namespace PcapDotNet
{ {
public enum class DeviceHandlerResult public enum class DeviceHandlerResult : int
{ {
Ok = 1, // if the packet has been read without problems Ok = 1, // if the packet has been read without problems
Timeout = 0, // if the timeout set with Open() has elapsed. Timeout = 0, // if the timeout set with Open() has elapsed.
...@@ -14,12 +16,29 @@ namespace PcapDotNet ...@@ -14,12 +16,29 @@ namespace PcapDotNet
Eof = -2 // if EOF was reached reading from an offline capture Eof = -2 // if EOF was reached reading from an offline capture
}; };
public enum class DeviceHandlerMode : int
{
Capture = 0x0, // Capture working mode.
Statistics = 0x1, // Statistical working mode.
KernelMonitor = 0x2, // Kernel monitoring mode.
KernelDump = 0x10 // Kernel dump working mode.
};
public ref class PcapDeviceHandler : System::IDisposable public ref class PcapDeviceHandler : System::IDisposable
{ {
public: public:
PcapDeviceHandler(pcap_t* pcapDescriptor, SocketAddress^ netmask); PcapDeviceHandler(const char* source, int snapLen, PcapDeviceOpenFlags flags, int readTimeout, pcap_rmtauth *auth,
SocketAddress^ netmask);
//PcapDeviceHandler(pcap_t* pcapDescriptor, SocketAddress^ netmask);
property DeviceHandlerMode Mode
{
DeviceHandlerMode get();
void set(DeviceHandlerMode value);
}
DeviceHandlerResult GetNextPacket([System::Runtime::InteropServices::Out] BPacket::Packet^% packet); DeviceHandlerResult GetNextPacket([System::Runtime::InteropServices::Out] BPacket::Packet^% packet);
DeviceHandlerResult GetNextStatistics([System::Runtime::InteropServices::Out] PcapStatistics^% statistics);
void SendPacket(BPacket::Packet^ packet); void SendPacket(BPacket::Packet^ packet);
...@@ -40,5 +59,6 @@ namespace PcapDotNet ...@@ -40,5 +59,6 @@ namespace PcapDotNet
private: private:
pcap_t* _pcapDescriptor; pcap_t* _pcapDescriptor;
IpV4SocketAddress^ _ipV4Netmask; IpV4SocketAddress^ _ipV4Netmask;
DeviceHandlerMode _mode;
}; };
} }
\ No newline at end of file
#pragma once
namespace PcapDotNet
{
[System::Flags]
public enum class PcapDeviceOpenFlags : System::Int32
{
None = 0,
Promiscuous = 1, // Defines if the adapter has to go in promiscuous mode.
DataTransferUdpRemote = 2, // Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol.
NoCaptureRemote = 4, // Defines if the remote probe will capture its own generated traffic.
NoCaptureLocal = 8, // Defines if the local adapter will capture its own generated traffic.
MaximumResponsiveness = 16 // This flag configures the adapter for maximum responsiveness.
};
}
\ No newline at end of file
...@@ -68,26 +68,14 @@ List<PcapAddress^>^ PcapLiveDevice::Addresses::get() ...@@ -68,26 +68,14 @@ List<PcapAddress^>^ PcapLiveDevice::Addresses::get()
PcapDeviceHandler^ PcapLiveDevice::Open(int snapLen, PcapDeviceOpenFlags flags, int readTimeout) PcapDeviceHandler^ PcapLiveDevice::Open(int snapLen, PcapDeviceOpenFlags flags, int readTimeout)
{ {
std::string deviceName = MarshalingServices::ManagedToUnmanagedString(Name); std::string deviceName = MarshalingServices::ManagedToUnmanagedString(Name);
// Open the device
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *pcapDescriptor = pcap_open(deviceName.c_str(), // name of the device
snapLen, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
safe_cast<int>(flags),
readTimeout, // read timeout
NULL, // authentication on the remote machine
errbuf); // error buffer
if (pcapDescriptor == NULL)
{
gcnew InvalidOperationException(String::Format("Unable to open the adapter. %s is not supported by WinPcap", Name));
}
// Get the netmask
SocketAddress^ netmask; SocketAddress^ netmask;
if (Addresses->Count != 0) if (Addresses->Count != 0)
netmask = Addresses[0]->Netmask; netmask = Addresses[0]->Netmask;
return gcnew PcapDeviceHandler(pcapDescriptor, netmask);
// Open the device
return gcnew PcapDeviceHandler(deviceName.c_str(), snapLen, flags, readTimeout, NULL, netmask);
} }
// Private Methods // Private Methods
......
...@@ -41,31 +41,16 @@ PcapDeviceHandler^ PcapOfflineDevice::Open(int snapLen, PcapDeviceOpenFlags flag ...@@ -41,31 +41,16 @@ PcapDeviceHandler^ PcapOfflineDevice::Open(int snapLen, PcapDeviceOpenFlags flag
// Create the source string according to the new WinPcap syntax // Create the source string according to the new WinPcap syntax
char source[PCAP_BUF_SIZE]; char source[PCAP_BUF_SIZE];
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
if ( pcap_createsrcstr( source, // variable that will keep the source string if (pcap_createsrcstr(source, // variable that will keep the source string
PCAP_SRC_FILE, // we want to open a file PCAP_SRC_FILE, // we want to open a file
NULL, // remote host NULL, // remote host
NULL, // port on the remote host NULL, // port on the remote host
unamangedFilename.c_str(), // name of the file we want to open unamangedFilename.c_str(), // name of the file we want to open
errbuf // error buffer errbuf // error buffer
) != 0) ) != 0)
{ {
throw gcnew InvalidOperationException("Error creating a source string from filename " + _filename + " Error: " + gcnew String(errbuf)); throw gcnew InvalidOperationException("Error creating a source string from filename " + _filename + " Error: " + gcnew String(errbuf));
} }
pcap_t *adhandle;
/* Open the capture file */
adhandle = pcap_open(source, // name of the device
snapLen, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
safe_cast<int>(flags), // promiscuous mode
readTimeout, // read timeout
NULL, // authentication on the remote machine
errbuf); // error buffer
if (adhandle == NULL) return gcnew PcapDeviceHandler(source, snapLen, flags, readTimeout, NULL, nullptr);
{
gcnew InvalidOperationException(String::Format("Unable to open the adapter. %s is not supported by WinPcap", Name));
}
return gcnew PcapDeviceHandler(adhandle, nullptr);
} }
#include "PcapStatistics.h"
using namespace System;
using namespace PcapDotNet;
PcapStatistics::PcapStatistics(DateTime timestamp, unsigned long acceptedPackets, unsigned long acceptedBytes)
{
_timestamp = timestamp;
_acceptedPackets = acceptedPackets;
_acceptedBytes = acceptedBytes;
}
DateTime PcapStatistics::Timestamp::get()
{
return _timestamp;
}
unsigned long PcapStatistics::AcceptedPackets::get()
{
return _acceptedPackets;
}
unsigned long PcapStatistics::AcceptedBytes::get()
{
return _acceptedBytes;
}
System::String^ PcapStatistics::ToString()
{
return _timestamp + ": " + AcceptedPackets + " packets. " + AcceptedBytes + " bytes.";
}
\ No newline at end of file
#pragma once
namespace PcapDotNet
{
public ref class PcapStatistics
{
public:
PcapStatistics(System::DateTime timestamp, unsigned long acceptedPackets, unsigned long acceptedBytes);
property System::DateTime Timestamp
{
System::DateTime get();
}
property unsigned long AcceptedPackets
{
unsigned long get();
}
property unsigned long AcceptedBytes
{
unsigned long get();
}
virtual System::String^ ToString() override;
private:
System::DateTime _timestamp;
unsigned long _acceptedPackets;
unsigned long _acceptedBytes;
};
}
\ No newline at end of file
...@@ -262,6 +262,10 @@ ...@@ -262,6 +262,10 @@
RelativePath=".\PcapDeviceHandler.h" RelativePath=".\PcapDeviceHandler.h"
> >
</File> </File>
<File
RelativePath=".\PcapDeviceOpenFlags.h"
>
</File>
<File <File
RelativePath=".\PcapDumpFile.cpp" RelativePath=".\PcapDumpFile.cpp"
> >
...@@ -294,6 +298,14 @@ ...@@ -294,6 +298,14 @@
RelativePath=".\PcapSendQueue.h" RelativePath=".\PcapSendQueue.h"
> >
</File> </File>
<File
RelativePath=".\PcapStatistics.cpp"
>
</File>
<File
RelativePath=".\PcapStatistics.h"
>
</File>
<File <File
RelativePath=".\Timestamp.cpp" RelativePath=".\Timestamp.cpp"
> >
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment