PInvoke PFCreateInterface C#

发布于 2024-11-15 03:27:29 字数 6556 浏览 2 评论 0原文

我正在尝试在 C# 中为数据包过滤应用程序调用 PFCreateInterface。然而,pinvoke.net 上的示例似乎没有充分记录。对于初学者来说,一旦调用 main 中的 StartPacketFilter() ,如何在不关闭应用程序的情况下以编程方式删除数据包过滤器?另外,我对数据包字符串的格式也很困惑。 即hostsToBlock[0] = "67.77.87.97,255.255.255.255,0"; //阻止任何端口上往返 67.77.87.97 的所有流量

我如何阻止所有 ip 上的远程端口 6980?

pinvoke代码如下:

/// <summary>
/// IP packet filter management wrapper for Iphlpapi.dll (Win 2000/XP)
/// </summary>
/// 
public class IpPacketFilter
{
    [DllImport("iphlpapi.dll", EntryPoint = "PfBindInterfaceToIPAddress")]
    public static extern int PfBindInterfaceToIPAddress(
                                    IntPtr Interface_handle,
                                    PFADDRESSTYPE pfatType,
                                    ref int ip_address
                                    );


    [DllImport("iphlpapi.dll", EntryPoint = "PfCreateInterface")]
    public static extern int PfCreateInterface(
                                    int dwName,
                                    PFFORWARD_ACTION inAction,
                                    PFFORWARD_ACTION outAction,
                                    bool UseLog,
                                    bool MustBeUnique,
                                    ref IntPtr ppInterface
                                    );

    //////


    ////

    [DllImport("iphlpapi.dll", EntryPoint = "PfAddFiltersToInterface")]
    public static extern int PfAddFiltersToInterface(
                                    IntPtr interface_handle,
                                    int cInFilters,
                                    [MarshalAsAttribute(UnmanagedType.Struct)] 
                                    ref PPF_FILTER_DESCRIPTOR pfiltIn,
                                    int cOutFilters,
                                    [MarshalAsAttribute(UnmanagedType.Struct)]
                                    ref PPF_FILTER_DESCRIPTOR pfiltOut,
                                    [MarshalAsAttribute(UnmanagedType.Struct)]
                                     ref PPF_FILTER_DESCRIPTOR pfHandle
                                    );

}


 public unsafe struct PPF_FILTER_DESCRIPTOR
{
    public FILTER_FLAGS dwFilterFlags;
    public int dwRule;
    public PFADDRESSTYPE pfatType;

    public int* SrcAddr;
    public int* SrcMask;
    public int* DstAddr;
    public int* DstMask;

    public PROTOCOL dwProtocol;
    public int fLateBound;
    public int wSrcPort;
    public int wDstPort;
    public int wSrcPortHighRange;
    public int wDstPortHighRange;
}
public enum PFFORWARD_ACTION : int
{
    PF_ACTION_FORWARD = 0,
    PF_ACTION_DROP
}

public enum PFADDRESSTYPE : int
{
    PF_IPV4,
    PF_IPV6
}
public  enum PROTOCOL : int
{
    ANY = 0x00,
    ICMP = 0x01,
    TCP = 0x06,
    UDP = 0x11
}

public  enum FILTER_FLAGS : int
{
    FD_FLAGS = 0x1
}

