/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * NC-SI (Network Controller Sideband Interface) "echo" model
 *
 * Copyright (C) 2016-2018 IBM Corp.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above
 * copyright notice, this list of conditions and the following
 * disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided
 * with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "slirp.h"

#include "ncsi-pkt.h"

static uint32_t ncsi_calculate_checksum(uint8_t *data, int len)
{
    uint32_t checksum = 0;
    int i;

    /*
     * 32-bit unsigned sum of the NC-SI packet header and NC-SI packet
     * payload interpreted as a series of 16-bit unsigned integer values.
     */
    for (i = 0; i < len; i += 2) {
        checksum += (((uint16_t) data[i]) << 8) + data[i+1];
    }

    checksum = (~checksum + 1);
    return checksum;
}

/* Get Capabilities */
static int ncsi_rsp_handler_gc(struct ncsi_rsp_pkt_hdr *rnh)
{
    struct ncsi_rsp_gc_pkt *rsp = (struct ncsi_rsp_gc_pkt *)rnh;

    rsp->cap = htonl(~0);
    rsp->bc_cap = htonl(~0);
    rsp->mc_cap = htonl(~0);
    rsp->buf_cap = htonl(~0);
    rsp->aen_cap = htonl(~0);
    rsp->vlan_mode = 0xff;
    rsp->uc_cnt = 2;
    return 0;
}

/* Get Link status */
static int ncsi_rsp_handler_gls(struct ncsi_rsp_pkt_hdr *rnh)
{
    struct ncsi_rsp_gls_pkt *rsp = (struct ncsi_rsp_gls_pkt *)rnh;

    rsp->status = htonl(0x1);
    return 0;
}

/* Get Parameters */
static int ncsi_rsp_handler_gp(struct ncsi_rsp_pkt_hdr *rnh)
{
    struct ncsi_rsp_gp_pkt *rsp = (struct ncsi_rsp_gp_pkt *)rnh;

    /* no MAC address filters or VLAN filters on the channel */
    rsp->mac_cnt = 0;
    rsp->mac_enable = 0;
    rsp->vlan_cnt = 0;
    rsp->vlan_enable = 0;

    return 0;
}

static const struct ncsi_rsp_handler {
    unsigned char type;
    int payload;
    int (*handler)(struct ncsi_rsp_pkt_hdr *rnh);
} ncsi_rsp_handlers[] = { { NCSI_PKT_RSP_CIS, 4, NULL },
                          { NCSI_PKT_RSP_SP, 4, NULL },
                          { NCSI_PKT_RSP_DP, 4, NULL },
                          { NCSI_PKT_RSP_EC, 4, NULL },
                          { NCSI_PKT_RSP_DC, 4, NULL },
                          { NCSI_PKT_RSP_RC, 4, NULL },
                          { NCSI_PKT_RSP_ECNT, 4, NULL },
                          { NCSI_PKT_RSP_DCNT, 4, NULL },
                          { NCSI_PKT_RSP_AE, 4, NULL },
                          { NCSI_PKT_RSP_SL, 4, NULL },
                          { NCSI_PKT_RSP_GLS, 16, ncsi_rsp_handler_gls },
                          { NCSI_PKT_RSP_SVF, 4, NULL },
                          { NCSI_PKT_RSP_EV, 4, NULL },
                          { NCSI_PKT_RSP_DV, 4, NULL },
                          { NCSI_PKT_RSP_SMA, 4, NULL },
                          { NCSI_PKT_RSP_EBF, 4, NULL },
                          { NCSI_PKT_RSP_DBF, 4, NULL },
                          { NCSI_PKT_RSP_EGMF, 4, NULL },
                          { NCSI_PKT_RSP_DGMF, 4, NULL },
                          { NCSI_PKT_RSP_SNFC, 4, NULL },
                          { NCSI_PKT_RSP_GVI, 40, NULL },
                          { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
                          { NCSI_PKT_RSP_GP, 40, ncsi_rsp_handler_gp },
                          { NCSI_PKT_RSP_GCPS, 172, NULL },
                          { NCSI_PKT_RSP_GNS, 172, NULL },
                          { NCSI_PKT_RSP_GNPTS, 172, NULL },
                          { NCSI_PKT_RSP_GPS, 8, NULL },
                          { NCSI_PKT_RSP_OEM, 0, NULL },
                          { NCSI_PKT_RSP_PLDM, 0, NULL },
                          { NCSI_PKT_RSP_GPUUID, 20, NULL } };

/*
 * packet format : ncsi header + payload + checksum
 */
#define NCSI_MAX_PAYLOAD 172
#define NCSI_MAX_LEN (sizeof(struct ncsi_pkt_hdr) + NCSI_MAX_PAYLOAD + 4)

void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
{
    const struct ncsi_pkt_hdr *nh =
        (const struct ncsi_pkt_hdr *)(pkt + ETH_HLEN);
    uint8_t ncsi_reply[ETH_HLEN + NCSI_MAX_LEN];
    struct ethhdr *reh = (struct ethhdr *)ncsi_reply;
    struct ncsi_rsp_pkt_hdr *rnh =
        (struct ncsi_rsp_pkt_hdr *)(ncsi_reply + ETH_HLEN);
    const struct ncsi_rsp_handler *handler = NULL;
    int i;
    int ncsi_rsp_len = sizeof(*nh);
    uint32_t checksum;
    uint32_t *pchecksum;

    if (pkt_len < ETH_HLEN + sizeof(struct ncsi_pkt_hdr)) {
        return; /* packet too short */
    }

    memset(ncsi_reply, 0, sizeof(ncsi_reply));

    memset(reh->h_dest, 0xff, ETH_ALEN);
    memset(reh->h_source, 0xff, ETH_ALEN);
    reh->h_proto = htons(ETH_P_NCSI);

    for (i = 0; i < G_N_ELEMENTS(ncsi_rsp_handlers); i++) {
        if (ncsi_rsp_handlers[i].type == nh->type + 0x80) {
            handler = &ncsi_rsp_handlers[i];
            break;
        }
    }

    rnh->common.mc_id = nh->mc_id;
    rnh->common.revision = NCSI_PKT_REVISION;
    rnh->common.id = nh->id;
    rnh->common.type = nh->type + 0x80;
    rnh->common.channel = nh->channel;

    if (handler) {
        rnh->common.length = htons(handler->payload);
        rnh->code = htons(NCSI_PKT_RSP_C_COMPLETED);
        rnh->reason = htons(NCSI_PKT_RSP_R_NO_ERROR);

        if (handler->handler) {
            /* TODO: handle errors */
            handler->handler(rnh);
        }
        ncsi_rsp_len += handler->payload;
    } else {
        rnh->common.length = 0;
        rnh->code = htons(NCSI_PKT_RSP_C_UNAVAILABLE);
        rnh->reason = htons(NCSI_PKT_RSP_R_UNKNOWN);
    }

    /* Add the optional checksum at the end of the frame. */
    checksum = ncsi_calculate_checksum((uint8_t *)rnh, ncsi_rsp_len);
    pchecksum = (uint32_t *)((void *)rnh + ncsi_rsp_len);
    *pchecksum = htonl(checksum);
    ncsi_rsp_len += 4;

    slirp_send_packet_all(slirp, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
}
