LOCAL_SRC_FILES:= \
BandwidthController.cpp \
+ ClatdController.cpp \
CommandListener.cpp \
DnsProxyListener.cpp \
FirewallController.cpp \
--- /dev/null
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#define LOG_TAG "ClatdController"
+#include <cutils/log.h>
+
+#include "ClatdController.h"
+
+ClatdController::ClatdController() {
+ mClatdPid = 0;
+}
+
+ClatdController::~ClatdController() {
+}
+
+int ClatdController::startClatd(char *interface) {
+ pid_t pid;
+
+ if(mClatdPid != 0) {
+ ALOGE("clatd already running");
+ errno = EBUSY;
+ return -1;
+ }
+
+ ALOGD("starting clatd");
+
+ if ((pid = fork()) < 0) {
+ ALOGE("fork failed (%s)", strerror(errno));
+ return -1;
+ }
+
+ if (!pid) {
+ char **args = (char **)malloc(sizeof(char *) * 4);
+ args[0] = (char *)"/system/bin/clatd";
+ args[1] = (char *)"-i";
+ args[2] = interface;
+ args[3] = NULL;
+
+ if (execv(args[0], args)) {
+ ALOGE("execv failed (%s)", strerror(errno));
+ }
+ ALOGE("Should never get here!");
+ free(args);
+ _exit(0);
+ } else {
+ mClatdPid = pid;
+ ALOGD("clatd started");
+ }
+
+ return 0;
+}
+
+int ClatdController::stopClatd() {
+ if (mClatdPid == 0) {
+ ALOGE("clatd already stopped");
+ return -1;
+ }
+
+ ALOGD("Stopping clatd");
+
+ kill(mClatdPid, SIGTERM);
+ waitpid(mClatdPid, NULL, 0);
+ mClatdPid = 0;
+
+ ALOGD("clatd stopped");
+
+ return 0;
+}
+
+bool ClatdController::isClatdStarted() {
+ pid_t waitpid_status;
+ if(mClatdPid == 0) {
+ return false;
+ }
+ waitpid_status = waitpid(mClatdPid, NULL, WNOHANG);
+ if(waitpid_status != 0) {
+ mClatdPid = 0; // child exited, don't call waitpid on it again
+ }
+ return waitpid_status == 0; // 0 while child is running
+}
--- /dev/null
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLATD_CONTROLLER_H
+#define _CLATD_CONTROLLER_H
+
+class ClatdController {
+ pid_t mClatdPid;
+
+public:
+ ClatdController();
+ virtual ~ClatdController();
+
+ int startClatd(char *interface);
+ int stopClatd();
+ bool isClatdStarted();
+};
+
+#endif
ResolverController *CommandListener::sResolverCtrl = NULL;
SecondaryTableController *CommandListener::sSecondaryTableCtrl = NULL;
FirewallController *CommandListener::sFirewallCtrl = NULL;
+ClatdController *CommandListener::sClatdCtrl = NULL;
/**
* List of module chains to be created, along with explicit ordering. ORDERING
registerCmd(new IdletimerControlCmd());
registerCmd(new ResolverCmd());
registerCmd(new FirewallCmd());
+ registerCmd(new ClatdCmd());
if (!sSecondaryTableCtrl)
sSecondaryTableCtrl = new SecondaryTableController();
sFirewallCtrl = new FirewallController();
if (!sInterfaceCtrl)
sInterfaceCtrl = new InterfaceController();
+ if (!sClatdCtrl)
+ sClatdCtrl = new ClatdController();
/*
* This is the only time we touch top-level chains in iptables; controllers
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false);
return 0;
}
+
+CommandListener::ClatdCmd::ClatdCmd() : NetdCommand("clatd") {
+}
+
+int CommandListener::ClatdCmd::runCommand(SocketClient *cli, int argc,
+ char **argv) {
+ int rc = 0;
+ if (argc < 2) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+ return 0;
+ }
+
+ if(!strcmp(argv[1], "stop")) {
+ rc = sClatdCtrl->stopClatd();
+ } else if (!strcmp(argv[1], "status")) {
+ char *tmp = NULL;
+
+ asprintf(&tmp, "Clatd status: %s", (sClatdCtrl->isClatdStarted() ?
+ "started" : "stopped"));
+ cli->sendMsg(ResponseCode::ClatdStatusResult, tmp, false);
+ free(tmp);
+ return 0;
+ } else if(!strcmp(argv[1], "start")) {
+ if (argc < 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+ return 0;
+ }
+ rc = sClatdCtrl->startClatd(argv[2]);
+ } else {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown clatd cmd", false);
+ return 0;
+ }
+
+ if (!rc) {
+ cli->sendMsg(ResponseCode::CommandOkay, "Clatd operation succeeded", false);
+ } else {
+ cli->sendMsg(ResponseCode::OperationFailed, "Clatd operation failed", false);
+ }
+
+ return 0;
+}
#include "ResolverController.h"
#include "SecondaryTableController.h"
#include "FirewallController.h"
+#include "ClatdController.h"
class CommandListener : public FrameworkListener {
static TetherController *sTetherCtrl;
static ResolverController *sResolverCtrl;
static SecondaryTableController *sSecondaryTableCtrl;
static FirewallController *sFirewallCtrl;
+ static ClatdController *sClatdCtrl;
public:
CommandListener();
int sendGenericOkFail(SocketClient *cli, int cond);
static FirewallRule parseRule(const char* arg);
};
+
+ class ClatdCmd : public NetdCommand {
+ public:
+ ClatdCmd();
+ virtual ~ClatdCmd() {}
+ int runCommand(SocketClient *c, int argc, char ** argv);
+ };
};
#endif
static const int QuotaCounterResult = 220;
static const int TetheringStatsResult = 221;
static const int DnsProxyQueryResult = 222;
+ static const int ClatdStatusResult = 223;
// 400 series - The command was accepted but the requested action
// did not take place.