/*
 *
 * (C) 2005-12 - Luca Deri <deri@ntop.org>
 *               Alfredo Cardigliano <cardigliano@ntop.org>
 *
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * VLAN support courtesy of Vincent Magnin <vincent.magnin@ci.unil.ch>
 *
 */

#define _GNU_SOURCE
#include <signal.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/poll.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <net/ethernet.h>     /* the L2 protocols */
#include <sys/time.h>
#include <time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <inttypes.h>

#include "pfring.h"
#include "pfutils.c"

#define ALARM_SLEEP             1

pfring_stat pfringStats;
char *in_dev = NULL, *out_dev = NULL;
int in_ifindex, out_ifindex;
u_int8_t wait_for_packet = 1, do_shutdown = 0;
static struct timeval startTime;
int mode = 0;
int bidirectional = 0;
int cluster_id = -1;
int flush = 0;
int print_interface_stats = 0;
pfring *pd1, *pd2, *pdb1, *pdb2;
pfring_dna_bouncer *bouncer_handle = NULL, *bouncer_handle2;
u_int numCPU;
int bind_core[2];
struct dir_info {
  u_int64_t __padding __attribute__((__aligned__(64)));
  u_int64_t numPkts;
  u_int64_t numBytes __attribute__((__aligned__(64)));
};
struct dir_info dir_stats[2];

u_int8_t handle_ts_card = 0;

/* ******************************** */

void print_stats() {
  struct timeval endTime;
  double deltaMillisec;
  static u_int8_t print_all;
  static u_int64_t lastPkts = 0;
  static u_int64_t lastBytes = 0;
  double diff, bytesDiff;
  static struct timeval lastTime;
  char buf1[64], buf2[64], buf3[64];
  unsigned long long nBytes = 0, nPkts = 0;
  double thpt;

  if(startTime.tv_sec == 0) {
    gettimeofday(&startTime, NULL);
    print_all = 0;
  } else
    print_all = 1;

  gettimeofday(&endTime, NULL);
  deltaMillisec = delta_time(&endTime, &startTime);

  nBytes = dir_stats[0].numBytes + dir_stats[1].numBytes;
  nPkts  = dir_stats[0].numPkts + dir_stats[1].numPkts;

  {
    thpt = ((double)8*nBytes)/(deltaMillisec*1000);

    fprintf(stderr, "---\nAbsolute Stats: %s pkts - %s bytes", 
	    pfring_format_numbers((double)nPkts, buf1, sizeof(buf1), 0),
	    pfring_format_numbers((double)nBytes, buf2, sizeof(buf2), 0));

    if(print_all)
      fprintf(stderr, " [%s pkt/sec - %s Mbit/sec]\n",
	      pfring_format_numbers((double)(nPkts*1000)/deltaMillisec, buf1, sizeof(buf1), 1),
	      pfring_format_numbers(thpt, buf2, sizeof(buf2), 1));
    else
      fprintf(stderr, "\n");

    if (print_interface_stats) {
      pfring_stat if_stats;

      if (pfring_stats(pd1, &if_stats) >= 0)
        fprintf(stderr, "                %s RX %" PRIu64 " pkts Dropped %" PRIu64 " pkts (%.1f %%)\n", 
                mode == 1 ? "Consumer Queue" : pd1->device_name, if_stats.recv, if_stats.drop,
		if_stats.recv == 0 ? 0 : ((double)(if_stats.drop*100)/(double)(if_stats.recv + if_stats.drop)));

      if (mode == 0 && bidirectional) {
        if (pfring_stats(bidirectional == 2 ? pdb1 : pd2, &if_stats) >= 0)
          fprintf(stderr, "                %s RX %" PRIu64 " pkts Dropped %" PRIu64 " pkts (%.1f %%)\n", 
                  (bidirectional == 2 ? pdb1 : pd2)->device_name, if_stats.recv, if_stats.drop,
		  if_stats.recv == 0 ? 0 : ((double)(if_stats.drop*100)/(double)(if_stats.recv + if_stats.drop)));
      }
    }

    if(print_all && (lastTime.tv_sec > 0)) {
      deltaMillisec = delta_time(&endTime, &lastTime);
      diff = nPkts-lastPkts;
      bytesDiff = nBytes - lastBytes;
      bytesDiff /= (1000*1000*1000)/8;

      fprintf(stderr, "Actual Stats: %llu pkts [%s ms][%s pps/%s Gbps]\n",
	      (long long unsigned int)diff,
	      pfring_format_numbers(deltaMillisec, buf1, sizeof(buf1), 1),
	      pfring_format_numbers(((double)diff/(double)(deltaMillisec/1000)),  buf2, sizeof(buf2), 1),
	      pfring_format_numbers(((double)bytesDiff/(double)(deltaMillisec/1000)),  buf3, sizeof(buf3), 1)
	      );
    }

    lastPkts = nPkts, lastBytes = nBytes;
  }

  lastTime.tv_sec = endTime.tv_sec, lastTime.tv_usec = endTime.tv_usec;
}

