int main (int argc, char *argv[]) { int sfd; struct ev_loop *loop = EV_DEFAULT; if (argc < 2) { fprintf(stderr, "usage: %s port\n", progname(argv[0])); exit(EXIT_FAILURE); } sfd = bind_and_listen(argv[1]); //printf("main: sfd = %d\n", sfd); /* Set sfd to non-blocking mode before using with libev */ set_nonblock(sfd); ev_io_init (&listen_watcher, listen_cb, sfd, EV_READ); ev_io_start (EV_A_ &listen_watcher); /* Start the event loop */ ev_run (EV_A_ 0); return EXIT_SUCCESS; }
void bind_and_listen(const std::string& port,bool reuse_addr,boost::system::error_code& e) { try { bind_and_listen(port,reuse_addr); } catch (const boost::system::system_error& ex) { e = ex.code(); ORCHID_DEBUG("bind_and_listen error: %s",e.message().c_str()); } }
bool GSISocketServer::Open() { char portstring[36]; snprintf(portstring, 35, "%ld", (long int)port); sck = bind_and_listen(portstring, backlog, logh); return sck != -1; }
int listen_sockaddr(const char *netaddr, void (*cb)(int, void *)) { struct addrinfo *result, *res; int got_address; if ((result = prepare_getaddrinfo(netaddr, 0)) == NULL) return -1; got_address = 0; for (res = result; res != NULL; res = res->ai_next) got_address |= bind_and_listen(res, cb); freeaddrinfo(result); return got_address ? 0 : -1; }
int Serv::initServ(struct conf_data *pconf_data) { pepd_conf = new struct epd_config; if(pepd_conf == NULL){ WARNING_LOG("Out of memory."); return -1; } if( init_epd_config(pepd_conf, pconf_data) < 0 ){ WARNING_LOG("init_epd_config failed"); return -1; } if( bind_and_listen(pepd_conf->server_port) < 0){ WARNING_LOG("failed to bind and listen!"); return -1; } return 0; }
/// This is main... int main(int argc,char* argv[]) { int ret; in_port_t fixedport = 0; struct sockaddr_storage fixedhost; struct addrinfo hints, *res, *reslist; struct tracker_s * conn; memset(&fixedhost, '\0', sizeof(fixedhost)); printf("netsed " VERSION " by Alexey Shumkin <*****@*****.**>\n" " based on 1.2 from Julien VdG <*****@*****.**>\n" " which is based on 0.01c from Michal Zalewski <*****@*****.**>\n"); setbuffer(stdout,NULL,0); parse_params(argc, argv); memset(&hints, '\0', sizeof(hints)); hints.ai_family = family; hints.ai_flags = AI_CANONNAME; hints.ai_socktype = tcp ? SOCK_STREAM : SOCK_DGRAM; if ((ret = getaddrinfo(rhost, rport, &hints, &reslist))) { ERR("getaddrinfo(): %s\n", gai_strerror(ret)); error("Impossible to resolve remote address or port."); } /* We have candidates for remote host. */ for (res = reslist; res; res = res->ai_next) { int sd = -1; if ( (sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) continue; /* Has successfully built a socket for this address family. */ /* Record the address structure and the port. */ fixedport = get_port(res->ai_addr); if (!is_addr_any(res->ai_addr)) memcpy(&fixedhost, res->ai_addr, res->ai_addrlen); close(sd); break; } freeaddrinfo(reslist); if (res == NULL) error("Failed in resolving remote host."); if (fixedhost.ss_family && fixedport) printf("[+] Using fixed forwarding to %s,%s.\n",rhost,rport); else if (fixedport) printf("[+] Using dynamic (transparent proxy) forwarding with fixed port %s.\n",rport); else if (fixedhost.ss_family) printf("[+] Using dynamic (transparent proxy) forwarding with fixed addr %s.\n",rhost); else printf("[+] Using dynamic (transparent proxy) forwarding.\n"); if (foreground) { printf("Run in foreground...\n"); } else { int x = fork(); if (x == -1) { printf("Error creating a fork. Run in foreground...\n"); } else if (x) { printf("Detached: PID=%d\n", x); exit(0); } } bind_and_listen(fixedhost.ss_family, tcp, lport); printf("[+] Listening on port %s/%s.\n", lport, (tcp)?"tcp":"udp"); signal(SIGPIPE, SIG_IGN); struct sigaction sa; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sa.sa_handler = sig_int; if (sigaction(SIGINT, &sa, NULL) == -1) error("netsed: sigaction() failed"); while (!stop) { struct sockaddr_storage s; socklen_t l = sizeof(s); struct sockaddr_storage conho; in_port_t conpo; char ipstr[INET6_ADDRSTRLEN], portstr[12]; int sel; fd_set rd_set; struct timeval timeout, *ptimeout; int nfds = lsock; FD_ZERO(&rd_set); FD_SET(lsock,&rd_set); timeout.tv_sec = UDP_TIMEOUT+1; timeout.tv_usec = 0; ptimeout = NULL; { conn = connections; while(conn != NULL) { if(tcp) { FD_SET(conn->csock, &rd_set); if (nfds < conn->csock) nfds = conn->csock; } else { // adjust timeout to earliest connection end time int remain = UDP_TIMEOUT - (now - conn->time); if (remain < 0) remain = 0; if (timeout.tv_sec > remain) { timeout.tv_sec = remain; // time updated to need to timeout ptimeout = &timeout; } } FD_SET(conn->fsock, &rd_set); if (nfds < conn->fsock) nfds = conn->fsock; // point on next conn = conn->n; } } sel=select(nfds+1, &rd_set, (fd_set*)0, (fd_set*)0, ptimeout); time(&now); if (stop) { break; } if (sel < 0) { DBG("[!] select fail! %s\n", strerror(errno)); break; } if (sel == 0) { DBG("[*] select timeout. now: %d\n", now); // Here we still have to go through the list to expire some udp // connection if they timed out... But no descriptor will be set. // For tcp, select will not timeout. } if (FD_ISSET(lsock, &rd_set)) { int csock=-1; ssize_t rd=-1; if (tcp) { csock = accept(lsock,(struct sockaddr*)&s,&l); } else { // udp does not handle accept, so track connections manually // also set csock if a new connection need to be registered // to share the code with tcp ;) rd = recvfrom(lsock,buf,sizeof(buf),0,(struct sockaddr*)&s,&l); if(rd >= 0) { conn = connections; while(conn != NULL) { // look for existing connections if ((conn->csl == l) && (0 == memcmp(&s, conn->csa, l))) { // found break; } // point on next conn = conn->n; } // not found if(conn == NULL) { // udp 'connection' socket is the listening one csock = lsock; } else { DBG("[+] Got incoming datagram from existing connection.\n"); } } else { ERR("recvfrom(): %s", strerror(errno)); } } // new connection (tcp accept, or udp conn not found) if ((csock)>=0) { int one=1; getnameinfo((struct sockaddr *) &s, l, ipstr, sizeof(ipstr), portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV); printf("[+] Got incoming connection from %s,%s", ipstr, portstr); conn = malloc(sizeof(struct tracker_s)); if(NULL == conn) error("netsed: unable to malloc() connection tracker struct"); // protocol specific init if (tcp) { setsockopt(csock,SOL_SOCKET,SO_OOBINLINE,&one,sizeof(int)); conn->csa = NULL; conn->csl = 0; conn->state = ESTABLISHED; } else { conn->csa = malloc(l); if(NULL == conn->csa) error("netsed: unable to malloc() connection tracker sockaddr struct"); memcpy(conn->csa, &s, l); conn->csl = l; conn->state = UNREPLIED; } conn->csock = csock; conn->time = now; conn->live = malloc(rules * sizeof(struct rule_item)); if(NULL == conn->live) error("netsed: unable to malloc() connection tracker sockaddr struct"); memcpy(conn->live, rule_live, rules * sizeof(struct rule_item)); l = sizeof(s); #ifndef LINUX_NETFILTER // was OK for linux 2.2 nat getsockname(csock,(struct sockaddr*)&s,&l); #else // for linux 2.4 and later getsockopt(csock, SOL_IP, SO_ORIGINAL_DST,(struct sockaddr*)&s,&l); #endif getnameinfo((struct sockaddr *) &s, l, ipstr, sizeof(ipstr), portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV); printf(" to %s,%s\n", ipstr, portstr); conpo = get_port((struct sockaddr *) &s); memcpy(&conho, &s, sizeof(conho)); if (fixedport) conpo=fixedport; if (fixedhost.ss_family) memcpy(&conho, &fixedhost, sizeof(conho)); // forward to addr memcpy(&s, &conho, sizeof(s)); set_port((struct sockaddr *) &s, conpo); getnameinfo((struct sockaddr *) &s, l, ipstr, sizeof(ipstr), portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV); printf("[*] Forwarding connection to %s,%s\n", ipstr, portstr); // connect will bind with some dynamic addr/port conn->fsock = socket(s.ss_family, tcp ? SOCK_STREAM : SOCK_DGRAM, 0); if (connect(conn->fsock,(struct sockaddr*)&s,l)) { printf("[!] Cannot connect to remote server, dropping connection.\n"); freetracker(conn); conn = NULL; } else { setsockopt(conn->fsock,SOL_SOCKET,SO_OOBINLINE,&one,sizeof(int)); conn->n = connections; connections = conn; } } // udp has data process forwarding if((rd >= 0) && (conn != NULL)) { b2server_sed(conn, rd); } } // lsock is set // all other sockets conn = connections; struct tracker_s ** pconn = &connections; while(conn != NULL) { // incoming data ? if(tcp && FD_ISSET(conn->csock, &rd_set)) { client2server_sed(conn); } if(FD_ISSET(conn->fsock, &rd_set)) { server2client_sed(conn); } // timeout ? udp only DBG("[!] connection last time: %d, now: %d\n", conn->time, now); if(!tcp && ((now - conn->time) >= UDP_TIMEOUT)) { DBG("[!] connection timeout.\n"); conn->state = TIMEOUT; } if(conn->state >= DISCONNECTED) { // remove it (*pconn)=conn->n; freetracker(conn); conn=(*pconn); } else { // point on next pconn = &(conn->n); conn = conn->n; } } } clean_socks(); exit(0); }
int main(int argc, char* argv[]) { signal(SIGSEGV, crash_sig); signal(SIGABRT, crash_sig); signal(SIGPIPE, SIG_IGN); char cmd[1024]; int localfd, remotefd; library_conf_t conf; int opt; char* ip = NULL; unsigned int port = 6687; struct in_addr a; struct option long_options[] = { {"aes", 1, NULL, 'a'}, {"des", 1, NULL, 'd'}, {"gzip", 0, NULL, 'g'}, {"mask", 1, NULL, 'm'}, {"localip", 1, NULL, 'l'}, {"server", 1, NULL, 's'}, {"port", 1, NULL, 'p'}, {NULL, 0, NULL, 0} }; char short_options[512] = {0}; longopt2shortopt(long_options, sizeof(long_options) / sizeof(struct option), short_options); conf.localip = 0; conf.netmask = 24; conf.use_gzip = 0; conf.use_aes = 0; conf.aes_key_file = NULL; conf.use_des = 0; conf.des_key_file = NULL; while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (opt) { case 'a': conf.use_aes = 1; conf.aes_key_file = optarg; break; case 'd': conf.use_des = 1; conf.des_key_file = optarg; break; case 'g': conf.use_gzip = 1; break; case 'l': conf.localip = inet_addr(optarg); break; case 's': ip = optarg; break; case 'm': conf.netmask = atoi(optarg); break; case 'p': port = atoi(optarg); break; default: fprintf(stderr, "param error\n"); return 1; } } if (conf.localip == 0) { fprintf(stderr, "localip is zero\n"); return 1; } if (port == 0) { fprintf(stderr, "port is zero\n"); return 1; } memset(this.dev_name, 0, IFNAMSIZ); localfd = tun_open(this.dev_name); if (localfd == -1) return 1; fprintf(stdout, "%s opened\n", this.dev_name); a.s_addr = conf.localip; if (ip == NULL) { if (conf.netmask == 0 || conf.netmask > 31) { fprintf(stderr, "netmask must > 0 and <= 31\n"); return 1; } library_init(conf); remotefd = bind_and_listen(port); if (remotefd == -1) return 1; sprintf(cmd, "ifconfig %s %s/%u up", this.dev_name, inet_ntoa(a), conf.netmask); SYSTEM_EXIT(cmd); a.s_addr = conf.localip & LEN2MASK(conf.netmask); sprintf(cmd, "route add -net %s/%u dev %s", inet_ntoa(a), conf.netmask, this.dev_name); SYSTEM_EXIT(cmd); server_loop(remotefd, localfd); } else { unsigned char mask; int inited = 0; library_init(conf); while (1) { remotefd = connect_server(ip, port); if (remotefd == -1) { sleep(5); continue; } if (!inited) { sprintf(cmd, "ifconfig %s %s up", this.dev_name, inet_ntoa(a)); SYSTEM_EXIT(cmd); mask = netmask(); a.s_addr = conf.localip & LEN2MASK(mask); sprintf(cmd, "route add -net %s/%u dev %s", inet_ntoa(a), mask, this.dev_name); SYSTEM_EXIT(cmd); inited = 1; } client_loop(remotefd, localfd); close(remotefd); fprintf(stderr, "retry\n"); } } return 0; }
int lrmd_init_remote_tls_server() { int rc; int filter; int port = crm_default_remote_port(); struct addrinfo hints, *res = NULL, *iter; char port_str[6]; // at most "65535" gnutls_datum_t psk_key = { NULL, 0 }; static struct mainloop_fd_callbacks remote_listen_fd_callbacks = { .dispatch = lrmd_remote_listen, .destroy = lrmd_remote_connection_destroy, }; crm_notice("Starting TLS listener on port %d", port); crm_gnutls_global_init(); gnutls_global_set_log_function(debug_log); if (pcmk__init_tls_dh(&dh_params) != GNUTLS_E_SUCCESS) { return -1; } gnutls_psk_allocate_server_credentials(&psk_cred_s); gnutls_psk_set_server_credentials_function(psk_cred_s, lrmd_tls_server_key_cb); gnutls_psk_set_server_dh_params(psk_cred_s, dh_params); /* The key callback won't get called until the first client connection * attempt. Do it once here, so we can warn the user at start-up if we can't * read the key. We don't error out, though, because it's fine if the key is * going to be added later. */ rc = lrmd_tls_set_key(&psk_key); if (rc != 0) { crm_warn("A cluster connection will not be possible until the key is available"); } gnutls_free(psk_key.data); memset(&hints, 0, sizeof(struct addrinfo)); /* Bind to the wildcard address (INADDR_ANY or IN6ADDR_ANY_INIT). * @TODO allow user to specify a specific address */ hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; /* Return IPv6 or IPv4 */ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; snprintf(port_str, sizeof(port_str), "%d", port); rc = getaddrinfo(NULL, port_str, &hints, &res); if (rc) { crm_err("Unable to get IP address info for local node: %s", gai_strerror(rc)); return -1; } iter = res; filter = AF_INET6; /* Try IPv6 addresses first, then IPv4 */ while (iter) { if (iter->ai_family == filter) { ssock = bind_and_listen(iter); } if (ssock != -1) { break; } iter = iter->ai_next; if (iter == NULL && filter == AF_INET6) { iter = res; filter = AF_INET; } } if (ssock < 0) { goto init_remote_cleanup; } mainloop_add_fd("pacemaker-remote-server", G_PRIORITY_DEFAULT, ssock, NULL, &remote_listen_fd_callbacks); rc = ssock; init_remote_cleanup: if (rc < 0) { close(ssock); ssock = 0; } else { crm_debug("Started TLS listener on port %d", port); } freeaddrinfo(res); return rc; }
int lrmd_init_remote_tls_server(int port) { int rc; int filter; struct addrinfo hints, *res = NULL, *iter; char port_str[16]; static struct mainloop_fd_callbacks remote_listen_fd_callbacks = { .dispatch = lrmd_remote_listen, .destroy = lrmd_remote_connection_destroy, }; crm_notice("Starting a tls listener on port %d.", port); crm_gnutls_global_init(); gnutls_global_set_log_function(debug_log); gnutls_dh_params_init(&dh_params); gnutls_dh_params_generate2(dh_params, 1024); gnutls_psk_allocate_server_credentials(&psk_cred_s); gnutls_psk_set_server_credentials_function(psk_cred_s, lrmd_tls_server_key_cb); gnutls_psk_set_server_dh_params(psk_cred_s, dh_params); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_PASSIVE; /* Only return socket addresses with wildcard INADDR_ANY or IN6ADDR_ANY_INIT */ hints.ai_family = AF_UNSPEC; /* Return IPv6 or IPv4 */ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; snprintf(port_str, sizeof(port_str), "%d", port); rc = getaddrinfo(NULL, port_str, &hints, &res); if (rc) { crm_err("getaddrinfo: %s", gai_strerror(rc)); return -1; } iter = res; filter = AF_INET6; /* Try IPv6 addresses first, then IPv4 */ while (iter) { if (iter->ai_family == filter) { ssock = bind_and_listen(iter); } if (ssock != -1) { break; } iter = iter->ai_next; if (iter == NULL && filter == AF_INET6) { iter = res; filter = AF_INET; } } if (ssock < 0) { crm_err("unable to bind to address"); goto init_remote_cleanup; } mainloop_add_fd("lrmd-remote", G_PRIORITY_DEFAULT, ssock, NULL, &remote_listen_fd_callbacks); rc = ssock; init_remote_cleanup: if (rc < 0) { close(ssock); ssock = 0; } freeaddrinfo(res); return rc; }
int main( int argc, char *argv[] ) { struct sockaddr_storage myaddr,remote; struct server_ctx ctx; int cli_fd, ret; socklen_t addrlen; char peer[INET6_ADDRSTRLEN]; void *ptr; if ( signal( SIGTERM, sighandler ) == SIG_ERR ) { fprintf(stderr, "Unable to set signal handler\n"); return EXIT_FAILURE; } if ( signal( SIGINT, sighandler ) == SIG_ERR ) { fprintf(stderr, "Unable to set signal handler\n"); return EXIT_FAILURE; } if ( signal( SIGPIPE, sighandler ) == SIG_ERR ) { fprintf(stderr, "Unable to set signal handler\n"); return EXIT_FAILURE; } memset( &ctx, 0, sizeof( ctx )); ctx.port = DEFAULT_PORT; ctx.recvbuf_size = RECVBUF_SIZE; partial_store_init(&ctx.partial); ret = parse_args( argc, argv, &ctx ); if ( ret < 0 ) { WARN("Error while parsing command line\n" ); return EXIT_FAILURE; } else if ( ret == 0 ) { return EXIT_SUCCESS; } memset( &myaddr, 0, sizeof( myaddr)); myaddr.ss_family = AF_INET6; if ( is_flag( ctx.options, SEQ_FLAG )) { DBG("Using SEQPKT socket\n"); ctx.sock = socket( PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP ); } else { DBG("Using STREAM socket\n"); ctx.sock = socket( PF_INET6, SOCK_STREAM, IPPROTO_SCTP ); } if ( ctx.sock < 0 ) { fprintf(stderr, "Unable to create socket: %s \n", strerror(errno)); return EXIT_FAILURE; } if (ctx.initmsg != NULL ) { TRACE("Requesting for %d output streams and at max %d input streams\n", ctx.initmsg->sinit_num_ostreams, ctx.initmsg->sinit_max_instreams); if (setsockopt( ctx.sock, SOL_SCTP, SCTP_INITMSG, ctx.initmsg, sizeof(*ctx.initmsg)) < 0) { fprintf(stderr,"Warning: unable to set the association parameters: %s\n", strerror(errno)); } } if ( bind_and_listen( &ctx ) < 0 ) { fprintf(stderr, "Error while initializing the server\n" ); close(ctx.sock); return EXIT_FAILURE; } if ( is_flag( ctx.options, VERBOSE_FLAG )) subscribe_to_events(ctx.sock); /* to err is not fatal */ memset( &remote, 0, sizeof(remote)); addrlen = sizeof( struct sockaddr_in6); TRACE("Allocating %d bytes for recv buffer \n", ctx.recvbuf_size ); ctx.recvbuf = mem_alloc( ctx.recvbuf_size * sizeof( uint8_t )); printf("Listening on port %d \n", ctx.port ); while ( !close_req ) { if ( is_flag( ctx.options, SEQ_FLAG ) ) { ret = do_server( &ctx, ctx.sock ); if ( ret == SERVER_ERROR ) break; } else { cli_fd = do_accept( &ctx, &remote, &addrlen ); if ( cli_fd < 0 ) { if ( errno == EINTR ) break; close( ctx.sock ); mem_free( ctx.recvbuf); WARN( "Error in accept!\n"); return EXIT_FAILURE; } else if ( cli_fd == 0 ) { break; } if ( remote.ss_family == AF_INET ) { ptr = &(((struct sockaddr_in *)&remote)->sin_addr); } else { ptr = &(((struct sockaddr_in6 *)&remote)->sin6_addr); } if ( inet_ntop(remote.ss_family, ptr, peer, INET6_ADDRSTRLEN ) != NULL ) { printf("Connection from %s \n", peer ); } else { printf("Connection from unknown\n"); } if( do_server( &ctx, cli_fd ) == SERVER_ERROR ) { close( cli_fd); break; } close( cli_fd ); } } mem_free( ctx.recvbuf); if (ctx.initmsg != NULL ) { mem_free( ctx.initmsg); } close( ctx.sock ); return EXIT_SUCCESS; }
int main(int argc, char* argv[]) { #ifdef HAVE_EXECINFO_H signal(SIGSEGV, crash_sig); signal(SIGABRT, crash_sig); signal(SIGPIPE, SIG_IGN); #endif #ifdef WIN32 HANDLE localfd; WSADATA wsa; enum_device_t devs[MAX_DEVICE_COUNT]; #else int localfd; #endif char cmd[1024]; int remotefd; library_conf_t conf; int opt; struct in_addr a; struct option long_options[] = { { "conf", 1, NULL, 'c' }, { NULL, 0, NULL, 0 } }; char short_options[512] = {0}; longopt2shortopt(long_options, sizeof(long_options) / sizeof(struct option), short_options); #ifdef HAVE_SYSLOG_H openlog(argv[0], LOG_PERROR | LOG_CONS | LOG_PID, LOG_LOCAL0); #endif qtun = calloc(sizeof(*qtun), 1); #ifdef WIN32 remotefd = -1; localfd = INVALID_HANDLE_VALUE; #else localfd = remotefd = -1; #endif { char path[MAX_PATH] = {0}; #ifdef WIN32 strcpy(path, argv[0]); #elif defined(__APPLE__) char tmp_path[sizeof(path)] = {0}; uint32_t len = sizeof(path); if (_NSGetExecutablePath(tmp_path, &len) == -1) { perror("_NSGetExecutablePath"); return 1; } if (readlink(tmp_path, path, sizeof(path)) == -1) { if (errno == EINVAL) strcpy(path, tmp_path); else { perror("readlink"); return 1; } } #else if (readlink("/proc/self/exe", path, sizeof(path)) == -1) { perror("readlink"); return 1; } #endif init_path(path); } conf_init(&conf); while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (opt) { case 'c': { char* path = realpath(optarg, NULL); if (path == NULL) { perror("realpath"); return 1; } strcpy(conf.conf_file, path); free(path); } break; default: fprintf(stderr, "param error\n"); return 1; } } #ifdef WIN32 { size_t count = enum_devices(devs); if (count == 0) { fprintf(stderr, "have no QTun Virtual Adapter\n"); return 1; } else if (count == 1) { strcpy(conf.dev_symbol, devs[0].dev_path); strcpy(conf.dev_name, devs[0].dev_name); } else { size_t i; char str[20] = { 0 }; int n = -1; printf("Have Adapters:\n"); for (i = 0; i < count; ++i) { printf("%lu: %s\n", i + 1, devs[i].dev_name); } printf("Choose One[1]: "); while (n == -1) { if (str[0] == '\n' && str[1] == 0) n = 1; else { if (!is_int(str, sizeof(str))) continue; n = atoi(str); if (n < 1 || n > (int)count) { fprintf(stderr, "Invalid Number must >= 1 and <= %lu\n", count); n = -1; continue; } } } strcpy(conf.dev_symbol, devs[n].dev_path); strcpy(conf.dev_name, devs[n].dev_name); } } #endif init_lua(); show_logo(); script_load_config(qtun->lua, &conf, conf.conf_file); #ifdef WIN32 if (strlen(conf.dev_symbol) == 0) { fprintf(stderr, "Missing param [-e] or [--device]\n"); return 1; } #endif #ifdef WIN32 localfd = tun_open(conf.dev_symbol); if (localfd == INVALID_HANDLE_VALUE) return 1; fprintf(stdout, "%s opened\n", conf.dev_name); #else memset(qtun->dev_name, 0, IFNAMSIZ); localfd = tun_open(qtun->dev_name); if (localfd == -1) return 1; syslog(LOG_INFO, "%s opened\n", qtun->dev_name); #endif a.s_addr = conf.localip; #ifdef WIN32 WSAStartup(MAKEWORD(2, 2), &wsa); #endif if (strlen(conf.server) == 0) { if (conf.netmask == 0 || conf.netmask > 31) { #ifdef WIN32 WSACleanup(); #endif fprintf(stderr, "netmask must > 0 and <= 31\n"); return 1; } library_init(conf); if (conf.localip == 0) { fprintf(stderr, "localip is zero\n"); return 1; } if (strlen(conf.signature_file) == 0) { fprintf(stderr, "missing signature file\n"); return 1; } qtun->is_server = 1; remotefd = bind_and_listen(conf.server_port); if (remotefd == -1) { #ifdef WIN32 WSACleanup(); #endif return 1; } #ifdef WIN32 { a.s_addr = conf.localip; sprintf(cmd, "netsh interface ip set address name=\"%s\" static %s %s", conf.dev_name, inet_ntoa(a), STR_LEN2MASK(conf.netmask)); SYSTEM_EXIT(cmd); } #elif defined(__APPLE__) { sprintf(cmd, "ifconfig %s %s/%u up", qtun->dev_name, inet_ntoa(a), conf.netmask); SYSTEM_EXIT(cmd); a.s_addr = conf.localip & LEN2MASK(conf.netmask); sprintf(cmd, "route add -net %s/%u %s", inet_ntoa(a), conf.netmask, inet_ntoa(a)); SYSTEM_EXIT(cmd); } #else { sprintf(cmd, "ifconfig %s %s/%u up", qtun->dev_name, inet_ntoa(a), conf.netmask); SYSTEM_EXIT(cmd); a.s_addr = conf.localip & LEN2MASK(conf.netmask); sprintf(cmd, "route add -net %s/%u dev %s", inet_ntoa(a), conf.netmask, qtun->dev_name); SYSTEM_EXIT(cmd); } #endif server_loop(remotefd, localfd); } else { #ifdef unix unsigned char mask; #endif int inited = 0; library_init(conf); qtun->is_server = 0; while (1) { remotefd = connect_server(conf.server, conf.server_port); if (remotefd == -1) { SLEEP(5); continue; } a.s_addr = qtun->localip; if (qtun->localip == 0) { fprintf(stderr, "localip is zero\n"); return 1; } if (strlen(conf.signature_file) == 0) { fprintf(stderr, "missing signature file\n"); return 1; } if (!inited) { #ifdef WIN32 { sprintf(cmd, "netsh interface ip set address name=\"%s\" static %s %s", conf.dev_name, inet_ntoa(a), STR_LEN2MASK(conf.netmask)); SYSTEM_EXIT(cmd); } #elif defined(__APPLE__) { char ip1[16], ip2[16]; a.s_addr = qtun->localip; strcpy(ip1, inet_ntoa(a)); a.s_addr = qtun->client.local_ip; strcpy(ip2, inet_ntoa(a)); sprintf(cmd, "ifconfig %s inet %s %s up", qtun->dev_name, ip1, ip2); SYSTEM_EXIT(cmd); mask = netmask(); a.s_addr = qtun->localip & LEN2MASK(mask); sprintf(cmd, "route add -net %s/%u %s", inet_ntoa(a), mask, ip2); SYSTEM_EXIT(cmd); } #else { sprintf(cmd, "ifconfig %s %s up", qtun->dev_name, inet_ntoa(a)); SYSTEM_EXIT(cmd); mask = netmask(); a.s_addr = qtun->localip & LEN2MASK(mask); sprintf(cmd, "route add -net %s/%u dev %s", inet_ntoa(a), mask, qtun->dev_name); SYSTEM_EXIT(cmd); } #endif inited = 1; } client_loop(remotefd, localfd); close(remotefd); SYSLOG(LOG_WARNING, "retry"); } } #ifdef WIN32 WSACleanup(); #endif #ifdef HAVE_SYSLOG_H closelog(); #endif library_free(); return 0; }