The framework layer and native layer implement network control (iptable mode) and nativeiptable
In recent work, you need to develop a function-network control, which is actually used by the root Android machine. It should be known that an application is prohibited from connecting to a mobile network or wifi.
After root, run the iptable command through su to control the application's Internet permissions based on the uid.
However, because the company is engaged in mobile phone system development, the mobile phone production does not allow root permissions, so we cannot use root permissions to complete this function.
Because of this function for the first time, I was naive at first to think that the system has an interface with this control permission, and then there is only one Internet permission, which cannot distinguish between data traffic and wifi.
Well, the final implementation method directly.
At that time, it was found that a function on the mobile phone was used to restrict data traffic in the background of the application. As described in this function, the application cannot use traffic in the background state. Through code tracing, we can find that it calls a NetworkManagementService. java Service. The method is the following, and the mConnector in it is used to encapsulate the class used to send commands. If you are interested, take a look at ---> NativeDaemonConnector. java
@Override public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); // silently discard when control disabled // TODO: eventually migrate to be always enabled if (!mBandwidthControlEnabled) return; synchronized (mQuotaLock) { final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false); if (oldRejectOnQuota == rejectOnQuotaInterfaces) { // TODO: eventually consider throwing return; } try { mConnector.execute("bandwidth", rejectOnQuotaInterfaces ? "addnaughtyapps" : "removenaughtyapps", uid); if (rejectOnQuotaInterfaces) { mUidRejectOnQuota.put(uid, true); } else { mUidRejectOnQuota.delete(uid); } } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } }
By searching the addnaughtyapps keyword, The CommandListener. cpp class finds the place to parse this command,
if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) { if (argc < 3) { sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ..."); return 0; } int rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2); sendGenericOkFail(cli, rc); return 0; }
Finally, execute the iptable operation command in the BandwidthController. cpp class,
OK. Since this Service has the permission to directly execute iptable, it is okay to add the method we need directly in it.
Therefore,
1. Add the filter keyword to CommandListener. cpp to determine the filter keyword,
2. Add Interfaces to NetworkManagementService. java to send commands,
3. The final implementation is carried out in BandwidthController. cpp.
Step 3 focuses on iptable operations and how to use the Internet a lot. However, at that time, I was able to understand iptable operations for a long time ...... -I and-D commands are mainly used.
In fact, I'm more curious about how the netd process has the permission to execute the root command. When you are free, you must study it.
Currently, only init. rc can be configured with the root permission to start the service.