Получить IP-адрес LibPcapLiveDevice
Поскольку проект 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.
РЕДАКТИРОВАТЬ
Как предложил Гай Харрис, я сравнил структуры и типы, используемые в 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
, Довольно просто в конце концов.
1 ответ
Ну, я не знаком с C#, но, если PcapUnmanagedStructures.cs пытается описать макет собственных структур C для ОС, эти объявления не подходят для многих UN*X, включая UN*Xes со вкусом BSD. такие как OS X - эти структуры начинаются с однобайтового поля длины, за которым следует однобайтовое поле семейства адресов, а не с двухбайтовым полем семейства адресов.
Так что все UInt16
семейные поля в структурах sockaddr не соответствуют расположению структур в OS X или в BSD {Free, Net, Open, DragonFly}. Они могут не совпадать в некоторых других UN*X, хотя они могут совпадать в Linux.
Является ли это тем, что вызывает вашу проблему - это другой вопрос.