Fix lint errors
This commit is contained in:
parent
a9f4123ba2
commit
46aa536b37
41 changed files with 498 additions and 406 deletions
41
.github/workflows/lint.yml
vendored
41
.github/workflows/lint.yml
vendored
|
|
@ -16,21 +16,56 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build
|
name: Lint ${{ matrix.goos }}/${{ matrix.goarch }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- goos: windows
|
||||||
|
goarch: amd64
|
||||||
|
- goos: windows
|
||||||
|
goarch: '386'
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm64
|
||||||
|
- goos: linux
|
||||||
|
goarch: amd64
|
||||||
|
- goos: linux
|
||||||
|
goarch: arm64
|
||||||
|
- goos: linux
|
||||||
|
goarch: arm
|
||||||
|
- goos: linux
|
||||||
|
goarch: '386'
|
||||||
|
- goos: darwin
|
||||||
|
goarch: amd64
|
||||||
|
- goos: darwin
|
||||||
|
goarch: arm64
|
||||||
|
- goos: android
|
||||||
|
goarch: arm64
|
||||||
|
- goos: freebsd
|
||||||
|
goarch: amd64
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.25
|
go-version: ^1.25
|
||||||
|
- name: Cache go module
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/go/pkg/mod
|
||||||
|
key: go-${{ hashFiles('**/go.sum') }}
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v8
|
uses: golangci/golangci-lint-action@v8
|
||||||
|
env:
|
||||||
|
GOOS: ${{ matrix.goos }}
|
||||||
|
GOARCH: ${{ matrix.goarch }}
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
args: --timeout=30m
|
args: --timeout=30m
|
||||||
install-mode: binary
|
install-mode: binary
|
||||||
verify: false
|
verify: false
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,24 @@
|
||||||
version: "2"
|
version: "2"
|
||||||
run:
|
run:
|
||||||
go: "1.25"
|
go: "1.24"
|
||||||
linters:
|
linters:
|
||||||
default: none
|
default: none
|
||||||
enable:
|
enable:
|
||||||
- govet
|
|
||||||
- ineffassign
|
- ineffassign
|
||||||
- paralleltest
|
|
||||||
- staticcheck
|
- staticcheck
|
||||||
|
- modernize
|
||||||
settings:
|
settings:
|
||||||
staticcheck:
|
staticcheck:
|
||||||
checks:
|
checks:
|
||||||
- all
|
- all
|
||||||
- -S1000
|
- -QF1008 # could remove embedded field "<interface>" from selector
|
||||||
- -S1008
|
- -ST1003 # should not use ALL_CAPS in Go names; use CamelCase instead
|
||||||
- -S1017
|
- -QF1001 # could apply De Morgan's law
|
||||||
- -ST1003
|
|
||||||
- -QF1001
|
|
||||||
- -QF1003
|
|
||||||
- -QF1008
|
|
||||||
exclusions:
|
exclusions:
|
||||||
generated: lax
|
generated: lax
|
||||||
presets:
|
presets:
|
||||||
- comments
|
- comments
|
||||||
- common-false-positives
|
- common-false-positives
|
||||||
- legacy
|
|
||||||
- std-error-handling
|
|
||||||
paths:
|
|
||||||
- third_party$
|
|
||||||
- builtin$
|
|
||||||
- examples$
|
|
||||||
formatters:
|
formatters:
|
||||||
enable:
|
enable:
|
||||||
- gci
|
- gci
|
||||||
|
|
@ -42,8 +31,4 @@ formatters:
|
||||||
- default
|
- default
|
||||||
custom-order: true
|
custom-order: true
|
||||||
exclusions:
|
exclusions:
|
||||||
generated: lax
|
generated: lax
|
||||||
paths:
|
|
||||||
- third_party$
|
|
||||||
- builtin$
|
|
||||||
- examples$
|
|
||||||
9
Makefile
9
Makefile
|
|
@ -18,11 +18,10 @@ fmt_install:
|
||||||
go install -v github.com/daixiang0/gci@latest
|
go install -v github.com/daixiang0/gci@latest
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
GOOS=linux golangci-lint run .
|
GOOS=linux golangci-lint --max-same-issues=0 --max-issues-per-linter=0 run ./...
|
||||||
GOOS=android golangci-lint run .
|
GOOS=android golangci-lint --max-same-issues=0 --max-issues-per-linter=0 run ./...
|
||||||
GOOS=windows golangci-lint run .
|
GOOS=windows golangci-lint --max-same-issues=0 --max-issues-per-linter=0 run ./...
|
||||||
GOOS=darwin golangci-lint run .
|
GOOS=darwin golangci-lint --max-same-issues=0 --max-issues-per-linter=0 run ./...
|
||||||
GOOS=freebsd golangci-lint run .
|
|
||||||
|
|
||||||
lint_install:
|
lint_install:
|
||||||
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
func BenchmarkTsChecksum(b *testing.B) {
|
func BenchmarkTsChecksum(b *testing.B) {
|
||||||
packet := make([][]byte, 1000)
|
packet := make([][]byte, 1000)
|
||||||
for i := 0; i < 1000; i++ {
|
for i := range 1000 {
|
||||||
packet[i] = make([]byte, 1500)
|
packet[i] = make([]byte, 1500)
|
||||||
rand.Read(packet[i])
|
rand.Read(packet[i])
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ func BenchmarkTsChecksum(b *testing.B) {
|
||||||
|
|
||||||
func BenchmarkGChecksum(b *testing.B) {
|
func BenchmarkGChecksum(b *testing.B) {
|
||||||
packet := make([][]byte, 1000)
|
packet := make([][]byte, 1000)
|
||||||
for i := 0; i < 1000; i++ {
|
for i := range 1000 {
|
||||||
packet[i] = make([]byte, 1500)
|
packet[i] = make([]byte, 1500)
|
||||||
rand.Read(packet[i])
|
rand.Read(packet[i])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@
|
||||||
// only use the first FD to write outbound packets. Once 5 tuple hashes for
|
// only use the first FD to write outbound packets. Once 5 tuple hashes for
|
||||||
// all outbound packets are available we will make use of all underlying FD's to
|
// all outbound packets are available we will make use of all underlying FD's to
|
||||||
// write outbound packets.
|
// write outbound packets.
|
||||||
|
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
package fdbased
|
package fdbased
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -46,7 +49,7 @@ import (
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip"
|
"github.com/sagernet/gvisor/pkg/tcpip"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/header"
|
"github.com/sagernet/gvisor/pkg/tcpip/header"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
||||||
"github.com/sagernet/sing-tun/internal/rawfile_darwin"
|
rawfile "github.com/sagernet/sing-tun/internal/rawfile_darwin"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
package fdbased
|
package fdbased
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -92,5 +94,5 @@ func endpointinitLockNames() {}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
endpointinitLockNames()
|
endpointinitLockNames()
|
||||||
endpointprefixIndex = locking.NewMutexClass(reflect.TypeOf(endpointRWMutex{}), endpointlockNames)
|
endpointprefixIndex = locking.NewMutexClass(reflect.TypeFor[endpointRWMutex](), endpointlockNames)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
package fdbased
|
package fdbased
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
package fdbased
|
package fdbased
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -19,7 +21,7 @@ import (
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip"
|
"github.com/sagernet/gvisor/pkg/tcpip"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
||||||
"github.com/sagernet/gvisor/pkg/tcpip/stack/gro"
|
"github.com/sagernet/gvisor/pkg/tcpip/stack/gro"
|
||||||
"github.com/sagernet/sing-tun/internal/rawfile_darwin"
|
rawfile "github.com/sagernet/sing-tun/internal/rawfile_darwin"
|
||||||
"github.com/sagernet/sing-tun/internal/stopfd_darwin"
|
"github.com/sagernet/sing-tun/internal/stopfd_darwin"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
@ -177,7 +179,7 @@ func (d *recvMMsgDispatcher) dispatch() (bool, tcpip.Error) {
|
||||||
d.gro.Dispatcher = dsp
|
d.gro.Dispatcher = dsp
|
||||||
defer d.pkts.Reset()
|
defer d.pkts.Reset()
|
||||||
|
|
||||||
for k := 0; k < nMsgs; k++ {
|
for k := range nMsgs {
|
||||||
n := int(d.msgHdrs[k].DataLen)
|
n := int(d.msgHdrs[k].DataLen)
|
||||||
payload := d.bufs[k].pullBuffer(n)
|
payload := d.bufs[k].pullBuffer(n)
|
||||||
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
package fdbased
|
package fdbased
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -60,5 +62,5 @@ func processorinitLockNames() {}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
processorinitLockNames()
|
processorinitLockNames()
|
||||||
processorprefixIndex = locking.NewMutexClass(reflect.TypeOf(processorMutex{}), processorlockNames)
|
processorprefixIndex = locking.NewMutexClass(reflect.TypeFor[processorMutex](), processorlockNames)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
package fdbased
|
package fdbased
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -878,7 +878,7 @@ func (o NDPDNSSearchList) iterDomainNames(fn func(string)) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the label and add a trailing period.
|
// Copy the label and add a trailing period.
|
||||||
for i := 0; i < labelLen; i++ {
|
for i := range labelLen {
|
||||||
b, err := searchList.ReadByte()
|
b, err := searchList.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
|
|
|
||||||
|
|
@ -476,20 +476,14 @@ func ParseSynOptions(opts []byte, isAck bool) TCPSynOptions {
|
||||||
if mss == 0 {
|
if mss == 0 {
|
||||||
return synOpts
|
return synOpts
|
||||||
}
|
}
|
||||||
synOpts.MSS = mss
|
synOpts.MSS = max(mss, TCPMinimumSendMSS)
|
||||||
if mss < TCPMinimumSendMSS {
|
|
||||||
synOpts.MSS = TCPMinimumSendMSS
|
|
||||||
}
|
|
||||||
i += 4
|
i += 4
|
||||||
|
|
||||||
case TCPOptionWS:
|
case TCPOptionWS:
|
||||||
if i+3 > limit || opts[i+1] != 3 {
|
if i+3 > limit || opts[i+1] != 3 {
|
||||||
return synOpts
|
return synOpts
|
||||||
}
|
}
|
||||||
ws := int(opts[i+2])
|
ws := min(int(opts[i+2]), MaxWndScale)
|
||||||
if ws > MaxWndScale {
|
|
||||||
ws = MaxWndScale
|
|
||||||
}
|
|
||||||
synOpts.WS = ws
|
synOpts.WS = ws
|
||||||
i += 3
|
i += 3
|
||||||
|
|
||||||
|
|
@ -561,7 +555,7 @@ func ParseTCPOptions(b []byte) TCPOptions {
|
||||||
}
|
}
|
||||||
numBlocks := (sackOptionLen - 2) / 8
|
numBlocks := (sackOptionLen - 2) / 8
|
||||||
opts.SACKBlocks = []SACKBlock{}
|
opts.SACKBlocks = []SACKBlock{}
|
||||||
for j := 0; j < numBlocks; j++ {
|
for j := range numBlocks {
|
||||||
start := binary.BigEndian.Uint32(b[i+2+j*8:])
|
start := binary.BigEndian.Uint32(b[i+2+j*8:])
|
||||||
end := binary.BigEndian.Uint32(b[i+2+j*8+4:])
|
end := binary.BigEndian.Uint32(b[i+2+j*8+4:])
|
||||||
opts.SACKBlocks = append(opts.SACKBlocks, SACKBlock{
|
opts.SACKBlocks = append(opts.SACKBlocks, SACKBlock{
|
||||||
|
|
@ -646,10 +640,7 @@ func EncodeSACKBlocks(sackBlocks []SACKBlock, b []byte) int {
|
||||||
if len(sackBlocks) == 0 {
|
if len(sackBlocks) == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
l := len(sackBlocks)
|
l := min(len(sackBlocks), TCPMaxSACKBlocks)
|
||||||
if l > TCPMaxSACKBlocks {
|
|
||||||
l = TCPMaxSACKBlocks
|
|
||||||
}
|
|
||||||
if ll := (len(b) - 2) / 8; ll < l {
|
if ll := (len(b) - 2) / 8; ll < l {
|
||||||
l = ll
|
l = ll
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,53 @@ func (a Address) Len() int {
|
||||||
return a.length
|
return a.length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String implements the fmt.Stringer interface.
|
||||||
|
func (a Address) String() string {
|
||||||
|
switch l := a.Len(); l {
|
||||||
|
case 4:
|
||||||
|
return fmt.Sprintf("%d.%d.%d.%d", int(a.addr[0]), int(a.addr[1]), int(a.addr[2]), int(a.addr[3]))
|
||||||
|
case 16:
|
||||||
|
// Find the longest subsequence of hexadecimal zeros.
|
||||||
|
start, end := -1, -1
|
||||||
|
for i := 0; i < a.Len(); i += 2 {
|
||||||
|
j := i
|
||||||
|
for j < a.Len() && a.addr[j] == 0 && a.addr[j+1] == 0 {
|
||||||
|
j += 2
|
||||||
|
}
|
||||||
|
if j > i+2 && j-i > end-start {
|
||||||
|
start, end = i, j
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var b strings.Builder
|
||||||
|
for i := 0; i < a.Len(); i += 2 {
|
||||||
|
if i == start {
|
||||||
|
b.WriteString("::")
|
||||||
|
i = end
|
||||||
|
if end >= a.Len() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else if i > 0 {
|
||||||
|
b.WriteByte(':')
|
||||||
|
}
|
||||||
|
v := uint16(a.addr[i+0])<<8 | uint16(a.addr[i+1])
|
||||||
|
if v == 0 {
|
||||||
|
b.WriteByte('0')
|
||||||
|
} else {
|
||||||
|
const digits = "0123456789abcdef"
|
||||||
|
for i := uint(3); i < 4; i-- {
|
||||||
|
if v := v >> (i * 4); v != 0 {
|
||||||
|
b.WriteByte(digits[v&0xf])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("%x", a.addr[:l])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithPrefix returns the address with a prefix that represents a point subnet.
|
// WithPrefix returns the address with a prefix that represents a point subnet.
|
||||||
func (a Address) WithPrefix() AddressWithPrefix {
|
func (a Address) WithPrefix() AddressWithPrefix {
|
||||||
return AddressWithPrefix{
|
return AddressWithPrefix{
|
||||||
|
|
@ -541,7 +588,7 @@ func (a AddressWithPrefix) Subnet() Subnet {
|
||||||
address: a.Address,
|
address: a.Address,
|
||||||
mask: AddressMask{length: addrLen},
|
mask: AddressMask{length: addrLen},
|
||||||
}
|
}
|
||||||
for i := 0; i < addrLen; i++ {
|
for i := range addrLen {
|
||||||
sub.mask.mask[i] = 0xff
|
sub.mask.mask[i] = 0xff
|
||||||
}
|
}
|
||||||
return sub
|
return sub
|
||||||
|
|
@ -550,7 +597,7 @@ func (a AddressWithPrefix) Subnet() Subnet {
|
||||||
sa := Address{length: addrLen}
|
sa := Address{length: addrLen}
|
||||||
sm := AddressMask{length: addrLen}
|
sm := AddressMask{length: addrLen}
|
||||||
n := uint(a.PrefixLen)
|
n := uint(a.PrefixLen)
|
||||||
for i := 0; i < addrLen; i++ {
|
for i := range addrLen {
|
||||||
if n >= 8 {
|
if n >= 8 {
|
||||||
sa.addr[i] = a.Address.addr[i]
|
sa.addr[i] = a.Address.addr[i]
|
||||||
sm.mask[i] = 0xff
|
sm.mask[i] = 0xff
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
package rawfile
|
package rawfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
@ -25,12 +26,8 @@ func IovecFromBytes(bs []byte) unix.Iovec {
|
||||||
return iov
|
return iov
|
||||||
}
|
}
|
||||||
|
|
||||||
func bytesFromIovec(iov unix.Iovec) (bs []byte) {
|
func bytesFromIovec(iov unix.Iovec) []byte {
|
||||||
sh := (*reflect.SliceHeader)(unsafe.Pointer(&bs))
|
return unsafe.Slice(iov.Base, iov.Len)
|
||||||
sh.Data = uintptr(unsafe.Pointer(iov.Base))
|
|
||||||
sh.Len = int(iov.Len)
|
|
||||||
sh.Cap = int(iov.Len)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendIovecFromBytes returns append(iovs, IovecFromBytes(bs)). If len(bs) ==
|
// AppendIovecFromBytes returns append(iovs, IovecFromBytes(bs)). If len(bs) ==
|
||||||
|
|
@ -56,6 +53,7 @@ type MsgHdrX struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NonBlockingSendMMsg(fd int, msgHdrs []MsgHdrX) (int, unix.Errno) {
|
func NonBlockingSendMMsg(fd int, msgHdrs []MsgHdrX) (int, unix.Errno) {
|
||||||
|
//nolint:staticcheck
|
||||||
n, _, e := unix.RawSyscall6(unix.SYS_SENDMSG_X, uintptr(fd), uintptr(unsafe.Pointer(&msgHdrs[0])), uintptr(len(msgHdrs)), unix.MSG_DONTWAIT, 0, 0)
|
n, _, e := unix.RawSyscall6(unix.SYS_SENDMSG_X, uintptr(fd), uintptr(unsafe.Pointer(&msgHdrs[0])), uintptr(len(msgHdrs)), unix.MSG_DONTWAIT, 0, 0)
|
||||||
return int(n), e
|
return int(n), e
|
||||||
}
|
}
|
||||||
|
|
@ -66,12 +64,14 @@ const SizeofMsgHdrX = unsafe.Sizeof(MsgHdrX{})
|
||||||
// It fails if partial data is written.
|
// It fails if partial data is written.
|
||||||
func NonBlockingWriteIovec(fd int, iovec []unix.Iovec) unix.Errno {
|
func NonBlockingWriteIovec(fd int, iovec []unix.Iovec) unix.Errno {
|
||||||
iovecLen := uintptr(len(iovec))
|
iovecLen := uintptr(len(iovec))
|
||||||
|
//nolint:staticcheck
|
||||||
_, _, e := unix.RawSyscall(unix.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovec[0])), iovecLen)
|
_, _, e := unix.RawSyscall(unix.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovec[0])), iovecLen)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, unix.Errno) {
|
func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, unix.Errno) {
|
||||||
for {
|
for {
|
||||||
|
//nolint:staticcheck
|
||||||
n, _, e := unix.RawSyscall(unix.SYS_READV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs)))
|
n, _, e := unix.RawSyscall(unix.SYS_READV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs)))
|
||||||
if e == 0 {
|
if e == 0 {
|
||||||
return int(n), 0
|
return int(n), 0
|
||||||
|
|
@ -91,6 +91,7 @@ func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, unix.
|
||||||
|
|
||||||
func BlockingRecvMMsgUntilStopped(efd int, fd int, msgHdrs []MsgHdrX) (int, unix.Errno) {
|
func BlockingRecvMMsgUntilStopped(efd int, fd int, msgHdrs []MsgHdrX) (int, unix.Errno) {
|
||||||
for {
|
for {
|
||||||
|
//nolint:staticcheck
|
||||||
n, _, e := unix.RawSyscall6(unix.SYS_RECVMSG_X, uintptr(fd), uintptr(unsafe.Pointer(&msgHdrs[0])), uintptr(len(msgHdrs)), unix.MSG_DONTWAIT, 0, 0)
|
n, _, e := unix.RawSyscall6(unix.SYS_RECVMSG_X, uintptr(fd), uintptr(unsafe.Pointer(&msgHdrs[0])), uintptr(len(msgHdrs)), unix.MSG_DONTWAIT, 0, 0)
|
||||||
if e == 0 {
|
if e == 0 {
|
||||||
return int(n), e
|
return int(n), e
|
||||||
|
|
@ -162,7 +163,7 @@ func BlockingPollUntilStopped(efd int, fd int, events int16) (bool, unix.Errno)
|
||||||
var efdHasData bool
|
var efdHasData bool
|
||||||
var errno unix.Errno
|
var errno unix.Errno
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := range n {
|
||||||
ev := &revents[i]
|
ev := &revents[i]
|
||||||
|
|
||||||
if int(ev.Ident) == efd && ev.Filter == unix.EVFILT_READ {
|
if int(ev.Ident) == efd && ev.Filter == unix.EVFILT_READ {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build darwin
|
||||||
|
|
||||||
package stopfd
|
package stopfd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -98,105 +98,105 @@ func firewallRuleAdd(name, description, group, appPath, serviceName, ports, remo
|
||||||
if profile == NET_FW_PROFILE2_CURRENT {
|
if profile == NET_FW_PROFILE2_CURRENT {
|
||||||
currentProfiles, err := oleutil.GetProperty(fwPolicy, "CurrentProfileTypes")
|
currentProfiles, err := oleutil.GetProperty(fwPolicy, "CurrentProfileTypes")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("Failed to get CurrentProfiles: %s", err)
|
return false, fmt.Errorf("failed to get CurrentProfiles: %s", err)
|
||||||
}
|
}
|
||||||
profile = currentProfiles.Value().(int32)
|
profile = currentProfiles.Value().(int32)
|
||||||
}
|
}
|
||||||
unknownRules, err := oleutil.GetProperty(fwPolicy, "Rules")
|
unknownRules, err := oleutil.GetProperty(fwPolicy, "Rules")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("Failed to get Rules: %s", err)
|
return false, fmt.Errorf("failed to get Rules: %s", err)
|
||||||
}
|
}
|
||||||
rules := unknownRules.ToIDispatch()
|
rules := unknownRules.ToIDispatch()
|
||||||
|
|
||||||
if ok, err := FirewallRuleExistsByName(rules, name); err != nil {
|
if ok, err := FirewallRuleExistsByName(rules, name); err != nil {
|
||||||
return false, fmt.Errorf("Error while checking rules for duplicate: %s", err)
|
return false, fmt.Errorf("error while checking rules for duplicate: %s", err)
|
||||||
} else if ok {
|
} else if ok {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
unknown2, err := oleutil.CreateObject("HNetCfg.FWRule")
|
unknown2, err := oleutil.CreateObject("HNetCfg.FWRule")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("Error creating Rule object: %s", err)
|
return false, fmt.Errorf("error creating Rule object: %s", err)
|
||||||
}
|
}
|
||||||
defer unknown2.Release()
|
defer unknown2.Release()
|
||||||
|
|
||||||
fwRule, err := unknown2.QueryInterface(ole.IID_IDispatch)
|
fwRule, err := unknown2.QueryInterface(ole.IID_IDispatch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("Error creating Rule object (2): %s", err)
|
return false, fmt.Errorf("error creating Rule object (2): %s", err)
|
||||||
}
|
}
|
||||||
defer fwRule.Release()
|
defer fwRule.Release()
|
||||||
|
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Name", name); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Name", name); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Name) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Name) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Description", description); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Description", description); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Description) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Description) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
if appPath != "" {
|
if appPath != "" {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Applicationname", appPath); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Applicationname", appPath); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Applicationname) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Applicationname) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if serviceName != "" {
|
if serviceName != "" {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "ServiceName", serviceName); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "ServiceName", serviceName); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (ServiceName) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (ServiceName) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if protocol != 0 {
|
if protocol != 0 {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Protocol", protocol); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Protocol", protocol); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Protocol) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Protocol) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if icmpTypes != "" {
|
if icmpTypes != "" {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "IcmpTypesAndCodes", icmpTypes); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "IcmpTypesAndCodes", icmpTypes); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (IcmpTypesAndCodes) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (IcmpTypesAndCodes) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ports != "" {
|
if ports != "" {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "LocalPorts", ports); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "LocalPorts", ports); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (LocalPorts) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (LocalPorts) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if remotePorts != "" {
|
if remotePorts != "" {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "RemotePorts", remotePorts); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "RemotePorts", remotePorts); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (RemotePorts) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (RemotePorts) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if localAddresses != "" {
|
if localAddresses != "" {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "LocalAddresses", localAddresses); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "LocalAddresses", localAddresses); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (LocalAddresses) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (LocalAddresses) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if remoteAddresses != "" {
|
if remoteAddresses != "" {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "RemoteAddresses", remoteAddresses); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "RemoteAddresses", remoteAddresses); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (RemoteAddresses) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (RemoteAddresses) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if direction != 0 {
|
if direction != 0 {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Direction", direction); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Direction", direction); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Direction) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Direction) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Enabled", enabled); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Enabled", enabled); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Enabled) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Enabled) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Grouping", group); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Grouping", group); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Grouping) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Grouping) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Profiles", profile); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Profiles", profile); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Profiles) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Profiles) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
if _, err := oleutil.PutProperty(fwRule, "Action", action); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "Action", action); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (Action) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (Action) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
if edgeTraversal {
|
if edgeTraversal {
|
||||||
if _, err := oleutil.PutProperty(fwRule, "EdgeTraversal", edgeTraversal); err != nil {
|
if _, err := oleutil.PutProperty(fwRule, "EdgeTraversal", edgeTraversal); err != nil {
|
||||||
return false, fmt.Errorf("Error setting property (EdgeTraversal) of Rule: %s", err)
|
return false, fmt.Errorf("error setting property (EdgeTraversal) of Rule: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := oleutil.CallMethod(rules, "Add", fwRule); err != nil {
|
if _, err := oleutil.CallMethod(rules, "Add", fwRule); err != nil {
|
||||||
return false, fmt.Errorf("Error adding Rule: %s", err)
|
return false, fmt.Errorf("error adding Rule: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
@ -205,13 +205,13 @@ func firewallRuleAdd(name, description, group, appPath, serviceName, ports, remo
|
||||||
func FirewallRuleExistsByName(rules *ole.IDispatch, name string) (bool, error) {
|
func FirewallRuleExistsByName(rules *ole.IDispatch, name string) (bool, error) {
|
||||||
enumProperty, err := rules.GetProperty("_NewEnum")
|
enumProperty, err := rules.GetProperty("_NewEnum")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("Failed to get enumeration property on Rules: %s", err)
|
return false, fmt.Errorf("failed to get enumeration property on Rules: %s", err)
|
||||||
}
|
}
|
||||||
defer enumProperty.Clear()
|
defer enumProperty.Clear()
|
||||||
|
|
||||||
enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
|
enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("Failed to cast enum to correct type: %s", err)
|
return false, fmt.Errorf("failed to cast enum to correct type: %s", err)
|
||||||
}
|
}
|
||||||
if enum == nil {
|
if enum == nil {
|
||||||
return false, fmt.Errorf("can't get IEnumVARIANT, enum is nil")
|
return false, fmt.Errorf("can't get IEnumVARIANT, enum is nil")
|
||||||
|
|
@ -219,7 +219,7 @@ func FirewallRuleExistsByName(rules *ole.IDispatch, name string) (bool, error) {
|
||||||
|
|
||||||
for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) {
|
for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("Failed to seek next Rule item: %s", err)
|
return false, fmt.Errorf("failed to seek next Rule item: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := func() (bool, error) {
|
t, err := func() (bool, error) {
|
||||||
|
|
@ -227,7 +227,7 @@ func FirewallRuleExistsByName(rules *ole.IDispatch, name string) (bool, error) {
|
||||||
defer item.Release()
|
defer item.Release()
|
||||||
|
|
||||||
if item, err := oleutil.GetProperty(item, "Name"); err != nil {
|
if item, err := oleutil.GetProperty(item, "Name"); err != nil {
|
||||||
return false, fmt.Errorf("Failed to get Property (Name) of Rule")
|
return false, fmt.Errorf("failed to get Property (Name) of Rule")
|
||||||
} else if item.ToString() == name {
|
} else if item.ToString() == name {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
@ -251,18 +251,18 @@ func FirewallRuleExistsByName(rules *ole.IDispatch, name string) (bool, error) {
|
||||||
func firewallAPIInit() (*ole.IUnknown, *ole.IDispatch, error) {
|
func firewallAPIInit() (*ole.IUnknown, *ole.IDispatch, error) {
|
||||||
err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
|
err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("Failed to initialize COM: %s", err)
|
return nil, nil, fmt.Errorf("failed to initialize COM: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
unknown, err := oleutil.CreateObject("HNetCfg.FwPolicy2")
|
unknown, err := oleutil.CreateObject("HNetCfg.FwPolicy2")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("Failed to create FwPolicy Object: %s", err)
|
return nil, nil, fmt.Errorf("failed to create FwPolicy Object: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fwPolicy, err := unknown.QueryInterface(ole.IID_IDispatch)
|
fwPolicy, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
unknown.Release()
|
unknown.Release()
|
||||||
return nil, nil, fmt.Errorf("Failed to create FwPolicy Object (2): %s", err)
|
return nil, nil, fmt.Errorf("failed to create FwPolicy Object (2): %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return unknown, fwPolicy, nil
|
return unknown, fwPolicy, nil
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
@ -60,9 +62,10 @@ const (
|
||||||
|
|
||||||
func (luid LUID) fallbackSetDNSForFamily(family AddressFamily, dnses []netip.Addr) error {
|
func (luid LUID) fallbackSetDNSForFamily(family AddressFamily, dnses []netip.Addr) error {
|
||||||
var templateFlush string
|
var templateFlush string
|
||||||
if family == windows.AF_INET {
|
switch family {
|
||||||
|
case windows.AF_INET:
|
||||||
templateFlush = netshCmdTemplateFlush4
|
templateFlush = netshCmdTemplateFlush4
|
||||||
} else if family == windows.AF_INET6 {
|
case windows.AF_INET6:
|
||||||
templateFlush = netshCmdTemplateFlush6
|
templateFlush = netshCmdTemplateFlush6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +75,7 @@ func (luid LUID) fallbackSetDNSForFamily(family AddressFamily, dnses []netip.Add
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cmds = append(cmds, fmt.Sprintf(templateFlush, ipif.InterfaceIndex))
|
cmds = append(cmds, fmt.Sprintf(templateFlush, ipif.InterfaceIndex))
|
||||||
for i := 0; i < len(dnses); i++ {
|
for i := range dnses {
|
||||||
if dnses[i].Is4() && family == windows.AF_INET {
|
if dnses[i].Is4() && family == windows.AF_INET {
|
||||||
cmds = append(cmds, fmt.Sprintf(netshCmdTemplateAdd4, ipif.InterfaceIndex, dnses[i].String()))
|
cmds = append(cmds, fmt.Sprintf(netshCmdTemplateAdd4, ipif.InterfaceIndex, dnses[i].String()))
|
||||||
} else if dnses[i].Is6() && family == windows.AF_INET6 {
|
} else if dnses[i].Is6() && family == windows.AF_INET6 {
|
||||||
|
|
@ -85,23 +88,23 @@ func (luid LUID) fallbackSetDNSForFamily(family AddressFamily, dnses []netip.Add
|
||||||
func (luid LUID) fallbackSetDNSDomain(domain string) error {
|
func (luid LUID) fallbackSetDNSDomain(domain string) error {
|
||||||
guid, err := luid.GUID()
|
guid, err := luid.GUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error converting luid to guid: %w", err)
|
return fmt.Errorf("error converting luid to guid: %w", err)
|
||||||
}
|
}
|
||||||
key, err := registry.OpenKey(registry.LOCAL_MACHINE, fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters\\%v", guid), registry.QUERY_VALUE)
|
key, err := registry.OpenKey(registry.LOCAL_MACHINE, fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters\\%v", guid), registry.QUERY_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error opening adapter-specific TCP/IP network registry key: %w", err)
|
return fmt.Errorf("error opening adapter-specific TCP/IP network registry key: %w", err)
|
||||||
}
|
}
|
||||||
paths, _, err := key.GetStringsValue("IpConfig")
|
paths, _, err := key.GetStringsValue("IpConfig")
|
||||||
key.Close()
|
key.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error reading IpConfig registry key: %w", err)
|
return fmt.Errorf("error reading IpConfig registry key: %w", err)
|
||||||
}
|
}
|
||||||
if len(paths) == 0 {
|
if len(paths) == 0 {
|
||||||
return errors.New("No TCP/IP interfaces found on adapter")
|
return errors.New("no TCP/IP interfaces found on adapter")
|
||||||
}
|
}
|
||||||
key, err = registry.OpenKey(registry.LOCAL_MACHINE, fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\%s", paths[0]), registry.SET_VALUE)
|
key, err = registry.OpenKey(registry.LOCAL_MACHINE, fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\%s", paths[0]), registry.SET_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Unable to open TCP/IP network registry key: %w", err)
|
return fmt.Errorf("unable to open TCP/IP network registry key: %w", err)
|
||||||
}
|
}
|
||||||
err = key.SetStringValue("Domain", domain)
|
err = key.SetStringValue("Domain", domain)
|
||||||
key.Close()
|
key.Close()
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
@ -62,206 +64,206 @@ type IfType uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
IfTypeOther IfType = 1 // None of the below
|
IfTypeOther IfType = 1 // None of the below
|
||||||
IfTypeRegular1822 = 2
|
IfTypeRegular1822 IfType = 2
|
||||||
IfTypeHdh1822 = 3
|
IfTypeHdh1822 IfType = 3
|
||||||
IfTypeDdnX25 = 4
|
IfTypeDdnX25 IfType = 4
|
||||||
IfTypeRfc877X25 = 5
|
IfTypeRfc877X25 IfType = 5
|
||||||
IfTypeEthernetCSMACD = 6
|
IfTypeEthernetCSMACD IfType = 6
|
||||||
IfTypeISO88023CSMACD = 7
|
IfTypeISO88023CSMACD IfType = 7
|
||||||
IfTypeISO88024Tokenbus = 8
|
IfTypeISO88024Tokenbus IfType = 8
|
||||||
IfTypeISO88025Tokenring = 9
|
IfTypeISO88025Tokenring IfType = 9
|
||||||
IfTypeISO88026Man = 10
|
IfTypeISO88026Man IfType = 10
|
||||||
IfTypeStarlan = 11
|
IfTypeStarlan IfType = 11
|
||||||
IfTypeProteon10Mbit = 12
|
IfTypeProteon10Mbit IfType = 12
|
||||||
IfTypeProteon80Mbit = 13
|
IfTypeProteon80Mbit IfType = 13
|
||||||
IfTypeHyperchannel = 14
|
IfTypeHyperchannel IfType = 14
|
||||||
IfTypeFddi = 15
|
IfTypeFddi IfType = 15
|
||||||
IfTypeLapB = 16
|
IfTypeLapB IfType = 16
|
||||||
IfTypeSdlc = 17
|
IfTypeSdlc IfType = 17
|
||||||
IfTypeDs1 = 18 // DS1-MIB
|
IfTypeDs1 IfType = 18 // DS1-MIB
|
||||||
IfTypeE1 = 19 // Obsolete; see DS1-MIB
|
IfTypeE1 IfType = 19 // Obsolete; see DS1-MIB
|
||||||
IfTypeBasicISDN = 20
|
IfTypeBasicISDN IfType = 20
|
||||||
IfTypePrimaryISDN = 21
|
IfTypePrimaryISDN IfType = 21
|
||||||
IfTypePropPoint2PointSerial = 22 // proprietary serial
|
IfTypePropPoint2PointSerial IfType = 22 // proprietary serial
|
||||||
IfTypePPP = 23
|
IfTypePPP IfType = 23
|
||||||
IfTypeSoftwareLoopback = 24
|
IfTypeSoftwareLoopback IfType = 24
|
||||||
IfTypeEon = 25 // CLNP over IP
|
IfTypeEon IfType = 25 // CLNP over IP
|
||||||
IfTypeEthernet3Mbit = 26
|
IfTypeEthernet3Mbit IfType = 26
|
||||||
IfTypeNsip = 27 // XNS over IP
|
IfTypeNsip IfType = 27 // XNS over IP
|
||||||
IfTypeSlip = 28 // Generic Slip
|
IfTypeSlip IfType = 28 // Generic Slip
|
||||||
IfTypeUltra = 29 // ULTRA Technologies
|
IfTypeUltra IfType = 29 // ULTRA Technologies
|
||||||
IfTypeDs3 = 30 // DS3-MIB
|
IfTypeDs3 IfType = 30 // DS3-MIB
|
||||||
IfTypeSip = 31 // SMDS, coffee
|
IfTypeSip IfType = 31 // SMDS, coffee
|
||||||
IfTypeFramerelay = 32 // DTE only
|
IfTypeFramerelay IfType = 32 // DTE only
|
||||||
IfTypeRs232 = 33
|
IfTypeRs232 IfType = 33
|
||||||
IfTypePara = 34 // Parallel port
|
IfTypePara IfType = 34 // Parallel port
|
||||||
IfTypeArcnet = 35
|
IfTypeArcnet IfType = 35
|
||||||
IfTypeArcnetPlus = 36
|
IfTypeArcnetPlus IfType = 36
|
||||||
IfTypeAtm = 37 // ATM cells
|
IfTypeAtm IfType = 37 // ATM cells
|
||||||
IfTypeMioX25 = 38
|
IfTypeMioX25 IfType = 38
|
||||||
IfTypeSonet = 39 // SONET or SDH
|
IfTypeSonet IfType = 39 // SONET or SDH
|
||||||
IfTypeX25Ple = 40
|
IfTypeX25Ple IfType = 40
|
||||||
IfTypeIso88022LLC = 41
|
IfTypeIso88022LLC IfType = 41
|
||||||
IfTypeLocaltalk = 42
|
IfTypeLocaltalk IfType = 42
|
||||||
IfTypeSmdsDxi = 43
|
IfTypeSmdsDxi IfType = 43
|
||||||
IfTypeFramerelayService = 44 // FRNETSERV-MIB
|
IfTypeFramerelayService IfType = 44 // FRNETSERV-MIB
|
||||||
IfTypeV35 = 45
|
IfTypeV35 IfType = 45
|
||||||
IfTypeHssi = 46
|
IfTypeHssi IfType = 46
|
||||||
IfTypeHippi = 47
|
IfTypeHippi IfType = 47
|
||||||
IfTypeModem = 48 // Generic Modem
|
IfTypeModem IfType = 48 // Generic Modem
|
||||||
IfTypeAal5 = 49 // AAL5 over ATM
|
IfTypeAal5 IfType = 49 // AAL5 over ATM
|
||||||
IfTypeSonetPath = 50
|
IfTypeSonetPath IfType = 50
|
||||||
IfTypeSonetVt = 51
|
IfTypeSonetVt IfType = 51
|
||||||
IfTypeSmdsIcip = 52 // SMDS InterCarrier Interface
|
IfTypeSmdsIcip IfType = 52 // SMDS InterCarrier Interface
|
||||||
IfTypePropVirtual = 53 // Proprietary virtual/internal
|
IfTypePropVirtual IfType = 53 // Proprietary virtual/internal
|
||||||
IfTypePropMultiplexor = 54 // Proprietary multiplexing
|
IfTypePropMultiplexor IfType = 54 // Proprietary multiplexing
|
||||||
IfTypeIEEE80212 = 55 // 100BaseVG
|
IfTypeIEEE80212 IfType = 55 // 100BaseVG
|
||||||
IfTypeFibrechannel = 56
|
IfTypeFibrechannel IfType = 56
|
||||||
IfTypeHippiinterface = 57
|
IfTypeHippiinterface IfType = 57
|
||||||
IfTypeFramerelayInterconnect = 58 // Obsolete, use 32 or 44
|
IfTypeFramerelayInterconnect IfType = 58 // Obsolete, use 32 or 44
|
||||||
IfTypeAflane8023 = 59 // ATM Emulated LAN for 802.3
|
IfTypeAflane8023 IfType = 59 // ATM Emulated LAN for 802.3
|
||||||
IfTypeAflane8025 = 60 // ATM Emulated LAN for 802.5
|
IfTypeAflane8025 IfType = 60 // ATM Emulated LAN for 802.5
|
||||||
IfTypeCctemul = 61 // ATM Emulated circuit
|
IfTypeCctemul IfType = 61 // ATM Emulated circuit
|
||||||
IfTypeFastether = 62 // Fast Ethernet (100BaseT)
|
IfTypeFastether IfType = 62 // Fast Ethernet (100BaseT)
|
||||||
IfTypeISDN = 63 // ISDN and X.25
|
IfTypeISDN IfType = 63 // ISDN and X.25
|
||||||
IfTypeV11 = 64 // CCITT V.11/X.21
|
IfTypeV11 IfType = 64 // CCITT V.11/X.21
|
||||||
IfTypeV36 = 65 // CCITT V.36
|
IfTypeV36 IfType = 65 // CCITT V.36
|
||||||
IfTypeG703_64k = 66 // CCITT G703 at 64Kbps
|
IfTypeG703_64k IfType = 66 // CCITT G703 at 64Kbps
|
||||||
IfTypeG703_2mb = 67 // Obsolete; see DS1-MIB
|
IfTypeG703_2mb IfType = 67 // Obsolete; see DS1-MIB
|
||||||
IfTypeQllc = 68 // SNA QLLC
|
IfTypeQllc IfType = 68 // SNA QLLC
|
||||||
IfTypeFastetherFX = 69 // Fast Ethernet (100BaseFX)
|
IfTypeFastetherFX IfType = 69 // Fast Ethernet (100BaseFX)
|
||||||
IfTypeChannel = 70
|
IfTypeChannel IfType = 70
|
||||||
IfTypeIEEE80211 = 71 // Radio spread spectrum
|
IfTypeIEEE80211 IfType = 71 // Radio spread spectrum
|
||||||
IfTypeIBM370parchan = 72 // IBM System 360/370 OEMI Channel
|
IfTypeIBM370parchan IfType = 72 // IBM System 360/370 OEMI Channel
|
||||||
IfTypeEscon = 73 // IBM Enterprise Systems Connection
|
IfTypeEscon IfType = 73 // IBM Enterprise Systems Connection
|
||||||
IfTypeDlsw = 74 // Data Link Switching
|
IfTypeDlsw IfType = 74 // Data Link Switching
|
||||||
IfTypeISDNS = 75 // ISDN S/T interface
|
IfTypeISDNS IfType = 75 // ISDN S/T interface
|
||||||
IfTypeISDNU = 76 // ISDN U interface
|
IfTypeISDNU IfType = 76 // ISDN U interface
|
||||||
IfTypeLapD = 77 // Link Access Protocol D
|
IfTypeLapD IfType = 77 // Link Access Protocol D
|
||||||
IfTypeIpswitch = 78 // IP Switching Objects
|
IfTypeIpswitch IfType = 78 // IP Switching Objects
|
||||||
IfTypeRsrb = 79 // Remote Source Route Bridging
|
IfTypeRsrb IfType = 79 // Remote Source Route Bridging
|
||||||
IfTypeAtmLogical = 80 // ATM Logical Port
|
IfTypeAtmLogical IfType = 80 // ATM Logical Port
|
||||||
IfTypeDs0 = 81 // Digital Signal Level 0
|
IfTypeDs0 IfType = 81 // Digital Signal Level 0
|
||||||
IfTypeDs0Bundle = 82 // Group of ds0s on the same ds1
|
IfTypeDs0Bundle IfType = 82 // Group of ds0s on the same ds1
|
||||||
IfTypeBsc = 83 // Bisynchronous Protocol
|
IfTypeBsc IfType = 83 // Bisynchronous Protocol
|
||||||
IfTypeAsync = 84 // Asynchronous Protocol
|
IfTypeAsync IfType = 84 // Asynchronous Protocol
|
||||||
IfTypeCnr = 85 // Combat Net Radio
|
IfTypeCnr IfType = 85 // Combat Net Radio
|
||||||
IfTypeIso88025rDtr = 86 // ISO 802.5r DTR
|
IfTypeIso88025rDtr IfType = 86 // ISO 802.5r DTR
|
||||||
IfTypeEplrs = 87 // Ext Pos Loc Report Sys
|
IfTypeEplrs IfType = 87 // Ext Pos Loc Report Sys
|
||||||
IfTypeArap = 88 // Appletalk Remote Access Protocol
|
IfTypeArap IfType = 88 // Appletalk Remote Access Protocol
|
||||||
IfTypePropCnls = 89 // Proprietary Connectionless Proto
|
IfTypePropCnls IfType = 89 // Proprietary Connectionless Proto
|
||||||
IfTypeHostpad = 90 // CCITT-ITU X.29 PAD Protocol
|
IfTypeHostpad IfType = 90 // CCITT-ITU X.29 PAD Protocol
|
||||||
IfTypeTermpad = 91 // CCITT-ITU X.3 PAD Facility
|
IfTypeTermpad IfType = 91 // CCITT-ITU X.3 PAD Facility
|
||||||
IfTypeFramerelayMpi = 92 // Multiproto Interconnect over FR
|
IfTypeFramerelayMpi IfType = 92 // Multiproto Interconnect over FR
|
||||||
IfTypeX213 = 93 // CCITT-ITU X213
|
IfTypeX213 IfType = 93 // CCITT-ITU X213
|
||||||
IfTypeAdsl = 94 // Asymmetric Digital Subscrbr Loop
|
IfTypeAdsl IfType = 94 // Asymmetric Digital Subscrbr Loop
|
||||||
IfTypeRadsl = 95 // Rate-Adapt Digital Subscrbr Loop
|
IfTypeRadsl IfType = 95 // Rate-Adapt Digital Subscrbr Loop
|
||||||
IfTypeSdsl = 96 // Symmetric Digital Subscriber Loop
|
IfTypeSdsl IfType = 96 // Symmetric Digital Subscriber Loop
|
||||||
IfTypeVdsl = 97 // Very H-Speed Digital Subscrb Loop
|
IfTypeVdsl IfType = 97 // Very H-Speed Digital Subscrb Loop
|
||||||
IfTypeIso88025Crfprint = 98 // ISO 802.5 CRFP
|
IfTypeIso88025Crfprint IfType = 98 // ISO 802.5 CRFP
|
||||||
IfTypeMyrinet = 99 // Myricom Myrinet
|
IfTypeMyrinet IfType = 99 // Myricom Myrinet
|
||||||
IfTypeVoiceEm = 100 // Voice recEive and transMit
|
IfTypeVoiceEm IfType = 100 // Voice recEive and transMit
|
||||||
IfTypeVoiceFxo = 101 // Voice Foreign Exchange Office
|
IfTypeVoiceFxo IfType = 101 // Voice Foreign Exchange Office
|
||||||
IfTypeVoiceFxs = 102 // Voice Foreign Exchange Station
|
IfTypeVoiceFxs IfType = 102 // Voice Foreign Exchange Station
|
||||||
IfTypeVoiceEncap = 103 // Voice encapsulation
|
IfTypeVoiceEncap IfType = 103 // Voice encapsulation
|
||||||
IfTypeVoiceOverip = 104 // Voice over IP encapsulation
|
IfTypeVoiceOverip IfType = 104 // Voice over IP encapsulation
|
||||||
IfTypeAtmDxi = 105 // ATM DXI
|
IfTypeAtmDxi IfType = 105 // ATM DXI
|
||||||
IfTypeAtmFuni = 106 // ATM FUNI
|
IfTypeAtmFuni IfType = 106 // ATM FUNI
|
||||||
IfTypeAtmIma = 107 // ATM IMA
|
IfTypeAtmIma IfType = 107 // ATM IMA
|
||||||
IfTypePPPmultilinkbundle = 108 // PPP Multilink Bundle
|
IfTypePPPmultilinkbundle IfType = 108 // PPP Multilink Bundle
|
||||||
IfTypeIpoverCdlc = 109 // IBM ipOverCdlc
|
IfTypeIpoverCdlc IfType = 109 // IBM ipOverCdlc
|
||||||
IfTypeIpoverClaw = 110 // IBM Common Link Access to Workstn
|
IfTypeIpoverClaw IfType = 110 // IBM Common Link Access to Workstn
|
||||||
IfTypeStacktostack = 111 // IBM stackToStack
|
IfTypeStacktostack IfType = 111 // IBM stackToStack
|
||||||
IfTypeVirtualipaddress = 112 // IBM VIPA
|
IfTypeVirtualipaddress IfType = 112 // IBM VIPA
|
||||||
IfTypeMpc = 113 // IBM multi-proto channel support
|
IfTypeMpc IfType = 113 // IBM multi-proto channel support
|
||||||
IfTypeIpoverAtm = 114 // IBM ipOverAtm
|
IfTypeIpoverAtm IfType = 114 // IBM ipOverAtm
|
||||||
IfTypeIso88025Fiber = 115 // ISO 802.5j Fiber Token Ring
|
IfTypeIso88025Fiber IfType = 115 // ISO 802.5j Fiber Token Ring
|
||||||
IfTypeTdlc = 116 // IBM twinaxial data link control
|
IfTypeTdlc IfType = 116 // IBM twinaxial data link control
|
||||||
IfTypeGigabitethernet = 117
|
IfTypeGigabitethernet IfType = 117
|
||||||
IfTypeHdlc = 118
|
IfTypeHdlc IfType = 118
|
||||||
IfTypeLapF = 119
|
IfTypeLapF IfType = 119
|
||||||
IfTypeV37 = 120
|
IfTypeV37 IfType = 120
|
||||||
IfTypeX25Mlp = 121 // Multi-Link Protocol
|
IfTypeX25Mlp IfType = 121 // Multi-Link Protocol
|
||||||
IfTypeX25Huntgroup = 122 // X.25 Hunt Group
|
IfTypeX25Huntgroup IfType = 122 // X.25 Hunt Group
|
||||||
IfTypeTransphdlc = 123
|
IfTypeTransphdlc IfType = 123
|
||||||
IfTypeInterleave = 124 // Interleave channel
|
IfTypeInterleave IfType = 124 // Interleave channel
|
||||||
IfTypeFast = 125 // Fast channel
|
IfTypeFast IfType = 125 // Fast channel
|
||||||
IfTypeIP = 126 // IP (for APPN HPR in IP networks)
|
IfTypeIP IfType = 126 // IP (for APPN HPR in IP networks)
|
||||||
IfTypeDocscableMaclayer = 127 // CATV Mac Layer
|
IfTypeDocscableMaclayer IfType = 127 // CATV Mac Layer
|
||||||
IfTypeDocscableDownstream = 128 // CATV Downstream interface
|
IfTypeDocscableDownstream IfType = 128 // CATV Downstream interface
|
||||||
IfTypeDocscableUpstream = 129 // CATV Upstream interface
|
IfTypeDocscableUpstream IfType = 129 // CATV Upstream interface
|
||||||
IfTypeA12mppswitch = 130 // Avalon Parallel Processor
|
IfTypeA12mppswitch IfType = 130 // Avalon Parallel Processor
|
||||||
IfTypeTunnel = 131 // Encapsulation interface
|
IfTypeTunnel IfType = 131 // Encapsulation interface
|
||||||
IfTypeCoffee = 132 // Coffee pot
|
IfTypeCoffee IfType = 132 // Coffee pot
|
||||||
IfTypeCes = 133 // Circuit Emulation Service
|
IfTypeCes IfType = 133 // Circuit Emulation Service
|
||||||
IfTypeAtmSubinterface = 134 // ATM Sub Interface
|
IfTypeAtmSubinterface IfType = 134 // ATM Sub Interface
|
||||||
IfTypeL2Vlan = 135 // Layer 2 Virtual LAN using 802.1Q
|
IfTypeL2Vlan IfType = 135 // Layer 2 Virtual LAN using 802.1Q
|
||||||
IfTypeL3Ipvlan = 136 // Layer 3 Virtual LAN using IP
|
IfTypeL3Ipvlan IfType = 136 // Layer 3 Virtual LAN using IP
|
||||||
IfTypeL3Ipxvlan = 137 // Layer 3 Virtual LAN using IPX
|
IfTypeL3Ipxvlan IfType = 137 // Layer 3 Virtual LAN using IPX
|
||||||
IfTypeDigitalpowerline = 138 // IP over Power Lines
|
IfTypeDigitalpowerline IfType = 138 // IP over Power Lines
|
||||||
IfTypeMediamailoverip = 139 // Multimedia Mail over IP
|
IfTypeMediamailoverip IfType = 139 // Multimedia Mail over IP
|
||||||
IfTypeDtm = 140 // Dynamic syncronous Transfer Mode
|
IfTypeDtm IfType = 140 // Dynamic syncronous Transfer Mode
|
||||||
IfTypeDcn = 141 // Data Communications Network
|
IfTypeDcn IfType = 141 // Data Communications Network
|
||||||
IfTypeIpforward = 142 // IP Forwarding Interface
|
IfTypeIpforward IfType = 142 // IP Forwarding Interface
|
||||||
IfTypeMsdsl = 143 // Multi-rate Symmetric DSL
|
IfTypeMsdsl IfType = 143 // Multi-rate Symmetric DSL
|
||||||
IfTypeIEEE1394 = 144 // IEEE1394 High Perf Serial Bus
|
IfTypeIEEE1394 IfType = 144 // IEEE1394 High Perf Serial Bus
|
||||||
IfTypeIfGsn = 145
|
IfTypeIfGsn IfType = 145
|
||||||
IfTypeDvbrccMaclayer = 146
|
IfTypeDvbrccMaclayer IfType = 146
|
||||||
IfTypeDvbrccDownstream = 147
|
IfTypeDvbrccDownstream IfType = 147
|
||||||
IfTypeDvbrccUpstream = 148
|
IfTypeDvbrccUpstream IfType = 148
|
||||||
IfTypeAtmVirtual = 149
|
IfTypeAtmVirtual IfType = 149
|
||||||
IfTypeMplsTunnel = 150
|
IfTypeMplsTunnel IfType = 150
|
||||||
IfTypeSrp = 151
|
IfTypeSrp IfType = 151
|
||||||
IfTypeVoiceoveratm = 152
|
IfTypeVoiceoveratm IfType = 152
|
||||||
IfTypeVoiceoverframerelay = 153
|
IfTypeVoiceoverframerelay IfType = 153
|
||||||
IfTypeIdsl = 154
|
IfTypeIdsl IfType = 154
|
||||||
IfTypeCompositelink = 155
|
IfTypeCompositelink IfType = 155
|
||||||
IfTypeSs7Siglink = 156
|
IfTypeSs7Siglink IfType = 156
|
||||||
IfTypePropWirelessP2P = 157
|
IfTypePropWirelessP2P IfType = 157
|
||||||
IfTypeFrForward = 158
|
IfTypeFrForward IfType = 158
|
||||||
IfTypeRfc1483 = 159
|
IfTypeRfc1483 IfType = 159
|
||||||
IfTypeUsb = 160
|
IfTypeUsb IfType = 160
|
||||||
IfTypeIEEE8023adLag = 161
|
IfTypeIEEE8023adLag IfType = 161
|
||||||
IfTypeBgpPolicyAccounting = 162
|
IfTypeBgpPolicyAccounting IfType = 162
|
||||||
IfTypeFrf16MfrBundle = 163
|
IfTypeFrf16MfrBundle IfType = 163
|
||||||
IfTypeH323Gatekeeper = 164
|
IfTypeH323Gatekeeper IfType = 164
|
||||||
IfTypeH323Proxy = 165
|
IfTypeH323Proxy IfType = 165
|
||||||
IfTypeMpls = 166
|
IfTypeMpls IfType = 166
|
||||||
IfTypeMfSiglink = 167
|
IfTypeMfSiglink IfType = 167
|
||||||
IfTypeHdsl2 = 168
|
IfTypeHdsl2 IfType = 168
|
||||||
IfTypeShdsl = 169
|
IfTypeShdsl IfType = 169
|
||||||
IfTypeDs1Fdl = 170
|
IfTypeDs1Fdl IfType = 170
|
||||||
IfTypePos = 171
|
IfTypePos IfType = 171
|
||||||
IfTypeDvbAsiIn = 172
|
IfTypeDvbAsiIn IfType = 172
|
||||||
IfTypeDvbAsiOut = 173
|
IfTypeDvbAsiOut IfType = 173
|
||||||
IfTypePlc = 174
|
IfTypePlc IfType = 174
|
||||||
IfTypeNfas = 175
|
IfTypeNfas IfType = 175
|
||||||
IfTypeTr008 = 176
|
IfTypeTr008 IfType = 176
|
||||||
IfTypeGr303Rdt = 177
|
IfTypeGr303Rdt IfType = 177
|
||||||
IfTypeGr303Idt = 178
|
IfTypeGr303Idt IfType = 178
|
||||||
IfTypeIsup = 179
|
IfTypeIsup IfType = 179
|
||||||
IfTypePropDocsWirelessMaclayer = 180
|
IfTypePropDocsWirelessMaclayer IfType = 180
|
||||||
IfTypePropDocsWirelessDownstream = 181
|
IfTypePropDocsWirelessDownstream IfType = 181
|
||||||
IfTypePropDocsWirelessUpstream = 182
|
IfTypePropDocsWirelessUpstream IfType = 182
|
||||||
IfTypeHiperlan2 = 183
|
IfTypeHiperlan2 IfType = 183
|
||||||
IfTypePropBwaP2MP = 184
|
IfTypePropBwaP2MP IfType = 184
|
||||||
IfTypeSonetOverheadChannel = 185
|
IfTypeSonetOverheadChannel IfType = 185
|
||||||
IfTypeDigitalWrapperOverheadChannel = 186
|
IfTypeDigitalWrapperOverheadChannel IfType = 186
|
||||||
IfTypeAal2 = 187
|
IfTypeAal2 IfType = 187
|
||||||
IfTypeRadioMac = 188
|
IfTypeRadioMac IfType = 188
|
||||||
IfTypeAtmRadio = 189
|
IfTypeAtmRadio IfType = 189
|
||||||
IfTypeImt = 190
|
IfTypeImt IfType = 190
|
||||||
IfTypeMvl = 191
|
IfTypeMvl IfType = 191
|
||||||
IfTypeReachDsl = 192
|
IfTypeReachDsl IfType = 192
|
||||||
IfTypeFrDlciEndpt = 193
|
IfTypeFrDlciEndpt IfType = 193
|
||||||
IfTypeAtmVciEndpt = 194
|
IfTypeAtmVciEndpt IfType = 194
|
||||||
IfTypeOpticalChannel = 195
|
IfTypeOpticalChannel IfType = 195
|
||||||
IfTypeOpticalTransport = 196
|
IfTypeOpticalTransport IfType = 196
|
||||||
IfTypeIEEE80216Wman = 237
|
IfTypeIEEE80216Wman IfType = 237
|
||||||
IfTypeWwanpp = 243 // WWAN devices based on GSM technology
|
IfTypeWwanpp IfType = 243 // WWAN devices based on GSM technology
|
||||||
IfTypeWwanpp2 = 244 // WWAN devices based on CDMA technology
|
IfTypeWwanpp2 IfType = 244 // WWAN devices based on CDMA technology
|
||||||
IfTypeIEEE802154 = 259 // IEEE 802.15.4 WPAN interface
|
IfTypeIEEE802154 IfType = 259 // IEEE 802.15.4 WPAN interface
|
||||||
IfTypeXboxWireless = 281
|
IfTypeXboxWireless IfType = 281
|
||||||
)
|
)
|
||||||
|
|
||||||
// MibIfEntryLevel enumeration specifies level of interface information to retrieve in GetIfTable2Ex function call.
|
// MibIfEntryLevel enumeration specifies level of interface information to retrieve in GetIfTable2Ex function call.
|
||||||
|
|
@ -270,7 +272,7 @@ type MibIfEntryLevel uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MibIfEntryNormal MibIfEntryLevel = 0
|
MibIfEntryNormal MibIfEntryLevel = 0
|
||||||
MibIfEntryNormalWithoutStatistics = 2
|
MibIfEntryNormalWithoutStatistics MibIfEntryLevel = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// NdisMedium enumeration type identifies the medium types that NDIS drivers support.
|
// NdisMedium enumeration type identifies the medium types that NDIS drivers support.
|
||||||
|
|
@ -522,12 +524,12 @@ type TunnelType uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TunnelTypeNone TunnelType = 0
|
TunnelTypeNone TunnelType = 0
|
||||||
TunnelTypeOther = 1
|
TunnelTypeOther TunnelType = 1
|
||||||
TunnelTypeDirect = 2
|
TunnelTypeDirect TunnelType = 2
|
||||||
TunnelType6to4 = 11
|
TunnelType6to4 TunnelType = 11
|
||||||
TunnelTypeIsatap = 13
|
TunnelTypeIsatap TunnelType = 13
|
||||||
TunnelTypeTeredo = 14
|
TunnelTypeTeredo TunnelType = 14
|
||||||
TunnelTypeIPHTTPS = 15
|
TunnelTypeIPHTTPS TunnelType = 15
|
||||||
)
|
)
|
||||||
|
|
||||||
// InterfaceAndOperStatusFlags enumeration type defines interface and operation flags
|
// InterfaceAndOperStatusFlags enumeration type defines interface and operation flags
|
||||||
|
|
@ -574,13 +576,13 @@ type ScopeLevel uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ScopeLevelInterface ScopeLevel = 1
|
ScopeLevelInterface ScopeLevel = 1
|
||||||
ScopeLevelLink = 2
|
ScopeLevelLink ScopeLevel = 2
|
||||||
ScopeLevelSubnet = 3
|
ScopeLevelSubnet ScopeLevel = 3
|
||||||
ScopeLevelAdmin = 4
|
ScopeLevelAdmin ScopeLevel = 4
|
||||||
ScopeLevelSite = 5
|
ScopeLevelSite ScopeLevel = 5
|
||||||
ScopeLevelOrganization = 8
|
ScopeLevelOrganization ScopeLevel = 8
|
||||||
ScopeLevelGlobal = 14
|
ScopeLevelGlobal ScopeLevel = 14
|
||||||
ScopeLevelCount = 16
|
ScopeLevelCount ScopeLevel = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
// RouteData structure describes a route to add
|
// RouteData structure describes a route to add
|
||||||
|
|
@ -757,7 +759,7 @@ func (addr *RawSockaddrInet) SetAddrPort(addrPort netip.AddrPort) error {
|
||||||
addr4.Family = windows.AF_INET
|
addr4.Family = windows.AF_INET
|
||||||
addr4.Addr = addrPort.Addr().As4()
|
addr4.Addr = addrPort.Addr().As4()
|
||||||
addr4.Port = htons(addrPort.Port())
|
addr4.Port = htons(addrPort.Port())
|
||||||
for i := 0; i < 8; i++ {
|
for i := range 8 {
|
||||||
addr4.Zero[i] = 0
|
addr4.Zero[i] = 0
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build 386 || arm
|
//go:build windows && (386 || arm)
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build amd64 || arm64
|
//go:build windows && (amd64 || arm64)
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build 386 || arm
|
//go:build windows && (386 || arm)
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build amd64 || arm64
|
//go:build windows && (amd64 || arm64)
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
@ -104,6 +106,9 @@ func TestAdaptersAddresses(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ifcs, err = GetAdaptersAddresses(windows.AF_UNSPEC, GAAFlagDefault)
|
ifcs, err = GetAdaptersAddresses(windows.AF_UNSPEC, GAAFlagDefault)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("GetAdaptersAddresses() returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, i := range ifcs {
|
for _, i := range ifcs {
|
||||||
ifc, err := i.LUID.Interface()
|
ifc, err := i.LUID.Interface()
|
||||||
|
|
@ -370,7 +375,7 @@ func TestAddDeleteIPAddress(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, err := ifc.LUID.IPAddress(nonexistantIPv4ToAdd.Addr())
|
_, err = ifc.LUID.IPAddress(nonexistantIPv4ToAdd.Addr())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Unicast address %s already exists. Please set nonexistantIPv4ToAdd appropriately.", nonexistantIPv4ToAdd.Addr().String())
|
t.Errorf("Unicast address %s already exists. Please set nonexistantIPv4ToAdd appropriately.", nonexistantIPv4ToAdd.Addr().String())
|
||||||
return
|
return
|
||||||
|
|
@ -414,7 +419,7 @@ func TestAddDeleteIPAddress(t *testing.T) {
|
||||||
if count != 1 {
|
if count != 1 {
|
||||||
t.Errorf("After adding there are %d new interface(s).", count)
|
t.Errorf("After adding there are %d new interface(s).", count)
|
||||||
}
|
}
|
||||||
addr, err = ifc.LUID.IPAddress(nonexistantIPv4ToAdd.Addr())
|
addr, err := ifc.LUID.IPAddress(nonexistantIPv4ToAdd.Addr())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("LUID.IPAddress() returned an error: %w", err)
|
t.Errorf("LUID.IPAddress() returned an error: %w", err)
|
||||||
} else if addr == nil {
|
} else if addr == nil {
|
||||||
|
|
@ -431,7 +436,7 @@ func TestAddDeleteIPAddress(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
|
||||||
addr, err = ifc.LUID.IPAddress(nonexistantIPv4ToAdd.Addr())
|
_, err = ifc.LUID.IPAddress(nonexistantIPv4ToAdd.Addr())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Unicast address %s still exists, although it's deleted successfully.", nonexistantIPv4ToAdd.Addr().String())
|
t.Errorf("Unicast address %s still exists, although it's deleted successfully.", nonexistantIPv4ToAdd.Addr().String())
|
||||||
} else if err != windows.ERROR_NOT_FOUND {
|
} else if err != windows.ERROR_NOT_FOUND {
|
||||||
|
|
|
||||||
|
|
@ -56,16 +56,16 @@ func (module *Module) copySections(address, size uintptr, oldHeaders *IMAGE_NT_H
|
||||||
if sectionSize == 0 {
|
if sectionSize == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dest, err := windows.VirtualAlloc(module.codeBase+uintptr(sections[i].VirtualAddress),
|
_, err := windows.VirtualAlloc(module.codeBase+uintptr(sections[i].VirtualAddress),
|
||||||
uintptr(sectionSize),
|
uintptr(sectionSize),
|
||||||
windows.MEM_COMMIT,
|
windows.MEM_COMMIT,
|
||||||
windows.PAGE_READWRITE)
|
windows.PAGE_READWRITE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error allocating section: %w", err)
|
return fmt.Errorf("error allocating section: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always use position from file to support alignments smaller than page size (allocation above will align to page size).
|
// Always use position from file to support alignments smaller than page size (allocation above will align to page size).
|
||||||
dest = module.codeBase + uintptr(sections[i].VirtualAddress)
|
dest := module.codeBase + uintptr(sections[i].VirtualAddress)
|
||||||
// NOTE: On 64bit systems we truncate to 32bit here but expand again later when "PhysicalAddress" is used.
|
// NOTE: On 64bit systems we truncate to 32bit here but expand again later when "PhysicalAddress" is used.
|
||||||
sections[i].SetPhysicalAddress((uint32)(dest & 0xffffffff))
|
sections[i].SetPhysicalAddress((uint32)(dest & 0xffffffff))
|
||||||
dst := unsafe.Slice((*byte)(a2p(dest)), sectionSize)
|
dst := unsafe.Slice((*byte)(a2p(dest)), sectionSize)
|
||||||
|
|
@ -76,7 +76,7 @@ func (module *Module) copySections(address, size uintptr, oldHeaders *IMAGE_NT_H
|
||||||
}
|
}
|
||||||
|
|
||||||
if size < uintptr(sections[i].PointerToRawData)+uintptr(sections[i].SizeOfRawData) {
|
if size < uintptr(sections[i].PointerToRawData)+uintptr(sections[i].SizeOfRawData) {
|
||||||
return errors.New("Incomplete section")
|
return errors.New("incomplete section")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit memory block and copy data from dll.
|
// Commit memory block and copy data from dll.
|
||||||
|
|
@ -85,7 +85,7 @@ func (module *Module) copySections(address, size uintptr, oldHeaders *IMAGE_NT_H
|
||||||
windows.MEM_COMMIT,
|
windows.MEM_COMMIT,
|
||||||
windows.PAGE_READWRITE)
|
windows.PAGE_READWRITE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error allocating memory block: %w", err)
|
return fmt.Errorf("error allocating memory block: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always use position from file to support alignments smaller than page size (allocation above will align to page size).
|
// Always use position from file to support alignments smaller than page size (allocation above will align to page size).
|
||||||
|
|
@ -158,7 +158,7 @@ func (module *Module) finalizeSection(sectionData *sectionFinalizeData) error {
|
||||||
var oldProtect uint32
|
var oldProtect uint32
|
||||||
err := windows.VirtualProtect(sectionData.address, sectionData.size, protect, &oldProtect)
|
err := windows.VirtualProtect(sectionData.address, sectionData.size, protect, &oldProtect)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error protecting memory page: %w", err)
|
return fmt.Errorf("error protecting memory page: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -204,7 +204,7 @@ func (module *Module) finalizeSections() error {
|
||||||
|
|
||||||
err := module.finalizeSection(§ionData)
|
err := module.finalizeSection(§ionData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error finalizing section: %w", err)
|
return fmt.Errorf("error finalizing section: %w", err)
|
||||||
}
|
}
|
||||||
sectionData.address = sectionAddress
|
sectionData.address = sectionAddress
|
||||||
sectionData.alignedAddress = alignedAddress
|
sectionData.alignedAddress = alignedAddress
|
||||||
|
|
@ -214,7 +214,7 @@ func (module *Module) finalizeSections() error {
|
||||||
sectionData.last = true
|
sectionData.last = true
|
||||||
err := module.finalizeSection(§ionData)
|
err := module.finalizeSection(§ionData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error finalizing section: %w", err)
|
return fmt.Errorf("error finalizing section: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -250,10 +250,10 @@ func (module *Module) performBaseRelocation(delta uintptr) (relocated bool, err
|
||||||
relocationHdr := (*IMAGE_BASE_RELOCATION)(a2p(relocBase))
|
relocationHdr := (*IMAGE_BASE_RELOCATION)(a2p(relocBase))
|
||||||
for uintptr(unsafe.Pointer(relocationHdr))+unsafe.Sizeof(*relocationHdr) <= relocEnd && relocationHdr.VirtualAddress > 0 {
|
for uintptr(unsafe.Pointer(relocationHdr))+unsafe.Sizeof(*relocationHdr) <= relocEnd && relocationHdr.VirtualAddress > 0 {
|
||||||
if uintptr(relocationHdr.SizeOfBlock) < unsafe.Sizeof(*relocationHdr) {
|
if uintptr(relocationHdr.SizeOfBlock) < unsafe.Sizeof(*relocationHdr) {
|
||||||
return false, errors.New("Invalid relocation block size")
|
return false, errors.New("invalid relocation block size")
|
||||||
}
|
}
|
||||||
if uintptr(unsafe.Pointer(relocationHdr))+uintptr(relocationHdr.SizeOfBlock) > relocEnd {
|
if uintptr(unsafe.Pointer(relocationHdr))+uintptr(relocationHdr.SizeOfBlock) > relocEnd {
|
||||||
return false, errors.New("Relocation block exceeds directory bounds")
|
return false, errors.New("relocation block exceeds directory bounds")
|
||||||
}
|
}
|
||||||
dest := module.codeBase + uintptr(relocationHdr.VirtualAddress)
|
dest := module.codeBase + uintptr(relocationHdr.VirtualAddress)
|
||||||
|
|
||||||
|
|
@ -272,11 +272,9 @@ func (module *Module) performBaseRelocation(delta uintptr) (relocated bool, err
|
||||||
|
|
||||||
case IMAGE_REL_BASED_LOW:
|
case IMAGE_REL_BASED_LOW:
|
||||||
*(*uint16)(a2p(dest + relOffset)) += uint16(delta & 0xffff)
|
*(*uint16)(a2p(dest + relOffset)) += uint16(delta & 0xffff)
|
||||||
break
|
|
||||||
|
|
||||||
case IMAGE_REL_BASED_HIGH:
|
case IMAGE_REL_BASED_HIGH:
|
||||||
*(*uint16)(a2p(dest + relOffset)) += uint16(uint32(delta) >> 16)
|
*(*uint16)(a2p(dest + relOffset)) += uint16(uint32(delta) >> 16)
|
||||||
break
|
|
||||||
|
|
||||||
case IMAGE_REL_BASED_HIGHLOW:
|
case IMAGE_REL_BASED_HIGHLOW:
|
||||||
*(*uint32)(a2p(dest + relOffset)) += uint32(delta)
|
*(*uint32)(a2p(dest + relOffset)) += uint32(delta)
|
||||||
|
|
@ -289,7 +287,7 @@ func (module *Module) performBaseRelocation(delta uintptr) (relocated bool, err
|
||||||
imm16 := ((inst << 1) & 0x0800) + ((inst << 12) & 0xf000) +
|
imm16 := ((inst << 1) & 0x0800) + ((inst << 12) & 0xf000) +
|
||||||
((inst >> 20) & 0x0700) + ((inst >> 16) & 0x00ff)
|
((inst >> 20) & 0x0700) + ((inst >> 16) & 0x00ff)
|
||||||
if (inst & 0x8000fbf0) != 0x0000f240 {
|
if (inst & 0x8000fbf0) != 0x0000f240 {
|
||||||
return false, fmt.Errorf("Wrong Thumb2 instruction %08x, expected MOVW", inst)
|
return false, fmt.Errorf("wrong Thumb2 instruction %08x, expected MOVW", inst)
|
||||||
}
|
}
|
||||||
imm16 += uint32(delta) & 0xffff
|
imm16 += uint32(delta) & 0xffff
|
||||||
hiDelta := (uint32(delta&0xffff0000) >> 16) + ((imm16 & 0xffff0000) >> 16)
|
hiDelta := (uint32(delta&0xffff0000) >> 16) + ((imm16 & 0xffff0000) >> 16)
|
||||||
|
|
@ -302,11 +300,11 @@ func (module *Module) performBaseRelocation(delta uintptr) (relocated bool, err
|
||||||
imm16 = ((inst << 1) & 0x0800) + ((inst << 12) & 0xf000) +
|
imm16 = ((inst << 1) & 0x0800) + ((inst << 12) & 0xf000) +
|
||||||
((inst >> 20) & 0x0700) + ((inst >> 16) & 0x00ff)
|
((inst >> 20) & 0x0700) + ((inst >> 16) & 0x00ff)
|
||||||
if (inst & 0x8000fbf0) != 0x0000f2c0 {
|
if (inst & 0x8000fbf0) != 0x0000f2c0 {
|
||||||
return false, fmt.Errorf("Wrong Thumb2 instruction %08x, expected MOVT", inst)
|
return false, fmt.Errorf("wrong Thumb2 instruction %08x, expected MOVT", inst)
|
||||||
}
|
}
|
||||||
imm16 += hiDelta
|
imm16 += hiDelta
|
||||||
if imm16 > 0xffff {
|
if imm16 > 0xffff {
|
||||||
return false, fmt.Errorf("Resulting immediate value won't fit: %08x", imm16)
|
return false, fmt.Errorf("resulting immediate value won't fit: %08x", imm16)
|
||||||
}
|
}
|
||||||
*(*uint32)(a2p(dest + relOffset + 4)) = (inst & 0x8f00fbf0) +
|
*(*uint32)(a2p(dest + relOffset + 4)) = (inst & 0x8f00fbf0) +
|
||||||
((imm16 >> 1) & 0x0400) +
|
((imm16 >> 1) & 0x0400) +
|
||||||
|
|
@ -316,7 +314,7 @@ func (module *Module) performBaseRelocation(delta uintptr) (relocated bool, err
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false, fmt.Errorf("Unsupported relocation: %v", relType)
|
return false, fmt.Errorf("unsupported relocation: %v", relType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,7 +335,7 @@ func (module *Module) buildImportTable() error {
|
||||||
for importDesc.Name != 0 {
|
for importDesc.Name != 0 {
|
||||||
handle, err := windows.LoadLibraryEx(windows.BytePtrToString((*byte)(a2p(module.codeBase+uintptr(importDesc.Name)))), 0, windows.LOAD_LIBRARY_SEARCH_SYSTEM32)
|
handle, err := windows.LoadLibraryEx(windows.BytePtrToString((*byte)(a2p(module.codeBase+uintptr(importDesc.Name)))), 0, windows.LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error loading module: %w", err)
|
return fmt.Errorf("error loading module: %w", err)
|
||||||
}
|
}
|
||||||
var thunkRef, funcRef *uintptr
|
var thunkRef, funcRef *uintptr
|
||||||
if importDesc.OriginalFirstThunk() != 0 {
|
if importDesc.OriginalFirstThunk() != 0 {
|
||||||
|
|
@ -357,7 +355,7 @@ func (module *Module) buildImportTable() error {
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
windows.FreeLibrary(handle)
|
windows.FreeLibrary(handle)
|
||||||
return fmt.Errorf("Error getting function address: %w", err)
|
return fmt.Errorf("error getting function address: %w", err)
|
||||||
}
|
}
|
||||||
thunkRef = (*uintptr)(a2p(uintptr(unsafe.Pointer(thunkRef)) + unsafe.Sizeof(*thunkRef)))
|
thunkRef = (*uintptr)(a2p(uintptr(unsafe.Pointer(thunkRef)) + unsafe.Sizeof(*thunkRef)))
|
||||||
funcRef = (*uintptr)(a2p(uintptr(unsafe.Pointer(funcRef)) + unsafe.Sizeof(*funcRef)))
|
funcRef = (*uintptr)(a2p(uintptr(unsafe.Pointer(funcRef)) + unsafe.Sizeof(*funcRef)))
|
||||||
|
|
@ -371,14 +369,14 @@ func (module *Module) buildImportTable() error {
|
||||||
func (module *Module) buildNameExports() error {
|
func (module *Module) buildNameExports() error {
|
||||||
directory := module.headerDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT)
|
directory := module.headerDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT)
|
||||||
if directory.Size == 0 {
|
if directory.Size == 0 {
|
||||||
return errors.New("No export table found")
|
return errors.New("no export table found")
|
||||||
}
|
}
|
||||||
exports := (*IMAGE_EXPORT_DIRECTORY)(a2p(module.codeBase + uintptr(directory.VirtualAddress)))
|
exports := (*IMAGE_EXPORT_DIRECTORY)(a2p(module.codeBase + uintptr(directory.VirtualAddress)))
|
||||||
if exports.NumberOfNames == 0 || exports.NumberOfFunctions == 0 {
|
if exports.NumberOfNames == 0 || exports.NumberOfFunctions == 0 {
|
||||||
return errors.New("No functions exported")
|
return errors.New("no functions exported")
|
||||||
}
|
}
|
||||||
if exports.NumberOfNames == 0 {
|
if exports.NumberOfNames == 0 {
|
||||||
return errors.New("No functions exported by name")
|
return errors.New("no functions exported by name")
|
||||||
}
|
}
|
||||||
nameRefs := unsafe.Slice((*uint32)(a2p(module.codeBase+uintptr(exports.AddressOfNames))), exports.NumberOfNames)
|
nameRefs := unsafe.Slice((*uint32)(a2p(module.codeBase+uintptr(exports.AddressOfNames))), exports.NumberOfNames)
|
||||||
ordinals := unsafe.Slice((*uint16)(a2p(module.codeBase+uintptr(exports.AddressOfNameOrdinals))), exports.NumberOfNames)
|
ordinals := unsafe.Slice((*uint16)(a2p(module.codeBase+uintptr(exports.AddressOfNameOrdinals))), exports.NumberOfNames)
|
||||||
|
|
@ -466,39 +464,39 @@ func hookRtlPcToFileHeader() error {
|
||||||
func LoadLibrary(data []byte) (module *Module, err error) {
|
func LoadLibrary(data []byte) (module *Module, err error) {
|
||||||
size := uintptr(len(data))
|
size := uintptr(len(data))
|
||||||
if size < unsafe.Sizeof(IMAGE_DOS_HEADER{}) {
|
if size < unsafe.Sizeof(IMAGE_DOS_HEADER{}) {
|
||||||
return nil, errors.New("Incomplete IMAGE_DOS_HEADER")
|
return nil, errors.New("incomplete IMAGE_DOS_HEADER")
|
||||||
}
|
}
|
||||||
addr := uintptr(unsafe.Pointer(&data[0]))
|
addr := uintptr(unsafe.Pointer(&data[0]))
|
||||||
dosHeader := (*IMAGE_DOS_HEADER)(a2p(addr))
|
dosHeader := (*IMAGE_DOS_HEADER)(a2p(addr))
|
||||||
if dosHeader.E_magic != IMAGE_DOS_SIGNATURE {
|
if dosHeader.E_magic != IMAGE_DOS_SIGNATURE {
|
||||||
return nil, fmt.Errorf("Not an MS-DOS binary (provided: %x, expected: %x)", dosHeader.E_magic, IMAGE_DOS_SIGNATURE)
|
return nil, fmt.Errorf("not an MS-DOS binary (provided: %x, expected: %x)", dosHeader.E_magic, IMAGE_DOS_SIGNATURE)
|
||||||
}
|
}
|
||||||
if dosHeader.E_lfanew < 0 || (size < uintptr(dosHeader.E_lfanew)+unsafe.Sizeof(IMAGE_NT_HEADERS{})) {
|
if dosHeader.E_lfanew < 0 || (size < uintptr(dosHeader.E_lfanew)+unsafe.Sizeof(IMAGE_NT_HEADERS{})) {
|
||||||
return nil, errors.New("Incomplete IMAGE_NT_HEADERS")
|
return nil, errors.New("incomplete IMAGE_NT_HEADERS")
|
||||||
}
|
}
|
||||||
oldHeader := (*IMAGE_NT_HEADERS)(a2p(addr + uintptr(dosHeader.E_lfanew)))
|
oldHeader := (*IMAGE_NT_HEADERS)(a2p(addr + uintptr(dosHeader.E_lfanew)))
|
||||||
if oldHeader.Signature != IMAGE_NT_SIGNATURE {
|
if oldHeader.Signature != IMAGE_NT_SIGNATURE {
|
||||||
return nil, fmt.Errorf("Not an NT binary (provided: %x, expected: %x)", oldHeader.Signature, IMAGE_NT_SIGNATURE)
|
return nil, fmt.Errorf("not an NT binary (provided: %x, expected: %x)", oldHeader.Signature, IMAGE_NT_SIGNATURE)
|
||||||
}
|
}
|
||||||
if oldHeader.FileHeader.Machine != imageFileProcess {
|
if oldHeader.FileHeader.Machine != imageFileProcess {
|
||||||
return nil, fmt.Errorf("Foreign platform (provided: %x, expected: %x)", oldHeader.FileHeader.Machine, imageFileProcess)
|
return nil, fmt.Errorf("foreign platform (provided: %x, expected: %x)", oldHeader.FileHeader.Machine, imageFileProcess)
|
||||||
}
|
}
|
||||||
if oldHeader.OptionalHeader.SectionAlignment == 0 || (oldHeader.OptionalHeader.SectionAlignment&(oldHeader.OptionalHeader.SectionAlignment-1)) != 0 {
|
if oldHeader.OptionalHeader.SectionAlignment == 0 || (oldHeader.OptionalHeader.SectionAlignment&(oldHeader.OptionalHeader.SectionAlignment-1)) != 0 {
|
||||||
return nil, errors.New("Unaligned section")
|
return nil, errors.New("unaligned section")
|
||||||
}
|
}
|
||||||
if oldHeader.FileHeader.NumberOfSections == 0 {
|
if oldHeader.FileHeader.NumberOfSections == 0 {
|
||||||
return nil, errors.New("No sections")
|
return nil, errors.New("no sections")
|
||||||
}
|
}
|
||||||
if uintptr(oldHeader.FileHeader.SizeOfOptionalHeader) < unsafe.Sizeof(oldHeader.OptionalHeader) {
|
if uintptr(oldHeader.FileHeader.SizeOfOptionalHeader) < unsafe.Sizeof(oldHeader.OptionalHeader) {
|
||||||
return nil, errors.New("Incomplete optional header")
|
return nil, errors.New("incomplete optional header")
|
||||||
}
|
}
|
||||||
if oldHeader.OptionalHeader.NumberOfRvaAndSizes < IMAGE_NUMBEROF_DIRECTORY_ENTRIES {
|
if oldHeader.OptionalHeader.NumberOfRvaAndSizes < IMAGE_NUMBEROF_DIRECTORY_ENTRIES {
|
||||||
return nil, errors.New("Incomplete data directory")
|
return nil, errors.New("incomplete data directory")
|
||||||
}
|
}
|
||||||
sectionHeadersEnd := uintptr(dosHeader.E_lfanew) + unsafe.Offsetof(oldHeader.OptionalHeader) + uintptr(oldHeader.FileHeader.SizeOfOptionalHeader) +
|
sectionHeadersEnd := uintptr(dosHeader.E_lfanew) + unsafe.Offsetof(oldHeader.OptionalHeader) + uintptr(oldHeader.FileHeader.SizeOfOptionalHeader) +
|
||||||
uintptr(oldHeader.FileHeader.NumberOfSections)*unsafe.Sizeof(IMAGE_SECTION_HEADER{})
|
uintptr(oldHeader.FileHeader.NumberOfSections)*unsafe.Sizeof(IMAGE_SECTION_HEADER{})
|
||||||
if size < sectionHeadersEnd {
|
if size < sectionHeadersEnd {
|
||||||
return nil, errors.New("Incomplete section headers")
|
return nil, errors.New("incomplete section headers")
|
||||||
}
|
}
|
||||||
lastSectionEnd := uintptr(0)
|
lastSectionEnd := uintptr(0)
|
||||||
sections := oldHeader.Sections()
|
sections := oldHeader.Sections()
|
||||||
|
|
@ -517,7 +515,7 @@ func LoadLibrary(data []byte) (module *Module, err error) {
|
||||||
}
|
}
|
||||||
alignedImageSize := alignUp(uintptr(oldHeader.OptionalHeader.SizeOfImage), uintptr(oldHeader.OptionalHeader.SectionAlignment))
|
alignedImageSize := alignUp(uintptr(oldHeader.OptionalHeader.SizeOfImage), uintptr(oldHeader.OptionalHeader.SectionAlignment))
|
||||||
if alignedImageSize != alignUp(lastSectionEnd, uintptr(oldHeader.OptionalHeader.SectionAlignment)) {
|
if alignedImageSize != alignUp(lastSectionEnd, uintptr(oldHeader.OptionalHeader.SectionAlignment)) {
|
||||||
return nil, errors.New("Section is not page-aligned")
|
return nil, errors.New("section is not page-aligned")
|
||||||
}
|
}
|
||||||
|
|
||||||
module = &Module{isDLL: (oldHeader.FileHeader.Characteristics & IMAGE_FILE_DLL) != 0}
|
module = &Module{isDLL: (oldHeader.FileHeader.Characteristics & IMAGE_FILE_DLL) != 0}
|
||||||
|
|
@ -541,18 +539,18 @@ func LoadLibrary(data []byte) (module *Module, err error) {
|
||||||
windows.MEM_RESERVE|windows.MEM_COMMIT,
|
windows.MEM_RESERVE|windows.MEM_COMMIT,
|
||||||
windows.PAGE_READWRITE)
|
windows.PAGE_READWRITE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Error allocating code: %w", err)
|
err = fmt.Errorf("error allocating code: %w", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = module.check4GBBoundaries(alignedImageSize)
|
err = module.check4GBBoundaries(alignedImageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Error reallocating code: %w", err)
|
err = fmt.Errorf("error reallocating code: %w", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if size < uintptr(oldHeader.OptionalHeader.SizeOfHeaders) {
|
if size < uintptr(oldHeader.OptionalHeader.SizeOfHeaders) {
|
||||||
err = errors.New("Incomplete headers")
|
err = errors.New("incomplete headers")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Commit memory for headers.
|
// Commit memory for headers.
|
||||||
|
|
@ -561,7 +559,7 @@ func LoadLibrary(data []byte) (module *Module, err error) {
|
||||||
windows.MEM_COMMIT,
|
windows.MEM_COMMIT,
|
||||||
windows.PAGE_READWRITE)
|
windows.PAGE_READWRITE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Error allocating headers: %w", err)
|
err = fmt.Errorf("error allocating headers: %w", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Copy PE header to code.
|
// Copy PE header to code.
|
||||||
|
|
@ -574,7 +572,7 @@ func LoadLibrary(data []byte) (module *Module, err error) {
|
||||||
// Copy sections from DLL file block to new memory location.
|
// Copy sections from DLL file block to new memory location.
|
||||||
err = module.copySections(addr, size, oldHeader)
|
err = module.copySections(addr, size, oldHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Error copying sections: %w", err)
|
err = fmt.Errorf("error copying sections: %w", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -583,7 +581,7 @@ func LoadLibrary(data []byte) (module *Module, err error) {
|
||||||
if locationDelta != 0 {
|
if locationDelta != 0 {
|
||||||
module.isRelocated, err = module.performBaseRelocation(locationDelta)
|
module.isRelocated, err = module.performBaseRelocation(locationDelta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Error relocating module: %w", err)
|
err = fmt.Errorf("error relocating module: %w", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !module.isRelocated {
|
if !module.isRelocated {
|
||||||
|
|
@ -597,14 +595,14 @@ func LoadLibrary(data []byte) (module *Module, err error) {
|
||||||
// Load required dlls and adjust function table of imports.
|
// Load required dlls and adjust function table of imports.
|
||||||
err = module.buildImportTable()
|
err = module.buildImportTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Error building import table: %w", err)
|
err = fmt.Errorf("error building import table: %w", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark memory pages depending on section headers and release sections that are marked as "discardable".
|
// Mark memory pages depending on section headers and release sections that are marked as "discardable".
|
||||||
err = module.finalizeSections()
|
err = module.finalizeSections()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Error finalizing sections: %w", err)
|
err = fmt.Errorf("error finalizing sections: %w", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -673,35 +671,35 @@ func (module *Module) Free() {
|
||||||
func (module *Module) ProcAddressByName(name string) (uintptr, error) {
|
func (module *Module) ProcAddressByName(name string) (uintptr, error) {
|
||||||
directory := module.headerDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT)
|
directory := module.headerDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT)
|
||||||
if directory.Size == 0 {
|
if directory.Size == 0 {
|
||||||
return 0, errors.New("No export table found")
|
return 0, errors.New("no export table found")
|
||||||
}
|
}
|
||||||
exports := (*IMAGE_EXPORT_DIRECTORY)(a2p(module.codeBase + uintptr(directory.VirtualAddress)))
|
exports := (*IMAGE_EXPORT_DIRECTORY)(a2p(module.codeBase + uintptr(directory.VirtualAddress)))
|
||||||
if module.nameExports == nil {
|
if module.nameExports == nil {
|
||||||
return 0, errors.New("No functions exported by name")
|
return 0, errors.New("no functions exported by name")
|
||||||
}
|
}
|
||||||
if idx, ok := module.nameExports[name]; ok {
|
if idx, ok := module.nameExports[name]; ok {
|
||||||
if uint32(idx) >= exports.NumberOfFunctions {
|
if uint32(idx) >= exports.NumberOfFunctions {
|
||||||
return 0, errors.New("Ordinal number too high")
|
return 0, errors.New("ordinal number too high")
|
||||||
}
|
}
|
||||||
// AddressOfFunctions contains the RVAs to the "real" functions.
|
// AddressOfFunctions contains the RVAs to the "real" functions.
|
||||||
return module.codeBase + uintptr(*(*uint32)(a2p(module.codeBase + uintptr(exports.AddressOfFunctions) + uintptr(idx)*4))), nil
|
return module.codeBase + uintptr(*(*uint32)(a2p(module.codeBase + uintptr(exports.AddressOfFunctions) + uintptr(idx)*4))), nil
|
||||||
}
|
}
|
||||||
return 0, errors.New("Function not found by name")
|
return 0, errors.New("function not found by name")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcAddressByOrdinal returns function address by exported ordinal.
|
// ProcAddressByOrdinal returns function address by exported ordinal.
|
||||||
func (module *Module) ProcAddressByOrdinal(ordinal uint16) (uintptr, error) {
|
func (module *Module) ProcAddressByOrdinal(ordinal uint16) (uintptr, error) {
|
||||||
directory := module.headerDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT)
|
directory := module.headerDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT)
|
||||||
if directory.Size == 0 {
|
if directory.Size == 0 {
|
||||||
return 0, errors.New("No export table found")
|
return 0, errors.New("no export table found")
|
||||||
}
|
}
|
||||||
exports := (*IMAGE_EXPORT_DIRECTORY)(a2p(module.codeBase + uintptr(directory.VirtualAddress)))
|
exports := (*IMAGE_EXPORT_DIRECTORY)(a2p(module.codeBase + uintptr(directory.VirtualAddress)))
|
||||||
if uint32(ordinal) < exports.Base {
|
if uint32(ordinal) < exports.Base {
|
||||||
return 0, errors.New("Ordinal number too low")
|
return 0, errors.New("ordinal number too low")
|
||||||
}
|
}
|
||||||
idx := ordinal - uint16(exports.Base)
|
idx := ordinal - uint16(exports.Base)
|
||||||
if uint32(idx) >= exports.NumberOfFunctions {
|
if uint32(idx) >= exports.NumberOfFunctions {
|
||||||
return 0, errors.New("Ordinal number too high")
|
return 0, errors.New("ordinal number too high")
|
||||||
}
|
}
|
||||||
// AddressOfFunctions contains the RVAs to the "real" functions.
|
// AddressOfFunctions contains the RVAs to the "real" functions.
|
||||||
return module.codeBase + uintptr(*(*uint32)(a2p(module.codeBase + uintptr(exports.AddressOfFunctions) + uintptr(idx)*4))), nil
|
return module.codeBase + uintptr(*(*uint32)(a2p(module.codeBase + uintptr(exports.AddressOfFunctions) + uintptr(idx)*4))), nil
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ func (module *Module) check4GBBoundaries(alignedImageSize uintptr) (err error) {
|
||||||
windows.MEM_RESERVE|windows.MEM_COMMIT,
|
windows.MEM_RESERVE|windows.MEM_COMMIT,
|
||||||
windows.PAGE_READWRITE)
|
windows.PAGE_READWRITE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error allocating memory block: %w", err)
|
return fmt.Errorf("error allocating memory block: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (wintun *Adapter) StartSession(capacity uint32) (session Session, err error) {
|
func (wintun *Adapter) StartSession(capacity uint32) (session Session, err error) {
|
||||||
r0, _, e1 := syscall.Syscall(procWintunStartSession.Addr(), 2, uintptr(wintun.handle), uintptr(capacity), 0)
|
r0, _, e1 := syscall.SyscallN(procWintunStartSession.Addr(), uintptr(wintun.handle), uintptr(capacity))
|
||||||
if r0 == 0 {
|
if r0 == 0 {
|
||||||
err = e1
|
err = e1
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -50,19 +50,18 @@ func (wintun *Adapter) StartSession(capacity uint32) (session Session, err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session Session) End() {
|
func (session Session) End() {
|
||||||
syscall.Syscall(procWintunEndSession.Addr(), 1, session.handle, 0, 0)
|
syscall.SyscallN(procWintunEndSession.Addr(), session.handle)
|
||||||
session.handle = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session Session) ReadWaitEvent() (handle windows.Handle) {
|
func (session Session) ReadWaitEvent() (handle windows.Handle) {
|
||||||
r0, _, _ := syscall.Syscall(procWintunGetReadWaitEvent.Addr(), 1, session.handle, 0, 0)
|
r0, _, _ := syscall.SyscallN(procWintunGetReadWaitEvent.Addr(), session.handle)
|
||||||
handle = windows.Handle(r0)
|
handle = windows.Handle(r0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session Session) ReceivePacket() (packet []byte, err error) {
|
func (session Session) ReceivePacket() (packet []byte, err error) {
|
||||||
var packetSize uint32
|
var packetSize uint32
|
||||||
r0, _, e1 := syscall.Syscall(procWintunReceivePacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packetSize)), 0)
|
r0, _, e1 := syscall.SyscallN(procWintunReceivePacket.Addr(), session.handle, uintptr(unsafe.Pointer(&packetSize)))
|
||||||
if r0 == 0 {
|
if r0 == 0 {
|
||||||
err = e1
|
err = e1
|
||||||
return
|
return
|
||||||
|
|
@ -72,11 +71,11 @@ func (session Session) ReceivePacket() (packet []byte, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session Session) ReleaseReceivePacket(packet []byte) {
|
func (session Session) ReleaseReceivePacket(packet []byte) {
|
||||||
syscall.Syscall(procWintunReleaseReceivePacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packet[0])), 0)
|
syscall.SyscallN(procWintunReleaseReceivePacket.Addr(), session.handle, uintptr(unsafe.Pointer(&packet[0])))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session Session) AllocateSendPacket(packetSize int) (packet []byte, err error) {
|
func (session Session) AllocateSendPacket(packetSize int) (packet []byte, err error) {
|
||||||
r0, _, e1 := syscall.Syscall(procWintunAllocateSendPacket.Addr(), 2, session.handle, uintptr(packetSize), 0)
|
r0, _, e1 := syscall.SyscallN(procWintunAllocateSendPacket.Addr(), session.handle, uintptr(packetSize))
|
||||||
if r0 == 0 {
|
if r0 == 0 {
|
||||||
err = e1
|
err = e1
|
||||||
return
|
return
|
||||||
|
|
@ -86,5 +85,5 @@ func (session Session) AllocateSendPacket(packetSize int) (packet []byte, err er
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session Session) SendPacket(packet []byte) {
|
func (session Session) SendPacket(packet []byte) {
|
||||||
syscall.Syscall(procWintunSendPacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packet[0])), 0)
|
syscall.SyscallN(procWintunSendPacket.Addr(), session.handle, uintptr(unsafe.Pointer(&packet[0])))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func closeAdapter(wintun *Adapter) {
|
func closeAdapter(wintun *Adapter) {
|
||||||
syscall.SyscallN(procWintunCloseAdapter.Addr(), 1, wintun.handle, 0, 0)
|
syscall.SyscallN(procWintunCloseAdapter.Addr(), wintun.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAdapter creates a Wintun adapter. name is the cosmetic name of the adapter.
|
// CreateAdapter creates a Wintun adapter. name is the cosmetic name of the adapter.
|
||||||
|
|
@ -53,7 +53,7 @@ func CreateAdapter(name string, tunnelType string, requestedGUID *windows.GUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r0, _, e1 := syscall.Syscall(procWintunCreateAdapter.Addr(), 3, uintptr(unsafe.Pointer(name16)), uintptr(unsafe.Pointer(tunnelType16)), uintptr(unsafe.Pointer(requestedGUID)))
|
r0, _, e1 := syscall.SyscallN(procWintunCreateAdapter.Addr(), uintptr(unsafe.Pointer(name16)), uintptr(unsafe.Pointer(tunnelType16)), uintptr(unsafe.Pointer(requestedGUID)))
|
||||||
if r0 == 0 {
|
if r0 == 0 {
|
||||||
err = e1
|
err = e1
|
||||||
return
|
return
|
||||||
|
|
@ -70,7 +70,7 @@ func OpenAdapter(name string) (wintun *Adapter, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r0, _, e1 := syscall.Syscall(procWintunOpenAdapter.Addr(), 1, uintptr(unsafe.Pointer(name16)), 0, 0)
|
r0, _, e1 := syscall.SyscallN(procWintunOpenAdapter.Addr(), uintptr(unsafe.Pointer(name16)))
|
||||||
if r0 == 0 {
|
if r0 == 0 {
|
||||||
err = e1
|
err = e1
|
||||||
return
|
return
|
||||||
|
|
@ -83,7 +83,7 @@ func OpenAdapter(name string) (wintun *Adapter, err error) {
|
||||||
// Close closes a Wintun adapter.
|
// Close closes a Wintun adapter.
|
||||||
func (wintun *Adapter) Close() (err error) {
|
func (wintun *Adapter) Close() (err error) {
|
||||||
runtime.SetFinalizer(wintun, nil)
|
runtime.SetFinalizer(wintun, nil)
|
||||||
r1, _, e1 := syscall.Syscall(procWintunCloseAdapter.Addr(), 1, wintun.handle, 0, 0)
|
r1, _, e1 := syscall.SyscallN(procWintunCloseAdapter.Addr(), wintun.handle)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
err = e1
|
err = e1
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ func (wintun *Adapter) Close() (err error) {
|
||||||
|
|
||||||
// Uninstall removes the driver from the system if no drivers are currently in use.
|
// Uninstall removes the driver from the system if no drivers are currently in use.
|
||||||
func Uninstall() (err error) {
|
func Uninstall() (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procWintunDeleteDriver.Addr(), 0, 0, 0, 0)
|
r1, _, e1 := syscall.SyscallN(procWintunDeleteDriver.Addr())
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
err = e1
|
err = e1
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +101,7 @@ func Uninstall() (err error) {
|
||||||
|
|
||||||
// RunningVersion returns the version of the running Wintun driver.
|
// RunningVersion returns the version of the running Wintun driver.
|
||||||
func RunningVersion() (version uint32, err error) {
|
func RunningVersion() (version uint32, err error) {
|
||||||
r0, _, e1 := syscall.Syscall(procWintunGetRunningDriverVersion.Addr(), 0, 0, 0, 0)
|
r0, _, e1 := syscall.SyscallN(procWintunGetRunningDriverVersion.Addr())
|
||||||
version = uint32(r0)
|
version = uint32(r0)
|
||||||
if version == 0 {
|
if version == 0 {
|
||||||
err = e1
|
err = e1
|
||||||
|
|
@ -111,6 +111,6 @@ func RunningVersion() (version uint32, err error) {
|
||||||
|
|
||||||
// LUID returns the LUID of the adapter.
|
// LUID returns the LUID of the adapter.
|
||||||
func (wintun *Adapter) LUID() (luid uint64) {
|
func (wintun *Adapter) LUID() (luid uint64) {
|
||||||
syscall.Syscall(procWintunGetAdapterLUID.Addr(), 2, uintptr(wintun.handle), uintptr(unsafe.Pointer(&luid)), 0)
|
syscall.SyscallN(procWintunGetAdapterLUID.Addr(), uintptr(wintun.handle), uintptr(unsafe.Pointer(&luid)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,8 @@ func (h *nfqueueHandler) handlePacket(attr nfqueue.Attribute) int {
|
||||||
var tcpOffset int
|
var tcpOffset int
|
||||||
|
|
||||||
version := payload[0] >> 4
|
version := payload[0] >> 4
|
||||||
if version == 4 {
|
switch version {
|
||||||
|
case 4:
|
||||||
ipv4 := header.IPv4(payload)
|
ipv4 := header.IPv4(payload)
|
||||||
if !ipv4.IsValid(len(payload)) || ipv4.Protocol() != uint8(unix.IPPROTO_TCP) {
|
if !ipv4.IsValid(len(payload)) || ipv4.Protocol() != uint8(unix.IPPROTO_TCP) {
|
||||||
h.setVerdict(packetID, nfqueue.NfAccept, 0)
|
h.setVerdict(packetID, nfqueue.NfAccept, 0)
|
||||||
|
|
@ -182,7 +183,7 @@ func (h *nfqueueHandler) handlePacket(attr nfqueue.Attribute) int {
|
||||||
srcAddr = M.SocksaddrFrom(ipv4.SourceAddr(), 0)
|
srcAddr = M.SocksaddrFrom(ipv4.SourceAddr(), 0)
|
||||||
dstAddr = M.SocksaddrFrom(ipv4.DestinationAddr(), 0)
|
dstAddr = M.SocksaddrFrom(ipv4.DestinationAddr(), 0)
|
||||||
tcpOffset = int(ipv4.HeaderLength())
|
tcpOffset = int(ipv4.HeaderLength())
|
||||||
} else if version == 6 {
|
case 6:
|
||||||
transportProto, transportOffset, ok := parseIPv6TransportHeader(payload)
|
transportProto, transportOffset, ok := parseIPv6TransportHeader(payload)
|
||||||
if !ok || transportProto != unix.IPPROTO_TCP {
|
if !ok || transportProto != unix.IPPROTO_TCP {
|
||||||
h.setVerdict(packetID, nfqueue.NfAccept, 0)
|
h.setVerdict(packetID, nfqueue.NfAccept, 0)
|
||||||
|
|
@ -192,7 +193,7 @@ func (h *nfqueueHandler) handlePacket(attr nfqueue.Attribute) int {
|
||||||
srcAddr = M.SocksaddrFrom(ipv6.SourceAddr(), 0)
|
srcAddr = M.SocksaddrFrom(ipv6.SourceAddr(), 0)
|
||||||
dstAddr = M.SocksaddrFrom(ipv6.DestinationAddr(), 0)
|
dstAddr = M.SocksaddrFrom(ipv6.DestinationAddr(), 0)
|
||||||
tcpOffset = transportOffset
|
tcpOffset = transportOffset
|
||||||
} else {
|
default:
|
||||||
h.setVerdict(packetID, nfqueue.NfAccept, 0)
|
h.setVerdict(packetID, nfqueue.NfAccept, 0)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
stack.go
2
stack.go
|
|
@ -68,7 +68,7 @@ func NewStack(
|
||||||
|
|
||||||
func HasNextAddress(prefix netip.Prefix, count int) bool {
|
func HasNextAddress(prefix netip.Prefix, count int) bool {
|
||||||
checkAddr := prefix.Addr()
|
checkAddr := prefix.Addr()
|
||||||
for i := 0; i < count; i++ {
|
for range count {
|
||||||
checkAddr = checkAddr.Next()
|
checkAddr = checkAddr.Next()
|
||||||
}
|
}
|
||||||
return prefix.Contains(checkAddr)
|
return prefix.Contains(checkAddr)
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ func (s *System) start() error {
|
||||||
var tcpListener net.Listener
|
var tcpListener net.Listener
|
||||||
var err error
|
var err error
|
||||||
if s.inet4NextAddress.IsValid() {
|
if s.inet4NextAddress.IsValid() {
|
||||||
for i := 0; i < 3; i++ {
|
for range 3 {
|
||||||
tcpListener, err = listener.Listen(s.ctx, "tcp4", net.JoinHostPort(s.inet4Address.String(), "0"))
|
tcpListener, err = listener.Listen(s.ctx, "tcp4", net.JoinHostPort(s.inet4Address.String(), "0"))
|
||||||
if !retryableListenError(err) {
|
if !retryableListenError(err) {
|
||||||
break
|
break
|
||||||
|
|
@ -146,7 +146,7 @@ func (s *System) start() error {
|
||||||
go s.acceptLoop(tcpListener)
|
go s.acceptLoop(tcpListener)
|
||||||
}
|
}
|
||||||
if s.inet6NextAddress.IsValid() {
|
if s.inet6NextAddress.IsValid() {
|
||||||
for i := 0; i < 3; i++ {
|
for range 3 {
|
||||||
tcpListener, err = listener.Listen(s.ctx, "tcp6", net.JoinHostPort(s.inet6Address.String(), "0"))
|
tcpListener, err = listener.Listen(s.ctx, "tcp6", net.JoinHostPort(s.inet6Address.String(), "0"))
|
||||||
if !retryableListenError(err) {
|
if !retryableListenError(err) {
|
||||||
break
|
break
|
||||||
|
|
@ -245,7 +245,7 @@ func (s *System) batchLoopLinux(linuxTUN LinuxTUN, batchSize int) {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for i := 0; i < n; i++ {
|
for i := range n {
|
||||||
packetSize := packetSizes[i]
|
packetSize := packetSizes[i]
|
||||||
if packetSize < header.IPv4MinimumSize {
|
if packetSize < header.IPv4MinimumSize {
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ func New(options Options) (Tun, error) {
|
||||||
stopFd: common.Must1(stopfd.New()),
|
stopFd: common.Must1(stopfd.New()),
|
||||||
sendMsgX: options.EXP_SendMsgX,
|
sendMsgX: options.EXP_SendMsgX,
|
||||||
}
|
}
|
||||||
for i := 0; i < batchSize; i++ {
|
for i := range batchSize {
|
||||||
nativeTun.iovecs[i] = newIovecBuffer(int(options.MTU))
|
nativeTun.iovecs[i] = newIovecBuffer(int(options.MTU))
|
||||||
nativeTun.iovecsOutput[i] = newIovecBuffer(int(options.MTU))
|
nativeTun.iovecsOutput[i] = newIovecBuffer(int(options.MTU))
|
||||||
}
|
}
|
||||||
|
|
@ -352,7 +352,7 @@ func (t *NativeTun) BatchRead() ([]*buf.Buffer, error) {
|
||||||
}
|
}
|
||||||
n, errno := rawfile.BlockingRecvMMsgUntilStopped(t.stopFd.ReadFD, t.tunFd, t.msgHdrs)
|
n, errno := rawfile.BlockingRecvMMsgUntilStopped(t.stopFd.ReadFD, t.tunFd, t.msgHdrs)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
for k := 0; k < n; k++ {
|
for k := range n {
|
||||||
t.iovecs[k].buffer.Release()
|
t.iovecs[k].buffer.Release()
|
||||||
t.iovecs[k].buffer = nil
|
t.iovecs[k].buffer = nil
|
||||||
}
|
}
|
||||||
|
|
@ -366,7 +366,7 @@ func (t *NativeTun) BatchRead() ([]*buf.Buffer, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
buffers := t.buffers
|
buffers := t.buffers
|
||||||
for k := 0; k < n; k++ {
|
for k := range n {
|
||||||
buffer := t.iovecs[k].buffer
|
buffer := t.iovecs[k].buffer
|
||||||
t.iovecs[k].buffer = nil
|
t.iovecs[k].buffer = nil
|
||||||
buffer.Truncate(int(t.msgHdrs[k].DataLen) - PacketOffset)
|
buffer.Truncate(int(t.msgHdrs[k].DataLen) - PacketOffset)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ type NativeTun struct {
|
||||||
vnetHdrWriteBuf []byte
|
vnetHdrWriteBuf []byte
|
||||||
gsoToWrite []int
|
gsoToWrite []int
|
||||||
tcpGROTable *tcpGROTable
|
tcpGROTable *tcpGROTable
|
||||||
udpGroAccess sync.Mutex
|
|
||||||
udpGROTable *udpGROTable
|
udpGROTable *udpGROTable
|
||||||
gro groDisablementFlags
|
gro groDisablementFlags
|
||||||
txChecksumOffload bool
|
txChecksumOffload bool
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,6 @@ import (
|
||||||
"github.com/sagernet/sing-tun/internal/gtcpip/header"
|
"github.com/sagernet/sing-tun/internal/gtcpip/header"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
gsoMaxSize = 65536
|
|
||||||
idealBatchSize = 128
|
|
||||||
)
|
|
||||||
|
|
||||||
// GSOType represents the type of segmentation offload.
|
// GSOType represents the type of segmentation offload.
|
||||||
type GSOType int
|
type GSOType int
|
||||||
|
|
||||||
|
|
@ -167,10 +162,7 @@ func GSOSplit(in []byte, options GSOOptions, outBufs [][]byte, sizes []int, outO
|
||||||
if i == len(outBufs) {
|
if i == len(outBufs) {
|
||||||
return i - 1, ErrTooManySegments
|
return i - 1, ErrTooManySegments
|
||||||
}
|
}
|
||||||
nextSegmentEnd := nextSegmentDataAt + int(options.GSOSize)
|
nextSegmentEnd := min(nextSegmentDataAt+int(options.GSOSize), len(in))
|
||||||
if nextSegmentEnd > len(in) {
|
|
||||||
nextSegmentEnd = len(in)
|
|
||||||
}
|
|
||||||
segmentDataLen := nextSegmentEnd - nextSegmentDataAt
|
segmentDataLen := nextSegmentEnd - nextSegmentDataAt
|
||||||
totalLen := int(options.HdrLen) + segmentDataLen
|
totalLen := int(options.HdrLen) + segmentDataLen
|
||||||
sizes[i] = totalLen
|
sizes[i] = totalLen
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"slices"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/sagernet/sing-tun/internal/gtcpip"
|
"github.com/sagernet/sing-tun/internal/gtcpip"
|
||||||
|
|
@ -20,6 +21,11 @@ import (
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
gsoMaxSize = 65536
|
||||||
|
idealBatchSize = 128
|
||||||
|
)
|
||||||
|
|
||||||
// virtioNetHdr is defined in the kernel in include/uapi/linux/virtio_net.h. The
|
// virtioNetHdr is defined in the kernel in include/uapi/linux/virtio_net.h. The
|
||||||
// kernel symbol is virtio_net_hdr.
|
// kernel symbol is virtio_net_hdr.
|
||||||
type virtioNetHdr struct {
|
type virtioNetHdr struct {
|
||||||
|
|
@ -606,7 +612,7 @@ func tcpGRO(bufs [][]byte, offset int, pktI int, table *tcpGROTable, isV6 bool)
|
||||||
if !existing {
|
if !existing {
|
||||||
return groResultTableInsert
|
return groResultTableInsert
|
||||||
}
|
}
|
||||||
for i := len(items) - 1; i >= 0; i-- {
|
for i, item := range slices.Backward(items) {
|
||||||
// In the best case of packets arriving in order iterating in reverse is
|
// In the best case of packets arriving in order iterating in reverse is
|
||||||
// more efficient if there are multiple items for a given flow. This
|
// more efficient if there are multiple items for a given flow. This
|
||||||
// also enables a natural table.deleteAt() in the
|
// also enables a natural table.deleteAt() in the
|
||||||
|
|
@ -615,7 +621,6 @@ func tcpGRO(bufs [][]byte, offset int, pktI int, table *tcpGROTable, isV6 bool)
|
||||||
// unordered packets, where pkt may land anywhere in items from a
|
// unordered packets, where pkt may land anywhere in items from a
|
||||||
// sequence number perspective, however once an item is inserted into
|
// sequence number perspective, however once an item is inserted into
|
||||||
// the table it is never compared across other items later.
|
// the table it is never compared across other items later.
|
||||||
item := items[i]
|
|
||||||
can := tcpPacketsCanCoalesce(pkt, uint8(iphLen), uint8(tcphLen), seq, pshSet, gsoSize, item, bufs, offset)
|
can := tcpPacketsCanCoalesce(pkt, uint8(iphLen), uint8(tcphLen), seq, pshSet, gsoSize, item, bufs, offset)
|
||||||
if can != coalesceUnavailable {
|
if can != coalesceUnavailable {
|
||||||
result := coalesceTCPPackets(can, pkt, pktI, gsoSize, seq, pshSet, &item, bufs, offset, isV6)
|
result := coalesceTCPPackets(can, pkt, pktI, gsoSize, seq, pshSet, &item, bufs, offset, isV6)
|
||||||
|
|
@ -793,7 +798,8 @@ func packetIsGROCandidate(b []byte, gro groDisablementFlags) groCandidateType {
|
||||||
if len(b) < 28 {
|
if len(b) < 28 {
|
||||||
return notGROCandidate
|
return notGROCandidate
|
||||||
}
|
}
|
||||||
if b[0]>>4 == 4 {
|
switch b[0] >> 4 {
|
||||||
|
case 4:
|
||||||
if b[0]&0x0F != 5 {
|
if b[0]&0x0F != 5 {
|
||||||
// IPv4 packets w/IP options do not coalesce
|
// IPv4 packets w/IP options do not coalesce
|
||||||
return notGROCandidate
|
return notGROCandidate
|
||||||
|
|
@ -804,7 +810,7 @@ func packetIsGROCandidate(b []byte, gro groDisablementFlags) groCandidateType {
|
||||||
if b[9] == unix.IPPROTO_UDP && gro.canUDPGRO() {
|
if b[9] == unix.IPPROTO_UDP && gro.canUDPGRO() {
|
||||||
return udp4GROCandidate
|
return udp4GROCandidate
|
||||||
}
|
}
|
||||||
} else if b[0]>>4 == 6 {
|
case 6:
|
||||||
if b[6] == unix.IPPROTO_TCP && len(b) >= 60 && gro.canTCPGRO() {
|
if b[6] == unix.IPPROTO_TCP && len(b) >= 60 && gro.canTCPGRO() {
|
||||||
return tcp6GROCandidate
|
return tcp6GROCandidate
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue