golang.zx2c4.com/wireguard/windows@v0.5.4-0.20230123132234-dcc0eb72a04b/driver/configuration_windows.go (about) 1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (C) 2017-2022 WireGuard LLC. All Rights Reserved. 4 */ 5 6 package driver 7 8 import ( 9 "syscall" 10 "unsafe" 11 12 "golang.org/x/sys/windows" 13 "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" 14 ) 15 16 type AdapterState uint32 17 18 const ( 19 AdapterStateDown AdapterState = 0 20 AdapterStateUp AdapterState = 1 21 ) 22 23 type AllowedIP struct { 24 Address [16]byte 25 AddressFamily winipcfg.AddressFamily 26 Cidr uint8 27 _ [4]byte 28 } 29 30 type PeerFlag uint32 31 32 const ( 33 PeerHasPublicKey PeerFlag = 1 << 0 34 PeerHasPresharedKey PeerFlag = 1 << 1 35 PeerHasPersistentKeepalive PeerFlag = 1 << 2 36 PeerHasEndpoint PeerFlag = 1 << 3 37 PeerReplaceAllowedIPs PeerFlag = 1 << 5 38 PeerRemove PeerFlag = 1 << 6 39 PeerUpdateOnly PeerFlag = 1 << 7 40 ) 41 42 type Peer struct { 43 Flags PeerFlag 44 _ uint32 45 PublicKey [32]byte 46 PresharedKey [32]byte 47 PersistentKeepalive uint16 48 _ uint16 49 Endpoint winipcfg.RawSockaddrInet 50 TxBytes uint64 51 RxBytes uint64 52 LastHandshake uint64 53 AllowedIPsCount uint32 54 _ [4]byte 55 } 56 57 type InterfaceFlag uint32 58 59 const ( 60 InterfaceHasPublicKey InterfaceFlag = 1 << 0 61 InterfaceHasPrivateKey InterfaceFlag = 1 << 1 62 InterfaceHasListenPort InterfaceFlag = 1 << 2 63 InterfaceReplacePeers InterfaceFlag = 1 << 3 64 ) 65 66 type Interface struct { 67 Flags InterfaceFlag 68 ListenPort uint16 69 PrivateKey [32]byte 70 PublicKey [32]byte 71 PeerCount uint32 72 _ [4]byte 73 } 74 75 var ( 76 procWireGuardSetAdapterState = modwireguard.NewProc("WireGuardSetAdapterState") 77 procWireGuardGetAdapterState = modwireguard.NewProc("WireGuardGetAdapterState") 78 procWireGuardSetConfiguration = modwireguard.NewProc("WireGuardSetConfiguration") 79 procWireGuardGetConfiguration = modwireguard.NewProc("WireGuardGetConfiguration") 80 ) 81 82 // SetAdapterState sets the adapter either Up or Down. 83 func (wireguard *Adapter) SetAdapterState(adapterState AdapterState) (err error) { 84 r0, _, e1 := syscall.SyscallN(procWireGuardSetAdapterState.Addr(), wireguard.handle, uintptr(adapterState)) 85 if r0 == 0 { 86 err = e1 87 } 88 return 89 } 90 91 // AdapterState returns the current state of the adapter. 92 func (wireguard *Adapter) AdapterState() (adapterState AdapterState, err error) { 93 r0, _, e1 := syscall.SyscallN(procWireGuardGetAdapterState.Addr(), wireguard.handle, uintptr(unsafe.Pointer(&adapterState))) 94 if r0 == 0 { 95 err = e1 96 } 97 return 98 } 99 100 // SetConfiguration sets the adapter configuration. 101 func (wireguard *Adapter) SetConfiguration(interfaze *Interface, size uint32) (err error) { 102 r0, _, e1 := syscall.SyscallN(procWireGuardSetConfiguration.Addr(), wireguard.handle, uintptr(unsafe.Pointer(interfaze)), uintptr(size)) 103 if r0 == 0 { 104 err = e1 105 } 106 return 107 } 108 109 // Configuration gets the adapter configuration. 110 func (wireguard *Adapter) Configuration() (interfaze *Interface, err error) { 111 size := wireguard.lastGetGuessSize 112 if size == 0 { 113 size = 512 114 } 115 for { 116 buf := make([]byte, size) 117 r0, _, e1 := syscall.SyscallN(procWireGuardGetConfiguration.Addr(), wireguard.handle, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&size))) 118 if r0 != 0 { 119 wireguard.lastGetGuessSize = size 120 return (*Interface)(unsafe.Pointer(&buf[0])), nil 121 } 122 if e1 != windows.ERROR_MORE_DATA { 123 return nil, e1 124 } 125 } 126 } 127 128 // FirstPeer returns the first peer attached to the interface. 129 func (interfaze *Interface) FirstPeer() *Peer { 130 return (*Peer)(unsafe.Add(unsafe.Pointer(interfaze), unsafe.Sizeof(*interfaze))) 131 } 132 133 // NextPeer returns the subsequent peer of the current one. 134 func (peer *Peer) NextPeer() *Peer { 135 return (*Peer)(unsafe.Pointer(uintptr(unsafe.Pointer(peer)) + unsafe.Sizeof(*peer) + uintptr(peer.AllowedIPsCount)*unsafe.Sizeof(AllowedIP{}))) 136 } 137 138 // FirstAllowedIP returns the first allowed IP attached to the peer. 139 func (peer *Peer) FirstAllowedIP() *AllowedIP { 140 return (*AllowedIP)(unsafe.Add(unsafe.Pointer(peer), unsafe.Sizeof(*peer))) 141 } 142 143 // NextAllowedIP returns the subsequent allowed IP of the current one. 144 func (allowedIP *AllowedIP) NextAllowedIP() *AllowedIP { 145 return (*AllowedIP)(unsafe.Add(unsafe.Pointer(allowedIP), unsafe.Sizeof(*allowedIP))) 146 } 147 148 type ConfigBuilder struct { 149 buffer []byte 150 } 151 152 // Preallocate reserves memory in the config builder to reduce allocations of append operations. 153 func (builder *ConfigBuilder) Preallocate(size uint32) { 154 if builder.buffer == nil { 155 builder.buffer = make([]byte, 0, size) 156 } 157 } 158 159 // AppendInterface appends an interface to the building configuration. This should be called first. 160 func (builder *ConfigBuilder) AppendInterface(interfaze *Interface) { 161 newBytes := unsafe.Slice((*byte)(unsafe.Pointer(interfaze)), unsafe.Sizeof(*interfaze)) 162 builder.buffer = append(builder.buffer, newBytes...) 163 } 164 165 // AppendPeer appends a peer to the building configuration. This should be called after an interface has been added. 166 func (builder *ConfigBuilder) AppendPeer(peer *Peer) { 167 newBytes := unsafe.Slice((*byte)(unsafe.Pointer(peer)), unsafe.Sizeof(*peer)) 168 builder.buffer = append(builder.buffer, newBytes...) 169 } 170 171 // AppendAllowedIP appends an allowed IP to the building configuration. This should be called after a peer has been added. 172 func (builder *ConfigBuilder) AppendAllowedIP(allowedIP *AllowedIP) { 173 newBytes := unsafe.Slice((*byte)(unsafe.Pointer(allowedIP)), unsafe.Sizeof(*allowedIP)) 174 builder.buffer = append(builder.buffer, newBytes...) 175 } 176 177 // Interface assembles the configuration and returns the interface and length to be passed to SetConfiguration. 178 func (builder *ConfigBuilder) Interface() (*Interface, uint32) { 179 if builder.buffer == nil { 180 return nil, 0 181 } 182 return (*Interface)(unsafe.Pointer(&builder.buffer[0])), uint32(len(builder.buffer)) 183 }