mirror of https://github.com/golang/go.git
fix: package reference causes compilation failure
This commit is contained in:
parent
ad4f8ff11f
commit
bff8d409eb
|
|
@ -1,154 +0,0 @@
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package net
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ifReq [40]byte
|
|
||||||
|
|
||||||
// Starting from Android 11, it is no longer possible to retrieve network card information
|
|
||||||
// using the RTM_GETLINK method.
|
|
||||||
// As a result, alternative methods need to be employed.
|
|
||||||
// After considering the Android NetworkInterface.getNetworkInterfaces() method,
|
|
||||||
// I opted to utilize the RTM_GETADDR + ioctl approach to obtain network card information.
|
|
||||||
// However, it appears that retrieving the
|
|
||||||
// HWAddr (hardware address) of the network card is currently not achievable.
|
|
||||||
func interfaceTableAndroid(ifindex int) ([]Interface, error) {
|
|
||||||
tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
|
|
||||||
if err != nil {
|
|
||||||
return nil, os.NewSyscallError("netlinkrib", err)
|
|
||||||
}
|
|
||||||
msgs, err := syscall.ParseNetlinkMessage(tab)
|
|
||||||
if err != nil {
|
|
||||||
return nil, os.NewSyscallError("parsenetlinkmessage", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var ift []Interface
|
|
||||||
im := make(map[uint32]struct{})
|
|
||||||
loop:
|
|
||||||
for _, m := range msgs {
|
|
||||||
switch m.Header.Type {
|
|
||||||
case syscall.NLMSG_DONE:
|
|
||||||
break loop
|
|
||||||
case syscall.RTM_NEWADDR:
|
|
||||||
ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
|
|
||||||
if _, ok := im[ifam.Index]; ok {
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
im[ifam.Index] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ifindex == 0 || ifindex == int(ifam.Index) {
|
|
||||||
ifi := newLinkAndroid(ifam)
|
|
||||||
if ifi != nil {
|
|
||||||
ift = append(ift, *ifi)
|
|
||||||
}
|
|
||||||
if ifindex == int(ifam.Index) {
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ift, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// According to the network card Index, get the Name, MTU and Flags of the network card through ioctl
|
|
||||||
func newLinkAndroid(ifam *syscall.IfAddrmsg) *Interface {
|
|
||||||
ift := &Interface{Index: int(ifam.Index)}
|
|
||||||
|
|
||||||
name, err := indexToName(ifam.Index)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
ift.Name = name
|
|
||||||
|
|
||||||
mtu, err := nameToMTU(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
ift.MTU = mtu
|
|
||||||
|
|
||||||
flags, err := nameToFlags(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
ift.Flags = flags
|
|
||||||
return ift
|
|
||||||
}
|
|
||||||
|
|
||||||
func ioctl(fd int, req uint, arg unsafe.Pointer) error {
|
|
||||||
_, _, e1 := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
|
|
||||||
if e1 != 0 {
|
|
||||||
return e1
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func indexToName(index uint32) (string, error) {
|
|
||||||
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM|syscall.SOCK_CLOEXEC, 0)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer syscall.Close(fd)
|
|
||||||
|
|
||||||
var ifr ifReq
|
|
||||||
*(*uint32)(unsafe.Pointer(&ifr[syscall.IFNAMSIZ])) = index
|
|
||||||
err = ioctl(fd, syscall.SIOCGIFNAME, unsafe.Pointer(&ifr[0]))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(bytes.Trim(ifr[:syscall.IFNAMSIZ], "\x00")), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameToMTU(name string) (int, error) {
|
|
||||||
// Leave room for terminating NULL byte.
|
|
||||||
if len(name) >= syscall.IFNAMSIZ {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
|
|
||||||
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM|syscall.SOCK_CLOEXEC, 0)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer syscall.Close(fd)
|
|
||||||
|
|
||||||
var ifr ifReq
|
|
||||||
copy(ifr[:], name)
|
|
||||||
err = ioctl(fd, syscall.SIOCGIFMTU, unsafe.Pointer(&ifr[0]))
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return int(*(*int32)(unsafe.Pointer(&ifr[syscall.IFNAMSIZ]))), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameToFlags(name string) (Flags, error) {
|
|
||||||
// Leave room for terminating NULL byte.
|
|
||||||
if len(name) >= syscall.IFNAMSIZ {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
|
|
||||||
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM|syscall.SOCK_CLOEXEC, 0)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer syscall.Close(fd)
|
|
||||||
|
|
||||||
var ifr ifReq
|
|
||||||
copy(ifr[:], name)
|
|
||||||
err = ioctl(fd, syscall.SIOCGIFFLAGS, unsafe.Pointer(&ifr[0]))
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return linkFlags(*(*uint32)(unsafe.Pointer(&ifr[syscall.IFNAMSIZ]))), nil
|
|
||||||
}
|
|
||||||
|
|
@ -12,12 +12,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// If the ifindex is zero, interfaceTable returns mappings of all
|
// If the ifindex is zero, interfaceTable returns mappings of all
|
||||||
// network interfaces. Otherwise it returns a mapping of a specific
|
// network interfaces. Otherwise, it returns a mapping of a specific
|
||||||
// interface.
|
// interface.
|
||||||
func interfaceTable(ifindex int) ([]Interface, error) {
|
func interfaceTable(ifindex int) ([]Interface, error) {
|
||||||
tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
|
tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsPermission(err) && runtime.GOOS == "android" {
|
if runtime.GOOS == "android" && os.IsPermission(err) {
|
||||||
return interfaceTableAndroid(ifindex)
|
return interfaceTableAndroid(ifindex)
|
||||||
}
|
}
|
||||||
return nil, os.NewSyscallError("netlinkrib", err)
|
return nil, os.NewSyscallError("netlinkrib", err)
|
||||||
|
|
@ -274,3 +274,157 @@ func parseProcNetIGMP6(path string, ifi *Interface) []Addr {
|
||||||
}
|
}
|
||||||
return ifmat
|
return ifmat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Starting from Android 11, it is no longer possible to retrieve network card information
|
||||||
|
// using the RTM_GETLINK method.
|
||||||
|
// As a result, alternative methods need to be employed.
|
||||||
|
// After considering the Android NetworkInterface.getNetworkInterfaces() method,
|
||||||
|
// I opted to utilize the RTM_GETADDR + ioctl approach to obtain network card information.
|
||||||
|
// However, it appears that retrieving the
|
||||||
|
// HWAddr (hardware address) of the network card is currently not achievable.
|
||||||
|
func interfaceTableAndroid(ifindex int) ([]Interface, error) {
|
||||||
|
tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
|
||||||
|
if err != nil {
|
||||||
|
return nil, os.NewSyscallError("netlinkrib", err)
|
||||||
|
}
|
||||||
|
msgs, err := syscall.ParseNetlinkMessage(tab)
|
||||||
|
if err != nil {
|
||||||
|
return nil, os.NewSyscallError("parsenetlinkmessage", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ift []Interface
|
||||||
|
im := make(map[uint32]struct{})
|
||||||
|
loop:
|
||||||
|
for _, m := range msgs {
|
||||||
|
switch m.Header.Type {
|
||||||
|
case syscall.NLMSG_DONE:
|
||||||
|
break loop
|
||||||
|
case syscall.RTM_NEWADDR:
|
||||||
|
ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
|
||||||
|
if _, ok := im[ifam.Index]; ok {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
im[ifam.Index] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ifindex == 0 || ifindex == int(ifam.Index) {
|
||||||
|
ifi := newLinkAndroid(ifam)
|
||||||
|
if ifi != nil {
|
||||||
|
ift = append(ift, *ifi)
|
||||||
|
}
|
||||||
|
if ifindex == int(ifam.Index) {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ift, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// According to the network card Index, get the Name, MTU and Flags of the network card through ioctl
|
||||||
|
func newLinkAndroid(ifam *syscall.IfAddrmsg) *Interface {
|
||||||
|
ift := &Interface{Index: int(ifam.Index)}
|
||||||
|
|
||||||
|
name, err := indexToName(ifam.Index)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ift.Name = name
|
||||||
|
|
||||||
|
mtu, err := nameToMTU(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ift.MTU = mtu
|
||||||
|
|
||||||
|
flags, err := nameToFlags(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ift.Flags = flags
|
||||||
|
return ift
|
||||||
|
}
|
||||||
|
|
||||||
|
func ioctl(fd int, req uint, arg unsafe.Pointer) error {
|
||||||
|
_, _, e1 := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
|
||||||
|
if e1 != 0 {
|
||||||
|
return e1
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexToName(index uint32) (string, error) {
|
||||||
|
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM|syscall.SOCK_CLOEXEC, 0)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer syscall.Close(fd)
|
||||||
|
|
||||||
|
var ifr [40]byte
|
||||||
|
*(*uint32)(unsafe.Pointer(&ifr[syscall.IFNAMSIZ])) = index
|
||||||
|
err = ioctl(fd, syscall.SIOCGIFNAME, unsafe.Pointer(&ifr[0]))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(trim(ifr[:syscall.IFNAMSIZ])), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func nameToMTU(name string) (int, error) {
|
||||||
|
// Leave room for terminating NULL byte.
|
||||||
|
if len(name) >= syscall.IFNAMSIZ {
|
||||||
|
return 0, syscall.EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM|syscall.SOCK_CLOEXEC, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer syscall.Close(fd)
|
||||||
|
|
||||||
|
var ifr [40]byte
|
||||||
|
copy(ifr[:], name)
|
||||||
|
err = ioctl(fd, syscall.SIOCGIFMTU, unsafe.Pointer(&ifr[0]))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(*(*int32)(unsafe.Pointer(&ifr[syscall.IFNAMSIZ]))), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func nameToFlags(name string) (Flags, error) {
|
||||||
|
// Leave room for terminating NULL byte.
|
||||||
|
if len(name) >= syscall.IFNAMSIZ {
|
||||||
|
return 0, syscall.EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM|syscall.SOCK_CLOEXEC, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer syscall.Close(fd)
|
||||||
|
|
||||||
|
var ifr [40]byte
|
||||||
|
copy(ifr[:], name)
|
||||||
|
err = ioctl(fd, syscall.SIOCGIFFLAGS, unsafe.Pointer(&ifr[0]))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return linkFlags(*(*uint32)(unsafe.Pointer(&ifr[syscall.IFNAMSIZ]))), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func trim(data []byte) []byte {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
index := len(data) - 1
|
||||||
|
|
||||||
|
for ; index > 0 && data[index] == 0; index-- {
|
||||||
|
}
|
||||||
|
result := make([]byte, index+1)
|
||||||
|
copy(result, data)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,7 @@
|
||||||
package syscall
|
package syscall
|
||||||
|
|
||||||
import (
|
import (
|
||||||
err2 "errors"
|
"internal/oserror"
|
||||||
"io/fs"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
@ -69,7 +68,11 @@ func NetlinkRIB(proto, family int) ([]byte, error) {
|
||||||
sa := &SockaddrNetlink{Family: AF_NETLINK}
|
sa := &SockaddrNetlink{Family: AF_NETLINK}
|
||||||
if err := Bind(s, sa); err != nil {
|
if err := Bind(s, sa); err != nil {
|
||||||
// Bind operation of Netlink socket is prohibited in Android11 and later versions
|
// Bind operation of Netlink socket is prohibited in Android11 and later versions
|
||||||
if !(runtime.GOOS == "android" && err2.Is(err, fs.ErrPermission)) {
|
if runtime.GOOS != "android" {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, ok := err.(Errno); !ok && !e.Is(oserror.ErrPermission) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue