sockaddr_windows.go 1.77 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
// sockaddr syscall extensions
package sockaddr

import (
	"syscall"
	"unsafe"
)

/*
type SockaddrInet4 struct {
	Port int
	Addr [4]byte
	raw  RawSockaddrInet4
}
*/

func (r *RawSockaddr) Update(s *syscall.Sockaddr) error {

	si4, ok := (*s).(*syscall.SockaddrInet4)
	if ok {
		return r.UpdateInet4(si4)
	}

	si6, ok := (*s).(*syscall.SockaddrInet6)
	if ok {
		return r.UpdateInet6(si6)
	}

	su, ok := (*s).(*syscall.SockaddrUnix)
	if ok {
		return r.UpdateUnix(su)
	}

	sdl, ok := (*s).(*syscall.SockaddrDatalink)
	if ok {
		return r.UpdateDatalink(sdl)
	}

	return fmt.Errorf("unknown sockaddr type")
}

func (r *RawSockaddr) UpdateInet4(sa *syscall.SockaddrInet4) error {
	if sa.Port < 0 || sa.Port > 0xFFFF {
		return syscall.EINVAL
	}
	raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&r.Raw))
	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]
	}
	raw.Len = uint(unsafe.Sizeof(sa.raw))
	return nil
}

/*
type SockaddrInet6 struct {
	Port   int
	ZoneId uint32
	Addr   [16]byte
	raw    RawSockaddrInet6
}
*/

func (r *RawSockaddr) UpdateInet6(sa *syscall.SockaddrInet6) error {
	if sa.Port < 0 || sa.Port > 0xFFFF {
		return 0, 0, syscall.EINVAL
	}
	raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&r.Raw))
	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]
	}
	raw.Len = uint(unsafe.Sizeof(sa.raw))
	return nil
}

/*
type SockaddrUnix struct {
	Name string
}
*/
func (r *RawSockaddr) UpdateUnix(sa *syscall.SockaddrUnix) error {
	// TODO(brainman): implement SockaddrUnix.sockaddr()
	return syscall.EWINDOWS
}