sockaddr_windows.go 2.03 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3 4 5 6 7 8
// sockaddr syscall extensions
package sockaddr

import (
	"syscall"
	"unsafe"
)

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
14 15 16 17 18 19 20 21 22 23 24 25 26 27
	switch sa := sa.(type) {
	case *syscall.SockaddrInet4:
		if sa.Port < 0 || sa.Port > 0xFFFF {
			return nil, 0, syscall.EINVAL
		}
		var raw syscall.RawSockaddrInet4
		raw.Family = syscall.AF_INET
		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]
		}
		return (*syscall.RawSockaddrAny)(unsafe.Pointer(&raw)), int32(unsafe.Sizeof(raw)), nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
28

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42
	case *syscall.SockaddrInet6:
		if sa.Port < 0 || sa.Port > 0xFFFF {
			return nil, 0, syscall.EINVAL
		}
		var raw syscall.RawSockaddrInet6
		raw.Family = syscall.AF_INET6
		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]
		}
		return (*syscall.RawSockaddrAny)(unsafe.Pointer(&raw)), int32(unsafe.Sizeof(raw)), nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
43

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

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

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

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

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