Exemplo n.º 1
0
void mp_bundle_terminated()
{
	TDB_DATA key;

	bundle_terminating = 1;
	upper_layers_down(pcb);
	notice("Connection terminated.");
#if PPP_STATS_SUPPORT
	print_link_stats();
#endif /* PPP_STATS_SUPPORT */
	if (!demand) {
		remove_pidfiles();
		script_unsetenv("IFNAME");
	}

	lock_db();
	destroy_bundle();
	iterate_bundle_links(sendhup);
	key.dptr = blinks_id;
	key.dsize = strlen(blinks_id);
	tdb_delete(pppdb, key);
	unlock_db();

	new_phase(PPP_PHASE_DEAD);

	doing_multilink = 0;
	multilink_master = 0;
}
Exemplo n.º 2
0
Arquivo: lcp.c Projeto: AoLaD/rtems
/*
 * lcp_close - Take LCP down.
 */
void
lcp_close(
    int unit,
    char *reason)
{
    fsm *f = &lcp_fsm[unit];

    if (pppd_phase != PHASE_DEAD)
	new_phase(PHASE_TERMINATE);
    if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
	/*
	 * This action is not strictly according to the FSM in RFC1548,
	 * but it does mean that the program terminates if you do a
	 * lcp_close() in passive/silent mode when a connection hasn't
	 * been established.
	 */
	f->state = CLOSED;
	lcp_finished(f);

    } else
	fsm_close(&lcp_fsm[unit], reason);
}
Exemplo n.º 3
0
/*
**  Logout of the BIDS2 system
**    
**  Returns - 0 - Could not connect to logout.
**            1 - Logout successful.
*/
int logout(INT2 reason,struct session * s)
{
	int err;
	char credentials[16];
	time_t logintime;

	int authsocket;
	struct transaction t;
	INT2 transactiontype;

	new_phase(PHASE_DEAD);
	
	s->localaddr.sin_port = htons(0);
	authsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	err = bind(authsocket,(struct sockaddr *)&s->localaddr,sizeof(struct sockaddr_in));
	if(err)
	{
		socketerror(s,"Error binding logout auth socket");
		closesocket(authsocket);
		return 0;
	}
	err = connect(authsocket,(struct sockaddr *)&s->authhost,sizeof(struct sockaddr_in));
	if(err)
	{
		socketerror(s,"Error connecting logout auth socket");
		closesocket(authsocket);
		return 0;
	}

	/*
	** start the negotiation 
	*/
	start_transaction(&t,T_MSG_LOGOUT_REQ,s->sessionid);
	add_field_string(s,&t,T_PARAM_USERNAME,s->username);
	add_field_INT2(s,&t,T_PARAM_CLIENT_VERSION,LOGIN_VERSION * 100);
	add_field_string(s,&t,T_PARAM_OS_IDENTITY,s->osname);
	add_field_string(s,&t,T_PARAM_OS_VERSION,s->osrelease);
	add_field_INT2(s,&t,T_PARAM_REASON_CODE,reason);

	send_transaction(s,authsocket,&t);

	transactiontype = receive_transaction(s,authsocket,&t);
	if(transactiontype != T_MSG_AUTH_RESP)
	{
		s->critical("logic error");
	}

	if(!extract_valueINT2(s,&t,T_PARAM_HASH_METHOD,&s->hashmethod))
	{
		s->critical("AUTH: no hashmethod");
	}
	if(!extract_valuestring(s,&t,T_PARAM_NONCE,s->nonce))
	{
		s->critical("Auth: no nonce");
	}

	if(s->hashmethod == T_AUTH_MD5_HASH)
	{
		genmd5(s->password,strlen(s->password),s->password);
	}

	start_transaction(&t,T_MSG_LOGOUT_AUTH_RESP,s->sessionid);

	s->timestamp = time(NULL);
	makecredentials(credentials,s,T_MSG_LOGOUT_AUTH_RESP,s->timestamp);

	add_field_data(s,&t,T_PARAM_AUTH_CREDENTIALS,credentials,16);
	add_field_INT4(s,&t,T_PARAM_TIMESTAMP,s->timestamp);

	send_transaction(s,authsocket,&t);

	transactiontype = receive_transaction(s,authsocket,&t);
	if(transactiontype != T_MSG_LOGOUT_RESP)
	{
		s->critical("logic error");
	}

	extract_valueINT2(s,&t,T_PARAM_STATUS_CODE,&s->retcode);
	switch(s->retcode)
	{
	case T_STATUS_SUCCESS:
	case T_STATUS_LOGOUT_SUCCESSFUL_ALREADY_DISCONNECTED:
		break;
	case T_STATUS_USERNAME_NOT_FOUND:
		s->critical("Login failure: username not known");
	case T_STATUS_INCORRECT_PASSWORD:
		s->critical("Login failure: incorrect password");
	case T_STATUS_ACCOUNT_DISABLED:
		s->critical("Login failure: disabled");
	case T_STATUS_LOGIN_RETRY_LIMIT:
	case T_STATUS_USER_DISABLED:
	case T_STATUS_FAIL_USERNAME_VALIDATE:
	case T_STATUS_FAIL_PASSWORD_VALIDATE:
	case T_STATUS_LOGIN_UNKNOWN:
		s->critical("Login failure: other error");
	}

	extract_valueINT2(s,&t,T_PARAM_LOGOUT_SERVICE_PORT,&s->logoutport);
	extract_valueINT2(s,&t,T_PARAM_STATUS_SERVICE_PORT,&s->statusport);
	extract_valuestring(s,&t,T_PARAM_TSMLIST,s->tsmlist);
	extract_valuestring(s,&t,T_PARAM_RESPONSE_TEXT,s->resptext);

	logintime = time(NULL);

	s->debug(0,"Logged out successful at %s",asctime(localtime(&logintime)));
	
	closesocket(authsocket);
	
	return 1;
}
Exemplo n.º 4
0
/*
**  Handle heartbeats, wait for the following events to happen -
**    
**    1. A heartbeat packet arrives, in which case we reply correctly
**    2. A timeout occured (ie no heartbeat arrived within 7 minutes)
**    3. The socket was closed.
**
**  Returns - 0 - Heartbeat timeout, and subsequent login failed to connect
**            1 - Socket closed on us, presuming the user wants to shut down.
*/
int handle_heartbeats(struct session *s)
{
	INT2 transactiontype;
	struct transaction t;

	while(1)
	{
		transactiontype = receive_udp_transaction(s,s->listensock,&t,&s->fromaddr);

		if(transactiontype == 0xffff)
		{
			s->debug(0,"Timed out waiting for heartbeat - logging on\n");
			if(!login(s))
				return 0;
			else
				new_phase(PHASE_RUNNING);
		}
		else if(transactiontype == 0xfffd)
		{
			s->debug(0,"Badly structured packet received - discarding\n");
		}
		else if(transactiontype == 0xfffe)
		{
			s->debug(0,"Socket closed - shutting down\n");
			return 1;
		}
		else if(transactiontype == T_MSG_STATUS_REQ)
		{
			char buf[16];

			start_transaction(&t,T_MSG_STATUS_RESP,s->sessionid);
			add_field_INT2(s,&t,T_PARAM_STATUS_CODE,T_STATUS_TRANSACTION_OK);

			s->sequence++;
			makecredentials(buf,s,T_MSG_STATUS_RESP,s->sequence);
			add_field_data(s,&t,T_PARAM_STATUS_AUTH,buf,16);
			add_field_INT4(s,&t,T_PARAM_SEQNUM,s->sequence);

			send_udp_transaction(s,&t);

			s->lastheartbeat = time(NULL);

			s->debug(1,"Responded to heartbeat at %s",asctime(localtime(&s->lastheartbeat)));
		}
		else if(transactiontype == T_MSG_RESTART_REQ)
		{
			s->debug(0,"Restart request - unimplemented");
			return 0;
		}
		else
		{
			/*
			**  Melbourne servers were sending spurious UDP packets after authentication
			**  This works around it.
			*/
			s->debug(0,"Unknown heartbeat message %d ",transactiontype);
		}
	}
	/*
	**  Should never get here
	*/
	return 0;
}
Exemplo n.º 5
0
/*
 * holdoff_end - called via a timeout when the holdoff period ends.
 */
