Android 有线网络开关问题

近期接到某客户特殊需求:把Android TV的主板做成显示器的功能,其中有一项需求是:网络端口保留的情况下,关闭网络通路。也就是说用户在网口中插入网线也无法联网。

这个需求的做法大致有这么几种:

1. 修改网络驱动:初始化的时候关闭网络服务,需要 BSP 技术栈相关经验同事处理。

2. 上层关闭网口:

    2.1 一种方式是通过串口关闭网口,单次开机过程中,用户都是无法联网的;

    2.2 一种方式是通过App接收到开机完成或网络变化的消息时,关闭网口。

其实修改都比较简单,修改驱动的方式比较彻底,但专业性强一点,修改驱动加载逻辑关联的风险及验证比较多,保险起见一般会采用下面方式里面的一种。

现总结一下下面的两种方式:

方式一:串口关闭网口,核心代码如下

#!/system/bin/sh

function_enable_eth0() {
    busybox ifconfig eth0 up
}

function_disable_eth0() {
    busybox ifconfig eth0 down
}

function_isEth0_enabled() {
    result_enabled=$(netcfg | grep "eth0" | grep "UP")
    if [[ "${result_enabled}" == "" ]]; then
        echo "false"
    else
        echo "true"
    fi
}

function_shutdown_eth0() {
    eth0_enabled=$(function_isEth0_enabled)
    if [[ "${eth0_enabled}" == "true" ]]; then
        function_disable_eth0
    fi
}


# 关闭有线网络
function_shutdown_eth0

网络功能的设置需要执行者具备 root 权限,也就是超级用户权限。

将此脚本存放在 /system/bin 下,赋予 root:root 或者 root:shell 用户组,在 init.rc 中植入对应程序的启动即可,时机可以是监听 boot 属性时触发。

方式二:App 调度关闭网口的接口

根据方式一,我们知道关闭有线网口的关闭指令为:busybox ifconfig eth0 down,而应用是可以通过执行 shell 指令来完成功能的调度,所以起始时尝试了此方法,发现并无作用,原因是 App 无执行网络写功能的权限,链路不通。

但根据功能定义来看,既然串口指令可以达到关闭的目的,理论上在App层也有相关的接口可以调度的,这样更符合功能设计和接口设计的初衷。

抱着解决问题的心态,研究下方式一指令会触发哪些过程,于是在串口下,我进行了如下调试:

1. 怀疑 selinux 权限问题:该平台抓 dmesg 日志有问题,于是查看 selinux,发现 selinux 本身就是关闭的,也就是说这个和 selinux 权限没有关系。

 2. 看看命令执行的过程中,系统会有哪些日志输出,我按序输入了如下指令:

# 作用是:清除日志缓存区的日志,新的操作会生成新的日志,方便查阅和分析
logcat -b all -c

# 查看最新日志:all,代表所有的日志缓冲区
# -vthreadtime:日志包含线程、时间戳信息
logcat -b all -vthreadtime 

# 由于上述指令输入后,发现进程号为 2889 的进程不断有日志输出,所以中断掉上述指令
# 此处筛选出 2889 进程的日志不显示,利于查阅、分析问题
# &:表示将该指令运行在后台
logcat -b all -vthreadtime | grep -v "2889" &

# 关闭有线网口
busybox ifconfig eth0 down

执行后,我们清晰看到如下日志输出:

 红色方框标注出来的信息表示:网络信息正在被更新,上方也明显标识着:

EthernetNetworkFactory( 3363): updateInterface: eth0 link down

这里的 3363 代表进程号,查看是 system_server 进程:

做 Android 的看到这个进程,基本都能猜想到:系统服务又在干活了,而这个进程里面的系统服务,都是通过 Binder 体系对外提供的调用。

根据日志信息,我们找到对应平台的代码:EthernetNetworkFactory.java,平台是 Android 5.1 的,这里因公司信息需要保密,此处截图供阅读者参考:

