예제 #1
0
파일: smbserver.c 프로젝트: ACGT/nbtool
int main(int argc, char *argv[])
{
	int s = tcp_listen("0.0.0.0", 445);
	select_group_t *sg = select_group_create();

	if(s < 0)
		return 0;

	select_group_add_socket(sg, s, SOCKET_TYPE_LISTEN, NULL);
	select_set_listen(sg, s, listener);

	/* We start by receiving a header. */
	state = RECV_STATE_HEADER;

	while(1)
	{
		select_group_do_select(sg, 3, 0);
	}
#if 0
	/* Do 'session setup' */
	length = smb_get_length(smb);
	data = safe_malloc(length);
	smb_get(smb, data, length);
	tcp_send(s, data, length);


	while(1)
	{
		select_group_do_select(sg, -1, -1);
	}

	select_group_destroy(sg);
#endif
	return 0;
}
예제 #2
0
파일: nbsniff.c 프로젝트: ACGT/nbtool
static void nb_poll(settings_t *settings)
{
	settings->group = select_group_create();
	select_group_add_socket(settings->group, settings->socket, SOCKET_TYPE_DATAGRAM, settings);
	select_set_recv(settings->group, settings->socket, nb_recv_callback);

	select_set_timeout(settings->group, settings->socket, nb_timeout);

	while(1)
		select_group_do_select(settings->group, settings->wait);

	select_group_destroy(settings->group);
}
예제 #3
0
파일: tcpcat.c 프로젝트: AmesianX/dnscat2
int main(int argc, char *argv[])
{
  /* Define the options specific to the DNS protocol. */
  struct option long_options[] =
  {
    {"host", required_argument, 0, 0},
    {"port", required_argument, 0, 0},
    {0,      0,                 0, 0}  /* End */
  };
  char        c;
  int         option_index;
  const char *option_name;

  options        = safe_malloc(sizeof(options_t));

  srand(time(NULL));

  /* Set up some default options. */
  options->s               = -1;

  options->host    = DEFAULT_HOST;
  options->port    = DEFAULT_PORT;
  options->buffer  = buffer_create(BO_BIG_ENDIAN);
  options->group   = select_group_create();
  options->session = session_create(options->group, tcpcat_send, options, 65535);

  /* Parse the command line options. */
  opterr = 0;
  while((c = getopt_long_only(argc, argv, "", long_options, &option_index)) != EOF)
  {
    switch(c)
    {
      case 0:
        option_name = long_options[option_index].name;

        if(!strcmp(option_name, "host"))
        {
          options->host = optarg;
        }
        else if(!strcmp(option_name, "port"))
        {
          options->port = atoi(optarg);
        }
        else
        {
          LOG_FATAL("Unknown option: %s\n", option_name);
          exit(1);
          /* TODO: Usage */
        }
        break;

      case '?':
      default:
        /* Do nothing; we expect some unknown arguments. */
        break;
    }
  }

  /* Tell the user what's going on */
  LOG_INFO("Host: %s\n", options->host);
  LOG_INFO("Port: %d\n", options->port);

  atexit(cleanup);

  /* Add the timeout function */
  select_set_timeout(options->group, timeout, (void*)options);

  while(TRUE)
    select_group_do_select(options->group, 1000);

  return 0;
}
예제 #4
0
int main(int argc, char *argv[])
{
  /* Define the options specific to the DNS protocol. */
  struct option long_options[] =
  {
    /* General options */
    {"help",    no_argument,       0, 0}, /* Help */
    {"h",       no_argument,       0, 0},
    {"version", no_argument,       0, 0}, /* Version */
#if 0
    {"name",    required_argument, 0, 0}, /* Name */
    {"n",       required_argument, 0, 0},
    {"download",required_argument, 0, 0}, /* Download */
    {"n",       required_argument, 0, 0},
    {"chunk",   required_argument, 0, 0}, /* Download chunk */
    {"isn",     required_argument, 0, 0}, /* Initial sequence number */
#endif

    {"delay",              required_argument, 0, 0}, /* Retransmit delay */
    {"steady",             no_argument,       0, 0}, /* Don't transmit immediately after getting a response. */
    {"max-retransmits",    required_argument, 0, 0}, /* Set the max retransmissions */
    {"retransmit-forever", no_argument,       0, 0}, /* Retransmit forever if needed */
#ifndef NO_ENCRYPTION
    {"secret",             required_argument, 0, 0}, /* Pre-shared secret */
    {"no-encryption",      no_argument,       0, 0}, /* Disable encryption */
#endif

    /* i/o options. */
    {"console", no_argument,       0, 0}, /* Enable console */
    {"exec",    required_argument, 0, 0}, /* Enable execute */
    {"e",       required_argument, 0, 0},
    {"command", no_argument,       0, 0}, /* Enable command (default) */
    {"ping",    no_argument,       0, 0}, /* Ping */

    /* Tunnel drivers */
    {"dns",     required_argument, 0, 0}, /* Enable DNS */
#if 0
    {"tcp",     optional_argument, 0, 0}, /* Enable TCP */
#endif

    /* Debug options */
    {"d",            no_argument, 0, 0}, /* More debug */
    {"q",            no_argument, 0, 0}, /* Less debug */
    {"packet-trace", no_argument, 0, 0}, /* Trace packets */

    /* Sentry */
    {0,              0,                 0, 0}  /* End */
  };

  int               c;
  int               option_index;
  const char       *option_name;

  NBBOOL            tunnel_driver_created = FALSE;
  ll_t             *drivers_to_create     = ll_create(NULL);
  uint32_t          drivers_created       = 0;

  log_level_t       min_log_level = LOG_LEVEL_WARNING;

  group = select_group_create();
  system_dns = dns_get_system();

  /* Seed with the current time; not great, but it'll suit our purposes. */
  srand((unsigned int)time(NULL));

  /* This is required for win32 support. */
  winsock_initialize();

#ifndef WIN32  
  /* set the SIGCHLD handler to SIG_IGN causing zombie child processes to be reaped automatically */
  if(signal(SIGCHLD, SIG_IGN) == SIG_ERR) 
  {
    perror("Couldn't set SIGCHLD handler to SIG_IGN");
    exit(1);
  }  
#endif

  /* Set the default log level */
  log_set_min_console_level(min_log_level);

  /* Parse the command line options. */
  opterr = 0;
  while((c = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
  {
    switch(c)
    {
      case 0:
        option_name = long_options[option_index].name;

        /* General options */
        if(!strcmp(option_name, "help") || !strcmp(option_name, "h"))
        {
          usage(argv[0], "--help requested");
        }
        if(!strcmp(option_name, "version"))
        {
          printf(NAME" "VERSION" (client)\n");
          exit(0);
        }
        else if(!strcmp(option_name, "isn"))
        {
          uint16_t isn = (uint16_t) (atoi(optarg) & 0xFFFF);
          debug_set_isn(isn);
        }
        else if(!strcmp(option_name, "delay"))
        {
          int delay = (int) atoi(optarg);
          session_set_delay(delay);
          LOG_INFO("Setting delay between packets to %dms", delay);
        }
        else if(!strcmp(option_name, "steady"))
        {
          session_set_transmit_immediately(FALSE);
        }
        else if(!strcmp(option_name, "max-retransmits"))
        {
          controller_set_max_retransmits(atoi(optarg));
        }
        else if(!strcmp(option_name, "retransmit-forever"))
        {
          controller_set_max_retransmits(-1);
        }
#ifndef NO_ENCRYPTION
        else if(!strcmp(option_name, "secret"))
        {
          session_set_preshared_secret(optarg);
        }
        else if(!strcmp(option_name, "no-encryption"))
        {
          session_set_encryption(FALSE);
        }
#endif

        /* i/o drivers */
        else if(!strcmp(option_name, "console"))
        {
          ll_add(drivers_to_create, ll_32(drivers_created++), make_console());

/*          session = session_create_console(group, "console");
          controller_add_session(session); */
        }
        else if(!strcmp(option_name, "exec") || !strcmp(option_name, "e"))
        {
          ll_add(drivers_to_create, ll_32(drivers_created++), make_exec(optarg));

/*          session = session_create_exec(group, optarg, optarg);
          controller_add_session(session); */
        }
        else if(!strcmp(option_name, "command"))
        {
          ll_add(drivers_to_create, ll_32(drivers_created++), make_command());

/*          session = session_create_command(group, "command");
          controller_add_session(session); */
        }
        else if(!strcmp(option_name, "ping"))
        {
          ll_add(drivers_to_create, ll_32(drivers_created++), make_ping());

/*          session = session_create_ping(group, "ping");
          controller_add_session(session); */
        }

        /* Tunnel driver options */
        else if(!strcmp(option_name, "dns"))
        {
          tunnel_driver_created = TRUE;
          tunnel_driver = create_dns_driver(group, optarg);
        }
        else if(!strcmp(option_name, "tcp"))
        {
          tunnel_driver_created = TRUE;
          create_tcp_driver(optarg);
        }

        /* Debug options */
        else if(!strcmp(option_name, "d"))
        {
          if(min_log_level > 0)
          {
            min_log_level--;
            log_set_min_console_level(min_log_level);
          }
        }
        else if(!strcmp(option_name, "q"))
        {
          min_log_level++;
          log_set_min_console_level(min_log_level);
        }
        else if(!strcmp(option_name, "packet-trace"))
        {
          session_enable_packet_trace();
        }
        else
        {
          usage(argv[0], "Unknown option");
        }
        break;

      case '?':
      default:
        usage(argv[0], "Unrecognized argument");
        break;
    }
  }

  create_drivers(drivers_to_create);
  ll_destroy(drivers_to_create);

  if(tunnel_driver_created && argv[optind])
  {
    printf("It looks like you used --dns and also passed a domain on the commandline.\n");
    printf("That's not allowed! Either use '--dns domain=xxx' or don't use a --dns\n");
    printf("argument!\n");
    exit(1);
  }

  /* If no output was set, use the domain, and use the last option as the
   * domain. */
  if(!tunnel_driver_created)
  {
    /* Make sure they gave a domain. */
    if(optind >= argc)
    {
      printf("Starting DNS driver without a domain! This will only work if you\n");
      printf("are directly connecting to the dnscat2 server.\n");
      printf("\n");
      printf("You'll need to use --dns server=<server> if you aren't.\n");
      tunnel_driver = create_dns_driver_internal(group, NULL, "0.0.0.0", 53, DEFAULT_TYPES, NULL);
    }
    else
    {
      tunnel_driver = create_dns_driver_internal(group, argv[optind], "0.0.0.0", 53, DEFAULT_TYPES, NULL);
    }
  }

  /* Be sure we clean up at exit. */
  atexit(cleanup);

  /* Start the driver! */
  driver_dns_go(tunnel_driver);

  return 0;
}
예제 #5
0
파일: smbtest.c 프로젝트: ACGT/nbtool
int main(int argc, char *argv[])
{
	size_t i;
	int ch;

	SMBCLIENT_t *smbclient = smbclient_create();

	sg = select_group_create();

	/* Default values. */
	memset(&settings, 0, sizeof(SETTINGS_t));
	settings.port = 445;

	smbclient_set_event_callback(smbclient, event_callback);
	smbclient_set_protocol_error_callback(smbclient, protocol_error_callback);
	smbclient_set_connection_error_callback(smbclient, connection_error_callback);

	opterr = 0;

	while((ch = getopt(argc, argv, "hd:u:p:n:P:t:vs")) != -1)
	{
		switch(ch)
		{
			case 'h':
				usage(argv[0]);
				break;

			case 'd':
				settings.domain   = optarg;
				break;

			case 'u':
				settings.username = optarg;
				break;

			case 'p':
				settings.password = optarg;
				break;

			case 'P':
				settings.hash = optarg;
				break;

			case 'n':
				settings.netbios_name = optarg;
				break;

			case 't':
				if(!strcmp(optarg, "default"))
					settings.logon = LOGONTYPE_DEFAULT;
				else if(!strcmp(optarg, "lm"))
					settings.logon = LOGONTYPE_LM;
				else if(!strcmp(optarg, "ntlm"))
					settings.logon = LOGONTYPE_NTLM;
				else if(!strcmp(optarg, "v2"))
					settings.logon = LOGONTYPE_DEFAULTv2;
				else if(!strcmp(optarg, "lmv2"))
					settings.logon = LOGONTYPE_LMv2;
				else if(!strcmp(optarg, "anonymous"))
					settings.logon = LOGONTYPE_ANONYMOUS;
				else
				{
					fprintf(stderr, "Error: unknown logon type (%s)\n\n", optarg);
					usage(argv[0]);
				}
				break;

			case 'v':
				smbclient_raise_verbose(smbclient);
				break;

			case 's':
				smbclient_raise_check_signature(smbclient);
				settings.check_signature++;
				break;

			case '?':
			default:
				fprintf(stderr, "Unknown switch: %c\n\n", ch);
				usage(argv[0]);
		}
	}

	/* The host has to be given */
	if(optind >= argc)
	{
		fprintf(stderr, "Host not given!\n\n");
		usage(argv[0]);
	}

	/* Create the socket. */
	if(optind < argc)
		settings.host = argv[optind++];
	if(optind < argc)
		settings.port = atoi(argv[optind++]);

	/* Sanity checks. */
	if(settings.port == 139 && settings.netbios_name == NULL)
	{
		/* TODO: Do a probe for the NetBIOS name. */
		fprintf(stderr, "To use port 139, you have to specify the NetBIOS (server) name of the server (using ./nbquery -t NBSTAT to get it). Specify it with -n.\n\n");
		exit(1);
	}
	if(settings.password && settings.hash)
	{
		fprintf(stderr, "-p and -P cannot be used together.\n\n");
		exit(1);
	}
	if((settings.logon == LOGONTYPE_ANONYMOUS) && (settings.username || settings.password || settings.hash))
	{
		fprintf(stderr, "Anonymous logons can't have a domain/username/password/hash.\n\n");
		exit(1);
	}
	if(settings.logon == LOGONTYPE_ANONYMOUS && settings.check_signature)
	{
		fprintf(stderr, "Can't check signatuers on anonymous logons.\n\n");
		exit(1);
	}
	if((settings.logon == LOGONTYPE_DEFAULTv2 || settings.logon == LOGONTYPE_LMv2) && settings.check_signature)
	{
		fprintf(stderr, "Can't currently check signatures on v2 and LMv2 logons.\n\n");
		exit(1);
	}

	/* Domain has to be present (even if blank) and uppercase. */
	if(!settings.domain)
		settings.domain = "";
	else
	{
		for(i = 0; i < strlen(settings.domain); i++)
			settings.domain[i] = toupper(settings.domain[i]);
	}

	/* We're ready to connect! */
	smbclient_connect(smbclient, settings.host, settings.port, TRUE, sg);

	while(1)
	{
		select_group_do_select(sg, -1, -1);
	}

	return 0;
}
예제 #6
0
파일: dnscat.c 프로젝트: sjas/dnscat2
int main(int argc, char *argv[])
{
  /* Define the options specific to the DNS protocol. */
  struct option long_options[] =
  {
    /* General options */
    {"help",    no_argument,       0, 0}, /* Help */
    {"h",       no_argument,       0, 0},
    {"version", no_argument,       0, 0}, /* Version */
#if 0
    {"name",    required_argument, 0, 0}, /* Name */
    {"n",       required_argument, 0, 0},
    {"download",required_argument, 0, 0}, /* Download */
    {"n",       required_argument, 0, 0},
    {"chunk",   required_argument, 0, 0}, /* Download chunk */
    {"isn",     required_argument, 0, 0}, /* Initial sequence number */
#endif

    {"delay",              required_argument, 0, 0}, /* Retransmit delay */
    {"steady",             no_argument,       0, 0}, /* Don't transmit immediately after getting a response. */
    {"max-retransmits",    required_argument, 0, 0}, /* Set the max retransmissions */
    {"retransmit-forever", no_argument,       0, 0}, /* Retransmit forever if needed */

    /* i/o options. */
    {"console", no_argument,       0, 0}, /* Enable console */
    {"exec",    required_argument, 0, 0}, /* Enable execute */
    {"e",       required_argument, 0, 0},
    {"command", no_argument,       0, 0}, /* Enable command (default) */
    {"ping",    no_argument,       0, 0}, /* Ping */

    /* Tunnel drivers */
    {"dns",     required_argument, 0, 0}, /* Enable DNS */
#if 0
    {"tcp",     optional_argument, 0, 0}, /* Enable TCP */
#endif

    /* Debug options */
    {"d",            no_argument, 0, 0}, /* More debug */
    {"q",            no_argument, 0, 0}, /* Less debug */
    {"packet-trace", no_argument, 0, 0}, /* Trace packets */

    /* Sentry */
    {0,              0,                 0, 0}  /* End */
  };

  char              c;
  int               option_index;
  const char       *option_name;

  NBBOOL            tunnel_driver_created = FALSE;
  NBBOOL            driver_created        = FALSE;


  log_level_t       min_log_level = LOG_LEVEL_WARNING;

  session_t        *session = NULL;

  group = select_group_create();
  system_dns = dns_get_system();

  /* Seed with the current time; not great, but it'll suit our purposes. */
  srand((unsigned int)time(NULL));

  /* This is required for win32 support. */
  winsock_initialize();

  /* Set the default log level */
  log_set_min_console_level(min_log_level);

  /* Parse the command line options. */
  opterr = 0;
  while((c = getopt_long_only(argc, argv, "", long_options, &option_index)) != EOF)
  {
    switch(c)
    {
      case 0:
        option_name = long_options[option_index].name;

        /* General options */
        if(!strcmp(option_name, "help") || !strcmp(option_name, "h"))
        {
          usage(argv[0], "--help requested");
        }
        if(!strcmp(option_name, "version"))
        {
          printf(NAME" v"VERSION" (client)\n");
          exit(0);
        }
        else if(!strcmp(option_name, "isn"))
        {
          uint16_t isn = (uint16_t) (atoi(optarg) & 0xFFFF);
          debug_set_isn(isn);
        }
        else if(!strcmp(option_name, "delay"))
        {
          int delay = (int) atoi(optarg);
          session_set_delay(delay);
          LOG_INFO("Setting delay between packets to %dms", delay);
        }
        else if(!strcmp(option_name, "steady"))
        {
          session_set_transmit_immediately(FALSE);
        }
        else if(!strcmp(option_name, "max-retransmits"))
        {
          controller_set_max_retransmits(atoi(optarg));
        }
        else if(!strcmp(option_name, "retransmit-forever"))
        {
          controller_set_max_retransmits(-1);
        }

        /* i/o drivers */
        else if(!strcmp(option_name, "console"))
        {
          driver_created = TRUE;

          session = session_create_console(group, "Console session");
          controller_add_session(session);
        }
        else if(!strcmp(option_name, "exec") || !strcmp(option_name, "e"))
        {
          driver_created = TRUE;

          session = session_create_exec(group, optarg, optarg);
          controller_add_session(session);
        }
        else if(!strcmp(option_name, "command"))
        {
          driver_created = TRUE;

          session = session_create_command(group, "Command session");
          controller_add_session(session);
        }
        else if(!strcmp(option_name, "ping"))
        {
          driver_created = TRUE;

          session = session_create_ping(group, "Ping session");
          controller_add_session(session);
        }

        /* Listener options. */
        else if(!strcmp(option_name, "listen") || !strcmp(option_name, "l"))
        {
          LOG_FATAL("--listen isn't implemented yet! :(\n");
          exit(1);
          /*listen_port = atoi(optarg);*/

          /*input_type = TYPE_LISTENER;*/
        }

        /* Tunnel driver options */
        else if(!strcmp(option_name, "dns"))
        {
          tunnel_driver_created = TRUE;
          tunnel_driver = create_dns_driver(group, optarg);
        }
        else if(!strcmp(option_name, "tcp"))
        {
          tunnel_driver_created = TRUE;
          create_tcp_driver(optarg);
        }

        /* Debug options */
        else if(!strcmp(option_name, "d"))
        {
          if(min_log_level > 0)
          {
            min_log_level--;
            log_set_min_console_level(min_log_level);
          }
        }
        else if(!strcmp(option_name, "q"))
        {
          min_log_level++;
          log_set_min_console_level(min_log_level);
        }
        else if(!strcmp(option_name, "packet-trace"))
        {
          session_enable_packet_trace();
        }
        else
        {
          usage(argv[0], "Unknown option");
        }
        break;

      case '?':
      default:
        usage(argv[0], "Unrecognized argument");
        break;
    }
  }

  /* If no output was set, use the domain, and use the last option as the
   * domain. */
  if(!tunnel_driver_created)
  {
    /* Make sure they gave a domain. */
    if(optind >= argc)
    {
      printf("Starting DNS driver without a domain! This will only work if you\n");
      printf("are directly connecting to the dnscat2 server.\n");
      printf("\n");
      printf("You'll need to use --dns server=<server> if you aren't.\n");
      tunnel_driver = create_dns_driver_internal(group, NULL, "0.0.0.0", 53, DEFAULT_TYPES, NULL);
    }
    else
    {
      tunnel_driver = create_dns_driver_internal(group, argv[optind], "0.0.0.0", 53, DEFAULT_TYPES, NULL);
    }
  }

  /* If no i/o was set, create a command session. */
  if(!driver_created)
  {
    session = session_create_command(group, "command (default)");
    controller_add_session(session);
  }

  /* Be sure we clean up at exit. */
  atexit(cleanup);

  /* Start the driver! */
  driver_dns_go(tunnel_driver);

  return 0;
}
예제 #7
0
파일: dnscat.c 프로젝트: 52piaoyu/dnscat2
int main(int argc, char *argv[])
{
  /* Define the options specific to the DNS protocol. */
  struct option long_options[] =
  {
    /* General options */
    {"help",    no_argument,       0, 0}, /* Help */
    {"h",       no_argument,       0, 0},
    {"name",    required_argument, 0, 0}, /* Name */
    {"n",       required_argument, 0, 0},
    {"download",required_argument, 0, 0}, /* Download */
    {"n",       required_argument, 0, 0},
    {"chunk",   required_argument, 0, 0}, /* Download chunk */
    {"ping",    no_argument,       0, 0}, /* Ping */

    /* Console options. */
    {"console", no_argument,       0, 0}, /* Enable console (default) */

    /* Execute-specific options. */
    {"exec",    required_argument, 0, 0}, /* Enable execute */
    {"e",       required_argument, 0, 0},

    /* Listener options */
    {"listen",  required_argument, 0, 0}, /* Enable listener */
    {"l",       required_argument, 0, 0},

    /* DNS-specific options */
    {"dns",        required_argument, 0, 0}, /* Enable DNS (default) */
    {"dnshost",    required_argument, 0, 0}, /* DNS server */
    {"host",       required_argument, 0, 0}, /* (alias) */
    {"dnsport",    required_argument, 0, 0}, /* DNS port */
    {"port",       required_argument, 0, 0}, /* (alias) */

    /* Debug options */
    {"d",       no_argument,       0, 0}, /* More debug */
    {"q",       no_argument,       0, 0}, /* Less debug */
    {0,         0,                 0, 0}  /* End */
  };

  /* Define DNS options so we can set them later. */
  struct {
    char     *host;
    uint16_t  port;
  } dns_options = { DEFAULT_DNS_HOST, DEFAULT_DNS_PORT };

  char              c;
  int               option_index;
  const char       *option_name;

  NBBOOL            output_set = FALSE;

  char             *name     = NULL;
  char             *download = NULL;
  uint32_t          chunk    = -1;

  log_level_t       min_log_level = LOG_LEVEL_WARNING;

  drivers_t input_type = TYPE_NOT_SET;

  char *exec_process = NULL;

  int listen_port = 0;

  /* Initialize the modules that need initialization. */
  log_init();
  sessions_init();

  group = select_group_create();

  /* Seed with the current time; not great, but it'll suit our purposes. */
  srand((unsigned int)time(NULL));

  /* This is required for win32 support. */
  winsock_initialize();

  /* Set the default log level */
  log_set_min_console_level(min_log_level);

  /* Parse the command line options. */
  opterr = 0;
  while((c = getopt_long_only(argc, argv, "", long_options, &option_index)) != EOF)
  {
    switch(c)
    {
      case 0:
        option_name = long_options[option_index].name;

        /* General options */
        if(!strcmp(option_name, "help") || !strcmp(option_name, "h"))
        {
          usage(argv[0], "--help requested");
        }
        else if(!strcmp(option_name, "name") || !strcmp(option_name, "n"))
        {
          name = optarg;
        }
        else if(!strcmp(option_name, "download"))
        {
          download = optarg;
        }
        else if(!strcmp(option_name, "chunk"))
        {
          chunk = atoi(optarg);
        }
        else if(!strcmp(option_name, "ping"))
        {
          if(input_type != TYPE_NOT_SET)
            too_many_inputs(argv[0]);

          input_type = TYPE_PING;

          /* Turn off logging, since this is a simple ping. */
          min_log_level++;
          log_set_min_console_level(min_log_level);
        }

        /* Console-specific options. */
        else if(!strcmp(option_name, "console"))
        {
          if(input_type != TYPE_NOT_SET)
            too_many_inputs(argv[0]);

          input_type = TYPE_CONSOLE;
        }

        /* Execute options. */
        else if(!strcmp(option_name, "exec") || !strcmp(option_name, "e"))
        {
          if(input_type != TYPE_NOT_SET)
            too_many_inputs(argv[0]);

          exec_process = optarg;
          input_type = TYPE_EXEC;
        }

        /* Listener options. */
        else if(!strcmp(option_name, "listen") || !strcmp(option_name, "l"))
        {
          if(input_type != TYPE_NOT_SET)
            too_many_inputs(argv[0]);

          listen_port = atoi(optarg);

          input_type = TYPE_LISTENER;
        }

        /* DNS-specific options */
        else if(!strcmp(option_name, "dns"))
        {
          output_set = TRUE;
          driver_dns = driver_dns_create(group, optarg);
        }
        else if(!strcmp(option_name, "dnshost") || !strcmp(option_name, "host"))
        {
          dns_options.host = optarg;
        }
        else if(!strcmp(option_name, "dnsport") || !strcmp(option_name, "port"))
        {
          dns_options.port = atoi(optarg);
        }

        /* Debug options */
        else if(!strcmp(option_name, "d"))
        {
          if(min_log_level > 0)
          {
            min_log_level--;
            log_set_min_console_level(min_log_level);
          }
        }
        else if(!strcmp(option_name, "q"))
        {
          log_set_min_console_level(min_log_level);
        }
        else
        {
          usage(argv[0], "Unknown option");
        }
        break;

      case '?':
      default:
        usage(argv[0], "Unrecognized argument");
        break;
    }
  }

  if(chunk != -1 && !download)
  {
    LOG_FATAL("--chunk can only be used with --download");
    exit(1);
  }

  /* If no input was created, default to command. */
  if(input_type == TYPE_NOT_SET)
    input_type = TYPE_COMMAND;

  switch(input_type)
  {
    case TYPE_CONSOLE:
      LOG_WARNING("INPUT: Console");
      driver_console_create(group, name, download, chunk);
      break;

    case TYPE_COMMAND:
      LOG_WARNING("INPUT: Command");
      driver_command_create(group, name);
      break;

    case TYPE_EXEC:
      LOG_WARNING("INPUT: Executing %s", exec_process);

      if(exec_process == NULL)
        usage(argv[0], "--exec set without a process!");

      driver_exec_create(group, exec_process, name);
      break;

    case TYPE_LISTENER:
      LOG_WARNING("INPUT: Listening on port %d", driver_listener->port);
      if(listen_port == 0)
        usage(argv[0], "--listen set without a port!");

      driver_listener = driver_listener_create(group, "0.0.0.0", listen_port, name);
      break;

    case TYPE_PING:
      LOG_WARNING("INPUT: ping");
      driver_ping = driver_ping_create(group);
      break;

    case TYPE_NOT_SET:
      usage(argv[0], "You have to pick an input type!");
      break;

    default:
      usage(argv[0], "Unknown type?");
  }

  /* If no output was set, use the domain, and use the last option as the
   * domain. */
  if(!output_set)
  {
    /* Make sure they gave a domain. */
    if(optind >= argc)
    {
      LOG_WARNING("Starting DNS driver without a domain! You'll probably need to use --host to specify a direct connection to your server.");
      driver_dns = driver_dns_create(group, NULL);
    }
    else
    {
      driver_dns = driver_dns_create(group, argv[optind]);
    }
  }

  if(driver_dns)
  {
    if(dns_options.host == DEFAULT_DNS_HOST)
      driver_dns->dns_host = dns_get_system();
    else
      driver_dns->dns_host = safe_strdup(dns_options.host);

    if(!driver_dns->dns_host)
    {
      LOG_FATAL("Couldn't determine the system DNS server! Please use --host to set one.");
      LOG_FATAL("You can also create a proper /etc/resolv.conf file to fix this");
      exit(1);
    }

    driver_dns->dns_port = dns_options.port;
    if(driver_dns->domain)
      LOG_WARNING("OUTPUT: DNS tunnel to %s via %s:%d", driver_dns->domain, driver_dns->dns_host, driver_dns->dns_port);
    else
      LOG_WARNING("OUTPUT: DNS tunnel to %s:%d (no domain set! This probably needs to be the exact server where the dnscat2 server is running!)", driver_dns->dns_host, driver_dns->dns_port);
  }
  else
  {
    LOG_FATAL("OUTPUT: Ended up with an unknown output driver!");
    exit(1);
  }

  /* Be sure we clean up at exit. */
  atexit(cleanup);

  /* Add the timeout function */
  select_set_timeout(group, timeout, NULL);
  while(TRUE)
    select_group_do_select(group, 1000);

  return 0;
}