20 return int(ret), nil |
19 return int(ret), nil |
21 } |
20 } |
22 |
21 |
23 func IoctlGetUint32(fd int, req uint) (uint32, error) { |
22 func IoctlGetUint32(fd int, req uint) (uint32, error) { |
24 var value uint32 |
23 var value uint32 |
25 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
24 err := ioctlPtr(fd, req, unsafe.Pointer(&value)) |
26 return value, err |
25 return value, err |
27 } |
26 } |
28 |
27 |
29 func IoctlGetRTCTime(fd int) (*RTCTime, error) { |
28 func IoctlGetRTCTime(fd int) (*RTCTime, error) { |
30 var value RTCTime |
29 var value RTCTime |
31 err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) |
30 err := ioctlPtr(fd, RTC_RD_TIME, unsafe.Pointer(&value)) |
32 return &value, err |
31 return &value, err |
33 } |
32 } |
34 |
33 |
35 func IoctlSetRTCTime(fd int, value *RTCTime) error { |
34 func IoctlSetRTCTime(fd int, value *RTCTime) error { |
36 err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) |
35 return ioctlPtr(fd, RTC_SET_TIME, unsafe.Pointer(value)) |
37 runtime.KeepAlive(value) |
|
38 return err |
|
39 } |
36 } |
40 |
37 |
41 func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) { |
38 func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) { |
42 var value RTCWkAlrm |
39 var value RTCWkAlrm |
43 err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value))) |
40 err := ioctlPtr(fd, RTC_WKALM_RD, unsafe.Pointer(&value)) |
44 return &value, err |
41 return &value, err |
45 } |
42 } |
46 |
43 |
47 func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error { |
44 func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error { |
48 err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value))) |
45 return ioctlPtr(fd, RTC_WKALM_SET, unsafe.Pointer(value)) |
49 runtime.KeepAlive(value) |
|
50 return err |
|
51 } |
|
52 |
|
53 type ifreqEthtool struct { |
|
54 name [IFNAMSIZ]byte |
|
55 data unsafe.Pointer |
|
56 } |
46 } |
57 |
47 |
58 // IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network |
48 // IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network |
59 // device specified by ifname. |
49 // device specified by ifname. |
60 func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) { |
50 func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) { |
61 // Leave room for terminating NULL byte. |
51 ifr, err := NewIfreq(ifname) |
62 if len(ifname) >= IFNAMSIZ { |
52 if err != nil { |
63 return nil, EINVAL |
53 return nil, err |
64 } |
54 } |
65 |
55 |
66 value := EthtoolDrvinfo{ |
56 value := EthtoolDrvinfo{Cmd: ETHTOOL_GDRVINFO} |
67 Cmd: ETHTOOL_GDRVINFO, |
57 ifrd := ifr.withData(unsafe.Pointer(&value)) |
68 } |
58 |
69 ifreq := ifreqEthtool{ |
59 err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd) |
70 data: unsafe.Pointer(&value), |
|
71 } |
|
72 copy(ifreq.name[:], ifname) |
|
73 err := ioctl(fd, SIOCETHTOOL, uintptr(unsafe.Pointer(&ifreq))) |
|
74 runtime.KeepAlive(ifreq) |
|
75 return &value, err |
60 return &value, err |
76 } |
61 } |
77 |
62 |
78 // IoctlGetWatchdogInfo fetches information about a watchdog device from the |
63 // IoctlGetWatchdogInfo fetches information about a watchdog device from the |
79 // Linux watchdog API. For more information, see: |
64 // Linux watchdog API. For more information, see: |
80 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. |
65 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. |
81 func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) { |
66 func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) { |
82 var value WatchdogInfo |
67 var value WatchdogInfo |
83 err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value))) |
68 err := ioctlPtr(fd, WDIOC_GETSUPPORT, unsafe.Pointer(&value)) |
84 return &value, err |
69 return &value, err |
85 } |
70 } |
86 |
71 |
87 // IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For |
72 // IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For |
88 // more information, see: |
73 // more information, see: |
89 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. |
74 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. |
90 func IoctlWatchdogKeepalive(fd int) error { |
75 func IoctlWatchdogKeepalive(fd int) error { |
|
76 // arg is ignored and not a pointer, so ioctl is fine instead of ioctlPtr. |
91 return ioctl(fd, WDIOC_KEEPALIVE, 0) |
77 return ioctl(fd, WDIOC_KEEPALIVE, 0) |
92 } |
78 } |
93 |
79 |
94 // IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the |
80 // IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the |
95 // range of data conveyed in value to the file associated with the file |
81 // range of data conveyed in value to the file associated with the file |
96 // descriptor destFd. See the ioctl_ficlonerange(2) man page for details. |
82 // descriptor destFd. See the ioctl_ficlonerange(2) man page for details. |
97 func IoctlFileCloneRange(destFd int, value *FileCloneRange) error { |
83 func IoctlFileCloneRange(destFd int, value *FileCloneRange) error { |
98 err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value))) |
84 return ioctlPtr(destFd, FICLONERANGE, unsafe.Pointer(value)) |
99 runtime.KeepAlive(value) |
|
100 return err |
|
101 } |
85 } |
102 |
86 |
103 // IoctlFileClone performs an FICLONE ioctl operation to clone the entire file |
87 // IoctlFileClone performs an FICLONE ioctl operation to clone the entire file |
104 // associated with the file description srcFd to the file associated with the |
88 // associated with the file description srcFd to the file associated with the |
105 // file descriptor destFd. See the ioctl_ficlone(2) man page for details. |
89 // file descriptor destFd. See the ioctl_ficlone(2) man page for details. |
164 |
148 |
165 return err |
149 return err |
166 } |
150 } |
167 |
151 |
168 func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error { |
152 func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error { |
169 err := ioctl(fd, HIDIOCGRDESC, uintptr(unsafe.Pointer(value))) |
153 return ioctlPtr(fd, HIDIOCGRDESC, unsafe.Pointer(value)) |
170 runtime.KeepAlive(value) |
|
171 return err |
|
172 } |
154 } |
173 |
155 |
174 func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) { |
156 func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) { |
175 var value HIDRawDevInfo |
157 var value HIDRawDevInfo |
176 err := ioctl(fd, HIDIOCGRAWINFO, uintptr(unsafe.Pointer(&value))) |
158 err := ioctlPtr(fd, HIDIOCGRAWINFO, unsafe.Pointer(&value)) |
177 return &value, err |
159 return &value, err |
178 } |
160 } |
179 |
161 |
180 func IoctlHIDGetRawName(fd int) (string, error) { |
162 func IoctlHIDGetRawName(fd int) (string, error) { |
181 var value [_HIDIOCGRAWNAME_LEN]byte |
163 var value [_HIDIOCGRAWNAME_LEN]byte |
182 err := ioctl(fd, _HIDIOCGRAWNAME, uintptr(unsafe.Pointer(&value[0]))) |
164 err := ioctlPtr(fd, _HIDIOCGRAWNAME, unsafe.Pointer(&value[0])) |
183 return ByteSliceToString(value[:]), err |
165 return ByteSliceToString(value[:]), err |
184 } |
166 } |
185 |
167 |
186 func IoctlHIDGetRawPhys(fd int) (string, error) { |
168 func IoctlHIDGetRawPhys(fd int) (string, error) { |
187 var value [_HIDIOCGRAWPHYS_LEN]byte |
169 var value [_HIDIOCGRAWPHYS_LEN]byte |
188 err := ioctl(fd, _HIDIOCGRAWPHYS, uintptr(unsafe.Pointer(&value[0]))) |
170 err := ioctlPtr(fd, _HIDIOCGRAWPHYS, unsafe.Pointer(&value[0])) |
189 return ByteSliceToString(value[:]), err |
171 return ByteSliceToString(value[:]), err |
190 } |
172 } |
191 |
173 |
192 func IoctlHIDGetRawUniq(fd int) (string, error) { |
174 func IoctlHIDGetRawUniq(fd int) (string, error) { |
193 var value [_HIDIOCGRAWUNIQ_LEN]byte |
175 var value [_HIDIOCGRAWUNIQ_LEN]byte |
194 err := ioctl(fd, _HIDIOCGRAWUNIQ, uintptr(unsafe.Pointer(&value[0]))) |
176 err := ioctlPtr(fd, _HIDIOCGRAWUNIQ, unsafe.Pointer(&value[0])) |
195 return ByteSliceToString(value[:]), err |
177 return ByteSliceToString(value[:]), err |
196 } |
178 } |
|
179 |
|
180 // IoctlIfreq performs an ioctl using an Ifreq structure for input and/or |
|
181 // output. See the netdevice(7) man page for details. |
|
182 func IoctlIfreq(fd int, req uint, value *Ifreq) error { |
|
183 // It is possible we will add more fields to *Ifreq itself later to prevent |
|
184 // misuse, so pass the raw *ifreq directly. |
|
185 return ioctlPtr(fd, req, unsafe.Pointer(&value.raw)) |
|
186 } |
|
187 |
|
188 // TODO(mdlayher): export if and when IfreqData is exported. |
|
189 |
|
190 // ioctlIfreqData performs an ioctl using an ifreqData structure for input |
|
191 // and/or output. See the netdevice(7) man page for details. |
|
192 func ioctlIfreqData(fd int, req uint, value *ifreqData) error { |
|
193 // The memory layout of IfreqData (type-safe) and ifreq (not type-safe) are |
|
194 // identical so pass *IfreqData directly. |
|
195 return ioctlPtr(fd, req, unsafe.Pointer(value)) |
|
196 } |
|
197 |
|
198 // IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an |
|
199 // existing KCM socket, returning a structure containing the file descriptor of |
|
200 // the new socket. |
|
201 func IoctlKCMClone(fd int) (*KCMClone, error) { |
|
202 var info KCMClone |
|
203 if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil { |
|
204 return nil, err |
|
205 } |
|
206 |
|
207 return &info, nil |
|
208 } |
|
209 |
|
210 // IoctlKCMAttach attaches a TCP socket and associated BPF program file |
|
211 // descriptor to a multiplexor. |
|
212 func IoctlKCMAttach(fd int, info KCMAttach) error { |
|
213 return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info)) |
|
214 } |
|
215 |
|
216 // IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor. |
|
217 func IoctlKCMUnattach(fd int, info KCMUnattach) error { |
|
218 return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info)) |
|
219 } |