' ########################################################################################
' Microsoft Windows
' File: fltdefs.inc
' Contents: Definitions for the WIN32 filter APIs
' Copyright (c) 2011 Jos? Roca
' Portions Copyright (c) Microsoft Corporation.
' All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#IF NOT %DEF(PBX_fltdefs_PBI)
#DEFINE PBX_fltdefs_PBI
%EQUATE `FLTDEFS_INC = 1
'typedef PVOID FILTER_HANDLE, *PFILTER_HANDLE;
'typedef PVOID INTERFACE_HANDLE, *PINTERFACE_HANDLE;
' enum GLOBAL_FILTER
%EQUATE `GF_FRAGMENTS = 2 ' // check consistency of fragments
%EQUATE `GF_STRONGHOST = 8 ' // check destination address of input frames
%EQUATE `GF_FRAGCACHE = 9 ' // check fragments from cache
' enum PFFORWARD_ACTION
%EQUATE `PF_ACTION_FORWARD = 0
%EQUATE `PF_ACTION_DROP = 1
' enum PFADDRESSTYPE
%EQUATE `PF_IPV4 = 0
%EQUATE `PF_IPV6 = 1
'//////////////////////////////////////////////////////////////////////////////
'// //
'// The constants that should be used to set up the FILTER_INFO_STRUCTURE //
'// //
'//////////////////////////////////////////////////////////////////////////////
'#define FILTER_PROTO(ProtoId) MAKELONG(MAKEWORD((ProtoId),0x00),0x00000)
MACRO FILTER_PROTO(ProtoId) = MAK(LONG,MAK(WORD,ProtoID,&H00),&H00000)
'#define FILTER_PROTO_ANY FILTER_PROTO(0x00)
'#define FILTER_PROTO_ICMP FILTER_PROTO(0x01)
'#define FILTER_PROTO_TCP FILTER_PROTO(0x06)
'#define FILTER_PROTO_UDP FILTER_PROTO(0x11)
%EQUATE `FILTER_PROTO_ANY = &H00&
%EQUATE `FILTER_PROTO_ICMP = &H01&
%EQUATE `FILTER_PROTO_TCP = &H06&
%EQUATE `FILTER_PROTO_UDP = &H11&
'#define FILTER_TCPUDP_PORT_ANY (WORD)0x0000
%EQUATE `FILTER_TCPUDP_PORT_ANY = &H0000
'#define FILTER_ICMP_TYPE_ANY (BYTE)0xff
'#define FILTER_ICMP_CODE_ANY (BYTE)0xff
%EQUATE `FILTER_ICMP_TYPE_ANY = &Hff
%EQUATE `FILTER_ICMP_CODE_ANY = &Hff
' // Size = 44 bytes
TYPE PF_FILTER_DESCRIPTOR DWORD FILL
 dwFilterFlags AS DWORD ' DWORD // see below
 dwRule AS DWORD ' DWORD // copied into the log when appropriate
 pfatType AS LONG
 SrcAddr AS BYTE PTR
 SrcMask AS BYTE PTR
 DstAddr AS BYTE PTR
 DstMask AS BYTE PTR
 dwProtocol AS DWORD
 fLateBound AS DWORD
 wSrcPort AS WORD ' WORD
 wDstPort AS WORD ' WORD
 wSrcPortHighRange AS WORD ' WORD
 wDstPortHighRange AS WORD ' WORD
END TYPE
'//////////////////////////////////////////////////////////////////////////////
'// //
'// Structure for PfGetInterfaceStatistics //
'// //
'//////////////////////////////////////////////////////////////////////////////
' // Size = 48 bytes
TYPE PF_FILTER_STATS DWORD FILL
 dwNumPacketsFiltered AS DWORD
 info AS PF_FILTER_DESCRIPTOR
END TYPE
' // Size = 120 bytes
TYPE PF_INTERFACE_STATS QWORD FILL
 pvDriverContext AS DWORD
 dwFlags AS DWORD ' DWORD // none as yet (28-Sept-1997)
 dwInDrops AS DWORD
 dwOutDrops AS DWORD
 eaInAction AS LONG ' PFFORWARD_ACTION
 eaOutAction AS LONG ' PFFORWARD_ACTION
 dwNumInFilters AS DWORD
 dwNumOutFilters AS DWORD
 dwFrag AS DWORD
 dwSpoof AS DWORD
 dwReserved1 AS DWORD
 dwReserved2 AS DWORD
 liSYN AS QUAD ' LARGE_INTEGER
 liTotalLogged AS QUAD ' LARGE_INTEGER
 dwLostLogEntries AS DWORD
 FilterInfo(0) AS PF_FILTER_STATS ' PF_FILTER_STATS FilterInfo[1];
END TYPE
'//////////////////////////////////////////////////////////////////////////////
'// //
'// The number of bytes starting at SrcAddr. If you add something to the //
'// structure make sure this remains valid //
'// //
'//////////////////////////////////////////////////////////////////////////////
'#define FILTERSIZE \
' (sizeof(PF_FILTER_DESCRIPTOR) - \
' (DWORD)(&((PPF_FILTER_DESCRIPTOR)0)->SrcAddr))
'//////////////////////////////////////////////////////////////////////////////
'// //
'// Flags for PF_FILTER_DESCRIPTOR //
'// //
'//////////////////////////////////////////////////////////////////////////////
'//
'// Disallows incoming SYN
'//
%EQUATE `FD_FLAGS_NOSYN = &H1
'//
'// All legal flags
'//
%EQUATE `FD_FLAGS_ALLFLAGS = %FD_FLAGS_NOSYN
'//////////////////////////////////////////////////////////////////////////////
'// //
'// Late bound defs. Go in fLateBound in a PF_FILTER_DESCRIPTOR and //
'// describe which other fields of the filter are affected by a //
'// PfRebindFilters call. In general such filters are on WAN interfaces //
'// where one or the other address may change as the connection is //
'// reconnected. //
'// The assumption is that such interfaces HAVE ONLY ONE ADDRESS. //
'// //
'//////////////////////////////////////////////////////////////////////////////
%EQUATE `LB_SRC_ADDR_USE_SRCADDR_FLAG = &H00000001
%EQUATE `LB_SRC_ADDR_USE_DSTADDR_FLAG = &H00000002
%EQUATE `LB_DST_ADDR_USE_SRCADDR_FLAG = &H00000004
%EQUATE `LB_DST_ADDR_USE_DSTADDR_FLAG = &H00000008
%EQUATE `LB_SRC_MASK_LATE_FLAG = &H00000010
%EQUATE `LB_DST_MASK_LATE_FLAG = &H00000020
' // Size = 12 bytes
TYPE PF_LATEBIND_INFO DWORD FILL
 SrcAddr AS BYTE PTR
 DstAddr AS BYTE PTR
 Mask AS BYTE PTR
END TYPE
'//////////////////////////////////////////////////////////////////////////////
'// //
'// The format of a logged frame and defs for it. //
'// //
'//////////////////////////////////////////////////////////////////////////////
' enum PFFRAMETYPE
%EQUATE `PFFT_FILTER = 1 ' // a filter violation
%EQUATE `PFFT_FRAG = 2 ' // bad fragment
%EQUATE `PFFT_SPOOF = 3 ' // strong host failure
' // Size = 40 bytes
TYPE PFLOGFRAME ' Must be 8 bytes aligned
 Timestamp AS QUAD ' LARGE_INTEGER
 pfeTypeOfFrame AS LONG
 dwTotalSizeUsed AS DWORD ' DWORD // used to find the next frame
 dwFilterRule AS DWORD ' DWORD // from the filter
 wSizeOfAdditionalData AS WORD ' WORD
 wSizeOfIpHeader AS WORD ' WORD
 dwInterfaceName AS DWORD ' DWORD // the name of the interface
 dwIPIndex AS DWORD
 bPacketData(7) AS BYTE ' BYTE bPacketData[1] // the frame. wsizeOfIpHeader
 ' // and wsizeOfAdditionalData describe this
 ' // Note: We are using bPacketData(7) instead of bPacketData(0) to keep 8 byte alignment
