📄 pppd.c
字号:
//==========================================================================
//
// 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 + -