/*
 * Copyright (c) 2019 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 <fcntl.h>
#include <vppinfra/mpcap.h>

/*
 * Unfortunately, the "make test" infra won't work with mapped pcap files.
 * Given enough work [mostly in .py code], one could fix that.
 */

/**
 * @file
 * @brief mapped pcap file support
 *
 * Usage:
 *
 * <code><pre>
 * \#include <vnet/unix/mpcap.h>
 *
 * static mpcap_main_t mpcap = {
 *  .file_name = "/tmp/ip4",
 *  .n_packets_to_capture = 2,
 *  .packet_type = MPCAP_PACKET_TYPE_ip,
 * };
 * </pre></code>
 *
 * To add a buffer:
 *
 *  <code><pre>mpcap_add_buffer (&mpcap, vm, pi0, 128);</pre></code>
 *
 * File will be written after @c n_packets_to_capture
 * or call to mpcap_close
 *
 */

/**
 * @brief Close a mapped pcap file
 * @param mpcap_main_t * pm
 * @return rc - clib_error_t
 *
 */
__clib_export clib_error_t *
mpcap_close (mpcap_main_t * pm)
{
  u64 actual_size = pm->current_va - pm->file_baseva;

  /* Not open? Done... */
  if ((pm->flags & MPCAP_FLAG_INIT_DONE) == 0)
    return 0;

  (void) munmap (pm->file_baseva, pm->max_file_size);
  pm->file_baseva = 0;
  pm->current_va = 0;
  pm->flags &= ~MPCAP_FLAG_INIT_DONE;

  if ((pm->flags & MPCAP_FLAG_WRITE_ENABLE) == 0)
    return 0;

  if (truncate (pm->file_name, actual_size) < 0)
    clib_unix_warning ("setting file size to %llu", actual_size);

  return 0;
}

/**
 * @brief Initialize a mapped pcap file
 * @param mpcap_main_t * pm
 * @return rc - clib_error_t
 *
 */
__clib_export clib_error_t *
mpcap_init (mpcap_main_t * pm)
{
  mpcap_file_header_t *fh;
  u8 zero = 0;
  int fd;

  if (pm->flags & MPCAP_FLAG_INIT_DONE)
    return 0;

  if (!pm->file_name)
    pm->file_name = "/tmp/vppinfra.mpcap";

  if (pm->flags & MPCAP_FLAG_THREAD_SAFE)
    clib_spinlock_init (&pm->lock);

  fd = open (pm->file_name, O_CREAT | O_TRUNC | O_RDWR, 0664);
  if (fd < 0)
    {
      return clib_error_return_unix (0, "failed to create `%s'",
				     pm->file_name);
    }

  if (pm->max_file_size == 0ULL)
    pm->max_file_size = MPCAP_DEFAULT_FILE_SIZE;

  /* Round to a multiple of the page size */
  pm->max_file_size += (u64) clib_mem_get_page_size ();
  pm->max_file_size &= ~(u64) clib_mem_get_page_size ();

  /* Set file size. */
  if (lseek (fd, pm->max_file_size - 1, SEEK_SET) == (off_t) - 1)
    {
      close (fd);
      (void) unlink (pm->file_name);
      return clib_error_return_unix (0, "file size seek");
    }

  if (write (fd, &zero, 1) != 1)
    {
      close (fd);
      (void) unlink (pm->file_name);
      return clib_error_return_unix (0, "file size write");
    }

  pm->file_baseva = mmap (0, pm->max_file_size,
			  PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (pm->file_baseva == (u8 *) MAP_FAILED)
    {
      clib_error_t *error = clib_error_return_unix (0, "mmap");
      close (fd);
      (void) unlink (pm->file_name);
      return error;
    }
  (void) close (fd);

  pm->flags |= MPCAP_FLAG_INIT_DONE | MPCAP_FLAG_WRITE_ENABLE;
  pm->n_packets_captured = 0;
  pm->n_mpcap_data_written = 0;

  /* Initialize file header */
  fh = pm->file_header = (mpcap_file_header_t *) pm->file_baseva;
  pm->current_va = pm->file_baseva + sizeof (*fh);

  fh->magic = 0xa1b2c3d4;
  fh->major_version = 2;
  fh->minor_version = 4;
  fh->time_zone = 0;
  fh->max_packet_size_in_bytes = 1 << 16;
  fh->packet_type = pm->packet_type;
  return 0;
}


/**
 * @brief mmap a mapped pcap file, e.g. to read from another process
 * @param pcap_main_t *pm
 * @return rc - clib_error_t
 */
clib_error_t *
mpcap_map (mpcap_main_t * pm)
{
  clib_error_t *error = 0;
  int fd = -1;
  mpcap_file_header_t *fh;
  mpcap_packet_header_t *ph;
  struct stat statb;
  u64 packets_read = 0;
  u32 min_packet_bytes = ~0;
  u32 max_packet_bytes = 0;

  fd = open (pm->file_name, O_RDONLY);
  if (fd < 0)
    {
      error = clib_error_return_unix (0, "open `%s'", pm->file_name);
      goto done;
    }

  if (fstat (fd, &statb) < 0)
    {
      error = clib_error_return_unix (0, "stat `%s'", pm->file_name);
      goto done;
    }

  if ((statb.st_mode & S_IFREG) == 0)
    {
      error = clib_error_return (0, "'%s' is not a regular file",
				 pm->file_name);
      goto done;
    }

  if (statb.st_size < sizeof (*fh) + sizeof (*ph))
    {
      error = clib_error_return_unix (0, "`%s' is too short", pm->file_name);
      goto done;
    }

  pm->max_file_size = statb.st_size;
  pm->file_baseva = mmap (0, statb.st_size, PROT_READ, MAP_SHARED, fd, 0);
  if (pm->file_baseva == (u8 *) MAP_FAILED)
    {
      error = clib_error_return_unix (0, "mmap");
      goto done;
    }

  pm->flags |= MPCAP_FLAG_INIT_DONE;
  fh = pm->file_header = (mpcap_file_header_t *) pm->file_baseva;
  ph = (mpcap_packet_header_t *) (fh + 1);

  if (fh->magic != 0xa1b2c3d4)
    {
      error = clib_error_return (0, "bad magic `%s'", pm->file_name);
      pm->flags &= ~(MPCAP_FLAG_INIT_DONE);
      (void) munmap (pm->file_baseva, pm->max_file_size);
      goto done;
    }

  /* for the client's convenience, count packets; compute min/max sizes */
  while (ph < (mpcap_packet_header_t *) pm->file_baseva + pm->max_file_size)
    {
      if (ph->n_packet_bytes_stored_in_file == 0)
	break;

      packets_read++;
      min_packet_bytes =
	ph->n_packet_bytes_stored_in_file <
	min_packet_bytes ? ph->n_packet_bytes_stored_in_file :
	min_packet_bytes;
      max_packet_bytes =
	ph->n_packet_bytes_stored_in_file >
	max_packet_bytes ? ph->n_packet_bytes_stored_in_file :
	max_packet_bytes;

      ph = (mpcap_packet_header_t *)
	(((u8 *) (ph)) + sizeof (*ph) + ph->n_packet_bytes_stored_in_file);
    }
  pm->packets_read = packets_read;
  pm->min_packet_bytes = min_packet_bytes;
  pm->max_packet_bytes = max_packet_bytes;

done:
  if (fd >= 0)
    close (fd);
  return error;
}

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