|  | // Copyright 2014 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows | 
|  | // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows | 
|  |  | 
|  | package icmp | 
|  |  | 
|  | import ( | 
|  | "net" | 
|  | "strconv" | 
|  | "syscall" | 
|  | ) | 
|  |  | 
|  | func sockaddr(family int, address string) (syscall.Sockaddr, error) { | 
|  | switch family { | 
|  | case syscall.AF_INET: | 
|  | a, err := net.ResolveIPAddr("ip4", address) | 
|  | if err != nil { | 
|  | return nil, err | 
|  | } | 
|  | if len(a.IP) == 0 { | 
|  | a.IP = net.IPv4zero | 
|  | } | 
|  | if a.IP = a.IP.To4(); a.IP == nil { | 
|  | return nil, net.InvalidAddrError("non-ipv4 address") | 
|  | } | 
|  | sa := &syscall.SockaddrInet4{} | 
|  | copy(sa.Addr[:], a.IP) | 
|  | return sa, nil | 
|  | case syscall.AF_INET6: | 
|  | a, err := net.ResolveIPAddr("ip6", address) | 
|  | if err != nil { | 
|  | return nil, err | 
|  | } | 
|  | if len(a.IP) == 0 { | 
|  | a.IP = net.IPv6unspecified | 
|  | } | 
|  | if a.IP.Equal(net.IPv4zero) { | 
|  | a.IP = net.IPv6unspecified | 
|  | } | 
|  | if a.IP = a.IP.To16(); a.IP == nil || a.IP.To4() != nil { | 
|  | return nil, net.InvalidAddrError("non-ipv6 address") | 
|  | } | 
|  | sa := &syscall.SockaddrInet6{ZoneId: zoneToUint32(a.Zone)} | 
|  | copy(sa.Addr[:], a.IP) | 
|  | return sa, nil | 
|  | default: | 
|  | return nil, net.InvalidAddrError("unexpected family") | 
|  | } | 
|  | } | 
|  |  | 
|  | func zoneToUint32(zone string) uint32 { | 
|  | if zone == "" { | 
|  | return 0 | 
|  | } | 
|  | if ifi, err := net.InterfaceByName(zone); err == nil { | 
|  | return uint32(ifi.Index) | 
|  | } | 
|  | n, err := strconv.Atoi(zone) | 
|  | if err != nil { | 
|  | return 0 | 
|  | } | 
|  | return uint32(n) | 
|  | } | 
|  |  | 
|  | func last(s string, b byte) int { | 
|  | i := len(s) | 
|  | for i--; i >= 0; i-- { | 
|  | if s[i] == b { | 
|  | break | 
|  | } | 
|  | } | 
|  | return i | 
|  | } |