/*
 * Copyright (C) 2009 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.
 */

/* A simple implementation of PPTP Network Server (RFC 2637) which only
 * creates a single session. The following code only handles control packets.
 * Data packets are handled by PPPoPNS driver which can be found in Android
 * kernel tree. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/if_pppopns.h>

#include "mtpd.h"

enum pptp_message {
    SCCRQ = 1,
    SCCRP = 2,
    STOPCCRQ = 3,
    STOPCCRP = 4,
    ECHORQ = 5,
    ECHORP = 6,
    OCRQ = 7,
    OCRP = 8,
    ICRQ = 9,
    ICRP = 10,
    ICCN = 11,
    CCRQ = 12,
    CDN = 13,
    WEN = 14,
    SLI = 15,
    MESSAGE_MAX = 15,
};

static char *messages[] = {
    NULL, "SCCRQ", "SCCRP", "STOPCCRQ", "STOPCCRP", "ECHORQ", "ECHORP",
    "OCRQ", "OCRP", "ICRQ", "ICRP", "ICCN", "CCRQ", "CDN", "WEN", "SLI",
};

static uint8_t lengths[] = {
    0, 156, 156, 16, 16, 16, 20, 168, 32, 220, 24, 28, 16, 148, 40, 24,
};

#define CONTROL_MESSAGE         htons(1)
#define MAGIC_COOKIE            htonl(0x1A2B3C4D)
#define PROTOCOL_VERSION        htons(0x0100)

#define RESULT_OK               1
#define RESULT_ERROR            2

/* Some implementation uses 0 instead of 1, so we allow both of them. */
#define ESTABLISHED(result)     (result <= 1)

#define HEADER_SIZE             8
#define MIN_MESSAGE_SIZE        10

static uint16_t local;
static uint16_t remote;
static uint16_t state;

#define MAX_PACKET_LENGTH       220

/* We define all the fields we used in this structure. Type conversion and byte
 * alignment are solved in one place. Although it looks a little bit ugly, it
 * really makes life easier. */
static struct packet {
    int length;
    int expect;
    union {
        uint8_t buffer[MAX_PACKET_LENGTH];
        struct {
            struct __attribute__((packed)) {
                uint16_t length;
                uint16_t type;
                uint32_t cookie;
            } header;
            uint16_t message;
            uint16_t reserved;
            union {
                struct __attribute__((packed)) {
                    uint16_t protocol_version;
                    uint8_t result;
                    uint8_t error;
                    uint32_t framing;
                    uint32_t bearer;
                    uint16_t channels;
                    uint16_t firmware_revision;
                    char host[64];
                } sccrp, sccrq;
                struct __attribute__((packed)) {
                    uint16_t call;
                    uint16_t serial;
                    uint32_t minimum_speed;
                    uint32_t maximum_speed;
                    uint32_t bearer;
                    uint32_t framing;
                    uint16_t window_size;
                } ocrq;
                struct __attribute__((packed)) {
                    uint16_t call;
                    uint16_t peer;
                    uint8_t result;
                } ocrp, icrp;
                struct __attribute__((packed)) {
                    uint32_t identifier;
                    uint8_t result;
                } echorq, echorp;
                struct __attribute__((packed)) {
                    uint16_t call;
                } icrq, ccrq, cdn;
            };
        } __attribute__((packed));
    } __attribute__((aligned(4)));
} incoming, outgoing;

static void set_message(uint16_t message)
{
    uint16_t length = lengths[message];
    memset(outgoing.buffer, 0, length);
    outgoing.length = length;
    outgoing.header.length = htons(length);
    outgoing.header.type = CONTROL_MESSAGE;
    outgoing.header.cookie = MAGIC_COOKIE;
    outgoing.message = htons(message);
}

static void send_packet()
{
    send(the_socket, outgoing.buffer, outgoing.length, 0);
}

