/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * 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 <ctype.h>

#include <vnet/vnet.h>
#include <vnet/api_errno.h>
#include <vnet/ip/ip.h>
#include <vnet/interface.h>

#include <vnet/ipsec/ipsec.h>
#include <vnet/ipsec/ikev2.h>
#include <vnet/ipsec/ikev2_priv.h>

/* *INDENT-OFF* */
typedef CLIB_PACKED (struct
		     {
		     u8 nextpayload;
		     u8 flags;
		     u16 length;
		     u8 protocol_id;
		     u8 spi_size;
		     u16 msg_type;
		     u8 payload[0];}) ike_notify_payload_header_t;
/* *INDENT-ON* */

/* *INDENT-OFF* */
typedef CLIB_PACKED (struct
		     {
		     u8 ts_type;
		     u8 protocol_id;
		     u16 selector_len;
		     u16 start_port;
		     u16 end_port;
		     ip4_address_t start_addr;
		     ip4_address_t end_addr;}) ikev2_ts_payload_entry_t;
/* *INDENT-OFF* */

/* *INDENT-OFF* */
typedef CLIB_PACKED (struct
		     {
		     u8 nextpayload;
		     u8 flags;
		     u16 length;
		     u8 num_ts;
		     u8 reserved[3];
		     ikev2_ts_payload_entry_t ts[0];})
  ike_ts_payload_header_t;
/* *INDENT-OFF* */

/* *INDENT-OFF* */
typedef CLIB_PACKED (struct {
  u8 last_or_more;
  u8 reserved;
  u16 proposal_len;
  u8 proposal_num;
  u8 protocol_id;
  u8 spi_size;
  u8 num_transforms; u32 spi[0];
}) ike_sa_proposal_data_t;
/* *INDENT-OFF* */

/* *INDENT-OFF* */
typedef CLIB_PACKED (struct {
  u8 last_or_more;
  u8 reserved;
  u16 transform_len;
  u8 transform_type;
  u8 reserved2;
  u16 transform_id;
  u8 attributes[0];
}) ike_sa_transform_data_t;
/* *INDENT-OFF* */

/* *INDENT-OFF* */
typedef CLIB_PACKED (struct {
  u8 nextpayload;
  u8 flags;
  u16 length;
  u8 protocol_id;
  u8 spi_size;
  u16 num_of_spi;
  u32 spi[0];
}) ike_delete_payload_header_t;
/* *INDENT-OFF* */

static ike_payload_header_t *
ikev2_payload_add_hdr (ikev2_payload_chain_t * c, u8 payload_type, int len)
{
  ike_payload_header_t *hdr =
    (ike_payload_header_t *) & c->data[c->last_hdr_off];
  u8 *tmp;

  if (c->data)
    hdr->nextpayload = payload_type;
  else
    c->first_payload_type = payload_type;

  c->last_hdr_off = vec_len (c->data);
  vec_add2 (c->data, tmp, len);
  hdr = (ike_payload_header_t *) tmp;
  clib_memset (hdr, 0, len);

  hdr->length = clib_host_to_net_u16 (len);

  return hdr;
}

static void
ikev2_payload_add_data (ikev2_payload_chain_t * c, u8 * data)
{
  u16 len;
  ike_payload_header_t *hdr;

  vec_append (c->data, data);
  hdr = (ike_payload_header_t *) & c->data[c->last_hdr_off];
  len = clib_net_to_host_u16 (hdr->length);
  hdr->length = clib_host_to_net_u16 (len + vec_len (data));
}

void
ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type, u8 * data)
{
  ikev2_payload_add_notify_2(c, msg_type, data, 0);
}

void
ikev2_payload_add_notify_2 (ikev2_payload_chain_t * c, u16 msg_type,
                               u8 * data, ikev2_notify_t * notify)
{
  ike_notify_payload_header_t *n;

  n =
    (ike_notify_payload_header_t *) ikev2_payload_add_hdr (c,
                                                           IKEV2_PAYLOAD_NOTIFY,
                                                           sizeof (*n));
  n->msg_type = clib_host_to_net_u16 (msg_type);
  if (notify)
    {
      n->protocol_id = notify->protocol_id;
      if (notify->spi)
        {
          n->spi_size = 4;
        }
    }
  ikev2_payload_add_data (c, data);
}