根据打印,可以看到,这个函数被调用时传递的两个参数分别是:eth0 和 false,而此函数是 private 修饰的,只在此类的内部调用,查看其调用的地方在内部类的监听器中:

 这个监听器也是私有类,在此类的 start 函数里面便被注册到对应服务中进行网络状态的监听:

 在这里,可以看到是被注册到 mNMService 这个变量之中,这个变量是一个基于 Binder 的客户端代理,可以看到其是从 ServiceManager 通过 NETWORKMANAGEMENT_SERVICE 来获取的,其接口声明在与 INetworkManagementService.aidl 之中。于是两个想法在我大脑中闪过:

 a. 这个服务在Android应用开发过程中是没见过的,应该是系统对SDK开发人员做的隔离,是隐藏的,不会打包到 SDK 之中,所以也不会有对应的 XXXManager 给客户端使用。

 b. 这个网络监听既然是通过这个代理类注册,也就说明底层获取到网络变化的消息时,通过这个代理类将消息逐层往上层传递,那么这个代理类是否有对端口的操作函数。

带着这两个想法,我找到了对应的代码:INetworkManagementService.aidl、接口实现类NetworkManagementService.java。

查看 NetworkManagementService.java 的类声明,可以验证猜想a确实如此;

查看 INetworkManagementService.aidl 的函数声明,可以看到:

这里确实有我们需要的函数:端口列表、端口关、开、配置等各类接口。

于是我们初步的代码出来了:


// INetworkManagementService mNwService;
Object mINetworkManagementServiceProxy;

public void init() {
    // IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
    // mNwService = INetworkManagementService.Stub.asInterface(b);
    try {
        Class<?> smClass = Class.forName("android.os.ServiceManager");
        Method getService = smClass.getMethod("getService", new Class[]{String.class});
        getService.setAccessible(true);
        IBinder networkManagementBinder = (IBinder) getService.invoke(null, new Object[]{"network_management"});

        Class<?> iNMSClass = Class.forName("android.os.INetworkManagementService$Stub");
        Method asInterface = iNMSClass.getMethod("asInterface", new Class[]{IBinder.class});
        asInterface.setAccessible(true);
        mINetworkManagementServiceProxy = asInterface.invoke(null, new Object[]{networkManagementBinder});
        Log.d("Debug", "init: mINetworkManagementServiceProxy = " + mINetworkManagementServiceProxy);
    } catch (Throwable e) {
        Log.d("Debug", "init: get INetworkManagementServiceProxy failed !!! ");
    }
}

private void openEth0() {
    try {
        Method setInterfaceUp = mINetworkManagementServiceProxy.getClass().getMethod("setInterfaceUp", new Class[]{String.class});
        setInterfaceUp.setAccessible(true);
        setInterfaceUp.invoke(mINetworkManagementServiceProxy, "eth0");
    } catch (Throwable e) {
        Log.d("Debug", "openEth0: failed !!! ");
    }
}

private void closeEth0() {
    try {
        Method setInterfaceDown = mINetworkManagementServiceProxy.getClass().getMethod("setInterfaceDown", new Class[]{String.class});
        setInterfaceDown.setAccessible(true);
        setInterfaceDown.invoke(mINetworkManagementServiceProxy, "eth0");
    } catch (Throwable e) {
        Log.d("Debug", "closeEth0: failed !!! ");
    }
}

执行时发现抛出了安全异常,查看源码发现会校验调用者权限声明:

在 AndroidManifest.xml 中添加对应权限:

<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />

此时编辑器提示此权限只有 system app 才可以申请,于是在 AndroidManifest.xml 中声明 systemUID 后重新打包、签名、安装应用,验证OK。

注意:

1. 上述方式适用于:Android 5~9 的平台

2. Android 10 之后的平台权限有所增加,权限检查详见源码:NetworkStack.checkNetworkStackPermission(mContext); 适配时,需要修改 compileSdkVersion 及对应的权限声明,补充如下权限:

<uses-permission android:name="android.permission.NETWORK_STACK" />
<uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />

3. 如上权限任意声明一个即可,因为权限校验时,具备任一个权限的授权认为都是有效的,源码传送门PermissionUtils.java在线源码

public final class PermissionUtils {


    /**
     * Return true if the context has one of given permission.
     */
    public static boolean checkAnyPermissionOf(@NonNull Context context, @NonNull String... permissions) {
        for (String permission : permissions) {
            if (context.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
                return true;
            }
        }
        return false;
    }

}