/* ******************************** */

void my_sigalarm(int sig) {
  if(do_shutdown) {
    exit(0);
  }

  print_stats();
  alarm(ALARM_SLEEP);
  signal(SIGALRM, my_sigalarm);
}

/* ******************************** */

void sigproc(int sig) {
  static int called = 0;

  fprintf(stderr, "Leaving...\n");
  if(called) return; else called = 1;
  do_shutdown = 1;

  switch (mode) {
  case 0: 
    pfring_dna_bouncer_breakloop(bouncer_handle);
    if (bidirectional == 2)
      pfring_dna_bouncer_breakloop(bouncer_handle2);
  break;
  case 1:
  case 2: 
    pfring_breakloop(pd1);
  break;
  }
}

/* *************************************** */

void printHelp(void) {
 printf("pfdnabounce - (C) 2011-12 ntop.org\n");
 printf("\nForward traffic from -a -> -b device using DNA\n\n");

  printf("pfdnabounce [-v] [-a] -i in_dev\n");
  printf("-h              Print this help\n");
  printf("-i <device>     Device name (RX)\n");
  printf("-o <device>     Device name (TX)\n");
  printf("-m <mode>       Specifies the library support to use\n"
	 "                0 - DNA Bouncer (default)\n"
	 "                1 - DNA Cluster (use -c <id>)\n"
	 "                2 - Standard DNA\n");
  printf("-c <id>         DNA Cluster id\n");
  printf("-b <mode>       Bridge mode (forward in both directions):\n"
         "                0 - disabled (default)\n"
         "                1 - single thread (DNA Cluster and Bouncer only)\n"
         "                2 - two threads, one per direction (DNA Bouncer only)\n");
  printf("-f              Flush packets immediately (do not use watermarks)\n");
  printf("-g <core id>    Bind this app to a core (with -b 2 use <core id>:<core id>)\n");
  printf("-a              Active packet wait\n");
  printf("-p              Print per-interface absolute stats\n");
  exit(0);
}

/* *************************************** */