static int recv_packet()
{
    int length;

    /* We are going to read a new message if incoming.expect is 0. */
    if (!incoming.expect) {
        incoming.length = 0;
        incoming.expect = HEADER_SIZE;
    }

    /* The longest message defined in RFC 2637 is 220 bytes, but the protocol
     * itself allows up to 65536 bytes. Therefore we always read a complete
     * message but only keep the first 220 bytes before passing up. */
    length = incoming.expect - incoming.length;
    if (incoming.length >= MAX_PACKET_LENGTH) {
        uint8_t buffer[length];
        length = recv(the_socket, buffer, length, 0);
    } else {
        if (incoming.expect > MAX_PACKET_LENGTH) {
            length = MAX_PACKET_LENGTH - incoming.length;
        }
        length = recv(the_socket, &incoming.buffer[incoming.length], length, 0);
    }
    if (length == -1) {
        if (errno == EINTR) {
            return 0;
        }
        log_print(FATAL, "Recv() %s", strerror(errno));
        exit(NETWORK_ERROR);
    }
    if (length == 0) {
        log_print(DEBUG, "Connection closed");
        log_print(INFO, "Remote server hung up");
        return -REMOTE_REQUESTED;
    }
    incoming.length += length;

    /* If incoming.header is valid, check cookie and update incoming.expect. */
    if (incoming.length == HEADER_SIZE && incoming.expect == HEADER_SIZE) {
        if (incoming.header.cookie != MAGIC_COOKIE) {
            log_print(DEBUG, "Loss of synchronization");
            log_print(ERROR, "Protocol error");
            return -PROTOCOL_ERROR;
        }
        incoming.expect = ntohs(incoming.header.length);
        if (incoming.expect < HEADER_SIZE) {
            log_print(DEBUG, "Invalid message length");
            log_print(ERROR, "Protocol error");
            return -PROTOCOL_ERROR;
        }
    }

    /* Now we have a complete message. Reset incoming.expect. */
    if (incoming.length == incoming.expect) {
        incoming.expect = 0;

        /* Return 1 if it is a control message. */
        if (incoming.header.type == CONTROL_MESSAGE) {
            return 1;
        }
        log_print(DEBUG, "Ignored non-control message (type = %d)",
                  ntohs(incoming.header.type));
    }
    return 0;
}

static int pptp_connect(int argc, char **argv)
{
    if (argc < 2) {
        return -USAGE_ERROR;
    }
    create_socket(AF_UNSPEC, SOCK_STREAM, argv[0], argv[1]);

    log_print(DEBUG, "Sending SCCRQ");
    state = SCCRQ;
    set_message(SCCRQ);
    outgoing.sccrq.protocol_version = PROTOCOL_VERSION;
    outgoing.sccrq.framing = htonl(3);
    outgoing.sccrq.bearer = htonl(3);
    outgoing.sccrq.channels = htons(1);
    strcpy(outgoing.sccrq.host, "anonymous");
    send_packet();
    return 0;
}

static int create_pppox()
{
    int pppox;
    log_print(INFO, "Creating PPPoX socket");
    pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OPNS);

    if (pppox == -1) {
        log_print(FATAL, "Socket() %s", strerror(errno));
        exit(SYSTEM_ERROR);
    } else {
        struct sockaddr_pppopns address = {
            .sa_family = AF_PPPOX,
            .sa_protocol = PX_PROTO_OPNS,
            .tcp_socket = the_socket,
            .local = local,
            .remote = remote,
        };
        if (connect(pppox, (struct sockaddr *)&address, sizeof(address)) != 0) {
            log_print(FATAL, "Connect() %s", strerror(errno));
            exit(SYSTEM_ERROR);
        }
    }
    return pppox;
}

