...
Source file src/vendor/golang.org/x/net/lif/address.go
1
2
3
4
5
6
7 package lif
8
9 import (
10 "errors"
11 "unsafe"
12 )
13
14
15 type Addr interface {
16
17 Family() int
18 }
19
20
21 type Inet4Addr struct {
22 IP [4]byte
23 PrefixLen int
24 }
25
26
27 func (a *Inet4Addr) Family() int { return sysAF_INET }
28
29
30 type Inet6Addr struct {
31 IP [16]byte
32 PrefixLen int
33 ZoneID int
34 }
35
36
37 func (a *Inet6Addr) Family() int { return sysAF_INET6 }
38
39
40
41
42
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 }
106
View as plain text