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_BROADCAST != 0 {
105 f |= FlagBroadcast
106 }
107 if rawFlags&syscall.IFF_LOOPBACK != 0 {
108 f |= FlagLoopback
109 }
110 if rawFlags&syscall.IFF_POINTOPOINT != 0 {
111 f |= FlagPointToPoint
112 }
113 if rawFlags&syscall.IFF_MULTICAST != 0 {
114 f |= FlagMulticast
115 }
116 return f
117 }
118
119
120
121
122 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
123 tab, err := getIfList()
124 if err != nil {
125 return nil, err
126 }
127
128 var ifat []Addr
129 for len(tab) > 0 {
130 ifm := (*syscall.IfMsgHdr)(unsafe.Pointer(&tab[0]))
131 if ifm.Msglen == 0 {
132 break
133 }
134 if ifm.Type == syscall.RTM_NEWADDR {
135 if ifi == nil || ifi.Index == int(ifm.Index) {
136 mask := ifm.Addrs
137 off := uint(syscall.SizeofIfMsghdr)
138
139 var iprsa, nmrsa *syscall.RawSockaddr
140 for i := uint(0); i < _RTAX_MAX; i++ {
141 if mask&(1<<i) == 0 {
142 continue
143 }
144 rsa := (*syscall.RawSockaddr)(unsafe.Pointer(&tab[off]))
145 if i == _RTAX_NETMASK {
146 nmrsa = rsa
147 }
148 if i == _RTAX_IFA {
149 iprsa = rsa
150 }
151 off += (uint(rsa.Len) + 3) &^ 3
152 }
153 if iprsa != nil && nmrsa != nil {
154 var mask IPMask
155 var ip IP
156
157 switch iprsa.Family {
158 case syscall.AF_INET:
159 ipsa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(iprsa))
160 nmsa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(nmrsa))
161 ip = IPv4(ipsa.Addr[0], ipsa.Addr[1], ipsa.Addr[2], ipsa.Addr[3])
162 mask = IPv4Mask(nmsa.Addr[0], nmsa.Addr[1], nmsa.Addr[2], nmsa.Addr[3])
163 case syscall.AF_INET6:
164 ipsa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(iprsa))
165 nmsa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(nmrsa))
166 ip = make(IP, IPv6len)
167 copy(ip, ipsa.Addr[:])
168 mask = make(IPMask, IPv6len)
169 copy(mask, nmsa.Addr[:])
170 }
171 ifa := &IPNet{IP: ip, Mask: mask}
172 ifat = append(ifat, ifa)
173 }
174 }
175 }
176 tab = tab[ifm.Msglen:]
177 }
178
179 return ifat, nil
180 }
181
182
183
184 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
185 return nil, nil
186 }
187
View as plain text