/*
 * 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 <vnet/lawful-intercept/lawful_intercept.h>

li_main_t li_main;

static clib_error_t *
set_li_command_fn (vlib_main_t * vm,
		   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  li_main_t *lm = &li_main;
  ip4_address_t collector;
  u8 collector_set = 0;
  ip4_address_t src;
  u8 src_set = 0;
  u32 tmp;
  u16 udp_port = 0;
  u8 is_add = 1;
  int i;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "collector %U", unformat_ip4_address, &collector))
	collector_set = 1;
      if (unformat (input, "src %U", unformat_ip4_address, &src))
	src_set = 1;
      else if (unformat (input, "udp-port %d", &tmp))
	udp_port = tmp;
      else if (unformat (input, "del"))
	is_add = 0;
      else
	break;
    }

  if (collector_set == 0)
    return clib_error_return (0, "collector must be set...");
  if (src_set == 0)
    return clib_error_return (0, "src must be set...");
  if (udp_port == 0)
    return clib_error_return (0, "udp-port must be set...");

  if (is_add == 1)
    {
      for (i = 0; i < vec_len (lm->collectors); i++)
	{
	  if (lm->collectors[i].as_u32 == collector.as_u32)
	    {
	      if (lm->ports[i] == udp_port)
		return clib_error_return (
		  0, "collector %U:%d already configured", format_ip4_address,
		  &collector, udp_port);
	      else
		return clib_error_return (
		  0, "collector %U already configured with port %d",
		  format_ip4_address, &collector, (int) (lm->ports[i]));
	    }
	}
      vec_add1 (lm->collectors, collector);
      vec_add1 (lm->ports, udp_port);
      vec_add1 (lm->src_addrs, src);
      return 0;
    }
  else
    {
      for (i = 0; i < vec_len (lm->collectors); i++)
	{
	  if ((lm->collectors[i].as_u32 == collector.as_u32)
	      && lm->ports[i] == udp_port)
	    {
	      vec_delete (lm->collectors, 1, i);
	      vec_delete (lm->ports, 1, i);
	      vec_delete (lm->src_addrs, 1, i);
	      return 0;
	    }
	}
      return clib_error_return (0, "collector %U:%d not configured",
				&collector, udp_port);
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_li_command, static) = {
    .path = "set li",
    .short_help =
    "set li src <ip4-address> collector <ip4-address> udp-port <nnnn>",
    .function = set_li_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
li_init (vlib_main_t * vm)
{
  li_main_t *lm = &li_main;

  lm->vlib_main = vm;
  lm->vnet_main = vnet_get_main ();
  lm->hit_node_index = li_hit_node.index;
  return 0;
}

VLIB_INIT_FUNCTION (li_init);


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