static void
holdoff_end(
    void *arg)
{
    new_phase(PHASE_DORMANT);
}
Exemplo n.º 6
0
int
pppdmain(
    int argc,
    char *argv[])
{
    int i, fdflags, t;
    char *connector;
    struct timeval timo;
    struct protent *protp;

    new_phase(PHASE_INITIALIZE);

    script_env = NULL;
    hostname[MAXNAMELEN-1] = 0;
    privileged = 1;
    privileged_option = 1;

    /*
     * Initialize magic number generator now so that protocols may
     * use magic numbers in initialization.
     */
    magic_init();

#ifdef XXX_XXX
    /* moved code the the rtems_pppd_reset_options function */

    /*
     * Initialize to the standard option set, then parse, in order,
     * the system options file, the user's options file,
     * the tty's options file, and the command line arguments.
     */
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
        (*protp->init)(0);
#endif


    if (!ppp_available()) {
	option_error(no_ppp_msg);
	return(EXIT_NO_KERNEL_SUPPORT);
    }

    /*
     * Check that the options given are valid and consistent.
     */
    if (!sys_check_options()) {
	return(EXIT_OPTION_ERROR);
    }
    if (!auth_check_options()) {
	return(EXIT_OPTION_ERROR);
    }
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
	if (protp->check_options != NULL)
	    (*protp->check_options)();

    /* default holdoff to 0 if no connect script has been given */
    if (connect_script == 0 && !holdoff_specified)
	holdoff = 0;

    if (default_device)
	nodetach = 1;

    /*
     * Initialize system-dependent stuff.
     */
    sys_init();
    /* if (debug)
	setlogmask(LOG_UPTO(LOG_DEBUG));
    */

    do_callback = 0;
    for (;;) {

	need_holdoff = 1;
	pppd_ttyfd = -1;
	real_ttyfd = -1;
	pppd_status = EXIT_OK;
	++unsuccess;
	doing_callback = do_callback;
	do_callback = 0;

	new_phase(PHASE_SERIALCONN);

	/*
	 * Get a pty master/slave pair if the pty, notty, or record
	 * options were specified.
	 */
	strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
	pty_master = -1;
	pty_slave = -1;

	/*
	 * Open the serial device and set it up to be the ppp interface.
	 * First we open it in non-blocking mode so we can set the
	 * various termios flags appropriately.  If we aren't dialling
	 * out and we want to use the modem lines, we reopen it later
	 * in order to wait for the carrier detect signal from the modem.
	 */
	hungup = 0;
	pppd_kill_link = 0;
	connector = doing_callback? callback_script: connect_script;
	if (devnam[0] != 0) {
	    for (;;) {
		/* If the user specified the device name, become the
		   user before opening it. */
		int err;
		pppd_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);
		err = errno;
		if (pppd_ttyfd >= 0) {
		    break;
		}
		errno = err;
		if (err != EINTR) {
		    error("Failed to open %s: %m", devnam);
		    pppd_status = EXIT_OPEN_FAILED;
		}
		if (!persist || err != EINTR)
		    goto fail;
	    }
	    if ((fdflags = fcntl(pppd_ttyfd, F_GETFL)) == -1
		|| fcntl(pppd_ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
		warn("Couldn't reset non-blocking mode on device: %m");

	    /*
	     * Set line speed, flow control, etc.
	     * If we have a non-null connection or initializer script,
	     * on most systems we set CLOCAL for now so that we can talk
	     * to the modem before carrier comes up.  But this has the
	     * side effect that we might miss it if CD drops before we
	     * get to clear CLOCAL below.  On systems where we can talk
	     * successfully to the modem with CLOCAL clear and CD down,
	     * we could clear CLOCAL at this point.
	     */
	    set_up_tty(pppd_ttyfd, ((connector != NULL && connector[0] != 0)
			       || initializer != NULL));
	    real_ttyfd = pppd_ttyfd;
	}

	/* run connection script */
	if ((connector && connector[0]) || initializer) {
	    if (real_ttyfd != -1) {
		/* XXX do this if doing_callback == CALLBACK_DIALIN? */
		if (!default_device && modem) {
		    setdtr(real_ttyfd, 0);	/* in case modem is off hook */
		    sleep(1);
		    setdtr(real_ttyfd, 1);
		}
	    }

	    if (initializer && initializer[0]) {
		if (device_script(pppd_ttyfd, DIALER_INIT, initializer) < 0) {
		    error("Initializer script failed");
		    pppd_status = EXIT_INIT_FAILED;
		    goto fail;
		}
		if (pppd_kill_link)
		    goto disconnect;

		info("Serial port initialized.");
	    }

	    if (connector && connector[0]) {
		if (device_script(pppd_ttyfd, DIALER_CONNECT, connector) < 0) {
		    error("Connect script failed");
		    pppd_status = EXIT_CONNECT_FAILED;
		    goto fail;
		}
		if (pppd_kill_link)
		    goto disconnect;

		info("Serial connection established.");
	    }

	    /* set line speed, flow control, etc.;
	       clear CLOCAL if modem option */
	    if (real_ttyfd != -1)
		set_up_tty(real_ttyfd, 0);

	    if (doing_callback == CALLBACK_DIALIN)
		connector = NULL;
	}

	/* reopen tty if necessary to wait for carrier */
	if (connector == NULL && modem && devnam[0] != 0) {
	    for (;;) {
		if ((i = open(devnam, O_RDWR)) >= 0)
		    break;
		if (errno != EINTR) {
		    error("Failed to reopen %s: %m", devnam);
		    pppd_status = EXIT_OPEN_FAILED;
		}
		if (!persist || errno != EINTR || hungup || pppd_kill_link)
		    goto fail;
	    }
	    close(i);
	}

        info("Serial connection established.");
        sleep(1);

	/* run welcome script, if any */
	if (welcomer && welcomer[0]) {
	    if (device_script(pppd_ttyfd, DIALER_WELCOME, welcomer) < 0)
		warn("Welcome script failed");
	}

	/* set up the serial device as a ppp interface */
	fd_ppp = establish_ppp(pppd_ttyfd);
	if (fd_ppp < 0) {
	    pppd_status = EXIT_FATAL_ERROR;
	    goto disconnect;
	}

	if (!demand) {
	    info("Using interface ppp%d", pppifunit);
	    slprintf(ifname, sizeof(ifname), "ppp%d", pppifunit);
	}

	/*
	 * Start opening the connection and wait for
	 * incoming events (reply, timeout, etc.).
	 */
	notice("Connect: %s <--> %s", ifname, ppp_devnam);
	gettimeofday(&start_time, NULL);

	lcp_lowerup(0);
	lcp_open(0);		/* Start protocol */

	open_ccp_flag = 0;
	pppd_status = EXIT_NEGOTIATION_FAILED;
	new_phase(PHASE_ESTABLISH);
	while (pppd_phase != PHASE_DEAD) {
   	    wait_input(timeleft(&timo));
	    calltimeout();
            get_input();

	    if (pppd_kill_link) {
		lcp_close(0, "User request");
		pppd_kill_link = 0;
	    }
	    if (open_ccp_flag) {
		if (pppd_phase == PHASE_NETWORK || pppd_phase == PHASE_RUNNING) {
		    ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
		    (*ccp_protent.open)(0);
		}
		open_ccp_flag = 0;
	    }
	}

	/*
	 * If we may want to bring the link up again, transfer
	 * the ppp unit back to the loopback.  Set the
	 * real serial device back to its normal mode of operation.
	 */
	clean_check();
	if (demand)
	    restore_loop();
	disestablish_ppp(pppd_ttyfd);
	fd_ppp = -1;
	if (!hungup)
	    lcp_lowerdown(0);

	/*
	 * Run disconnector script, if requested.
	 * XXX we may not be able to do this if the line has hung up!
	 */
    disconnect:
	if (disconnect_script && !hungup) {
	    new_phase(PHASE_DISCONNECT);
	    if (real_ttyfd >= 0)
		set_up_tty(real_ttyfd, 1);
	    if (device_script(pppd_ttyfd, DIALER_DISCONNECT, disconnect_script) < 0) {
		warn("disconnect script failed");
	    } else {
		info("Serial link disconnected.");
	    }
	}

    fail:
	if (pty_master >= 0)
	    close(pty_master);
	if (pty_slave >= 0)
	    close(pty_slave);
	if (real_ttyfd >= 0)
	    close_tty();

	if (!persist || (maxfail > 0 && unsuccess >= maxfail))
	    break;

	pppd_kill_link = 0;
	if (demand)
	    demand_discard();
	t = need_holdoff? holdoff: 0;
	if (holdoff_hook)
	    t = (*holdoff_hook)();
	if (t > 0) {
	    new_phase(PHASE_HOLDOFF);
	    TIMEOUT(holdoff_end, NULL, t);
	    do {
   	        wait_input(timeleft(&timo));

		calltimeout();
		if (pppd_kill_link) {
		    pppd_kill_link = 0;
		    new_phase(PHASE_DORMANT); /* allow signal to end holdoff */
		}
	    } while (pppd_phase == PHASE_HOLDOFF);
	    if (!persist)
		break;
	}
    }

    die(pppd_status);
    return pppd_status;
}