github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/net/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 //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows 6 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows 7 8 package icmp 9 10 import ( 11 "net" 12 "strconv" 13 "syscall" 14 ) 15 16 func sockaddr(family int, address string) (syscall.Sockaddr, error) { 17 switch family { 18 case syscall.AF_INET: 19 a, err := net.ResolveIPAddr("ip4", address) 20 if err != nil { 21 return nil, err 22 } 23 if len(a.IP) == 0 { 24 a.IP = net.IPv4zero 25 } 26 if a.IP = a.IP.To4(); a.IP == nil { 27 return nil, net.InvalidAddrError("non-ipv4 address") 28 } 29 sa := &syscall.SockaddrInet4{} 30 copy(sa.Addr[:], a.IP) 31 return sa, nil 32 case syscall.AF_INET6: 33 a, err := net.ResolveIPAddr("ip6", address) 34 if err != nil { 35 return nil, err 36 } 37 if len(a.IP) == 0 { 38 a.IP = net.IPv6unspecified 39 } 40 if a.IP.Equal(net.IPv4zero) { 41 a.IP = net.IPv6unspecified 42 } 43 if a.IP = a.IP.To16(); a.IP == nil || a.IP.To4() != nil { 44 return nil, net.InvalidAddrError("non-ipv6 address") 45 } 46 sa := &syscall.SockaddrInet6{ZoneId: zoneToUint32(a.Zone)} 47 copy(sa.Addr[:], a.IP) 48 return sa, nil 49 default: 50 return nil, net.InvalidAddrError("unexpected family") 51 } 52 } 53 54 func zoneToUint32(zone string) uint32 { 55 if zone == "" { 56 return 0 57 } 58 if ifi, err := net.InterfaceByName(zone); err == nil { 59 return uint32(ifi.Index) 60 } 61 n, err := strconv.Atoi(zone) 62 if err != nil { 63 return 0 64 } 65 return uint32(n) 66 } 67 68 func last(s string, b byte) int { 69 i := len(s) 70 for i--; i >= 0; i-- { 71 if s[i] == b { 72 break 73 } 74 } 75 return i 76 }