Source file
src/net/interface_plan9.go
1
2
3
4
5 package net
6
7 import (
8 "errors"
9 "internal/itoa"
10 "internal/stringslite"
11 "os"
12 )
13
14
15
16
17 func interfaceTable(ifindex int) ([]Interface, error) {
18 if ifindex == 0 {
19 n, err := interfaceCount()
20 if err != nil {
21 return nil, err
22 }
23 ifcs := make([]Interface, n)
24 for i := range ifcs {
25 ifc, err := readInterface(i)
26 if err != nil {
27 return nil, err
28 }
29 ifcs[i] = *ifc
30 }
31 return ifcs, nil
32 }
33
34 ifc, err := readInterface(ifindex - 1)
35 if err != nil {
36 return nil, err
37 }
38 return []Interface{*ifc}, nil
39 }
40
41 func readInterface(i int) (*Interface, error) {
42 ifc := &Interface{
43 Index: i + 1,
44 Name: netdir + "/ipifc/" + itoa.Itoa(i),
45 }
46
47 ifcstat := ifc.Name + "/status"
48 ifcstatf, err := open(ifcstat)
49 if err != nil {
50 return nil, err
51 }
52 defer ifcstatf.close()
53
54 line, ok := ifcstatf.readLine()
55 if !ok {
56 return nil, errors.New("invalid interface status file: " + ifcstat)
57 }
58
59 fields := getFields(line)
60
61
62
63
64
65 if stringslite.HasPrefix(line, "device maxtu ") {
66 fields = append(fields, "")
67 copy(fields[2:], fields[1:])
68 fields[1] = ""
69 }
70
71 if len(fields) < 4 {
72 return nil, errors.New("invalid interface status file: " + ifcstat)
73 }
74
75 device := fields[1]
76 mtustr := fields[3]
77
78 mtu, _, ok := dtoi(mtustr)
79 if !ok {
80 return nil, errors.New("invalid status file of interface: " + ifcstat)
81 }
82 ifc.MTU = mtu
83
84
85 if stringslite.HasPrefix(device, netdir+"/") {
86 deviceaddrf, err := open(device + "/addr")
87 if err != nil {
88 return nil, err
89 }
90 defer deviceaddrf.close()
91
92 line, ok = deviceaddrf.readLine()
93 if !ok {
94 return nil, errors.New("invalid address file for interface: " + device + "/addr")
95 }
96
97 if len(line) > 0 && len(line)%2 == 0 {
98 ifc.HardwareAddr = make([]byte, len(line)/2)
99 var ok bool
100 for i := range ifc.HardwareAddr {
101 j := (i + 1) * 2
102 ifc.HardwareAddr[i], ok = xtoi2(line[i*2:j], 0)
103 if !ok {
104 ifc.HardwareAddr = ifc.HardwareAddr[:i]
105 break
106 }
107 }
108 }
109
110 ifc.Flags = FlagUp | FlagRunning | FlagBroadcast | FlagMulticast
111 } else {
112 ifc.Flags = FlagUp | FlagRunning | FlagMulticast | FlagLoopback
113 }
114
115 return ifc, nil
116 }
117
118 func interfaceCount() (int, error) {
119 d, err := os.Open(netdir + "/ipifc")
120 if err != nil {
121 return -1, err
122 }
123 defer d.Close()
124
125 names, err := d.Readdirnames(0)
126 if err != nil {
127 return -1, err
128 }
129
130
131
132
133 c := 0
134 for _, name := range names {
135 if _, _, ok := dtoi(name); !ok {
136 continue
137 }
138 c++
139 }
140
141 return c, nil
142 }
143
144
145
146
147 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
148 var ifcs []Interface
149 if ifi == nil {
150 var err error
151 ifcs, err = interfaceTable(0)
152 if err != nil {
153 return nil, err
154 }
155 } else {
156 ifcs = []Interface{*ifi}
157 }
158
159 var addrs []Addr
160 for _, ifc := range ifcs {
161 status := ifc.Name + "/status"
162 statusf, err := open(status)
163 if err != nil {
164 return nil, err
165 }
166 defer statusf.close()
167
168
169
170 if _, ok := statusf.readLine(); !ok {
171 return nil, errors.New("cannot read header line for interface: " + status)
172 }
173
174 for line, ok := statusf.readLine(); ok; line, ok = statusf.readLine() {
175 fields := getFields(line)
176 if len(fields) < 1 {
177 continue
178 }
179 addr := fields[0]
180 ip := ParseIP(addr)
181 if ip == nil {
182 return nil, errors.New("cannot parse IP address for interface: " + status)
183 }
184
185
186
187 maskfld := fields[1]
188 maskfld = maskfld[1:]
189 pfxlen, _, ok := dtoi(maskfld)
190 if !ok {
191 return nil, errors.New("cannot parse network mask for interface: " + status)
192 }
193 var mask IPMask
194 if ip.To4() != nil {
195 mask = CIDRMask(pfxlen-8*len(v4InV6Prefix), 8*IPv4len)
196 }
197 if ip.To16() != nil && ip.To4() == nil {
198 mask = CIDRMask(pfxlen, 8*IPv6len)
199 }
200
201 addrs = append(addrs, &IPNet{IP: ip, Mask: mask})
202 }
203 }
204
205 return addrs, nil
206 }
207
208
209
210 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
211 return nil, nil
212 }
213
View as plain text