📄 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 voidcyg_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 voidget_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. */voiddie(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 voidcleanup(){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 voidclose_tty(){ disestablish_ppp(tty_handle);#ifndef __ECOS /* drop dtr to hang up */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -