/******************************************************************************
**
** parse_cl.c
**
** Sun Oct  7 12:44:00 2001
** Linux 2.4.2 (#5 Thu Apr 26 12:29:16 CDT 2001) i686
** mborella@stratos.mw.3com.com (Mike Borella)
**
** C file for command line parser
**
** Automatically created by genparse v0.5.2
**
** See http://genparse.sourceforge.net/ for details and updates
**
******************************************************************************/

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include "parse_cl.h"

/*----------------------------------------------------------------------------
**
** usage()
**
** Print out usage information, then exit
**
**--------------------------------------------------------------------------*/

void usage(char *executable)
{
  printf("usage: %s [ -abcCdilmnPprTtwxhv ] \n", executable);
  printf("  [ -a ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Don't print application layer data\n");
  printf("  [ -b ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Make stdout buffered\n");
  printf("  [ -c ] ");
  printf("[ --count  ] ");
  printf("(");
  printf("type=");
  printf("INTEGER,");
  printf(" range=1...,");
  printf(")\n");
  printf("         Exit after receiving 'count' packets\n");
  printf("  [ -C ] ");
  printf("[ --CCP  ] ");
  printf("(");
  printf("type=");
  printf("STRING");
  printf(")\n");
  printf("         CCP compression algorithm\n");
  printf("  [ -d ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Dump padding if any exists\n");
  printf("  [ -i ] ");
  printf("[ --interface  ] ");
  printf("(");
  printf("type=");
  printf("STRING");
  printf(")\n");
  printf("         Listen on interface 'interface'\n");
  printf("  [ -l ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Don't print link-layer headers\n");
  printf("  [ -m ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Minimal output\n");
  printf("  [ -n ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Don't print network-layer headers\n");
  printf("  [ -P ] ");
  printf("(");
  printf("type=");
  printf("STRING");
  printf(")\n");
  printf("         Dynamic port mapping (usage: 'protocol=port')\n");
  printf("  [ -p ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Display unknown application payloads in hex\n");
  printf("  [ -r ] ");
  printf("(");
  printf("type=");
  printf("STRING");
  printf(")\n");
  printf("         Read from file rather than interface\n");
  printf("  [ -T ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Don't print timestamps in minimal mode\n");
  printf("  [ -t ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Don't print transport-layer headers\n");
  printf("  [ -w ] ");
  printf("(");
  printf("type=");
  printf("STRING");
  printf(")\n");
  printf("         Write the raw packets to a file\n");
  printf("  [ -x ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Display hex dump of each field\n");
  printf("  [ -h ] ");
  printf("[ --help  ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Display help information.\n");
  printf("  [ -v ] ");
  printf("[ --version  ] ");
  printf("(");
  printf("type=");
  printf("FLAG");
  printf(")\n");
  printf("         Output version.\n");

  exit(1);
}

/*----------------------------------------------------------------------------
**
** free_args()
**
** Call this to free the memory that was dynamically allocated by the parser.
**
**--------------------------------------------------------------------------*/

void free_args(struct arg_t *my_args)
{
  my_free(my_args);
}

/*----------------------------------------------------------------------------
**
** Cmdline()
**
** Parse the argv array into the command line structure
**
**--------------------------------------------------------------------------*/

struct arg_t *Cmdline(int argc, char *argv[])
{
  extern char *optarg;
  extern int optind;
  int option_index = 0;
  int c;
  struct arg_t *my_args;
  int errflg = 0;

  static struct option long_options[] =
  {
    {"", 0, 0, 'a'},
    {"", 0, 0, 'b'},
    {"count", 1, 0, 'c'},
    {"CCP", 1, 0, 'C'},
    {"", 0, 0, 'd'},
    {"interface", 1, 0, 'i'},
    {"", 0, 0, 'l'},
    {"", 0, 0, 'm'},
    {"", 0, 0, 'n'},
    {"", 1, 0, 'P'},
    {"", 0, 0, 'p'},
    {"", 1, 0, 'r'},
    {"", 0, 0, 'T'},
    {"", 0, 0, 't'},
    {"", 1, 0, 'w'},
    {"", 0, 0, 'x'},
    {"help", 0, 0, 'h'},
    {"version", 0, 0, 'v'},
    {0, 0, 0, 0}
  };

  my_args = (struct arg_t *) my_malloc (sizeof(struct arg_t));

  my_args->a = false;
  my_args->b = false;
  my_args->C = NULL;
  my_args->d = false;
  my_args->i = NULL;
  my_args->l = false;
  my_args->m = false;
  my_args->n = false;
  my_args->P = NULL;
  my_args->p = false;
  my_args->r = NULL;
  my_args->T = false;
  my_args->t = false;
  my_args->w = NULL;
  my_args->x = false;
  my_args->h = false;
  my_args->v = false;

  while ((c = getopt_long(argc, argv, "abc:C:di:lmnP:pr:Ttw:xhv", long_options, &option_index)) != EOF)
    {
      switch(c)
        {
        case 'a': 
          my_args->a = true;
          break;

        case 'b': 
          my_args->b = true;
          break;

        case 'c': 
          my_args->c = atoi(optarg);
          if (my_args->c < 1)
            {
              fprintf(stderr, "parameter range error: c must be >= 1\n");
              errflg++;
            }
          break;

        case 'C': 
          my_args->C = strdup(optarg);
          break;

        case 'd': 
          my_args->d = true;
          break;

        case 'i': 
          my_args->i = strdup(optarg);
          break;

        case 'l': 
          my_args->l = true;
          break;

        case 'm': 
          my_args->m = true;
          break;

        case 'n': 
          my_args->n = true;
          break;

        case 'P': 
          my_args->P = strdup(optarg);
          break;

        case 'p': 
          my_args->p = true;
          break;

        case 'r': 
          my_args->r = strdup(optarg);
          break;

        case 'T': 
          my_args->T = true;
          break;

        case 't': 
          my_args->t = true;
          break;

        case 'w': 
          my_args->w = strdup(optarg);
          break;

        case 'x': 
          my_args->x = true;
          break;

        case 'h': 
          my_args->h = true;
          usage(argv[0]);
          break;

        case 'v': 
          my_args->v = true;
          break;

        default:
          usage(argv[0]);

        }
    } /* while */

  if (errflg)
    usage(argv[0]);

  if (optind >= argc)
    my_args->optind = 0;
  else
    my_args->optind = optind;
  return my_args;
}
