/*
 * b_sample_ext.c -- Sample program using the extended blocking API
 *
 * Copyright (C) 2005, Ranch Networks, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * Author : Srivatsa Chivukula <srivatsa@ranchnetworks.com>
 *
 */

/*
 * The flow of the program is as follows:
 *  1. Initialize the library.
 *  2. Open the SIMCO communication channel to the middlebox.
 *  3. Do SIMCO session establish (SE).
 *  4. Do SIMCO session authenticate (SA).
 *  5. Do firewall rule create (FRC) request.
 *  6. Do firewall rule status (FRS) for the rule set in step 6.
 *  7. Do firewall rule list (FRL) for all the rules set on the middlebox.
 *  8. Do session terminate request on communication (ST) channel.
 *  9. Cleanup and exit.
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

#include "simco_defs_ext.h"
#include "simco_client_ext.h"

static char *cert = "/home/srivatsa/certificate/server.pem";

int main(int argc, char** argv)
{
  int con = -1;
  char *host = "192.1.1.59";
  int ret, temp = 0;

  simcoExtPacket_t sepacket;

  int *rules, nrules, i;

  char *login = "root";
  char *password = "ranchroot";

  if (argc >= 3)
    {
      login = argv[1];
      password = argv[2];
    }

  /* Initialize the library */
  if (!mc_init(cert))
    {
      return -1;
    }

  /* Get the SIMCO communication channel */
  if ((con = mc_comm_connect(host)) == -1)
    {
      goto end;
    }

  /* SIMCO session establish */
  if ((ret = simco_se_b(con)) != 0)
    {
      mc_comm_disconnect(con);
      goto end;
    }

  /* session authenticate */
  if ((ret = simco_sa_b(con, login, password)) != 0)
    {
      printf("Could not authenticate with Login: %s Passsword: %s \n", login, password);
      simco_st_b(con);
      mc_comm_disconnect(con);
      goto end;
    }

  /* FRC */
  memset((void*)&sepacket, 0, sizeof(simcoExtPacket_t));
  sepacket.action = FWC_ALW_FLG;
  sepacket.syslog = FWC_SSG_FLG;
  sepacket.srcZoneId = 1;
  sepacket.protocol = 6; /* TCP */
  sepacket.tos = 4;
  // FW_FLG_SET_IPFRAG(sepacket.ipfrag_selfdst);
  FW_FLG_SET_DSTSELF(sepacket.ipfrag_selfdst);
  IP_OPT_SET_LSRR(sepacket.ip_options);
  IP_OPT_NSET_RR(sepacket.ip_options);
  TCP_FLG_SET_SYN(sepacket.tcp_flags_options);
  TCP_OPT_NSET_TS(sepacket.tcp_flags_options);
  sepacket.packet_rate = 30000;
  sepacket.internal_ip_mask = 24;
  strcpy(sepacket.internal_ip, "192.1.1.0");
  sepacket.internal_port = 8;
  sepacket.internal_port_range = 8;
  strcpy(sepacket.copy_forward_ip, "192.1.1.1");
  sepacket.lifetime = 60;
  if ((ret = simco_frc_b(con, &sepacket)) != 0)
    {
      fprintf(stderr, "Error - simco_frc_b: 0x%x\n", ret);
      simco_st_b(con);
      mc_comm_disconnect(con);
      goto end;
    }
  fprintf(stderr, "RuleId:%d Status: %d\n", sepacket.ruleId, sepacket.status);
  
  temp = sepacket.ruleId;

  /* FRS */
  memset((void*)&sepacket, 0, sizeof(simcoExtPacket_t));
  sepacket.ruleId = temp;
  if ((ret = simco_frs_b(con, &sepacket)) != 0)
    {
      fprintf(stderr, "Error - simco_frs_b: 0x%x\n", ret);
      simco_st_b(con);
      mc_comm_disconnect(con);
      goto end;
    }
  fprintf(stderr, "RuleId:%d Internal_IP: %s Internal_mask: %d Status: %d\n", sepacket.ruleId, sepacket.internal_ip, sepacket.internal_ip_mask, sepacket.status);

  /* FRL */
  nrules = 128;
  rules = (int *)malloc(nrules*sizeof(int));
  if ((ret = simco_frl_b(con, &rules, &nrules)) != 0)
    {
      fprintf(stderr, "Error - simco_frl_b: 0x%x\n", ret);
      simco_st_b(con);
      mc_comm_disconnect(con);
      free(rules);
      goto end;
    }
  printf("Number of rules returned: %d\n", nrules);
  for (i = 0; i < nrules; i++)
    printf("Rule Id: %d\n", rules[i]);
  free(rules);

  simco_st_b(con);
  mc_comm_disconnect(con);

 end:

  mc_close();
  return ret;
}