void
ikev2_payload_add_sa (ikev2_payload_chain_t * c,
		      ikev2_sa_proposal_t * proposals)
{
  ike_payload_header_t *ph;
  ike_sa_proposal_data_t *prop;
  ike_sa_transform_data_t *tr;
  ikev2_sa_proposal_t *p;
  ikev2_sa_transform_t *t;

  u8 *tmp;
  u8 *pr_data = 0;
  u8 *tr_data = 0;

  ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_SA, sizeof (*ph));

  vec_foreach (p, proposals)
  {
    int spi_size = (p->protocol_id == IKEV2_PROTOCOL_ESP) ? 4 : 0;
    pr_data = vec_new (u8, sizeof (ike_sa_proposal_data_t) + spi_size);
    prop = (ike_sa_proposal_data_t *) pr_data;
    prop->last_or_more = proposals - p + 1 < vec_len (proposals) ? 2 : 0;
    prop->protocol_id = p->protocol_id;
    prop->proposal_num = p->proposal_num;
    prop->spi_size = spi_size;
    prop->num_transforms = vec_len (p->transforms);

    if (spi_size)
      prop->spi[0] = clib_host_to_net_u32 (p->spi);

    DBG_PLD ("proposal num %u protocol_id %u last_or_more %u spi_size %u%s%U",
	     prop->proposal_num, prop->protocol_id, prop->last_or_more,
	     prop->spi_size, prop->spi_size ? " spi_data " : "",
	     format_hex_bytes, prop->spi, prop->spi_size);

    vec_foreach (t, p->transforms)
    {
      vec_add2 (tr_data, tmp, sizeof (*tr) + vec_len (t->attrs));
      tr = (ike_sa_transform_data_t *) tmp;
      tr->last_or_more =
	((t - p->transforms) + 1 < vec_len (p->transforms)) ? 3 : 0;
      tr->transform_type = t->type;
      tr->transform_id = clib_host_to_net_u16 (t->transform_id);
      tr->transform_len =
	clib_host_to_net_u16 (sizeof (*tr) + vec_len (t->attrs));

      if (vec_len (t->attrs) > 0)
	clib_memcpy (tr->attributes, t->attrs, vec_len (t->attrs));

      DBG_PLD
	("transform type %U transform_id %u last_or_more %u attr_size %u%s%U",
	 format_ikev2_transform_type, tr->transform_type, t->transform_id,
	 tr->last_or_more, vec_len (t->attrs),
	 vec_len (t->attrs) ? " attrs " : "", format_hex_bytes,
	 tr->attributes, vec_len (t->attrs));
    }

    prop->proposal_len =
      clib_host_to_net_u16 (vec_len (tr_data) + vec_len (pr_data));
    ikev2_payload_add_data (c, pr_data);
    ikev2_payload_add_data (c, tr_data);
    vec_free (pr_data);
    vec_free (tr_data);
  }
}

void
ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group, u8 * dh_data)
{
  ike_ke_payload_header_t *ke;
  ke = (ike_ke_payload_header_t *) ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_KE,
							  sizeof (*ke));

  ke->dh_group = clib_host_to_net_u16 (dh_group);
  ikev2_payload_add_data (c, dh_data);
}

void
ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce)
{
  ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_NONCE,
			 sizeof (ike_payload_header_t));
  ikev2_payload_add_data (c, nonce);
}

void
ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id, u8 type)
{
  ike_id_payload_header_t *idp;
  idp =
    (ike_id_payload_header_t *) ikev2_payload_add_hdr (c, type,
						       sizeof (*idp));

  idp->id_type = id->type;
  ikev2_payload_add_data (c, id->data);
}

void
ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d)
{
  ike_delete_payload_header_t *dp;
  u16 num_of_spi = vec_len (d);
  ikev2_delete_t *d2;
  dp =
    (ike_delete_payload_header_t *) ikev2_payload_add_hdr (c,
							   IKEV2_PAYLOAD_DELETE,
							   sizeof (*dp));

  if (d[0].protocol_id == IKEV2_PROTOCOL_IKE)
    {
      dp->protocol_id = 1;
    }
  else
    {
      dp->protocol_id = d[0].protocol_id;
      dp->spi_size = 4;
      dp->num_of_spi = clib_host_to_net_u16 (num_of_spi);
      vec_foreach (d2, d)
      {
	u8 *data = vec_new (u8, 4);
	u32 spi = clib_host_to_net_u32 (d2->spi);
	clib_memcpy (data, &spi, 4);
	ikev2_payload_add_data (c, data);
	vec_free (data);
      }
    }
}

void
ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth)
{
  ike_auth_payload_header_t *ap;
  ap =
    (ike_auth_payload_header_t *) ikev2_payload_add_hdr (c,
							 IKEV2_PAYLOAD_AUTH,
							 sizeof (*ap));

  ap->auth_method = auth->method;
  ikev2_payload_add_data (c, auth->data);
}

