/*
 * Copyright (c) 2018 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.
 */
/**
 * @file syslog.c
 * RFC5424 syslog protocol implementation
 */

#include <unistd.h>
#include <vnet/fib/fib_table.h>
#include <vnet/ip/format.h>
#include <vnet/syslog/syslog.h>
#include <vnet/syslog/syslog_udp.h>

#define SYSLOG_VERSION "1"
#define NILVALUE "-"
#define DEFAULT_UDP_PORT 514
#define DEFAULT_MAX_MSG_SIZE 480

#define encode_priority(f, p) ((f << 3) | p)

syslog_main_t syslog_main;

/* format timestamp RFC5424 6.2.3. */
static u8 *
format_syslog_timestamp (u8 * s, va_list * args)
{
  f64 timestamp = va_arg (*args, f64);
  struct tm *tm;
  word msec;

  time_t t = timestamp;
  tm = gmtime (&t);
  msec = 1e6 * (timestamp - t);
  return format (s, "%4d-%02d-%02dT%02d:%02d:%02d.%06dZ", 1900 + tm->tm_year,
		 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min,
		 tm->tm_sec, msec);
}

/* format header RFC5424 6.2. */
static u8 *
format_syslog_header (u8 * s, va_list * args)
{
  syslog_main_t *sm = &syslog_main;
  syslog_header_t *h = va_arg (*args, syslog_header_t *);
  u32 pri = encode_priority (h->facility, h->severity);

  return format (s, "<%d>%s %U %U %s %d %s", pri, SYSLOG_VERSION,
		 format_syslog_timestamp, h->timestamp + sm->time_offset,
		 format_ip4_address, &sm->src_address,
		 h->app_name ? h->app_name : NILVALUE, sm->procid,
		 h->msgid ? h->msgid : NILVALUE);
}

/* format strucured data elements RFC5424 6.3. */
static u8 *
format_syslog_structured_data (u8 * s, va_list * args)
{
  u8 **sds = va_arg (*args, u8 **);
  int i;

  if (vec_len (sds))
    {
      for (i = 0; i < vec_len (sds); i++)
	s = format (s, "[%v]", sds[i]);
    }
  /* if zero structured data elemts field must contain NILVALUE */
  else
    s = format (s, "%s", NILVALUE);

  return s;
}

static u8 *
format_syslog_msg (u8 * s, va_list * args)
{
  syslog_msg_t *m = va_arg (*args, syslog_msg_t *);

  s =
    format (s, "%U %U", format_syslog_header, &m->header,
	    format_syslog_structured_data, m->structured_data);
  /* free-form message is optional */
  if (m->msg)
    s = format (s, " %s", m->msg);

  return s;
}

void
syslog_msg_sd_init (syslog_msg_t * syslog_msg, char *sd_id)
{
  u8 *sd;

  sd = format (0, "%s", sd_id);
  vec_add1 (syslog_msg->structured_data, sd);
  syslog_msg->curr_sd_index++;
}

void
syslog_msg_add_sd_param (syslog_msg_t * syslog_msg, char *name, char *fmt,
			 ...)
{
  va_list va;
  u8 *value;

  va_start (va, fmt);
  value = va_format (0, fmt, &va);
  va_end (va);
  vec_terminate_c_string (value);

  syslog_msg->structured_data[syslog_msg->curr_sd_index] =
    format (syslog_msg->structured_data[syslog_msg->curr_sd_index],
	    " %s=\"%s\"", name, value);
  vec_free (value);
}

void
syslog_msg_add_msg (syslog_msg_t * syslog_msg, char *fmt, ...)
{
  va_list va;
  u8 *msg;

  va_start (va, fmt);
  msg = va_format (0, fmt, &va);
  va_end (va);
  vec_terminate_c_string (msg);

  syslog_msg->msg = msg;
}

void
syslog_msg_init (syslog_msg_t * syslog_msg, syslog_facility_t facility,
		 syslog_severity_t severity, char *app_name, char *msgid)
{
  vlib_main_t *vm = vlib_get_main ();

  syslog_msg->header.facility = facility;
  syslog_msg->header.severity = severity;
  syslog_msg->header.timestamp = vlib_time_now (vm);
  syslog_msg->header.app_name = app_name;
  syslog_msg->header.msgid = msgid;
  syslog_msg->structured_data = 0;
  syslog_msg->curr_sd_index = ~0;
  syslog_msg->msg = 0;
}

