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