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  }