int
syslog_msg_send (syslog_msg_t * syslog_msg)
{
  syslog_main_t *sm = &syslog_main;
  vlib_main_t *vm = vlib_get_main ();
  u32 bi, msg_len, *to_next;
  u8 *tmp;
  vlib_buffer_t *b;
  vlib_frame_t *f;
  int i;

  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
    return -1;

  b = vlib_get_buffer (vm, bi);

  /* one message per UDP datagram RFC5426 3.1. */
  tmp = format (0, "%U", format_syslog_msg, syslog_msg);
  msg_len = vec_len (tmp) - (vec_c_string_is_terminated (tmp) ? 1 : 0);
  msg_len = msg_len < sm->max_msg_size ? msg_len : sm->max_msg_size;
  clib_memcpy_fast (b->data, tmp, msg_len);
  b->current_length = msg_len;
  vec_free (tmp);

  vec_free (syslog_msg->msg);
  for (i = 0; i < vec_len (syslog_msg->structured_data); i++)
    vec_free (syslog_msg->structured_data[i]);
  vec_free (syslog_msg->structured_data);

  syslog_add_udp_transport (vm, bi);

  f = vlib_get_frame_to_node (vm, sm->ip4_lookup_node_index);
  to_next = vlib_frame_vector_args (f);
  to_next[0] = bi;
  f->n_vectors = 1;
  vlib_put_frame_to_node (vm, sm->ip4_lookup_node_index, f);

  return 0;
}

static uword
unformat_syslog_facility (unformat_input_t * input, va_list * args)
{
  u32 *r = va_arg (*args, u32 *);

  if (0);
#define _(v,f,s) else if (unformat (input, s)) *r = SYSLOG_FACILITY_##f;
  foreach_syslog_facility
#undef _
    else
    return 0;

  return 1;
}

static uword
unformat_syslog_severity (unformat_input_t * input, va_list * args)
{
  u32 *r = va_arg (*args, u32 *);

  if (0);
#define _(v,f,s) else if (unformat (input, s)) *r = SYSLOG_SEVERITY_##f;
  foreach_syslog_severity
#undef _
    else
    return 0;

  return 1;
}

static u8 *
format_syslog_severity (u8 * s, va_list * args)
{
  u32 i = va_arg (*args, u32);
  u8 *t = 0;

  switch (i)
    {
#define _(v,f,str) case SYSLOG_SEVERITY_##f: t = (u8 *) str; break;
      foreach_syslog_severity
#undef _
    default:
      return format (s, "unknown");
    }

  return format (s, "%s", t);
}

vnet_api_error_t
set_syslog_sender (ip4_address_t * collector, u16 collector_port,
		   ip4_address_t * src, u32 vrf_id, u32 max_msg_size)
{
  syslog_main_t *sm = &syslog_main;
  u32 fib_index;

  if (max_msg_size < DEFAULT_MAX_MSG_SIZE)
    return VNET_API_ERROR_INVALID_VALUE;

  if (collector->as_u32 == 0 || collector_port == 0 || src->as_u32 == 0)
    return VNET_API_ERROR_INVALID_VALUE;

  if (vrf_id == ~0)
    {
      fib_index = ~0;
    }
  else
    {
      fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id);
      if (fib_index == ~0)
	return VNET_API_ERROR_NO_SUCH_FIB;
    }

  sm->fib_index = fib_index;

  sm->collector.as_u32 = collector->as_u32;
  sm->collector_port = (u16) collector_port;
  sm->src_address.as_u32 = src->as_u32;
  sm->max_msg_size = max_msg_size;

  return 0;
}

static clib_error_t *
set_syslog_sender_command_fn (vlib_main_t * vm, unformat_input_t * input,
			      vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  ip4_address_t collector, src;
  u32 collector_port = DEFAULT_UDP_PORT;
  u32 vrf_id = ~0;
  u32 max_msg_size = DEFAULT_MAX_MSG_SIZE;
  clib_error_t *ret = 0;

  collector.as_u32 = 0;
  src.as_u32 = 0;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat
	  (line_input, "collector %U", unformat_ip4_address, &collector))
	;
      else if (unformat (line_input, "port %u", &collector_port))
	;
      else if (unformat (line_input, "src %U", unformat_ip4_address, &src))
	;
      else if (unformat (line_input, "vrf-id %u", &vrf_id))
	;
      else if (unformat (line_input, "max-msg-size %u", &max_msg_size))
	;
      else
	{
	  ret = clib_error_return (0, "Unknown input `%U'",
				   format_unformat_error, line_input);
	  goto done;
	}
    }

  if (collector.as_u32 == 0)
    {
      ret = clib_error_return (0, "collector address required");
      goto done;
    }

  if (src.as_u32 == 0)
    {
      ret = clib_error_return (0, "src address required");
      goto done;
    }

  if (max_msg_size < DEFAULT_MAX_MSG_SIZE)
    {
      ret =
	clib_error_return (0, "too small max-msg-size value, minimum is %u",
			   DEFAULT_MAX_MSG_SIZE);
      goto done;
    }

  vnet_api_error_t rv =
    set_syslog_sender (&collector, collector_port, &src, vrf_id,
		       max_msg_size);

  if (rv)
    ret =
      clib_error_return (0, "set syslog sender failed rv=%d:%U", (int) rv,
			 format_vnet_api_errno, rv);

