TxaKy Network v0.6


 

Using Packet Filtering API

Introduction

Recently, I have been searching how I can make filter applications using Packet Filtering API included in Windows 2000 and above. First, I decided to make a C++ class in order to encapsulate all and make easy next applications. But I thought... why don't write a .NET C++ class? Because I haven't seen any other class to do it for this platform, I answered "yes". 

The problem is that I am a beginner with .NET. I know C++ and I have used C# a few but I haven't written mix managed/unmanaged C++ code never. Anyway, I didn't change  my answer, I decided to write this class and I'll write it :P(and in this way, I can learn more about .NET). For this reason, you can see any bug in my code or probably you think you would write some code better. Feel free to tell me all you think and we will learn together: you will learn something about packet filtering ( I hope it...) and I will learn something about .NET mixing managed/unmanaged code(I hope it, too).

 

The Packet Filtering API

With Windows 2000 Microsoft included one API in order to implement packet filtering funcionality in our programs. This API is included in Windows XP and Windows 2003, too. Packet Filtering API allow us to associate filters to IP adapter interfaces. We can implement a funcionality similar that included in tcp/ip filter options in tcp/ip properties of a network adapter.

Now I will comment the basic functions for this API, used to write this class:

  • PfCreateInterface(...)
    Used to create an interface. In this function, we pass the default action for incoming and outgoing packets.Then, we associate filters to interfaces.

  • PfBindInterfaceToIPAddress(...)
    We created a interface, but we have to bind it with a Ip address. To do it, we use this function.

  • PfAddFiltersToInterface(...)
    We have created the interface and bind it with a local ip. Now, we can associate filters in order to filter IP traffic. When we created the interface, we indicated the default action for incoming and outgoing packets. The filters reverse the default actions for the interface.

  • PfAddGlobalFilterToInterface(...)
    Add a global filter to all filters of an interface. We have three predefined global filters: check packets fragments, check fragments from the cache, check destination for incoming packets (check ip spoofing attacks).

  • PfRemoveGlobalFilterToInterface(...)
    Remove a global filter from an interface.

  • PfRemoveFiltersFromInterface(...)
    Remove an added filter from an interface.

  • PfUnBindInterface(...)
    Unbind an ip address and an interface.

  • PfDeleteInterface(...)
    Delete an interface created. 

If you want more information about this functions parameters, you can find it in msdn. One reason to write this article is the few documentation (I love documentation with samples!!!). Important: You can only use this functions if you have administrative privilegies.

 

Installing Ip Filters

We know the functions we have to used. Now we have to known the process to install filters:

  1. We must know the ip address of the local interface where we want to apply packet filtering. The initial process is easy: create the interface and bind the known local ip address with it.
  2. Second, we add as filter rules as i want. We can add filter rules or global filters.
  3. When we finish, we must unbind interfaces and local Ip address and delete interfaces created.

In C words:

// Creating the interface and associating it with a local ip address 
INTERFACE_HANDLE hInterface; PfCreateInterface(0, PF_ACTION_FORWARD, PF_ACTION_FORWARD, FALSE, TRUE, &hInterface);
BYTE localIp[] = {172,29,16,2};


// Look this byte order for ip address!!             PfBindInterfaceToIPAddress(hInterface, PF_IPV4, localIp); // We go to add a filter. Forbid outgoing http traffic, for example. FILTER_HANDLE fHandle; // Fill the filter rule data PF_FILTER_DESCRIPTOR inFilter; inFilter.dwFilterFlags = FD_FLAGS_NOSYN; //always this value inFilter.dwRule = 0; //always this value inFilter.pfatType = PF_IPV4; //using ipV4 addresses inFilter.SrcAddr = localIp; //set local ip inFilter.SrcMask = "\xff\xff\xff\xff"; //mask for local ip inFilter.wSrcPort = FILTER_TCPUDP_PORT_ANY; //any source port inFilter.wSrcPortHighRange = FILTER_TCPUDP_PORT_ANY; inFilter.DstAddr = 0; //any destination inFilter.DstMask = 0; inFilter.wDstPort = 80; //destination port 80(http service) inFilter.wDstPortHighRange = 80; inFilter.dwProtocol = FILTER_PROTO_TCP; // Tcp protocol // Add the filter PfAddFiltersToInterface(hInterface, 1, &inFilter, 0, NULL, &fHandle); //............... //............... // Remove the filter PfRemoveFilterHandles(hInterface, 1, &fHandle); // Unbind and delete interface PfUnBindInterface(hInterface); PfDeleteInterface(hInterface);

 

