First commit of the Windows Divert project
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* divert.c
|
||||
* (C) 2011, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __DIVERT_H
|
||||
#define __DIVERT_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef DIVERTEXPORT
|
||||
#define DIVERTEXPORT __declspec(dllimport)
|
||||
#endif /* DIVERTEXPORT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* DIVERT API */
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* Divert packet.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT8 Reserved[7]; // Reserved for internal use.
|
||||
UINT8 Direction; // Packet's direction.
|
||||
UINT32 IfIdx; // Packet's interface index.
|
||||
UINT32 SubIfIdx; // Packet's sub-interface index.
|
||||
} DIVERT_PACKET, *PDIVERT_PACKET;
|
||||
|
||||
#ifndef DIVERT_PACKET_DIRECTION_OUTBOUND
|
||||
#define DIVERT_PACKET_DIRECTION_OUTBOUND 0
|
||||
#define DIVERT_PACKET_DIRECTION_INBOUND 1
|
||||
#endif /* DIVERT_PACKET_DIRECTION_OUTBOUND */
|
||||
|
||||
#define DIVERT_PACKET_DIRECTION(pPacket) (pPacket->Direction)
|
||||
#define DIVERT_PACKET_INTERFACE_INDEX(pPacket) (pPacket->IfIdx)
|
||||
#define DIVERT_PACKET_SUB_INTERFACE_INDEX(pPacket) (pPacket->SubIfIdx)
|
||||
#define DIVERT_PACKET_DATA(pPacket) \
|
||||
((PVOID)(pPacket+1))
|
||||
|
||||
/*
|
||||
* Open a handle to the divert device with the given filter.
|
||||
*/
|
||||
extern DIVERTEXPORT HANDLE DivertOpen(
|
||||
__in const char *filter);
|
||||
|
||||
/*
|
||||
* Receive (read) a packet from the Divert handle.
|
||||
*/
|
||||
extern DIVERTEXPORT BOOL DivertRecv(
|
||||
__in HANDLE handle,
|
||||
__inout PDIVERT_PACKET pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt UINT *readLen);
|
||||
|
||||
/*
|
||||
* Send (write/inject) a packet to the Divert handle.
|
||||
*/
|
||||
extern DIVERTEXPORT BOOL DivertSend(
|
||||
__in HANDLE handle,
|
||||
__in PDIVERT_PACKET pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt UINT *writeLen);
|
||||
|
||||
/*
|
||||
* Close a Divert handle.
|
||||
*/
|
||||
extern DIVERTEXPORT BOOL DivertClose(
|
||||
__in HANDLE handle);
|
||||
|
||||
/****************************************************************************/
|
||||
/* DIVERT HELPER API */
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef DIVERT_NO_HELPER_API
|
||||
|
||||
/*
|
||||
* IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT8 HdrLength:4;
|
||||
UINT8 Version:4;
|
||||
UINT8 TOS;
|
||||
UINT16 Length;
|
||||
UINT16 Id;
|
||||
UINT16 FragOff0;
|
||||
UINT8 TTL;
|
||||
UINT8 Protocol;
|
||||
UINT16 Checksum;
|
||||
UINT32 SrcAddr;
|
||||
UINT32 DstAddr;
|
||||
} DIVERT_IPHDR, *PDIVERT_IPHDR;
|
||||
|
||||
#define DIVERT_IPHDR_GET_FRAGOFF(hdr) \
|
||||
(((hdr)->FragOff0) & 0xFF1F)
|
||||
#define DIVERT_IPHDR_GET_MF(hdr) \
|
||||
((((hdr)->FragOff0) & 0x0020) != 0)
|
||||
#define DIVERT_IPHDR_GET_DF(hdr) \
|
||||
((((hdr)->FragOff0) & 0x0040) != 0)
|
||||
#define DIVERT_IPHDR_GET_RESERVED(hdr) \
|
||||
((((hdr)->FragOff0) & 0x0080) != 0)
|
||||
|
||||
#define DIVERT_IPHDR_SET_FRAGOFF(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0x00E0) | \
|
||||
((val) & 0xFF1F); \
|
||||
} \
|
||||
while (FALSE)
|
||||
#define DIVERT_IPHDR_SET_MF(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFFDF) | \
|
||||
(((val) & 0x0001) << 5); \
|
||||
} \
|
||||
while (FALSE)
|
||||
#define DIVERT_IPHDR_SET_DF(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFFBF) | \
|
||||
(((val) & 0x0001) << 6); \
|
||||
} \
|
||||
while (FALSE)
|
||||
#define DIVERT_IPHDR_SET_RESERVED(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFF7F) | \
|
||||
(((val) & 0x0001) << 7); \
|
||||
} \
|
||||
while (FALSE)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 TrafficClass0:4;
|
||||
UINT8 Version:4;
|
||||
UINT8 FlowLabel0:4;
|
||||
UINT8 TrafficClass1:4;
|
||||
UINT16 FlowLabel1;
|
||||
UINT16 Length;
|
||||
UINT8 NextHdr;
|
||||
UINT8 HopLimit;
|
||||
UINT32 SrcAddr[4];
|
||||
UINT32 DstAddr[4];
|
||||
} DIVERT_IPV6HDR, *PDIVERT_IPV6HDR;
|
||||
|
||||
#define DIVERT_IPV6HDR_GET_TRAFFICCLASS(hdr) \
|
||||
((((hdr)->TrafficClass0) << 4) | ((hdr)->TrafficClass1))
|
||||
#define DIVERT_IPV6HDR_GET_FLOWLABEL(hdr) \
|
||||
((((UINT32)(hdr)->FlowLabel0) << 16) | ((UINT32)(hdr)->FlowLabel1))
|
||||
|
||||
#define DIVERT_IPV6HDR_SET_TRAFFICCLASS(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->TrafficClass0 = ((UINT8)(val) >> 4); \
|
||||
(hdr)->TrafficClass1 = (UINT8)(val); \
|
||||
} \
|
||||
while (FALSE)
|
||||
#define DIVERT_IPV6HDR_SET_FLOWLABEL(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FlowLabel0 = (UINT8)((val) >> 16); \
|
||||
(hdr)->FlowLabel1 = (UINT16)(val); \
|
||||
} \
|
||||
while (FALSE)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 Type;
|
||||
UINT8 Code;
|
||||
UINT16 Checksum;
|
||||
UINT32 Body;
|
||||
} DIVERT_ICMPHDR, *PDIVERT_ICMPHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 Type;
|
||||
UINT8 Code;
|
||||
UINT16 Checksum;
|
||||
UINT32 Body;
|
||||
} DIVERT_ICMPV6HDR, *PDIVERT_ICMPV6HDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT16 SrcPort;
|
||||
UINT16 DstPort;
|
||||
UINT32 SeqNum;
|
||||
UINT32 AckNum;
|
||||
UINT16 Reserved1:4;
|
||||
UINT16 HdrLength:4;
|
||||
UINT16 Fin:1;
|
||||
UINT16 Syn:1;
|
||||
UINT16 Rst:1;
|
||||
UINT16 Psh:1;
|
||||
UINT16 Ack:1;
|
||||
UINT16 Urg:1;
|
||||
UINT16 Reserved2:2;
|
||||
UINT16 Window;
|
||||
UINT16 Checksum;
|
||||
UINT16 UrgPtr;
|
||||
} DIVERT_TCPHDR, *PDIVERT_TCPHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT16 SrcPort;
|
||||
UINT16 DstPort;
|
||||
UINT16 Length;
|
||||
UINT16 Checksum;
|
||||
} DIVERT_UDPHDR, *PDIVERT_UDPHDR;
|
||||
|
||||
/*
|
||||
* Flags for DivertHelperCalcChecksums()
|
||||
*/
|
||||
#define DIVERT_HELPER_NO_IP_CHECKSUM 1
|
||||
#define DIVERT_HELPER_NO_ICMP_CHECKSUM 2
|
||||
#define DIVERT_HELPER_NO_ICMPV6_CHECKSUM 4
|
||||
#define DIVERT_HELPER_NO_TCP_CHECKSUM 8
|
||||
#define DIVERT_HELPER_NO_UDP_CHECKSUM 16
|
||||
|
||||
/*
|
||||
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
|
||||
*/
|
||||
extern DIVERTEXPORT BOOL DivertHelperParse(
|
||||
__in PDIVERT_PACKET pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt PDIVERT_IPHDR *ppIpHdr,
|
||||
__out_opt PDIVERT_IPV6HDR *ppIpv6Hdr,
|
||||
__out_opt PDIVERT_ICMPHDR *ppIcmpHdr,
|
||||
__out_opt PDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
|
||||
__out_opt PDIVERT_TCPHDR *ppTcpHdr,
|
||||
__out_opt PDIVERT_UDPHDR *ppUdpHdr,
|
||||
__out_opt PVOID *ppData,
|
||||
__out_opt UINT *pDataLen);
|
||||
|
||||
/*
|
||||
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
|
||||
*/
|
||||
extern DIVERTEXPORT UINT DivertHelperCalcChecksums(
|
||||
__inout PDIVERT_PACKET pPacket,
|
||||
__in UINT packetLen,
|
||||
__in UINT64 flags);
|
||||
|
||||
#endif /* DIVERT_NO_HELPER_API */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DIVERT_H */
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* divert_device.h
|
||||
* (C) 2011, all rights reserved,
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: This file is NOT part of the divert API. For the divert API, include
|
||||
* "divert.h" instead.
|
||||
*/
|
||||
|
||||
#ifndef __DIVERT_DEVICE_H
|
||||
#define __DIVERT_DEVICE_H
|
||||
|
||||
#define DIVERT_DEVICE_NAME L"\\Device\\Divert"
|
||||
#define DIVERT_DOS_DEVICE_NAME L"\\??\\Divert"
|
||||
|
||||
#define DIVERT_VERSION 0
|
||||
#define DIVERT_MAGIC 0xF8D3
|
||||
|
||||
#define DIVERT_FILTER_FIELD_ZERO 0
|
||||
#define DIVERT_FILTER_FIELD_INBOUND 1
|
||||
#define DIVERT_FILTER_FIELD_OUTBOUND 2
|
||||
#define DIVERT_FILTER_FIELD_IFIDX 3
|
||||
#define DIVERT_FILTER_FIELD_SUBIFIDX 4
|
||||
#define DIVERT_FILTER_FIELD_IP 5
|
||||
#define DIVERT_FILTER_FIELD_IPV6 6
|
||||
#define DIVERT_FILTER_FIELD_ICMP 7
|
||||
#define DIVERT_FILTER_FIELD_TCP 8
|
||||
#define DIVERT_FILTER_FIELD_UDP 9
|
||||
#define DIVERT_FILTER_FIELD_ICMPV6 10
|
||||
#define DIVERT_FILTER_FIELD_IP_HDRLENGTH 11
|
||||
#define DIVERT_FILTER_FIELD_IP_TOS 12
|
||||
#define DIVERT_FILTER_FIELD_IP_LENGTH 13
|
||||
#define DIVERT_FILTER_FIELD_IP_ID 14
|
||||
#define DIVERT_FILTER_FIELD_IP_DF 15
|
||||
#define DIVERT_FILTER_FIELD_IP_MF 16
|
||||
#define DIVERT_FILTER_FIELD_IP_FRAGOFF 17
|
||||
#define DIVERT_FILTER_FIELD_IP_TTL 18
|
||||
#define DIVERT_FILTER_FIELD_IP_PROTOCOL 19
|
||||
#define DIVERT_FILTER_FIELD_IP_CHECKSUM 20
|
||||
#define DIVERT_FILTER_FIELD_IP_SRCADDR 21
|
||||
#define DIVERT_FILTER_FIELD_IP_DSTADDR 22
|
||||
#define DIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS 23
|
||||
#define DIVERT_FILTER_FIELD_IPV6_FLOWLABEL 24
|
||||
#define DIVERT_FILTER_FIELD_IPV6_LENGTH 25
|
||||
#define DIVERT_FILTER_FIELD_IPV6_NEXTHDR 26
|
||||
#define DIVERT_FILTER_FIELD_IPV6_HOPLIMIT 27
|
||||
#define DIVERT_FILTER_FIELD_IPV6_SRCADDR 28
|
||||
#define DIVERT_FILTER_FIELD_IPV6_DSTADDR 29
|
||||
#define DIVERT_FILTER_FIELD_ICMP_TYPE 30
|
||||
#define DIVERT_FILTER_FIELD_ICMP_CODE 31
|
||||
#define DIVERT_FILTER_FIELD_ICMP_CHECKSUM 32
|
||||
#define DIVERT_FILTER_FIELD_ICMP_BODY 33
|
||||
#define DIVERT_FILTER_FIELD_ICMPV6_TYPE 34
|
||||
#define DIVERT_FILTER_FIELD_ICMPV6_CODE 35
|
||||
#define DIVERT_FILTER_FIELD_ICMPV6_CHECKSUM 36
|
||||
#define DIVERT_FILTER_FIELD_ICMPV6_BODY 37
|
||||
#define DIVERT_FILTER_FIELD_TCP_SRCPORT 38
|
||||
#define DIVERT_FILTER_FIELD_TCP_DSTPORT 39
|
||||
#define DIVERT_FILTER_FIELD_TCP_SEQNUM 40
|
||||
#define DIVERT_FILTER_FIELD_TCP_ACKNUM 41
|
||||
#define DIVERT_FILTER_FIELD_TCP_HDRLENGTH 42
|
||||
#define DIVERT_FILTER_FIELD_TCP_URG 43
|
||||
#define DIVERT_FILTER_FIELD_TCP_ACK 44
|
||||
#define DIVERT_FILTER_FIELD_TCP_PSH 45
|
||||
#define DIVERT_FILTER_FIELD_TCP_RST 46
|
||||
#define DIVERT_FILTER_FIELD_TCP_SYN 47
|
||||
#define DIVERT_FILTER_FIELD_TCP_FIN 48
|
||||
#define DIVERT_FILTER_FIELD_TCP_WINDOW 49
|
||||
#define DIVERT_FILTER_FIELD_TCP_CHECKSUM 50
|
||||
#define DIVERT_FILTER_FIELD_TCP_URGPTR 51
|
||||
#define DIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH 52
|
||||
#define DIVERT_FILTER_FIELD_UDP_SRCPORT 53
|
||||
#define DIVERT_FILTER_FIELD_UDP_DSTPORT 54
|
||||
#define DIVERT_FILTER_FIELD_UDP_LENGTH 55
|
||||
#define DIVERT_FILTER_FIELD_UDP_CHECKSUM 56
|
||||
#define DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH 57
|
||||
#define DIVERT_FILTER_FIELD_MAX \
|
||||
DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH
|
||||
|
||||
#define DIVERT_FILTER_TEST_EQ 0
|
||||
#define DIVERT_FILTER_TEST_NEQ 1
|
||||
#define DIVERT_FILTER_TEST_LT 2
|
||||
#define DIVERT_FILTER_TEST_LEQ 3
|
||||
#define DIVERT_FILTER_TEST_GT 4
|
||||
#define DIVERT_FILTER_TEST_GEQ 5
|
||||
#define DIVERT_FILTER_TEST_MAX DIVERT_FILTER_TEST_GEQ
|
||||
|
||||
#define DIVERT_FILTER_MAXLEN 64
|
||||
|
||||
#define DIVERT_FILTER_RESULT_ACCEPT (DIVERT_FILTER_MAXLEN+1)
|
||||
#define DIVERT_FILTER_RESULT_REJECT (DIVERT_FILTER_MAXLEN+2)
|
||||
|
||||
/*
|
||||
* Packet definitions.
|
||||
*/
|
||||
#ifndef DIVERT_PACKET_DIRECTION_OUTBOUND
|
||||
#define DIVERT_PACKET_DIRECTION_OUTBOUND 0
|
||||
#define DIVERT_PACKET_DIRECTION_INBOUND 1
|
||||
#endif /* DIVERT_PACKET_DIRECTION_OUTBOUND */
|
||||
|
||||
/*
|
||||
* Message definitions.
|
||||
*/
|
||||
struct divert_message_s
|
||||
{
|
||||
UINT16 magic; // DIVERT_MAGIC
|
||||
UINT8 version; // DIVERT_VERSION
|
||||
UINT8 reserved; // Reserved (set to 0x0)
|
||||
};
|
||||
typedef struct divert_message_s *divert_message_t;
|
||||
|
||||
/*
|
||||
* IOCTL structures.
|
||||
*/
|
||||
struct divert_ioctl_filter_s
|
||||
{
|
||||
UINT8 field; // DIVERT_FILTER_FIELD_IP_*
|
||||
UINT8 test; // DIVERT_FILTER_TEST_*
|
||||
UINT8 success; // Success continuation.
|
||||
UINT8 failure; // Fail continuation.
|
||||
UINT32 arg[4]; // Argument.
|
||||
};
|
||||
typedef struct divert_ioctl_filter_s *divert_ioctl_filter_t;
|
||||
|
||||
/*
|
||||
* IOCTL codes.
|
||||
*/
|
||||
#define IOCTL_DIVERT_SET_FILTER \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0x90A, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#endif // __DIVERT_DEVICE_H
|
||||
Reference in New Issue
Block a user