sockaddr_windows.go 2.02 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
		}
Steven Allen's avatar
Steven Allen committed
20 21
		var raw windows.RawSockaddrInet4
		raw.Family = windows.AF_INET
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
22 23 24 25 26 27
		p := (*[2]byte)(unsafe.Pointer(&raw.Port))
		p[0] = byte(sa.Port >> 8)
		p[1] = byte(sa.Port)
		for i := 0; i < len(sa.Addr); i++ {
			raw.Addr[i] = sa.Addr[i]
		}
Steven Allen's avatar
Steven Allen committed
28
		return (*windows.RawSockaddrAny)(unsafe.Pointer(&raw)), int32(unsafe.Sizeof(raw)), nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
29

Steven Allen's avatar
Steven Allen committed
30
	case *windows.SockaddrInet6:
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
31
		if sa.Port < 0 || sa.Port > 0xFFFF {
Steven Allen's avatar
Steven Allen committed
32
			return nil, 0, syscall.EINVAL
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
33
		}
Steven Allen's avatar
Steven Allen committed
34 35
		var raw windows.RawSockaddrInet6
		raw.Family = windows.AF_INET6
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
36 37 38 39 40 41 42
		p := (*[2]byte)(unsafe.Pointer(&raw.Port))
		p[0] = byte(sa.Port >> 8)
		p[1] = byte(sa.Port)
		raw.Scope_id = sa.ZoneId
		for i := 0; i < len(sa.Addr); i++ {
			raw.Addr[i] = sa.Addr[i]
		}
Steven Allen's avatar
Steven Allen committed
43
		return (*windows.RawSockaddrAny)(unsafe.Pointer(&raw)), int32(unsafe.Sizeof(raw)), nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
44

Steven Allen's avatar
Steven Allen committed
45 46
	case *windows.SockaddrUnix:
		return nil, 0, syscall.EWINDOWS
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
47
	}
Steven Allen's avatar
Steven Allen committed
48
	return nil, 0, syscall.EAFNOSUPPORT
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
49 50
}

Steven Allen's avatar
Steven Allen committed
51
func anyToSockaddr(rsa *windows.RawSockaddrAny) (windows.Sockaddr, error) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
52
	if rsa == nil {
Steven Allen's avatar
Steven Allen committed
53
		return nil, 0, syscall.EINVAL
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
54 55
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
56
	switch rsa.Addr.Family {
Steven Allen's avatar
Steven Allen committed
57 58
	case windows.AF_UNIX:
		return nil, syscall.EWINDOWS
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
59

Steven Allen's avatar
Steven Allen committed
60 61 62
	case windows.AF_INET:
		pp := (*windows.RawSockaddrInet4)(unsafe.Pointer(rsa))
		sa := new(windows.SockaddrInet4)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
63 64 65 66 67 68
		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
69

Steven Allen's avatar
Steven Allen committed
70 71 72
	case windows.AF_INET6:
		pp := (*windows.RawSockaddrInet6)(unsafe.Pointer(rsa))
		sa := new(windows.SockaddrInet6)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
73 74 75 76 77 78 79 80
		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
81
	return nil, syscall.EAFNOSUPPORT
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
82
}