一.概述
所谓 Netd 就是Network Daemon 的缩写,表示Network守护进程,类似的命名还有很多,例如 Vold(Volumn Deamon),Rild(Radio Interface Layer Deamon)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
理解一个模块最好方法就是实际应用。netd最为一个deamon,为开发者提供了一个用于管理的接口。就是ndc (nativedeamonconnector),通过adb可以直接使用CommandListener中定义的各类命令。相似的framework层的NativeDeamonConnector是为上层提供的接口。下面是4.2中ndc可用的命令集合:
interface | list |
readrxcounter| readtxcounter | |
getthrottle |
|
setthrottle |
|
driver |
|
route |
|
list_ttys | |
ipfwd | status |
enable|disable | |
tether | status |
start-reverse|stop-reverse | |
stop< | |
start |
|
interface |
|
dnslist | |
dnsset |
|
nat | |
pppd | attach |
detach |
|
softap | startap|stopap |
fwreload |
|
clients | |
status | |
set |
|
resolver | setdefaultif |
setifdns |
|
flushdefaultif | |
flushif |
|
bandwith | enable|disable |
removequota|rq | |
getquota|gq | |
getiquota|giq |
|
setquota|sq |
|
removequota|rqs |
|
removeiiquota|riq |
|
setiquota|sq |
|
addnaughtyapps|ana |
|
removenaughtyapps|rna |
|
setgolbalalert|sga |
|
debugsettetherglobalalert|dstga |
|
setsharedalert|ssa |
|
removesharedalert|rsa | |
setinterfacealert|sia |
|
removeinterfacealert|ria |
|
gettetherstats|gts |
|
idletimer | enable|disable |
add|remove |
|
firewall | enable|disable|is_enabled |
set_interface_rule |
|
set_egress_source_rule |
|
set_egress_dest_rule |
|
set_uid_rule |
|
clatd | stop|status|start |
从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 函数。
- //NetworkManagementService.java
- @Override
- public void startAccessPoint(
- WifiConfiguration wifiConfig, String wlanIface, String softapIface) {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- try {
- wifiFirmwareReload(wlanIface, "AP");
- if (wifiConfig == null) {
- mConnector.execute("softap", "set", wlanIface, softapIface);
- } else {
- mConnector.execute("softap", "set", wlanIface, softapIface, wifiConfig.SSID,
- getSecurityType(wifiConfig), wifiConfig.preSharedKey);
- }
- mConnector.execute("softap", "startap");
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
- }
- }
NetworkManagementService 通过NativeDaemonConnector, 这里用来和系统的 netd 守护进程通过 socket 进行通信,发送命令。3) netd 接受命令并进行处理,并将处理结果反馈给 Framework 层。
Netd 中 softap 控制的功能在/system/netd/SoftapController.{h,cpp}里, 具体的执行是通过调用网卡驱动的 ap 功能。NetworkManagementService 通过 NativeDaemonConnector 向下通过 socket 向下 softap 相关的字符串命令,NativeDaemonConnector 中维护着与 Netd 中 CommandListener 相关联的内部socket 线程。两者可以通过它相互通信。
- //CommandListener.cpp
- int CommandListener::SoftapCmd::runCommand(SocketClient *cli,
- int argc, char **argv) {
- int rc = 0, flag = 0;
- char *retbuf = NULL;
- if (argc < 2) {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Softap Missing argument", false);
- return 0;
- }
- if (!strcmp(argv[1], "start")) {
- rc = sSoftapCtrl->startDriver(argv[2]);
- } else if (!strcmp(argv[1], "stop")) {
- rc = sSoftapCtrl->stopDriver(argv[2]);
- } else if (!strcmp(argv[1], "startap")) {
- rc = sSoftapCtrl->startSoftap();
- } else if (!strcmp(argv[1], "stopap")) {
- rc = sSoftapCtrl->stopSoftap();
- } else if (!strcmp(argv[1], "fwreload")) {
- rc = sSoftapCtrl->fwReloadSoftap(argc, argv);
- } else if (!strcmp(argv[1], "clients")) {
- rc = sSoftapCtrl->clientsSoftap(&retbuf);
- if (!rc) {
- cli->sendMsg(ResponseCode::CommandOkay, retbuf, false);
- free(retbuf);
- return 0;
- }
- } else if (!strcmp(argv[1], "status")) {
- ……
- ……
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