github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/icmp/helper_posix.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows 6 7 package icmp 8 9 import ( 10 "net" 11 "strconv" 12 "syscall" 13 ) 14 15 func sockaddr(family int, address string) (syscall.Sockaddr, error) { 16 switch family { 17 case syscall.AF_INET: 18 a, err := net.ResolveIPAddr("ip4", address) 19 if err != nil { 20 return nil, err 21 } 22 if len(a.IP) == 0 { 23 a.IP = net.IPv4zero 24 } 25 if a.IP = a.IP.To4(); a.IP == nil { 26 return nil, net.InvalidAddrError("non-ipv4 address") 27 } 28 sa := &syscall.SockaddrInet4{} 29 copy(sa.Addr[:], a.IP) 30 return sa, nil 31 case syscall.AF_INET6: 32 a, err := net.ResolveIPAddr("ip6", address) 33 if err != nil { 34 return nil, err 35 } 36 if len(a.IP) == 0 { 37 a.IP = net.IPv6unspecified 38 } 39 if a.IP.Equal(net.IPv4zero) { 40 a.IP = net.IPv6unspecified 41 } 42 if a.IP = a.IP.To16(); a.IP == nil || a.IP.To4() != nil { 43 return nil, net.InvalidAddrError("non-ipv6 address") 44 } 45 sa := &syscall.SockaddrInet6{ZoneId: zoneToUint32(a.Zone)} 46 copy(sa.Addr[:], a.IP) 47 return sa, nil 48 default: 49 return nil, net.InvalidAddrError("unexpected family") 50 } 51 } 52 53 func zoneToUint32(zone string) uint32 { 54 if zone == "" { 55 return 0 56 } 57 if ifi, err := net.InterfaceByName(zone); err == nil { 58 return uint32(ifi.Index) 59 } 60 n, err := strconv.Atoi(zone) 61 if err != nil { 62 return 0 63 } 64 return uint32(n) 65 } 66 67 func last(s string, b byte) int { 68 i := len(s) 69 for i--; i >= 0; i-- { 70 if s[i] == b { 71 break 72 } 73 } 74 return i 75 }