NatController.cpp revision 9ff78fb7da7158f5bd7c86d89a842691820259cf
19ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat/* 29ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Copyright (C) 2008 The Android Open Source Project 39ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 49ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 59ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * you may not use this file except in compliance with the License. 69ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * You may obtain a copy of the License at 79ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 89ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * http://www.apache.org/licenses/LICENSE-2.0 99ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * 109ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * Unless required by applicable law or agreed to in writing, software 119ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * distributed under the License is distributed on an "AS IS" BASIS, 129ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * See the License for the specific language governing permissions and 149ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat * limitations under the License. 159ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat */ 169ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 179ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <stdlib.h> 189ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <errno.h> 199ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/socket.h> 209ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <sys/stat.h> 219ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <fcntl.h> 229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <netinet/in.h> 239ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <arpa/inet.h> 249ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 259ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#define LOG_TAG "NatController" 269ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include <cutils/log.h> 279ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 289ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat#include "NatController.h" 299ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 309ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatextern "C" int logwrap(int argc, const char **argv, int background); 319ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 329ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatstatic char IPTABLES_PATH[] = "/system/bin/iptables"; 339ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 349ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController::NatController() { 359ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 369ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 379ff78fb7da7158f5bd7c86d89a842691820259cfSan MehatNatController::~NatController() { 389ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 399ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 409ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::runIptablesCmd(const char *cmd) { 419ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char buffer[255]; 429ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 439ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat strncpy(buffer, cmd, sizeof(buffer)-1); 449ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 459ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat const char *args[16]; 469ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char *next = buffer; 479ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char *tmp; 489ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 499ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat args[0] = IPTABLES_PATH; 509ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat args[1] = "--verbose"; 519ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat int i = 2; 529ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 539ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat while ((tmp = strsep(&next, " "))) { 549ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat args[i++] = tmp; 559ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (i == 16) { 569ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat LOGE("iptables argument overflow"); 579ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat errno = E2BIG; 589ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 599ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 609ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 619ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat args[i] = NULL; 629ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 639ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return logwrap(i, args, 0); 649ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 659ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 669ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::setDefaults() { 679ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 689ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-P INPUT ACCEPT")) 699ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 709ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-F INPUT")) 719ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 729ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-P OUTPUT ACCEPT")) 739ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 749ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-F OUTPUT")) 759ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 769ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-P FORWARD DROP")) 779ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 789ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-F FORWARD")) 799ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 809ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd("-t nat -F")) 819ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 829ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return 0; 839ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 849ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 859ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatbool NatController::interfaceExists(const char *iface) { 869ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat // XXX: STOPSHIP - Implement this 879ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return true; 889ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 899ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 909ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat// TODO: Make this work for multiple masqueraded networks 919ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::enableNat(const char *intIface, const char *extIface) { 929ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat char cmd[255]; 939ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 949ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (!interfaceExists(intIface) || !interfaceExists (extIface)) { 959ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat LOGE("Invalid interface specified"); 969ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat errno = ENODEV; 979ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 989ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 999ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1009ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat snprintf(cmd, sizeof(cmd), 1019ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat "-A FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT", 1029ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat extIface, intIface); 1039ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd(cmd)) { 1049ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1059ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1069ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1079ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat snprintf(cmd, sizeof(cmd), "-A FORWARD -i %s -o %s -j ACCEPT", intIface, extIface); 1089ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd(cmd)) { 1099ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1109ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1119ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1129ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface); 1139ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat if (runIptablesCmd(cmd)) { 1149ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return -1; 1159ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat } 1169ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1179ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return 0; 1189ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 1199ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat 1209ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat// TODO: Make this work for multiple masqueraded networks 1219ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehatint NatController::disableNat(const char *intIface, const char *extIface) { 1229ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat return setDefaults(); 1239ff78fb7da7158f5bd7c86d89a842691820259cfSan Mehat} 124