golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/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  
     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  }