END TYPE
'//////////////////////////////////////////////////////////////////////////////
'// //
'// Error codes. These extend the WIN32 errors by having errors specific to //
'// these APIs. Besides these errors, the APIs may return any of the WIN32 //
'// errors. //
'// //
'//////////////////////////////////////////////////////////////////////////////
%EQUATE `ERROR_BASE = 23000
%EQUATE `PFERROR_NO_PF_INTERFACE = %ERROR_BASE + 0 ' // never returned.
%EQUATE `PFERROR_NO_FILTERS_GIVEN = %ERROR_BASE + 1
%EQUATE `PFERROR_BUFFER_TOO_SMALL = %ERROR_BASE + 2
%EQUATE `ERROR_IPV6_NOT_IMPLEMENTED = %ERROR_BASE + 3
'//////////////////////////////////////////////////////////////////////////////
'// //
'// The API prototypes //
'// //
'//////////////////////////////////////////////////////////////////////////////
DECLARE FUNCTION PfCreateInterface LIB "iphlpapi.dll" ALIAS "PfCreateInterface" ( BYVAL dwName AS QUAD , BYVAL inAction AS LONG , BYVAL outAction AS LONG , BYVAL bUseLog AS LONG , BYVAL bMustBeUnique AS LONG , BYREF ppInterface AS QUAD ) AS QUAD
DECLARE FUNCTION PfDeleteInterface LIB "iphlpapi.dll" ALIAS "PfDeleteInterface" ( BYVAL pInterface AS QUAD
 ) AS DWORD
DECLARE FUNCTION PfAddFiltersToInterface LIB "iphlpapi.dll" ALIAS "PfAddFiltersToInterface" ( BYVAL ih AS DWORD
 , BYVAL cInFilters AS DWORD
 , BYREF pfiltIn AS PF_FILTER_DESCRIPTOR
 , BYVAL cOutFilters AS DWORD
 , BYREF pfiltOut AS PF_FILTER_DESCRIPTOR
 , BYREF pfHandle AS DWORD
 ) AS DWORD
DECLARE FUNCTION PfRemoveFiltersFromInterface LIB "iphlpapi.dll" ALIAS "PfRemoveFiltersFromInterface" ( BYVAL ih AS DWORD
 , BYVAL cInFilters AS DWORD
 , BYREF pfiltIn AS PF_FILTER_DESCRIPTOR
 , BYVAL cOutFilters AS DWORD
 , BYREF pfiltOut AS PF_FILTER_DESCRIPTOR
 ) AS DWORD
DECLARE FUNCTION PfRemoveFilterHandles LIB "iphlpapi.dll" ALIAS "PfRemoveFilterHandles" ( BYVAL pInterface AS DWORD
 , BYVAL cFilters AS DWORD
 , BYREF pvHandles AS DWORD
 ) AS DWORD
DECLARE FUNCTION PfUnBindInterface LIB "iphlpapi.dll" ALIAS "PfUnBindInterface" ( BYVAL pInterface AS DWORD
 ) AS DWORD
DECLARE FUNCTION PfBindInterfaceToIndex LIB "iphlpapi.dll" ALIAS "PfBindInterfaceToIndex" ( BYVAL pInterface AS DWORD
 , BYVAL dwIndex AS DWORD
 , BYVAL pfatLinkType AS LONG
 , BYVAL LinkIPAddress AS BYTE PTR
 ) AS DWORD
DECLARE FUNCTION PfBindInterfaceToIPAddress LIB "iphlpapi.dll" ALIAS "PfBindInterfaceToIPAddress" ( BYVAL pInterface AS DWORD
 , BYVAL pfatType AS LONG
 , BYVAL IPAddress AS BYTE PTR
 ) AS DWORD
DECLARE FUNCTION PfRebindFilters LIB "iphlpapi.dll" ALIAS "PfRebindFilters" ( BYVAL pInterface AS DWORD
 , BYREF pLateBindInfo AS PF_LATEBIND_INFO
 ) AS DWORD
DECLARE FUNCTION PfAddGlobalFilterToInterface LIB "iphlpapi.dll" ALIAS "PfAddGlobalFilterToInterface" ( BYVAL pInterface AS DWORD
 , BYVAL gfFilter AS LONG
 ) AS DWORD
DECLARE FUNCTION PfRemoveGlobalFilterFromInterface LIB "iphlpapi.dll" ALIAS "PfRemoveGlobalFilterFromInterface" ( BYVAL pInterface AS DWORD
 , BYVAL gfFilter AS LONG
 ) AS DWORD
'//////////////////////////////////////////////////////////////////////////////
'// //
'// Log APIs. Note that there is at most one log and it must be created //
'// before any interface needing it is created. There is no way to set a //
'// log onto an existing interface. The log can be applied to any or all of //
'// the interfaces. //
'// //
'//////////////////////////////////////////////////////////////////////////////
DECLARE FUNCTION PfMakeLog LIB "iphlpapi.dll" ALIAS "PfMakeLog" ( BYVAL hEvent AS QUAD ) AS QUAD
'//
'// Provide a buffer, and notification parameters, and get back
'// the old buffer and status.
'//
DECLARE FUNCTION PfSetLogBuffer LIB "iphlpapi.dll" ALIAS "PfSetLogBuffer" ( BYVAL pbBuffer AS BYTE PTR , BYVAL dwSize AS QUAD , BYVAL dwThreshold AS QUAD , BYVAL dwEntries AS QUAD , BYREF pdwLoggedEntries AS QUAD , BYREF pdwLostEntries AS QUAD , BYREF pdwSizeUsed AS QUAD ) AS QUAD
'//
'// Doing this will disable the log on any of the interfaces. But if
'// an interface was created with the log, the actual log will not be
'// completely deleted until that interface is deleted. This is a small
'// point, but it might explain a mystery or two.
'//
DECLARE FUNCTION PfDeleteLog LIB "iphlpapi.dll" ALIAS "PfDeleteLog" ( ) AS QUAD
'//////////////////////////////////////////////////////////////////////////////
'// //
'// Get statistics. Note pdwBufferSize in an IN/OUT parameter. If //
'// ERROR_INSUFFICIENT_BUFFER is returned, the common statistics are //
'// available and the correct byte count is in *pdwBufferSize. If only the //
'// interface statistics are needed, provide a buffer of size //
'// PF_INTERFACE_STATS only. //
'// If the filter descriptions are also needed, then supply a large buffer, //
'// or use the returned count from the first call to allocate a buffer of //
'// sufficient size. Note that for a shared interface, this second call may //
'// fail with ERROR_INSUFFICIENT_BUFFER. This can happen if the other //
'// sharers add filters in the interim. This should not happen for a UNIQUE //
'// interface. //
'// //
'//////////////////////////////////////////////////////////////////////////////
DECLARE FUNCTION PfGetInterfaceStatistics LIB "iphlpapi.dll" ALIAS "PfGetInterfaceStatistics" ( BYVAL pInterface AS QUAD , BYREF ppfStats AS PF_INTERFACE_STATS , BYREF pdwBufferSize AS QUAD , BYVAL fResetCounters AS LONG ) AS QUAD
'//////////////////////////////////////////////////////////////////////////////
'// //
'// Test a packet. //
'// This call will evaluate the packet against the given interfaces //
'// and return the filtering action. //
'// //
'//////////////////////////////////////////////////////////////////////////////
DECLARE FUNCTION PfTestPacket LIB "iphlpapi.dll" ALIAS "PfTestPacket" ( BYVAL pInInterface AS QUAD , BYVAL pOutInterface AS QUAD , BYVAL cBytes AS QUAD , BYVAL pbPacket AS BYTE PTR , BYREF ppAction AS LONG ) AS QUAD
#ENDIF
