1

SharpPcap プロジェクトは Mono と互換性があると主張しているため、プロジェクトを Mac で実行することにしました。

このために、WinPcapDeviceaを作成し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.csGuy Harris が示唆したように、Apple OS Reference Docs で使用されている構造体と型を比較しました。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に変更したことに注意してくださいsinpadの名前も に変更しましたsin_zero。結局のところ、非常に簡単です。

4

1 に答える 1

1

私は C# に詳しくありませんが、PcapUnmanagedStructures.csが OS のネイティブ C構造体のレイアウトを記述しようとしている場合、これらの宣言は、BSD 風味の UN*Xes を含む多くの UN*Xes では正しくありません。 OS X など - これらの構造は、 2バイトのアドレス ファミリ フィールドではなく、 1バイトの長さフィールドで始まり、その後に1 バイトのアドレス ファミリ フィールドが続きます。

そのため、そこにある sockaddr 構造体のすべてのUInt16ファミリ フィールドは、OS X または {Free,Net,Open,DragonFly}BSD の構造体のレイアウトと一致しません。Linux では一致する場合でも、他の一部の UN*Xes では一致しない場合もあります。

これが問題の原因であるかどうかは別の問題です。

于 2014-12-11T22:19:06.903 に答える