int dummyProcessPacketZero(u_int32_t *pkt_len, u_char *pkt, const u_char *user_bytes, u_int8_t direction) {
  struct dir_info *di;
  u_int32_t len = *pkt_len;

#ifdef DEBUG
    int i = 0;
    for(i=0; i<32; i++) printf("%02X ", pkt[i]);
    printf("\n");
#endif

  if(unlikely(handle_ts_card)) {
    u_int8_t ts_len = 0;
    switch(pkt[len-1]) {
      case 0xC3: ts_len = 9; break;
      case 0xC2: ts_len = 5; break;
    }
    // printf("ts_len: %u\n", ts_len);
    len -= ts_len;
  }

  if (bidirectional == 2)
    di = (struct dir_info *) user_bytes;
  else
    di = &dir_stats[direction];

#if 0 /* change something inside the packet */
  {
    u_int16_t *nshort2 = (u_int16_t *) (&pkt[16]);
    u_int16_t *nshort3 = (u_int16_t *) (&pkt[18]);
    u_int16_t newhshort3 = ntohs(*nshort2) + 1;
    //printf(" [>] Changing 0x%04X 0x%04X\n", ntohs(*nshort2), ntohs(*nshort3));
    *nshort2 = *nshort3;
    *nshort3 = htons(newhshort3);
    //printf("to 0x%04X 0x%04X\n", ntohs(*nshort2), ntohs(*nshort3));
  }
#endif

  di->numPkts++;
  di->numBytes += len + 24 /* 8 Preamble + 4 CRC + 12 IFG */;

  *pkt_len = len;
  return DNA_BOUNCER_PASS;
}

/* *************************************** */

void packetConsumerLoopZeroCluster() { 
  struct pfring_pkthdr h;
  int tx_ifindex;
  pfring_pkt_buff *pkt_handle = NULL;

  memset(&h, 0, sizeof(h));

  if ((pkt_handle = pfring_alloc_pkt_buff(pd1)) == NULL) {
    printf("Error allocating pkt buff\n");
    return;
  }

  while (!do_shutdown) {
    if (pfring_recv_pkt_buff(pd1, pkt_handle, &h, wait_for_packet) > 0) {

      if (bidirectional && h.extended_hdr.if_index == in_ifindex)
        tx_ifindex = out_ifindex;
      else if (bidirectional && h.extended_hdr.if_index == out_ifindex)
        tx_ifindex = in_ifindex;
      else if (!bidirectional && h.extended_hdr.if_index == in_ifindex)
        tx_ifindex = out_ifindex;
      else {
        /* unexpected packet, skipping */
        printf("Unexpected packet from interface %d: skipping\n", h.extended_hdr.if_index);
        continue;
      }

      if (pfring_set_pkt_buff_ifindex(pd1, pkt_handle, tx_ifindex) == PF_RING_ERROR_INVALID_ARGUMENT) {
        printf("Wrong interface id: skipping packet\n");
        continue;
      }

      pfring_send_pkt_buff(pd1, pkt_handle, flush);
    }

    dir_stats[(h.extended_hdr.if_index == out_ifindex)].numPkts++;
    dir_stats[(h.extended_hdr.if_index == out_ifindex)].numBytes += h.len + 24 /* 8 Preamble + 4 CRC + 12 IFG */; 
  }
}

/* *************************************** */

void dummyProcessPacket(const struct pfring_pkthdr *h, const u_char *p, const u_char *user_bytes) { 

#ifdef DEBUG
    int i = 0;
    for(i=0; i<32; i++) printf("%02X ", p[i]);
    printf("\n");
#endif

  pfring_send(pd2, (char*)p, h->caplen, flush);

  dir_stats[0].numPkts++;
  dir_stats[0].numBytes += h->len + 24 /* 8 Preamble + 4 CRC + 12 IFG */; 
}

/* *************************************** */

void* bouncer_dir2_thread(void *data) {
  if (bind_core[1] >= 0)
    bind2core(bind_core[1]);

  if(pfring_dna_bouncer_loop(bouncer_handle2, dummyProcessPacketZero, (u_char *) &dir_stats[1], wait_for_packet) == -1) {
    printf("Problems while starting bouncer. See dmesg for details.\n");
    exit(-1);
  }
  return NULL;
}

/* *************************************** */

