helper_unix.go 1.8 KB

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