done:
  unformat_free (line_input);
  return ret;
}

static clib_error_t *
show_syslog_sender_command_fn (vlib_main_t * vm, unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  syslog_main_t *sm = &syslog_main;
  u32 vrf_id = ~0;

  if (sm->fib_index != ~0)
    vrf_id = fib_table_get_table_id (sm->fib_index, FIB_PROTOCOL_IP4);

  if (syslog_is_enabled ())
    vlib_cli_output (vm, "collector %U:%u, src address %U, VRF ID %d, "
		     "max-msg-size %u",
		     format_ip4_address, &sm->collector, sm->collector_port,
		     format_ip4_address, &sm->src_address,
		     vrf_id, sm->max_msg_size);
  else
    vlib_cli_output (vm, "syslog sender is disabled");

  return 0;
}

static clib_error_t *
test_syslog_command_fn (vlib_main_t * vm, unformat_input_t * input,
			vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  syslog_msg_t syslog_msg;
  syslog_facility_t facility;
  syslog_severity_t severity;
  clib_error_t *ret = 0;
  u8 *app_name = 0, *msgid = 0, *sd_id = 0, *param_name = 0, *param_value = 0;

  if (!syslog_is_enabled ())
    return 0;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  if (unformat (line_input, "%U", unformat_syslog_facility, &facility))
    {
      if (unformat (line_input, "%U", unformat_syslog_severity, &severity))
	{
	  if (syslog_severity_filter_block (severity))
	    goto done;

	  if (unformat (line_input, "%s", &app_name))
	    {
	      if (unformat (line_input, "%s", &msgid))
		{
		  syslog_msg_init (&syslog_msg, facility, severity,
				   (char *) app_name, (char *) msgid);
		  while (unformat (line_input, "sd-id %s", &sd_id))
		    {
		      syslog_msg_sd_init (&syslog_msg, (char *) sd_id);
		      while (unformat
			     (line_input, "sd-param %s %s", &param_name,
			      &param_value))
			{
			  syslog_msg_add_sd_param (&syslog_msg,
						   (char *) param_name,
						   (char *) param_value);
			  vec_free (param_name);
			  vec_free (param_value);
			}
		      vec_free (sd_id);
		    }
		  if (unformat_check_input (line_input) !=
		      UNFORMAT_END_OF_INPUT)
		    syslog_msg_add_msg (&syslog_msg, "%U",
					format_unformat_input, line_input);
		  syslog_msg_send (&syslog_msg);
		}
	      else
		{
		  ret =
		    clib_error_return (0, "Unknown input `%U'",
				       format_unformat_error, line_input);
		  goto done;
		}
	    }
	  else
	    {
	      ret =
		clib_error_return (0, "Unknown input `%U'",
				   format_unformat_error, line_input);
	      goto done;
	    }
	}
      else
	{
	  ret =
	    clib_error_return (0, "Unknown input `%U'", format_unformat_error,
			       line_input);
	  goto done;
	}
    }
  else
    {
      ret =
	clib_error_return (0, "Unknown input `%U'", format_unformat_error,
			   line_input);
      goto done;
    }

done:
  vec_free (app_name);
  vec_free (msgid);
  unformat_free (line_input);
  return ret;
}

static clib_error_t *
set_syslog_filter_command_fn (vlib_main_t * vm, unformat_input_t * input,
			      vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  syslog_main_t *sm = &syslog_main;
  clib_error_t *ret = 0;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat
	  (line_input, "severity %U", unformat_syslog_severity,
	   &sm->severity_filter))
	;
      else
	{
	  ret = clib_error_return (0, "Unknown input `%U'",
				   format_unformat_error, line_input);
	  goto done;
	}
    }

done:
  unformat_free (line_input);
  return ret;
}

