LEFT | RIGHT |
(no file at all) | |
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 // +build darwin freebsd openbsd | 5 // +build darwin freebsd openbsd |
6 | 6 |
7 // Network interface identification for BSD variants | 7 // Network interface identification for BSD variants |
8 | 8 |
9 package net | 9 package net |
10 | 10 |
11 import ( | 11 import ( |
12 "os" | 12 "os" |
13 "syscall" | 13 "syscall" |
14 "unsafe" | 14 "unsafe" |
15 ) | 15 ) |
16 | 16 |
17 // If the ifindex is zero, interfaceTable returns mappings of all | 17 // If the ifindex is zero, interfaceTable returns mappings of all |
18 // network interfaces. Otheriwse it returns a mapping of a specific | 18 // network interfaces. Otheriwse it returns a mapping of a specific |
19 // interface. | 19 // interface. |
20 func interfaceTable(ifindex int) ([]Interface, error) { | 20 func interfaceTable(ifindex int) ([]Interface, error) { |
21 var ( | 21 var ( |
22 tab []byte | 22 tab []byte |
23 » » e int | 23 » » e error |
24 msgs []syscall.RoutingMessage | 24 msgs []syscall.RoutingMessage |
25 ift []Interface | 25 ift []Interface |
26 ) | 26 ) |
27 | 27 |
28 tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex) | 28 tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex) |
29 » if e != 0 { | 29 » if e != nil { |
30 return nil, os.NewSyscallError("route rib", e) | 30 return nil, os.NewSyscallError("route rib", e) |
31 } | 31 } |
32 | 32 |
33 msgs, e = syscall.ParseRoutingMessage(tab) | 33 msgs, e = syscall.ParseRoutingMessage(tab) |
34 » if e != 0 { | 34 » if e != nil { |
35 return nil, os.NewSyscallError("route message", e) | 35 return nil, os.NewSyscallError("route message", e) |
36 } | 36 } |
37 | 37 |
38 for _, m := range msgs { | 38 for _, m := range msgs { |
39 switch v := m.(type) { | 39 switch v := m.(type) { |
40 case *syscall.InterfaceMessage: | 40 case *syscall.InterfaceMessage: |
41 if ifindex == 0 || ifindex == int(v.Header.Index) { | 41 if ifindex == 0 || ifindex == int(v.Header.Index) { |
42 ifi, err := newLink(v) | 42 ifi, err := newLink(v) |
43 if err != nil { | 43 if err != nil { |
44 return nil, err | 44 return nil, err |
45 } | 45 } |
46 ift = append(ift, ifi...) | 46 ift = append(ift, ifi...) |
47 } | 47 } |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 return ift, nil | 51 return ift, nil |
52 } | 52 } |
53 | 53 |
54 func newLink(m *syscall.InterfaceMessage) ([]Interface, error) { | 54 func newLink(m *syscall.InterfaceMessage) ([]Interface, error) { |
55 var ift []Interface | 55 var ift []Interface |
56 | 56 |
57 sas, e := syscall.ParseRoutingSockaddr(m) | 57 sas, e := syscall.ParseRoutingSockaddr(m) |
58 » if e != 0 { | 58 » if e != nil { |
59 return nil, os.NewSyscallError("route sockaddr", e) | 59 return nil, os.NewSyscallError("route sockaddr", e) |
60 } | 60 } |
61 | 61 |
62 for _, s := range sas { | 62 for _, s := range sas { |
63 switch v := s.(type) { | 63 switch v := s.(type) { |
64 case *syscall.SockaddrDatalink: | 64 case *syscall.SockaddrDatalink: |
65 // NOTE: SockaddrDatalink.Data is minimum work area, | 65 // NOTE: SockaddrDatalink.Data is minimum work area, |
66 // can be larger. | 66 // can be larger. |
67 m.Data = m.Data[unsafe.Offsetof(v.Data):] | 67 m.Data = m.Data[unsafe.Offsetof(v.Data):] |
68 ifi := Interface{Index: int(m.Header.Index), Flags: link
Flags(m.Header.Flags)} | 68 ifi := Interface{Index: int(m.Header.Index), Flags: link
Flags(m.Header.Flags)} |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 } | 103 } |
104 return f | 104 return f |
105 } | 105 } |
106 | 106 |
107 // If the ifindex is zero, interfaceAddrTable returns addresses | 107 // If the ifindex is zero, interfaceAddrTable returns addresses |
108 // for all network interfaces. Otherwise it returns addresses | 108 // for all network interfaces. Otherwise it returns addresses |
109 // for a specific interface. | 109 // for a specific interface. |
110 func interfaceAddrTable(ifindex int) ([]Addr, error) { | 110 func interfaceAddrTable(ifindex int) ([]Addr, error) { |
111 var ( | 111 var ( |
112 tab []byte | 112 tab []byte |
113 » » e int | 113 » » e error |
114 msgs []syscall.RoutingMessage | 114 msgs []syscall.RoutingMessage |
115 ifat []Addr | 115 ifat []Addr |
116 ) | 116 ) |
117 | 117 |
118 tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex) | 118 tab, e = syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex) |
119 » if e != 0 { | 119 » if e != nil { |
120 return nil, os.NewSyscallError("route rib", e) | 120 return nil, os.NewSyscallError("route rib", e) |
121 } | 121 } |
122 | 122 |
123 msgs, e = syscall.ParseRoutingMessage(tab) | 123 msgs, e = syscall.ParseRoutingMessage(tab) |
124 » if e != 0 { | 124 » if e != nil { |
125 return nil, os.NewSyscallError("route message", e) | 125 return nil, os.NewSyscallError("route message", e) |
126 } | 126 } |
127 | 127 |
128 for _, m := range msgs { | 128 for _, m := range msgs { |
129 switch v := m.(type) { | 129 switch v := m.(type) { |
130 case *syscall.InterfaceAddrMessage: | 130 case *syscall.InterfaceAddrMessage: |
131 if ifindex == 0 || ifindex == int(v.Header.Index) { | 131 if ifindex == 0 || ifindex == int(v.Header.Index) { |
132 ifa, err := newAddr(v) | 132 ifa, err := newAddr(v) |
133 if err != nil { | 133 if err != nil { |
134 return nil, err | 134 return nil, err |
135 } | 135 } |
136 ifat = append(ifat, ifa...) | 136 ifat = append(ifat, ifa...) |
137 } | 137 } |
138 } | 138 } |
139 } | 139 } |
140 | 140 |
141 return ifat, nil | 141 return ifat, nil |
142 } | 142 } |
143 | 143 |
144 func newAddr(m *syscall.InterfaceAddrMessage) ([]Addr, error) { | 144 func newAddr(m *syscall.InterfaceAddrMessage) ([]Addr, error) { |
145 var ifat []Addr | 145 var ifat []Addr |
146 | 146 |
147 sas, e := syscall.ParseRoutingSockaddr(m) | 147 sas, e := syscall.ParseRoutingSockaddr(m) |
148 » if e != 0 { | 148 » if e != nil { |
149 return nil, os.NewSyscallError("route sockaddr", e) | 149 return nil, os.NewSyscallError("route sockaddr", e) |
150 } | 150 } |
151 | 151 |
152 for _, s := range sas { | 152 for _, s := range sas { |
153 switch v := s.(type) { | 153 switch v := s.(type) { |
154 case *syscall.SockaddrInet4: | 154 case *syscall.SockaddrInet4: |
155 ifa := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2],
v.Addr[3])} | 155 ifa := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2],
v.Addr[3])} |
156 ifat = append(ifat, ifa.toAddr()) | 156 ifat = append(ifat, ifa.toAddr()) |
157 case *syscall.SockaddrInet6: | 157 case *syscall.SockaddrInet6: |
158 ifa := &IPAddr{IP: make(IP, IPv6len)} | 158 ifa := &IPAddr{IP: make(IP, IPv6len)} |
159 copy(ifa.IP, v.Addr[:]) | 159 copy(ifa.IP, v.Addr[:]) |
160 // NOTE: KAME based IPv6 protcol stack usually embeds | 160 // NOTE: KAME based IPv6 protcol stack usually embeds |
161 // the interface index in the interface-local or link- | 161 // the interface index in the interface-local or link- |
162 // local address as the kernel-internal form. | 162 // local address as the kernel-internal form. |
163 if ifa.IP.IsLinkLocalUnicast() { | 163 if ifa.IP.IsLinkLocalUnicast() { |
164 // remove embedded scope zone ID | 164 // remove embedded scope zone ID |
165 ifa.IP[2], ifa.IP[3] = 0, 0 | 165 ifa.IP[2], ifa.IP[3] = 0, 0 |
166 } | 166 } |
167 ifat = append(ifat, ifa.toAddr()) | 167 ifat = append(ifat, ifa.toAddr()) |
168 } | 168 } |
169 } | 169 } |
170 | 170 |
171 return ifat, nil | 171 return ifat, nil |
172 } | 172 } |
LEFT | RIGHT |