int BandwidthController::getTetherStats(SocketClient *cli, TetherStats &stats, std::string &extraProcessingInfo) { int res; std::string fullCmd; FILE *iptOutput; /* * Why not use some kind of lib to talk to iptables? * Because the only libs are libiptc and libip6tc in iptables, and they are * not easy to use. They require the known iptables match modules to be * preloaded/linked, and require apparently a lot of wrapper code to get * the wanted info. */ fullCmd = IPTABLES_PATH; fullCmd += " -nvx -w -L "; fullCmd += NatController::LOCAL_TETHER_COUNTERS_CHAIN; iptOutput = popen(fullCmd.c_str(), "r"); if (!iptOutput) { ALOGE("Failed to run %s err=%s", fullCmd.c_str(), strerror(errno)); extraProcessingInfo += "Failed to run iptables."; return -1; } res = parseForwardChainStats(cli, stats, iptOutput, extraProcessingInfo); pclose(iptOutput); /* Currently NatController doesn't do ipv6 tethering, so we are done. */ return res; }
int BandwidthController::getTetherStats(TetherStats &stats, std::string &extraProcessingInfo) { int res; std::string fullCmd; FILE *iptOutput; const char *cmd; if (stats.rxBytes != -1 || stats.txBytes != -1) { ALOGE("Unexpected input stats. Byte counts should be -1."); return -1; } /* * Why not use some kind of lib to talk to iptables? * Because the only libs are libiptc and libip6tc in iptables, and they are * not easy to use. They require the known iptables match modules to be * preloaded/linked, and require apparently a lot of wrapper code to get * the wanted info. */ fullCmd = IPTABLES_PATH; fullCmd += " -nvx -L natctrl_FORWARD"; iptOutput = popen(fullCmd.c_str(), "r"); if (!iptOutput) { ALOGE("Failed to run %s err=%s", fullCmd.c_str(), strerror(errno)); extraProcessingInfo += "Failed to run iptables."; return -1; } res = parseForwardChainStats(stats, iptOutput, extraProcessingInfo); pclose(iptOutput); /* Currently NatController doesn't do ipv6 tethering, so we are done. */ return res; }