...
Source file src/vendor/golang.org/x/net/lif/link.go
1
2
3
4
5
6
7 package lif
8
9 import "unsafe"
10
11
12
13
14
15
16
17
18 type Link struct {
19 Name string
20 Index int
21 Type int
22 Flags int
23 MTU int
24 Addr []byte
25 }
26
27 func (ll *Link) fetch(s uintptr) {
28 var lifr lifreq
29 for i := 0; i < len(ll.Name); i++ {
30 lifr.Name[i] = int8(ll.Name[i])
31 }
32 ioc := int64(sysSIOCGLIFINDEX)
33 if err := ioctl(s, uintptr(ioc), unsafe.Pointer(&lifr)); err == nil {
34 ll.Index = int(nativeEndian.Uint32(lifr.Lifru[:4]))
35 }
36 ioc = int64(sysSIOCGLIFFLAGS)
37 if err := ioctl(s, uintptr(ioc), unsafe.Pointer(&lifr)); err == nil {
38 ll.Flags = int(nativeEndian.Uint64(lifr.Lifru[:8]))
39 }
40 ioc = int64(sysSIOCGLIFMTU)
41 if err := ioctl(s, uintptr(ioc), unsafe.Pointer(&lifr)); err == nil {
42 ll.MTU = int(nativeEndian.Uint32(lifr.Lifru[:4]))
43 }
44 switch ll.Type {
45 case sysIFT_IPV4, sysIFT_IPV6, sysIFT_6TO4:
46 default:
47 ioc = int64(sysSIOCGLIFHWADDR)
48 if err := ioctl(s, uintptr(ioc), unsafe.Pointer(&lifr)); err == nil {
49 ll.Addr, _ = parseLinkAddr(lifr.Lifru[4:])
50 }
51 }
52 }
53
54
55
56
57
58 func Links(af int, name string) ([]Link, error) {
59 eps, err := newEndpoints(af)
60 if len(eps) == 0 {
61 return nil, err
62 }
63 defer func() {
64 for _, ep := range eps {
65 ep.close()
66 }
67 }()
68 return links(eps, name)
69 }
70
71 func links(eps []endpoint, name string) ([]Link, error) {
72 var lls []Link
73 lifn := lifnum{Flags: sysLIFC_NOXMIT | sysLIFC_TEMPORARY | sysLIFC_ALLZONES | sysLIFC_UNDER_IPMP}
74 lifc := lifconf{Flags: sysLIFC_NOXMIT | sysLIFC_TEMPORARY | sysLIFC_ALLZONES | sysLIFC_UNDER_IPMP}
75 for _, ep := range eps {
76 lifn.Family = uint16(ep.af)
77 ioc := int64(sysSIOCGLIFNUM)
78 if err := ioctl(ep.s, uintptr(ioc), unsafe.Pointer(&lifn)); err != nil {
79 continue
80 }
81 if lifn.Count == 0 {
82 continue
83 }
84 b := make([]byte, lifn.Count*sizeofLifreq)
85 lifc.Family = uint16(ep.af)
86 lifc.Len = lifn.Count * sizeofLifreq
87 if len(lifc.Lifcu) == 8 {
88 nativeEndian.PutUint64(lifc.Lifcu[:], uint64(uintptr(unsafe.Pointer(&b[0]))))
89 } else {
90 nativeEndian.PutUint32(lifc.Lifcu[:], uint32(uintptr(unsafe.Pointer(&b[0]))))
91 }
92 ioc = int64(sysSIOCGLIFCONF)
93 if err := ioctl(ep.s, uintptr(ioc), unsafe.Pointer(&lifc)); err != nil {
94 continue
95 }
96 nb := make([]byte, 32)
97 for i := 0; i < int(lifn.Count); i++ {
98 lifr := (*lifreq)(unsafe.Pointer(&b[i*sizeofLifreq]))
99 for i := 0; i < 32; i++ {
100 if lifr.Name[i] == 0 {
101 nb = nb[:i]
102 break
103 }
104 nb[i] = byte(lifr.Name[i])
105 }
106 llname := string(nb)
107 nb = nb[:32]
108 if isDupLink(lls, llname) || name != "" && name != llname {
109 continue
110 }
111 ll := Link{Name: llname, Type: int(lifr.Type)}
112 ll.fetch(ep.s)
113 lls = append(lls, ll)
114 }
115 }
116 return lls, nil
117 }
118
119 func isDupLink(lls []Link, name string) bool {
120 for _, ll := range lls {
121 if ll.Name == name {
122 return true
123 }
124 }
125 return false
126 }
127
View as plain text