/*
 * 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.
 */
/*
 * pcap.c: libpcap packet capture format
 *
 * Copyright (c) 2008 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <sys/fcntl.h>
#include <vppinfra/pcap.h>

/**
 * @file
 * @brief PCAP function.
 *
 * Usage:
 *
 * <code><pre>
 * \#include <vppinfra/pcap.h>
 *
 * static pcap_main_t pcap = {
 *  .file_name = "/tmp/ip4",
 *  .n_packets_to_capture = 2,
 *  .packet_type = PCAP_PACKET_TYPE_ip,
 * };
 * </pre></code>
 *
 * To add a buffer:
 *
 *  <code><pre>pcap_add_buffer (&pcap, vm, pi0, 128);</pre></code>
 *
 * File will be written after @c n_packets_to_capture or call to pcap_write (&amp;pcap).
 *
*/

/**
 * @brief Close PCAP file
 *
 * @return rc - clib_error_t
 *
 */
clib_error_t *
pcap_close (pcap_main_t * pm)
{
  close (pm->file_descriptor);
  pm->flags &= ~PCAP_MAIN_INIT_DONE;
  pm->file_descriptor = -1;
  return 0;
}

/**
 * @brief Write PCAP file
 *
 * @return rc - clib_error_t
 *
 */
clib_error_t *
pcap_write (pcap_main_t * pm)
{
  clib_error_t *error = 0;

  if (!(pm->flags & PCAP_MAIN_INIT_DONE))
    {
      pcap_file_header_t fh;
      int n;

      if (!pm->file_name)
	pm->file_name = "/tmp/vnet.pcap";

      pm->file_descriptor =
	open (pm->file_name, O_CREAT | O_TRUNC | O_WRONLY, 0664);
      if (pm->file_descriptor < 0)
	{
	  error =
	    clib_error_return_unix (0, "failed to open `%s'", pm->file_name);
	  goto done;
	}

      pm->flags |= PCAP_MAIN_INIT_DONE;
      pm->n_packets_captured = 0;
      pm->n_pcap_data_written = 0;
      clib_spinlock_init (&pm->lock);

      /* Write file header. */
      clib_memset (&fh, 0, 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;
      n = write (pm->file_descriptor, &fh, sizeof (fh));
      if (n != sizeof (fh))
	{
	  if (n < 0)
	    error =
	      clib_error_return_unix (0, "write file header `%s'",
				      pm->file_name);
	  else
	    error =
	      clib_error_return (0, "short write of file header `%s'",
				 pm->file_name);
	  goto done;
	}
    }

  while (vec_len (pm->pcap_data) > pm->n_pcap_data_written)
    {
      int n = vec_len (pm->pcap_data) - pm->n_pcap_data_written;

      n = write (pm->file_descriptor,
		 vec_elt_at_index (pm->pcap_data, pm->n_pcap_data_written),
		 n);

      if (n < 0 && unix_error_is_fatal (errno))
	{
	  error = clib_error_return_unix (0, "write `%s'", pm->file_name);
	  goto done;
	}
      pm->n_pcap_data_written += n;
    }

  if (pm->n_pcap_data_written >= vec_len (pm->pcap_data))
    {
      vec_reset_length (pm->pcap_data);
      pm->n_pcap_data_written = 0;
    }

  if (pm->n_packets_captured >= pm->n_packets_to_capture)
    pcap_close (pm);

done:
  if (error)
    {
      if (pm->file_descriptor >= 0)
	close (pm->file_descriptor);
    }
  return error;
}

/**
 * @brief Read PCAP file
 *
 * @return rc - clib_error_t
 *
 */
clib_error_t *
pcap_read (pcap_main_t * pm)
{
  clib_error_t *error = 0;
  int fd, need_swap, n;
  pcap_file_header_t fh;
  pcap_packet_header_t ph;

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

  if (read (fd, &fh, sizeof (fh)) != sizeof (fh))
    {
      error =
	clib_error_return_unix (0, "read file header `%s'", pm->file_name);
      goto done;
    }

  need_swap = 0;
  if (fh.magic == 0xd4c3b2a1)
    {
      need_swap = 1;
#define _(t,f) fh.f = clib_byte_swap_##t (fh.f);
      foreach_pcap_file_header;
#undef _
    }

  if (fh.magic != 0xa1b2c3d4)
    {
      error = clib_error_return (0, "bad magic `%s'", pm->file_name);
      goto done;
    }

  pm->min_packet_bytes = 0;
  pm->max_packet_bytes = 0;
  while ((n = read (fd, &ph, sizeof (ph))) != 0)
    {
      u8 *data;
      u64 timestamp;
      u32 timestamp_sec;
      u32 timestamp_usec;

      if (need_swap)
	{
#define _(t,f) ph.f = clib_byte_swap_##t (ph.f);
	  foreach_pcap_packet_header;
#undef _
	}

      data = vec_new (u8, ph.n_bytes_in_packet);
      if (read (fd, data, ph.n_packet_bytes_stored_in_file) !=
	  ph.n_packet_bytes_stored_in_file)
	{
	  error = clib_error_return (0, "short read `%s'", pm->file_name);
	  goto done;
	}

      if (vec_len (pm->packets_read) == 0)
	pm->min_packet_bytes = pm->max_packet_bytes = ph.n_bytes_in_packet;
      else
	{
	  pm->min_packet_bytes =
	    clib_min (pm->min_packet_bytes, ph.n_bytes_in_packet);
	  pm->max_packet_bytes =
	    clib_max (pm->max_packet_bytes, ph.n_bytes_in_packet);
	}

      timestamp_sec = ph.time_in_sec;
      timestamp_usec = ph.time_in_usec;
      timestamp = ((u64) timestamp_sec) * 1000000 + (u64) timestamp_usec;
      vec_add1 (pm->packets_read, data);
      vec_add1 (pm->timestamps, timestamp);
    }

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

}

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