static void run_writer(pid_t peer)
{
    // writer is a type_nest_i writer
    qeo_factory_t *factory;
    qeocore_type_t *type_nest_i;
    qeocore_writer_t *writer;
    qeocore_data_t *outer=NULL;
    qeocore_data_t *inner=NULL;

    int status;

    /* initialize */
    assert(NULL != (factory = qeocore_factory_new(QEO_IDENTITY_DEFAULT)));
    init_factory(factory);
    assert(NULL != (type_nest_i = type_nest_i_register(factory)));
    assert(NULL != (writer = qeocore_writer_open(factory, type_nest_i, NULL,
                                                 QEOCORE_EFLAG_STATE_DATA | QEOCORE_EFLAG_ENABLE,
                                                 NULL, NULL)));
    log_pid("=================================== writer initialized");
    assert(NULL != (outer = qeocore_writer_data_new(writer)));
    /* fill outer struct */
    assert(QEO_OK == qeocore_data_set_member(outer, _outer_int32_id, &_outer_int32_value));
    assert(QEO_OK == qeocore_data_set_member(outer, _outer_int8_id, &_outer_int8_value));
    assert(QEO_OK == qeocore_data_set_member(outer, _outer_string_id, &_outer_string_value));
    assert(QEO_OK == qeocore_data_set_member(outer, _outer_int16_id, &_outer_int16_value));
    assert(QEO_OK == qeocore_data_set_member(outer, _outer_int64_id, &_outer_int64_value));

    /* fill inner struct */
    assert(QEO_OK == qeocore_data_get_member(outer, _inner_id, &inner));
    assert(QEO_OK == qeocore_data_set_member(inner, _inner_int32_id, &_inner_int32_value));
    assert(QEO_OK == qeocore_data_set_member(inner, _inner_int8_id, &_inner_int8_value));
    assert(QEO_OK == qeocore_data_set_member(inner, _inner_string_id, &_inner_string_value));
    assert(QEO_OK == qeocore_data_set_member(inner, _inner_int16_id, &_inner_int16_value));
    assert(QEO_OK == qeocore_data_set_member(inner, _inner_int64_id, &_inner_int64_value));
    assert(QEO_OK == qeocore_data_set_member(outer, _inner_id, &inner));
    log_verbose(" =================== _outer_int32_value = %u \n", _outer_int32_value );
    log_verbose(" =================== _outer_int8_value = %u \n", _outer_int8_value );
    log_verbose(" =================== _outer_int16_value = %u \n", _outer_int16_value );
    log_verbose(" =================== _outer_int64_value = %"PRIu64" \n", _outer_int64_value );
    log_verbose(" =================== _inner_int32_value = %u \n", _inner_int32_value );
    log_verbose(" =================== _inner_int8_value = %u \n", _inner_int8_value );
    log_verbose(" =================== _inner_int16_value = %u \n", _inner_int16_value );
    log_verbose(" =================== _inner_int64_value = %"PRIu64" \n", _inner_int64_value );
    /* write */
    assert(QEO_OK == qeocore_writer_write(writer, outer));
    log_pid("===================================== writer wrote outer data");
    assert(peer == waitpid(peer, &status, 0));
    assert(0 == status);
    log_pid("===================================== writer done");
    /* clean up */
    qeocore_data_free(inner);
    qeocore_data_free(outer);
    qeocore_writer_close(writer);
    qeocore_type_free(type_nest_i);
    qeocore_factory_close(factory);
}
Beispiel #2
0
int
main(void) {
    /*
      * lixiang modify at 2012-02-06
      * if acmanage exit, cron will start it.
      */
#if 0    
    if(get_deamon_state(AC_MANAGE_STATE_FILE)) {
        manage_log(LOG_WARNING, "Ac manage is already running!\n" );
        return -1;
    }
#endif

	manage_init();
//	manage_log(LOG_INFO,"rety = %d\n",rety);

	log_pid(AC_MANAGE_PID_FILE);

	set_deamon_state(AC_MANAGE_STATE_FILE, 1);
	
	manage_register();
	manage_log(LOG_INFO, "acmanage service enable, start process data...\n");
	manage_process();
	manage_receive();

	manage_log(LOG_INFO,"acmanage service disable...\n");
	manage_destory();
	
	return 0;
}
static void my_on_data_available(const qeocore_reader_t *reader,
                                 const qeocore_data_t *data,
                                 uintptr_t userdata)
{
    switch (qeocore_data_get_status(data)) {
        case QEOCORE_DATA: {
            qeocore_data_t *seqdata = NULL;
            byte_array_t array;
            int i, size;

            log_pid("reader received data");
            assert(QEO_OK == qeocore_data_get_member(data, _size_id, &size));
            assert(QEO_OK == qeocore_data_get_member(data, _buf_id, &seqdata));
            assert(QEO_OK == qeocore_data_sequence_get(seqdata, (qeo_sequence_t *)&array, 0, QEOCORE_SIZE_UNLIMITED));
            assert(size == DDS_SEQ_LENGTH(array));
            assert(_test_size == DDS_SEQ_LENGTH(array));
            for (i = 0; i < size; i++) {
                assert(DDS_SEQ_ITEM(array, i) == (i & 0xff));
            }
            qeocore_data_sequence_free(seqdata, (qeo_sequence_t *)&array);
            qeocore_data_free(seqdata);
            sem_post(&_sync); /* release main thread */
            break;
        }
        case QEOCORE_NO_MORE_DATA:
        case QEOCORE_REMOVE:
            /* ignore */
            break;
        default:
            abort();
            break;
    }
}
static void run_writer(pid_t peer)
{
    qeo_factory_t *factory;
    qeocore_type_t *type;
    qeocore_writer_t *writer;
    qeocore_data_t *data, *seqdata;
    byte_array_t array;
    int status, i;

    /* initialize */
    assert(NULL != (factory = qeocore_factory_new(QEO_IDENTITY_DEFAULT)));
    init_factory(factory);
    assert(NULL != (type = type_register(factory)));
    assert(NULL != (writer = qeocore_writer_open(factory, type, NULL,
                                                 QEOCORE_EFLAG_STATE_DATA | QEOCORE_EFLAG_ENABLE,
                                                 NULL, NULL)));
    log_pid("writer initialized");
    assert(NULL != (data = qeocore_writer_data_new(writer)));
    assert(QEO_OK == qeocore_data_set_member(data, _size_id, &_test_size));
    /* init sequence */
    DDS_SEQ_INIT(array);
    assert(NULL != (DDS_SEQ_DATA(array) = malloc(_test_size * sizeof(char))));
    DDS_SEQ_LENGTH(array) = DDS_SEQ_MAXIMUM(array) = _test_size;
    for (i = 0; i < _test_size; i++) {
        DDS_SEQ_ITEM(array, i) = i & 0xff;
    }
    assert(QEO_OK == qeocore_data_get_member(data, _buf_id, &seqdata));
    assert(QEO_OK == qeocore_data_sequence_set(seqdata, (const qeo_sequence_t *)&array, 0));
    assert(QEO_OK == qeocore_data_set_member(data, _buf_id, &seqdata));
    /* write */
    assert(QEO_OK == qeocore_writer_write(writer, data));
    log_pid("writer wrote data");
    assert(peer == waitpid(peer, &status, 0));
    assert(0 == status);
    log_pid("writer done");
    /* clean up */
    free(DDS_SEQ_DATA(array));
    qeocore_data_free(seqdata);
    qeocore_data_free(data);
    qeocore_writer_close(writer);
    qeocore_type_free(type);
    qeocore_factory_close(factory);
}
Beispiel #5
0
void daemonize()
{
    int i;
    umask(0);

    struct rlimit rl;
    if(getrlimit(RLIMIT_NOFILE, &rl)<0)
        perror("getrlimit()");

    pid_t pid;
    if((pid = fork()) < 0)
    {
        perror("fork()");
        exit(errno);
    }
    else if(pid != 0)
    {
        // 父进程退出
        exit(0);
    }

    // 子进程继续运行
    log_pid();

    // 关闭所有文件描述符
    if(rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;
    for(i = 0; i < rl.rlim_max; i++)
    {
        close(i);
    }

    int fd0, fd1, fd2;
    // 取消标准输入
    fd0 = open("/dev/null", O_RDWR);
    // 重定向标准输出至配置的log文件
    fd1 = open(log_path, O_WRONLY|O_APPEND|O_CREAT,
               S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    fd2 = open(log_path, O_WRONLY|O_APPEND|O_CREAT,
               S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);

    dup2(fd0, STDIN_FILENO);
    dup2(fd1, STDOUT_FILENO);
    dup2(fd2, STDERR_FILENO);

    setsid();
    if(chdir("/") == -1)
    {
        perror("chdir()");
        exit(errno);
    }
}
static void run_reader(void)
{
    qeo_factory_t *factory;
    qeocore_type_t *type_nest_i;
    qeocore_reader_t *reader;
    qeocore_reader_listener_t listener = { .on_data = my_on_data_available };

    sem_init(&_sync, 0, 0);
    assert(NULL != (factory = qeocore_factory_new(QEO_IDENTITY_DEFAULT)));
    init_factory(factory);
    assert(NULL != (type_nest_i = type_nest_i_register(factory)));
    assert(NULL != (reader = qeocore_reader_open(factory, type_nest_i, NULL,
                             QEOCORE_EFLAG_STATE_DATA | QEOCORE_EFLAG_ENABLE,
                             &listener, NULL)));
    log_pid("=============================== reader initialized");
    sem_wait(&_sync); /* wait for sample */
    log_pid("=============================== reader done");
    sem_destroy(&_sync);
    qeocore_reader_close(reader);
    qeocore_type_free(type_nest_i);
    qeocore_factory_close(factory);
}
static void my_on_data_available(const qeocore_reader_t *reader,
                                 const qeocore_data_t *data,
                                 uintptr_t userdata)
{
    // the reader is a type_unnest reader
    switch (qeocore_data_get_status(data)) {
        case QEOCORE_DATA: {

            int outer_int32_value_rx=0, outer_int8_value_rx=0, outer_int16_value_rx=0;
            int64_t outer_int64_value_rx=0;
            char* outer_string_value_rx="";
            log_pid("===================================== reader received data");
            assert(QEO_OK == qeocore_data_get_member(data, _outer_int32_id, &outer_int32_value_rx));
            assert(QEO_OK == qeocore_data_get_member(data, _outer_int8_id, &outer_int8_value_rx));
            assert(QEO_OK == qeocore_data_get_member(data, _outer_string_id, &outer_string_value_rx));
            assert(QEO_OK == qeocore_data_get_member(data, _outer_int16_id, &outer_int16_value_rx));
            assert(QEO_OK == qeocore_data_get_member(data, _outer_int64_id, &outer_int64_value_rx));
            log_verbose(" =================== outer_int32_value_rx = %u \n", outer_int32_value_rx );
            log_verbose(" =================== outer_int8_value_rx = %u \n", outer_int8_value_rx );
            log_verbose(" =================== outer_string_value_rx = \"%s\" \n", outer_string_value_rx );
            log_verbose(" =================== outer_int16_value_rx = %u \n", outer_int16_value_rx );
            log_verbose(" =================== outer_int64_value_rx = %"PRIu64" \n", outer_int64_value_rx );
            assert(outer_int32_value_rx==_outer_int32_value);
            assert(outer_int8_value_rx==_outer_int8_value);
            assert(0 == strcmp(_outer_string_value, outer_string_value_rx));
            assert(outer_int16_value_rx==_outer_int16_value);
            assert(outer_int64_value_rx==_outer_int64_value);
            free(outer_string_value_rx);
            sem_post(&_sync); /* release main thread */
            break;
        }
        case QEOCORE_NO_MORE_DATA:
        case QEOCORE_REMOVE:
            /* ignore */
            break;
        default:
            abort();
            break;
    }
}
Beispiel #8
0
int main(int argc, char **argv)
{
	/* command line options */
	int c;

	/* function-local options */
	int foreground = FALSE;
	char *pid_file = NULL;

	/* config file */
	char *configFile = NULL;

	/* config file parsing temp strings */
	char tmp[MAX_CONFIG_STRING_SIZE], *tmpstr;

	/* open a connection to the syslog daemon */
	openlog("pptpd", LOG_PID, PPTP_FACILITY);
	syslog(LOG_ERR, "MGR: Config file not found!");

	/* process command line options */
	while (1) {
		int option_index = 0;
#ifdef BCRELAY
		char *optstring = "b:c:de:fhil:o:p:s:t:T:vwC:Dk";
#else
		char *optstring = "c:de:fhil:o:p:s:t:T:vwC:Dk";
#endif

		static struct option long_options[] =
		{
#ifdef BCRELAY
			{"bcrelay", 1, 0, 0},
#endif
			{"conf", 1, 0, 'c'},
			{"debug", 0, 0, 'd'},
			{"ppp", 1, 0, 'e'},
			{"fg", 0, 0, 'f'},
			{"help", 0, 0, 'h'},
			{"noipparam", 0, 0, 'i'},
			{"listen", 1, 0, 'l'},
			{"option", 1, 0, 'o'},
			{"pidfile", 1, 0, 'p'},
			{"speed", 1, 0, 's'},
			{"stimeout", 1, 0, 't'},
			{"ptimeout", 1, 0, 'T'},
			{"version", 0, 0, 'v'},
			{"logwtmp", 0, 0, 'w'},
			{"connections", 1, 0, 'C'},
			{"delegate", 0, 0, 'D'},
			{"keep", 0, 0, 'k'},
			{0, 0, 0, 0}
		};

		c = getopt_long(argc, argv, optstring, long_options, &option_index);
		if (c == -1)
			break;
		/* convert long options to short form */
		if (c == 0)
#ifdef BCRELAY
			c = "bcdefhilopstvwCDk"[option_index];
#else
			c = "cdefhilopstvwCDk"[option_index];
#endif
		switch (c) {
#ifdef BCRELAY
		case 'b': /* --bcrelay */
			if (bcrelay) free(bcrelay);
			bcrelay = strdup(optarg);
			break;
#endif

		case 'l': /* --listen */
			tmpstr = lookup(optarg);
			if (!tmpstr) {
				syslog(LOG_ERR, "MGR: Invalid listening address: %s!", optarg);
				return 1;
			}
			if (bindaddr) free(bindaddr);
			bindaddr = strdup(tmpstr);
			break;

		case 'h': /* --help */
			showusage(argv[0]);
			return 0;

		case 'i': /* --noipparam */
			pptp_noipparam = TRUE;
			break;

		case 'e': /* --ppp */
			if (ppp_binary) free(ppp_binary);
			ppp_binary = strdup(optarg);
			break;

		case 'd': /* --debug */
			pptp_debug = TRUE;
			break;

		case 'f': /* --fg */
			foreground = TRUE;
			break;

		case 'v': /* --version */
			showversion();
			return 0;

		case 'w': /* --logwtmp */
		        pptp_logwtmp = TRUE;
			break;

		case 'C': /* --connections */
		        pptp_connections = atoi(optarg);
			break;

		case 'D': /* --delegate */
		        pptp_delegate = TRUE;
			break;

		case 'o': /* --option */
			if (pppdoptstr) free(pppdoptstr);
			pppdoptstr = strdup(optarg);
			break;

		case 'p': /* --pidfile */
			if (pid_file) free(pid_file);
			pid_file = strdup(optarg);
			break;

		case 's': /* --speed */
			if (speedstr) free(speedstr);
			speedstr = strdup(optarg);
			break;

		case 't': /* --stimeout */
			pptp_stimeout = atoi(optarg);
			break;

		case 'T': /* --stimeout */
			pptp_ptimeout = atoi(optarg);
			break;
		case 'k': /* --keep */
			keep_connections = 1;
			break;

		case 'c': /* --conf */
			{
				FILE *f;
				if (!(f = fopen(optarg, "r"))) {
					syslog(LOG_ERR, "MGR: Config file not found!");
					return 1;
				}
				fclose(f);
				if(configFile) free(configFile);
				configFile = strdup(optarg);
				break;
			}

		default:
			showusage(argv[0]);
			return 1;
		}
	}

	/* Now that we have all the command line args.. lets open the
	 * conf file and add anything else (remembering not to override
	 * anything since the command line has more privilages :-)
	 */

	if (!configFile)
		configFile = strdup(PPTPD_CONFIG_FILE_DEFAULT);

	if (read_config_file(configFile, CONNECTIONS_KEYWORD, tmp) > 0) {
		pptp_connections = atoi(tmp);
		if (pptp_connections <= 0)
			pptp_connections = CONNECTIONS_DEFAULT;
	}

	slot_init(pptp_connections);

	if (!pptp_debug && read_config_file(configFile, DEBUG_KEYWORD, tmp) > 0)
		pptp_debug = TRUE;

#ifdef BCRELAY
	if (!bcrelay && read_config_file(configFile, BCRELAY_KEYWORD, tmp) > 0) 
		bcrelay = strdup(tmp);
#endif

	if (!pptp_stimeout && read_config_file(configFile, STIMEOUT_KEYWORD, tmp) > 0) {
		pptp_stimeout = atoi(tmp);
		if (pptp_stimeout <= 0)
			pptp_stimeout = STIMEOUT_DEFAULT;
	}

	if (!pptp_ptimeout && read_config_file(configFile, PTIMEOUT_KEYWORD, tmp) > 0) {
		pptp_ptimeout = atoi(tmp);
		if (pptp_ptimeout <= 0)
			pptp_ptimeout = PTIMEOUT_DEFAULT;
	}

	if (!pptp_noipparam && read_config_file(configFile, NOIPPARAM_KEYWORD, tmp) > 0) {
		pptp_noipparam = TRUE;
	}

	if (!bindaddr && read_config_file(configFile, LISTEN_KEYWORD, tmp) > 0) {
		tmpstr = lookup(tmp);
		if(!tmpstr) {
			syslog(LOG_ERR, "MGR: Invalid listening address: %s!", tmp);
			return 1;
		}
		bindaddr = strdup(tmpstr);
	}

	if (!speedstr && read_config_file(configFile, SPEED_KEYWORD, tmp) > 0)
		speedstr = strdup(tmp);

	if (!pppdoptstr && read_config_file(configFile, PPPD_OPTION_KEYWORD, tmp) > 0) {
		pppdoptstr = strdup(tmp);
	}

	if (!ppp_binary && read_config_file(configFile, PPP_BINARY_KEYWORD, tmp) > 0) {
		ppp_binary = strdup(tmp);
	}

	if (!pptp_logwtmp && read_config_file(configFile, LOGWTMP_KEYWORD, tmp) > 0) {
		pptp_logwtmp = TRUE;
	}

	if (!pptp_delegate && read_config_file(configFile, DELEGATE_KEYWORD, tmp) > 0) {
		pptp_delegate = TRUE;
	}

	if (read_config_file(configFile, KEEP_KEYWORD, tmp) > 0) {
		keep_connections = TRUE;
	}

	if (!pid_file)
		pid_file = strdup((read_config_file(configFile, PIDFILE_KEYWORD,
					tmp) > 0) ? tmp : PIDFILE_DEFAULT);

	if (!pptp_delegate) {
		/* NOTE: remote then local, reason can be seen at the end of processIPStr */

		/* grab the remoteip string from the config file */
		if (read_config_file(configFile, REMOTEIP_KEYWORD, tmp) <= 0) {
			/* use "smart" defaults */
			strlcpy(tmp, DEFAULT_REMOTE_IP_LIST, sizeof(tmp));
		}
		processIPStr(REMOTE, tmp);
	
		/* grab the localip string from the config file */
		if (read_config_file(configFile, LOCALIP_KEYWORD, tmp) <= 0) {
			/* use "smart" defaults */
			strlcpy(tmp, DEFAULT_LOCAL_IP_LIST, sizeof(tmp));
		}
		processIPStr(LOCAL, tmp);
	}

	free(configFile);

	/* if not yet set, adopt default PPP binary path */
	if (!ppp_binary) ppp_binary = strdup(PPP_BINARY);
	/* check that the PPP binary is executable */
	if (access(ppp_binary, X_OK) < 0) {
		syslog(LOG_ERR, "MGR: PPP binary %s not executable",
		       ppp_binary);
		return 1;
	}
	/* check that the PPP options file is readable */
	if (pppdoptstr && access(pppdoptstr, R_OK) < 0) {
		syslog(LOG_ERR, "MGR: PPP options file %s not readable",
		       pppdoptstr);
		return 1;
	}
#ifdef BCRELAY
	/* check that the bcrelay binary is executable */
	if (bcrelay && access(BCRELAY_BIN, X_OK) < 0) {
		syslog(LOG_ERR, "MGR: bcrelay binary %s not executable", 
		       BCRELAY_BIN);
		return 1;
	}
#endif

	syslog(LOG_INFO, "accel-pptpd-%s compiled for pppd-%s\n",VERSION, "2.4.2");

	if (!foreground) {
#if HAVE_DAEMON
		closelog();
		freopen("/dev/null", "r", stdin);
		daemon(0, 0);
		/* returns to child only */
		/* pid will have changed */
		openlog("pptpd", LOG_PID, PPTP_FACILITY);
#else	/* !HAVE_DAEMON */
		my_daemon(argc, argv);
		/* returns to child if !HAVE_FORK
		 * never returns if HAVE_FORK (re-execs with -f)
		 */
#endif
	}

#ifdef BCRELAY
      if (bcrelay) {
             syslog(LOG_DEBUG, "CTRL: BCrelay incoming interface is %s", bcrelay);
             /* Launch BCrelay  */
#ifndef HAVE_FORK
             switch(bcrelayfork = vfork()){
#else
             switch(bcrelayfork = fork()){
#endif
             case -1:        /* fork() error */
                   syslog(LOG_ERR, "CTRL: Error forking to exec bcrelay");
                   _exit(1);

             case 0:         /* child */
                   syslog(LOG_DEBUG, "CTRL (BCrelay Launcher): Launching BCrelay with pid %i", bcrelayfork);
                   launch_bcrelay();
                   syslog(LOG_ERR, "CTRL (BCrelay Launcher): Failed to launch BCrelay.");
                   _exit(1);
             }
       } /* End bcrelay */
#endif

#ifdef CONFIG_NETtel
	/* turn the NETtel VPN LED on */
	ledman_cmd(LEDMAN_CMD_ON, LEDMAN_VPN);
#endif
	/* after we have our final pid... */
	log_pid(pid_file);

	/* manage connections until SIGTERM */
	pptp_manager(argc, argv);
	
#ifdef BCRELAY
	if (bcrelayfork > 0) {
		syslog(LOG_DEBUG, "CTRL: Closing child BCrelay with pid %i", bcrelayfork);
		kill(bcrelayfork, SIGTERM);
	}
#endif

	slot_free();
	return 0;
}

static void log_pid(char *pid_file) {
        FILE    *f;
        pid_t   pid;

        pid = getpid();
        if ((f = fopen(pid_file, "w")) == NULL) {
                syslog(LOG_ERR, "PPTPD: failed to open(%s), errno=%d\n",
                        pid_file, errno);
                return;
        }
        fprintf(f, "%d\n", pid);
        fclose(f);
}
Beispiel #9
0
int main(int argc, char **argv)
{
  /* gengeopt declarations */
  struct gengetopt_args_info args_info;

  struct hostent *host;

  /* Handle keyboard interrupt SIGINT */
  struct sigaction s;
  s.sa_handler = (void *) signal_handler;
  if ((0 != sigemptyset( &s.sa_mask )) && debug)
    printf("sigemptyset failed.\n");
  s.sa_flags = SA_RESETHAND;
  if ((sigaction(SIGINT, &s, NULL) != 0) && debug)
    printf("Could not register SIGINT signal handler.\n");
	
  fd_set fds;			/* For select() */
  struct timeval idleTime;	/* How long to select() */


  int timelimit; /* Number of seconds to be connected */
  int starttime; /* Time program was started */

  /* open a connection to the syslog daemon */
  /*openlog(PACKAGE, LOG_PID, LOG_DAEMON);*/

  /* TODO: Only use LOG__PERROR for linux */
#ifdef __linux__
  openlog(PACKAGE, (LOG_PID | LOG_PERROR), LOG_DAEMON);
#else
  openlog(PACKAGE, (LOG_PID), LOG_DAEMON);
#endif


  if (cmdline_parser (argc, argv, &args_info) != 0)
    exit(1);
  if (args_info.debug_flag) {
    printf("listen: %s\n", args_info.listen_arg);
    if (args_info.conf_arg) printf("conf: %s\n", args_info.conf_arg);
    printf("fg: %d\n", args_info.fg_flag);
    printf("debug: %d\n", args_info.debug_flag);
    printf("qos: %#08x\n", args_info.qos_arg);
    if (args_info.apn_arg) printf("apn: %s\n", args_info.apn_arg);
    if (args_info.net_arg) printf("net: %s\n", args_info.net_arg);
    if (args_info.dynip_arg) printf("dynip: %s\n", args_info.dynip_arg);
    if (args_info.statip_arg) printf("statip: %s\n", args_info.statip_arg);
    if (args_info.ipup_arg) printf("ipup: %s\n", args_info.ipup_arg);
    if (args_info.ipdown_arg) printf("ipdown: %s\n", args_info.ipdown_arg);
    if (args_info.pidfile_arg) printf("pidfile: %s\n", args_info.pidfile_arg);
    if (args_info.statedir_arg) printf("statedir: %s\n", args_info.statedir_arg);
    printf("timelimit: %d\n", args_info.timelimit_arg);
  }

  /* Try out our new parser */
  
  if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0, 0, 0) != 0)
    exit(1);
  if (args_info.debug_flag) {
    printf("cmdline_parser_configfile\n");
    printf("listen: %s\n", args_info.listen_arg);
    printf("conf: %s\n", args_info.conf_arg);
    printf("fg: %d\n", args_info.fg_flag);
    printf("debug: %d\n", args_info.debug_flag);
    printf("qos: %#08x\n", args_info.qos_arg);
    if (args_info.apn_arg) printf("apn: %s\n", args_info.apn_arg);
    if (args_info.net_arg) printf("net: %s\n", args_info.net_arg);
    if (args_info.dynip_arg) printf("dynip: %s\n", args_info.dynip_arg);
    if (args_info.statip_arg) printf("statip: %s\n", args_info.statip_arg);
    if (args_info.ipup_arg) printf("ipup: %s\n", args_info.ipup_arg);
    if (args_info.ipdown_arg) printf("ipdown: %s\n", args_info.ipdown_arg);
    if (args_info.pidfile_arg) printf("pidfile: %s\n", args_info.pidfile_arg);
    if (args_info.statedir_arg) printf("statedir: %s\n", args_info.statedir_arg);
    printf("timelimit: %d\n", args_info.timelimit_arg);
  }

  /* Handle each option */

  /* debug                                                        */
  debug = args_info.debug_flag;

  /* listen                                                       */
  /* Do hostname lookup to translate hostname to IP address       */
  /* Any port listening is not possible as a valid address is     */
  /* required for create_pdp_context_response messages            */
  if (args_info.listen_arg) {
    if (!(host = gethostbyname(args_info.listen_arg))) {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "Invalid listening address: %s!", args_info.listen_arg);
      exit(1);
    }
    else {
      memcpy(&listen_.s_addr, host->h_addr, host->h_length);
    }
  }
  else {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Listening address must be specified! "
	    "Please use command line option --listen or "
	    "edit %s configuration file\n", args_info.conf_arg);
    exit(1);
  }
  

  /* net                                                          */
  /* Store net as in_addr net and mask                            */
  if (args_info.net_arg) {
    if(ippool_aton(&net, &mask, args_info.net_arg, 0)) {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "Invalid network address: %s!", args_info.net_arg);
      exit(1);
    }
    netaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
    destaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
  }
  else {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Network address must be specified: %s!", args_info.net_arg);
    exit(1);
  }

  /* dynip                                                        */
  if (!args_info.dynip_arg) {
    if (ippool_new(&ippool, args_info.net_arg, NULL, 1, 0,
		   IPPOOL_NONETWORK | IPPOOL_NOGATEWAY | IPPOOL_NOBROADCAST)) {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "Failed to allocate IP pool!");
      exit(1);
    }
  }
  else {
    if (ippool_new(&ippool, args_info.dynip_arg, NULL, 1 ,0,
		   IPPOOL_NONETWORK | IPPOOL_NOGATEWAY | IPPOOL_NOBROADCAST)) {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "Failed to allocate IP pool!");
      exit(1);
    }
  }

  /* DNS1 and DNS2 */