static clib_error_t *
show_syslog_filter_command_fn (vlib_main_t * vm, unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  syslog_main_t *sm = &syslog_main;

  vlib_cli_output (vm, "severity-filter: %U", format_syslog_severity,
		   sm->severity_filter);

  return 0;
}

/* *INDENT-OFF* */
/*?
 * Set syslog sender configuration.
 *
 * @cliexpar
 * @parblock
 *
 * Example of how to configure syslog sender:
 * @cliexcmd{set syslog sender collector 10.10.10.10 port 514 src 172.16.2.2}
 * @endparblock
?*/
VLIB_CLI_COMMAND (set_syslog_sender_command, static) = {
    .path = "set syslog sender",
    .short_help = "set syslog sender "
                  "collector <ip4-address> [port <port>] "
                  "src <ip4-address> [vrf-id <vrf-id>] "
                  "[max-msg-size <max-msg-size>]",
    .function = set_syslog_sender_command_fn,
};

/*?
 * Show syslog sender configuration.
 *
 * @cliexpar
 * @parblock
 *
 * Example of how to display syslog sender configuration:
 * @cliexstart{show syslog sender}
 * collector 10.10.10.10:514, src address 172.16.2.2, VRF ID 0, max-msg-size 480
 * @cliexend
 * @endparblock
?*/
VLIB_CLI_COMMAND (show_syslog_sender_command, static) = {
    .path = "show syslog sender",
    .short_help = "show syslog sender",
    .function = show_syslog_sender_command_fn,
};

/*?
 * This command generate test syslog message.
 *
 * @cliexpar
 * @parblock
 *
 * Example of how to generate following syslog message
 * '<em><180>1 2018-11-07T11:36:41.231759Z 172.16.1.1 test 10484 testMsg
 * [exampleSDID@32473 eventID="1011" eventSource="App" iut="3"]
 * this is message</em>'
 * @cliexcmd{test syslog local6 warning test testMsg sd-id <!--
 * --> exampleSDID@32473 sd-param eventID 1011 sd-param eventSource App <!--
 * --> sd-param iut 3 this is message}
 * @endparblock
?*/
VLIB_CLI_COMMAND (test_syslog_command, static) = {
    .path = "test syslog",
    .short_help = "test syslog <facility> <severity> <app-name> <msgid> "
                  "[sd-id <sd-id> sd-param <name> <value>] [<message]",
    .function = test_syslog_command_fn,
};

/*?
 * Set syslog severity filter, specified severity and greater match.
 *
 * @cliexpar
 * @parblock
 *
 * Example of how to configure syslog severity filter:
 * @cliexcmd{set syslog filter severity warning}
 * @endparblock
?*/
VLIB_CLI_COMMAND (set_syslog_filter_command, static) = {
    .path = "set syslog filter",
    .short_help = "set syslog filter severity <severity>",
    .function = set_syslog_filter_command_fn,
};

/*?
 * Show syslog severity filter.
 *
 * @cliexpar
 * @parblock
 *
 * Example of how to display syslog severity filter:
 * @cliexstart{show syslog filter}
 * severity-filter: warning
 * @cliexend
 * @endparblock
?*/
VLIB_CLI_COMMAND (show_syslog_filter_command, static) = {
    .path = "show syslog filter",
    .short_help = "show syslog filter",
    .function = show_syslog_filter_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
syslog_init (vlib_main_t * vm)
{
  syslog_main_t *sm = &syslog_main;
  f64 vlib_time_0 = vlib_time_now (vm);
  struct timeval timeval_0;
  vlib_node_t *ip4_lookup_node;

  sm->vnet_main = vnet_get_main ();

  sm->procid = getpid ();
  gettimeofday (&timeval_0, 0);
  sm->time_offset =
    (f64) timeval_0.tv_sec + (((f64) timeval_0.tv_usec) * 1e-6) - vlib_time_0;

  sm->collector.as_u32 = 0;
  sm->src_address.as_u32 = 0;
  sm->collector_port = DEFAULT_UDP_PORT;
  sm->max_msg_size = DEFAULT_MAX_MSG_SIZE;
  sm->fib_index = ~0;
  sm->severity_filter = SYSLOG_SEVERITY_INFORMATIONAL;

  ip4_lookup_node = vlib_get_node_by_name (vm, (u8 *) "ip4-lookup");
  sm->ip4_lookup_node_index = ip4_lookup_node->index;

  return 0;
}

VLIB_INIT_FUNCTION (syslog_init);

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