Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1139)

Side by Side Diff: src/pkg/net/interface_linux.go

Issue 7300081: code review 7300081: net: set up IPv6 scoped addressing zone for network fac... (Closed)
Patch Set: diff -r 3836bcbafa69 https://code.google.com/p/go Created 11 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/net/interface_freebsd.go ('k') | src/pkg/net/interface_netbsd.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Network interface identification for Linux 5 // Network interface identification for Linux
6 6
7 package net 7 package net
8 8
9 import ( 9 import (
10 "os" 10 "os"
11 "syscall" 11 "syscall"
12 "unsafe" 12 "unsafe"
13 ) 13 )
14 14
15 // If the ifindex is zero, interfaceTable returns mappings of all 15 // If the ifindex is zero, interfaceTable returns mappings of all
16 // network interfaces. Otherwise it returns a mapping of a specific 16 // network interfaces. Otherwise it returns a mapping of a specific
17 // interface. 17 // interface.
18 func interfaceTable(ifindex int) ([]Interface, error) { 18 func interfaceTable(ifindex int) ([]Interface, error) {
19 tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC) 19 tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
20 if err != nil { 20 if err != nil {
21 return nil, os.NewSyscallError("netlink rib", err) 21 return nil, os.NewSyscallError("netlink rib", err)
22 } 22 }
23
24 msgs, err := syscall.ParseNetlinkMessage(tab) 23 msgs, err := syscall.ParseNetlinkMessage(tab)
25 if err != nil { 24 if err != nil {
26 return nil, os.NewSyscallError("netlink message", err) 25 return nil, os.NewSyscallError("netlink message", err)
27 } 26 }
28
29 var ift []Interface 27 var ift []Interface
28 done:
30 for _, m := range msgs { 29 for _, m := range msgs {
31 switch m.Header.Type { 30 switch m.Header.Type {
32 case syscall.NLMSG_DONE: 31 case syscall.NLMSG_DONE:
33 » » » goto done 32 » » » break done
rsc 2013/02/19 15:20:31 done is weird label for a for loop. If you want to
mikio 2013/02/19 23:18:14 Done.
34 case syscall.RTM_NEWLINK: 33 case syscall.RTM_NEWLINK:
35 ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0])) 34 ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0]))
36 if ifindex == 0 || ifindex == int(ifim.Index) { 35 if ifindex == 0 || ifindex == int(ifim.Index) {
37 attrs, err := syscall.ParseNetlinkRouteAttr(&m) 36 attrs, err := syscall.ParseNetlinkRouteAttr(&m)
38 if err != nil { 37 if err != nil {
39 return nil, os.NewSyscallError("netlink routeattr", err) 38 return nil, os.NewSyscallError("netlink routeattr", err)
40 } 39 }
41 ifi := newLink(ifim, attrs) 40 ifi := newLink(ifim, attrs)
42 ift = append(ift, ifi) 41 ift = append(ift, ifi)
43 } 42 }
44 } 43 }
45 } 44 }
46 done:
47 return ift, nil 45 return ift, nil
48 } 46 }
49 47
50 func newLink(ifim *syscall.IfInfomsg, attrs []syscall.NetlinkRouteAttr) Interfac e { 48 func newLink(ifim *syscall.IfInfomsg, attrs []syscall.NetlinkRouteAttr) Interfac e {
51 ifi := Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)} 49 ifi := Interface{Index: int(ifim.Index), Flags: linkFlags(ifim.Flags)}
52 for _, a := range attrs { 50 for _, a := range attrs {
53 switch a.Attr.Type { 51 switch a.Attr.Type {
54 case syscall.IFLA_ADDRESS: 52 case syscall.IFLA_ADDRESS:
55 var nonzero bool 53 var nonzero bool
56 for _, b := range a.Value { 54 for _, b := range a.Value {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 } 89 }
92 90
93 // If the ifindex is zero, interfaceAddrTable returns addresses 91 // If the ifindex is zero, interfaceAddrTable returns addresses
94 // for all network interfaces. Otherwise it returns addresses 92 // for all network interfaces. Otherwise it returns addresses
95 // for a specific interface. 93 // for a specific interface.
96 func interfaceAddrTable(ifindex int) ([]Addr, error) { 94 func interfaceAddrTable(ifindex int) ([]Addr, error) {
97 tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC) 95 tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
98 if err != nil { 96 if err != nil {
99 return nil, os.NewSyscallError("netlink rib", err) 97 return nil, os.NewSyscallError("netlink rib", err)
100 } 98 }
101
102 msgs, err := syscall.ParseNetlinkMessage(tab) 99 msgs, err := syscall.ParseNetlinkMessage(tab)
103 if err != nil { 100 if err != nil {
104 return nil, os.NewSyscallError("netlink message", err) 101 return nil, os.NewSyscallError("netlink message", err)
105 } 102 }
106
107 ifat, err := addrTable(msgs, ifindex) 103 ifat, err := addrTable(msgs, ifindex)
108 if err != nil { 104 if err != nil {
109 return nil, err 105 return nil, err
110 } 106 }
111 return ifat, nil 107 return ifat, nil
112 } 108 }
113 109
114 func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) { 110 func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
115 var ifat []Addr 111 var ifat []Addr
112 done:
116 for _, m := range msgs { 113 for _, m := range msgs {
117 switch m.Header.Type { 114 switch m.Header.Type {
118 case syscall.NLMSG_DONE: 115 case syscall.NLMSG_DONE:
119 » » » goto done 116 » » » break done
rsc 2013/02/19 15:20:31 Same.
mikio 2013/02/19 23:18:14 Done.
120 case syscall.RTM_NEWADDR: 117 case syscall.RTM_NEWADDR:
121 ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0])) 118 ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
122 if ifindex == 0 || ifindex == int(ifam.Index) { 119 if ifindex == 0 || ifindex == int(ifam.Index) {
123 attrs, err := syscall.ParseNetlinkRouteAttr(&m) 120 attrs, err := syscall.ParseNetlinkRouteAttr(&m)
124 if err != nil { 121 if err != nil {
125 return nil, os.NewSyscallError("netlink routeattr", err) 122 return nil, os.NewSyscallError("netlink routeattr", err)
126 } 123 }
127 » » » » ifat = append(ifat, newAddr(attrs, int(ifam.Fami ly), int(ifam.Prefixlen))) 124 » » » » ifat = append(ifat, newAddr(ifam, attrs))
128 } 125 }
129 } 126 }
130 } 127 }
131 done:
132 return ifat, nil 128 return ifat, nil
133 } 129 }
134 130
135 func newAddr(attrs []syscall.NetlinkRouteAttr, family, pfxlen int) Addr { 131 func newAddr(ifam *syscall.IfAddrmsg, attrs []syscall.NetlinkRouteAttr) Addr {
136 ifa := &IPNet{} 132 ifa := &IPNet{}
137 for _, a := range attrs { 133 for _, a := range attrs {
138 switch a.Attr.Type { 134 switch a.Attr.Type {
139 case syscall.IFA_ADDRESS: 135 case syscall.IFA_ADDRESS:
140 » » » switch family { 136 » » » switch ifam.Family {
141 case syscall.AF_INET: 137 case syscall.AF_INET:
142 ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2] , a.Value[3]) 138 ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2] , a.Value[3])
143 » » » » ifa.Mask = CIDRMask(pfxlen, 8*IPv4len) 139 » » » » ifa.Mask = CIDRMask(int(ifam.Prefixlen), 8*IPv4l en)
144 case syscall.AF_INET6: 140 case syscall.AF_INET6:
145 ifa.IP = make(IP, IPv6len) 141 ifa.IP = make(IP, IPv6len)
146 copy(ifa.IP, a.Value[:]) 142 copy(ifa.IP, a.Value[:])
147 » » » » ifa.Mask = CIDRMask(pfxlen, 8*IPv6len) 143 » » » » ifa.Mask = CIDRMask(int(ifam.Prefixlen), 8*IPv6l en)
144 » » » » if ifam.Scope == syscall.RT_SCOPE_HOST || ifam.S cope == syscall.RT_SCOPE_LINK {
145 » » » » » ifa.Zone = zoneToString(int(ifam.Index))
146 » » » » }
148 } 147 }
149 } 148 }
150 } 149 }
151 return ifa 150 return ifa
152 } 151 }
153 152
154 // If the ifindex is zero, interfaceMulticastAddrTable returns 153 // If the ifindex is zero, interfaceMulticastAddrTable returns
155 // addresses for all network interfaces. Otherwise it returns 154 // addresses for all network interfaces. Otherwise it returns
156 // addresses for a specific interface. 155 // addresses for a specific interface.
157 func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) { 156 func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
(...skipping 11 matching lines...) Expand all
169 ifmat6 := parseProcNetIGMP6("/proc/net/igmp6", ifi) 168 ifmat6 := parseProcNetIGMP6("/proc/net/igmp6", ifi)
170 return append(ifmat4, ifmat6...), nil 169 return append(ifmat4, ifmat6...), nil
171 } 170 }
172 171
173 func parseProcNetIGMP(path string, ifi *Interface) []Addr { 172 func parseProcNetIGMP(path string, ifi *Interface) []Addr {
174 fd, err := open(path) 173 fd, err := open(path)
175 if err != nil { 174 if err != nil {
176 return nil 175 return nil
177 } 176 }
178 defer fd.close() 177 defer fd.close()
179
180 var ( 178 var (
181 ifmat []Addr 179 ifmat []Addr
182 name string 180 name string
183 ) 181 )
184 fd.readLine() // skip first line 182 fd.readLine() // skip first line
185 b := make([]byte, IPv4len) 183 b := make([]byte, IPv4len)
186 for l, ok := fd.readLine(); ok; l, ok = fd.readLine() { 184 for l, ok := fd.readLine(); ok; l, ok = fd.readLine() {
187 f := splitAtBytes(l, " :\r\t\n") 185 f := splitAtBytes(l, " :\r\t\n")
188 if len(f) < 4 { 186 if len(f) < 4 {
189 continue 187 continue
(...skipping 17 matching lines...) Expand all
207 } 205 }
208 return ifmat 206 return ifmat
209 } 207 }
210 208
211 func parseProcNetIGMP6(path string, ifi *Interface) []Addr { 209 func parseProcNetIGMP6(path string, ifi *Interface) []Addr {
212 fd, err := open(path) 210 fd, err := open(path)
213 if err != nil { 211 if err != nil {
214 return nil 212 return nil
215 } 213 }
216 defer fd.close() 214 defer fd.close()
217
218 var ifmat []Addr 215 var ifmat []Addr
219 b := make([]byte, IPv6len) 216 b := make([]byte, IPv6len)
220 for l, ok := fd.readLine(); ok; l, ok = fd.readLine() { 217 for l, ok := fd.readLine(); ok; l, ok = fd.readLine() {
221 f := splitAtBytes(l, " \r\t\n") 218 f := splitAtBytes(l, " \r\t\n")
222 if len(f) < 6 { 219 if len(f) < 6 {
223 continue 220 continue
224 } 221 }
225 if ifi == nil || f[1] == ifi.Name { 222 if ifi == nil || f[1] == ifi.Name {
226 for i := 0; i+1 < len(f[2]); i += 2 { 223 for i := 0; i+1 < len(f[2]); i += 2 {
227 b[i/2], _ = xtoi2(f[2][i:i+2], 0) 224 b[i/2], _ = xtoi2(f[2][i:i+2], 0)
228 } 225 }
229 ifma := IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5] , b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}} 226 ifma := IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5] , b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}}
227 if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLink LocalMulticast() {
228 ifma.Zone = ifi.Name
229 }
230 ifmat = append(ifmat, ifma.toAddr()) 230 ifmat = append(ifmat, ifma.toAddr())
231 } 231 }
232 } 232 }
233 return ifmat 233 return ifmat
234 } 234 }
OLDNEW
« no previous file with comments | « src/pkg/net/interface_freebsd.go ('k') | src/pkg/net/interface_netbsd.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b