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