⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pppd.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================
//
//      src/pppd.c
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Portions created by Nick Garnett are
// Copyright (C) 2003 eCosCentric Ltd.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD, 
// FreeBSD or other sources, and are covered by the appropriate
// copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================

/*
 * main.c - Point-to-Point Protocol main module
 *
 * Copyright (c) 1989 Carnegie Mellon University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by Carnegie Mellon University.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef lint
//static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/main.c,v 1.19.6.1 2002/07/30 19:17:27 nectar Exp $";
#endif

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <cyg/ppp/syslog.h>
#include <sys/param.h>
#include <netdb.h>
#include <sys/types.h>
#ifndef __ECOS
#include <sys/wait.h>
#endif
#include <sys/time.h>
#ifndef __ECOS
#include <sys/resource.h>
#endif
#include <sys/stat.h>
#include <sys/socket.h>

#define MAXPATHLEN PATH_MAX

#include "cyg/ppp/pppd.h"
#include "cyg/ppp/magic.h"
#include "cyg/ppp/fsm.h"
#include "cyg/ppp/lcp.h"
#include "cyg/ppp/ipcp.h"
#include "cyg/ppp/upap.h"
#include "cyg/ppp/chap.h"
#include "cyg/ppp/ccp.h"
#include "cyg/ppp/ppp_io.h"

#ifdef CBCP_SUPPORT
#include "cbcp.h"
#endif

#if defined(SUNOS4)
extern char *strerror();
#endif

#ifdef IPX_CHANGE
#include "ipxcp.h"
#endif /* IPX_CHANGE */
#ifdef AT_CHANGE
#include "atcp.h"
#endif

/* options */

#define option_error(msg) db_printf("Option error: %s\n", msg )


/*
 * Variables set by command-line options.
 */

int	debug = 1;		/* Debug flag */
int	kdebugflag = 1;	        /* Tell kernel to print debug messages */
int	default_device = 0;	/* Using /dev/tty or equivalent */
char	devnam[MAXPATHLEN] = "/dev/ser0";	/* Device name */
int     flowctl = CYG_PPP_FLOWCTL_HARDWARE; /* flow control */
int	modem  = 0;		/* Use modem control lines */
cyg_serial_baud_rate_t	inspeed = 0;    	/* Input/Output speed requested */
u_int32_t netmask = 0;	        /* IP netmask to set on interface */
int	lockflag = 0;	        /* Create lock file to lock the serial dev */
char	*connector = NULL;	/* Script to establish physical link */
char	*disconnector = NULL;	/* Script to disestablish physical link */
char	*welcomer = NULL;	/* Script to welcome client after connection */
int	max_con_attempts = 10;  /* Maximum number of times to try dialing */
int	maxconnect = 0;	        /* Maximum connect time (seconds) */
char	user[MAXNAMELEN] = "nickg";	/* Our name for authenticating ourselves */
char	passwd[MAXSECRETLEN] = "xsecretx";	/* Password for PAP */
int	auth_required = 0;	/* Peer is required to authenticate */
int	proxyarp = 0;	        /* Set up proxy ARP entry for peer */
int	persist = 0;	        /* Reopen link after it goes down */
int	uselogin = 0;	        /* Use /etc/passwd for checking PAP */
int	lcp_echo_interval = 60; /* Interval between LCP echo-requests */
int	lcp_echo_fails = 4;	/* Tolerance to unanswered echo-requests */
char	our_name[20];	        /* Our name for authentication purposes */
char	remote_name[20];	/* Peer's name for authentication */
int	explicit_remote = 1;    /* remote_name specified with remotename opt */
int	usehostname = 0;	/* Use hostname for our_name */
int	disable_defaultip = 0;  /* Don't use hostname for default IP adrs */
//int	demand = 0;		/* Do dial-on-demand */
char	*ipparam = NULL;	/* Extra parameter for ip up/down scripts */
int	cryptpap = 0;	        /* Others' PAP passwords are encrypted */
int	idle_time_limit = 60;   /* Shut down link if idle for this long */
int	holdoff = 0;	        /* Dead time before restarting */
int	refuse_pap = 0;	        /* Don't wanna auth. ourselves with PAP */
int	refuse_chap = 0;	/* Don't wanna auth. ourselves with CHAP */

const char    **script;               /* Chat connection script */


/* interface vars */
char ifname[32];		/* Interface name */
static int ifunit;		/* Interface unit number */

