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

import (
	"syscall"
	"unsafe"
)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
8 9 10
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
11 12
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
13 14 15 16 17 18 19 20 21 22 23 24 25 26
	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
27

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41
	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
42

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
49 50 51
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
52 53
	}

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
58 59 60 61 62 63 64 65 66
	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
67

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
68 69 70 71 72 73 74 75 76 77 78 79
	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
80
}