The .NET Classes

My packet filtering API for .NET implement two public classes:

  • TxFilterController.
    The basic class. Used to add filter or remove filters to an interface. You can implement filtering only with this class. This class create only the interfaces needed, without require the user to do it.

    Its methods are the follow:

    -int AddFilter(IPAddress *ip, TxIpFilter *filter)
    Add a filter to a local ip address. If no error, return 0. This method is overloaded in order to pass the filters rules without create a TxIpFilter object. Packets that matches a filter rule will be dropped.

    -int AddGlobalFilter(IPAddress *ip, int globalFilter)
    Add a global filter to a local ip address. If no error return 0.

    -int RevomeFilter(IPAddress *ip, TxIpFilter *filter)
    Remove a filter from an interface. If no error, return 0. This method is overloaded in order to pass the filters rules without create a TxIpFilter object.

    -int RevomeGlobalFilter(IPAddress *ip, int globalFilter)
    Remove a global filter from a interface. If no error, return 0.

    -CloseController()
    Remove and unbind all interfaces created.

TxIpFilter.
The equivalent of PF_FILTER_DESCRIPTOR in packet filtering api. Define a filter rule. You can add as TxIpFilters as you want to TxFilterController.

 

The Sample Application

To test the class I write a simple C# application that install two rules: forbid all incoming icmp traffic and forbid all outgoing http traffic. You can see how use my classes seeing the code:



static void Main(string[] args)

{

	TxFilterController fltCont = new TxFilterController();

	TxIpFilter flt = new TxIpFilter();

	

		

	// Drop incoming ICMP traffic

	// source port = icmp type	

	// destination port = icmp code	

	flt.direction = TxIpFilter.IN_DIRECTION; 

	flt.ipSource = IPAddress.Any; 

	flt.maskSource = IPAddress.Any; 

	flt.ipDestination = IPAddress.Any;

	flt.maskDestination = IPAddress.Any;

	flt.protocol = TxIpFilter.ICMP_PROTOCOL;

	flt.sourcePort = TxIpFilter.ANY_ICMP_TYPES;

	flt.destinationPort = TxIpFilter.ANY_ICMP_CODES;

	

	fltCont.AddFilter(IPAddress.Parse("172.16.0.5"), flt);

	

	

	// Drop outgoing Http traffic

		

	fltCont.AddFilter(IPAddress.Parse("172.16.0.5"), 

			  TxIpFilter.OUT_DIRECTION,

			  IPAddress.Parse("172.16.0.5"),

			  IPAddress.Parse("255.255.255.255"),

			  IPAddress.Any, IPAddress.Any,

			  TxIpFilter.ANY_TCPUDP_PORTS,

			  80,

			  TxIpFilter.TCP_PROTOCOL);

					

	Console.ReadLine();

	fltCont.CloseController();

}



 

Conclusion

Where you can use this class? You can use in applications where you can add easily packet filtering funcionality. You can use in a complete filtering application because this API is few flexible: you can only filter at ip and transport level (ips, ports and protocol), don't filter at link level and don't filter at application level.

I don't know if you can use Packet Filtering API with Wan interfaces, because I don't have a modem to test. If you test it, please tell me the result.

And... that's all. I hope this class will be useful for somebody.

Article writen by Jesús O . This Article was published in www.codeproject.com - 20/07/03

Download Article's Source Code