Example #1
0
int main(int argc, char *argv[], char *env[])
{
  int svr, daemon, sock, dofork, fd, opt;
     struct vtun_host *host = NULL;
     struct sigaction sa;
     char *hst;

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

     vtun.cfg_file = VTUN_CONFIG_FILE;
     vtun.persist = -1;
     vtun.timeout = -1;
	
     /* Dup strings because parser will try to free them */
     vtun.ppp   = strdup("/usr/sbin/pppd");
     vtun.ifcfg = strdup("/sbin/ifconfig");
     vtun.route = strdup("/sbin/route");
     vtun.fwall = strdup("/sbin/ipchains");	
     vtun.iproute = strdup("/sbin/ip");	

     vtun.svr_name = NULL;
     vtun.svr_addr = NULL;
     vtun.bind_addr.port = -1;
     vtun.svr_type = -1;
     vtun.syslog   = LOG_DAEMON;

     /* Initialize default host options */
     memset(&default_host, 0, sizeof(default_host));
     default_host.flags   = VTUN_TTY | VTUN_TCP|VTUN_SCTP;
     default_host.multi   = VTUN_MULTI_ALLOW;
     default_host.timeout = VTUN_CONNECT_TIMEOUT;
     default_host.ka_interval = 30;
     default_host.ka_maxfail  = 4;
     default_host.loc_fd = default_host.rmt_fd = -1;

     /* Start logging to syslog and stderr */
     openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);

     while( (opt=getopt(argc,argv,"misf:P:L:t:npq")) != EOF ){
	switch(opt){
	    case 'm':
	        if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
		    perror("Unable to mlockall()");
		    exit(-1);
	        }
		break;
	    case 'i':
		vtun.svr_type = VTUN_INETD;
	    case 's':
		svr = 1;
		break;
	    case 'L':
		vtun.svr_addr = strdup(optarg);
		break;
	    case 'P':
		vtun.bind_addr.port = atoi(optarg);
		break;
	    case 'f':
		vtun.cfg_file = strdup(optarg);
		break;
	    case 'n':
		daemon = 0;
		break;
	    case 'p':
		vtun.persist = 1;
		break;
	    case 't':
	        vtun.timeout = atoi(optarg);	
	        break;
	    case 'q':
		vtun.quiet = 1;
		break;
	    default:
		usage();
	        exit(1);
	}
     }	
     reread_config(0);

     if (vtun.syslog != LOG_DAEMON) {
	/* Restart logging to syslog using specified facility  */
 	closelog();
 	openlog("vtund", LOG_PID|LOG_NDELAY|LOG_PERROR, vtun.syslog);
     }

	clear_nat_hack_flags(svr);

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

        if( !(host = find_host(hst)) ){	
	   vtun_syslog(LOG_ERR,"Host %s not found in %s", hst, vtun.cfg_file);
	   exit(1);
        }

	vtun.svr_name = strdup(argv[optind]);
     } 
      	
     /* 
      * Now fill uninitialized fields of the options structure
      * with default values. 
      */ 
     if(vtun.bind_addr.port == -1)
	vtun.bind_addr.port = VTUN_PORT;
     if(vtun.persist == -1)
	vtun.persist = 0;
     if(vtun.timeout == -1)
	vtun.timeout = VTUN_TIMEOUT;

     switch( vtun.svr_type ){
	case -1:
	   vtun.svr_type = VTUN_STAND_ALONE;
	   break;
	case VTUN_INETD:
	   sock = dup(0);
	   dofork = 0; 
	   break;
     }

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

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

	setsid();

	chdir("/");
     }

     if(svr){
        memset(&sa,0,sizeof(sa));     
        sa.sa_handler=reread_config;
        sigaction(SIGHUP,&sa,NULL);

        init_title(argc,argv,env,"vtund[s]: ");

	if( vtun.svr_type == VTUN_STAND_ALONE )	
	   write_pid();
	
	runmode=1;
	server(sock);
     } else {	
        init_title(argc,argv,env,"vtund[c]: ");
	runmode=0;
        client(host);
     }

     closelog();
	
     return 0;
}
Example #2
0
static
int get_connecting_socket(struct descriptor_set d_set) {
#ifdef HAVE_SOCKLEN_T
	socklen_t size;
#else
	int size;
#endif
	static int nfd;
	int shandle, ahandle;
	fd_set backupset;
	struct sockaddr_in sin;

	size = sizeof(sin);

	memcpy(&backupset, &d_set.set, sizeof(fd_set));

	/* is there no remaining ready fd from the last select() ? */
	if (nfd == 0) {
		while (1) {
			/* eternal select() */
			/* nfd returns the number of fds that are ready */
			nfd = select(d_set.maxfd + 1, &d_set.set, 0, 0, 0);
			if (nfd > 0) {
				break;
			}
			if (errno == EINTR) {
				memcpy(&d_set.set, &backupset, sizeof(fd_set));
				if (chlds_exited > 0) {
					get_chld_pid();
				}
				if (should_read_config) {
					jlog(9, "Re-reading configuration");
					reread_config();
				}
				continue;
			}
			jlog(1, "select() failed: %s, nfd: %d", strerror(errno), nfd);
			return -1;
		}
	}
	/* a descriptor is ready */
	shandle = 0;
	while (!FD_ISSET(shandle, &d_set.set)) {
		shandle++;
	}
	/* one descriptor less is ready in the set */
	nfd--;

	while(1) {
		ahandle = accept(shandle, (struct sockaddr *) &sin, &size);
		if (ahandle < 0) {
			switch(errno) {
				case EINTR:        /* signal */
				case ECONNRESET:   /* client quit before three-way-handshake */
				case ENETDOWN:     /* the others: see manpage */
#ifdef EPROTO
				case EPROTO:
#endif
				case ENOPROTOOPT:
				case EHOSTDOWN:
#ifdef ENONET
				case ENONET:
#endif
				case EHOSTUNREACH:
				case EOPNOTSUPP:
				case ENETUNREACH:
					continue;
			}
			jlog(1, "accept() failed: %s", strerror(errno));
			return -1;
		}
		break;
	}
	return ahandle;
}