static int pptp_process()
{
    int result = recv_packet();
    if (result <= 0) {
        return result;
    }

    if (incoming.length < MIN_MESSAGE_SIZE) {
        log_print(DEBUG, "Control message too short");
        return 0;
    }
    incoming.message = ntohs(incoming.message);
    if (incoming.message > MESSAGE_MAX || !messages[incoming.message]) {
        log_print(DEBUG, "Received UNKNOWN %d", incoming.message);
        return 0;
    }
    if (incoming.length < lengths[incoming.message]) {
        log_print(DEBUG, "Received %s with invalid length (length = %d)",
                  messages[incoming.message], incoming.length);
        return 0;
    }

    switch(incoming.message) {
        case SCCRP:
            if (state == SCCRQ) {
                if (incoming.sccrp.protocol_version == PROTOCOL_VERSION
                    && ESTABLISHED(incoming.sccrp.result)) {
                    while (!local) {
                        local = random();
                    }
                    log_print(DEBUG, "Received SCCRP -> Sending OCRQ "
                              "(local = %d)", local);
                    log_print(INFO, "Tunnel established");
                    state = OCRQ;
                    set_message(OCRQ);
                    outgoing.ocrq.call = local;
                    outgoing.ocrq.serial = random();
                    outgoing.ocrq.minimum_speed = htonl(1000);
                    outgoing.ocrq.maximum_speed = htonl(100000000);
                    outgoing.ocrq.bearer = htonl(3);
                    outgoing.ocrq.framing = htonl(3);
                    outgoing.ocrq.window_size = htons(8192);
                    send_packet();
                    return 0;
                }
                log_print(DEBUG, "Received SCCRP (result = %d)",
                          incoming.sccrq.result);
                log_print(INFO, "Remote server hung up");
                return -REMOTE_REQUESTED;
            }
            break;

        case OCRP:
            if (state == OCRQ && incoming.ocrp.peer == local) {
                if (ESTABLISHED(incoming.ocrp.result)) {
                    remote = incoming.ocrp.call;
                    log_print(DEBUG, "Received OCRQ (remote = %d)", remote);
                    log_print(INFO, "Session established");
                    state = OCRP;
                    start_pppd(create_pppox());
                    return 0;
                }
                log_print(DEBUG, "Received OCRP (result = %d)",
                          incoming.ocrp.result);
                log_print(INFO, "Remote server hung up");
                return -REMOTE_REQUESTED;
            }
            break;

        case STOPCCRQ:
            log_print(DEBUG, "Received STOPCCRQ");
            log_print(INFO, "Remote server hung up");
            state = STOPCCRQ;
            return -REMOTE_REQUESTED;

        case CCRQ:
            /* According to RFC 2637 page 45, we should never receive CCRQ for
             * outgoing calls. However, some implementation only acts as PNS and
             * always uses CCRQ to clear a call, so here we still handle it. */
            if (state == OCRP && incoming.ccrq.call == remote) {
                log_print(DEBUG, "Received CCRQ (remote = %d)", remote);
                log_print(INFO, "Remote server hung up");
                return -REMOTE_REQUESTED;
            }
            break;

        case CDN:
            if (state == OCRP && incoming.cdn.call == remote) {
                log_print(DEBUG, "Received CDN (remote = %d)", remote);
                log_print(INFO, "Remote server hung up");
                return -REMOTE_REQUESTED;
            }
            break;

        case ECHORQ:
            log_print(DEBUG, "Received ECHORQ -> Sending ECHORP");
            set_message(ECHORP);
            outgoing.echorp.identifier = incoming.echorq.identifier;
            outgoing.echorp.result = RESULT_OK;
            send_packet();
            return 0;

        case WEN:
        case SLI:
            log_print(DEBUG, "Recevied %s", messages[incoming.message]);
            return 0;

        case ICRQ:
            log_print(DEBUG, "Received ICRQ (remote = %d) -> Sending ICRP "
                      "with error", incoming.icrq.call);
            set_message(ICRP);
            outgoing.icrp.peer = incoming.icrq.call;
            outgoing.icrp.result = RESULT_ERROR;
            send_packet();
            return 0;

        case OCRQ:
            log_print(DEBUG, "Received OCRQ (remote = %d) -> Sending OCRP "
                      "with error", incoming.ocrq.call);
            set_message(OCRP);
            outgoing.ocrp.peer = incoming.ocrq.call;
            outgoing.ocrp.result = RESULT_ERROR;
            send_packet();
            return 0;
    }

    /* We reach here if we got an unexpected message. Just log it. */
    log_print(DEBUG, "Received UNEXPECTED %s", messages[incoming.message]);
    return 0;
}

static int pptp_timeout()
{
    return 0;
}

static void pptp_shutdown()
{
    /* Normally we should send STOPCCRQ and wait for STOPCCRP, but this might
     * block for a long time. Here we simply take the shortcut: do nothing. */
}

struct protocol pptp = {
    .name = "pptp",
    .usage = "<server> <port>",
    .connect = pptp_connect,
    .process = pptp_process,
    .timeout = pptp_timeout,
    .shutdown = pptp_shutdown,
};
