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