#ifdef HAVE_INET_ATON
  dns1.s_addr = 0;
  if (args_info.pcodns1_arg) {
    if (0 == inet_aton(args_info.pcodns1_arg, &dns1)) {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "Failed to convert pcodns1!");
      exit(1);
    }
  }
  dns2.s_addr = 0;
  if (args_info.pcodns2_arg) {
    if (0 == inet_aton(args_info.pcodns2_arg, &dns2)) {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "Failed to convert pcodns2!");
      exit(1);
    }
  }
#else
  dns1.s_addr = 0;
  if (args_info.pcodns1_arg) {
    dns1.s_addr = inet_addr(args_info.pcodns1_arg);
    if (dns1.s_addr == -1)  {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "Failed to convert pcodns1!");
      exit(1);
    }
  }
  dns2.s_addr = 0;
  if (args_info.pcodns2_arg) {
    dns2.s_addr = inet_addr(args_info.pcodns2_arg);
    if (dns2.s_addr == -1) {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "Failed to convert pcodns2!");
      exit(1);
    }
  }
#endif


  pco.l = 20;
  pco.v[0] = 0x80; /* x0000yyy x=1, yyy=000: PPP */
  pco.v[1] = 0x80; /* IPCP */
  pco.v[2] = 0x21; 
  pco.v[3] = 0x10; /* Length of contents */
  pco.v[4] = 0x02; /* ACK */
  pco.v[5] = 0x00; /* ID: Need to match request */
  pco.v[6] = 0x00; /* Length */
  pco.v[7] = 0x10;
  pco.v[8] = 0x81; /* DNS 1 */
  pco.v[9] = 0x06;
  memcpy(&pco.v[10], &dns1, sizeof(dns1));
  pco.v[14] = 0x83;
  pco.v[15] = 0x06; /* DNS 2 */
  memcpy(&pco.v[16], &dns2, sizeof(dns2));

  /* ipup */
  ipup = args_info.ipup_arg;

  /* ipdown */
  ipdown = args_info.ipdown_arg;

  /* Timelimit                                                       */
  timelimit = args_info.timelimit_arg;
  starttime = time(NULL);
  
  /* qos                                                             */
  qos.l = 3;
  qos.v[2] = (args_info.qos_arg) & 0xff;
  qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
  qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;

  /* apn                                                             */
  if (strlen(args_info.apn_arg) > (sizeof(apn.v)-1)) {
    printf("Invalid APN\n");
    return -1;
  }
  apn.l = strlen(args_info.apn_arg) + 1;
  apn.v[0] = (char) strlen(args_info.apn_arg);
  strncpy((char *) &apn.v[1], args_info.apn_arg, sizeof(apn.v)-1);


  /* foreground                                                   */
  /* If flag not given run as a daemon                            */
  if (!args_info.fg_flag)
    {
      closelog(); 
      /* Close the standard file descriptors. */
      /* Is this really needed ? */
      freopen("/dev/null", "w", stdout);
      freopen("/dev/null", "w", stderr);
      freopen("/dev/null", "r", stdin);
      daemon(0, 0);
      /* Open log again. This time with new pid */
      openlog(PACKAGE, LOG_PID, LOG_DAEMON);
    }

  /* pidfile */
  /* This has to be done after we have our final pid */
  if (args_info.pidfile_arg) {
    log_pid(args_info.pidfile_arg);
  }
  

  if (debug) printf("gtpclient: Initialising GTP tunnel\n");
  
  if (gtp_new(&gsn, args_info.statedir_arg,  &listen_, GTP_MODE_GGSN)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Failed to create gtp");
    exit(1);
  }
  if (gsn->fd0 > maxfd) maxfd = gsn->fd0;
  if (gsn->fd1c > maxfd) maxfd = gsn->fd1c;
  if (gsn->fd1u > maxfd) maxfd = gsn->fd1u;

  gtp_set_cb_data_ind(gsn, encaps_tun);
  gtp_set_cb_delete_context(gsn, delete_context);
  gtp_set_cb_create_context_ind(gsn, create_context_ind);


  /* Create a tunnel interface */
  if (debug) printf("Creating tun interface\n");
  if (tun_new((struct tun_t**) &tun)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Failed to create tun");
    if (debug) printf("Failed to create tun\n");
    exit(1);
  }

  if (debug) printf("Setting tun IP address\n");
  if (tun_setaddr(tun, &netaddr, &destaddr, &mask)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Failed to set tun IP address");
    if (debug) printf("Failed to set tun IP address\n");
    exit(1);
  }


  tun_set_cb_ind(tun, cb_tun_ind);
  if (tun->fd > maxfd) maxfd = tun->fd;
  
  if (ipup) tun_runscript(tun, ipup);

  /******************************************************************/
  /* Main select loop                                               */
  /******************************************************************/

  while ((((starttime + timelimit) > time(NULL)) || (0 == timelimit)) && (!end)) {

    FD_ZERO(&fds);
    if (tun) FD_SET(tun->fd, &fds);
    FD_SET(gsn->fd0, &fds);
    FD_SET(gsn->fd1c, &fds);
    FD_SET(gsn->fd1u, &fds);
    
    gtp_retranstimeout(gsn, &idleTime);
    switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
    case -1:	/* errno == EINTR : unblocked signal */
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "select() returned -1");
      /* On error, select returns without modifying fds */
      FD_ZERO(&fds);
      break;  
    case 0:
      /* printf("Select returned 0\n"); */
      gtp_retrans(gsn); /* Only retransmit if nothing else */
      break; 
    default:
      break;
    }

    if (tun->fd != -1 && FD_ISSET(tun->fd, &fds) && 
	tun_decaps(tun) < 0) {
      sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	      "TUN read failed (fd)=(%d)", tun->fd);
    }
    
    if (FD_ISSET(gsn->fd0, &fds))
      gtp_decaps0(gsn);
    
    if (FD_ISSET(gsn->fd1c, &fds))
      gtp_decaps1c(gsn);
    
    if (FD_ISSET(gsn->fd1u, &fds))
      gtp_decaps1u(gsn);
    
  }

  cmdline_parser_free(&args_info);
  ippool_free(ippool);
  gtp_free(gsn);
  tun_free(tun);
  
  return 1;
  
}