由于SharpPcap项目声称与Mono兼容,我决定让我的项目在Mac上运行。
为此,我必须将WinPcapDevice
设为LibPcapLiveDevice
并将WinPcap.dll
映射到libpcap.dylib
。
SharpPcap.dll.config:
<configuration>
<dllmap dll="wpcap" target="libpcap.1.6.2.dylib" />
</configuration>
代码:
private static string GetFilterString(ICaptureDevice captureDevice)
{
var device = (LibPcapLiveDevice) captureDevice;
return String.Format("((tcp dst port 80) and (src net {0})) or ((dst net {0}) and (tcp src port 80))", device.Addresses[1]);
}
问题是,属性device.Addresses
是空的,我找不到任何其他包含IP地址的属性。实际上除了设备名称和MAC地址之外,几乎所有属性都是空的。
我不确定这是由SharpPcap或Libpcap引起的问题。
修改
正如Guy Harris建议我将PcapUnmanagedStructures.cs
中使用的结构和类型与Apple OS参考文档进行比较。我尝试调整它们,因此它们符合操作系统的规范:
[StructLayout(LayoutKind.Sequential)]
public struct sockaddr
{
public byte sa_family; /* address family */
[MarshalAs(UnmanagedType.ByValArray, SizeConst=14)]
public byte[] sa_data; /* 14 bytes of protocol address */
};
public struct in_addr
{
public UInt32 s_addr; //in_addr_t
}
[StructLayout(LayoutKind.Sequential)]
public struct sockaddr_in
{
public byte sa_family; /* address family */
public UInt16 sa_port; /* port */
public in_addr sin_addr; /* address */
// char sin_zero[8]; not sure this whether to add this as it was contained in the doc
// pad the size of sockaddr_in out to 16 bytes
MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
// Disable warnings around this unused field
#pragma warning disable 0169
private byte[] pad; // not sure about this one either
#pragma warning restore 0169
};
[StructLayout(LayoutKind.Sequential)]
internal struct sockaddr_in6
{
public byte sin6_family; /* address family */
public UInt16 sin6_port; /* Transport layer port # */
public UInt32 sin6_flowinfo; /* IPv6 flow information */
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)] // raised it to 32 as the struct in6_addr contains an element of type __uint32_t
public byte[] sin6_addr; /* IPv6 address */
public UInt32 sin6_scope_id; /* scope id (new in RFC2553) */
};
我不确定我做得对,因为ipAddress
仍然是空的:
编辑2
盖伊·哈里斯对那个长场非常正确。这对我现在有用:
[StructLayout(LayoutKind.Sequential)]
public struct sockaddr
{
public byte sa_len;
public byte sa_family;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=14)]
public byte[] sa_data;
};
public struct in_addr
{
public UInt32 s_addr;
}
[StructLayout(LayoutKind.Sequential)]
public struct sockaddr_in
{
public byte sin_len;
public byte sin_family;
public UInt16 sin_port;
public in_addr sin_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
public byte sin_zero;
};
请注意,我还将某个字段的名称前缀从sa
更改为sin
。我还将pad
的名称更改为sin_zero
。毕竟很容易。
答案 0 :(得分:1)
好吧,我不熟悉C#,但是,如果PcapUnmanagedStructures.cs试图描述操作系统的本机C 结构的布局,那些声明不正确许多UN * Xes,包括BSD风格的UN * Xes,例如OS X--这些结构以一字节长度字段开头,后跟一字节地址族字段,而不是双字节地址族字段。
因此,sockaddr结构中的所有UInt16
族字段都与OS X中的结构布局不匹配 - 或者在{Free,Net,Open,DragonFly} BSD中。它们可能与其他一些UN * Xes不匹配,即使它们可能在Linux中匹配。
这是否是造成问题的原因是另一回事。