session.go raw
1 //go:build windows
2
3 /* SPDX-License-Identifier: MIT
4 *
5 * Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved.
6 */
7
8 package wintun
9
10 import (
11 "syscall"
12 "unsafe"
13
14 "golang.org/x/sys/windows"
15 )
16
17 type Session struct {
18 handle uintptr
19 }
20
21 const (
22 PacketSizeMax = 0xffff // Maximum packet size
23 RingCapacityMin = 0x20000 // Minimum ring capacity (128 kiB)
24 RingCapacityMax = 0x4000000 // Maximum ring capacity (64 MiB)
25 )
26
27 // Packet with data
28 type Packet struct {
29 Next *Packet // Pointer to next packet in queue
30 Size uint32 // Size of packet (max WINTUN_MAX_IP_PACKET_SIZE)
31 Data *[PacketSizeMax]byte // Pointer to layer 3 IPv4 or IPv6 packet
32 }
33
34 var (
35 procWintunAllocateSendPacket = modwintun.NewProc("WintunAllocateSendPacket")
36 procWintunEndSession = modwintun.NewProc("WintunEndSession")
37 procWintunGetReadWaitEvent = modwintun.NewProc("WintunGetReadWaitEvent")
38 procWintunReceivePacket = modwintun.NewProc("WintunReceivePacket")
39 procWintunReleaseReceivePacket = modwintun.NewProc("WintunReleaseReceivePacket")
40 procWintunSendPacket = modwintun.NewProc("WintunSendPacket")
41 procWintunStartSession = modwintun.NewProc("WintunStartSession")
42 )
43
44 func (wintun *Adapter) StartSession(capacity uint32) (session Session, err error) {
45 r0, _, e1 := syscall.Syscall(procWintunStartSession.Addr(), 2, uintptr(wintun.handle), uintptr(capacity), 0)
46 if r0 == 0 {
47 err = e1
48 } else {
49 session = Session{r0}
50 }
51 return
52 }
53
54 func (session Session) End() {
55 syscall.Syscall(procWintunEndSession.Addr(), 1, session.handle, 0, 0)
56 session.handle = 0
57 }
58
59 func (session Session) ReadWaitEvent() (handle windows.Handle) {
60 r0, _, _ := syscall.Syscall(procWintunGetReadWaitEvent.Addr(), 1, session.handle, 0, 0)
61 handle = windows.Handle(r0)
62 return
63 }
64
65 func (session Session) ReceivePacket() (packet []byte, err error) {
66 var packetSize uint32
67 r0, _, e1 := syscall.Syscall(procWintunReceivePacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packetSize)), 0)
68 if r0 == 0 {
69 err = e1
70 return
71 }
72 packet = unsafe.Slice((*byte)(unsafe.Pointer(r0)), packetSize)
73 return
74 }
75
76 func (session Session) ReleaseReceivePacket(packet []byte) {
77 syscall.Syscall(procWintunReleaseReceivePacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packet[0])), 0)
78 }
79
80 func (session Session) AllocateSendPacket(packetSize int) (packet []byte, err error) {
81 r0, _, e1 := syscall.Syscall(procWintunAllocateSendPacket.Addr(), 2, session.handle, uintptr(packetSize), 0)
82 if r0 == 0 {
83 err = e1
84 return
85 }
86 packet = unsafe.Slice((*byte)(unsafe.Pointer(r0)), packetSize)
87 return
88 }
89
90 func (session Session) SendPacket(packet []byte) {
91 syscall.Syscall(procWintunSendPacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packet[0])), 0)
92 }
93