From 931e8f2a3d2e3714ceed7f071de24805b8a3e535 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Klaus=20N=C3=B6ske?=
<40196862+klaus0x7c4@users.noreply.github.com>
Date: Sat, 28 Dec 2024 12:46:15 +0100
Subject: [PATCH] Improve/fix error buffer handling for native pcap methods
Credit to @trivalik
See: https://github.com/klaus0x7c4/Pcap.Net/pull/2
and: https://github.com/dotpcap/sharppcap/pull/533
---
.../src/PcapDotNet.Core/Native/IPcapPal.cs | 41 +++++-----
.../src/PcapDotNet.Core/Native/PcapUnixPal.cs | 78 ++++++++++--------
.../Native/PcapUnmanagedStructures.cs | 27 +++++-
.../PcapDotNet.Core/Native/PcapWindowsPal.cs | 82 +++++++++++--------
.../LivePacketCommunicator.cs | 5 +-
.../OfflinePacketCommunicator.cs | 3 +-
.../PacketCommunicator/PacketCommunicator.cs | 8 +-
PcapDotNet/src/PcapDotNet.Core/Pcap.cs | 7 --
8 files changed, 142 insertions(+), 109 deletions(-)
diff --git a/PcapDotNet/src/PcapDotNet.Core/Native/IPcapPal.cs b/PcapDotNet/src/PcapDotNet.Core/Native/IPcapPal.cs
index 0b098463..b07ecd6b 100644
--- a/PcapDotNet/src/PcapDotNet.Core/Native/IPcapPal.cs
+++ b/PcapDotNet/src/PcapDotNet.Core/Native/IPcapPal.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.InteropServices;
using System.Text;
using PcapDotNet.Packets;
using static PcapDotNet.Core.Native.PcapUnmanagedStructures;
@@ -18,7 +19,7 @@ internal interface IPcapPal
///
/// Creates a platform depend pcap packet header.handle
///
- /// MUST be freed with Marshal.FreeHCGlobal!
+ /// MUST be freed with !
/// Pointer to the header structure
IntPtr CreatePcapPacketHeaderHandle(Packet packet);
@@ -34,7 +35,7 @@ internal interface IPcapPal
PacketTotalStatistics GetTotalStatistics(PcapHandle pcapDescriptor);
- int pcap_findalldevs(ref PcapInterfaceHandle /* pcap_if_t** */ alldevs, StringBuilder /* char* */ errbuf);
+ int pcap_findalldevs(ref PcapInterfaceHandle /* pcap_if_t** */ alldevs, out string /* char* */ errbuf);
void pcap_freealldevs(IntPtr /* pcap_if_t * */ alldevs);
@@ -49,11 +50,11 @@ internal interface IPcapPal
int flags,
int read_timeout,
ref pcap_rmtauth rmtauth,
- StringBuilder errbuf);
+ out string errbuf);
- PcapHandle /* pcap_t* */ pcap_create(string dev, StringBuilder errbuf);
+ PcapHandle /* pcap_t* */ pcap_create(string dev, out string errbuf);
- PcapHandle /* pcap_t* */ pcap_open_offline(string/*const char* */ fname, StringBuilder/* char* */ errbuf);
+ PcapHandle /* pcap_t* */ pcap_open_offline(string/*const char* */ fname, out string /* char* */ errbuf);
///
@@ -154,54 +155,54 @@ internal interface IPcapPal
///
/// Is used to get a list of the supported link-layer header types of the interface associated with the pcap descriptor. pcap_list_datalinks() allocates an array to hold the list and sets *dataLinkList to point to that array.
/// The caller is responsible for freeing the array with pcap_free_datalinks(), which frees the list of link-layer header types pointed to by dataLinkList.
- /// It must not be called on a pcap descriptor created by pcap_create(3PCAP) that has not yet been activated by pcap_activate(3PCAP).
+ /// It must not be called on a pcap descriptor created by pcap_create(3PCAP) that has not yet been activated by pcap_activate(3PCAP).
///
/// list of link-layer header types supported by a capture device
/// The number of link-layer header types in the array on success, PCAP_ERROR_NOT_ACTIVATED if called on a capture handle that has been created but not activated, and PCAP_ERROR on other errors. If PCAP_ERROR is returned, pcap_geterr(3PCAP) or pcap_perror(3PCAP) may be called with p as an argument to fetch or display the error text.
int pcap_list_datalinks(PcapHandle /* pcap_t* */ adaptHandle, ref IntPtr /* int** */ dataLinkList);
///
- /// Frees the list of link-layer header types pointed to by dataLinkList.
+ /// Frees the list of link-layer header types pointed to by dataLinkList.
///
void pcap_free_datalinks(IntPtr /* int* */ dataLinkList);
///
/// Get the link-layer header type value corresponding to a header type name.
- /// Translates a link-layer header type name, which is a DLT_ name with the DLT_ removed,
+ /// Translates a link-layer header type name, which is a DLT_ name with the DLT_ removed,
/// to the corresponding link-layer header type value.The translation is case-insensitive.
///
/// Returns the type value on success and PCAP_ERROR if the name is not a known type name.
int pcap_datalink_name_to_val(string /*const char* */ name);
///
- /// Translates a link-layer header type value to the corresponding link-layer header type name,
- /// which is the DLT_ name for the link-layer header type value with the DLT_ removed.
- /// NULL is returned if the type value does not correspond to a known DLT_ value.
+ /// Translates a link-layer header type value to the corresponding link-layer header type name,
+ /// which is the DLT_ name for the link-layer header type value with the DLT_ removed.
+ /// NULL is returned if the type value does not correspond to a known DLT_ value.
///
string /* const char* */ pcap_datalink_val_to_name(int dlt);
///
- /// Translates a link-layer header type value to a short description of that link-layer header type.
- /// NULL is returned if the type value does not correspond to a known DLT_ value.
+ /// Translates a link-layer header type value to a short description of that link-layer header type.
+ /// NULL is returned if the type value does not correspond to a known DLT_ value.
///
string /* const char* */ pcap_datalink_val_to_description(int dlt);
///
/// Translates a link-layer header type value to a short description of that link-layer header type
- /// just like pcap_datalink_val_to_description. If the type value does not correspond to a known DLT_ value,
- /// the string "DLT n" is returned, where n is the value of the dlt argument.
+ /// just like pcap_datalink_val_to_description. If the type value does not correspond to a known DLT_ value,
+ /// the string "DLT n" is returned, where n is the value of the dlt argument.
///
string /* const char* */ pcap_datalink_val_to_description_or_dlt(int dlt);
///
/// Set nonblocking mode. pcap_loop() and pcap_next() doesnt work in nonblocking mode!
///
- int pcap_setnonblock(PcapHandle /* pcap_t* */ adaptHandle, int nonblock, StringBuilder /* char* */ errbuf);
+ int pcap_setnonblock(PcapHandle /* pcap_t* */ adaptHandle, int nonblock, out string /* char* */ errbuf);
///
/// Get nonblocking mode, returns allways 0 for savefiles.
///
- int pcap_getnonblock(PcapHandle /* pcap_t* */ adaptHandle, StringBuilder /* char* */ errbuf);
+ int pcap_getnonblock(PcapHandle /* pcap_t* */ adaptHandle, out string /* char* */ errbuf);
///
/// Read packets until cnt packets are processed or an error occurs.
@@ -237,7 +238,7 @@ internal interface IPcapPal
int pcap_snapshot(PcapHandle /* pcap_t* */ adapter);
///
- /// find out whether a 'savefile' has the native byte order
+ /// find out whether a 'savefile' has the native byte order
///
///
/// returns true (1) if p refers to a 'savefile' that uses a different byte order than the current system. For a live capture, it always returns false (0). Returns PCAP_ERROR_NOT_ACTIVATED if called on a capture handle that has been created but not activated.
@@ -245,7 +246,7 @@ internal interface IPcapPal
int pcap_is_swapped(PcapHandle /* pcap_t* */ adapter);
///
- /// The version number of a 'savefile'
+ /// The version number of a 'savefile'
///
/// The major number of the file format of the 'savefile'
///
@@ -255,7 +256,7 @@ internal interface IPcapPal
int pcap_major_version(PcapHandle /* pcap_t* */ adapter);
///
- /// The version number of a 'savefile'
+ /// The version number of a 'savefile'
///
/// The minor number of the file format of the 'savefile'
///
diff --git a/PcapDotNet/src/PcapDotNet.Core/Native/PcapUnixPal.cs b/PcapDotNet/src/PcapDotNet.Core/Native/PcapUnixPal.cs
index 4d8a5170..c7f6d376 100644
--- a/PcapDotNet/src/PcapDotNet.Core/Native/PcapUnixPal.cs
+++ b/PcapDotNet/src/PcapDotNet.Core/Native/PcapUnixPal.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
@@ -45,12 +45,10 @@ public virtual unsafe PcapPacketHeader CreatePcapPacketHeader(IntPtr /* pcap_pkt
public PcapInterfaceHandle GetAllLocalMachine()
{
var handle = new PcapInterfaceHandle();
- var errorBuffer = Pcap.CreateErrorBuffer();
-
- var result = pcap_findalldevs(ref handle, errorBuffer);
+ var result = pcap_findalldevs(ref handle, out var errorBuffer);
if (result < 0)
{
- PcapError.ThrowInvalidOperation("Failed getting devices. Error: " + errorBuffer.ToString(), null);
+ PcapError.ThrowInvalidOperation($"Failed getting devices. Error: {errorBuffer}", null);
}
return handle;
}
@@ -95,9 +93,11 @@ public int pcap_compile(PcapHandle adaptHandle, IntPtr fp, string str, int optim
return SafeNativeMethods.pcap_compile(adaptHandle, fp, str, optimize, netmask);
}
- public PcapHandle pcap_create(string dev, StringBuilder errbuf)
+ public PcapHandle pcap_create(string dev, out string errbuf)
{
- return SafeNativeMethods.pcap_create(dev, errbuf);
+ var result = SafeNativeMethods.pcap_create(dev, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public int pcap_datalink(PcapHandle adaptHandle)
@@ -165,9 +165,11 @@ public int pcap_fileno(PcapHandle adapter)
return SafeNativeMethods.pcap_fileno(adapter);
}
- public int pcap_findalldevs(ref PcapInterfaceHandle alldevs, StringBuilder errbuf)
+ public int pcap_findalldevs(ref PcapInterfaceHandle alldevs, out string errbuf)
{
- return SafeNativeMethods.pcap_findalldevs(ref alldevs, errbuf);
+ var result = SafeNativeMethods.pcap_findalldevs(ref alldevs, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public void pcap_freealldevs(IntPtr alldevs)
@@ -185,9 +187,11 @@ public string pcap_geterr(PcapHandle adaptHandle)
return SafeNativeMethods.pcap_geterr(adaptHandle);
}
- public int pcap_getnonblock(PcapHandle adaptHandle, StringBuilder errbuf)
+ public int pcap_getnonblock(PcapHandle adaptHandle, out string errbuf)
{
- return SafeNativeMethods.pcap_getnonblock(adaptHandle, errbuf);
+ var result = SafeNativeMethods.pcap_getnonblock(adaptHandle, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public int pcap_get_selectable_fd(PcapHandle adaptHandle)
@@ -210,9 +214,11 @@ public int pcap_offline_filter(IntPtr prog, IntPtr header, IntPtr pkt_data)
return SafeNativeMethods.pcap_offline_filter(prog, header, pkt_data);
}
- public PcapHandle pcap_open(string dev, int packetLen, int flags, int read_timeout, ref pcap_rmtauth rmtauth, StringBuilder errbuf)
+ public PcapHandle pcap_open(string dev, int packetLen, int flags, int read_timeout, ref pcap_rmtauth rmtauth, out string errbuf)
{
- return SafeNativeMethods.pcap_open(dev, packetLen, flags, read_timeout, ref rmtauth, errbuf);
+ var result = SafeNativeMethods.pcap_open(dev, packetLen, flags, read_timeout, ref rmtauth, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public PcapHandle pcap_open_dead(int linktype, int snaplen)
@@ -220,9 +226,11 @@ public PcapHandle pcap_open_dead(int linktype, int snaplen)
return SafeNativeMethods.pcap_open_dead(linktype, snaplen);
}
- public PcapHandle pcap_open_offline(string fname, StringBuilder errbuf)
+ public PcapHandle pcap_open_offline(string fname, out string errbuf)
{
- return SafeNativeMethods.pcap_open_offline(fname, errbuf);
+ var result = SafeNativeMethods.pcap_open_offline(fname, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public int pcap_sendpacket(PcapHandle adaptHandle, IntPtr data, int size)
@@ -235,9 +243,11 @@ public int pcap_setfilter(PcapHandle adaptHandle, IntPtr fp)
return SafeNativeMethods.pcap_setfilter(adaptHandle, fp);
}
- public int pcap_setnonblock(PcapHandle adaptHandle, int nonblock, StringBuilder errbuf)
+ public int pcap_setnonblock(PcapHandle adaptHandle, int nonblock, out string errbuf)
{
- return SafeNativeMethods.pcap_setnonblock(adaptHandle, nonblock, errbuf);
+ var result = SafeNativeMethods.pcap_setnonblock(adaptHandle, nonblock, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public int pcap_set_buffer_size(PcapHandle adapter, int bufferSizeInBytes)
@@ -351,7 +361,7 @@ private static class SafeNativeMethods
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_findalldevs(
ref PcapInterfaceHandle /* pcap_if_t** */ alldevs,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder /* char* */ errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static void pcap_freealldevs(IntPtr /* pcap_if_t* */ alldevs);
@@ -363,17 +373,17 @@ internal extern static int pcap_findalldevs(
int flags,
int read_timeout,
ref pcap_rmtauth rmtauth,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static PcapHandle /* pcap_t* */ pcap_create(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] string dev,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static PcapHandle /* pcap_t* */ pcap_open_offline(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] string/*const char* */ fname,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder/* char* */ errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static PcapHandle /* pcap_t* */ pcap_open_dead(int linktype, int snaplen);
@@ -388,7 +398,7 @@ internal extern static int pcap_findalldevs(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] string /*const char * */fname);
///
- /// Save a packet to disk.
+ /// Save a packet to disk.
///
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static void pcap_dump(IntPtr /*u_char * */user, IntPtr /*const struct pcap_pkthdr * */h, IntPtr /*const u_char * */sp);
@@ -405,7 +415,7 @@ internal extern static int pcap_findalldevs(
///
/// Send a raw packet.
- /// This function allows to send a raw packet to the network.
+ /// This function allows to send a raw packet to the network.
/// The MAC CRC doesn't need to be included, because it is transparently calculated
/// and added by the network interface driver.
///
@@ -417,7 +427,7 @@ internal extern static int pcap_findalldevs(
internal extern static int pcap_sendpacket(PcapHandle /* pcap_t* */ adaptHandle, IntPtr data, int size);
///
- /// Compile a packet filter, converting an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine.
+ /// Compile a packet filter, converting an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine.
///
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_compile(
@@ -431,7 +441,7 @@ internal extern static int pcap_compile(
internal extern static int pcap_setfilter(PcapHandle /* pcap_t* */ adaptHandle, IntPtr /*bpf_program **/fp);
///
- /// Returns if a given filter applies to an offline packet.
+ /// Returns if a given filter applies to an offline packet.
///
///
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
@@ -459,8 +469,8 @@ internal extern static int pcap_compile(
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static IntPtr /*FILE **/ pcap_dump_file(IntPtr /*pcap_dumper_t **/p);
- /// Flushes the output buffer to the 'savefile', so that any packets
- /// written with pcap_dump() but not yet written to the 'savefile' will be written.
+ /// Flushes the output buffer to the 'savefile', so that any packets
+ /// written with pcap_dump() but not yet written to the 'savefile' will be written.
/// -1 is returned on error, 0 on success.
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_dump_flush(IntPtr /*pcap_dumper_t **/p);
@@ -499,7 +509,7 @@ internal extern static int pcap_datalink_name_to_val(
internal extern static int pcap_setnonblock(
PcapHandle /* pcap_if_t** */ adaptHandle,
int nonblock,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder /* char* */ errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
///
/// Get nonblocking mode, returns allways 0 for savefiles.
@@ -507,7 +517,7 @@ internal extern static int pcap_setnonblock(
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_getnonblock(
PcapHandle /* pcap_if_t** */ adaptHandle,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder /* char* */ errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
///
/// Read packets until cnt packets are processed or an error occurs.
@@ -536,22 +546,22 @@ internal extern static int pcap_getnonblock(
///
/// pcap_set_rfmon() sets whether monitor mode should be set on a capture handle when the handle is activated.
- /// If rfmon is non-zero, monitor mode will be set, otherwise it will not be set.
+ /// If rfmon is non-zero, monitor mode will be set, otherwise it will not be set.
///
/// Returns 0 on success or PCAP_ERROR_ACTIVATED if called on a capture handle that has been activated.
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_set_rfmon(PcapHandle /* pcap_t* */ p, int rfmon);
///
- /// pcap_set_snaplen() sets the snapshot length to be used on a capture handle when the handle is activated to snaplen.
+ /// pcap_set_snaplen() sets the snapshot length to be used on a capture handle when the handle is activated to snaplen.
///
/// Returns 0 on success or PCAP_ERROR_ACTIVATED if called on a capture handle that has been activated.
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_set_snaplen(PcapHandle /* pcap_t* */ p, int snaplen);
///
- /// pcap_set_promisc() sets whether promiscuous mode should be set on a capture handle when the handle is activated.
- /// If promisc is non-zero, promiscuous mode will be set, otherwise it will not be set.
+ /// pcap_set_promisc() sets whether promiscuous mode should be set on a capture handle when the handle is activated.
+ /// If promisc is non-zero, promiscuous mode will be set, otherwise it will not be set.
///
/// Returns 0 on success or PCAP_ERROR_ACTIVATED if called on a capture handle that has been activated.
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
@@ -591,4 +601,4 @@ internal extern static int pcap_getnonblock(
#endregion
}
}
-}
\ No newline at end of file
+}
diff --git a/PcapDotNet/src/PcapDotNet.Core/Native/PcapUnmanagedStructures.cs b/PcapDotNet/src/PcapDotNet.Core/Native/PcapUnmanagedStructures.cs
index 23053627..9dcda87f 100644
--- a/PcapDotNet/src/PcapDotNet.Core/Native/PcapUnmanagedStructures.cs
+++ b/PcapDotNet/src/PcapDotNet.Core/Native/PcapUnmanagedStructures.cs
@@ -1,4 +1,4 @@
-/*
+/*
This file is part of SharpPcap.
SharpPcap is free software: you can redistribute it and/or modify
@@ -21,6 +21,7 @@ You should have received a copy of the GNU Lesser General Public License
using System;
using System.Runtime.InteropServices;
+using System.Text;
namespace PcapDotNet.Core.Native
{
@@ -375,8 +376,30 @@ public struct pcap_samp
///
public int value;
};
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct PcapErrorBuffer
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = Pcap.PCAP_ERRBUF_SIZE)]
+ internal byte[] Data;
+
+ public override string ToString()
+ {
+ return ToString(Interop.Pcap.StringEncoding);
+ }
+
+ public string ToString(Encoding encoding)
+ {
+ var nbBytes = 0;
+ while (Data[nbBytes] != 0)
+ {
+ nbBytes++;
+ }
+ return encoding.GetString(Data, 0, nbBytes);
+ }
+ }
#endregion Unmanaged Structs Implementation
}
#pragma warning restore IDE1006 // Naming Styles
-}
\ No newline at end of file
+}
diff --git a/PcapDotNet/src/PcapDotNet.Core/Native/PcapWindowsPal.cs b/PcapDotNet/src/PcapDotNet.Core/Native/PcapWindowsPal.cs
index 3efeb79b..5d4ef3d9 100644
--- a/PcapDotNet/src/PcapDotNet.Core/Native/PcapWindowsPal.cs
+++ b/PcapDotNet/src/PcapDotNet.Core/Native/PcapWindowsPal.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
@@ -21,14 +21,15 @@ private static Encoding ConfigureStringEncoding()
try
{
// Try to change Libpcap to UTF-8 mode
- var errorBuffer = Pcap.CreateErrorBuffer();
const uint PCAP_CHAR_ENC_UTF_8 = 1;
- var res = SafeNativeMethods.pcap_init(PCAP_CHAR_ENC_UTF_8, errorBuffer);
+ var res = SafeNativeMethods.pcap_init(PCAP_CHAR_ENC_UTF_8, out var errorBuffer);
if (res == 0)
{
// We made it
return Encoding.UTF8;
}
+
+ throw new InvalidOperationException($"Failed to set pcap_init to UTF-8. Error: {errorBuffer.ToString(Encoding.Default)} ({res})");
}
catch (TypeLoadException)
{
@@ -71,13 +72,12 @@ public unsafe PcapPacketHeader CreatePcapPacketHeader(IntPtr /* pcap_pkthdr* */
public PcapInterfaceHandle GetAllLocalMachine()
{
var handle = new PcapInterfaceHandle();
- var errorBuffer = Pcap.CreateErrorBuffer();
var auth = default(pcap_rmtauth); //auth is not needed
- var result = pcap_findalldevs_ex(Pcap.PCAP_SRC_IF_STRING, ref auth, ref handle, errorBuffer);
+ var result = pcap_findalldevs_ex(Pcap.PCAP_SRC_IF_STRING, ref auth, ref handle, out var errbuf);
if (result < 0)
{
- PcapError.ThrowInvalidOperation("Failed getting devices. Error: " + errorBuffer.ToString(), null);
+ PcapError.ThrowInvalidOperation($"Failed getting devices. Error: {errbuf}", null);
}
return handle;
}
@@ -112,9 +112,11 @@ public int pcap_compile(PcapHandle adaptHandle, IntPtr fp, string str, int optim
return SafeNativeMethods.pcap_compile(adaptHandle, fp, str, optimize, netmask);
}
- public PcapHandle pcap_create(string dev, StringBuilder errbuf)
+ public PcapHandle pcap_create(string dev, out string errbuf)
{
- return SafeNativeMethods.pcap_create(dev, errbuf);
+ var result = SafeNativeMethods.pcap_create(dev, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public int pcap_datalink(PcapHandle adaptHandle)
@@ -182,14 +184,18 @@ public int pcap_fileno(PcapHandle adapter)
return SafeNativeMethods.pcap_fileno(adapter);
}
- public int pcap_findalldevs(ref PcapInterfaceHandle alldevs, StringBuilder errbuf)
+ public int pcap_findalldevs(ref PcapInterfaceHandle alldevs, out string errbuf)
{
- return SafeNativeMethods.pcap_findalldevs(ref alldevs, errbuf);
+ var result = SafeNativeMethods.pcap_findalldevs(ref alldevs, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
- public int pcap_findalldevs_ex(string source, ref pcap_rmtauth auth, ref PcapInterfaceHandle alldevs, StringBuilder errbuf)
+ public int pcap_findalldevs_ex(string source, ref pcap_rmtauth auth, ref PcapInterfaceHandle alldevs, out string errbuf)
{
- return SafeNativeMethods.pcap_findalldevs_ex(source, ref auth, ref alldevs, errbuf);
+ var result = SafeNativeMethods.pcap_findalldevs_ex(source, ref auth, ref alldevs, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public void pcap_freealldevs(IntPtr alldevs)
@@ -207,9 +213,11 @@ public string pcap_geterr(PcapHandle adaptHandle)
return SafeNativeMethods.pcap_geterr(adaptHandle);
}
- public int pcap_getnonblock(PcapHandle adaptHandle, StringBuilder errbuf)
+ public int pcap_getnonblock(PcapHandle adaptHandle, out string errbuf)
{
- return SafeNativeMethods.pcap_getnonblock(adaptHandle, errbuf);
+ var result = SafeNativeMethods.pcap_getnonblock(adaptHandle, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public int pcap_get_selectable_fd(PcapHandle adaptHandle)
@@ -232,9 +240,11 @@ public int pcap_offline_filter(IntPtr prog, IntPtr header, IntPtr pkt_data)
return SafeNativeMethods.pcap_offline_filter(prog, header, pkt_data);
}
- public PcapHandle pcap_open(string dev, int packetLen, int flags, int read_timeout, ref pcap_rmtauth rmtauth, StringBuilder errbuf)
+ public PcapHandle pcap_open(string dev, int packetLen, int flags, int read_timeout, ref pcap_rmtauth rmtauth, out string errbuf)
{
- return SafeNativeMethods.pcap_open(dev, packetLen, flags, read_timeout, ref rmtauth, errbuf);
+ var handle = SafeNativeMethods.pcap_open(dev, packetLen, flags, read_timeout, ref rmtauth, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return handle;
}
public PcapHandle pcap_open_dead(int linktype, int snaplen)
@@ -242,9 +252,11 @@ public PcapHandle pcap_open_dead(int linktype, int snaplen)
return SafeNativeMethods.pcap_open_dead(linktype, snaplen);
}
- public PcapHandle pcap_open_offline(string fname, StringBuilder errbuf)
+ public PcapHandle pcap_open_offline(string fname, out string errbuf)
{
- return SafeNativeMethods.pcap_open_offline(fname, errbuf);
+ var result = SafeNativeMethods.pcap_open_offline(fname, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public int pcap_sendpacket(PcapHandle adaptHandle, IntPtr data, int size)
@@ -257,9 +269,11 @@ public int pcap_setfilter(PcapHandle adaptHandle, IntPtr fp)
return SafeNativeMethods.pcap_setfilter(adaptHandle, fp);
}
- public int pcap_setnonblock(PcapHandle adaptHandle, int nonblock, StringBuilder errbuf)
+ public int pcap_setnonblock(PcapHandle adaptHandle, int nonblock, out string errbuf)
{
- return SafeNativeMethods.pcap_setnonblock(adaptHandle, nonblock, errbuf);
+ var result = SafeNativeMethods.pcap_setnonblock(adaptHandle, nonblock, out var errorBuffer);
+ errbuf = errorBuffer.ToString();
+ return result;
}
public int pcap_set_buffer_size(PcapHandle adapter, int bufferSizeInBytes)
@@ -358,7 +372,7 @@ public int pcap_sendqueue_transmit(PcapHandle p, ref pcap_send_queue queue, int
}
///
- /// Per http://msdn.microsoft.com/en-us/ms182161.aspx
+ /// Per http://msdn.microsoft.com/en-us/ms182161.aspx
///
[SuppressUnmanagedCodeSecurity]
private static class SafeNativeMethods
@@ -375,21 +389,17 @@ static SafeNativeMethods()
}
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
- internal extern static int pcap_init(
- uint opts,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder /* char* */ errbuf);
+ internal static extern int pcap_init(uint opts, out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
- internal extern static int pcap_findalldevs(
- ref PcapInterfaceHandle /* pcap_if_t** */ alldevs,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder /* char* */ errbuf);
+ internal extern static int pcap_findalldevs(ref PcapInterfaceHandle /* pcap_if_t** */ alldevs, out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_findalldevs_ex(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] string /* char* */source,
ref pcap_rmtauth /* pcap_rmtauth* */auth,
ref PcapInterfaceHandle /* pcap_if_t** */alldevs,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder /* char* */errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static void pcap_freealldevs(IntPtr /* pcap_if_t* */ alldevs);
@@ -397,7 +407,7 @@ internal extern static int pcap_findalldevs_ex(
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static PcapHandle /* pcap_t* */ pcap_create(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] string dev,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static PcapHandle /* pcap_t* */ pcap_open(
@@ -406,12 +416,12 @@ internal extern static int pcap_findalldevs_ex(
int flags,
int read_timeout,
ref pcap_rmtauth rmtauth,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static PcapHandle /* pcap_t* */ pcap_open_offline(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] string/* const char* */ fname,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder/* char* */ errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static PcapHandle /* pcap_t* */ pcap_open_dead(int linktype, int snaplen);
@@ -535,17 +545,17 @@ internal extern static int pcap_datalink_name_to_val(
///
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_setnonblock(
- PcapHandle /* pcap_if_t** */ adaptHandle,
+ PcapHandle /* pcap_t* */ adaptHandle,
int nonblock,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder /* char* */ errbuf);
+ out PcapErrorBuffer /* char* */ errbuf);
///
/// Get nonblocking mode, returns allways 0 for savefiles.
///
[DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)]
internal extern static int pcap_getnonblock(
- PcapHandle /* pcap_if_t** */ adaptHandle,
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder /* char* */ errbuf);
+ PcapHandle /* pcap_t* */ adaptHandle,
+ out PcapErrorBuffer /* char* */ errbuf);
///
/// Read packets until cnt packets are processed or an error occurs.
@@ -693,4 +703,4 @@ internal extern static int pcap_getnonblock(
#endregion
}
}
-}
\ No newline at end of file
+}
diff --git a/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/LivePacketCommunicator.cs b/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/LivePacketCommunicator.cs
index 34b49e10..e68ed445 100644
--- a/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/LivePacketCommunicator.cs
+++ b/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/LivePacketCommunicator.cs
@@ -1,4 +1,4 @@
-using PcapDotNet.Core.Native;
+using PcapDotNet.Core.Native;
using System;
namespace PcapDotNet.Core
@@ -55,7 +55,6 @@ public override void Transmit(PacketSendBuffer sendBuffer, bool isSync)
private static PcapHandle PcapOpen(string source, int snapshotLength, PacketDeviceOpenAttributes attributes, int readTimeout, PcapUnmanagedStructures.pcap_rmtauth auth)
{
- var errorBuffer = Pcap.CreateErrorBuffer();
var handle = Interop.Pcap.pcap_open(
source, // name of the device
snapshotLength, // portion of the packet to capture
@@ -63,7 +62,7 @@ private static PcapHandle PcapOpen(string source, int snapshotLength, PacketDevi
(int)attributes,
readTimeout,
ref auth, // authentication on the remote machine
- errorBuffer);
+ out var errorBuffer);
if (handle.IsInvalid)
{
diff --git a/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/OfflinePacketCommunicator.cs b/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/OfflinePacketCommunicator.cs
index 2a0d9fc9..48b5f79e 100644
--- a/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/OfflinePacketCommunicator.cs
+++ b/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/OfflinePacketCommunicator.cs
@@ -40,8 +40,7 @@ private static PcapHandle OpenFile(string fileName)
// ToDo: This is currently still very simplified
// compared to the original native version. Still needs to be revised.
- var errorBuffer = Pcap.CreateErrorBuffer();
- var handle = Interop.Pcap.pcap_open_offline(fileName, errorBuffer);
+ var handle = Interop.Pcap.pcap_open_offline(fileName, out var errorBuffer);
if(handle.IsInvalid)
{
PcapError.ThrowInvalidOperation($"Failed opening file {fileName}. Error: {errorBuffer}.", null);
diff --git a/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/PacketCommunicator.cs b/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/PacketCommunicator.cs
index d54ae8fc..9073daa1 100644
--- a/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/PacketCommunicator.cs
+++ b/PcapDotNet/src/PcapDotNet.Core/PacketCommunicator/PacketCommunicator.cs
@@ -172,18 +172,16 @@ public bool NonBlocking
{
get
{
- var errorBuffer = Pcap.CreateErrorBuffer();
- var nonBlockValue = Interop.Pcap.pcap_getnonblock(PcapDescriptor, errorBuffer);
+ var nonBlockValue = Interop.Pcap.pcap_getnonblock(PcapDescriptor, out var errorBuffer);
if (nonBlockValue < 0)
{
- ThrowInvalidOperation("Error getting NonBlocking value: " + errorBuffer.ToString());
+ ThrowInvalidOperation("Error getting NonBlocking value: " + errorBuffer);
}
return nonBlockValue != 0;
}
set
{
- var errorBuffer = Pcap.CreateErrorBuffer();
- if (Interop.Pcap.pcap_setnonblock(PcapDescriptor, value ? 1 : 0, errorBuffer) < 0)
+ if (Interop.Pcap.pcap_setnonblock(PcapDescriptor, value ? 1 : 0, out var errorBuffer) < 0)
{
ThrowInvalidOperation($"Error setting NonBlocking to {value}: {errorBuffer}");
}
diff --git a/PcapDotNet/src/PcapDotNet.Core/Pcap.cs b/PcapDotNet/src/PcapDotNet.Core/Pcap.cs
index 16b3f131..232ca9fd 100644
--- a/PcapDotNet/src/PcapDotNet.Core/Pcap.cs
+++ b/PcapDotNet/src/PcapDotNet.Core/Pcap.cs
@@ -1,5 +1,3 @@
-using System.Text;
-
namespace PcapDotNet.Core
{
///
@@ -45,10 +43,5 @@ public class Pcap
/// interface isn't up
internal const int PCAP_ERROR_IFACE_NOT_UP = -9;
#endregion
-
- internal static StringBuilder CreateErrorBuffer()
- {
- return new StringBuilder(PCAP_ERRBUF_SIZE);
- }
}
}