class Program {

internal const int FALSE = 0;
internal const int TRUE = 1;


static void Main(string[] args)
{
    string[] hostsToBlock = new string[2];
    hostsToBlock[0] = "67.77.87.97,255.255.255.255,0";    //blocks all traffic on any port to/from 67.77.87.97
    hostsToBlock[1] = "0.0.0.0,0.0.0.0,29000";        //blocks all traffic on port 29000, in and out
    StartPacketFilter(hostsToBlock);
}

internal static int lIpFromString(string sIpAddress)
{
    int lIp = 0;
    try
    {
        string[] octets = sIpAddress.Split(new string[] { "." }, StringSplitOptions.None);

        if (octets.Length != 4)
            return 0;

        for (int i = 0; i < 4; i++)
            lIp |= (int.Parse(octets[i]) << (i * 8));
    }
    catch { }
    return lIp;
}

internal static string[] GetLocalIpAddresses()
{
    IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
    string[] localIpAddresses = new string[host.AddressList.Length];
    for (int i = 0; i < host.AddressList.Length; i++)
    {
        localIpAddresses[i] = host.AddressList[i].ToString();
    }
    return localIpAddresses;
}

internal static bool StartPacketFilter(string[] hosts)
{
    string[] localIpAddresses = GetLocalIpAddresses();
    if (localIpAddresses == null)
        return false;

    foreach (string localAddress in localIpAddresses)
    {
        int result;
        IntPtr interfaceHandle = new IntPtr();

        //convert the string IP to an unsigned int for p/invoke
        int lLocalIp = lIpFromString(localAddress);

        //create a filter interface in the tcp/ip stack
        result = IpPacketFilter.PfCreateInterface(0, PFFORWARD_ACTION.PF_ACTION_FORWARD, PFFORWARD_ACTION.PF_ACTION_FORWARD, false, true, ref interfaceHandle);
        if (result != 0)
            return false;

        //bind interface to an ip address
        result = IpPacketFilter.PfBindInterfaceToIPAddress(interfaceHandle, PFADDRESSTYPE.PF_IPV4, ref lLocalIp);
        if (result != 0)
            return false;

        foreach (string targetHost in hosts)
        {
            IntPtr filterHandle = new IntPtr();
            string[] hostDetail = targetHost.Split(new string[] { "," }, StringSplitOptions.None);
            if (hostDetail != null && hostDetail.Length == 3)
            {
                //build the filter structure
                PPF_FILTER_DESCRIPTOR filter = new PPF_FILTER_DESCRIPTOR();
                filter.dwFilterFlags = FILTER_FLAGS.FD_FLAGS;
                filter.dwRule = FALSE;
                filter.pfatType = PFADDRESSTYPE.PF_IPV4;
                filter.dwProtocol = PROTOCOL.TCP;

                int iSrcAddr = lLocalIp;
                int iSrcMask = lIpFromString("255.255.255.255");
                filter.wSrcPort = 0;
                filter.wSrcPortHighRange = 0;

                int iDstAddr = lIpFromString(hostDetail[0]);
                int iDstMask = lIpFromString(hostDetail[1]);
                filter.wDstPort = int.Parse(hostDetail[2]);
                filter.wDstPortHighRange = int.Parse(hostDetail[2]);

                unsafe
                {
                    filter.SrcAddr = &iSrcAddr;
                    filter.DstAddr = &iDstAddr;
                    filter.SrcMask = &iSrcMask;
                    filter.DstMask = &iDstMask;
                }
                // add filter to interface (both inbound and outbound)
                result = IpPacketFilter.PfAddFiltersToInterface(interfaceHandle, 1, ref filter, 1, ref filter, ref filter);

                if (result != 0)
                    return false;
            }
        }
    }
    return true;
}

}

I am attempting to pinvoke PFCreateInterface in C# for a packet filtering app. However, the example on pinvoke.net seems inadequately documented. For starters, once StartPacketFilter() in main is called, how can i remove the packet filter programatically without closing the app? Also, i'm also quite confused about the format of the packet string.
I.e hostsToBlock[0] = "67.77.87.97,255.255.255.255,0"; //blocks all traffic on any port to/from 67.77.87.97

How would i go about blocking a remote port of 6980 across all ips?

The pinvoke codes are as follows :

/// <summary>
/// IP packet filter management wrapper for Iphlpapi.dll (Win 2000/XP)
/// </summary>
/// 
public class IpPacketFilter
{
    [DllImport("iphlpapi.dll", EntryPoint = "PfBindInterfaceToIPAddress")]
    public static extern int PfBindInterfaceToIPAddress(
                                    IntPtr Interface_handle,
                                    PFADDRESSTYPE pfatType,
                                    ref int ip_address
                                    );


    [DllImport("iphlpapi.dll", EntryPoint = "PfCreateInterface")]
    public static extern int PfCreateInterface(
                                    int dwName,
                                    PFFORWARD_ACTION inAction,
                                    PFFORWARD_ACTION outAction,
                                    bool UseLog,
                                    bool MustBeUnique,
                                    ref IntPtr ppInterface
                                    );

    //////


    ////

    [DllImport("iphlpapi.dll", EntryPoint = "PfAddFiltersToInterface")]
    public static extern int PfAddFiltersToInterface(
                                    IntPtr interface_handle,
                                    int cInFilters,
                                    [MarshalAsAttribute(UnmanagedType.Struct)] 
                                    ref PPF_FILTER_DESCRIPTOR pfiltIn,
                                    int cOutFilters,
                                    [MarshalAsAttribute(UnmanagedType.Struct)]
                                    ref PPF_FILTER_DESCRIPTOR pfiltOut,
                                    [MarshalAsAttribute(UnmanagedType.Struct)]
                                     ref PPF_FILTER_DESCRIPTOR pfHandle
                                    );

}


 public unsafe struct PPF_FILTER_DESCRIPTOR
{
    public FILTER_FLAGS dwFilterFlags;
    public int dwRule;
    public PFADDRESSTYPE pfatType;

