address.go 2.5 KB

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