OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / icmp / helper_posix.go
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 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 }