void
ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type)
{
  ike_ts_payload_header_t *tsh;
  ikev2_ts_t *ts2;
  u8 *data = 0, *tmp;

  tsh =
    (ike_ts_payload_header_t *) ikev2_payload_add_hdr (c, type,
						       sizeof (*tsh));
  tsh->num_ts = vec_len (ts);

  vec_foreach (ts2, ts)
  {
    ASSERT (ts2->ts_type == 7);	/*TS_IPV4_ADDR_RANGE */
    ikev2_ts_payload_entry_t *entry;
    vec_add2 (data, tmp, sizeof (*entry));
    entry = (ikev2_ts_payload_entry_t *) tmp;
    entry->ts_type = ts2->ts_type;
    entry->protocol_id = ts2->protocol_id;
    entry->selector_len = clib_host_to_net_u16 (16);
    entry->start_port = clib_host_to_net_u16 (ts2->start_port);
    entry->end_port = clib_host_to_net_u16 (ts2->end_port);
    entry->start_addr.as_u32 = ts2->start_addr.as_u32;
    entry->end_addr.as_u32 = ts2->end_addr.as_u32;
  }

  ikev2_payload_add_data (c, data);
  vec_free (data);
}

void
ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs)
{
  u8 *tmp __attribute__ ((unused));
  u8 pad_len = (vec_len (c->data) / bs + 1) * bs - vec_len (c->data);
  vec_add2 (c->data, tmp, pad_len);
  c->data[vec_len (c->data) - 1] = pad_len - 1;
}

ikev2_sa_proposal_t *
ikev2_parse_sa_payload (ike_payload_header_t * ikep)
{
  ikev2_sa_proposal_t *v = 0;
  ikev2_sa_proposal_t *proposal;
  ikev2_sa_transform_t *transform;

  u32 plen = clib_net_to_host_u16 (ikep->length);

  ike_sa_proposal_data_t *sap;
  int proposal_ptr = 0;

  do
    {
      sap = (ike_sa_proposal_data_t *) & ikep->payload[proposal_ptr];
      int i;
      int transform_ptr;

      DBG_PLD ("proposal num %u len %u last_or_more %u id %u "
	       "spi_size %u num_transforms %u",
	       sap->proposal_num, clib_net_to_host_u16 (sap->proposal_len),
	       sap->last_or_more, sap->protocol_id, sap->spi_size,
	       sap->num_transforms);

      /* IKE proposal should not have SPI */
      if (sap->protocol_id == IKEV2_PROTOCOL_IKE && sap->spi_size != 0)
	goto data_corrupted;

      /* IKE proposal should not have SPI */
      if (sap->protocol_id == IKEV2_PROTOCOL_ESP && sap->spi_size != 4)
	goto data_corrupted;

      transform_ptr = proposal_ptr + sizeof (*sap) + sap->spi_size;

      vec_add2 (v, proposal, 1);
      proposal->proposal_num = sap->proposal_num;
      proposal->protocol_id = sap->protocol_id;

      if (sap->spi_size == 4)
	{
	  proposal->spi = clib_net_to_host_u32 (sap->spi[0]);
	}

      for (i = 0; i < sap->num_transforms; i++)
	{
	  ike_sa_transform_data_t *tr =
	    (ike_sa_transform_data_t *) & ikep->payload[transform_ptr];
	  u16 tlen = clib_net_to_host_u16 (tr->transform_len);

	  if (tlen < sizeof (*tr))
	    goto data_corrupted;

	  vec_add2 (proposal->transforms, transform, 1);

	  transform->type = tr->transform_type;
	  transform->transform_id = clib_net_to_host_u16 (tr->transform_id);
	  if (tlen > sizeof (*tr))
	    vec_add (transform->attrs, tr->attributes, tlen - sizeof (*tr));

	  DBG_PLD
	    ("transform num %u len %u last_or_more %u type %U id %u%s%U", i,
	     tlen, tr->last_or_more, format_ikev2_sa_transform, transform,
	     clib_net_to_host_u16 (tr->transform_id),
	     tlen > sizeof (*tr) ? " attrs " : "", format_hex_bytes,
	     tr->attributes, tlen - sizeof (*tr));

	  transform_ptr += tlen;
	}

      proposal_ptr += clib_net_to_host_u16 (sap->proposal_len);
    }
  while (proposal_ptr < (plen - sizeof (*ikep)) && sap->last_or_more == 2);

  /* data validation */
  if (proposal_ptr != (plen - sizeof (*ikep)) || sap->last_or_more)
    goto data_corrupted;

  return v;

data_corrupted:
  DBG_PLD ("SA payload data corrupted");
  ikev2_sa_free_proposal_vector (&v);
  return 0;
}

