/*
 * Tentun - covert tunneling project
 *
 * Copyright (C) 2003 David Gordon
 *
 *      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.
 */


#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>

#define _GNU_SOURCE
#include <getopt.h>
 
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#include "lib.h"
#include "tentun.h"

int debuglevel = DEBUG_INIT | DEBUG_DNS;


/* Global options for the server and client */
struct tentun_opts tentun;
struct tentun_host default_host;

void usage(void);

extern int optind,opterr,optopt;
extern char *optarg;

int main(int argc, char *argv[], char *env[])
{
  int daemon, sock, dofork, fd, opt;
  /* struct tentun_host *host = NULL; */
  struct sigaction sa;
  int option_index = 0;
  /*     char *hst;*/

  /* Configure default settings */
  daemon = 1; sock = 0; dofork = 1;

  tentun.persist = -1;
  tentun.timeout = -1;
	
  tentun.svr_name = NULL;
  tentun.svr_port = -1;
  tentun.svr_type = -1;

  /* Initialize default host options */
  memset(&default_host, 0, sizeof(default_host));
  default_host.svr = 0;
  default_host.flags   = TENTUN_TUN | TENTUN_TCP;
  default_host.multi   = TENTUN_MULTI_ALLOW;
  default_host.timeout = TENTUN_CONNECT_TIMEOUT;
  default_host.ka_interval = 30;
  default_host.ka_failure  = 4;
  default_host.loc_fd = default_host.rmt_fd = -1;
  /*
  while( (opt=getopt_long(argc,argv,"isf:P:t:np",
		     long_options, &option_index)) != EOF ){
  */
  while(1) {
    static int param_flags;
    static struct option long_options[] = {
      {"simple-http", 0, &param_flags, TENTUN_S_HTTP},
      {"dns", 0, &param_flags, TENTUN_DNS},
      {0, 0, 0, 0}
    };

    opt = getopt_long(argc,argv,"isf:P:t:np",
		    long_options, &option_index);

    if (opt == -1) break;

    switch(opt){
    case 0:
      default_host.flags |= param_flags;
      break;
    case 'i':
      tentun.svr_type = TENTUN_INETD;
    case 's':
      default_host.svr = 1;
      break;
    case 'P':
      tentun.svr_port = atoi(optarg);
      break;
    case 'n':
      daemon = 0;
      break;
    case 'p':
      tentun.persist = 1;
      break;
    case 't':
      tentun.timeout = atoi(optarg);	
      break;
    default:
      usage();
      exit(1);
    }
  }	

  if(!default_host.svr){
    if( argc - optind < 1 ){
      usage();
      exit(1);
    }
    /* hst = argv[optind++]; */

    tentun.svr_name = strdup(argv[optind]);
  } 
      	
  /* 
   * Now fill uninitialized fields of the options structure
   * with default values. 
   */ 
  if(tentun.svr_port == -1)
    tentun.svr_port = TENTUN_PORT;
  if(tentun.persist == -1)
    tentun.persist = 0;
  if(tentun.timeout == -1)
    tentun.timeout = TENTUN_TIMEOUT;

  switch( tentun.svr_type ){
  case -1:
    tentun.svr_type = TENTUN_STAND_ALONE;
    break;
  case TENTUN_INETD:
    sock = dup(0);
    dofork = 0; 
    break;
  }

  if( daemon ){
    if( dofork && fork() )
      exit(0);

    /* Direct stdin,stdout,stderr to '/dev/null' */
    fd = open("/dev/null", O_RDWR);
    close(0); dup(fd);
    close(1); dup(fd);
    close(2); dup(fd);
    close(fd);

    setsid();

    chdir("/");
  }

  if(default_host.svr){
    server(sock, &default_host);
  } else {	
    client(&default_host);
  }

  return 0;
}

void usage(void)
{
  printf("Tentun ver %s\n", TENTUN_VER);
  printf("Usage: \n");
  printf("  Server: tentun <-s>\n");
  printf("  Client: tentun <server adress>\n\n");

  printf("Common options:\n");
  printf("\t--dns\t\tDNS tunnel\n");
  printf("\t-i\t\tUse inetd daemon\n");
  printf("\t-n\t\tDo not run as a daemon\n");
  printf("\t-p\t\tPersistent connection\n");
  printf("\t-P port\t\tPort (default: %d)\n", TENTUN_PORT);
  printf("\t--simple-http\tSimple HTTP tunnel\n");
  printf("\t-t timeout\tConnection timeout in seconds (default: %d)\n", TENTUN_TIMEOUT);

}
