/*
 * 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;
  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:
 */
