//Copy from golang source func anyToSockaddr(rsa *syscall.RawSockaddrAny) (syscall.Sockaddr, error) { switch rsa.Addr.Family { 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 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 }
func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) { switch family { case syscall.AF_INET: if len(ip) == 0 { ip = IPv4zero } if ip = ip.To4(); ip == nil { return nil, InvalidAddrError("non-IPv4 address") } sa := new(syscall.SockaddrInet4) for i := 0; i < IPv4len; i++ { sa.Addr[i] = ip[i] } sa.Port = port return sa, nil case syscall.AF_INET6: if len(ip) == 0 { ip = IPv6zero } // IPv4 callers use 0.0.0.0 to mean "announce on any available address". // In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0", // which it refuses to do. Rewrite to the IPv6 unspecified address. if ip.Equal(IPv4zero) { ip = IPv6zero } if ip = ip.To16(); ip == nil { return nil, InvalidAddrError("non-IPv6 address") } sa := new(syscall.SockaddrInet6) for i := 0; i < IPv6len; i++ { sa.Addr[i] = ip[i] } sa.Port = port sa.ZoneId = uint32(zoneToInt(zone)) return sa, nil } return nil, InvalidAddrError("unexpected socket family") }