char *progname;			/* Name of this program */
char cyg_ppp_hostname[MAXNAMELEN];	/* Our hostname */
time_t		etime,stime;	/* End and Start time */
int		minutes;	/* connection duration */

cyg_io_handle_t tty_handle;     /* IO handle on serial stream */
mode_t tty_mode = -1;		/* Original access permissions to tty */
int baud_rate;			/* Actual bits/second for serial device */
int hungup;			/* terminal has been hung up */
int privileged;			/* we're running as real uid root */
int need_holdoff;		/* need holdoff period before restarting */

int phase;                      /* where the link is at */
int kill_link;
int open_ccp_flag;

char **script_env;		/* Env. variable values for scripts */
int s_env_nalloc;		/* # words avail at script_env */

u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */

char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";

/* Prototypes for procedures local to this file. */

static void cleanup __P((void));
static void close_tty __P((void));
static void get_input __P((void));
static void calltimeout __P((void));
static struct timeval *timeleft __P((struct timeval *));
//static void holdoff_end __P((void *));
static void pr_log __P((void *, char *, ...));

extern	char	*ttyname __P((int));
extern	char	*getlogin __P((void));
int main __P((int, char *[]));

#ifdef ultrix
#undef	O_NONBLOCK
#define	O_NONBLOCK	O_NDELAY
#endif

#ifdef ULTRIX
#define setlogmask(x)
#endif

/*
 * PPP Data Link Layer "protocol" table.
 * One entry per supported protocol.
 * The last entry must be NULL.
 */
struct protent *protocols[] = {
    &lcp_protent,
#ifdef CYGPKG_PPP_PAP
    &pap_protent,
#endif
#ifdef CYGPKG_PPP_CHAP    
    &chap_protent,
#endif
#ifdef CBCP_SUPPORT
    &cbcp_protent,
#endif
    &ipcp_protent,
    &ccp_protent,
#ifdef IPX_CHANGE
    &ipxcp_protent,
#endif
#ifdef AT_CHANGE
    &atcp_protent,
#endif
    NULL
};


externC void
cyg_pppd_main(CYG_ADDRWORD arg)
{
    int i;
    struct timeval timo;
    struct protent *protp;
    int connect_attempts = 0;

    phase = PHASE_INITIALIZE;

    for (i = 0; (protp = protocols[i]) != NULL; ++i)
        (*protp->init)(0);

    cyg_ppp_options_install( ((struct tty *)arg)->options );
    
    if (!ppp_available()) {
	option_error(no_ppp_msg);
	exit(1);
    }
    
    /*
     * Initialize system-dependent stuff and magic number package.
     */
    sys_init();
    magic_init();
    if (debug)
	setlogmask(LOG_UPTO(LOG_DEBUG));

   
    for (;;) {

	need_holdoff = 1;

        {
            Cyg_ErrNo err;
            while ((err = cyg_io_lookup(devnam, &tty_handle)) < 0) {
                if (err != 0)
                    syslog(LOG_ERR, "Failed to open %s: %d", devnam,err);
            }

#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
            if( modem )
            {
                cyg_uint32 len = sizeof(ppp_tty.serial_callbacks);
                ppp_tty.serial_callbacks.fn = cyg_ppp_serial_callback;
                ppp_tty.serial_callbacks.priv = (CYG_ADDRWORD)&ppp_tty;

                
                err = cyg_io_set_config( tty_handle,
                                         CYG_IO_SET_CONFIG_SERIAL_STATUS_CALLBACK,
                                         &ppp_tty.serial_callbacks,
                                         &len);

                if( err != 0 ) {
                    syslog(LOG_ERR, "cyg_io_set_config(serial callbacks): %d",err);
                    die(1);
                }

            }
#endif
        }

	hungup = 0;
	kill_link = 0;

	/* set line speed, flow control, etc.; clear CLOCAL if modem option */
	set_up_tty(tty_handle, 0);

        if( script != NULL )
        {
            if( !cyg_ppp_chat( devnam, script ) )
            {
                connect_attempts++;
                goto fail;
            }
        }

#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
        if( modem )
        {
            while( !ppp_tty.carrier_detected )
                cyg_thread_delay(100);
        }
#endif
        
	connect_attempts = 0;	/* we made it through ok */

	/* set up the serial device as a ppp interface */
	establish_ppp(tty_handle);

        syslog(LOG_INFO, "Using interface ppp%d", ifunit);
        (void) sprintf(ifname, "ppp%d", ifunit);
        
	/*
	 * Start opening the connection and wait for
	 * incoming events (reply, timeout, etc.).
	 */
	syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam);
	stime = time((time_t *) NULL);
        
	lcp_lowerup(0);
	lcp_open(0);		/* Start protocol */
	for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
	    wait_input(timeleft(&timo));
	    calltimeout();
	    get_input();
	    if (kill_link) {
		lcp_close(0, "User request");
		kill_link = 0;
	    }
	    if (open_ccp_flag) {
		if (phase == PHASE_NETWORK) {
		    ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
		    (*ccp_protent.open)(0);
		}
		open_ccp_flag = 0;
	    }
	}

	clean_check();
	disestablish_ppp(tty_handle);

    fail:        
	if (tty_handle != 0)
	    close_tty();
        
	/* limit to retries? */
	if (max_con_attempts)
	    if (connect_attempts >= max_con_attempts)
		break;

	if (!persist)
	    die(1);

