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 if len(fields) < 4 {
61 return nil, errors.New("invalid interface status file: " + ifcstat)
62 }
63
64 device := fields[1]
65 mtustr := fields[3]
66
67 mtu, _, ok := dtoi(mtustr)
68 if !ok {
69 return nil, errors.New("invalid status file of interface: " + ifcstat)
70 }
71 ifc.MTU = mtu
72
73
74 if stringslite.HasPrefix(device, netdir+"/") {
75 deviceaddrf, err := open(device + "/addr")
76 if err != nil {
77 return nil, err
78 }
79 defer deviceaddrf.close()
80
81 line, ok = deviceaddrf.readLine()
82 if !ok {
83 return nil, errors.New("invalid address file for interface: " + device + "/addr")
84 }
85
86 if len(line) > 0 && len(line)%2 == 0 {
87 ifc.HardwareAddr = make([]byte, len(line)/2)
88 var ok bool
89 for i := range ifc.HardwareAddr {
90 j := (i + 1) * 2
91 ifc.HardwareAddr[i], ok = xtoi2(line[i*2:j], 0)
92 if !ok {
93 ifc.HardwareAddr = ifc.HardwareAddr[:i]
94 break
95 }
96 }
97 }
98
99 ifc.Flags = FlagUp | FlagRunning | FlagBroadcast | FlagMulticast
100 } else {
101 ifc.Flags = FlagUp | FlagRunning | FlagMulticast | FlagLoopback
102 }
103
104 return ifc, nil
105 }
106
107 func interfaceCount() (int, error) {
108 d, err := os.Open(netdir + "/ipifc")
109 if err != nil {
110 return -1, err
111 }
112 defer d.Close()
113
114 names, err := d.Readdirnames(0)
115 if err != nil {
116 return -1, err
117 }
118
119
120
121
122 c := 0
123 for _, name := range names {
124 if _, _, ok := dtoi(name); !ok {
125 continue
126 }
127 c++
128 }
129
130 return c, nil
131 }
132
133
134
135
136 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
137 var ifcs []Interface
138 if ifi == nil {
139 var err error
140 ifcs, err = interfaceTable(0)
141 if err != nil {
142 return nil, err
143 }
144 } else {
145 ifcs = []Interface{*ifi}
146 }
147
148 var addrs []Addr
149 for _, ifc := range ifcs {
150 status := ifc.Name + "/status"
151 statusf, err := open(status)
152 if err != nil {
153 return nil, err
154 }
155 defer statusf.close()
156
157
158
159 if _, ok := statusf.readLine(); !ok {
160 return nil, errors.New("cannot read header line for interface: " + status)
161 }
162
163 for line, ok := statusf.readLine(); ok; line, ok = statusf.readLine() {
164 fields := getFields(line)
165 if len(fields) < 1 {
166 return nil, errors.New("cannot parse IP address for interface: " + status)
167 }
168 addr := fields[0]
169 ip := ParseIP(addr)
170 if ip == nil {
171 return nil, errors.New("cannot parse IP address for interface: " + status)
172 }
173
174
175
176 maskfld := fields[1]
177 maskfld = maskfld[1:]
178 pfxlen, _, ok := dtoi(maskfld)
179 if !ok {
180 return nil, errors.New("cannot parse network mask for interface: " + status)
181 }
182 var mask IPMask
183 if ip.To4() != nil {
184 mask = CIDRMask(pfxlen-8*len(v4InV6Prefix), 8*IPv4len)
185 }
186 if ip.To16() != nil && ip.To4() == nil {
187 mask = CIDRMask(pfxlen, 8*IPv6len)
188 }
189
190 addrs = append(addrs, &IPNet{IP: ip, Mask: mask})
191 }
192 }
193
194 return addrs, nil
195 }
196
197
198
199 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
200 return nil, nil
201 }
202
View as plain text