/*
 * 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 <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <cutils/properties.h>

#define LOG_TAG "NatController"
#include <cutils/log.h>

#include "NatController.h"
#include "SecondaryTableController.h"

extern "C" int logwrap(int argc, const char **argv, int background);

static char IPTABLES_PATH[] = "/system/bin/iptables";
static char IP_PATH[] = "/system/bin/ip";

NatController::NatController(SecondaryTableController *ctrl) {
    secondaryTableCtrl = ctrl;
    setDefaults();
}

NatController::~NatController() {
}

int NatController::runCmd(const char *path, const char *cmd) {
    char *buffer;
    size_t len = strnlen(cmd, 255);
    int res;

    if (len == 255) {
        LOGE("command too long");
        errno = E2BIG;
        return -1;
    }

    asprintf(&buffer, "%s %s", path, cmd);
    res = system(buffer);
    free(buffer);
    return res;
}

int NatController::setDefaults() {

    if (runCmd(IPTABLES_PATH, "-P INPUT ACCEPT"))
        return -1;
    if (runCmd(IPTABLES_PATH, "-P OUTPUT ACCEPT"))
        return -1;
    if (runCmd(IPTABLES_PATH, "-P FORWARD DROP"))
        return -1;
    if (runCmd(IPTABLES_PATH, "-F FORWARD"))
        return -1;
    if (runCmd(IPTABLES_PATH, "-t nat -F"))
        return -1;

    runCmd(IP_PATH, "rule flush");
    runCmd(IP_PATH, "rule add from all lookup default prio 32767");
    runCmd(IP_PATH, "rule add from all lookup main prio 32766");

    natCount = 0;
    return 0;
}

bool NatController::checkInterface(const char *iface) {
    if (strlen(iface) > MAX_IFACE_LENGTH) return false;
    return true;
}

//  0    1       2       3       4            5
// nat enable intface extface addrcnt nated-ipaddr/prelength
int NatController::enableNat(const int argc, char **argv) {
    char cmd[255];
    int i;
    int addrCount = atoi(argv[4]);
    int ret = 0;
    const char *intIface = argv[2];
    const char *extIface = argv[3];
    int tableNumber;

    if (!checkInterface(intIface) || !checkInterface(extIface)) {
        LOGE("Invalid interface specified");
        errno = ENODEV;
        return -1;
    }

    if (argc < 5 + addrCount) {
        LOGE("Missing Argument");
        errno = EINVAL;
        return -1;
    }

    tableNumber = secondaryTableCtrl->findTableNumber(extIface);
    if (tableNumber != -1) {
        for(i = 0; i < addrCount && ret == 0; i++) {
            snprintf(cmd, sizeof(cmd), "rule add from %s table %d", argv[5+i],
                    tableNumber + BASE_TABLE_NUMBER);
            ret |= runCmd(IP_PATH, cmd);
            if (ret) LOGE("IP rule %s got %d", cmd, ret);

            snprintf(cmd, sizeof(cmd), "route add %s dev %s table %d", argv[5+i], intIface,
                    tableNumber + BASE_TABLE_NUMBER);
            ret |= runCmd(IP_PATH, cmd);
            if (ret) LOGE("IP route %s got %d", cmd, ret);
        }
    }

    if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) {
        if (tableNumber != -1) {
            for (i = 0; i < addrCount; i++) {
                snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface,
                        tableNumber + BASE_TABLE_NUMBER);
                runCmd(IP_PATH, cmd);

                snprintf(cmd, sizeof(cmd), "rule del from %s table %d", argv[5+i],
                        tableNumber + BASE_TABLE_NUMBER);
                runCmd(IP_PATH, cmd);
            }
        }
        LOGE("Error setting forward rules");
        errno = ENODEV;
        return -1;
    }

    natCount++;
    // add this if we are the first added nat
    if (natCount == 1) {
        snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface);
        if (runCmd(IPTABLES_PATH, cmd)) {
            LOGE("Error seting postroute rule: %s", cmd);
            // unwind what's been done, but don't care about success - what more could we do?
            for (i = 0; i < addrCount; i++) {
                snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface,
                        tableNumber + BASE_TABLE_NUMBER);
                runCmd(IP_PATH, cmd);
            }
            setDefaults();
            return -1;
        }
    }

    return 0;
}

int NatController::setForwardRules(bool add, const char *intIface, const char * extIface) {
    char cmd[255];

    snprintf(cmd, sizeof(cmd),
             "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT",
             (add ? "A" : "D"),
             extIface, intIface);
    if (runCmd(IPTABLES_PATH, cmd) && add) {
        return -1;
    }

    snprintf(cmd, sizeof(cmd),
            "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP",
            (add ? "A" : "D"),
            intIface, extIface);
    if (runCmd(IPTABLES_PATH, cmd) && add) {
        // bail on error, but only if adding
        snprintf(cmd, sizeof(cmd),
                "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT",
                (!add ? "A" : "D"),
                extIface, intIface);
        runCmd(IPTABLES_PATH, cmd);
        return -1;
    }

    snprintf(cmd, sizeof(cmd), "-%s FORWARD -i %s -o %s -j ACCEPT", (add ? "A" : "D"),
            intIface, extIface);
    if (runCmd(IPTABLES_PATH, cmd) && add) {
        // unwind what's been done, but don't care about success - what more could we do?
        snprintf(cmd, sizeof(cmd),
                "-%s FORWARD -i %s -o %s -m state --state INVALID -j DROP",
                (!add ? "A" : "D"),
                intIface, extIface);
        runCmd(IPTABLES_PATH, cmd);

        snprintf(cmd, sizeof(cmd),
                 "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT",
                 (!add ? "A" : "D"),
                 extIface, intIface);
        runCmd(IPTABLES_PATH, cmd);
        return -1;
    }
    return 0;
}

// nat disable intface extface
//  0    1       2       3       4            5
// nat enable intface extface addrcnt nated-ipaddr/prelength
int NatController::disableNat(const int argc, char **argv) {
    char cmd[255];
    int i;
    int addrCount = atoi(argv[4]);
    const char *intIface = argv[2];
    const char *extIface = argv[3];
    int tableNumber;

    if (!checkInterface(intIface) || !checkInterface(extIface)) {
        LOGE("Invalid interface specified");
        errno = ENODEV;
        return -1;
    }

    if (argc < 5 + addrCount) {
        LOGE("Missing Argument");
        errno = EINVAL;
        return -1;
    }

    setForwardRules(false, intIface, extIface);

    tableNumber = secondaryTableCtrl->findTableNumber(extIface);
    if (tableNumber != -1) {
        for (i = 0; i < addrCount; i++) {
            snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface,
                    tableNumber + BASE_TABLE_NUMBER);
            // if the interface has gone down these will be gone already and give errors
            // ignore them.
            runCmd(IP_PATH, cmd);
        }
    }

    if (--natCount <= 0) {
        char bootmode[PROPERTY_VALUE_MAX] = {0};
        property_get("ro.bootmode", bootmode, "unknown");
        if (0 != strcmp("bp-tools", bootmode)) {
            // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
            setDefaults();
        }
        natCount = 0;
    }
    return 0;
}
