sockaddr_windows.go 2.08 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3
package sockaddr

import (
Steven Allen's avatar
Steven Allen committed
4
	"syscall"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
5
	"unsafe"
Steven Allen's avatar
Steven Allen committed
6 7

	"golang.org/x/sys/windows"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
8 9
)

Steven Allen's avatar
Steven Allen committed
10
func sockaddrToAny(sa windows.Sockaddr) (*windows.RawSockaddrAny, Socklen, error) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
11
	if sa == nil {
Steven Allen's avatar
Steven Allen committed
12
		return nil, 0, syscall.EINVAL
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
13 14
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
15
	switch sa := sa.(type) {
Steven Allen's avatar
Steven Allen committed
16
	case *windows.SockaddrInet4:
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
17
		if sa.Port < 0 || sa.Port > 0xFFFF {
Steven Allen's avatar
Steven Allen committed
18
			return nil, 0, syscall.EINVAL
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
19
		}
20 21 22 23 24

		raw := new(windows.RawSockaddrAny)
		raw.Addr.Family = windows.AF_INET
		raw4 := (*windows.RawSockaddrInet4)(unsafe.Pointer(raw))
		p := (*[2]byte)(unsafe.Pointer(&raw4.Port))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
25 26 27
		p[0] = byte(sa.Port >> 8)
		p[1] = byte(sa.Port)
		for i := 0; i < len(sa.Addr); i++ {
28
			raw4.Addr[i] = sa.Addr[i]
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
29
		}
30
		return raw, Socklen(unsafe.Sizeof(*raw4)), nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
31

Steven Allen's avatar
Steven Allen committed
32
	case *windows.SockaddrInet6:
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
33
		if sa.Port < 0 || sa.Port > 0xFFFF {
Steven Allen's avatar
Steven Allen committed
34
			return nil, 0, syscall.EINVAL
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
35
		}
36 37 38 39 40

		raw := new(windows.RawSockaddrAny)
		raw.Addr.Family = windows.AF_INET6
		raw6 := (*windows.RawSockaddrInet6)(unsafe.Pointer(raw))
		p := (*[2]byte)(unsafe.Pointer(&raw6.Port))
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
41 42
		p[0] = byte(sa.Port >> 8)
		p[1] = byte(sa.Port)
43
		raw6.Scope_id = sa.ZoneId
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
44
		for i := 0; i < len(sa.Addr); i++ {
45
			raw6.Addr[i] = sa.Addr[i]
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
46
		}
47
		return raw, Socklen(unsafe.Sizeof(*raw6)), nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
48

Steven Allen's avatar
Steven Allen committed
49 50
	case *windows.SockaddrUnix:
		return nil, 0, syscall.EWINDOWS
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
51
	}
Steven Allen's avatar
Steven Allen committed
52
	return nil, 0, syscall.EAFNOSUPPORT
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
53 54
}

Steven Allen's avatar
Steven Allen committed
55
func anyToSockaddr(rsa *windows.RawSockaddrAny) (windows.Sockaddr, error) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
56
	if rsa == nil {
Maksim Fedorov's avatar
Maksim Fedorov committed
57
		return nil, syscall.EINVAL
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
58 59
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
60
	switch rsa.Addr.Family {
Steven Allen's avatar
Steven Allen committed
61 62
	case windows.AF_UNIX:
		return nil, syscall.EWINDOWS
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
63

Steven Allen's avatar
Steven Allen committed
64 65 66
	case windows.AF_INET:
		pp := (*windows.RawSockaddrInet4)(unsafe.Pointer(rsa))
		sa := new(windows.SockaddrInet4)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
67 68 69 70 71 72
		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
		sa.Port = int(p[0])<<8 + int(p[1])
		for i := 0; i < len(sa.Addr); i++ {
			sa.Addr[i] = pp.Addr[i]
		}
		return sa, nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
73

Steven Allen's avatar
Steven Allen committed
74 75 76
	case windows.AF_INET6:
		pp := (*windows.RawSockaddrInet6)(unsafe.Pointer(rsa))
		sa := new(windows.SockaddrInet6)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
77 78 79 80 81 82 83 84
		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
		sa.Port = int(p[0])<<8 + int(p[1])
		sa.ZoneId = pp.Scope_id
		for i := 0; i < len(sa.Addr); i++ {
			sa.Addr[i] = pp.Addr[i]
		}
		return sa, nil
	}
Steven Allen's avatar
Steven Allen committed
85
	return nil, syscall.EAFNOSUPPORT
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
86
}