#if 0
	if (holdoff > 0 && need_holdoff) {
	    phase = PHASE_HOLDOFF;
	    TIMEOUT(holdoff_end, NULL, holdoff);
	    do {
		wait_time(timeleft(&timo));
		calltimeout();
		if (kill_link) {
		    if (!persist)
			die(0);
		    kill_link = 0;
		    phase = PHASE_DORMANT; /* allow signal to end holdoff */
		}

	    } while (phase == PHASE_HOLDOFF);
	}
#endif
        
    }

    die(0);
}

/*
 * get_input - called when incoming data is available.
 */
static void
get_input()
{
    int len, i;
    u_char *p;
    u_short protocol;
    struct protent *protp;

    p = inpacket_buf;	/* point to beginning of packet buffer */

    len = read_packet(inpacket_buf);

    if (len < 0)
	return;

    if (len == 0) {
	etime = time((time_t *) NULL);
	minutes = (etime-stime)/60;
	syslog(LOG_NOTICE, "Modem hangup, connected for %d minutes", (minutes >1) ? minutes : 1);
	hungup = 1;
	lcp_lowerdown(0);	/* serial link is no longer available */
	link_terminated(0);
	return;
    }

    if (debug /*&& (debugflags & DBG_INPACKET)*/)
	log_packet(p, len, "rcvd ", LOG_DEBUG);

    if (len < PPP_HDRLEN) {
	MAINDEBUG((LOG_INFO, "io(): Received short packet."));
	return;
    }

    p += 2;				/* Skip address and control */
    GETSHORT(protocol, p);
    len -= PPP_HDRLEN;

    /*
     * Toss all non-LCP packets unless LCP is OPEN.
     */
    if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
	MAINDEBUG((LOG_INFO,
		   "get_input: Received non-LCP packet when LCP not open."));
	return;
    }

    /*
     * Until we get past the authentication phase, toss all packets
     * except LCP, LQR and authentication packets.
     */
    if (phase <= PHASE_AUTHENTICATE
	&& !(protocol == PPP_LCP || protocol == PPP_LQR
	     || protocol == PPP_PAP || protocol == PPP_CHAP)) {
	MAINDEBUG((LOG_INFO, "get_input: discarding proto 0x%x in phase %d",
		   protocol, phase));
	return;
    }

    /*
     * Upcall the proper protocol input routine.
     */
    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
	if (protp->protocol == protocol && protp->enabled_flag) {
	    (*protp->input)(0, p, len);
	    return;
	}
        if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
	    && protp->datainput != NULL) {
	    (*protp->datainput)(0, p, len);
	    return;
	}
    }

    if (debug)
    	syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol);
    lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
}


/*
 * quit - Clean up state and exit (with an error indication).
 */
void 
quit()
{
    die(1);
}

/*
 * die - like quit, except we can specify an exit status.
 */
void
die(status)
    int status;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);    
#ifndef __ECOS
    cleanup();
    syslog(LOG_INFO, "Exit.");
    exit(status);
#else
    externC void sys_exit(void);
    cleanup();    
    sys_exit();
#endif
}

/*
 * cleanup - restore anything which needs to be restored before we exit
 */
/* ARGSUSED */
static void
cleanup()
{
db_printf("%s called\n", __PRETTY_FUNCTION__);    
    sys_cleanup();

    if (tty_handle != 0)
	close_tty();
}

/*
 * close_tty - restore the terminal device and close it.
 */
static void
close_tty()
{
    disestablish_ppp(tty_handle);

#ifndef __ECOS
    /* drop dtr to hang up */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -