#ifndef _FLTDEFS_H
#define _FLTDEFS_H

/* Windows filter API definitions */

typedef PVOID FILTER_HANDLE, *PFILTER_HANDLE;
typedef PVOID INTERFACE_HANDLE, *PINTERFACE_HANDLE;

#define PFEXPORT __declspec(dllexport)

#ifdef __cplusplus
#define EXTERNCDECL EXTERN_C
#else
#define EXTERNCDECL
#endif

#define PFAPIENTRY EXTERNCDECL DWORD PFEXPORT WINAPI

#define FILTER_PROTO(ProtoId)  MAKELONG(MAKEWORD((ProtoId),0x00),0x00000)

#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)

#define FILTER_TCPUDP_PORT_ANY  (WORD)0x0000

#define FILTER_ICMP_TYPE_ANY  (BYTE)0xff
#define FILTER_ICMP_CODE_ANY  (BYTE)0xff

#define FILTERSIZE  (sizeof(PF_FILTER_DESCRIPTOR)-(DWORD)(&((PPF_FILTER_DESCRIPTOR)0)->SrcAddr))

#define FD_FLAGS_NOSYN  0x1
#define FD_FLAGS_ALLFLAGS  FD_FLAGS_NOSYN

#define LB_SRC_ADDR_USE_SRCADDR_FLAG  0x00000001
#define LB_SRC_ADDR_USE_DSTADDR_FLAG  0x00000002
#define LB_DST_ADDR_USE_SRCADDR_FLAG  0x00000004
#define LB_DST_ADDR_USE_DSTADDR_FLAG  0x00000008
#define LB_SRC_MASK_LATE_FLAG  0x00000010
#define LB_DST_MASK_LATE_FLAG  0x00000020

#define ERROR_BASE  23000

#define PFERROR_NO_PF_INTERFACE  (ERROR_BASE+0)
#define PFERROR_NO_FILTERS_GIVEN  (ERROR_BASE+1)
#define PFERROR_BUFFER_TOO_SMALL  (ERROR_BASE+2)
#define ERROR_IPV6_NOT_IMPLEMENTED (ERROR_BASE+3)

typedef enum _GlobalFilter {
    GF_FRAGMENTS = 2,
    GF_STRONGHOST = 8,
    GF_FRAGCACHE = 9
} GLOBAL_FILTER, *PGLOBAL_FILTER;

typedef enum _PfForwardAction {
    PF_ACTION_FORWARD = 0,
    PF_ACTION_DROP
} PFFORWARD_ACTION, *PPFFORWARD_ACTION;

typedef enum _PfAddresType {
    PF_IPV4,
    PF_IPV6
} PFADDRESSTYPE, *PPFADDRESSTYPE;

typedef struct _PF_FILTER_DESCRIPTOR {
    DWORD dwFilterFlags;
    DWORD dwRule;
    PFADDRESSTYPE pfatType;
    PBYTE SrcAddr;
    PBYTE SrcMask;
    PBYTE DstAddr;
    PBYTE DstMask;
    DWORD dwProtocol;
    DWORD fLateBound;
    WORD wSrcPort;
    WORD wDstPort;
    WORD wSrcPortHighRange;
    WORD wDstPortHighRange;
} PF_FILTER_DESCRIPTOR, *PPF_FILTER_DESCRIPTOR;

typedef struct _PF_FILTER_STATS {
    DWORD dwNumPacketsFiltered;
    PF_FILTER_DESCRIPTOR info;
} PF_FILTER_STATS, *PPF_FILTER_STATS;

typedef struct _PF_INTERFACE_STATS {
    PVOID pvDriverContext;
    DWORD dwFlags;
    DWORD dwInDrops;
    DWORD dwOutDrops;
    PFFORWARD_ACTION eaInAction;
    PFFORWARD_ACTION eaOutAction;
    DWORD dwNumInFilters;
    DWORD dwNumOutFilters;
    DWORD dwFrag;
    DWORD dwSpoof;
    DWORD dwReserved1;
    DWORD dwReserved2;
    LARGE_INTEGER liSYN;
    LARGE_INTEGER liTotalLogged;
    DWORD dwLostLogEntries;
    PF_FILTER_STATS FilterInfo[1];
} PF_INTERFACE_STATS, *PPF_INTERFACE_STATS;

typedef struct _PF_LATEBIND_INFO {
    PBYTE SrcAddr;
    PBYTE DstAddr;
    PBYTE Mask;
} PF_LATEBIND_INFO, *PPF_LATEBIND_INFO;

typedef enum _PfFrameType {
    PFFT_FILTER = 1,
    PFFT_FRAG = 2,
    PFFT_SPOOF = 3
} PFFRAMETYPE, *PPFFRAMETYPE;

typedef struct _pfLogFrame {
    LARGE_INTEGER Timestamp;
    PFFRAMETYPE pfeTypeOfFrame;
    DWORD dwTotalSizeUsed;
    DWORD dwFilterRule;
    WORD wSizeOfAdditionalData;
    WORD wSizeOfIpHeader;
    DWORD dwInterfaceName;
    DWORD dwIPIndex;
    BYTE bPacketData[1];

} PFLOGFRAME, *PPFLOGFRAME;

PFAPIENTRY PfCreateInterface(DWORD,PFFORWARD_ACTION,PFFORWARD_ACTION,BOOL,BOOL,INTERFACE_HANDLE*);
PFAPIENTRY PfDeleteInterface(INTERFACE_HANDLE);
PFAPIENTRY PfAddFiltersToInterface(INTERFACE_HANDLE,DWORD,PPF_FILTER_DESCRIPTOR,DWORD,PPF_FILTER_DESCRIPTOR,PFILTER_HANDLE);
PFAPIENTRY PfRemoveFiltersFromInterface(INTERFACE_HANDLE,DWORD,PPF_FILTER_DESCRIPTOR,DWORD,PPF_FILTER_DESCRIPTOR);
PFAPIENTRY PfRemoveFilterHandles(INTERFACE_HANDLE,DWORD,PFILTER_HANDLE);
PFAPIENTRY PfUnBindInterface(INTERFACE_HANDLE);
PFAPIENTRY PfBindInterfaceToIndex(INTERFACE_HANDLE,DWORD,PFADDRESSTYPE,PBYTE);
PFAPIENTRY PfBindInterfaceToIPAddress(INTERFACE_HANDLE,PFADDRESSTYPE,PBYTE);
PFAPIENTRY PfRebindFilters(INTERFACE_HANDLE,PPF_LATEBIND_INFO);
PFAPIENTRY PfAddGlobalFilterToInterface(INTERFACE_HANDLE,GLOBAL_FILTER);
PFAPIENTRY PfRemoveGlobalFilterFromInterface(INTERFACE_HANDLE,GLOBAL_FILTER);
PFAPIENTRY PfMakeLog(HANDLE);
PFAPIENTRY PfSetLogBuffer(PBYTE,DWORD,DWORD,DWORD,PDWORD,PDWORD,PDWORD);
PFAPIENTRY PfDeleteLog(VOID);
PFAPIENTRY PfGetInterfaceStatistics(INTERFACE_HANDLE,PPF_INTERFACE_STATS,PDWORD,BOOL);
PFAPIENTRY PfTestPacket(INTERFACE_HANDLE,INTERFACE_HANDLE,DWORD,PBYTE,PPFFORWARD_ACTION);

#endif /* _FLTDEFS_H */
