You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.4 KiB

  1. // Copyright 2016 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 solaris
  5. package lif
  6. import (
  7. "errors"
  8. "unsafe"
  9. )
  10. // An Addr represents an address associated with packet routing.
  11. type Addr interface {
  12. // Family returns an address family.
  13. Family() int
  14. }
  15. // An Inet4Addr represents an internet address for IPv4.
  16. type Inet4Addr struct {
  17. IP [4]byte // IP address
  18. PrefixLen int // address prefix length
  19. }
  20. // Family implements the Family method of Addr interface.
  21. func (a *Inet4Addr) Family() int { return sysAF_INET }
  22. // An Inet6Addr represents an internet address for IPv6.
  23. type Inet6Addr struct {
  24. IP [16]byte // IP address
  25. PrefixLen int // address prefix length
  26. ZoneID int // zone identifier
  27. }
  28. // Family implements the Family method of Addr interface.
  29. func (a *Inet6Addr) Family() int { return sysAF_INET6 }
  30. // Addrs returns a list of interface addresses.
  31. //
  32. // The provided af must be an address family and name must be a data
  33. // link name. The zero value of af or name means a wildcard.
  34. func Addrs(af int, name string) ([]Addr, error) {
  35. eps, err := newEndpoints(af)
  36. if len(eps) == 0 {
  37. return nil, err
  38. }
  39. defer func() {
  40. for _, ep := range eps {
  41. ep.close()
  42. }
  43. }()
  44. lls, err := links(eps, name)
  45. if len(lls) == 0 {
  46. return nil, err
  47. }
  48. var as []Addr
  49. for _, ll := range lls {
  50. var lifr lifreq
  51. for i := 0; i < len(ll.Name); i++ {
  52. lifr.Name[i] = int8(ll.Name[i])
  53. }
  54. for _, ep := range eps {
  55. ioc := int64(sysSIOCGLIFADDR)
  56. err := ioctl(ep.s, uintptr(ioc), unsafe.Pointer(&lifr))
  57. if err != nil {
  58. continue
  59. }
  60. sa := (*sockaddrStorage)(unsafe.Pointer(&lifr.Lifru[0]))
  61. l := int(nativeEndian.Uint32(lifr.Lifru1[:4]))
  62. if l == 0 {
  63. continue
  64. }
  65. switch sa.Family {
  66. case sysAF_INET:
  67. a := &Inet4Addr{PrefixLen: l}
  68. copy(a.IP[:], lifr.Lifru[4:8])
  69. as = append(as, a)
  70. case sysAF_INET6:
  71. a := &Inet6Addr{PrefixLen: l, ZoneID: int(nativeEndian.Uint32(lifr.Lifru[24:28]))}
  72. copy(a.IP[:], lifr.Lifru[8:24])
  73. as = append(as, a)
  74. }
  75. }
  76. }
  77. return as, nil
  78. }
  79. func parseLinkAddr(b []byte) ([]byte, error) {
  80. nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
  81. l := 4 + nlen + alen + slen
  82. if len(b) < l {
  83. return nil, errors.New("invalid address")
  84. }
  85. b = b[4:]
  86. var addr []byte
  87. if nlen > 0 {
  88. b = b[nlen:]
  89. }
  90. if alen > 0 {
  91. addr = make([]byte, alen)
  92. copy(addr, b[:alen])
  93. }
  94. return addr, nil
  95. }