ikev2_ts_t *
ikev2_parse_ts_payload (ike_payload_header_t * ikep)
{
  ike_ts_payload_header_t *tsp = (ike_ts_payload_header_t *) ikep;
  ikev2_ts_t *r = 0, *ts;
  u8 i;

  for (i = 0; i < tsp->num_ts; i++)
    {
      if (tsp->ts[i].ts_type != 7)	/*  TS_IPV4_ADDR_RANGE */
	{
	  DBG_PLD ("unsupported TS type received (%u)", tsp->ts[i].ts_type);
	  continue;
	}

      vec_add2 (r, ts, 1);
      ts->ts_type = tsp->ts[i].ts_type;
      ts->protocol_id = tsp->ts[i].protocol_id;
      ts->start_port = tsp->ts[i].start_port;
      ts->end_port = tsp->ts[i].end_port;
      ts->start_addr.as_u32 = tsp->ts[i].start_addr.as_u32;
      ts->end_addr.as_u32 = tsp->ts[i].end_addr.as_u32;
    }
  return r;
}

ikev2_notify_t *
ikev2_parse_notify_payload (ike_payload_header_t * ikep)
{
  ike_notify_payload_header_t *n = (ike_notify_payload_header_t *) ikep;
  u32 plen = clib_net_to_host_u16 (ikep->length);
  ikev2_notify_t *r = 0;
  u32 spi;

  DBG_PLD ("msg_type %U len %u%s%U",
	   format_ikev2_notify_msg_type, clib_net_to_host_u16 (n->msg_type),
	   plen, plen > sizeof (*n) ? " data " : "",
	   format_hex_bytes, n->payload, plen - sizeof (*n));

  r = vec_new (ikev2_notify_t, 1);
  r->msg_type = clib_net_to_host_u16 (n->msg_type);
  r->protocol_id = n->protocol_id;

  if (n->spi_size == 4)
    {
      clib_memcpy (&spi, n->payload, n->spi_size);
      r->spi = clib_net_to_host_u32 (spi);
      DBG_PLD ("spi %lx", r->spi);
    }
  else if (n->spi_size == 0)
    {
      r->spi = 0;
    }
  else
    {
      clib_warning ("invalid SPI Size %d", n->spi_size);
    }

  if (plen > (sizeof (*n) + n->spi_size))
    {
      vec_add (r->data, n->payload + n->spi_size,
	       plen - sizeof (*n) - n->spi_size);
    }

  return r;
}

void
ikev2_parse_vendor_payload (ike_payload_header_t * ikep)
{
  u32 plen = clib_net_to_host_u16 (ikep->length);
  int i;
  int is_string = 1;

  for (i = 0; i < plen - 4; i++)
    if (!isprint (ikep->payload[i]))
      is_string = 0;

  DBG_PLD ("len %u data %s:%U",
	   plen,
	   is_string ? "string" : "hex",
	   is_string ? format_ascii_bytes : format_hex_bytes,
	   ikep->payload, plen - sizeof (*ikep));
}

ikev2_delete_t *
ikev2_parse_delete_payload (ike_payload_header_t * ikep)
{
  ike_delete_payload_header_t *d = (ike_delete_payload_header_t *) ikep;
  u32 plen = clib_net_to_host_u16 (ikep->length);
  ikev2_delete_t *r = 0, *del;
  u16 num_of_spi = clib_net_to_host_u16 (d->num_of_spi);
  u16 i = 0;

  DBG_PLD ("protocol_id %u spi_size %u num_of_spi %u len %u%s%U",
	   d->protocol_id, d->spi_size, num_of_spi,
	   plen, plen > sizeof (d) ? " data " : "",
	   format_hex_bytes, d->spi, plen - sizeof (*d));

  if (d->protocol_id == IKEV2_PROTOCOL_IKE)
    {
      r = vec_new (ikev2_delete_t, 1);
      r->protocol_id = 1;
    }
  else
    {
      r = vec_new (ikev2_delete_t, num_of_spi);
      vec_foreach (del, r)
      {
	del->protocol_id = d->protocol_id;
	del->spi = clib_net_to_host_u32 (d->spi[i++]);
      }
    }

  return r;
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
