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); }
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); }
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; } }
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); }
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; }