mirror of
https://github.com/safing/portmaster
synced 2025-09-02 18:49:14 +00:00
Remove old windivert interception
This commit is contained in:
parent
81eee568f2
commit
960e1bcc16
7 changed files with 0 additions and 1019 deletions
|
@ -1,154 +0,0 @@
|
||||||
package windivert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/google/gopacket"
|
|
||||||
"github.com/google/gopacket/layers"
|
|
||||||
|
|
||||||
"github.com/Safing/safing-core/log"
|
|
||||||
"github.com/Safing/safing-core/network/packet"
|
|
||||||
|
|
||||||
"github.com/tevino/abool"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (wd *WinDivert) Packets(packets chan packet.Packet) error {
|
|
||||||
go wd.packetHandler(packets)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WinDivert) packetHandler(packets chan packet.Packet) {
|
|
||||||
defer close(packets)
|
|
||||||
|
|
||||||
for {
|
|
||||||
if !wd.valid.IsSet() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
packetData, packetAddress, err := wd.Recv()
|
|
||||||
if err != nil {
|
|
||||||
log.Warningf("failed to get packet from windivert: %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ipHeader, tpcUdpHeader, payload, err := parseIpPacket(packetData)
|
|
||||||
if err != nil {
|
|
||||||
log.Warningf("failed to parse packet from windivert: %s", err)
|
|
||||||
log.Warningf("failed packet payload (%d): %s", len(packetData), string(packetData))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
new := &Packet{
|
|
||||||
windivert: wd,
|
|
||||||
packetData: packetData,
|
|
||||||
packetAddress: packetAddress,
|
|
||||||
verdictSet: abool.NewBool(false),
|
|
||||||
}
|
|
||||||
new.IPHeader = ipHeader
|
|
||||||
new.TCPUDPHeader = tpcUdpHeader
|
|
||||||
new.Payload = payload
|
|
||||||
if packetAddress.Direction == directionInbound {
|
|
||||||
new.Direction = packet.InBound
|
|
||||||
} else {
|
|
||||||
new.Direction = packet.OutBound
|
|
||||||
}
|
|
||||||
|
|
||||||
packets <- new
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseIpPacket(packetData []byte) (ipHeader *packet.IPHeader, tpcUdpHeader *packet.TCPUDPHeader, payload []byte, err error) {
|
|
||||||
|
|
||||||
var parsedPacket gopacket.Packet
|
|
||||||
|
|
||||||
if len(packetData) == 0 {
|
|
||||||
return nil, nil, nil, errors.New("empty packet")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch packetData[0] >> 4 {
|
|
||||||
case 4:
|
|
||||||
parsedPacket = gopacket.NewPacket(packetData, layers.LayerTypeIPv4, gopacket.DecodeOptions{Lazy: true, NoCopy: true})
|
|
||||||
if ipv4Layer := parsedPacket.Layer(layers.LayerTypeIPv4); ipv4Layer != nil {
|
|
||||||
ipv4, _ := ipv4Layer.(*layers.IPv4)
|
|
||||||
ipHeader = &packet.IPHeader{
|
|
||||||
Version: 4,
|
|
||||||
Protocol: packet.IPProtocol(ipv4.Protocol),
|
|
||||||
Tos: ipv4.TOS,
|
|
||||||
TTL: ipv4.TTL,
|
|
||||||
Src: ipv4.SrcIP,
|
|
||||||
Dst: ipv4.DstIP,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
|
|
||||||
err = errLayer.Error()
|
|
||||||
}
|
|
||||||
return nil, nil, nil, fmt.Errorf("failed to parse IPv4 packet: %s", err)
|
|
||||||
}
|
|
||||||
case 6:
|
|
||||||
parsedPacket = gopacket.NewPacket(packetData, layers.LayerTypeIPv6, gopacket.DecodeOptions{Lazy: true, NoCopy: true})
|
|
||||||
if ipv6Layer := parsedPacket.Layer(layers.LayerTypeIPv6); ipv6Layer != nil {
|
|
||||||
ipv6, _ := ipv6Layer.(*layers.IPv6)
|
|
||||||
ipHeader = &packet.IPHeader{
|
|
||||||
Version: 6,
|
|
||||||
Protocol: packet.IPProtocol(ipv6.NextHeader),
|
|
||||||
Tos: ipv6.TrafficClass,
|
|
||||||
TTL: ipv6.HopLimit,
|
|
||||||
Src: ipv6.SrcIP,
|
|
||||||
Dst: ipv6.DstIP,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
|
|
||||||
err = errLayer.Error()
|
|
||||||
}
|
|
||||||
return nil, nil, nil, fmt.Errorf("failed to parse IPv6 packet: %s", err)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, nil, nil, errors.New("unknown IP version")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ipHeader.Protocol {
|
|
||||||
case packet.TCP:
|
|
||||||
if tcpLayer := parsedPacket.Layer(layers.LayerTypeTCP); tcpLayer != nil {
|
|
||||||
tcp, _ := tcpLayer.(*layers.TCP)
|
|
||||||
tpcUdpHeader = &packet.TCPUDPHeader{
|
|
||||||
SrcPort: uint16(tcp.SrcPort),
|
|
||||||
DstPort: uint16(tcp.DstPort),
|
|
||||||
Checksum: tcp.Checksum,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
|
|
||||||
err = errLayer.Error()
|
|
||||||
}
|
|
||||||
return nil, nil, nil, fmt.Errorf("could not parse TCP layer: %s", err)
|
|
||||||
}
|
|
||||||
case packet.UDP:
|
|
||||||
if udpLayer := parsedPacket.Layer(layers.LayerTypeUDP); udpLayer != nil {
|
|
||||||
udp, _ := udpLayer.(*layers.UDP)
|
|
||||||
tpcUdpHeader = &packet.TCPUDPHeader{
|
|
||||||
SrcPort: uint16(udp.SrcPort),
|
|
||||||
DstPort: uint16(udp.DstPort),
|
|
||||||
Checksum: udp.Checksum,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
|
|
||||||
err = errLayer.Error()
|
|
||||||
}
|
|
||||||
return nil, nil, nil, fmt.Errorf("could not parse UDP layer: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if appLayer := parsedPacket.ApplicationLayer(); appLayer != nil {
|
|
||||||
payload = appLayer.Payload()
|
|
||||||
}
|
|
||||||
|
|
||||||
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
|
|
||||||
return nil, nil, nil, errLayer.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
# Notes
|
|
||||||
|
|
||||||
## Interception
|
|
||||||
|
|
||||||
- use windivert DLL
|
|
||||||
- cgo or loadDLL?
|
|
||||||
|
|
||||||
- netfilter exmaple: https://reqrypt.org/samples/netfilter.html
|
|
||||||
- v1.4 docs: https://reqrypt.org/windivert-doc.html#divert_recv_ex
|
|
||||||
- source: https://github.com/basil00/Divert
|
|
||||||
|
|
||||||
- other GO package wrapping this: https://github.com/clmul/go-windivert/blob/master/divert_windows.go
|
|
||||||
|
|
||||||
## Packet/Process Attribution
|
|
||||||
|
|
||||||
- use Iphlpapi.dll
|
|
||||||
- GetExtendedTcpTable
|
|
||||||
- GetOwnerModuleFromTcpEntry
|
|
||||||
- GetExtendedUdpTable
|
|
||||||
- GetOwnerModuleFromUdpEntry
|
|
||||||
- for generic IP?
|
|
||||||
|
|
||||||
## Helpful resources
|
|
||||||
|
|
||||||
Calling Windows APIs
|
|
||||||
https://stackoverflow.com/questions/33709033/golang-how-can-i-call-win32-api-without-cgo#33709631
|
|
||||||
|
|
||||||
GetExtendedTcpTable (from Iphlpapi.dll)
|
|
||||||
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365928(v=vs.85).aspx
|
|
||||||
|
|
||||||
GetUdpTable Example
|
|
||||||
https://stackoverflow.com/questions/49167311/how-to-convert-uintptr-to-go-struct
|
|
|
@ -1,55 +0,0 @@
|
||||||
package windivert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Safing/safing-core/network/packet"
|
|
||||||
"github.com/tevino/abool"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Packet struct {
|
|
||||||
packet.PacketBase
|
|
||||||
|
|
||||||
windivert *WinDivert
|
|
||||||
packetData []byte
|
|
||||||
packetAddress *WinDivertAddress
|
|
||||||
|
|
||||||
verdictSet *abool.AtomicBool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *Packet) Accept() error {
|
|
||||||
if pkt.verdictSet.SetToIf(false, true) {
|
|
||||||
return pkt.windivert.Send(pkt.packetData, pkt.packetAddress)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *Packet) Block() error {
|
|
||||||
if pkt.verdictSet.SetToIf(false, true) {
|
|
||||||
// TODO: implement blocking mechanism
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *Packet) Drop() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *Packet) PermanentAccept() error {
|
|
||||||
return pkt.Accept()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *Packet) PermanentBlock() error {
|
|
||||||
return pkt.Block()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *Packet) PermanentDrop() error {
|
|
||||||
return pkt.Drop()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *Packet) RerouteToNameserver() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkt *Packet) RerouteToTunnel() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# get build data
|
|
||||||
if [[ "$BUILD_COMMIT" == "" ]]; then
|
|
||||||
BUILD_COMMIT=$(git describe --all --long --abbrev=99 --dirty 2>/dev/null)
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_USER" == "" ]]; then
|
|
||||||
BUILD_USER=$(id -un)
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_HOST" == "" ]]; then
|
|
||||||
BUILD_HOST=$(hostname -f)
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_DATE" == "" ]]; then
|
|
||||||
BUILD_DATE=$(date +%d.%m.%Y)
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_SOURCE" == "" ]]; then
|
|
||||||
BUILD_SOURCE=$(git remote -v | grep origin | cut -f2 | cut -d" " -f1 | head -n 1)
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_SOURCE" == "" ]]; then
|
|
||||||
BUILD_SOURCE=$(git remote -v | cut -f2 | cut -d" " -f1 | head -n 1)
|
|
||||||
fi
|
|
||||||
BUILD_BUILDOPTIONS=$(echo $* | sed "s/ /§/g")
|
|
||||||
|
|
||||||
# check
|
|
||||||
if [[ "$BUILD_COMMIT" == "" ]]; then
|
|
||||||
echo "could not automatically determine BUILD_COMMIT, please supply manually as environment variable."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_USER" == "" ]]; then
|
|
||||||
echo "could not automatically determine BUILD_USER, please supply manually as environment variable."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_HOST" == "" ]]; then
|
|
||||||
echo "could not automatically determine BUILD_HOST, please supply manually as environment variable."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_DATE" == "" ]]; then
|
|
||||||
echo "could not automatically determine BUILD_DATE, please supply manually as environment variable."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [[ "$BUILD_SOURCE" == "" ]]; then
|
|
||||||
echo "could not automatically determine BUILD_SOURCE, please supply manually as environment variable."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Please notice, that this build script includes metadata into the build."
|
|
||||||
echo "This information is useful for debugging and license compliance."
|
|
||||||
echo "Run the compiled binary with the -v flag to see the information included."
|
|
||||||
|
|
||||||
# build
|
|
||||||
if [[ "$BUILD_PATH" == "" ]]; then
|
|
||||||
BUILD_PATH=$(go list)
|
|
||||||
fi
|
|
||||||
go build -ldflags "-X ${BUILD_PATH}/meta.commit=${BUILD_COMMIT} -X ${BUILD_PATH}/meta.buildOptions=${BUILD_BUILDOPTIONS} -X ${BUILD_PATH}/meta.buildUser=${BUILD_USER} -X ${BUILD_PATH}/meta.buildHost=${BUILD_HOST} -X ${BUILD_PATH}/meta.buildDate=${BUILD_DATE} -X ${BUILD_PATH}/meta.buildSource=${BUILD_SOURCE}" $*
|
|
|
@ -1,66 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"runtime/pprof"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Safing/safing-core/firewall/interception/windivert"
|
|
||||||
"github.com/Safing/safing-core/log"
|
|
||||||
"github.com/Safing/safing-core/modules"
|
|
||||||
"github.com/Safing/safing-core/network/packet"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
modules.RegisterLogger(log.Logger)
|
|
||||||
|
|
||||||
wd, err := windivert.New("C:/WinDivert.dll", "")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer wd.Close()
|
|
||||||
|
|
||||||
packets := make(chan packet.Packet, 1000)
|
|
||||||
wd.Packets(packets)
|
|
||||||
go func() {
|
|
||||||
for pkt := range packets {
|
|
||||||
log.Infof("pkt: %s", pkt)
|
|
||||||
if pkt.GetIPHeader().Protocol == 0 || pkt.GetIPHeader().Protocol == 128 {
|
|
||||||
pl := pkt.GetPayload()
|
|
||||||
log.Infof("payload (%d): %s", len(pl), string(pl))
|
|
||||||
}
|
|
||||||
pkt.Accept()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// SHUTDOWN
|
|
||||||
// catch interrupt for clean shutdown
|
|
||||||
signalCh := make(chan os.Signal)
|
|
||||||
signal.Notify(
|
|
||||||
signalCh,
|
|
||||||
os.Interrupt,
|
|
||||||
os.Kill,
|
|
||||||
syscall.SIGHUP,
|
|
||||||
syscall.SIGINT,
|
|
||||||
syscall.SIGTERM,
|
|
||||||
syscall.SIGQUIT,
|
|
||||||
syscall.SIGKILL,
|
|
||||||
syscall.SIGSEGV,
|
|
||||||
)
|
|
||||||
select {
|
|
||||||
case <-signalCh:
|
|
||||||
log.Warning("program was interrupted, shutting down.")
|
|
||||||
modules.InitiateFullShutdown()
|
|
||||||
case <-modules.GlobalShutdown:
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for shutdown to complete, panic after timeout
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
fmt.Println("===== TAKING TOO LONG FOR SHUTDOWN - PRINTING STACK TRACES =====")
|
|
||||||
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
|
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
package windivert
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
|
||||||
|
|
||||||
"github.com/tevino/abool"
|
|
||||||
)
|
|
||||||
|
|
||||||
type WinDivert struct {
|
|
||||||
dll *windows.DLL
|
|
||||||
handle uintptr
|
|
||||||
|
|
||||||
open *windows.Proc
|
|
||||||
recv *windows.Proc
|
|
||||||
send *windows.Proc
|
|
||||||
close *windows.Proc
|
|
||||||
setParam *windows.Proc
|
|
||||||
getParam *windows.Proc
|
|
||||||
helperCalcChecksums *windows.Proc
|
|
||||||
helperCheckFilter *windows.Proc
|
|
||||||
|
|
||||||
valid *abool.AtomicBool
|
|
||||||
}
|
|
||||||
|
|
||||||
// copied from windivert.h
|
|
||||||
type WinDivertAddress struct {
|
|
||||||
Timestamp int64 /* Packet's timestamp. */
|
|
||||||
IfIdx uint32 /* Packet's interface index. */
|
|
||||||
SubIfIdx uint32 /* Packet's sub-interface index. */
|
|
||||||
Direction uint8 /* Packet's direction. */
|
|
||||||
Loopback uint8 /* Packet is loopback? */
|
|
||||||
Impostor uint8 /* Packet is impostor? */
|
|
||||||
PseudoIPChecksum uint8 /* Packet has pseudo IPv4 checksum? */
|
|
||||||
PseudoTCPChecksum uint8 /* Packet has pseudo TCP checksum? */
|
|
||||||
PseudoUDPChecksum uint8 /* Packet has pseudo UDP checksum? */
|
|
||||||
Reserved uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
// copied from windivert.h
|
|
||||||
const (
|
|
||||||
directionInbound uint8 = 1
|
|
||||||
directionOutbound uint8 = 0
|
|
||||||
|
|
||||||
// Divert layers
|
|
||||||
layerNetwork uintptr = 0 /* Network layer. */
|
|
||||||
layerNetworkForward uintptr = 1 /* Network layer (forwarded packets) */
|
|
||||||
|
|
||||||
// Divert parameters
|
|
||||||
flagSniff uintptr = 1
|
|
||||||
flagDrop uintptr = 2
|
|
||||||
flagDebug uintptr = 4
|
|
||||||
|
|
||||||
paramQueueLen uintptr = 0 /* Packet queue length. */
|
|
||||||
paramQueueTime uintptr = 1 /* Packet queue time. */
|
|
||||||
paramQueueSize uintptr = 2 /* Packet queue size. */
|
|
||||||
|
|
||||||
rvInvalidHandle int = -1
|
|
||||||
rvFalse uintptr = 0
|
|
||||||
rvTrue uintptr = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
func New(dllLocation, filter string) (*WinDivert, error) {
|
|
||||||
|
|
||||||
new := &WinDivert{}
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// load dll
|
|
||||||
new.dll, err = windows.LoadDLL(dllLocation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// load functions
|
|
||||||
new.open, err = new.dll.FindProc("WinDivertOpen")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not find proc WinDivertOpen: %s", err)
|
|
||||||
}
|
|
||||||
new.recv, err = new.dll.FindProc("WinDivertRecv")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not find proc WinDivertRecv: %s", err)
|
|
||||||
}
|
|
||||||
new.send, err = new.dll.FindProc("WinDivertSend")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not find proc WinDivertSend: %s", err)
|
|
||||||
}
|
|
||||||
new.close, err = new.dll.FindProc("WinDivertClose")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not find proc WinDivertClose: %s", err)
|
|
||||||
}
|
|
||||||
new.setParam, err = new.dll.FindProc("WinDivertSetParam")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not find proc WinDivertSetParam: %s", err)
|
|
||||||
}
|
|
||||||
new.getParam, err = new.dll.FindProc("WinDivertGetParam")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not find proc WinDivertGetParam: %s", err)
|
|
||||||
}
|
|
||||||
new.helperCalcChecksums, err = new.dll.FindProc("WinDivertHelperCalcChecksums")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not find proc WinDivertHelperCalcChecksums: %s", err)
|
|
||||||
}
|
|
||||||
new.helperCheckFilter, err = new.dll.FindProc("WinDivertHelperCheckFilter")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not find proc WinDivertHelperCheckFilter: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// default filter
|
|
||||||
if filter == "" {
|
|
||||||
filter = "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
// open
|
|
||||||
err = new.Open(filter)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not open new windivert handle: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return new, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WinDivert) Open(filter string) error {
|
|
||||||
|
|
||||||
r1, _, lastErr := wd.open.Call(
|
|
||||||
stringToPtr(filter), // __in const char *filter
|
|
||||||
layerNetwork, // __in WINDIVERT_LAYER layer
|
|
||||||
0, // __in INT16 priority
|
|
||||||
0, // __in UINT64 flags
|
|
||||||
)
|
|
||||||
if int(r1) == rvInvalidHandle {
|
|
||||||
return lastErr
|
|
||||||
}
|
|
||||||
|
|
||||||
wd.handle = r1
|
|
||||||
wd.valid = abool.NewBool(true)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WinDivert) Recv() ([]byte, *WinDivertAddress, error) {
|
|
||||||
buf := make([]byte, 4096) // TODO: we can do this better
|
|
||||||
address := &WinDivertAddress{}
|
|
||||||
readLen := 0
|
|
||||||
|
|
||||||
r1, _, lastErr := wd.recv.Call(
|
|
||||||
wd.handle, // __in HANDLE handle
|
|
||||||
byteSliceToPtr(buf), // __out PVOID pPacket
|
|
||||||
uintptr(len(buf)), // __in UINT packetLen
|
|
||||||
uintptr(unsafe.Pointer(address)), // __out_opt PWINDIVERT_ADDRESS pAddr
|
|
||||||
uintptr(unsafe.Pointer(&readLen)), // __out_opt UINT *readLen
|
|
||||||
)
|
|
||||||
if r1 == rvFalse {
|
|
||||||
return nil, nil, lastErr
|
|
||||||
}
|
|
||||||
if readLen == 0 {
|
|
||||||
return nil, nil, errors.New("empty read")
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf[:readLen], address, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WinDivert) Send(packetData []byte, address *WinDivertAddress) error {
|
|
||||||
writeLen := 0
|
|
||||||
|
|
||||||
r1, _, lastErr := wd.send.Call(
|
|
||||||
wd.handle, // __in HANDLE handle
|
|
||||||
byteSliceToPtr(packetData), // __in PVOID pPacket
|
|
||||||
uintptr(len(packetData)), // __in UINT packetLen
|
|
||||||
uintptr(unsafe.Pointer(address)), // __in PWINDIVERT_ADDRESS pAddr
|
|
||||||
uintptr(unsafe.Pointer(&writeLen)), // __out_opt UINT *writeLen
|
|
||||||
)
|
|
||||||
if r1 == rvFalse {
|
|
||||||
return lastErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WinDivert) Close() error {
|
|
||||||
r1, _, lastErr := wd.close.Call(
|
|
||||||
wd.handle, // __in HANDLE handle
|
|
||||||
)
|
|
||||||
if r1 == rvFalse {
|
|
||||||
return lastErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WinDivert) SetParam(param, value uintptr) error {
|
|
||||||
r1, _, lastErr := wd.setParam.Call(
|
|
||||||
wd.handle, // __in HANDLE handle
|
|
||||||
param, // __in WINDIVERT_PARAM param
|
|
||||||
value, // __in UINT64 value
|
|
||||||
)
|
|
||||||
if r1 == rvFalse {
|
|
||||||
return lastErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WinDivert) GetParam(param uintptr) (uint64, error) {
|
|
||||||
var value uint64
|
|
||||||
|
|
||||||
r1, _, lastErr := wd.getParam.Call(
|
|
||||||
wd.handle, // __in HANDLE handle
|
|
||||||
param, // __in WINDIVERT_PARAM param
|
|
||||||
uintptr(unsafe.Pointer(&value)), // __out UINT64 *pValue
|
|
||||||
)
|
|
||||||
if r1 == rvFalse {
|
|
||||||
return 0, lastErr
|
|
||||||
}
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wd *WinDivert) HelperCalcChecksums(packetData []byte, address *WinDivertAddress, flags uintptr) error {
|
|
||||||
r1, _, lastErr := wd.setParam.Call(
|
|
||||||
byteSliceToPtr(packetData), // __inout PVOID pPacket
|
|
||||||
uintptr(len(packetData)), // __in UINT packetLen
|
|
||||||
uintptr(unsafe.Pointer(address)), // __in_opt PWINDIVERT_ADDRESS pAddr
|
|
||||||
flags, // __in UINT64 flags
|
|
||||||
)
|
|
||||||
if r1 == rvFalse {
|
|
||||||
return lastErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (wd *WinDivert) HelperCheckFilter() {
|
|
||||||
// // __in const char *filter
|
|
||||||
// // __in WINDIVERT_LAYER layer
|
|
||||||
// // __out_opt const char **errorStr
|
|
||||||
// // __out_opt UINT *errorPos
|
|
||||||
// }
|
|
||||||
|
|
||||||
func stringToPtr(s string) uintptr {
|
|
||||||
if !strings.HasSuffix(s, "\x00") {
|
|
||||||
s = s + "\x00"
|
|
||||||
}
|
|
||||||
a := []byte(s)
|
|
||||||
return uintptr(unsafe.Pointer(&a[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func byteSliceToPtr(a []byte) uintptr {
|
|
||||||
return uintptr(unsafe.Pointer(&a[0]))
|
|
||||||
}
|
|
|
@ -1,410 +0,0 @@
|
||||||
/*
|
|
||||||
* windivert.h
|
|
||||||
* (C) 2018, all rights reserved,
|
|
||||||
*
|
|
||||||
* This file is part of WinDivert.
|
|
||||||
*
|
|
||||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
|
||||||
* the terms of the GNU Lesser 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 Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* WinDivert 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 2 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, write to the Free Software Foundation, Inc., 51
|
|
||||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __WINDIVERT_H
|
|
||||||
#define __WINDIVERT_H
|
|
||||||
|
|
||||||
#ifndef WINDIVERT_KERNEL
|
|
||||||
#include <windows.h>
|
|
||||||
#endif /* WINDIVERT_KERNEL */
|
|
||||||
|
|
||||||
#ifndef WINDIVERTEXPORT
|
|
||||||
#define WINDIVERTEXPORT __declspec(dllimport)
|
|
||||||
#endif /* WINDIVERTEXPORT */
|
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
#define __in
|
|
||||||
#define __in_opt
|
|
||||||
#define __out
|
|
||||||
#define __out_opt
|
|
||||||
#define __inout
|
|
||||||
#define __inout_opt
|
|
||||||
#include <stdint.h>
|
|
||||||
#define INT8 int8_t
|
|
||||||
#define UINT8 uint8_t
|
|
||||||
#define INT16 int16_t
|
|
||||||
#define UINT16 uint16_t
|
|
||||||
#define INT32 int32_t
|
|
||||||
#define UINT32 uint32_t
|
|
||||||
#define INT64 int64_t
|
|
||||||
#define UINT64 uint64_t
|
|
||||||
#endif /* __MINGW32__ */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/* WINDIVERT API */
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Divert address.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
INT64 Timestamp; /* Packet's timestamp. */
|
|
||||||
UINT32 IfIdx; /* Packet's interface index. */
|
|
||||||
UINT32 SubIfIdx; /* Packet's sub-interface index. */
|
|
||||||
UINT8 Direction:1; /* Packet's direction. */
|
|
||||||
UINT8 Loopback:1; /* Packet is loopback? */
|
|
||||||
UINT8 Impostor:1; /* Packet is impostor? */
|
|
||||||
UINT8 PseudoIPChecksum:1; /* Packet has pseudo IPv4 checksum? */
|
|
||||||
UINT8 PseudoTCPChecksum:1; /* Packet has pseudo TCP checksum? */
|
|
||||||
UINT8 PseudoUDPChecksum:1; /* Packet has pseudo UDP checksum? */
|
|
||||||
UINT8 Reserved:2;
|
|
||||||
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
|
|
||||||
|
|
||||||
#define WINDIVERT_DIRECTION_OUTBOUND 0
|
|
||||||
#define WINDIVERT_DIRECTION_INBOUND 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Divert layers.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */
|
|
||||||
WINDIVERT_LAYER_NETWORK_FORWARD = 1 /* Network layer (forwarded packets) */
|
|
||||||
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Divert flags.
|
|
||||||
*/
|
|
||||||
#define WINDIVERT_FLAG_SNIFF 1
|
|
||||||
#define WINDIVERT_FLAG_DROP 2
|
|
||||||
#define WINDIVERT_FLAG_DEBUG 4
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Divert parameters.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
WINDIVERT_PARAM_QUEUE_LEN = 0, /* Packet queue length. */
|
|
||||||
WINDIVERT_PARAM_QUEUE_TIME = 1, /* Packet queue time. */
|
|
||||||
WINDIVERT_PARAM_QUEUE_SIZE = 2 /* Packet queue size. */
|
|
||||||
} WINDIVERT_PARAM, *PWINDIVERT_PARAM;
|
|
||||||
#define WINDIVERT_PARAM_MAX WINDIVERT_PARAM_QUEUE_SIZE
|
|
||||||
|
|
||||||
#ifndef WINDIVERT_KERNEL
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Open a WinDivert handle.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT HANDLE WinDivertOpen(
|
|
||||||
__in const char *filter,
|
|
||||||
__in WINDIVERT_LAYER layer,
|
|
||||||
__in INT16 priority,
|
|
||||||
__in UINT64 flags);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Receive (read) a packet from a WinDivert handle.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertRecv(
|
|
||||||
__in HANDLE handle,
|
|
||||||
__out PVOID pPacket,
|
|
||||||
__in UINT packetLen,
|
|
||||||
__out_opt PWINDIVERT_ADDRESS pAddr,
|
|
||||||
__out_opt UINT *readLen);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Receive (read) a packet from a WinDivert handle.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertRecvEx(
|
|
||||||
__in HANDLE handle,
|
|
||||||
__out PVOID pPacket,
|
|
||||||
__in UINT packetLen,
|
|
||||||
__in UINT64 flags,
|
|
||||||
__out_opt PWINDIVERT_ADDRESS pAddr,
|
|
||||||
__out_opt UINT *readLen,
|
|
||||||
__inout_opt LPOVERLAPPED lpOverlapped);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Send (write/inject) a packet to a WinDivert handle.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertSend(
|
|
||||||
__in HANDLE handle,
|
|
||||||
__in PVOID pPacket,
|
|
||||||
__in UINT packetLen,
|
|
||||||
__in PWINDIVERT_ADDRESS pAddr,
|
|
||||||
__out_opt UINT *writeLen);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Send (write/inject) a packet to a WinDivert handle.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertSendEx(
|
|
||||||
__in HANDLE handle,
|
|
||||||
__in PVOID pPacket,
|
|
||||||
__in UINT packetLen,
|
|
||||||
__in UINT64 flags,
|
|
||||||
__in PWINDIVERT_ADDRESS pAddr,
|
|
||||||
__out_opt UINT *writeLen,
|
|
||||||
__inout_opt LPOVERLAPPED lpOverlapped);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Close a WinDivert handle.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertClose(
|
|
||||||
__in HANDLE handle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a WinDivert handle parameter.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertSetParam(
|
|
||||||
__in HANDLE handle,
|
|
||||||
__in WINDIVERT_PARAM param,
|
|
||||||
__in UINT64 value);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a WinDivert handle parameter.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertGetParam(
|
|
||||||
__in HANDLE handle,
|
|
||||||
__in WINDIVERT_PARAM param,
|
|
||||||
__out UINT64 *pValue);
|
|
||||||
|
|
||||||
#endif /* WINDIVERT_KERNEL */
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/* WINDIVERT 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;
|
|
||||||
} WINDIVERT_IPHDR, *PWINDIVERT_IPHDR;
|
|
||||||
|
|
||||||
#define WINDIVERT_IPHDR_GET_FRAGOFF(hdr) \
|
|
||||||
(((hdr)->FragOff0) & 0xFF1F)
|
|
||||||
#define WINDIVERT_IPHDR_GET_MF(hdr) \
|
|
||||||
((((hdr)->FragOff0) & 0x0020) != 0)
|
|
||||||
#define WINDIVERT_IPHDR_GET_DF(hdr) \
|
|
||||||
((((hdr)->FragOff0) & 0x0040) != 0)
|
|
||||||
#define WINDIVERT_IPHDR_GET_RESERVED(hdr) \
|
|
||||||
((((hdr)->FragOff0) & 0x0080) != 0)
|
|
||||||
|
|
||||||
#define WINDIVERT_IPHDR_SET_FRAGOFF(hdr, val) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0x00E0) | \
|
|
||||||
((val) & 0xFF1F); \
|
|
||||||
} \
|
|
||||||
while (FALSE)
|
|
||||||
#define WINDIVERT_IPHDR_SET_MF(hdr, val) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFFDF) | \
|
|
||||||
(((val) & 0x0001) << 5); \
|
|
||||||
} \
|
|
||||||
while (FALSE)
|
|
||||||
#define WINDIVERT_IPHDR_SET_DF(hdr, val) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFFBF) | \
|
|
||||||
(((val) & 0x0001) << 6); \
|
|
||||||
} \
|
|
||||||
while (FALSE)
|
|
||||||
#define WINDIVERT_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];
|
|
||||||
} WINDIVERT_IPV6HDR, *PWINDIVERT_IPV6HDR;
|
|
||||||
|
|
||||||
#define WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(hdr) \
|
|
||||||
((((hdr)->TrafficClass0) << 4) | ((hdr)->TrafficClass1))
|
|
||||||
#define WINDIVERT_IPV6HDR_GET_FLOWLABEL(hdr) \
|
|
||||||
((((UINT32)(hdr)->FlowLabel0) << 16) | ((UINT32)(hdr)->FlowLabel1))
|
|
||||||
|
|
||||||
#define WINDIVERT_IPV6HDR_SET_TRAFFICCLASS(hdr, val) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
(hdr)->TrafficClass0 = ((UINT8)(val) >> 4); \
|
|
||||||
(hdr)->TrafficClass1 = (UINT8)(val); \
|
|
||||||
} \
|
|
||||||
while (FALSE)
|
|
||||||
#define WINDIVERT_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;
|
|
||||||
} WINDIVERT_ICMPHDR, *PWINDIVERT_ICMPHDR;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UINT8 Type;
|
|
||||||
UINT8 Code;
|
|
||||||
UINT16 Checksum;
|
|
||||||
UINT32 Body;
|
|
||||||
} WINDIVERT_ICMPV6HDR, *PWINDIVERT_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;
|
|
||||||
} WINDIVERT_TCPHDR, *PWINDIVERT_TCPHDR;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UINT16 SrcPort;
|
|
||||||
UINT16 DstPort;
|
|
||||||
UINT16 Length;
|
|
||||||
UINT16 Checksum;
|
|
||||||
} WINDIVERT_UDPHDR, *PWINDIVERT_UDPHDR;
|
|
||||||
|
|
||||||
#ifndef WINDIVERT_KERNEL
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Flags for WinDivertHelperCalcChecksums()
|
|
||||||
*/
|
|
||||||
#define WINDIVERT_HELPER_NO_IP_CHECKSUM 1
|
|
||||||
#define WINDIVERT_HELPER_NO_ICMP_CHECKSUM 2
|
|
||||||
#define WINDIVERT_HELPER_NO_ICMPV6_CHECKSUM 4
|
|
||||||
#define WINDIVERT_HELPER_NO_TCP_CHECKSUM 8
|
|
||||||
#define WINDIVERT_HELPER_NO_UDP_CHECKSUM 16
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
|
|
||||||
__in PVOID pPacket,
|
|
||||||
__in UINT packetLen,
|
|
||||||
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
|
|
||||||
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
|
|
||||||
__out_opt PWINDIVERT_ICMPHDR *ppIcmpHdr,
|
|
||||||
__out_opt PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
|
|
||||||
__out_opt PWINDIVERT_TCPHDR *ppTcpHdr,
|
|
||||||
__out_opt PWINDIVERT_UDPHDR *ppUdpHdr,
|
|
||||||
__out_opt PVOID *ppData,
|
|
||||||
__out_opt UINT *pDataLen);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse an IPv4 address.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv4Address(
|
|
||||||
__in const char *addrStr,
|
|
||||||
__out_opt UINT32 *pAddr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse an IPv6 address.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
|
|
||||||
__in const char *addrStr,
|
|
||||||
__out_opt UINT32 *pAddr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT UINT WinDivertHelperCalcChecksums(
|
|
||||||
__inout PVOID pPacket,
|
|
||||||
__in UINT packetLen,
|
|
||||||
__in_opt PWINDIVERT_ADDRESS pAddr,
|
|
||||||
__in UINT64 flags);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check the given filter string.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertHelperCheckFilter(
|
|
||||||
__in const char *filter,
|
|
||||||
__in WINDIVERT_LAYER layer,
|
|
||||||
__out_opt const char **errorStr,
|
|
||||||
__out_opt UINT *errorPos);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Evaluate the given filter string.
|
|
||||||
*/
|
|
||||||
extern WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
|
|
||||||
__in const char *filter,
|
|
||||||
__in WINDIVERT_LAYER layer,
|
|
||||||
__in PVOID pPacket,
|
|
||||||
__in UINT packetLen,
|
|
||||||
__in PWINDIVERT_ADDRESS pAddr);
|
|
||||||
|
|
||||||
#endif /* WINDIVERT_KERNEL */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __WINDIVERT_H */
|
|
Loading…
Add table
Reference in a new issue