int main(int argc, char* argv[]) {
  char c;
  char buf[32];
  char *bind_mask = NULL;
  u_int32_t version;
  pthread_t pthread2;

  bind_core[0] = bind_core[1] = -1;

  dir_stats[0].numPkts  = dir_stats[1].numPkts = 0;
  dir_stats[0].numBytes = dir_stats[1].numBytes = 0;

  numCPU = sysconf( _SC_NPROCESSORS_ONLN );
  startTime.tv_sec = 0;

  while((c = getopt(argc,argv,"hai:o:m:b:c:g:fpt")) != -1) {
    switch(c) {
    case 'h':
      printHelp();      
      break;
    case 'a':
      wait_for_packet = 0;
      break;
    case 'i':
      in_dev = strdup(optarg);
      break;
    case 'o':
      out_dev = strdup(optarg);
      break;
    case 'm':
      mode = atoi(optarg);
      break;
    case 'c':
      cluster_id = atoi(optarg);
      break;
    case 'b':
      bidirectional = atoi(optarg);
      break;
    case 'f':
      flush = 1;
      break;
    case 'g':
      bind_mask = strdup(optarg);
      break;
    case 'p':
      print_interface_stats = 1;
      break;
    case 't':
      handle_ts_card = 1;
      break;
    }
  }

  if (in_dev == NULL)  printHelp();
  if (out_dev == NULL) out_dev = strdup(in_dev);
  if (mode < 0 || mode > 2) printHelp();
  if (bidirectional < 0 || bidirectional > 2) printHelp();
  if (bidirectional == 1 && mode != 0 && mode != 1) printHelp();
  if (bidirectional == 2 && mode != 0) printHelp();
  if (bidirectional && strcmp(in_dev, out_dev) == 0) printHelp();
  if (mode == 1 && cluster_id < 0) printHelp();

  printf("Bouncing packets from %s to %s (%s)\n", in_dev, out_dev, bidirectional ? "two-way" : "one-way");

  if(handle_ts_card) printf("Stripping timestamp before bouncing packets\n");

  if(bind_mask != NULL) {
    char *id;
    if ((id = strtok(bind_mask, ":")) != NULL)
      bind_core[0] = atoi(id) % numCPU;
    if ((id = strtok(NULL, ":")) != NULL)
      bind_core[1] = atoi(id) % numCPU;
  }

  switch (mode) {
  case 0:
    if (bidirectional == 2 /* bidirectional with one thread per direction: opening two bouncer, two sockets per bouncer */) {
      pdb1 = pfring_open(out_dev, 1500 /* snaplen */, PF_RING_PROMISC);
      if(pdb1 == NULL) {
        printf("pfring_open %s error [%s]\n", in_dev, strerror(errno));
        return(-1);
      }
      pfring_set_socket_mode(pdb1, recv_only_mode);
      pfring_set_application_name(pdb1, "pfdnabounce");

      pdb2 = pfring_open(in_dev, 1500 /* snaplen */, PF_RING_PROMISC);
      if(pdb2 == NULL) {
        printf("pfring_open %s error [%s]\n", out_dev, strerror(errno));
        return(-1);
      } 
      pfring_set_socket_mode(pdb2, send_only_mode);
      pfring_set_application_name(pdb2, "pfdnabounce");
    }
  /* no break here! */
  case 2:
    pd1 = pfring_open(in_dev, 1500 /* snaplen */, PF_RING_PROMISC);
    if(pd1 == NULL) {
      printf("pfring_open %s error [%s]\n", in_dev, strerror(errno));
      return(-1);
    }
    if (bidirectional != 1)
      pfring_set_socket_mode(pd1, recv_only_mode);

    pd2 = pfring_open(out_dev, 1500 /* snaplen */, bidirectional ? PF_RING_PROMISC : 0);
    if(pd2 == NULL) {
      printf("pfring_open %s error [%s]\n", out_dev, strerror(errno));
      return(-1);
    } 
    if (bidirectional != 1)
      pfring_set_socket_mode(pd2, send_only_mode);
    pfring_set_application_name(pd2, "pfdnabounce");
  break;

  case 1:
    snprintf(buf, sizeof(buf), "dnacluster:%d", cluster_id);
    pd1 = pfring_open(buf, 1500 /* snaplen */, PF_RING_PROMISC);
    if(pd1 == NULL) {
      printf("pfring_open %s error [%s] (please run \"pfdnacluster_master -i %s,%s -c %d -s\")\n", buf, strerror(errno), in_dev, out_dev, cluster_id);
      return(-1);
    }
    pfring_set_socket_mode(pd1, send_and_recv_mode);
  break;
  }

  pfring_version(pd1, &version);
  printf("Using PF_RING v.%d.%d.%d\n", (version & 0xFFFF0000) >> 16, 
         (version & 0x0000FF00) >> 8, version & 0x000000FF);

  pfring_set_application_name(pd1, "pfdnabounce");

  signal(SIGINT, sigproc);
  signal(SIGTERM, sigproc);
  signal(SIGINT, sigproc);

  signal(SIGALRM, my_sigalarm);
  alarm(ALARM_SLEEP);

  if(bind_core[0] >= 0)
    bind2core(bind_core[0]);

  switch (mode) {
  case 0: 
    printf("Using Libzero DNA Bouncer (zero-copy)\n");

    if ((bouncer_handle = pfring_dna_bouncer_create(pd1, pd2)) == NULL) {
      printf("WARNING: Unable to initialize the DNA Bouncer (ports already in use ?)\n");
      pfring_close(pd1);
      pfring_close(pd2);

      return(-1);
    }

    if (bidirectional == 2) {
      if ((bouncer_handle2 = pfring_dna_bouncer_create(pdb1, pdb2)) == NULL) {
        printf("WARNING: Unable to initialize the second DNA Bouncer (ports already in use ?)\n");
	pfring_dna_bouncer_destroy(bouncer_handle);
        pfring_close(pdb1);
        pfring_close(pdb2);
        return(-1);
      }
      printf("Starting direction 0 thread..\n"); 
      pthread_create(&pthread2, NULL, bouncer_dir2_thread, NULL);
      printf("Starting direction 1 thread..\n"); 
    } else if (bidirectional == 1) {
      if (pfring_dna_bouncer_set_mode(bouncer_handle, two_way_mode) < 0) {
        printf("Error setting the DNA Bouncer to bidirectional\n");
	pfring_dna_bouncer_destroy(bouncer_handle);
	return(-1);
      }
    } 

    if(pfring_dna_bouncer_loop(bouncer_handle, dummyProcessPacketZero, (u_char *) &dir_stats[0], wait_for_packet) == -1) {
      printf("Problems while starting bouncer. See dmesg for details.\n");
    }

    if (bidirectional == 2) {
      pthread_join(pthread2, NULL);
      pfring_dna_bouncer_destroy(bouncer_handle2);
    }
    pfring_dna_bouncer_destroy(bouncer_handle);
  break;
  case 1: 
    printf("Using Libzero DNA Cluster (0-copy)\n");

    if (pfring_get_device_ifindex(pd1, in_dev,  &in_ifindex ) < 0 ||
        pfring_get_device_ifindex(pd1, out_dev, &out_ifindex) < 0) {
       printf("Error retrieving interface id\n");
      pfring_close(pd1);
      return(-1);
    }
   
    pfring_enable_ring(pd1);

    packetConsumerLoopZeroCluster();

    pfring_close(pd1);
  break;
  case 2: 
    printf("Using Standard DNA (1-copy)\n");

    pfring_set_direction(pd1, rx_only_direction);
    pfring_set_direction(pd2, tx_only_direction);

    pfring_enable_ring(pd1);
    pfring_enable_ring(pd2);

    pfring_loop(pd1, dummyProcessPacket, (u_char*) NULL, wait_for_packet);

    pfring_close(pd1);
    pfring_close(pd2);
  break;
  }

  sleep(3);

  return(0);
}
