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