    public int* SrcAddr;
    public int* SrcMask;
    public int* DstAddr;
    public int* DstMask;

    public PROTOCOL dwProtocol;
    public int fLateBound;
    public int wSrcPort;
    public int wDstPort;
    public int wSrcPortHighRange;
    public int wDstPortHighRange;
}
public enum PFFORWARD_ACTION : int
{
    PF_ACTION_FORWARD = 0,
    PF_ACTION_DROP
}

public enum PFADDRESSTYPE : int
{
    PF_IPV4,
    PF_IPV6
}
public  enum PROTOCOL : int
{
    ANY = 0x00,
    ICMP = 0x01,
    TCP = 0x06,
    UDP = 0x11
}

public  enum FILTER_FLAGS : int
{
    FD_FLAGS = 0x1
}

class Program
{

internal const int FALSE = 0;
internal const int TRUE = 1;


static void Main(string[] args)
{
    string[] hostsToBlock = new string[2];
    hostsToBlock[0] = "67.77.87.97,255.255.255.255,0";    //blocks all traffic on any port to/from 67.77.87.97
    hostsToBlock[1] = "0.0.0.0,0.0.0.0,29000";        //blocks all traffic on port 29000, in and out
    StartPacketFilter(hostsToBlock);
}

internal static int lIpFromString(string sIpAddress)
{
    int lIp = 0;
    try
    {
        string[] octets = sIpAddress.Split(new string[] { "." }, StringSplitOptions.None);

        if (octets.Length != 4)
            return 0;

        for (int i = 0; i < 4; i++)
            lIp |= (int.Parse(octets[i]) << (i * 8));
    }
    catch { }
    return lIp;
}

internal static string[] GetLocalIpAddresses()
{
    IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
    string[] localIpAddresses = new string[host.AddressList.Length];
    for (int i = 0; i < host.AddressList.Length; i++)
    {
        localIpAddresses[i] = host.AddressList[i].ToString();
    }
    return localIpAddresses;
}

internal static bool StartPacketFilter(string[] hosts)
{
    string[] localIpAddresses = GetLocalIpAddresses();
    if (localIpAddresses == null)
        return false;

    foreach (string localAddress in localIpAddresses)
    {
        int result;
        IntPtr interfaceHandle = new IntPtr();

        //convert the string IP to an unsigned int for p/invoke
        int lLocalIp = lIpFromString(localAddress);

        //create a filter interface in the tcp/ip stack
        result = IpPacketFilter.PfCreateInterface(0, PFFORWARD_ACTION.PF_ACTION_FORWARD, PFFORWARD_ACTION.PF_ACTION_FORWARD, false, true, ref interfaceHandle);
        if (result != 0)
            return false;

        //bind interface to an ip address
        result = IpPacketFilter.PfBindInterfaceToIPAddress(interfaceHandle, PFADDRESSTYPE.PF_IPV4, ref lLocalIp);
        if (result != 0)
            return false;

        foreach (string targetHost in hosts)
        {
            IntPtr filterHandle = new IntPtr();
            string[] hostDetail = targetHost.Split(new string[] { "," }, StringSplitOptions.None);
            if (hostDetail != null && hostDetail.Length == 3)
            {
                //build the filter structure
                PPF_FILTER_DESCRIPTOR filter = new PPF_FILTER_DESCRIPTOR();
                filter.dwFilterFlags = FILTER_FLAGS.FD_FLAGS;
                filter.dwRule = FALSE;
                filter.pfatType = PFADDRESSTYPE.PF_IPV4;
                filter.dwProtocol = PROTOCOL.TCP;

                int iSrcAddr = lLocalIp;
                int iSrcMask = lIpFromString("255.255.255.255");
                filter.wSrcPort = 0;
                filter.wSrcPortHighRange = 0;

                int iDstAddr = lIpFromString(hostDetail[0]);
                int iDstMask = lIpFromString(hostDetail[1]);
                filter.wDstPort = int.Parse(hostDetail[2]);
                filter.wDstPortHighRange = int.Parse(hostDetail[2]);

                unsafe
                {
                    filter.SrcAddr = &iSrcAddr;
                    filter.DstAddr = &iDstAddr;
                    filter.SrcMask = &iSrcMask;
                    filter.DstMask = &iDstMask;
                }
                // add filter to interface (both inbound and outbound)
                result = IpPacketFilter.PfAddFiltersToInterface(interfaceHandle, 1, ref filter, 1, ref filter, ref filter);

                if (result != 0)
                    return false;
            }
        }
    }
    return true;
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

铁憨憨 2024-11-22 03:27:29

After a quick search, I found this: PfRemoveFiltersFromInterface. This seems to do exactly what your asking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文