Android Netd

2023-11-17

一.概述

      所谓 Netd 就是Network Daemon 的缩写,表示Network守护进程,类似的命名还有很多,例如 Vold(Volumn Deamon),Rild(Radio Interface Layer Deamon)
      Netd负责跟一些涉及网络的配置,操作,管理,查询等相关的功能实现,比如,例如带宽控制(Bandwidth),流量统计,带宽控制,网络地址转换(NAT),个人局域网(pan),PPP链接,soft-ap,共享上网(Tether),配置路由表,interface配置管理,等等……
      通过netlink,虚拟文件系统,等linux内核提供的用户接口,通信内核,或者直接执行系统模块,管理网络相关部分。

涉及主要源码位置:

    Netd:
             /System/netd/*
    lib:
             /system/core/libsysutils/src
    Framework:
            /frameworks/base/services/java/com/android/server/NetworkManagementService.java
            /frameworks/base/services/java/com/android/server/NativeDaemonConnector.java

框架图~

很不规范,会意即可:









二.ndc

      理解一个模块最好方法就是实际应用。netd最为一个deamon,为开发者提供了一个用于管理的接口。就是ndc (nativedeamonconnector),通过adb可以直接使用CommandListener中定义的各类命令。相似的framework层的NativeDeamonConnector是为上层提供的接口。下面是4.2中ndc可用的命令集合:

可用命令表:

    例如:  leo@leo-weng:~$ adb shell ndc interface list

interface list
readrxcounter| readtxcounter
getthrottle<iface><”rx|tx”>
setthrottle<iface><rx_kbps|tx_kbps>
driver<iface><cmd><args>
route<add|remove> <iface> <”default|secondary”><dst> <prefix> <gateway>
list_ttys  
ipfwd status
enable|disable
tether status
start-reverse|stop-reverse
stop<
start<addr_1 addr_2 addr_3 addr_4 [addr_2n]>
interface<add|remove|list>
dnslist
dnsset <addr_1> < addr_2>
nat <enable|disable><iface><extface><addrcnt><nated-ipaddr/prelength>
pppd attach<tty> <addr_local> <add_remote> <dns_1><dns_2>
detach<tty>
softap startap|stopap
fwreload<iface> <AP|P2P>
clients
status
set<iface> <SSID> <wpa-psk|wpa2-psk|open> [<key><channel> <preamble><max SCB>]
resolver setdefaultif<iface>
setifdns<iface><dns_1><dns_2>
flushdefaultif
flushif<iface>
bandwith enable|disable
removequota|rq
getquota|gq
getiquota|giq<iface>
setquota|sq<bytes> <iface>
removequota|rqs<iface>
removeiiquota|riq<iface>
setiquota|sq<interface><bytes>
addnaughtyapps|ana<appUid>
removenaughtyapps|rna<appUid>
setgolbalalert|sga<bytes>
debugsettetherglobalalert|dstga<iface0><iface1>
setsharedalert|ssa<bytes>
removesharedalert|rsa
setinterfacealert|sia<iface><bytes>
removeinterfacealert|ria<iface>
gettetherstats|gts<iface0><iface1>
idletimer enable|disable
add|remove<iface><timeout><classLabel>
firewall enable|disable|is_enabled
set_interface_rule<rmnet0><allow|deny>
set_egress_source_rule<ip_addr><allow|deny>
set_egress_dest_rule<ip_addr><port><allow|deny>
set_uid_rule<uid><allow|deny>
clatd stop|status|start<iface>

从init.rc文件中可以看到,是系统级的守护进程,手动kill后还会从新启动。


一、文件构成

Netd文件下的源文件模块~组织以及基本实现功能:

======================================================================
Android.mk                                            \Android makefile
CleanSpec.mk
main.cpp                                                \主函数入口

======================================================================
CommandListener.cpp
                                                                 \监听 frameworek 层命令,通过 tcp
                                                                 \向 framework 层注册处理函数命令的 cmd
                                                                 \实现对应命令的处理函数
CommandListener.h

======================================================================
NetlinkManager.cpp                                 \监听 kernel 的 event,通过无连接socket 可以
                                                                 \理解为udp在 setsocketopt 中实现与 kernel 
                                                                 \的关联监听事件类型
NetlinkManager.h

======================================================================
NetdCommand.cpp                             \直接调用 frameworkcommand
NetdCommand.h
NetlinkHandler.cpp                             \继承自 NetlinkListener
                                                                 \onEvent 函数的实现
                                                                 \根据 onEvent 函数命令的解析调用不同的处理函数
                                                                 \并调用 nm->sendBroadcast 广播 ResponseCode
NetlinkHandler.h
NetdConstants.cpp                             \全局路径 为操作 iptable 的函数提供
NetdConstants.h

======================================================================
List.h
logwrapper.c
ndc.c                                                 \NativeDaemonConnector
oem_iptables_hook.cpp                     \iptable 系统调用 hook
oem_iptables_hook.h

======================================================================
DnsProxyListener.cpp                         \DNS 解析相关独立部分
DnsProxyListener.h

MdnsSdListener.cpp                           \Multi-DNS 解析独立部分
MdnsSdListener.h

======================================================================
IdletimerController.cpp                       \具体的要注册给 Framework 的 cmd 的处理部分
IdletimerController.h
BandwidthController.cpp
BandwidthController.h
NatController.cpp
NatController.h
PanController.cpp
PanController.h
PppController.cpp
PppController.h
ResolverController.cpp
ResolverController.h
ResponseCode.h
SecondaryTableController.cpp
SecondaryTableController.h
SoftapController.cpp
SoftapController.h
TetherController.cpp
TetherController.h
ThrottleController.cpp
ThrottleController.h

======================================================================

二、文件中最主要的类是:


管理类:

CommandListener、NetlinkManager、MdnsSdListener、DnsProxyListener

处理类:

ResponseCode、Netlinkhandler、 CommandListener::XXXCmd 

相关类:

Socketlistener、SocketClient、NetlinkListener、NetlinkEvent、FrameworkListener、FrameworkCommand、FrameworkClient

下面是一些UML,也不规范,大概意思明白就可以~~ 在后面还会详细的介绍。


(1)CommandListener、NetlinkHandler


(2)命令的上传/下达

(3)各种cmd功能


三.基本实例

就拿手机的soft-ap功能来举例吧,以使用 softap(Soft Access Point)为例。softap可以为wlan接入设备共享手机使用的移动网络,笔记本接入softap,可以通过手机的 3g 上网。以htc 中的 WLAN 热点的 app,如下图所示。

 

1)设置并开启 softap(便携式 WLAN 热点)

在 Setting 选项中进行设置,该设置功能的开启将涉及相关的UI 路径下相关的文件,packages /apps/Settings/src/com/android/settings/wifi 路径下,程序中的 WifiApEnabler. OnPreferenceChange 里, 设置 soft ap 在 wifiApDialog.onClick 里。

2)调用相应的处理函数,通过 socket 向 netd 下发命令

应用层通过ConnectivityManager接口,最终走到 Framework 层的 NetworkManagementService.startAccessPoint 函数。

[java]  view plain  copy
  1. //NetworkManagementService.java     
  2.  @Override  
  3.     public void startAccessPoint(  
  4.             WifiConfiguration wifiConfig, String wlanIface, String softapIface) {  
  5.         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);  
  6.         try {  
  7.             wifiFirmwareReload(wlanIface, "AP");  
  8.             if (wifiConfig == null) {  
  9.                 mConnector.execute("softap""set", wlanIface, softapIface);  
  10.             } else {  
  11.                 mConnector.execute("softap""set", wlanIface, softapIface, wifiConfig.SSID,  
  12.                         getSecurityType(wifiConfig), wifiConfig.preSharedKey);  
  13.             }  
  14.             mConnector.execute("softap""startap");  
  15.         } catch (NativeDaemonConnectorException e) {  
  16.             throw e.rethrowAsParcelableException();  
  17.         }  
  18.     }  

NetworkManagementService 通过NativeDaemonConnector, 这里用来和系统的 netd 守护进程通过 socket 进行通信,发送命令。

3) netd 接受命令并进行处理,并将处理结果反馈给 Framework 层。

Netd 中 softap 控制的功能在/system/netd/SoftapController.{h,cpp}里, 具体的执行是通过调用网卡驱动的 ap 功能。NetworkManagementService 通过 NativeDaemonConnector 向下通过 socket 向下 softap 相关的字符串命令,NativeDaemonConnector 中维护着与 Netd 中 CommandListener 相关联的内部socket 线程。两者可以通过它相互通信。

[cpp]  view plain  copy
  1. //CommandListener.cpp  
  2. int CommandListener::SoftapCmd::runCommand(SocketClient *cli,  
  3.                                         int argc, char **argv) {  
  4.     int rc = 0, flag = 0;  
  5.     char *retbuf = NULL;  
  6.   
  7.     if (argc < 2) {  
  8.         cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument"false);  
  9.         return 0;  
  10.     }  
  11.   
  12.     if (!strcmp(argv[1], "start")) {  
  13.         rc = sSoftapCtrl->startDriver(argv[2]);  
  14.     } else if (!strcmp(argv[1], "stop")) {  
  15.         rc = sSoftapCtrl->stopDriver(argv[2]);  
  16.     } else if (!strcmp(argv[1], "startap")) {  
  17.         rc = sSoftapCtrl->startSoftap();  
  18.     } else if (!strcmp(argv[1], "stopap")) {  
  19.         rc = sSoftapCtrl->stopSoftap();  
  20.     } else if (!strcmp(argv[1], "fwreload")) {  
  21.         rc = sSoftapCtrl->fwReloadSoftap(argc, argv);  
  22.     } else if (!strcmp(argv[1], "clients")) {  
  23.         rc = sSoftapCtrl->clientsSoftap(&retbuf);  
  24.         if (!rc) {  
  25.             cli->sendMsg(ResponseCode::CommandOkay, retbuf, false);  
  26.             free(retbuf);  
  27.             return 0;  
  28.         }  
  29.     } else if (!strcmp(argv[1], "status")) {  
  30.       
  31. ……  
  32. ……  

4) Framework 受到回馈的信息,并通知 UI 处理结果,呈现给用户。

相关的 Log 实例:

D/NetworkManagementService( 1760): ===================startAccessPoint
commandLine=softap set wlan0 wlan0 "HTC Portable Hotspot E2D4" "wpa2-psk" *** 0 0 5 0

D/NetdConnector( 1760): SND -> {softap set wlan0 wlan0 "HTC Portable Hotspot E2D4""wpa2-psk" "3FF8F7531FBB9" 0 0 5 0} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Softap operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Softap operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): SND -> {softap startap} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate wlan0 down}
D/NetdConnector( 1760): listenToSocket read--: (24,0)
D/NetdConnector( 1760): RCV <- {600 Iface added m.wlan0}
D/NetdConnector( 1760): listenToSocket read--: (33,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate m.wlan0 down}
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate m.wlan0 up}
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Softap operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Softap operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): SND -> {softap setMaxConns 5} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Softap operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Softap operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): listenToSocket read--: (29,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate wlan0 up}
D/NetdConnector( 1760): listenToSocket read--: (29,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate wlan0 up}
D/NetdConnector( 1760): listenToSocket read--: (29,0)
D/NetdConnector( 1760): RCV <- {600 Iface linkstate wlan0 up}
D/NetdConnector( 1760): SND -> {interface getcfg wlan0} {null}
D/NetdConnector( 1760): listenToSocket read--: (65,0)
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): RCV <- {213 1c:b0:94:36:bf:cb 0.0.0.0 0 [up broadcast running multicast]}
D/NetdConnector( 1760): RSP <- {213 1c:b0:94:36:bf:cb 0.0.0.0 0 [up broadcast runningmulticast]}

D/NetworkManagementService( 1760): rsp <213 1c:b0:94:36:bf:cb 0.0.0.0 0 [up broadcast running multicast]>
D/NetworkManagementService( 1760): flags <[up broadcast running multicast]>
D/NetdConnector( 1760): SND -> {interface setcfg wlan0 192.168.1.1 24 [up]} {null}
D/NetdConnector( 1760): listenToSocket read--: (32,0)
D/NetdConnector( 1760): RCV <- {200 Interface configuration set}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): RSP <- {200 Interface configuration set}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
E/NetworkManagementService( 1760): DEBUG softap setmaclist: softap setmaclist 0 "" ""
D/NetdConnector( 1760): SND -> {softap setmaclist 0 "" ""} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Softap operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Softap operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): SND -> {tether interface add wlan0} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (31,0)
D/NetdConnector( 1760): RCV <- {200 Tether operation succeeded}
D/NetdConnector( 1760): RSP <- {200 Tether operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetdConnector( 1760): SND -> {softap getassoclist} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (7,0)
D/NetdConnector( 1760): RCV <- {222 0|}
D/NetdConnector( 1760): RSP <- {222 0|}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
E/NetworkManagementService( 1760): DEBUG softap getassoclist: 0|
D/NetdConnector( 1760): SND -> {ipfwd enable} {null}
D/NetdConnector( 1760): already send Command (Wait Response)
D/NetdConnector( 1760): listenToSocket read--: (30,0)
D/NetdConnector( 1760): RCV <- {200 ipfwd operation succeeded}
D/NetdConnector( 1760): RSP <- {200 ipfwd operation succeeded}
D/NetdConnector( 1760): No Resp times=0
D/NetdConnector( 1760): finish send Command (complete)
D/NetworkManagementService( 1760): stopTethering
D/NetdConnector( 1760): SND -> {tether status} {null}
D/NetdConnector( 1760): listenToSocket read--: (31,0)


转载来自:https://blog.csdn.net/xiaokeweng/article/details/8130218

                 https://blog.csdn.net/xiaokeweng/article/details/8135535

系列文章:https://blog.csdn.net/feng1072218457/article/details/77913373

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android Netd 的相关文章

随机推荐

  • React 中ref的几种用法

    React 中ref的几种用法 1 字符串 通过 this refs a 来引用真实dom的节点 dom 节点上使用
  • 结构光相机国产、非国产统计参数对比分析

    结构光相机国产 非国产统计参数对比分析 1 Kinect v1 Kinect v1深度相机拥有一个RGB彩色摄像头 一个红外线CMOS摄像机和一个红外发射器 相机的红外线CMOS摄像机和红外发射器以左右水平的方式分布 该相机采用的是以结构光
  • Unix环境下Oracle数据库完全优化详解

    Unix环境下Oracle数据库完全优化详解 2007 04 19 12 54 02 作者 changelive 浏览次数 14 文字大小 大 中 小 进入论坛 如今的优化己经向优化等待 waits 转型了 实际中性能优化最根本的出现点也都
  • Windows驱动开发第11课(R3与R0通信交换数据第二节)

    在上一节课我们证实了在用户层调用CreateFile函数时 相应的在驱动层会响应一个IRP MJ CREATE的事件 这节课我们来看看用户层和驱动层是怎么交换数据的 首先来介绍一下控制码 由CTL CODE宏创建 是一个唯一的32位系统I
  • 数据库系统原理(第二版)知识点总结

    目录 第一章 概述 基本知识 数据模型 数据模型的组成要素 数据模型的分类 数据库系统的结构 第二章 关系运算 2 1 关系运算语言 1 关系代数语言 第三章 数据完整性 实体完整性 主属性的取值不能为空值 主属性的候选键的取值要非空且唯一
  • Python中的一些特殊函数

    https www cnblogs com maybe2030 p 4678920 html
  • centos7系统启动流程

    开机自检 gt 查找第一启动项设备 gt 加载第一启动项设备上的bootloader 存在于MBR中 gt 加载内核 initramfs gt 只读加载rootfs gt sbin init 即systemd
  • Flask 数据库 连接池、DBUtils、http 连接池

    1 DBUtils 简介 使用 DBUtils 简介 DBUtils 是一套用于管理 数据库 连接池 的Python包 为 高频度 高并发 的数据库访问提供更好的性能 可以自动管理连接对象的创建和释放 并允许对非线程安全的数据库接口进行线程
  • vector 查找_怎么写出无bug的二分查找算法代码

    封面图来自 geeksforgeeks 1 简介 二分查找算法是一类比较基础的算法 然而想要短时间内 写出二分查找的无 bug 版本 也不是很容易的 为此我查找了一些资料 终于弄清了二分查找算法的套路 在此分享给大家 也算是对自己学习知识的
  • Chisel3实践用例,安装

    新建SBT工程 sbt version 1 2 8 name ScalaExample version 0 1 scalaVersion 2 12 8
  • @Transient 理解

    transient使用小结 1 一旦变量被transient修饰 变量将不再是对象持久化的一部分 该变量内容在序列化后无法获得访问 2 transient关键字只能修饰变量 而不能修饰方法和类 注意 本地变量是不能被transient关键字
  • YOLOV2个人理解总结

    YOLOv2框架图 YOLOv2改进之处 1 Batch Normalization BN Batch Normalization 层简单讲就是对网络的每一层的输入都做了归一化 这样网络就不需要每层都去学数据的分布 收敛会快点 原来的YOL
  • 面试题:如何测试登录功能

    最近在做一个创新项目 这个项目有二个平台 每个平台都有前后端 故有四个系统 每个系统都有登录功能 而且不同系统代码设计方式都有所差异 所以就这个登录功能而言就要测试四次 看似一个简单的登录功能其中设计的测试点也是相当复杂 今天就讲讲如何测试
  • php scp跨服器拷贝文件到sftp

    一般要装php的ssh2扩展 比较麻烦 所以转念一想 为什么不用我们经常用的scp 但是scp跨服务器拷贝需要输入密码 这里就用到了一个工具试试sshpass 可以指定密码 1 工具安装 ubuntu安装 sudo apt get inst
  • 【问题解决】org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io

    1 出现问题异常 核心错误输出 org springframework dao QueryTimeoutException Redis command timed out nested exception is io lettuce cor
  • B站马士兵python入门基础版详细笔记(3)

    一 input函数的使用 他的返回值类型一定是str类型 m1 input please input the first word m2 input please input the second word print int m1 int
  • c++库 Android调用

    如果您想在Android应用程序中使用C 库 您可以通过以下几个步骤封装C 库以供Android调用 创建一个新的Android项目并设置C 支持 在Android Studio中创建一个新的Android项目 并选择包含C 支持的选项 将
  • [学C日记]---递归

    递归 自己调用自己 大事化小 必要条件 1 有限制条件 当满足限制条件时 递归便不继续 2 每次递归调用之后越来越接近这个限制条件 3 递归层次不能太深 太深容易栈溢出 每次递归调用都要给函数分栈区 次数过多容易空间不足 1 一串数字挨个输
  • 深聊自动化测试之:小鱼整理21条避坑指南,让你完美运行自动化

    自动化测试避坑总结 1 引言 2 避坑内容总结 2 1无法定位到元素 2 2 Indentation Error 2 3 PO设计模式类 2 4 页面封装类中没有已定义函数的问题 2 4 1 提示没有该方法 2 4 2 没有定义好的函数 2
  • Android Netd

    一 概述 所谓 Netd 就是Network Daemon 的缩写 表示Network守护进程 类似的命名还有很多 例如 Vold Volumn Deamon Rild Radio Interface Layer Deamon Netd负责