/*
 * SLIRP stateless DHCPv6
 *
 * We only support stateless DHCPv6, e.g. for network booting.
 * See RFC 3315, RFC 3736, RFC 3646 and RFC 5970 for details.
 *
 * Copyright 2016 Thomas Huth, Red Hat Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "slirp.h"
#include "dhcpv6.h"

/* DHCPv6 message types */
#define MSGTYPE_REPLY 7
#define MSGTYPE_INFO_REQUEST 11

/* DHCPv6 option types */
#define OPTION_CLIENTID 1
#define OPTION_IAADDR 5
#define OPTION_ORO 6
#define OPTION_DNS_SERVERS 23
#define OPTION_BOOTFILE_URL 59

struct requested_infos {
    uint8_t *client_id;
    int client_id_len;
    bool want_dns;
    bool want_boot_url;
};

/**
 * Analyze the info request message sent by the client to see what data it
 * provided and what it wants to have. The information is gathered in the
 * "requested_infos" struct. Note that client_id (if provided) points into
 * the odata region, thus the caller must keep odata valid as long as it
 * needs to access the requested_infos struct.
 */
static int dhcpv6_parse_info_request(uint8_t *odata, int olen,
                                     struct requested_infos *ri)
{
    int i, req_opt;

    while (olen > 4) {
        /* Parse one option */
        int option = odata[0] << 8 | odata[1];
        int len = odata[2] << 8 | odata[3];

        if (len + 4 > olen) {
            qemu_log_mask(LOG_GUEST_ERROR, "Guest sent bad DHCPv6 packet!\n");
            return -E2BIG;
        }

        switch (option) {
        case OPTION_IAADDR:
            /* According to RFC3315, we must discard requests with IA option */
            return -EINVAL;
        case OPTION_CLIENTID:
            if (len > 256) {
                /* Avoid very long IDs which could cause problems later */
                return -E2BIG;
            }
            ri->client_id = odata + 4;
            ri->client_id_len = len;
            break;
        case OPTION_ORO: /* Option request option */
            if (len & 1) {
                return -EINVAL;
            }
            /* Check which options the client wants to have */
            for (i = 0; i < len; i += 2) {
                req_opt = odata[4 + i] << 8 | odata[4 + i + 1];
                switch (req_opt) {
                case OPTION_DNS_SERVERS:
                    ri->want_dns = true;
                    break;
                case OPTION_BOOTFILE_URL:
                    ri->want_boot_url = true;
                    break;
                default:
                    DEBUG_MISC((dfd, "dhcpv6: Unsupported option request %d\n",
                                req_opt));
                }
            }
            break;
        default:
            DEBUG_MISC((dfd, "dhcpv6 info req: Unsupported option %d, len=%d\n",
                        option, len));
        }

        odata += len + 4;
        olen -= len + 4;
    }

    return 0;
}


/**
 * Handle information request messages
 */
static void dhcpv6_info_request(Slirp *slirp, struct sockaddr_in6 *srcsas,
                                uint32_t xid, uint8_t *odata, int olen)
{
    struct requested_infos ri = { NULL };
    struct sockaddr_in6 sa6, da6;
    struct mbuf *m;
    uint8_t *resp;

    if (dhcpv6_parse_info_request(odata, olen, &ri) < 0) {
        return;
    }

    m = m_get(slirp);
    if (!m) {
        return;
    }
    memset(m->m_data, 0, m->m_size);
    m->m_data += IF_MAXLINKHDR;
    resp = (uint8_t *)m->m_data + sizeof(struct ip6) + sizeof(struct udphdr);

    /* Fill in response */
    *resp++ = MSGTYPE_REPLY;
    *resp++ = (uint8_t)(xid >> 16);
    *resp++ = (uint8_t)(xid >> 8);
    *resp++ = (uint8_t)xid;

    if (ri.client_id) {
        *resp++ = OPTION_CLIENTID >> 8; /* option-code high byte */
        *resp++ = OPTION_CLIENTID; /* option-code low byte */
        *resp++ = ri.client_id_len >> 8; /* option-len high byte */
        *resp++ = ri.client_id_len; /* option-len low byte */
        memcpy(resp, ri.client_id, ri.client_id_len);
        resp += ri.client_id_len;
    }
    if (ri.want_dns) {
        *resp++ = OPTION_DNS_SERVERS >> 8; /* option-code high byte */
        *resp++ = OPTION_DNS_SERVERS; /* option-code low byte */
        *resp++ = 0; /* option-len high byte */
        *resp++ = 16; /* option-len low byte */
        memcpy(resp, &slirp->vnameserver_addr6, 16);
        resp += 16;
    }
    if (ri.want_boot_url) {
        uint8_t *sa = slirp->vhost_addr6.s6_addr;
        int slen, smaxlen;

        *resp++ = OPTION_BOOTFILE_URL >> 8; /* option-code high byte */
        *resp++ = OPTION_BOOTFILE_URL; /* option-code low byte */
        smaxlen = (uint8_t *)m->m_data + IF_MTU - (resp + 2);
        slen = snprintf((char *)resp + 2, smaxlen,
                        "tftp://[%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
                        "%02x%02x:%02x%02x:%02x%02x:%02x%02x]/%s",
                        sa[0], sa[1], sa[2], sa[3], sa[4], sa[5], sa[6], sa[7],
                        sa[8], sa[9], sa[10], sa[11], sa[12], sa[13], sa[14],
                        sa[15], slirp->bootp_filename);
        slen = MIN(slen, smaxlen);
        *resp++ = slen >> 8; /* option-len high byte */
        *resp++ = slen; /* option-len low byte */
        resp += slen;
    }

    sa6.sin6_addr = slirp->vhost_addr6;
    sa6.sin6_port = DHCPV6_SERVER_PORT;
    da6.sin6_addr = srcsas->sin6_addr;
    da6.sin6_port = srcsas->sin6_port;
    m->m_data += sizeof(struct ip6) + sizeof(struct udphdr);
    m->m_len = resp - (uint8_t *)m->m_data;
    udp6_output(NULL, m, &sa6, &da6);
}

/**
 * Handle DHCPv6 messages sent by the client
 */
void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m)
{
    uint8_t *data = (uint8_t *)m->m_data + sizeof(struct udphdr);
    int data_len = m->m_len - sizeof(struct udphdr);
    uint32_t xid;

    if (data_len < 4) {
        return;
    }

    xid = ntohl(*(uint32_t *)data) & 0xffffff;

    switch (data[0]) {
    case MSGTYPE_INFO_REQUEST:
        dhcpv6_info_request(m->slirp, srcsas, xid, &data[4], data_len - 4);
        break;
    default:
        DEBUG_MISC(
            (dfd, "dhcpv6_input: Unsupported message type 0x%x\n", data[0]));
    }
}
