/*
 * Copyright (C) 2011 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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include <poll.h>
#include <unistd.h>

#include "config.h"
#include "gcmalloc.h"
#include "schedule.h"
#include "plog.h"

#ifdef ANDROID_CHANGES

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/if.h>
#include <linux/if_tun.h>

#include <android/log.h>
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>

static void notify_death()
{
    creat("/data/misc/vpn/abort", 0);
}

static int android_get_control_and_arguments(int *argc, char ***argv)
{
    static char *args[32];
    int control;
    int i;

    atexit(notify_death);

    if ((i = android_get_control_socket("racoon")) == -1) {
        return -1;
    }
    do_plog(LLV_DEBUG, "Waiting for control socket");
    if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
        do_plog(LLV_ERROR, "Cannot get control socket");
        exit(1);
    }
    close(i);
    fcntl(control, F_SETFD, FD_CLOEXEC);

    args[0] = (*argv)[0];
    for (i = 1; i < 32; ++i) {
        unsigned char bytes[2];
        if (recv(control, &bytes[0], 1, 0) != 1 ||
                recv(control, &bytes[1], 1, 0) != 1) {
            do_plog(LLV_ERROR, "Cannot get argument length");
            exit(1);
        } else {
            int length = bytes[0] << 8 | bytes[1];
            int offset = 0;

            if (length == 0xFFFF) {
                break;
            }
            args[i] = malloc(length + 1);
            while (offset < length) {
                int n = recv(control, &args[i][offset], length - offset, 0);
                if (n > 0) {
                    offset += n;
                } else {
                    do_plog(LLV_ERROR, "Cannot get argument value");
                    exit(1);
                }
            }
            args[i][length] = 0;
        }
    }
    do_plog(LLV_DEBUG, "Received %d arguments", i - 1);

    *argc = i;
    *argv = args;
    return control;
}

const char *android_hook(char **envp)
{
    struct ifreq ifr = {.ifr_flags = IFF_TUN};
    int tun = open("/dev/tun", 0);

    /* Android does not support INTERNAL_WINS4_LIST, so we just use it. */
    while (*envp && strncmp(*envp, "INTERNAL_WINS4_LIST=", 20)) {
        ++envp;
    }
    if (!*envp) {
        do_plog(LLV_ERROR, "Cannot find environment variable\n");
        exit(1);
    }
    if (ioctl(tun, TUNSETIFF, &ifr)) {
        do_plog(LLV_ERROR, "Cannot allocate TUN: %s\n", strerror(errno));
        exit(1);
    }
    sprintf(*envp, "INTERFACE=%s", ifr.ifr_name);
    return "/etc/ppp/ip-up-vpn";
}

#endif

extern void setup(int argc, char **argv);
extern void shutdown_session();

static int monitors;
static void (*callbacks[10])(int fd);
static struct pollfd pollfds[10];

char *pname;

static void terminate(int signal)
{
    exit(1);
}

static void terminated()
{
    do_plog(LLV_INFO, "Bye\n");
}

void monitor_fd(int fd, void (*callback)(int))
{
    if (fd < 0 || monitors == 10) {
        do_plog(LLV_ERROR, "Cannot monitor fd");
        exit(1);
    }
    callbacks[monitors] = callback;
    pollfds[monitors].fd = fd;
    pollfds[monitors].events = callback ? POLLIN : 0;
    ++monitors;
}

int main(int argc, char **argv)
{
#ifdef ANDROID_CHANGES
    int control = android_get_control_and_arguments(&argc, &argv);

    if (control != -1) {
        pname = "%p";
        monitor_fd(control, NULL);
    }
#endif

    do_plog(LLV_INFO, "ipsec-tools 0.7.3 (http://ipsec-tools.sf.net)\n");

    signal(SIGHUP, terminate);
    signal(SIGINT, terminate);
    signal(SIGTERM, terminate);
    signal(SIGPIPE, SIG_IGN);
    atexit(terminated);

    setup(argc, argv);

#ifdef ANDROID_CHANGES
    shutdown(control, SHUT_WR);
#endif

    while (1) {
        struct timeval *tv = schedular();
        int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1;

        if (poll(pollfds, monitors, timeout) > 0) {
            int i;
            for (i = 0; i < monitors; ++i) {
                if (pollfds[i].revents & POLLHUP) {
                    do_plog(LLV_INFO, "Connection is closed\n", pollfds[i].fd);
                    shutdown_session();

                    /* Wait for few seconds to consume late messages. */
                    sleep(5);
                    exit(1);
                }
                if (pollfds[i].revents & POLLIN) {
                    callbacks[i](pollfds[i].fd);
                }
            }
        }
    }

    return 0;
}

/* plog.h */

void do_plog(int level, char *format, ...)
{
    if (level >= 0 && level <= 5) {
#ifdef ANDROID_CHANGES
        static int levels[6] = {
            ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO,
            ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE
        };
        va_list ap;
        va_start(ap, format);
        __android_log_vprint(levels[level], "racoon", format, ap);
        va_end(ap);
#else
        static char *levels = "EWNIDV";
        fprintf(stderr, "%c: ", levels[level]);
        va_list ap;
        va_start(ap, format);
        vfprintf(stderr, format, ap);
        va_end(ap);
#endif
    }
}

char *binsanitize(char *data, size_t length)
{
    char *output = racoon_malloc(length + 1);
    if (output) {
        size_t i;
        for (i = 0; i < length; ++i) {
            output[i] = (data[i] < ' ' || data[i] > '~') ? '?' : data[i];
        }
        output[length] = '\0';
    }
    return output;
}
