/* aagobl.c */

/* Gobble traffic on a particular vci using the */
/* atm sockets interface.                       */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/times.h>

#ifdef GLIBC_PATCH
#include <stdint.h>
#undef __GLIBC__
#include <linux/socket.h>
#include <linux/atm.h>
#else
#include <sys/socket.h>
#include <linux/types.h>
#endif


#include <signal.h>

static struct timezone dummy = {0,0};
static double tu1;
static double tu2;
static int    frames = 0;
static int    drops = 0;
static int    dropcount = 0;
static int    max_frames = 0;

struct sockaddr_atmpvc addr;
struct atm_qos         qos;

void sigintr(
int  dummy)
{
   printf("Frames recvd = %10d \n", frames);
   printf("Drops        = %10d \n", drops);
   printf("Drop count   = %10d \n", dropcount);
   printf("Total        = %10d \n", frames + dropcount);
   exit(1);
}

char bufi[65536];
void aa_recv(
int s)                  /* socket handle */
{
   int rc;
   int amt = 0;
   int fc  = 0;
   int fctrue;

   signal(SIGINT, sigintr);

   rc = 0;
   while (rc >= 0)
   {
      amt += rc;
      rc = read(s, bufi, sizeof(bufi));

      fctrue = *(long *)bufi;
#if 1
      if (fctrue > fc)
      {
         drops += 1;
         dropcount += fctrue - fc;

      }
#endif
      frames += 1;

      if (max_frames > 0)
      {
         if (frames > max_frames)
         {
            int rc;

            printf("Closing after %d frames \n", frames);
            close(s);
            exit(1);
         }
      }

      fc = fctrue + 1;
      if (rc == 0)
         printf("Read %d bytes first was %c \n", rc, bufi[0]);
   }
   printf("Receiver complete.. received  %d \n", amt);
}

main(
int argc,
char **argv)
{
   int  in;
   int  fd;
   int  len;
   int  vci;
   int  rc;
   int  fc;
   int  psr;
   int  blk;
   int  count = 4096;
   int  sent  = 0;
   struct timeval time1;
   struct timeval time2;
   double tu1;
   double tu2;
   int    s,size,offset;


   if (argc < 2)
   {
      printf("This gobbles from  the vci specified.              \n");
      printf("You must give vci number in decimal as parm 1.      \n");
      printf("You may  give max input frames as parm 2.            \n");
      exit(1);
   }

   sscanf(argv[1], "%d", &vci);
   printf("Recv from vci %d \n", vci);

   if (argc > 2)
      sscanf(argv[2], "%d", &max_frames);


   s = socket(PF_ATMPVC,SOCK_DGRAM,ATM_AAL5);
   printf("Socket call returned %d \n", s);

   qos.aal = 5;
   qos.txtp.traffic_class = ATM_UBR;
   qos.txtp.max_sdu = 1200;
   qos.txtp.max_pcr = 5 * 1024 * 1024;
   qos.txtp.min_pcr = 1 * 1024 * 1024;
   qos.txtp.max_cdv = 1 * 1024 * 1024;

   qos.rxtp.traffic_class = ATM_UBR;
   qos.rxtp.max_sdu = 1200;
   qos.rxtp.max_pcr = 5 * 1024 * 1024;
   qos.rxtp.min_pcr = 1 * 1024 * 1024;
   qos.rxtp.max_cdv = 1 * 1024 * 1024;

   rc = setsockopt(s, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos));
   printf("Return from setsock is %d \n", rc);

   addr.sap_family   = AF_ATMPVC;
   addr.sap_addr.itf = 0;
   addr.sap_addr.vpi = 0;
   addr.sap_addr.vci = vci;

   while (rc = connect(s,(struct sockaddr *) &addr,sizeof(addr)))
   {
      printf("Return from connect is %d \n", rc);
      sleep(1);
   }

   printf("Return from connect is %d \n", rc);
   aa_recv(s);

}

