Source file
src/net/interface_aix.go
1
2
3
4
5 package net
6
7 import (
8 "internal/poll"
9 "internal/syscall/unix"
10 "syscall"
11 "unsafe"
12 )
13
14 type rawSockaddrDatalink struct {
15 Len uint8
16 Family uint8
17 Index uint16
18 Type uint8
19 Nlen uint8
20 Alen uint8
21 Slen uint8
22 Data [120]byte
23 }
24
25 type ifreq struct {
26 Name [16]uint8
27 Ifru [16]byte
28 }
29
30 const _KINFO_RT_IFLIST = (0x1 << 8) | 3 | (1 << 30)
31
32 const _RTAX_NETMASK = 2
33 const _RTAX_IFA = 5
34 const _RTAX_MAX = 8
35
36 func getIfList() ([]byte, error) {
37 needed, err := syscall.Getkerninfo(_KINFO_RT_IFLIST, 0, 0, 0)
38 if err != nil {
39 return nil, err
40 }
41 tab := make([]byte, needed)
42 _, err = syscall.Getkerninfo(_KINFO_RT_IFLIST, uintptr(unsafe.Pointer(&tab[0])), uintptr(unsafe.Pointer(&needed)), 0)
43 if err != nil {
44 return nil, err
45 }
46 return tab[:needed], nil
47 }
48
49
50
51
52 func interfaceTable(ifindex int) ([]Interface, error) {
53 tab, err := getIfList()
54 if err != nil {
55 return nil, err
56 }
57
58 sock, err := sysSocket(syscall.AF_INET, syscall.SOCK_DGRAM, 0)
59 if err != nil {
60 return nil, err
61 }
62 defer poll.CloseFunc(sock)
63
64 var ift []Interface
65 for len(tab) > 0 {
66 ifm := (*syscall.IfMsgHdr)(unsafe.Pointer(&tab[0]))
67 if ifm.Msglen == 0 {
68 break
69 }
70 if ifm.Type == syscall.RTM_IFINFO {
71 if ifindex == 0 || ifindex == int(ifm.Index) {
72 sdl := (*rawSockaddrDatalink)(unsafe.Pointer(&tab[syscall.SizeofIfMsghdr]))
73
74 ifi := &Interface{Index: int(ifm.Index), Flags: linkFlags(ifm.Flags)}
75 ifi.Name = string(sdl.Data[:sdl.Nlen])
76 ifi.HardwareAddr = sdl.Data[sdl.Nlen : sdl.Nlen+sdl.Alen]
77
78
79 ifr := &ifreq{}
80 copy(ifr.Name[:], ifi.Name)
81 err = unix.Ioctl(sock, syscall.SIOCGIFMTU, unsafe.Pointer(ifr))
82 if err != nil {
83 return nil, err
84 }
85 ifi.MTU = int(ifr.Ifru[0])<<24 | int(ifr.Ifru[1])<<16 | int(ifr.Ifru[2])<<8 | int(ifr.Ifru[3])
86
87 ift = append(ift, *ifi)
88 if ifindex == int(ifm.Index) {
89 break
90 }
91 }
92 }
93 tab = tab[ifm.Msglen:]
94 }
95
96 return ift, nil
97 }
98
99 func linkFlags(rawFlags int32) Flags {
100 var f Flags
101 if rawFlags&syscall.IFF_UP != 0 {
102 f |= FlagUp
103 }
104 if rawFlags&syscall.IFF_RUNNING != 0 {
105 f |= FlagRunning
106 }
107 if rawFlags&syscall.IFF_BROADCAST != 0 {
108 f |= FlagBroadcast
109 }
110 if rawFlags&syscall.IFF_LOOPBACK != 0 {
111 f |= FlagLoopback
112 }
113 if rawFlags&syscall.IFF_POINTOPOINT != 0 {
114 f |= FlagPointToPoint
115 }
116 if rawFlags&syscall.IFF_MULTICAST != 0 {
117 f |= FlagMulticast
118 }
119 return f
120 }
121
122
123
124
125 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
126 tab, err := getIfList()
127 if err != nil {
128 return nil, err
129 }
130
131 var ifat []Addr
132 for len(tab) > 0 {
133 ifm := (*syscall.IfMsgHdr)(unsafe.Pointer(&tab[0]))
134 if ifm.Msglen == 0 {
135 break
136 }
137 if ifm.Type == syscall.RTM_NEWADDR {
138 if ifi == nil || ifi.Index == int(ifm.Index) {
139 mask := ifm.Addrs
140 off := uint(syscall.SizeofIfMsghdr)
141
142 var iprsa, nmrsa *syscall.RawSockaddr
143 for i := uint(0); i < _RTAX_MAX; i++ {
144 if mask&(1<<i) == 0 {
145 continue
146 }
147 rsa := (*syscall.RawSockaddr)(unsafe.Pointer(&tab[off]))
148 if i == _RTAX_NETMASK {
149 nmrsa = rsa
150 }
151 if i == _RTAX_IFA {
152 iprsa = rsa
153 }
154 off += (uint(rsa.Len) + 3) &^ 3
155 }
156 if iprsa != nil && nmrsa != nil {
157 var mask IPMask
158 var ip IP
159
160 switch iprsa.Family {
161 case syscall.AF_INET:
162 ipsa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(iprsa))
163 nmsa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(nmrsa))
164 ip = IPv4(ipsa.Addr[0], ipsa.Addr[1], ipsa.Addr[2], ipsa.Addr[3])
165 mask = IPv4Mask(nmsa.Addr[0], nmsa.Addr[1], nmsa.Addr[2], nmsa.Addr[3])
166 case syscall.AF_INET6:
167 ipsa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(iprsa))
168 nmsa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(nmrsa))
169 ip = make(IP, IPv6len)
170 copy(ip, ipsa.Addr[:])
171 mask = make(IPMask, IPv6len)
172 copy(mask, nmsa.Addr[:])
173 }
174 ifa := &IPNet{IP: ip, Mask: mask}
175 ifat = append(ifat, ifa)
176 }
177 }
178 }
179 tab = tab[ifm.Msglen:]
180 }
181
182 return ifat, nil
183 }
184
185
186
187 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
188 return nil, nil
189 }
190
View as plain text