参考文档:Android系统的超级终端命令大全(五)--网络操作命令-爱码网ifconfig1.作用ifconfig用于查看和更改网络接口的地址和参数,包括IP地址、网络掩码、广播地址,使用权限是超级用户。2.格式ifconfig-interface[options]https://www.likecs.com/show-422844.html#sc=965

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 监控AP有线网络拓扑结构是指通过监控设备对无线接入点的有线连接网络进行拓扑结构的监控和管理。 在一个典型的监控AP有线网络拓扑结构中,通常会有一个监控控制中心,用于集中管理和监控所有接入点的状态和性能信息。控制中心与每个接入点之间通过有线连接进行通信。有线连接可以使用以太网电缆或光纤进行传输。 有线网络拓扑结构的主要组成部分包括接入点、交换机和监控控制中心。接入点是无线信号的转发设备,将用户的无线设备连接到有线网络中。交换机则是网络中的核心设备,负责接收来自接入点的数据流,并将其转发到合适的目的地。监控控制中心通过有线连接与交换机和接入点进行通信,以获取状态信息、配置接入点和解决网络问题。 监控AP有线网络拓扑结构的优点在于可以实时监控和管理每个接入点的状态和性能。管理员可以通过控制中心远程监控接入点的连接状态、信号强度、数据流量等信息,并及时发现和解决网络故障。此外,有线连接相对于无线连接更加稳定和可靠,能够提供更好的网络传输性能。 总之,监控AP有线网络拓扑结构是通过有线连接将接入点、交换机和监控控制中心连接起来,实现对无线网络的监控和管理。这种拓扑结构可以提供稳定的网络传输性能和全面的监控能力,有助于优化网络性能和提高用户体验。 ### 回答2: 监控AP有线网络拓扑结构指的是在一个网络系统中,通过监视、管理和控制访问点(AP)以及与之连接的有线网络设备的布局和连接方式。 在一个典型的拓扑结构中,AP连接到一个局域网(LAN)交换机或路由器的端口。这个交换机或路由器是网络的核心设备,负责将数据包转发到目标设备。AP通过有线连接到交换机或路由器,提供无线网络信号覆盖。 通过监控AP有线网络拓扑结构,可以实现以下几个目标: 1. 网络监视:监控AP有线网络拓扑结构可以帮助管理员实时监视网络状态,包括AP的连接状态、信号质量、频率等信息。这有助于提前发现网络故障或性能问题,并及时采取措施进行修复或优化。 2. 安全管理:监控AP有线网络拓扑结构可以帮助管理员检测未授权设备的连接,并及时采取措施保护网络安全。通过监控可以获知网络中哪些设备连接到了AP,对于未知设备可以进行身份验证或阻止其访问。 3. 网络优化:监控AP有线网络拓扑结构可以帮助管理员分析网络使用情况,发现瓶颈点,并进行相应的优化。通过监控可以了解到网络拥塞、信号干扰等问题,从而调整AP的位置或设置,提升无线信号覆盖和带宽利用率。 总之,监控AP有线网络拓扑结构对于网络管理和优化至关重要。通过实时监视和分析,可以及时发现和解决网络问题,提高网络性能和安全性。 ### 回答3: 监控 AP 有线网络拓扑结构是指在一个网络中,AP(Access Point)作为无线接入点连接到有线网络上,用于实现无线网络的覆盖和连接。AP 有线网络拓扑结构一般包括以下组成部分。 首先,有线网络主干是构成基础的一部分。它由交换机、路由器等网络设备组成,是整个局域网的核心,用于传输数据和连接各个子网。通过有线网络主干,AP可以与其他网络设备进行通信,获得网络资源以及提供无线网络服务。 其次,AP作为无线接入设备,通过网线与有线网络主干相连。AP负责接收来自有线网络设备的数据,并将其转换成无线信号发送给周围的无线终端设备。 此外,为了提供更好的无线网络覆盖范围,可以在有线网络拓扑中设置多个AP。这些AP之间可以通过有线链路以及相应的有线网络设备进行互联,形成一个覆盖整个区域的无线网络。当无线终端设备从一个AP的覆盖范围切换到另一个AP的覆盖范围时,无线信号的传输可以通过有线网络进行连接,以实现无缝切换。 总的来说,监控AP有线网络拓扑结构是将无线网络有线网络进行有机连接的一种方式。通过合理布置AP和有线网络设备,可以实现整个区域的无线网络覆盖,方便用户进行无线上网。同时,通过对AP的监控,可以实时掌握无线网络的状态,保障网络的稳定性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值