From 369e6c5bf775ccb2d1c601fbb7562cd6bf6a7adb Mon Sep 17 00:00:00 2001 From: Vijay Kumar Banerjee Date: Wed, 24 Feb 2021 19:08:09 -0700 Subject: cpukit: remove pppd Update #3850 --- cpukit/include/rtems/rtemspppd.h | 49 - cpukit/pppd/README | 25 - cpukit/pppd/STATUS | 23 - cpukit/pppd/auth.c | 1124 --------------------- cpukit/pppd/cbcp.c | 456 --------- cpukit/pppd/cbcp.h | 26 - cpukit/pppd/ccp.c | 1224 ----------------------- cpukit/pppd/ccp.h | 48 - cpukit/pppd/chap.c | 854 ---------------- cpukit/pppd/chap.h | 124 --- cpukit/pppd/chap_ms.c | 338 ------- cpukit/pppd/chap_ms.h | 33 - cpukit/pppd/chat.c | 854 ---------------- cpukit/pppd/demand.c | 343 ------- cpukit/pppd/fsm.c | 760 --------------- cpukit/pppd/fsm.h | 144 --- cpukit/pppd/ipcp.c | 1768 --------------------------------- cpukit/pppd/ipcp.h | 73 -- cpukit/pppd/lcp.c | 1949 ------------------------------------- cpukit/pppd/lcp.h | 88 -- cpukit/pppd/magic.c | 54 - cpukit/pppd/magic.h | 23 - cpukit/pppd/options.c | 1515 ---------------------------- cpukit/pppd/patchlevel.h | 6 - cpukit/pppd/pathnames.h | 43 - cpukit/pppd/pppd.8 | 1479 ---------------------------- cpukit/pppd/pppd.h | 655 ------------- cpukit/pppd/rtemsmain.c | 892 ----------------- cpukit/pppd/rtemspppd.c | 228 ----- cpukit/pppd/sys-rtems.c | 1321 ------------------------- cpukit/pppd/upap.c | 627 ------------ cpukit/pppd/upap.h | 87 -- cpukit/pppd/utils.c | 823 ---------------- spec/build/cpukit/grp.yml | 2 - spec/build/cpukit/libpppd.yml | 33 - spec/build/cpukit/librtemscpu.yml | 1 - 36 files changed, 18092 deletions(-) delete mode 100644 cpukit/include/rtems/rtemspppd.h delete mode 100644 cpukit/pppd/README delete mode 100644 cpukit/pppd/STATUS delete mode 100644 cpukit/pppd/auth.c delete mode 100644 cpukit/pppd/cbcp.c delete mode 100644 cpukit/pppd/cbcp.h delete mode 100644 cpukit/pppd/ccp.c delete mode 100644 cpukit/pppd/ccp.h delete mode 100644 cpukit/pppd/chap.c delete mode 100644 cpukit/pppd/chap.h delete mode 100644 cpukit/pppd/chap_ms.c delete mode 100644 cpukit/pppd/chap_ms.h delete mode 100644 cpukit/pppd/chat.c delete mode 100644 cpukit/pppd/demand.c delete mode 100644 cpukit/pppd/fsm.c delete mode 100644 cpukit/pppd/fsm.h delete mode 100644 cpukit/pppd/ipcp.c delete mode 100644 cpukit/pppd/ipcp.h delete mode 100644 cpukit/pppd/lcp.c delete mode 100644 cpukit/pppd/lcp.h delete mode 100644 cpukit/pppd/magic.c delete mode 100644 cpukit/pppd/magic.h delete mode 100644 cpukit/pppd/options.c delete mode 100644 cpukit/pppd/patchlevel.h delete mode 100644 cpukit/pppd/pathnames.h delete mode 100644 cpukit/pppd/pppd.8 delete mode 100644 cpukit/pppd/pppd.h delete mode 100644 cpukit/pppd/rtemsmain.c delete mode 100644 cpukit/pppd/rtemspppd.c delete mode 100644 cpukit/pppd/sys-rtems.c delete mode 100644 cpukit/pppd/upap.c delete mode 100644 cpukit/pppd/upap.h delete mode 100644 cpukit/pppd/utils.c delete mode 100644 spec/build/cpukit/libpppd.yml diff --git a/cpukit/include/rtems/rtemspppd.h b/cpukit/include/rtems/rtemspppd.h deleted file mode 100644 index a6c8d0b398..0000000000 --- a/cpukit/include/rtems/rtemspppd.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * COPYRIGHT (c) 2001, Michael Siers . - * Poliac Research, Burnsville, Minnesota USA. - * COPYRIGHT (c) 2001, On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#ifndef RTEMSPPPD_H -#define RTEMSPPPD_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* define hook function identifiers */ -#define RTEMS_PPPD_LINKUP_HOOK 1 -#define RTEMS_PPPD_LINKDOWN_HOOK 2 -#define RTEMS_PPPD_IPUP_HOOK 3 -#define RTEMS_PPPD_IPDOWN_HOOK 4 -#define RTEMS_PPPD_ERROR_HOOK 5 -#define RTEMS_PPPD_EXIT_HOOK 6 - -/* define hook function pointer prototype */ -typedef void (*rtems_pppd_hookfunction)(void); -typedef int (*rtems_pppd_dialerfunction)(int tty, int mode, char *pScript); - - -/* define pppd function prototyes */ -int rtems_pppd_initialize(void); -int rtems_pppd_terminate(void); -int rtems_pppd_reset_options(void); -int rtems_pppd_set_hook(int id, rtems_pppd_hookfunction hookfp); -int rtems_pppd_set_dialer(rtems_pppd_dialerfunction dialerfp); -int rtems_pppd_set_option(const char *pOption, const char *pValue); -int rtems_pppd_connect(void); -int rtems_pppd_disconnect(void); - -struct rtems_bsdnet_ifconfig; - -int rtems_ppp_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/cpukit/pppd/README b/cpukit/pppd/README deleted file mode 100644 index 3767703ec4..0000000000 --- a/cpukit/pppd/README +++ /dev/null @@ -1,25 +0,0 @@ -This directory contains a port of ppp-2.3.11. The official site for -the original source for this PPP implementation is: - -ftp://cs.anu.edu.au/pub/software/ppp - -================================================================ -History - -The original port was of 2.3.5 by Tomasz Domin of -ComArch SA and was initially only tested on the mpc823. He -provided the modem driver as well. - -The port was updated to 2.3.11 by Mike Siers -who added an example test. - -Updated the chat program to return the correct errors and support -the ABORT commands. Removed some dead code and did a lot of -testing on a new Coldfire BSP. Version seems to be very stable. - -Update code to use RTEMS pppd network drivers. Now the pppd -software is not dependent on using task driven mode. This -change improved stablity and performance. This was updated -by Mike Siers . -================================================================= - diff --git a/cpukit/pppd/STATUS b/cpukit/pppd/STATUS deleted file mode 100644 index e1b371ac40..0000000000 --- a/cpukit/pppd/STATUS +++ /dev/null @@ -1,23 +0,0 @@ -The pppd application seems to very stable. It has been tested using -the example application with the i386/pc586 and m68k/sbc5206e BSPs. -The tests were executed using a null modem serial cable to connect -with a UNIX box running either the ppp or pppd application and with -an external modem to dial up a local ISP. - -If you have problems getting your target to make consistent connections -with an ISP, the problem is most likely with the ppp options. First -try using the "novj" and "noaccomp" options. If you have questions -about what other option values are available for the rtems_pppd_set_option -function, please look at the pppd.8 man page file or the the source code. -The majority of options that are documented in man page should work -with this function call. - -The pppd code had now been updated to use it's own RTEMS network -drivers. This removes the requirement for the task driven termios -support. This update has fixed the large packet ping problem. -Currently, I do not know of any problems with the port. - -If you find any other problems or fix some problems, please post your -changes to the RTEMS mailing list. - -Good Luck diff --git a/cpukit/pppd/auth.c b/cpukit/pppd/auth.c deleted file mode 100644 index 9df1d32524..0000000000 --- a/cpukit/pppd/auth.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* - * auth.c - PPP authentication and phase control. - * - * Copyright (c) 1993 The Australian National 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 the Australian National 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. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(_PATH_LASTLOG) && defined(_linux_) -#include -#endif - -#include -#include -#include - -#ifdef USE_PAM -#include -#endif - -#ifdef HAS_SHADOW -#include -#ifndef PW_PPP -#define PW_PPP PW_LOGIN -#endif -#endif - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "upap.h" -#include "chap.h" -#ifdef CBCP_SUPPORT -#include "cbcp.h" -#endif -#include "pathnames.h" - -/* The name by which the peer authenticated itself to us. */ -char peer_authname[MAXNAMELEN]; - -/* Records which authentication operations haven't completed yet. */ -static int auth_pending[NUM_PPP]; - -/* List of addresses which the peer may use. */ -static struct permitted_ip *addresses[NUM_PPP]; - -/* Wordlist giving addresses which the peer may use - without authenticating itself. */ -static struct wordlist *noauth_addrs; - -/* Extra options to apply, from the secrets file entry for the peer. */ -static struct wordlist *extra_options; - -/* Number of network protocols which we have opened. */ -static int num_np_open; - -/* Number of network protocols which have come up. */ -static int num_np_up; - -/* Set if we got the contents of passwd[] from the pap-secrets file. */ -static int passwd_from_file; - -/* Set if we require authentication only because we have a default route. */ -static bool default_auth; - -/* Hook for a link status */ -void (*auth_linkup_hook)(void) = NULL; -void (*auth_linkdown_hook)(void) = NULL; - -/* Hook to enable a plugin to control the idle time limit */ -int (*idle_time_hook)(struct ppp_idle *) = NULL; - -/* Hook for a plugin to say whether we can possibly authenticate any peer */ -int (*pap_check_hook)(void) = NULL; - -/* Hook for a plugin to check the PAP user and password */ -int (*pap_auth_hook)(char *user, char *passwd/*, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts*/) = NULL; - -/* Hook for a plugin to know about the PAP user logout */ -void (*pap_logout_hook)(void) = NULL; - -/* Hook for a plugin to get the PAP password for authenticating us */ -int (*pap_passwd_hook)(char *user, char *passwd) = NULL; - -/* - * This is used to ensure that we don't start an auth-up/down - * script while one is already running. - */ -enum script_state { - s_down, - s_up -}; - -static enum script_state auth_state = s_down; -static enum script_state auth_script_state = s_down; - -/* - * Option variables. - */ -bool uselogin = 0; /* Use /etc/passwd for checking PAP */ -bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ -bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ -bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ -bool usehostname = 0; /* Use hostname for our_name */ -bool auth_required = 0; /* Always require authentication from peer */ -bool allow_any_ip = 0; /* Allow peer to use any IP address */ -bool explicit_remote = 0; /* User specified explicit remote name */ -char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ - -/* Bits in auth_pending[] */ -#define PAP_WITHPEER 1 -#define PAP_PEER 2 -#define CHAP_WITHPEER 4 -#define CHAP_PEER 8 - -extern char *crypt(const char *, const char *); - -/* Prototypes for procedures local to this file. */ - -static void network_phase(int); -static void check_idle(void *); -static void connect_time_expired(void *); -static int null_login(int); -static int get_pap_passwd(char *); -static int have_pap_secret(int *); -static int have_chap_secret(char *, char *, int, int *); -#if 0 -static int ip_addr_check(uint32_t, struct permitted_ip *); -#endif -static void free_wordlist(struct wordlist *); -static void auth_script(enum script_state s); -static void set_allowed_addrs(int, struct wordlist *, struct wordlist *); - - -/* - * Authentication-related options. - */ -option_t auth_options[] = { - { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", 1, &auth_required, 0, 0 }, - { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", 1, &auth_required, 0, 0 }, - { "refuse-pap", o_bool, &refuse_pap, - "Don't agree to auth to peer with PAP", 1, NULL, 0, 0 }, - { "-pap", o_bool, &refuse_pap, - "Don't allow PAP authentication with peer", 1, NULL, 0, 0 }, - { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap, - "Require CHAP authentication from peer", 1, &auth_required, 0, 0 }, - { "+chap", o_bool, &lcp_wantoptions[0].neg_chap, - "Require CHAP authentication from peer", 1, &auth_required, 0, 0 }, - { "refuse-chap", o_bool, &refuse_chap, - "Don't agree to auth to peer with CHAP", 1, NULL, 0, 0 }, - { "-chap", o_bool, &refuse_chap, - "Don't allow CHAP authentication with peer", 1, NULL, 0, 0 }, - { "name", o_string, our_name, - "Set local name for authentication", - OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN, 0 }, - { "user", o_string, user, - "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN, 0 }, - { "usehostname", o_bool, &usehostname, - "Must use hostname for authentication", 1, NULL, 0, 0 }, - { "remotename", o_string, remote_name, - "Set remote name for authentication", OPT_STATIC, - &explicit_remote, MAXNAMELEN, 0 }, - { "auth", o_bool, &auth_required, - "Require authentication from peer", 1, NULL, 0, 0 }, - { "noauth", o_bool, &auth_required, - "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip, 0, 0 }, - { "login", o_bool, &uselogin, - "Use system password database for PAP", 1, NULL, 0, 0 }, - { "papcrypt", o_bool, &cryptpap, - "PAP passwords are encrypted", 1, NULL, 0, 0 }, -/* Removed for RTEMS PORT - { "+ua", o_special, setupapfile, - "Get PAP user and password from file" }, -*/ - { "password", o_string, passwd, - "Password for authenticating us to the peer", OPT_STATIC, - NULL, MAXSECRETLEN, 0 }, -/* Removed for RTEMS_PORT - { "privgroup", o_special, privgroup, - "Allow group members to use privileged options", OPT_PRIV }, - { "allow-ip", o_special, set_noauth_addr, - "Set IP address(es) which can be used without authentication", - OPT_PRIV }, -*/ - { NULL, 0, NULL, NULL, 0, NULL, 0, 0 } -}; - -/* - * An Open on LCP has requested a change from Dead to Establish phase. - * Do what's necessary to bring the physical layer up. - */ -void -link_required( - int unit ) -{ -} - -/* - * LCP has terminated the link; go to the Dead phase and take the - * physical layer down. - */ -void -link_terminated( - int unit) -{ - if (pppd_phase == PHASE_DEAD) - return; - if (pap_logout_hook) { - pap_logout_hook(); - } - new_phase(PHASE_DEAD); - notice("Connection terminated."); -} - -/* - * LCP has gone down; it will either die or try to re-establish. - */ -void -link_down( - int unit) -{ - int i; - struct protent *protp; - - auth_state = s_down; - if (auth_script_state == s_up) { - update_link_stats(unit); - auth_script(s_down); - } - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (!protp->enabled_flag) - continue; - if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) - (*protp->lowerdown)(unit); - if (protp->protocol < 0xC000 && protp->close != NULL) - (*protp->close)(unit, "LCP down"); - } - num_np_open = 0; - num_np_up = 0; - if (pppd_phase != PHASE_DEAD) - new_phase(PHASE_TERMINATE); -} - -/* - * The link is established. - * Proceed to the Dead, Authenticate or Network phase as appropriate. - */ -void -link_established( - int unit ) -{ - int auth; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ho = &lcp_hisoptions[unit]; - int i; - struct protent *protp; - - /* - * Tell higher-level protocols that LCP is up. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol != PPP_LCP && protp->enabled_flag - && protp->lowerup != NULL) - (*protp->lowerup)(unit); - - if (auth_required && !(go->neg_chap || go->neg_upap)) { - /* - * We wanted the peer to authenticate itself, and it refused: - * if we have some address(es) it can use without auth, fine, - * otherwise treat it as though it authenticated with PAP using - * a username * of "" and a password of "". If that's not OK, - * boot it out. - */ - if (noauth_addrs != NULL) { - set_allowed_addrs(unit, noauth_addrs, NULL); - } else if (!wo->neg_upap || !null_login(unit)) { - warn("peer refused to authenticate: terminating link"); - lcp_close(unit, "peer refused to authenticate"); - pppd_status = EXIT_PEER_AUTH_FAILED; - return; - } - } - - new_phase(PHASE_AUTHENTICATE); - auth = 0; - if (go->neg_chap) { - ChapAuthPeer(unit, our_name, go->chap_mdtype); - auth |= CHAP_PEER; - } else if (go->neg_upap) { - upap_authpeer(unit); - auth |= PAP_PEER; - } - if (ho->neg_chap) { - ChapAuthWithPeer(unit, user, ho->chap_mdtype); - auth |= CHAP_WITHPEER; - } else if (ho->neg_upap) { - if (passwd[0] == 0) { - passwd_from_file = 1; - if (!get_pap_passwd(passwd)) - error("No secret found for PAP login"); - } - upap_authwithpeer(unit, user, passwd); - auth |= PAP_WITHPEER; - } - auth_pending[unit] = auth; - - if (!auth) - network_phase(unit); -} - -/* - * Proceed to the network phase. - */ -static void -network_phase( - int unit ) -{ -#ifdef CBCP_SUPPORT - lcp_options *go = &lcp_gotoptions[unit]; -#endif - - /* always run the auth-up script */ - auth_state = s_up; - if (auth_script_state == s_down) { - auth_script(s_up); - } - -#ifdef CBCP_SUPPORT - /* - * If we negotiated callback, do it now. - */ - if (go->neg_cbcp) { - new_phase(PHASE_CALLBACK); - (*cbcp_protent.open)(unit); - return; - } -#endif - - /* - * Process extra options from the secrets file - */ - if (extra_options) { - options_from_list(extra_options, 1); - free_wordlist(extra_options); - extra_options = 0; - } - start_networks(); -} - -void -start_networks(void) -{ - int i; - struct protent *protp; - - new_phase(PHASE_NETWORK); - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol < 0xC000 && protp->enabled_flag - && protp->open != NULL) { - (*protp->open)(0); - if (protp->protocol != PPP_CCP) - ++num_np_open; - } - - if (num_np_open == 0) - /* nothing to do */ - lcp_close(0, "No network protocols running"); -} - -/* - * The peer has failed to authenticate himself using `protocol'. - */ -void -auth_peer_fail( - int unit, - int protocol) -{ - /* - * Authentication failure: take the link down - */ - lcp_close(unit, "Authentication failed"); - pppd_status = EXIT_PEER_AUTH_FAILED; -} - -/* - * The peer has been successfully authenticated using `protocol'. - */ -void -auth_peer_success( - int unit, - int protocol, - char *name, - int namelen) -{ - int bit; - - switch (protocol) { - case PPP_CHAP: - bit = CHAP_PEER; - break; - case PPP_PAP: - bit = PAP_PEER; - break; - default: - warn("auth_peer_success: unknown protocol %x", protocol); - return; - } - - /* - * Save the authenticated name of the peer for later. - */ - if (namelen > sizeof(peer_authname) - 1) - namelen = sizeof(peer_authname) - 1; - BCOPY(name, peer_authname, namelen); - peer_authname[namelen] = 0; - - /* - * If there is no more authentication still to be done, - * proceed to the network (or callback) phase. - */ - if ((auth_pending[unit] &= ~bit) == 0) - network_phase(unit); -} - -/* - * We have failed to authenticate ourselves to the peer using `protocol'. - */ -void -auth_withpeer_fail( - int unit, - int protocol ) -{ - if (passwd_from_file) - BZERO(passwd, MAXSECRETLEN); - /* - * We've failed to authenticate ourselves to our peer. - * Some servers keep sending CHAP challenges, but there - * is no point in persisting without any way to get updated - * authentication secrets. - */ - lcp_close(unit, "Failed to authenticate ourselves to peer"); - pppd_status = EXIT_AUTH_TOPEER_FAILED; -} - -/* - * We have successfully authenticated ourselves with the peer using `protocol'. - */ -void -auth_withpeer_success( - int unit, - int protocol ) -{ - int bit; - - switch (protocol) { - case PPP_CHAP: - bit = CHAP_WITHPEER; - break; - case PPP_PAP: - if (passwd_from_file) - BZERO(passwd, MAXSECRETLEN); - bit = PAP_WITHPEER; - break; - default: - warn("auth_withpeer_success: unknown protocol %x", protocol); - bit = 0; - } - - /* - * If there is no more authentication still being done, - * proceed to the network (or callback) phase. - */ - if ((auth_pending[unit] &= ~bit) == 0) - network_phase(unit); -} - - -/* - * np_up - a network protocol has come up. - */ -void -np_up( - int unit, - int proto ) -{ - int tlim; - - if (num_np_up == 0) { - /* - * At this point we consider that the link has come up successfully. - */ - pppd_status = EXIT_OK; - unsuccess = 0; - new_phase(PHASE_RUNNING); - - if (idle_time_hook != 0) - tlim = (*idle_time_hook)(NULL); - else - tlim = idle_time_limit; - if (tlim > 0) - TIMEOUT(check_idle, NULL, tlim); - - /* - * Set a timeout to close the connection once the maximum - * connect time has expired. - */ - if (maxconnect > 0) - TIMEOUT(connect_time_expired, 0, maxconnect); - } - ++num_np_up; -} - -/* - * np_down - a network protocol has gone down. - */ -void -np_down( - int unit, - int proto) -{ - if (--num_np_up == 0) { - UNTIMEOUT(check_idle, NULL); - new_phase(PHASE_NETWORK); - } -} - -/* - * np_finished - a network protocol has finished using the link. - */ -void -np_finished( - int unit, - int proto ) -{ - if (--num_np_open <= 0) { - /* no further use for the link: shut up shop. */ - lcp_close(0, "No network protocols running"); - } -} - -/* - * check_idle - check whether the link has been idle for long - * enough that we can shut it down. - */ -static void -check_idle( - void *arg ) -{ - struct ppp_idle idle; - time_t itime; - int tlim; - - if (!get_idle_time(0, &idle)) - return; - if (idle_time_hook != 0) { - tlim = idle_time_hook(&idle); - } else { - itime = MIN(idle.xmit_idle, idle.recv_idle); - tlim = idle_time_limit - itime; - } - if (tlim <= 0) { - /* link is idle: shut it down. */ - notice("Terminating connection due to lack of activity."); - lcp_close(0, "Link inactive"); - need_holdoff = 0; - pppd_status = EXIT_IDLE_TIMEOUT; - } else { - TIMEOUT(check_idle, NULL, tlim); - } -} - -/* - * connect_time_expired - log a message and close the connection. - */ -static void -connect_time_expired( - void *arg) -{ - info("Connect time expired"); - lcp_close(0, "Connect time expired"); /* Close connection */ - pppd_status = EXIT_CONNECT_TIME; -} - -/* - * auth_check_options - called to check authentication options. - */ -int -auth_check_options(void) -{ - lcp_options *wo = &lcp_wantoptions[0]; - int status = 1; - int can_auth; - int lacks_ip; - - /* Default our_name to hostname, and user to our_name */ - if (our_name[0] == 0 || usehostname) - strlcpy(our_name, hostname, sizeof(our_name)); - if (user[0] == 0) - strlcpy(user, our_name, sizeof(user)); - - /* - * If we have a default route, require the peer to authenticate - * unless the noauth option was given or the real user is root. - */ - if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { - printf("auth_check_options: turning on\n"); - auth_required = 1; - default_auth = 1; - } - - /* If authentication is required, ask peer for CHAP or PAP. */ - if (auth_required) { - if (!wo->neg_chap && !wo->neg_upap) { - wo->neg_chap = 1; - wo->neg_upap = 1; - } - } else { - wo->neg_chap = 0; - wo->neg_upap = 0; - } - - /* - * Check whether we have appropriate secrets to use - * to authenticate the peer. - */ - lacks_ip = 0; - can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); - if (!can_auth && wo->neg_chap) { - can_auth = have_chap_secret((explicit_remote? remote_name: NULL), - our_name, 1, &lacks_ip); - } - - if (auth_required && !can_auth && noauth_addrs == NULL) { - if (default_auth) { - option_error( -"By default the remote system is required to authenticate itself"); - option_error( -"(because this system has a default route to the internet)"); - } else if (explicit_remote) - option_error( -"The remote system (%s) is required to authenticate itself", - remote_name); - else - option_error( -"The remote system is required to authenticate itself"); - option_error( -"but I couldn't find any suitable secret (password) for it to use to do so."); - if (lacks_ip) - option_error( -"(None of the available passwords would let it use an IP address.)"); - - status = 0; - } - return ( status ); -} - -/* - * auth_reset - called when LCP is starting negotiations to recheck - * authentication options, i.e. whether we have appropriate secrets - * to use for authenticating ourselves and/or the peer. - */ -void -auth_reset( - int unit) -{ - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[0]; - - ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); - ao->neg_chap = !refuse_chap - && (passwd[0] != 0 - || have_chap_secret(user, (explicit_remote? remote_name: NULL), - 0, NULL)); - - if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) - go->neg_upap = 0; - if (go->neg_chap) { - if (!have_chap_secret((explicit_remote? remote_name: NULL), - our_name, 1, NULL)) - go->neg_chap = 0; - } -} - - -/* - * check_passwd - Check the user name and passwd against the PAP secrets - * file. If requested, also check against the system password database, - * and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Authentication failed. - * UPAP_AUTHACK: Authentication succeeded. - * In either case, msg points to an appropriate message. - */ -int -check_passwd( - int unit, - char *auser, - int userlen, - char *apasswd, - int passwdlen, - char **msg) -{ - char passwd[64], user[64]; - - if (pap_auth_hook) - { - slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd); - slprintf(user, sizeof(user), "%.*v", userlen, auser); - - return (*pap_auth_hook)(user, passwd/*, NULL, NULL, NULL*/) ? - UPAP_AUTHACK : UPAP_AUTHNAK; - } - - return UPAP_AUTHACK; - -#if 0 - int ret = (int)UPAP_AUTHNAK; - - if (( userlen == 0 ) && ( passwdlen == 0 )) { - ret = (int)UPAP_AUTHACK; - } - printf("check_passwd: %d\n", ret); - - return ret; -#endif -} - -/* - * null_login - Check if a username of "" and a password of "" are - * acceptable, and iff so, set the list of acceptable IP addresses - * and return 1. - */ -static int -null_login( - int unit) -{ - return 0; -} - - -/* - * get_pap_passwd - get a password for authenticating ourselves with - * our peer using PAP. Returns 1 on success, 0 if no suitable password - * could be found. - * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). - */ -static int -get_pap_passwd( - char *passwd) -{ - int ret = (int)0; - - /* - * Check whether a plugin wants to supply this. - */ - if (pap_passwd_hook) { - ret = (*pap_passwd_hook)(user, passwd); - } - - return ( ret ); -} - - -/* - * have_pap_secret - check whether we have a PAP file with any - * secrets that we could possibly use for authenticating the peer. - */ -static int -have_pap_secret( - int *lacks_ipp) -{ - return 1; - -#if 0 - int ret = (int)0; - - /* let the plugin decide, if there is one */ - printf("have_pap_secret:\n"); - if (pap_check_hook) { - ret = (*pap_check_hook)(); - } - - return ( ret ); -#endif -} - - -/* - * have_chap_secret - check whether we have a CHAP file with a - * secret that we could possibly use for authenticating `client' - * on `server'. Either can be the null string, meaning we don't - * know the identity yet. - */ -static int -have_chap_secret( - char *client, - char *server, - int need_ip, - int *lacks_ipp) -{ - return 0; -} - - -/* - * get_secret - open the CHAP secret file and return the secret - * for authenticating the given client on the given server. - * (We could be either client or server). - */ -int -get_secret( - int unit, - char *client, - char *server, - unsigned char *secret, - int *secret_len, - int am_server) -{ - int len; - char secbuf[MAXWORDLEN]; - - if (!am_server && passwd[0] != 0) { - strlcpy(secbuf, passwd, sizeof(secbuf)); - } else { - return 0; - } - - len = strlen(secbuf); - if (len > MAXSECRETLEN) { - error("Secret for %s on %s is too long", client, server); - len = MAXSECRETLEN; - } - BCOPY(secbuf, secret, len); - BZERO(secbuf, sizeof(secbuf)); - *secret_len = len; - - return 1; -} - -/* - * set_allowed_addrs() - set the list of allowed addresses. - * Also looks for `--' indicating options to apply for this peer - * and leaves the following words in extra_options. - */ -static void -set_allowed_addrs( - int unit, - struct wordlist *addrs, - struct wordlist *opts) -{ - int n; - struct wordlist *ap, **pap; - struct permitted_ip *ip; - char *ptr_word, *ptr_mask; - struct hostent *hp; - struct netent *np; - uint32_t a, mask, ah, offset; - struct ipcp_options *wo = &ipcp_wantoptions[unit]; - uint32_t suggested_ip = 0; - - if (addresses[unit] != NULL) - free(addresses[unit]); - addresses[unit] = NULL; - if (extra_options != NULL) - free_wordlist(extra_options); - extra_options = opts; - - /* - * Count the number of IP addresses given. - */ - for (n = 0, pap = &addrs; (ap = *pap) != NULL; pap = &ap->next) - ++n; - if (n == 0) - return; - ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); - if (ip == 0) - return; - - n = 0; - for (ap = addrs; ap != NULL; ap = ap->next) { - /* "-" means no addresses authorized, "*" means any address allowed */ - ptr_word = ap->word; - if (strcmp(ptr_word, "-") == 0) - break; - if (strcmp(ptr_word, "*") == 0) { - ip[n].permit = 1; - ip[n].base = ip[n].mask = 0; - ++n; - break; - } - - ip[n].permit = 1; - if (*ptr_word == '!') { - ip[n].permit = 0; - ++ptr_word; - } - - mask = ~ (uint32_t) 0; - offset = 0; - ptr_mask = strchr (ptr_word, '/'); - if (ptr_mask != NULL) { - int bit_count; - char *endp; - - bit_count = (int) strtol (ptr_mask+1, &endp, 10); - if (bit_count <= 0 || bit_count > 32) { - warn("invalid address length %v in auth. address list", - ptr_mask+1); - continue; - } - bit_count = 32 - bit_count; /* # bits in host part */ - if (*endp == '+') { - offset = pppifunit + 1; - ++endp; - } - if (*endp != 0) { - warn("invalid address length syntax: %v", ptr_mask+1); - continue; - } - *ptr_mask = '\0'; - mask <<= bit_count; - } - - hp = gethostbyname(ptr_word); - if (hp != NULL && hp->h_addrtype == AF_INET) { - a = *(uint32_t *)hp->h_addr; - } else { - np = getnetbyname (ptr_word); - if (np != NULL && np->n_addrtype == AF_INET) { - a = htonl (np->n_net); - if (ptr_mask == NULL) { - /* calculate appropriate mask for net */ - ah = ntohl(a); - if (IN_CLASSA(ah)) - mask = IN_CLASSA_NET; - else if (IN_CLASSB(ah)) - mask = IN_CLASSB_NET; - else if (IN_CLASSC(ah)) - mask = IN_CLASSC_NET; - } - } else { - a = inet_addr (ptr_word); - } - } - - if (ptr_mask != NULL) - *ptr_mask = '/'; - - if (a == (uint32_t)-1L) { - warn("unknown host %s in auth. address list", ap->word); - continue; - } - if (offset != 0) { - if (offset >= ~mask) { - warn("interface unit %d too large for subnet %v", - pppifunit, ptr_word); - continue; - } - a = htonl((ntohl(a) & mask) + offset); - mask = ~(uint32_t)0; - } - ip[n].mask = htonl(mask); - ip[n].base = a & ip[n].mask; - ++n; - if (~mask == 0 && suggested_ip == 0) - suggested_ip = a; - } - - ip[n].permit = 0; /* make the last entry forbid all addresses */ - ip[n].base = 0; /* to terminate the list */ - ip[n].mask = 0; - - addresses[unit] = ip; - - /* - * If the address given for the peer isn't authorized, or if - * the user hasn't given one, AND there is an authorized address - * which is a single host, then use that if we find one. - */ - if (suggested_ip != 0 - && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) - wo->hisaddr = suggested_ip; -} - -/* - * auth_ip_addr - check whether the peer is authorized to use - * a given IP address. Returns 1 if authorized, 0 otherwise. - */ -int -auth_ip_addr( - int unit, - uint32_t addr) -{ -#if 0 - int ok; -#endif - - /* don't allow loopback or multicast address */ - if (bad_ip_adrs(addr)) - return 0; - - return 1; - -#if 0 - if (addresses[unit] != NULL) { - ok = ip_addr_check(addr, addresses[unit]); - if (ok >= 0) - return ok; - } - if (auth_required) - return 0; /* no addresses authorized */ - return allow_any_ip || !have_route_to(addr); -#endif -} - -#if 0 -static int -ip_addr_check( - uint32_t addr, - struct permitted_ip *addrs) -{ - for (; ; ++addrs) - if ((addr & addrs->mask) == addrs->base) - return addrs->permit; -} -#endif - -/* - * bad_ip_adrs - return 1 if the IP address is one we don't want - * to use, such as an address in the loopback net or a multicast address. - * addr is in network byte order. - */ -int -bad_ip_adrs( - uint32_t addr) -{ - addr = ntohl(addr); - return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET - || IN_MULTICAST(addr) || IN_BADCLASS(addr); -} - -/* - * free_wordlist - release memory allocated for a wordlist. - */ -static void -free_wordlist( - struct wordlist *wp) -{ - struct wordlist *next; - - while (wp != NULL) { - next = wp->next; - free(wp); - wp = next; - } -} - -/* - * auth_script - execute a script with arguments - * interface-name peer-name real-user tty speed - */ -static void -auth_script( - enum script_state s) -{ - switch (s) { - case s_up: - auth_script_state = s_up; - if ( auth_linkup_hook ) { - (*auth_linkup_hook)(); - } - break; - case s_down: - auth_script_state = s_down; - if ( auth_linkdown_hook ) { - (*auth_linkdown_hook)(); - } - break; - } -} diff --git a/cpukit/pppd/cbcp.c b/cpukit/pppd/cbcp.c deleted file mode 100644 index eb750838cc..0000000000 --- a/cpukit/pppd/cbcp.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * cbcp - Call Back Configuration Protocol. - * - * Copyright (c) 1995 Pedro Roque Marques - * 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 Pedro Roque Marques. The name of the author 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. - */ - -#define RCSID "$Id$" - -#include -#include -#include -#include - -#include "pppd.h" -#include "cbcp.h" -#include "fsm.h" -#include "lcp.h" - -static const char rcsid[] = RCSID; - -/* - * Options. - */ -static int setcbcp(char **); - -static option_t cbcp_option_list[] = { - { "callback", o_special, setcbcp, - "Ask for callback" }, - { NULL } -}; - -/* - * Protocol entry points. - */ -static void cbcp_init (int unit); -static void cbcp_open (int unit); -static void cbcp_lowerup (int unit); -static void cbcp_input (int unit, u_char *pkt, int len); -static void cbcp_protrej (int unit); -static int cbcp_printpkt (u_char *pkt, int len, - void (*printer)(void *, char *, ...), - void *arg); - -struct protent cbcp_protent = { - PPP_CBCP, - cbcp_init, - cbcp_input, - cbcp_protrej, - cbcp_lowerup, - NULL, - cbcp_open, - NULL, - cbcp_printpkt, - NULL, - 0, - "CBCP", - NULL, - cbcp_option_list, - NULL, - NULL, - NULL -}; - -cbcp_state cbcp[NUM_PPP]; - -/* internal prototypes */ - -static void cbcp_recvreq(cbcp_state *us, char *pckt, int len); -static void cbcp_resp(cbcp_state *us); -static void cbcp_up(cbcp_state *us); -static void cbcp_recvack(cbcp_state *us, char *pckt, int len); -static void cbcp_send(cbcp_state *us, u_char code, u_char *buf, int len); - -/* option processing */ -static int -setcbcp(argv) - char **argv; -{ - lcp_wantoptions[0].neg_cbcp = 1; - cbcp_protent.enabled_flag = 1; - cbcp[0].us_number = strdup(*argv); - if (cbcp[0].us_number == 0) - novm("callback number"); - cbcp[0].us_type |= (1 << CB_CONF_USER); - cbcp[0].us_type |= (1 << CB_CONF_ADMIN); - return (1); -} - -/* init state */ -static void -cbcp_init(iface) - int iface; -{ - cbcp_state *us; - - us = &cbcp[iface]; - memset(us, 0, sizeof(cbcp_state)); - us->us_unit = iface; - us->us_type |= (1 << CB_CONF_NO); -} - -/* lower layer is up */ -static void -cbcp_lowerup(iface) - int iface; -{ - cbcp_state *us = &cbcp[iface]; - - dbglog("cbcp_lowerup"); - dbglog("want: %d", us->us_type); - - if (us->us_type == CB_CONF_USER) - dbglog("phone no: %s", us->us_number); -} - -static void -cbcp_open(unit) - int unit; -{ - dbglog("cbcp_open"); -} - -/* process an incomming packet */ -static void -cbcp_input(unit, inpacket, pktlen) - int unit; - u_char *inpacket; - int pktlen; -{ - u_char *inp; - u_char code, id; - u_short len; - - cbcp_state *us = &cbcp[unit]; - - inp = inpacket; - - if (pktlen < CBCP_MINLEN) { - error("CBCP packet is too small"); - return; - } - - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - -#if 0 - if (len > pktlen) { - error("CBCP packet: invalid length"); - return; - } -#endif - - len -= CBCP_MINLEN; - - switch(code) { - case CBCP_REQ: - us->us_id = id; - cbcp_recvreq(us, inp, len); - break; - - case CBCP_RESP: - dbglog("CBCP_RESP received"); - break; - - case CBCP_ACK: - if (id != us->us_id) - dbglog("id doesn't match: expected %d recv %d", - us->us_id, id); - - cbcp_recvack(us, inp, len); - break; - - default: - break; - } -} - -/* protocol was rejected by foe */ -void cbcp_protrej(int iface) -{ -} - -char *cbcp_codenames[] = { - "Request", "Response", "Ack" -}; - -char *cbcp_optionnames[] = { - "NoCallback", - "UserDefined", - "AdminDefined", - "List" -}; - -/* pretty print a packet */ -static int -cbcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer)(void *, char *, ...); - void *arg; -{ - int code, opt, id, len, olen, delay; - u_char *pstart; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *)) - printer(arg, " %s", cbcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - - switch (code) { - case CBCP_REQ: - case CBCP_RESP: - case CBCP_ACK: - while(len >= 2) { - GETCHAR(opt, p); - GETCHAR(olen, p); - - if (olen < 2 || olen > len) { - break; - } - - printer(arg, " <"); - len -= olen; - - if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *)) - printer(arg, " %s", cbcp_optionnames[opt-1]); - else - printer(arg, " option=0x%x", opt); - - if (olen > 2) { - GETCHAR(delay, p); - printer(arg, " delay = %d", delay); - } - - if (olen > 3) { - int addrt; - char str[256]; - - GETCHAR(addrt, p); - memcpy(str, p, olen - 4); - str[olen - 4] = 0; - printer(arg, " number = %s", str); - } - printer(arg, ">"); - break; - } - - default: - break; - } - - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} - -/* received CBCP request */ -static void -cbcp_recvreq(us, pckt, pcktlen) - cbcp_state *us; - char *pckt; - int pcktlen; -{ - u_char type, opt_len, delay, addr_type; - char address[256]; - int len = pcktlen; - - address[0] = 0; - - while (len) { - dbglog("length: %d", len); - - GETCHAR(type, pckt); - GETCHAR(opt_len, pckt); - - if (opt_len > 2) - GETCHAR(delay, pckt); - - us->us_allowed |= (1 << type); - - switch(type) { - case CB_CONF_NO: - dbglog("no callback allowed"); - break; - - case CB_CONF_USER: - dbglog("user callback allowed"); - if (opt_len > 4) { - GETCHAR(addr_type, pckt); - memcpy(address, pckt, opt_len - 4); - address[opt_len - 4] = 0; - if (address[0]) - dbglog("address: %s", address); - } - break; - - case CB_CONF_ADMIN: - dbglog("user admin defined allowed"); - break; - - case CB_CONF_LIST: - break; - } - len -= opt_len; - } - - cbcp_resp(us); -} - -static void -cbcp_resp(us) - cbcp_state *us; -{ - u_char cb_type; - u_char buf[256]; - u_char *bufp = buf; - int len = 0; - - cb_type = us->us_allowed & us->us_type; - dbglog("cbcp_resp cb_type=%d", cb_type); - -#if 0 - if (!cb_type) - lcp_down(us->us_unit); -#endif - - if (cb_type & ( 1 << CB_CONF_USER ) ) { - dbglog("cbcp_resp CONF_USER"); - PUTCHAR(CB_CONF_USER, bufp); - len = 3 + 1 + strlen(us->us_number) + 1; - PUTCHAR(len , bufp); - PUTCHAR(5, bufp); /* delay */ - PUTCHAR(1, bufp); - BCOPY(us->us_number, bufp, strlen(us->us_number) + 1); - cbcp_send(us, CBCP_RESP, buf, len); - return; - } - - if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { - dbglog("cbcp_resp CONF_ADMIN"); - PUTCHAR(CB_CONF_ADMIN, bufp); - len = 3; - PUTCHAR(len, bufp); - PUTCHAR(5, bufp); /* delay */ - cbcp_send(us, CBCP_RESP, buf, len); - return; - } - - if (cb_type & ( 1 << CB_CONF_NO ) ) { - dbglog("cbcp_resp CONF_NO"); - PUTCHAR(CB_CONF_NO, bufp); - len = 3; - PUTCHAR(len , bufp); - PUTCHAR(0, bufp); - cbcp_send(us, CBCP_RESP, buf, len); - start_networks(); - return; - } -} - -static void -cbcp_send(us, code, buf, len) - cbcp_state *us; - u_char code; - u_char *buf; - int len; -{ - u_char *outp; - int outlen; - - outp = outpacket_buf; - - outlen = 4 + len; - - MAKEHEADER(outp, PPP_CBCP); - - PUTCHAR(code, outp); - PUTCHAR(us->us_id, outp); - PUTSHORT(outlen, outp); - - if (len) - BCOPY(buf, outp, len); - - output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN); -} - -static void -cbcp_recvack(us, pckt, len) - cbcp_state *us; - char *pckt; - int len; -{ - u_char type, delay, addr_type; - int opt_len; - char address[256]; - - if (len) { - GETCHAR(type, pckt); - GETCHAR(opt_len, pckt); - - if (opt_len > 2) - GETCHAR(delay, pckt); - - if (opt_len > 4) { - GETCHAR(addr_type, pckt); - memcpy(address, pckt, opt_len - 4); - address[opt_len - 4] = 0; - if (address[0]) - dbglog("peer will call: %s", address); - } - if (type == CB_CONF_NO) - return; - } - - cbcp_up(us); -} - -/* ok peer will do callback */ -static void -cbcp_up(us) - cbcp_state *us; -{ - persist = 0; - lcp_close(0, "Call me back, please"); - status = EXIT_CALLBACK; -} diff --git a/cpukit/pppd/cbcp.h b/cpukit/pppd/cbcp.h deleted file mode 100644 index c2ab3f6899..0000000000 --- a/cpukit/pppd/cbcp.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef CBCP_H -#define CBCP_H - -typedef struct cbcp_state { - int us_unit; /* Interface unit number */ - u_char us_id; /* Current id */ - u_char us_allowed; - int us_type; - char *us_number; /* Telefone Number */ -} cbcp_state; - -extern cbcp_state cbcp[]; - -extern struct protent cbcp_protent; - -#define CBCP_MINLEN 4 - -#define CBCP_REQ 1 -#define CBCP_RESP 2 -#define CBCP_ACK 3 - -#define CB_CONF_NO 1 -#define CB_CONF_USER 2 -#define CB_CONF_ADMIN 3 -#define CB_CONF_LIST 4 -#endif diff --git a/cpukit/pppd/ccp.c b/cpukit/pppd/ccp.c deleted file mode 100644 index 6ada96c22b..0000000000 --- a/cpukit/pppd/ccp.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* - * ccp.c - PPP Compression Control Protocol. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -#include -#include - -#include "pppd.h" -#include "fsm.h" -#include "ccp.h" -#include - -/* - * Command-line options. - */ -static int setbsdcomp(char **); -static int setdeflate(char **); - -static option_t ccp_option_list[] = { - { "noccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation", 0, NULL, 0, 0 }, - { "-ccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation", 0, NULL, 0, 0 }, - { "bsdcomp", o_special, setbsdcomp, - "Request BSD-Compress packet compression", 0, NULL, 0, 0 }, - { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_A2COPY, - &ccp_allowoptions[0].bsd_compress, 0, 0 }, - { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_A2COPY, - &ccp_allowoptions[0].bsd_compress, 0, 0 }, - { "deflate", 1, setdeflate, - "request Deflate compression", 0, NULL, 0, 0 }, - { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_A2COPY, - &ccp_allowoptions[0].deflate, 0, 0 }, - { "-deflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_A2COPY, - &ccp_allowoptions[0].deflate, 0, 0 }, - { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, - "don't use draft deflate #", OPT_A2COPY, - &ccp_allowoptions[0].deflate_draft, 0, 0 }, - { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "request Predictor-1", 1, - &ccp_allowoptions[0].predictor_1, 0, 0 }, - { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_A2COPY, - &ccp_allowoptions[0].predictor_1, 0, 0 }, - { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_A2COPY, - &ccp_allowoptions[0].predictor_1, 0, 0 }, - - { NULL, 0, NULL, NULL, 0, NULL, 0, 0 } -}; - -/* - * Protocol entry points from main code. - */ -static void ccp_init(int unit); -static void ccp_open(int unit); -static void ccp_close(int unit, char *); -static void ccp_lowerup(int unit); -static void ccp_lowerdown(int); -static void ccp_input(int unit, u_char *pkt, int len); -static void ccp_protrej(int unit); -static int ccp_printpkt(u_char *pkt, int len, - void (*printer)(void *, char *, ...), - void *arg); -static void ccp_datainput(int unit, u_char *pkt, int len); - -struct protent ccp_protent = { - PPP_CCP, - ccp_init, - ccp_input, - ccp_protrej, - ccp_lowerup, - ccp_lowerdown, - ccp_open, - ccp_close, - ccp_printpkt, - ccp_datainput, - 1, - "CCP", - "Compressed", - ccp_option_list, - NULL, - NULL, - NULL -}; - -fsm ccp_fsm[NUM_PPP]; -ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */ -ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ -ccp_options ccp_allowoptions[NUM_PPP]; /* what we'll agree to do */ -ccp_options ccp_hisoptions[NUM_PPP]; /* what we agreed to do */ - -/* - * Callbacks for fsm code. - */ -static void ccp_resetci(fsm *); -static int ccp_cilen(fsm *); -static void ccp_addci(fsm *, u_char *, int *); -static int ccp_ackci(fsm *, u_char *, int); -static int ccp_nakci(fsm *, u_char *, int); -static int ccp_rejci(fsm *, u_char *, int); -static int ccp_reqci(fsm *, u_char *, int *, int); -static void ccp_up(fsm *); -static void ccp_down(fsm *); -static int ccp_extcode(fsm *, int, int, u_char *, int); -static void ccp_rack_timeout(void *); -static char *method_name(ccp_options *, ccp_options *); - -static fsm_callbacks ccp_callbacks = { - ccp_resetci, - ccp_cilen, - ccp_addci, - ccp_ackci, - ccp_nakci, - ccp_rejci, - ccp_reqci, - ccp_up, - ccp_down, - NULL, - NULL, - NULL, - NULL, - ccp_extcode, - "CCP" -}; - -/* - * Do we want / did we get any compression? - */ -#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \ - || (opt).predictor_1 || (opt).predictor_2) - -/* - * Local state (mainly for handling reset-reqs and reset-acks). - */ -static int ccp_localstate[NUM_PPP]; -#define RACK_PENDING 1 /* waiting for reset-ack */ -#define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */ - -#define RACKTIMEOUT 1 /* second */ - -static int all_rejected[NUM_PPP]; /* we rejected all peer's options */ - -/* - * Option parsing. - */ -static int -setbsdcomp( - char **argv) -{ - int rbits, abits; - char *str, *endp; - - str = *argv; - abits = rbits = strtol(str, &endp, 0); - if (endp != str && *endp == ',') { - str = endp + 1; - abits = strtol(str, &endp, 0); - } - if (*endp != 0 || endp == str) { - option_error("invalid parameter '%s' for bsdcomp option", *argv); - return 0; - } - if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) - || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) { - option_error("bsdcomp option values must be 0 or %d .. %d", - BSD_MIN_BITS, BSD_MAX_BITS); - return 0; - } - if (rbits > 0) { - ccp_wantoptions[0].bsd_compress = 1; - ccp_wantoptions[0].bsd_bits = rbits; - } else - ccp_wantoptions[0].bsd_compress = 0; - if (abits > 0) { - ccp_allowoptions[0].bsd_compress = 1; - ccp_allowoptions[0].bsd_bits = abits; - } else - ccp_allowoptions[0].bsd_compress = 0; - return 1; -} - -static int -setdeflate( - char **argv) -{ - int rbits, abits; - char *str, *endp; - - str = *argv; - abits = rbits = strtol(str, &endp, 0); - if (endp != str && *endp == ',') { - str = endp + 1; - abits = strtol(str, &endp, 0); - } - if (*endp != 0 || endp == str) { - option_error("invalid parameter '%s' for deflate option", *argv); - return 0; - } - if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)) - || (abits != 0 && (abits < DEFLATE_MIN_SIZE - || abits > DEFLATE_MAX_SIZE))) { - option_error("deflate option values must be 0 or %d .. %d", - DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); - return 0; - } - if (rbits > 0) { - ccp_wantoptions[0].deflate = 1; - ccp_wantoptions[0].deflate_size = rbits; - } else - ccp_wantoptions[0].deflate = 0; - if (abits > 0) { - ccp_allowoptions[0].deflate = 1; - ccp_allowoptions[0].deflate_size = abits; - } else - ccp_allowoptions[0].deflate = 0; - return 1; -} - - -/* - * ccp_init - initialize CCP. - */ -static void -ccp_init( - int unit) -{ - fsm *f = &ccp_fsm[unit]; - - f->unit = unit; - f->protocol = PPP_CCP; - f->callbacks = &ccp_callbacks; - fsm_init(f); - - memset(&ccp_wantoptions[unit], 0, sizeof(ccp_options)); - memset(&ccp_gotoptions[unit], 0, sizeof(ccp_options)); - memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options)); - memset(&ccp_hisoptions[unit], 0, sizeof(ccp_options)); - - ccp_wantoptions[0].deflate = 1; - ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE; - ccp_wantoptions[0].deflate_correct = 1; - ccp_wantoptions[0].deflate_draft = 1; - ccp_allowoptions[0].deflate = 1; - ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE; - ccp_allowoptions[0].deflate_correct = 1; - ccp_allowoptions[0].deflate_draft = 1; - - ccp_wantoptions[0].bsd_compress = 1; - ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS; - ccp_allowoptions[0].bsd_compress = 1; - ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS; - - ccp_allowoptions[0].predictor_1 = 1; -} - -/* - * ccp_open - CCP is allowed to come up. - */ -static void -ccp_open( - int unit) -{ - fsm *f = &ccp_fsm[unit]; - - if (f->state != OPENED) - ccp_flags_set(unit, 1, 0); - - /* - * Find out which compressors the kernel supports before - * deciding whether to open in silent mode. - */ - ccp_resetci(f); - if (!ANY_COMPRESS(ccp_gotoptions[unit])) - f->flags |= OPT_SILENT; - - fsm_open(f); -} - -/* - * ccp_close - Terminate CCP. - */ -static void -ccp_close( - int unit, - char *reason) -{ - ccp_flags_set(unit, 0, 0); - fsm_close(&ccp_fsm[unit], reason); -} - -/* - * ccp_lowerup - we may now transmit CCP packets. - */ -static void -ccp_lowerup( - int unit) -{ - fsm_lowerup(&ccp_fsm[unit]); -} - -/* - * ccp_lowerdown - we may not transmit CCP packets. - */ -static void -ccp_lowerdown( - int unit) -{ - fsm_lowerdown(&ccp_fsm[unit]); -} - -/* - * ccp_input - process a received CCP packet. - */ -static void -ccp_input( - int unit, - u_char *p, - int len) -{ - fsm *f = &ccp_fsm[unit]; - int oldstate; - - /* - * Check for a terminate-request so we can print a message. - */ - oldstate = f->state; - fsm_input(f, p, len); - if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) - notice("Compression disabled by peer."); - - /* - * If we get a terminate-ack and we're not asking for compression, - * close CCP. - */ - if (oldstate == REQSENT && p[0] == TERMACK - && !ANY_COMPRESS(ccp_gotoptions[unit])) - ccp_close(unit, "No compression negotiated"); -} - -/* - * Handle a CCP-specific code. - */ -static int -ccp_extcode( - fsm *f, - int code, int id, - u_char *p, - int len) -{ - switch (code) { - case CCP_RESETREQ: - if (f->state != OPENED) - break; - /* send a reset-ack, which the transmitter will see and - reset its compression state. */ - fsm_sdata(f, CCP_RESETACK, id, NULL, 0); - break; - - case CCP_RESETACK: - if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) { - ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT); - UNTIMEOUT(ccp_rack_timeout, f); - } - break; - - default: - return 0; - } - - return 1; -} - -/* - * ccp_protrej - peer doesn't talk CCP. - */ -static void -ccp_protrej( - int unit) -{ - ccp_flags_set(unit, 0, 0); - fsm_lowerdown(&ccp_fsm[unit]); -} - -/* - * ccp_resetci - initialize at start of negotiation. - */ -static void -ccp_resetci( - fsm *f) -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char opt_buf[16]; - - *go = ccp_wantoptions[f->unit]; - all_rejected[f->unit] = 0; - - /* - * Check whether the kernel knows about the various - * compression methods we might request. - */ - if (go->bsd_compress) { - opt_buf[0] = CI_BSD_COMPRESS; - opt_buf[1] = CILEN_BSD_COMPRESS; - opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS); - if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0) - go->bsd_compress = 0; - } - if (go->deflate) { - if (go->deflate_correct) { - opt_buf[0] = CI_DEFLATE; - opt_buf[1] = CILEN_DEFLATE; - opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE); - opt_buf[3] = DEFLATE_CHK_SEQUENCE; - if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) - go->deflate_correct = 0; - } - if (go->deflate_draft) { - opt_buf[0] = CI_DEFLATE_DRAFT; - opt_buf[1] = CILEN_DEFLATE; - opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_SIZE); - opt_buf[3] = DEFLATE_CHK_SEQUENCE; - if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) - go->deflate_draft = 0; - } - if (!go->deflate_correct && !go->deflate_draft) - go->deflate = 0; - } - if (go->predictor_1) { - opt_buf[0] = CI_PREDICTOR_1; - opt_buf[1] = CILEN_PREDICTOR_1; - if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0) - go->predictor_1 = 0; - } - if (go->predictor_2) { - opt_buf[0] = CI_PREDICTOR_2; - opt_buf[1] = CILEN_PREDICTOR_2; - if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0) - go->predictor_2 = 0; - } -} - -/* - * ccp_cilen - Return total length of our configuration info. - */ -static int -ccp_cilen( - fsm *f) -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - - return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) - + (go->deflate? CILEN_DEFLATE: 0) - + (go->predictor_1? CILEN_PREDICTOR_1: 0) - + (go->predictor_2? CILEN_PREDICTOR_2: 0); -} - -/* - * ccp_addci - put our requests in a packet. - */ -static void -ccp_addci( - fsm *f, - u_char *p, - int *lenp) -{ - int res; - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char *p0 = p; - - /* - * Add the compression types that we can receive, in decreasing - * preference order. Get the kernel to allocate the first one - * in case it gets Acked. - */ - if (go->deflate) { - p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT; - p[1] = CILEN_DEFLATE; - p[2] = DEFLATE_MAKE_OPT(go->deflate_size); - p[3] = DEFLATE_CHK_SEQUENCE; - for (;;) { - res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); - if (res > 0) { - p += CILEN_DEFLATE; - break; - } - if (res < 0 || go->deflate_size <= DEFLATE_MIN_SIZE) { - go->deflate = 0; - break; - } - --go->deflate_size; - p[2] = DEFLATE_MAKE_OPT(go->deflate_size); - } - if (p != p0 && go->deflate_correct && go->deflate_draft) { - p[0] = CI_DEFLATE_DRAFT; - p[1] = CILEN_DEFLATE; - p[2] = p[2 - CILEN_DEFLATE]; - p[3] = DEFLATE_CHK_SEQUENCE; - p += CILEN_DEFLATE; - } - } - if (go->bsd_compress) { - p[0] = CI_BSD_COMPRESS; - p[1] = CILEN_BSD_COMPRESS; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); - if (p != p0) { - p += CILEN_BSD_COMPRESS; /* not the first option */ - } else { - for (;;) { - res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); - if (res > 0) { - p += CILEN_BSD_COMPRESS; - break; - } - if (res < 0 || go->bsd_bits <= BSD_MIN_BITS) { - go->bsd_compress = 0; - break; - } - --go->bsd_bits; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); - } - } - } - /* XXX Should Predictor 2 be preferable to Predictor 1? */ - if (go->predictor_1) { - p[0] = CI_PREDICTOR_1; - p[1] = CILEN_PREDICTOR_1; - if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) { - go->predictor_1 = 0; - } else { - p += CILEN_PREDICTOR_1; - } - } - if (go->predictor_2) { - p[0] = CI_PREDICTOR_2; - p[1] = CILEN_PREDICTOR_2; - if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) { - go->predictor_2 = 0; - } else { - p += CILEN_PREDICTOR_2; - } - } - - go->method = (p > p0)? p0[0]: -1; - - *lenp = p - p0; -} - -/* - * ccp_ackci - process a received configure-ack, and return - * 1 iff the packet was OK. - */ -static int -ccp_ackci( - fsm *f, - u_char *p, - int len) -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char *p0 = p; - - if (go->deflate) { - if (len < CILEN_DEFLATE - || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - || p[1] != CILEN_DEFLATE - || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - /* XXX Cope with first/fast ack */ - if (len == 0) - return 1; - if (go->deflate_correct && go->deflate_draft) { - if (len < CILEN_DEFLATE - || p[0] != CI_DEFLATE_DRAFT - || p[1] != CILEN_DEFLATE - || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - } - if (go->bsd_compress) { - if (len < CILEN_BSD_COMPRESS - || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS - || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) - return 0; - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } - if (go->predictor_1) { - if (len < CILEN_PREDICTOR_1 - || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1) - return 0; - p += CILEN_PREDICTOR_1; - len -= CILEN_PREDICTOR_1; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } - if (go->predictor_2) { - if (len < CILEN_PREDICTOR_2 - || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2) - return 0; - p += CILEN_PREDICTOR_2; - len -= CILEN_PREDICTOR_2; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } - - if (len != 0) - return 0; - return 1; -} - -/* - * ccp_nakci - process received configure-nak. - * Returns 1 iff the nak was OK. - */ -static int -ccp_nakci( - fsm *f, - u_char *p, - int len) -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - ccp_options no; /* options we've seen already */ - ccp_options try; /* options to ask for next time */ - - memset(&no, 0, sizeof(no)); - try = *go; - - if (go->deflate && len >= CILEN_DEFLATE - && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - && p[1] == CILEN_DEFLATE) { - no.deflate = 1; - /* - * Peer wants us to use a different code size or something. - * Stop asking for Deflate if we don't understand his suggestion. - */ - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL - || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_SIZE - || p[3] != DEFLATE_CHK_SEQUENCE) - try.deflate = 0; - else if (DEFLATE_SIZE(p[2]) < go->deflate_size) - try.deflate_size = DEFLATE_SIZE(p[2]); - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - if (go->deflate_correct && go->deflate_draft - && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT - && p[1] == CILEN_DEFLATE) { - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - } - - if (go->bsd_compress && len >= CILEN_BSD_COMPRESS - && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { - no.bsd_compress = 1; - /* - * Peer wants us to use a different number of bits - * or a different version. - */ - if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION) - try.bsd_compress = 0; - else if (BSD_NBITS(p[2]) < go->bsd_bits) - try.bsd_bits = BSD_NBITS(p[2]); - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - } - - /* - * Predictor-1 and 2 have no options, so they can't be Naked. - * - * There may be remaining options but we ignore them. - */ - - if (f->state != OPENED) - *go = try; - return 1; -} - -/* - * ccp_rejci - reject some of our suggested compression methods. - */ -static int -ccp_rejci( - fsm *f, - u_char *p, - int len) -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - ccp_options try; /* options to request next time */ - - try = *go; - - /* - * Cope with empty configure-rejects by ceasing to send - * configure-requests. - */ - if (len == 0 && all_rejected[f->unit]) - return -1; - - if (go->deflate && len >= CILEN_DEFLATE - && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - && p[1] == CILEN_DEFLATE) { - if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; /* Rej is bad */ - if (go->deflate_correct) - try.deflate_correct = 0; - else - try.deflate_draft = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - if (go->deflate_correct && go->deflate_draft - && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT - && p[1] == CILEN_DEFLATE) { - if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; /* Rej is bad */ - try.deflate_draft = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - if (!try.deflate_correct && !try.deflate_draft) - try.deflate = 0; - } - if (go->bsd_compress && len >= CILEN_BSD_COMPRESS - && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { - if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) - return 0; - try.bsd_compress = 0; - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - } - if (go->predictor_1 && len >= CILEN_PREDICTOR_1 - && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) { - try.predictor_1 = 0; - p += CILEN_PREDICTOR_1; - len -= CILEN_PREDICTOR_1; - } - if (go->predictor_2 && len >= CILEN_PREDICTOR_2 - && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) { - try.predictor_2 = 0; - p += CILEN_PREDICTOR_2; - len -= CILEN_PREDICTOR_2; - } - - if (len != 0) - return 0; - - if (f->state != OPENED) - *go = try; - - return 1; -} - -/* - * ccp_reqci - processed a received configure-request. - * Returns CONFACK, CONFNAK or CONFREJ and the packet modified - * appropriately. - */ -static int -ccp_reqci( - fsm *f, - u_char *p, - int *lenp, - int dont_nak) -{ - int ret, newret, res; - u_char *p0, *retp; - int len, clen, type, nb; - ccp_options *ho = &ccp_hisoptions[f->unit]; - ccp_options *ao = &ccp_allowoptions[f->unit]; - - ret = CONFACK; - retp = p0 = p; - len = *lenp; - - memset(ho, 0, sizeof(ccp_options)); - ho->method = (len > 0)? p[0]: -1; - - while (len > 0) { - newret = CONFACK; - if (len < 2 || p[1] < 2 || p[1] > len) { - /* length is bad */ - clen = len; - newret = CONFREJ; - - } else { - type = p[0]; - clen = p[1]; - - switch (type) { - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (!ao->deflate || clen != CILEN_DEFLATE - || (!ao->deflate_correct && type == CI_DEFLATE) - || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) { - newret = CONFREJ; - break; - } - - ho->deflate = 1; - ho->deflate_size = nb = DEFLATE_SIZE(p[2]); - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL - || p[3] != DEFLATE_CHK_SEQUENCE - || nb > ao->deflate_size || nb < DEFLATE_MIN_SIZE) { - newret = CONFNAK; - if (!dont_nak) { - p[2] = DEFLATE_MAKE_OPT(ao->deflate_size); - p[3] = DEFLATE_CHK_SEQUENCE; - /* fall through to test this #bits below */ - } else - break; - } - - /* - * Check whether we can do Deflate with the window - * size they want. If the window is too big, reduce - * it until the kernel can cope and nak with that. - * We only check this for the first option. - */ - if (p == p0) { - for (;;) { - res = ccp_test(f->unit, p, CILEN_DEFLATE, 1); - if (res > 0) - break; /* it's OK now */ - if (res < 0 || nb == DEFLATE_MIN_SIZE || dont_nak) { - newret = CONFREJ; - p[2] = DEFLATE_MAKE_OPT(ho->deflate_size); - break; - } - newret = CONFNAK; - --nb; - p[2] = DEFLATE_MAKE_OPT(nb); - } - } - break; - - case CI_BSD_COMPRESS: - if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) { - newret = CONFREJ; - break; - } - - ho->bsd_compress = 1; - ho->bsd_bits = nb = BSD_NBITS(p[2]); - if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION - || nb > ao->bsd_bits || nb < BSD_MIN_BITS) { - newret = CONFNAK; - if (!dont_nak) { - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits); - /* fall through to test this #bits below */ - } else - break; - } - - /* - * Check whether we can do BSD-Compress with the code - * size they want. If the code size is too big, reduce - * it until the kernel can cope and nak with that. - * We only check this for the first option. - */ - if (p == p0) { - for (;;) { - res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1); - if (res > 0) - break; - if (res < 0 || nb == BSD_MIN_BITS || dont_nak) { - newret = CONFREJ; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, - ho->bsd_bits); - break; - } - newret = CONFNAK; - --nb; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); - } - } - break; - - case CI_PREDICTOR_1: - if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) { - newret = CONFREJ; - break; - } - - ho->predictor_1 = 1; - if (p == p0 - && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) { - newret = CONFREJ; - } - break; - - case CI_PREDICTOR_2: - if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) { - newret = CONFREJ; - break; - } - - ho->predictor_2 = 1; - if (p == p0 - && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) { - newret = CONFREJ; - } - break; - - default: - newret = CONFREJ; - } - } - - if (newret == CONFNAK && dont_nak) - newret = CONFREJ; - if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) { - /* we're returning this option */ - if (newret == CONFREJ && ret == CONFNAK) - retp = p0; - ret = newret; - if (p != retp) - BCOPY(p, retp, clen); - retp += clen; - } - - p += clen; - len -= clen; - } - - if (ret != CONFACK) { - if (ret == CONFREJ && *lenp == retp - p0) - all_rejected[f->unit] = 1; - else - *lenp = retp - p0; - } - return ret; -} - -/* - * Make a string name for a compression method (or 2). - */ -static char * -method_name( - ccp_options *opt, - ccp_options *opt2) -{ - static char result[64]; - - if (!ANY_COMPRESS(*opt)) - return "(none)"; - switch (opt->method) { - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) - slprintf(result, sizeof(result), "Deflate%s (%d/%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size, opt2->deflate_size); - else - slprintf(result, sizeof(result), "Deflate%s (%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size); - break; - case CI_BSD_COMPRESS: - if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) - slprintf(result, sizeof(result), "BSD-Compress (%d/%d)", - opt->bsd_bits, opt2->bsd_bits); - else - slprintf(result, sizeof(result), "BSD-Compress (%d)", - opt->bsd_bits); - break; - case CI_PREDICTOR_1: - return "Predictor 1"; - case CI_PREDICTOR_2: - return "Predictor 2"; - default: - slprintf(result, sizeof(result), "Method %d", opt->method); - } - return result; -} - -/* - * CCP has come up - inform the kernel driver and log a message. - */ -static void -ccp_up( - fsm *f) -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - ccp_options *ho = &ccp_hisoptions[f->unit]; - char method1[64]; - - ccp_flags_set(f->unit, 1, 1); - if (ANY_COMPRESS(*go)) { - if (ANY_COMPRESS(*ho)) { - if (go->method == ho->method) { - notice("%s compression enabled", method_name(go, ho)); - } else { - strlcpy(method1, method_name(go, NULL), sizeof(method1)); - notice("%s / %s compression enabled", - method1, method_name(ho, NULL)); - } - } else - notice("%s receive compression enabled", method_name(go, NULL)); - } else if (ANY_COMPRESS(*ho)) - notice("%s transmit compression enabled", method_name(ho, NULL)); -} - -/* - * CCP has gone down - inform the kernel driver. - */ -static void -ccp_down( - fsm *f) -{ - if (ccp_localstate[f->unit] & RACK_PENDING) - UNTIMEOUT(ccp_rack_timeout, f); - ccp_localstate[f->unit] = 0; - ccp_flags_set(f->unit, 1, 0); -} - -/* - * Print the contents of a CCP packet. - */ -static char *ccp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", - NULL, NULL, NULL, NULL, NULL, NULL, - "ResetReq", "ResetAck", -}; - -static int -ccp_printpkt( - u_char *p, - int plen, - void (*printer)(void *, char *, ...), - void *arg) -{ - u_char *p0, *optend; - int code, id, len; - int optlen; - - p0 = p; - if (plen < HEADERLEN) - return 0; - code = p[0]; - id = p[1]; - len = (p[2] << 8) + p[3]; - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *) - && ccp_codenames[code-1] != NULL) - printer(arg, " %s", ccp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - p += HEADERLEN; - - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print list of possible compression methods */ - while (len >= 2) { - code = p[0]; - optlen = p[1]; - if (optlen < 2 || optlen > len) - break; - printer(arg, " <"); - len -= optlen; - optend = p + optlen; - switch (code) { - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (optlen >= CILEN_DEFLATE) { - printer(arg, "deflate%s %d", - (code == CI_DEFLATE_DRAFT? "(old#)": ""), - DEFLATE_SIZE(p[2])); - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL) - printer(arg, " method %d", DEFLATE_METHOD(p[2])); - if (p[3] != DEFLATE_CHK_SEQUENCE) - printer(arg, " check %d", p[3]); - p += CILEN_DEFLATE; - } - break; - case CI_BSD_COMPRESS: - if (optlen >= CILEN_BSD_COMPRESS) { - printer(arg, "bsd v%d %d", BSD_VERSION(p[2]), - BSD_NBITS(p[2])); - p += CILEN_BSD_COMPRESS; - } - break; - case CI_PREDICTOR_1: - if (optlen >= CILEN_PREDICTOR_1) { - printer(arg, "predictor 1"); - p += CILEN_PREDICTOR_1; - } - break; - case CI_PREDICTOR_2: - if (optlen >= CILEN_PREDICTOR_2) { - printer(arg, "predictor 2"); - p += CILEN_PREDICTOR_2; - } - break; - } - while (p < optend) - printer(arg, " %.2x", *p++); - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - } - - /* dump out the rest of the packet in hex */ - while (--len >= 0) - printer(arg, " %.2x", *p++); - - return p - p0; -} - -/* - * We have received a packet that the decompressor failed to - * decompress. Here we would expect to issue a reset-request, but - * Motorola has a patent on resetting the compressor as a result of - * detecting an error in the decompressed data after decompression. - * (See US patent 5,130,993; international patent publication number - * WO 91/10289; Australian patent 73296/91.) - * - * So we ask the kernel whether the error was detected after - * decompression; if it was, we take CCP down, thus disabling - * compression :-(, otherwise we issue the reset-request. - */ -static void -ccp_datainput( - int unit, - u_char *pkt, - int len) -{ - fsm *f; - - f = &ccp_fsm[unit]; - if (f->state == OPENED) { - if (ccp_fatal_error(unit)) { - /* - * Disable compression by taking CCP down. - */ - error("Lost compression sync: disabling compression"); - ccp_close(unit, "Lost compression sync"); - } else { - /* - * Send a reset-request to reset the peer's compressor. - * We don't do that if we are still waiting for an - * acknowledgement to a previous reset-request. - */ - if (!(ccp_localstate[f->unit] & RACK_PENDING)) { - fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - ccp_localstate[f->unit] |= RACK_PENDING; - } else - ccp_localstate[f->unit] |= RREQ_REPEAT; - } - } -} - -/* - * Timeout waiting for reset-ack. - */ -static void -ccp_rack_timeout( - void *arg) -{ - fsm *f = arg; - - if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) { - fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - ccp_localstate[f->unit] &= ~RREQ_REPEAT; - } else - ccp_localstate[f->unit] &= ~RACK_PENDING; -} diff --git a/cpukit/pppd/ccp.h b/cpukit/pppd/ccp.h deleted file mode 100644 index 609d858c5e..0000000000 --- a/cpukit/pppd/ccp.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ccp.h - Definitions for PPP Compression Control Protocol. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -typedef struct ccp_options { - bool bsd_compress; /* do BSD Compress? */ - bool deflate; /* do Deflate? */ - bool predictor_1; /* do Predictor-1? */ - bool predictor_2; /* do Predictor-2? */ - bool deflate_correct; /* use correct code for deflate? */ - bool deflate_draft; /* use draft RFC code for deflate? */ - u_short bsd_bits; /* # bits/code for BSD Compress */ - u_short deflate_size; /* lg(window size) for Deflate */ - short method; /* code for chosen compression method */ -} ccp_options; - -extern fsm ccp_fsm[]; -extern ccp_options ccp_wantoptions[]; -extern ccp_options ccp_gotoptions[]; -extern ccp_options ccp_allowoptions[]; -extern ccp_options ccp_hisoptions[]; - -extern struct protent ccp_protent; diff --git a/cpukit/pppd/chap.c b/cpukit/pppd/chap.c deleted file mode 100644 index 55f1896966..0000000000 --- a/cpukit/pppd/chap.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * chap.c - Challenge Handshake Authentication Protocol. - * - * Copyright (c) 1993 The Australian National 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 the Australian National 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. - * - * Copyright (c) 1991 Gregory M. Christy. - * 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 Gregory M. Christy. The name of the author 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. - */ - -/* - * TODO: - */ - -#include -#include -#include /* drand48, srand48 */ -#include -#include - -#include "pppd.h" -#include "chap.h" -#include "md5.h" -#ifdef CHAPMS -#include "chap_ms.h" -#endif - -/* - * Command-line options. - */ -static option_t chap_option_list[] = { - { "chap-restart", o_int, &chap[0].timeouttime, - "Set timeout for CHAP", 0, NULL, 0, 0 }, - { "chap-max-challenge", o_int, &chap[0].max_transmits, - "Set max #xmits for challenge", 0, NULL, 0, 0 }, - { "chap-interval", o_int, &chap[0].chal_interval, - "Set interval for rechallenge", 0, NULL, 0, 0 }, -#ifdef MSLANMAN - { "ms-lanman", o_bool, &ms_lanman, - "Use LanMan passwd when using MS-CHAP", 1, NULL, 0, 0 }, -#endif - { NULL, 0, NULL, NULL, 0, NULL, 0, 0 } -}; - -/* - * Protocol entry points. - */ -static void ChapInit(int); -static void ChapLowerUp(int); -static void ChapLowerDown(int); -static void ChapInput(int, u_char *, int); -static void ChapProtocolReject(int); -static int ChapPrintPkt(u_char *, int, - void (*)(void *, char *, ...), void *); - -struct protent chap_protent = { - PPP_CHAP, - ChapInit, - ChapInput, - ChapProtocolReject, - ChapLowerUp, - ChapLowerDown, - NULL, - NULL, - ChapPrintPkt, - NULL, - 1, - "CHAP", - NULL, - chap_option_list, - NULL, - NULL, - NULL -}; - -chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */ - -static void ChapChallengeTimeout(void *); -static void ChapResponseTimeout(void *); -static void ChapReceiveChallenge(chap_state *, u_char *, int, int); -static void ChapRechallenge(void *); -static void ChapReceiveResponse(chap_state *, u_char *, int, int); -static void ChapReceiveSuccess(chap_state *, u_char *, u_char, int); -static void ChapReceiveFailure(chap_state *, u_char *, u_char, int); -static void ChapSendStatus(chap_state *, int); -static void ChapSendChallenge(chap_state *); -static void ChapSendResponse(chap_state *); -static void ChapGenChallenge(chap_state *); - -/* - * ChapInit - Initialize a CHAP unit. - */ -static void -ChapInit( - int unit) -{ - chap_state *cstate = &chap[unit]; - - BZERO(cstate, sizeof(*cstate)); - cstate->unit = unit; - cstate->clientstate = CHAPCS_INITIAL; - cstate->serverstate = CHAPSS_INITIAL; - cstate->timeouttime = CHAP_DEFTIMEOUT; - cstate->max_transmits = CHAP_DEFTRANSMITS; - /* random number generator is initialized in magic_init */ -} - - -/* - * ChapAuthWithPeer - Authenticate us with our peer (start client). - * - */ -void -ChapAuthWithPeer( - int unit, - char *our_name, - int digest) -{ - chap_state *cstate = &chap[unit]; - - cstate->resp_name = our_name; - cstate->resp_type = digest; - - if (cstate->clientstate == CHAPCS_INITIAL || - cstate->clientstate == CHAPCS_PENDING) { - /* lower layer isn't up - wait until later */ - cstate->clientstate = CHAPCS_PENDING; - return; - } - - /* - * We get here as a result of LCP coming up. - * So even if CHAP was open before, we will - * have to re-authenticate ourselves. - */ - cstate->clientstate = CHAPCS_LISTEN; -} - - -/* - * ChapAuthPeer - Authenticate our peer (start server). - */ -void -ChapAuthPeer( - int unit, - char *our_name, - int digest) -{ - chap_state *cstate = &chap[unit]; - - cstate->chal_name = our_name; - cstate->chal_type = digest; - - if (cstate->serverstate == CHAPSS_INITIAL || - cstate->serverstate == CHAPSS_PENDING) { - /* lower layer isn't up - wait until later */ - cstate->serverstate = CHAPSS_PENDING; - return; - } - - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); /* crank it up dude! */ - cstate->serverstate = CHAPSS_INITIAL_CHAL; -} - - -/* - * ChapChallengeTimeout - Timeout expired on sending challenge. - */ -static void -ChapChallengeTimeout( - void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending challenges, don't worry. then again we */ - /* probably shouldn't be here either */ - if (cstate->serverstate != CHAPSS_INITIAL_CHAL && - cstate->serverstate != CHAPSS_RECHALLENGE) - return; - - if (cstate->chal_transmits >= cstate->max_transmits) { - /* give up on peer */ - error("Peer failed to respond to CHAP challenge"); - cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, PPP_CHAP); - return; - } - - ChapSendChallenge(cstate); /* Re-send challenge */ -} - - -/* - * ChapResponseTimeout - Timeout expired on sending response. - */ -static void -ChapResponseTimeout( - void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending a response, don't worry. */ - if (cstate->clientstate != CHAPCS_RESPONSE) - return; - - ChapSendResponse(cstate); /* re-send response */ -} - - -/* - * ChapRechallenge - Time to challenge the peer again. - */ -static void -ChapRechallenge( - void *arg) -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending a response, don't worry. */ - if (cstate->serverstate != CHAPSS_OPEN) - return; - - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); - cstate->serverstate = CHAPSS_RECHALLENGE; -} - - -/* - * ChapLowerUp - The lower layer is up. - * - * Start up if we have pending requests. - */ -static void -ChapLowerUp( - int unit) -{ - chap_state *cstate = &chap[unit]; - - if (cstate->clientstate == CHAPCS_INITIAL) - cstate->clientstate = CHAPCS_CLOSED; - else if (cstate->clientstate == CHAPCS_PENDING) - cstate->clientstate = CHAPCS_LISTEN; - - if (cstate->serverstate == CHAPSS_INITIAL) - cstate->serverstate = CHAPSS_CLOSED; - else if (cstate->serverstate == CHAPSS_PENDING) { - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); - cstate->serverstate = CHAPSS_INITIAL_CHAL; - } -} - - -/* - * ChapLowerDown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void -ChapLowerDown( - int unit) -{ - chap_state *cstate = &chap[unit]; - - /* Timeout(s) pending? Cancel if so. */ - if (cstate->serverstate == CHAPSS_INITIAL_CHAL || - cstate->serverstate == CHAPSS_RECHALLENGE) - UNTIMEOUT(ChapChallengeTimeout, cstate); - else if (cstate->serverstate == CHAPSS_OPEN - && cstate->chal_interval != 0) - UNTIMEOUT(ChapRechallenge, cstate); - if (cstate->clientstate == CHAPCS_RESPONSE) - UNTIMEOUT(ChapResponseTimeout, cstate); - - cstate->clientstate = CHAPCS_INITIAL; - cstate->serverstate = CHAPSS_INITIAL; -} - - -/* - * ChapProtocolReject - Peer doesn't grok CHAP. - */ -static void -ChapProtocolReject( - int unit) -{ - chap_state *cstate = &chap[unit]; - - if (cstate->serverstate != CHAPSS_INITIAL && - cstate->serverstate != CHAPSS_CLOSED) - auth_peer_fail(unit, PPP_CHAP); - if (cstate->clientstate != CHAPCS_INITIAL && - cstate->clientstate != CHAPCS_CLOSED) - auth_withpeer_fail(unit, PPP_CHAP); - ChapLowerDown(unit); /* shutdown chap */ -} - - -/* - * ChapInput - Input CHAP packet. - */ -static void -ChapInput( - int unit, - u_char *inpacket, - int packet_len) -{ - chap_state *cstate = &chap[unit]; - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (packet_len < CHAP_HEADERLEN) { - CHAPDEBUG(("ChapInput: rcvd short header.")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < CHAP_HEADERLEN) { - CHAPDEBUG(("ChapInput: rcvd illegal length.")); - return; - } - if (len > packet_len) { - CHAPDEBUG(("ChapInput: rcvd short packet.")); - return; - } - len -= CHAP_HEADERLEN; - - /* - * Action depends on code (as in fact it usually does :-). - */ - switch (code) { - case CHAP_CHALLENGE: - ChapReceiveChallenge(cstate, inp, id, len); - break; - - case CHAP_RESPONSE: - ChapReceiveResponse(cstate, inp, id, len); - break; - - case CHAP_FAILURE: - ChapReceiveFailure(cstate, inp, id, len); - break; - - case CHAP_SUCCESS: - ChapReceiveSuccess(cstate, inp, id, len); - break; - - default: /* Need code reject? */ - warn("Unknown CHAP code (%d) received.", code); - break; - } -} - - -/* - * ChapReceiveChallenge - Receive Challenge and send Response. - */ -static void -ChapReceiveChallenge( - chap_state *cstate, - u_char *inp, - int id, - int len) -{ - int rchallenge_len; - u_char *rchallenge; - int secret_len; - unsigned char secret[MAXSECRETLEN]; - char rhostname[256]; - MD5_CTX mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; - - if (cstate->clientstate == CHAPCS_CLOSED || - cstate->clientstate == CHAPCS_PENDING) { - CHAPDEBUG(("ChapReceiveChallenge: in state %d", cstate->clientstate)); - return; - } - - if (len < 2) { - CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet.")); - return; - } - - GETCHAR(rchallenge_len, inp); - len -= sizeof (u_char) + rchallenge_len; /* now name field length */ - if (len < 0) { - CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet.")); - return; - } - rchallenge = inp; - INCPTR(rchallenge_len, inp); - - if (len >= sizeof(rhostname)) - len = sizeof(rhostname) - 1; - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - /* Microsoft doesn't send their name back in the PPP packet */ - if (explicit_remote || (remote_name[0] != 0 && rhostname[0] == 0)) { - strlcpy(rhostname, remote_name, sizeof(rhostname)); - CHAPDEBUG(("ChapReceiveChallenge: using '%q' as remote name", - rhostname)); - } - - /* get secret for authenticating ourselves with the specified host */ - if (!get_secret(cstate->unit, cstate->resp_name, rhostname, - secret, &secret_len, 0)) { - secret_len = 0; /* assume null secret if can't find one */ - warn("No CHAP secret found for authenticating us to %q", rhostname); - } - - /* cancel response send timeout if necessary */ - if (cstate->clientstate == CHAPCS_RESPONSE) - UNTIMEOUT(ChapResponseTimeout, cstate); - - cstate->resp_id = id; - cstate->resp_transmits = 0; - - /* generate MD based on negotiated type */ - switch (cstate->resp_type) { - - case CHAP_DIGEST_MD5: - MD5Init(&mdContext); - MD5Update(&mdContext, &cstate->resp_id, 1); - MD5Update(&mdContext, secret, secret_len); - MD5Update(&mdContext, rchallenge, rchallenge_len); - MD5Final(hash, &mdContext); - BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE); - cstate->resp_length = MD5_SIGNATURE_SIZE; - break; - -#ifdef CHAPMS - case CHAP_MICROSOFT: - ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); - break; -#endif - - default: - CHAPDEBUG(("unknown digest type %d", cstate->resp_type)); - return; - } - - BZERO(secret, sizeof(secret)); - ChapSendResponse(cstate); -} - - -/* - * ChapReceiveResponse - Receive and process response. - */ -static void -ChapReceiveResponse( - chap_state *cstate, - u_char *inp, - int id, - int len) -{ - u_char *remmd, remmd_len; - int secret_len, old_state; - int code; - char rhostname[256]; - MD5_CTX mdContext; - unsigned char secret[MAXSECRETLEN]; - u_char hash[MD5_SIGNATURE_SIZE]; - - if (cstate->serverstate == CHAPSS_CLOSED || - cstate->serverstate == CHAPSS_PENDING) { - CHAPDEBUG(("ChapReceiveResponse: in state %d", cstate->serverstate)); - return; - } - - if (id != cstate->chal_id) - return; /* doesn't match ID of last challenge */ - - /* - * If we have received a duplicate or bogus Response, - * we have to send the same answer (Success/Failure) - * as we did for the first Response we saw. - */ - if (cstate->serverstate == CHAPSS_OPEN) { - ChapSendStatus(cstate, CHAP_SUCCESS); - return; - } - if (cstate->serverstate == CHAPSS_BADAUTH) { - ChapSendStatus(cstate, CHAP_FAILURE); - return; - } - - if (len < 2) { - CHAPDEBUG(("ChapReceiveResponse: rcvd short packet.")); - return; - } - GETCHAR(remmd_len, inp); /* get length of MD */ - remmd = inp; /* get pointer to MD */ - INCPTR(remmd_len, inp); - - len -= sizeof (u_char) + remmd_len; - if (len < 0) { - CHAPDEBUG(("ChapReceiveResponse: rcvd short packet.")); - return; - } - - UNTIMEOUT(ChapChallengeTimeout, cstate); - - if (len >= sizeof(rhostname)) - len = sizeof(rhostname) - 1; - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - /* - * Get secret for authenticating them with us, - * do the hash ourselves, and compare the result. - */ - code = CHAP_FAILURE; - if (!get_secret(cstate->unit, (explicit_remote? remote_name: rhostname), - cstate->chal_name, secret, &secret_len, 1)) { - warn("No CHAP secret found for authenticating %q", rhostname); - } else { - - /* generate MD based on negotiated type */ - switch (cstate->chal_type) { - - case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ - if (remmd_len != MD5_SIGNATURE_SIZE) - break; /* it's not even the right length */ - MD5Init(&mdContext); - MD5Update(&mdContext, &cstate->chal_id, 1); - MD5Update(&mdContext, secret, secret_len); - MD5Update(&mdContext, cstate->challenge, cstate->chal_len); - MD5Final(hash, &mdContext); - - /* compare local and remote MDs and send the appropriate status */ - if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) - code = CHAP_SUCCESS; /* they are the same! */ - break; - - default: - CHAPDEBUG(("unknown digest type %d", cstate->chal_type)); - } - } - - BZERO(secret, sizeof(secret)); - ChapSendStatus(cstate, code); - - if (code == CHAP_SUCCESS) { - old_state = cstate->serverstate; - cstate->serverstate = CHAPSS_OPEN; - if (old_state == CHAPSS_INITIAL_CHAL) { - auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len); - } - if (cstate->chal_interval != 0) - TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval); - notice("CHAP peer authentication succeeded for %q", rhostname); - - } else { - error("CHAP peer authentication failed for remote host %q", rhostname); - cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, PPP_CHAP); - } -} - -/* - * ChapReceiveSuccess - Receive Success - */ -static void -ChapReceiveSuccess( - chap_state *cstate, - u_char *inp, - u_char id, - int len) -{ - - if (cstate->clientstate == CHAPCS_OPEN) - /* presumably an answer to a duplicate response */ - return; - - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG(("ChapReceiveSuccess: in state %d\n", cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) - PRINTMSG(inp, len); - - cstate->clientstate = CHAPCS_OPEN; - - auth_withpeer_success(cstate->unit, PPP_CHAP); -} - - -/* - * ChapReceiveFailure - Receive failure. - */ -static void -ChapReceiveFailure( - chap_state *cstate, - u_char *inp, - u_char id, - int len) -{ - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG(("ChapReceiveFailure: in state %d\n", cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) - PRINTMSG(inp, len); - - error("CHAP authentication failed"); - auth_withpeer_fail(cstate->unit, PPP_CHAP); -} - - -/* - * ChapSendChallenge - Send an Authenticate challenge. - */ -static void -ChapSendChallenge( - chap_state *cstate) -{ - u_char *outp; - int chal_len, name_len; - int outlen; - - chal_len = cstate->chal_len; - name_len = strlen(cstate->chal_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */ - - PUTCHAR(CHAP_CHALLENGE, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - - PUTCHAR(chal_len, outp); /* put length of challenge */ - BCOPY(cstate->challenge, outp, chal_len); - INCPTR(chal_len, outp); - - BCOPY(cstate->chal_name, outp, name_len); /* append hostname */ - - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); - - TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime); - ++cstate->chal_transmits; -} - - -/* - * ChapSendStatus - Send a status response (ack or nak). - */ -static void -ChapSendStatus( - chap_state *cstate, - int code) -{ - u_char *outp; - int outlen, msglen; - char msg[256]; - - if (code == CHAP_SUCCESS) - slprintf(msg, sizeof(msg), "Welcome to %s.", hostname); - else - slprintf(msg, sizeof(msg), "I don't like you. Go 'way."); - msglen = strlen(msg); - - outlen = CHAP_HEADERLEN + msglen; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ - - PUTCHAR(code, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - BCOPY(msg, outp, msglen); - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); -} - -/* - * ChapGenChallenge is used to generate a pseudo-random challenge string of - * a pseudo-random length between min_len and max_len. The challenge - * string and its length are stored in *cstate, and various other fields of - * *cstate are initialized. - */ - -static void -ChapGenChallenge( - chap_state *cstate) -{ - int chal_len; - u_char *ptr = cstate->challenge; - int i; - - /* pick a random challenge length between MIN_CHALLENGE_LENGTH and - MAX_CHALLENGE_LENGTH */ - chal_len = (unsigned) ((drand48() * - (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) + - MIN_CHALLENGE_LENGTH); - cstate->chal_len = chal_len; - cstate->chal_id = ++cstate->id; - cstate->chal_transmits = 0; - - /* generate a random string */ - for (i = 0; i < chal_len; i++) - *ptr++ = (char) (drand48() * 0xff); -} - -/* - * ChapSendResponse - send a response packet with values as specified - * in *cstate. - */ -/* ARGSUSED */ -static void -ChapSendResponse( - chap_state *cstate) -{ - u_char *outp; - int outlen, md_len, name_len; - - md_len = cstate->resp_length; - name_len = strlen(cstate->resp_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); - - PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */ - PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */ - PUTSHORT(outlen, outp); /* packet length */ - - PUTCHAR(md_len, outp); /* length of MD */ - BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */ - INCPTR(md_len, outp); - - BCOPY(cstate->resp_name, outp, name_len); /* append our name */ - - /* send the packet */ - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); - - cstate->clientstate = CHAPCS_RESPONSE; - TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime); - ++cstate->resp_transmits; -} - -/* - * ChapPrintPkt - print the contents of a CHAP packet. - */ -static char *ChapCodenames[] = { - "Challenge", "Response", "Success", "Failure" -}; - -static int -ChapPrintPkt( - u_char *p, - int plen, - void (*printer)(void *, char *, ...), - void *arg) -{ - int code, id, len; - int clen, nlen; - u_char x; - - if (plen < CHAP_HEADERLEN) - return 0; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < CHAP_HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) - printer(arg, " %s", ChapCodenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= CHAP_HEADERLEN; - switch (code) { - case CHAP_CHALLENGE: - case CHAP_RESPONSE: - if (len < 1) - break; - clen = p[0]; - if (len < clen + 1) - break; - ++p; - nlen = len - clen - 1; - printer(arg, " <"); - for (; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, "%.2x", x); - } - printer(arg, ">, name = "); - print_string((char *)p, nlen, printer, arg); - break; - case CHAP_FAILURE: - case CHAP_SUCCESS: - printer(arg, " "); - print_string((char *)p, len, printer, arg); - break; - default: - for (clen = len; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, " %.2x", x); - } - } - - return len + CHAP_HEADERLEN; -} diff --git a/cpukit/pppd/chap.h b/cpukit/pppd/chap.h deleted file mode 100644 index 78833554fe..0000000000 --- a/cpukit/pppd/chap.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * chap.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1993 The Australian National 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 the Australian National 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. - * - * Copyright (c) 1991 Gregory M. Christy - * 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 the author. - * - * 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. - * - * $Id$ - */ - -#ifndef __CHAP_INCLUDE__ - -/* Code + ID + length */ -#define CHAP_HEADERLEN 4 - -/* - * CHAP codes. - */ - -#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */ -#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */ -#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */ -#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ - -#define CHAP_CHALLENGE 1 -#define CHAP_RESPONSE 2 -#define CHAP_SUCCESS 3 -#define CHAP_FAILURE 4 - -/* - * Challenge lengths (for challenges we send) and other limits. - */ -#define MIN_CHALLENGE_LENGTH 16 -#define MAX_CHALLENGE_LENGTH 24 -#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */ - -/* - * Each interface is described by a chap structure. - */ - -typedef struct chap_state { - int unit; /* Interface unit number */ - int clientstate; /* Client state */ - int serverstate; /* Server state */ - u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */ - u_char chal_len; /* challenge length */ - u_char chal_id; /* ID of last challenge */ - u_char chal_type; /* hash algorithm for challenges */ - u_char id; /* Current id */ - char *chal_name; /* Our name to use with challenge */ - int chal_interval; /* Time until we challenge peer again */ - int timeouttime; /* Timeout time in seconds */ - int max_transmits; /* Maximum # of challenge transmissions */ - int chal_transmits; /* Number of transmissions of challenge */ - int resp_transmits; /* Number of transmissions of response */ - u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */ - u_char resp_length; /* length of response */ - u_char resp_id; /* ID for response messages */ - u_char resp_type; /* hash algorithm for responses */ - char *resp_name; /* Our name to send with response */ -} chap_state; - - -/* - * Client (peer) states. - */ -#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */ -#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */ -#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */ -#define CHAPCS_LISTEN 3 /* Listening for a challenge */ -#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */ -#define CHAPCS_OPEN 5 /* We've received Success */ - -/* - * Server (authenticator) states. - */ -#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */ -#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */ -#define CHAPSS_PENDING 2 /* Auth peer when lower up */ -#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */ -#define CHAPSS_OPEN 4 /* We've sent a Success msg */ -#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */ -#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */ - -/* - * Timeouts. - */ -#define CHAP_DEFTIMEOUT 5 /* Timeout time in seconds */ -#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ - -extern chap_state chap[]; - -void ChapAuthWithPeer(int, char *, int); -void ChapAuthPeer(int, char *, int); - -extern struct protent chap_protent; - -#define __CHAP_INCLUDE__ -#endif /* __CHAP_INCLUDE__ */ diff --git a/cpukit/pppd/chap_ms.c b/cpukit/pppd/chap_ms.c deleted file mode 100644 index 3ccf83ad8d..0000000000 --- a/cpukit/pppd/chap_ms.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * chap_ms.c - Microsoft MS-CHAP compatible implementation. - * - * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. - * http://www.strataware.com/ - * - * 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 Eric Rosenquist. The name of the author 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. - */ - -/* - * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 - * - * Implemented LANManager type password response to MS-CHAP challenges. - * Now pppd provides both NT style and LANMan style blocks, and the - * prefered is set by option "ms-lanman". Default is to use NT. - * The hash text (StdText) was taken from Win95 RASAPI32.DLL. - * - * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 - */ - -#define RCSID "$Id$" - -#ifdef CHAPMS - -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_CRYPT_H -#include -#endif - -#include "pppd.h" -#include "chap.h" -#include "chap_ms.h" -#include "md4.h" - -#ifndef USE_CRYPT -#include -#endif - -static const char rcsid[] = RCSID; - -typedef struct { - u_char LANManResp[24]; - u_char NTResp[24]; - u_char UseNT; /* If 1, ignore the LANMan response field */ -} MS_ChapResponse; -/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse), - in case this struct gets padded. */ - - -static void ChallengeResponse(u_char *, u_char *, u_char *); -static void DesEncrypt(u_char *, u_char *, u_char *); -static void MakeKey(u_char *, u_char *); -static u_char Get7Bits(u_char *, int); -static void ChapMS_NT(char *, int, char *, int, MS_ChapResponse *); -#ifdef MSLANMAN -static void ChapMS_LANMan(char *, int, char *, int, MS_ChapResponse *); -#endif - -#ifdef USE_CRYPT -static void Expand(u_char *, u_char *); -static void Collapse(u_char *, u_char *); -#endif - -#ifdef MSLANMAN -bool ms_lanman = 0; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -static void -ChallengeResponse(challenge, pwHash, response) - u_char *challenge; /* IN 8 octets */ - u_char *pwHash; /* IN 16 octets */ - u_char *response; /* OUT 24 octets */ -{ - char ZPasswordHash[21]; - - BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - BCOPY(pwHash, ZPasswordHash, MD4_SIGNATURE_SIZE); - -#if 0 - dbglog("ChallengeResponse - ZPasswordHash %.*B", - sizeof(ZPasswordHash), ZPasswordHash); -#endif - - DesEncrypt(challenge, ZPasswordHash + 0, response + 0); - DesEncrypt(challenge, ZPasswordHash + 7, response + 8); - DesEncrypt(challenge, ZPasswordHash + 14, response + 16); - -#if 0 - dbglog("ChallengeResponse - response %.24B", response); -#endif -} - - -#ifdef USE_CRYPT -static void -DesEncrypt(clear, key, cipher) - u_char *clear; /* IN 8 octets */ - u_char *key; /* IN 7 octets */ - u_char *cipher; /* OUT 8 octets */ -{ - u_char des_key[8]; - u_char crypt_key[66]; - u_char des_input[66]; - - MakeKey(key, des_key); - - Expand(des_key, crypt_key); - setkey(crypt_key); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear)); -#endif - - Expand(clear, des_input); - encrypt(des_input, 0); - Collapse(des_input, cipher); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher)); -#endif -} - -#else /* USE_CRYPT */ - -static void -DesEncrypt(clear, key, cipher) - u_char *clear; /* IN 8 octets */ - u_char *key; /* IN 7 octets */ - u_char *cipher; /* OUT 8 octets */ -{ - des_cblock des_key; - des_key_schedule key_schedule; - - MakeKey(key, des_key); - - des_set_key(&des_key, key_schedule); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear)); -#endif - - des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher)); -#endif -} - -#endif /* USE_CRYPT */ - - -static u_char Get7Bits(input, startBit) - u_char *input; - int startBit; -{ - register unsigned int word; - - word = (unsigned)input[startBit / 8] << 8; - word |= (unsigned)input[startBit / 8 + 1]; - - word >>= 15 - (startBit % 8 + 7); - - return word & 0xFE; -} - -#ifdef USE_CRYPT - -/* in == 8-byte string (expanded version of the 56-bit key) - * out == 64-byte string where each byte is either 1 or 0 - * Note that the low-order "bit" is always ignored by by setkey() - */ -static void Expand(in, out) - u_char *in; - u_char *out; -{ - int j, c; - int i; - - for(i = 0; i < 64; in++){ - c = *in; - for(j = 7; j >= 0; j--) - *out++ = (c >> j) & 01; - i += 8; - } -} - -/* The inverse of Expand - */ -static void Collapse(in, out) - u_char *in; - u_char *out; -{ - int j; - int i; - unsigned int c; - - for (i = 0; i < 64; i += 8, out++) { - c = 0; - for (j = 7; j >= 0; j--, in++) - c |= *in << j; - *out = c & 0xff; - } -} -#endif - -static void MakeKey(key, des_key) - u_char *key; /* IN 56 bit DES key missing parity bits */ - u_char *des_key; /* OUT 64 bit DES key with parity bits added */ -{ - des_key[0] = Get7Bits(key, 0); - des_key[1] = Get7Bits(key, 7); - des_key[2] = Get7Bits(key, 14); - des_key[3] = Get7Bits(key, 21); - des_key[4] = Get7Bits(key, 28); - des_key[5] = Get7Bits(key, 35); - des_key[6] = Get7Bits(key, 42); - des_key[7] = Get7Bits(key, 49); - -#ifndef USE_CRYPT - des_set_odd_parity((des_cblock *)des_key); -#endif - -#if 0 - CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %.7B", key)); - CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %.8B", des_key)); -#endif -} - -static void -ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, response) - char *rchallenge; - int rchallenge_len; - char *secret; - int secret_len; - MS_ChapResponse *response; -{ - int i; -#ifdef __NetBSD__ - /* NetBSD uses the libc md4 routines which take bytes instead of bits */ - int mdlen = secret_len * 2; -#else - int mdlen = secret_len * 2 * 8; -#endif - MD4_CTX md4Context; - u_char hash[MD4_SIGNATURE_SIZE]; - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - - /* Initialize the Unicode version of the secret (== password). */ - /* This implicitly supports 8-bit ISO8859/1 characters. */ - BZERO(unicodePassword, sizeof(unicodePassword)); - for (i = 0; i < secret_len; i++) - unicodePassword[i * 2] = (u_char)secret[i]; - - MD4Init(&md4Context); - MD4Update(&md4Context, unicodePassword, mdlen); - - MD4Final(hash, &md4Context); /* Tell MD4 we're done */ - - ChallengeResponse(rchallenge, hash, response->NTResp); -} - -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void -ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, response) - char *rchallenge; - int rchallenge_len; - char *secret; - int secret_len; - MS_ChapResponse *response; -{ - int i; - u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - - /* LANMan password is case insensitive */ - BZERO(UcasePassword, sizeof(UcasePassword)); - for (i = 0; i < secret_len; i++) - UcasePassword[i] = (u_char)toupper(secret[i]); - DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 ); - DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 ); - ChallengeResponse(rchallenge, PasswordHash, response->LANManResp); -} -#endif - -void -ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len) - chap_state *cstate; - char *rchallenge; - int rchallenge_len; - char *secret; - int secret_len; -{ - MS_ChapResponse response; - -#if 0 - CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret)); -#endif - BZERO(&response, sizeof(response)); - - /* Calculate both always */ - ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response); - -#ifdef MSLANMAN - ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response); - - /* prefered method is set by option */ - response.UseNT = !ms_lanman; -#else - response.UseNT = 1; -#endif - - BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN); - cstate->resp_length = MS_CHAP_RESPONSE_LEN; -} - -#endif /* CHAPMS */ diff --git a/cpukit/pppd/chap_ms.h b/cpukit/pppd/chap_ms.h deleted file mode 100644 index 5776251210..0000000000 --- a/cpukit/pppd/chap_ms.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * chap.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. - * http://www.strataware.com/ - * - * 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 Eric Rosenquist. The name of the author 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. - * - * $Id$ - */ - -#ifndef __CHAPMS_INCLUDE__ - -#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ -#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */ - -void ChapMS(chap_state *, char *, int, char *, int); - -#define __CHAPMS_INCLUDE__ -#endif /* __CHAPMS_INCLUDE__ */ diff --git a/cpukit/pppd/chat.c b/cpukit/pppd/chat.c deleted file mode 100644 index 6eeec97864..0000000000 --- a/cpukit/pppd/chat.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Chat -- a program for automatic session establishment (i.e. dial - * the phone and log in). - * - * Standard termination codes: - * 0 - successful completion of the script - * 1 - invalid argument, expect string too large, etc. - * 2 - error on an I/O operation or fatal error condition. - * 3 - timeout waiting for a simple string. - * 4 - the first string declared as "ABORT" - * 5 - the second string declared as "ABORT" - * 6 - ... and so on for successive ABORT strings. - * - * This software is in the public domain. - * - * ----------------- - * 22-May-99 added environment substitutuion, enabled with -E switch. - * Andreas Arens . - * - * 12-May-99 added a feature to read data to be sent from a file, - * if the send string starts with @. Idea from gpk . - * - * added -T and -U option and \T and \U substitution to pass a phone - * number into chat script. Two are needed for some ISDN TA applications. - * Keith Dart - * - * - * Added SAY keyword to send output to stderr. - * This allows to turn ECHO OFF and to output specific, user selected, - * text to give progress messages. This best works when stderr - * exists (i.e.: pppd in nodetach mode). - * - * Added HANGUP directives to allow for us to be called - * back. When HANGUP is set to NO, chat will not hangup at HUP signal. - * We rely on timeouts in that case. - * - * Added CLR_ABORT to clear previously set ABORT string. This has been - * dictated by the HANGUP above as "NO CARRIER" (for example) must be - * an ABORT condition until we know the other host is going to close - * the connection for call back. As soon as we have completed the - * first stage of the call back sequence, "NO CARRIER" is a valid, non - * fatal string. As soon as we got called back (probably get "CONNECT"), - * we should re-arm the ABORT "NO CARRIER". Hence the CLR_ABORT command. - * Note that CLR_ABORT packs the abort_strings[] array so that we do not - * have unused entries not being reclaimed. - * - * In the same vein as above, added CLR_REPORT keyword. - * - * Allow for comments. Line starting with '#' are comments and are - * ignored. If a '#' is to be expected as the first character, the - * expect string must be quoted. - * - * - * Francis Demierre - * Thu May 15 17:15:40 MET DST 1997 - * - * - * Added -r "report file" switch & REPORT keyword. - * Robert Geer - * - * Added -s "use stderr" and -S "don't use syslog" switches. - * June 18, 1997 - * Karl O. Pinc - * - * - * Added -e "echo" switch & ECHO keyword - * Dick Streefland - * - * - * Considerable updates and modifications by - * Al Longyear - * Paul Mackerras - * - * - * The original author is: - * - * Karl Fox - * Morning Star Technologies, Inc. - * 1760 Zollinger Road - * Columbus, OH 43221 - * (614)451-1883 - * - */ - -/* $Id$ */ - -/* - Fixes and some Changes by Wilfried Busalski Lancier-Monitoring GmbH Germany - wilfried.busalski@muenster.de - - Fixes: put_string() Free memory allocated by clean() - get_string() Free memory allocated by clean() - chat_main() Will Distroy's no more the chat-script - getnextcommand() sepatator changed to '@' -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pppd.h" - -#undef TERMIOS -#define TERMIOS - - -#define STR_LEN 1024 -char temp2[STR_LEN]; - -#ifndef SIGTYPE -#define SIGTYPE void -#endif - -#undef __V - -#ifdef __STDC__ -#include -#define __V(x) x -#else -#include -#define __V(x) (va_alist) va_dcl -#define const -#endif - -#ifndef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - - -/*************** Micro getopt() *********************************************/ -#define OPTION(c,v) (_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \ - (--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\ - &&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0)) -#define OPTARG(c,v) (_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \ - (_O=4,(char*)0):(char*)0) -#define OPTONLYARG(c,v) (_O&2&&**v?(_O=1,--c,*v++):(char*)0) -#define ARG(c,v) (c?(--c,*v++):(char*)0) - -#if 0 -static int _O = 0; /* Internal state */ -#endif -/*************** Micro getopt() *********************************************/ - -#define MAX_ABORTS 16 -#define MAX_REPORTS 16 -#define DEFAULT_CHAT_TIMEOUT 45 -#define MAX_TIMEOUTS 10 - -static int echo = 0; -static int quiet = 0; -static int use_env = 0; -static int exit_code = 0; -static char *phone_num = (char *) 0; -static char *phone_num2 = (char *) 0; -static int ttyfd; -static int timeout = DEFAULT_CHAT_TIMEOUT; - -#ifdef TERMIOS -#define term_parms struct termios -#define get_term_param(param) tcgetattr(0, param) -#define set_term_param(param) tcsetattr(0, TCSANOW, param) -struct termios saved_tty_parameters; -#endif - -char *fail_reason = (char *)0; -char fail_buffer[50]; -char *abort_string[MAX_ABORTS]={"BUSY","NO DIALTONE","NO CARRIER","NO ANSWER","RING\r\nRING"}; -int n_aborts = 5; -int abort_next = 0, timeout_next = 0, echo_next = 0; -int clear_abort_next = 0; - -char *report_string[MAX_REPORTS] ; -char report_buffer[50] ; -int n_reports = 0, report_next = 0, report_gathering = 0 ; -int clear_report_next = 0; - -int say_next = 0, hup_next = 0; - -void *dup_mem(void *b, size_t c); -void *copy_of(char *s); -void break_sequence(void); -static int get_string(register char *string); -static int put_string(register char *s); -static int write_char(int c); -static int put_char(int c); -static int get_char(void); -void chat_send(register char *s); -/* static char *character(int c); */ -void chat_expect(register char *s); -static char *clean(register char *s, int sending); -char *expect_strtok(char *, char *); -int chatmain(int, int, char *); - - -void *dup_mem( - void *b, - size_t c) -{ - void *ans = malloc (c); - if (!ans) - return NULL; - - memcpy(ans, b, c); - return ans; -} - -void *copy_of( - char *s) -{ - return dup_mem(s, strlen (s) + 1); -} - -static char *getnextcommand(char *string,char *buff) -{ - char *token; - int len; - - token=strchr(string,'@'); - if (token==NULL){ - return NULL; - } - len=token-string; - if(len > 78 ){ - len=78; - } - memcpy(buff,string,len); - buff[len]=0; - return(token+1); -} - -int chatmain(int fd, int mode, char *pScript) -{ - char arg[80]; - char *script; - - /* initialize exit code */ - exit_code = 0; - ttyfd = fd; - - script=pScript; - - if ( debug ) { - dbglog("chat_main: %s\n", script); - } - - /* get first expect string */ - script = getnextcommand(script,arg); - while (( script != NULL ) && ( exit_code == 0 )) { - /* process the expect string */ - chat_expect(arg); - if ( exit_code == 0 ) { - /* get the next send string */ - script = getnextcommand(script,arg); - if ( script != NULL ) { - /* process the send string */ - chat_send(arg); - - /* get the next expect string */ - script = getnextcommand(script,arg); - } - } - } - ttyfd = (int)-1; - - return ( exit_code ); -} - -void break_sequence(void) -{ - tcsendbreak(ttyfd, 0); -} - -/* - * 'Clean up' this string. - */ -static char *clean( - char *s, - int sending ) /* set to 1 when sending (putting) this string. */ -{ - char temp[STR_LEN], env_str[STR_LEN], cur_chr; - register char *s1, *phchar; - int add_return = sending; -#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7')) -#define isalnumx(chr) ((((chr) >= '0') && ((chr) <= '9')) \ - || (((chr) >= 'a') && ((chr) <= 'z')) \ - || (((chr) >= 'A') && ((chr) <= 'Z')) \ - || (chr) == '_') - - s1 = temp; - while (*s) { - cur_chr = *s++; - if (cur_chr == '^') { - cur_chr = *s++; - if (cur_chr == '\0') { - *s1++ = '^'; - break; - } - cur_chr &= 0x1F; - if (cur_chr != 0) { - *s1++ = cur_chr; - } - continue; - } - - if (use_env && cur_chr == '$') { /* ARI */ - phchar = env_str; - while (isalnumx(*s)) - *phchar++ = *s++; - *phchar = '\0'; - phchar = getenv(env_str); - if (phchar) - while (*phchar) - *s1++ = *phchar++; - continue; - } - - if (cur_chr != '\\') { - *s1++ = cur_chr; - continue; - } - - cur_chr = *s++; - if (cur_chr == '\0') { - if (sending) { - *s1++ = '\\'; - *s1++ = '\\'; - } - break; - } - - switch (cur_chr) { - case 'b': - *s1++ = '\b'; - break; - - case 'c': - if (sending && *s == '\0') - add_return = 0; - else - *s1++ = cur_chr; - break; - - case '\\': - case 'K': - case 'p': - case 'd': - if (sending) - *s1++ = '\\'; - *s1++ = cur_chr; - break; - - case 'T': - if (sending && phone_num) { - for (phchar = phone_num; *phchar != '\0'; phchar++) - *s1++ = *phchar; - } - else { - *s1++ = '\\'; - *s1++ = 'T'; - } - break; - - case 'U': - if (sending && phone_num2) { - for (phchar = phone_num2; *phchar != '\0'; phchar++) - *s1++ = *phchar; - } - else { - *s1++ = '\\'; - *s1++ = 'U'; - } - break; - - case 'q': - quiet = 1; - break; - - case 'r': - *s1++ = '\r'; - break; - - case 'n': - *s1++ = '\n'; - break; - - case 's': - *s1++ = ' '; - break; - - case 't': - *s1++ = '\t'; - break; - - case 'N': - if (sending) { - *s1++ = '\\'; - *s1++ = '\0'; - } - else - *s1++ = 'N'; - break; - - case '$': /* ARI */ - if (use_env) { - *s1++ = cur_chr; - break; - } - /* FALL THROUGH */ - - default: - if (isoctal (cur_chr)) { - cur_chr &= 0x07; - if (isoctal (*s)) { - cur_chr <<= 3; - cur_chr |= *s++ - '0'; - if (isoctal (*s)) { - cur_chr <<= 3; - cur_chr |= *s++ - '0'; - } - } - - if (cur_chr != 0 || sending) { - if (sending && (cur_chr == '\\' || cur_chr == 0)) - *s1++ = '\\'; - *s1++ = cur_chr; - } - break; - } - - if (sending) - *s1++ = '\\'; - *s1++ = cur_chr; - break; - } - } - - if (add_return) - *s1++ = '\r'; - - *s1++ = '\0'; /* guarantee closure */ - *s1++ = '\0'; /* terminate the string */ - return dup_mem (temp, (size_t) (s1 - temp)); /* may have embedded nuls */ -} - -/* - * A modified version of 'strtok'. This version skips \ sequences. - */ -char *expect_strtok ( - char *s, char *term) -{ - static char *str = ""; - int escape_flag = 0; - char *result; - -/* - * If a string was specified then do initial processing. - */ - if (s) - str = s; - -/* - * If this is the escape flag then reset it and ignore the character. - */ - if (*str) - result = str; - else - result = (char *) 0; - - while (*str) { - if (escape_flag) { - escape_flag = 0; - ++str; - continue; - } - - if (*str == '\\') { - ++str; - escape_flag = 1; - continue; - } - -/* - * If this is not in the termination string, continue. - */ - if (strchr (term, *str) == (char *) 0) { - ++str; - continue; - } - -/* - * This is the terminator. Mark the end of the string and stop. - */ - *str++ = '\0'; - break; - } - return (result); -} - -/* - * Process the expect string - */ -void chat_expect ( - char *s) -{ - char *expect; - char *reply; - - if (strcmp(s, "HANGUP") == 0) { - ++hup_next; - return; - } - - if (strcmp(s, "ABORT") == 0) { - ++abort_next; - return; - } - - if (strcmp(s, "CLR_ABORT") == 0) { - ++clear_abort_next; - return; - } - - if (strcmp(s, "REPORT") == 0) { - ++report_next; - return; - } - - if (strcmp(s, "CLR_REPORT") == 0) { - ++clear_report_next; - return; - } - - if (strcmp(s, "TIMEOUT") == 0) { - ++timeout_next; - return; - } - - if (strcmp(s, "ECHO") == 0) { - ++echo_next; - return; - } - - if (strcmp(s, "SAY") == 0) { - ++say_next; - return; - } - -/* - * Fetch the expect and reply string. - */ - for (;;) { - expect = expect_strtok (s, "-"); - s = (char *) 0; - - if (expect == (char *) 0) - return; - - reply = expect_strtok (s, "-"); - -/* - * Handle the expect string. If successful then exit. - */ - if (get_string (expect)) - return; - -/* - * If there is a sub-reply string then send it. Otherwise any condition - * is terminal. - */ - if (reply == (char *) 0 || exit_code != 3) - break; - - chat_send (reply); - } -} - -#if 0 -/* - * Translate the input character to the appropriate string for printing - * the data. - */ - -static char *character( - int c) -{ - static char string[10]; - char *meta; - - meta = (c & 0x80) ? "M-" : ""; - c &= 0x7F; - - if (c < 32) - sprintf(string, "%s^%c", meta, (int)c + '@'); - else if (c == 127) - sprintf(string, "%s^?", meta); - else - sprintf(string, "%s%c", meta, c); - - return (string); -} -#endif - -/* - * process the reply string - */ -void chat_send ( - char *s) -{ -/* char file_data[STR_LEN]; */ - - if (say_next) { - say_next = 0; - s = clean(s, 1); - write(2, s, strlen(s)); - free(s); - return; - } - - if (hup_next) { - hup_next = 0; - return; - } - - if (echo_next) { - echo_next = 0; - echo = (strcmp(s, "ON") == 0); - return; - } - - if (abort_next) { - abort_next = 0; - if ( n_aborts < MAX_ABORTS ) { - char *s1; - s1 = clean(s, 0); - if (( strlen(s1) <= strlen(s) ) && ( strlen(s1) < sizeof(fail_buffer))) - abort_string[n_aborts++] = s1; - else - free(s1); - } - return; - } - - if (clear_abort_next) { - clear_abort_next = 0; - return; - } - - if (report_next) { - report_next = 0; - return; - } - - if (clear_report_next) { - clear_report_next = 0; - return; - } - - if (timeout_next) { - timeout_next = 0; - timeout = atoi(s); - - if (timeout <= 0){ - timeout = DEFAULT_CHAT_TIMEOUT; - } - return; - } - - if (strcmp(s, "EOT") == 0){ - s = "^D\\c"; - } - else{ - if (strcmp(s, "BREAK") == 0){ - s = "\\K\\c"; - } - - if (!put_string(s)) { - exit_code = 2; - } - } -} - -static int get_char(void) -{ - int status; - char c; - int tries=MAX_TIMEOUTS; - - while(tries) - { - status = read(ttyfd, &c, 1); - switch (status) { - case 1: - return ((int)c & 0x7F); - default: - tries--; - } - } - return -1; -} - -static int put_char( - int c) -{ - char ch = c; - - return(write(ttyfd, &ch, 1)); -} - -static int write_char ( - int c) -{ - if (put_char(c) < 1) { - return (0); - } - return (1); -} - -static int put_string ( - char *s) -{ - char *out,*free_ptr=0; - - quiet = 0; - out = free_ptr = clean(s, 1); - while (*out) { - register char c = *out++; - - if (c != '\\') { - if (!write_char (c)){ - free(free_ptr); - return 0; - } - continue; - } - - c = *out++; - - switch (c) { - case 'd': - sleep(1); - break; - - case 'K': - break_sequence(); - break; - - case 'p': -#if 0 /* FIXME!!! */ - usleep(10000); /* 1/100th of a second (arg is microseconds) */ -#else - sleep(1); -#endif - break; - - default: - if (!write_char (c)){ - free(free_ptr); - return 0; - } - break; - } - } - free(free_ptr); - - return (1); -} - -/* - * 'Wait for' this string to appear on this file descriptor. - */ -static int get_string( - char *in_string) -{ - int c, len, minlen; - register char *s = temp2, *end = s + STR_LEN; - char *logged = temp2; - char *string=0; - struct termios tios; - - memset(temp2, 0, sizeof(temp2)); - - tcgetattr(ttyfd, &tios); - tios.c_cc[VMIN] = 0; - tios.c_cc[VTIME] = timeout*10/MAX_TIMEOUTS; - tcsetattr(ttyfd, TCSANOW, &tios); - - string = clean(in_string, 0); - len = strlen(string); - minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1; - - if (len > STR_LEN) { - exit_code = 1; - free(string); - return 0; - } - - if (len == 0) { - free(string); - return (1); - } - - while ( (c = get_char()) >= 0) { - int n, abort_len; - - if(c == '\n' || c == '\r'){ - s = temp2; - *s=0; - } - else{ - *s++ = c; - *s=0; - } - - if (s - temp2 >= len && - c == string[len - 1] && - strncmp(s - len, string, len) == 0) { - free(string); - return (1); - } - - for (n = 0; n < n_aborts; ++n) { - if (s - temp2 >= (abort_len = strlen(abort_string[n])) && - strncmp(s - abort_len, abort_string[n], abort_len) == 0) { - - exit_code = n + 4; - strcpy(fail_reason = fail_buffer, abort_string[n]); - free(string); - return (0); - } - } - - if (s >= end) { - if (logged < s - minlen) { - logged = s; - } - s -= minlen; - memmove(temp2, s, minlen); - logged = temp2 + (logged - s); - s = temp2 + minlen; - } - } - - exit_code = 3; - free(string); - return (0); -} diff --git a/cpukit/pppd/demand.c b/cpukit/pppd/demand.c deleted file mode 100644 index a5c13f71b6..0000000000 --- a/cpukit/pppd/demand.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * demand.c - Support routines for demand-dialling. - * - * Copyright (c) 1993 The Australian National 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 the Australian National 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PPP_FILTER -#include -#include -#include -#endif - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" -#include "lcp.h" - -static unsigned char *frame; -static int framelen; -static int framemax; -static int escape_flag; -static int flush_flag; -static int fcs; - -struct packet { - int length; - struct packet *next; - unsigned char data[1]; -}; - -struct packet *pend_q; -struct packet *pend_qtail; - -static int active_packet(unsigned char *, int); - -/* - * demand_conf - configure the interface for doing dial-on-demand. - */ -void -demand_conf(void) -{ - int i; - struct protent *protp; - -/* framemax = lcp_allowoptions[0].mru; - if (framemax < PPP_MRU) */ - framemax = PPP_MRU; - framemax += PPP_HDRLEN + PPP_FCSLEN; - frame = malloc(framemax); - if (frame == NULL) - novm("demand frame"); - framelen = 0; - pend_q = NULL; - escape_flag = 0; - flush_flag = 0; - fcs = PPP_INITFCS; - - ppp_send_config(0, PPP_MRU, (uint32_t) 0, 0, 0); - ppp_recv_config(0, PPP_MRU, (uint32_t) 0, 0, 0); - -#ifdef PPP_FILTER - set_filters(&pass_filter, &active_filter); -#endif - - /* - * Call the demand_conf procedure for each protocol that's got one. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->enabled_flag && protp->demand_conf != NULL) - if (!((*protp->demand_conf)(0))) - die(1); -} - - -/* - * demand_block - set each network protocol to block further packets. - */ -void -demand_block(void) -{ - int i; - struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE); - get_loop_output(); -} - -/* - * demand_discard - set each network protocol to discard packets - * with an error. - */ -void -demand_discard(void) -{ - struct packet *pkt, *nextpkt; - int i; - struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR); - get_loop_output(); - - /* discard all saved packets */ - for (pkt = pend_q; pkt != NULL; pkt = nextpkt) { - nextpkt = pkt->next; - free(pkt); - } - pend_q = NULL; - framelen = 0; - flush_flag = 0; - escape_flag = 0; - fcs = PPP_INITFCS; -} - -/* - * demand_unblock - set each enabled network protocol to pass packets. - */ -void -demand_unblock(void) -{ - int i; - struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS); -} - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -/* - * loop_chars - process characters received from the loopback. - * Calls loop_frame when a complete frame has been accumulated. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -loop_chars( - unsigned char *p, - int n) -{ - int c, rv; - - rv = 0; - for (; n > 0; --n) { - c = *p++; - if (c == PPP_FLAG) { - if (!escape_flag && !flush_flag - && framelen > 2 && fcs == PPP_GOODFCS) { - framelen -= 2; - if (loop_frame(frame, framelen)) - rv = 1; - } - framelen = 0; - flush_flag = 0; - escape_flag = 0; - fcs = PPP_INITFCS; - continue; - } - if (flush_flag) - continue; - if (escape_flag) { - c ^= PPP_TRANS; - escape_flag = 0; - } else if (c == PPP_ESCAPE) { - escape_flag = 1; - continue; - } - if (framelen >= framemax) { - flush_flag = 1; - continue; - } - frame[framelen++] = c; - fcs = PPP_FCS(fcs, c); - } - return rv; -} - -/* - * loop_frame - given a frame obtained from the loopback, - * decide whether to bring up the link or not, and, if we want - * to transmit this frame later, put it on the pending queue. - * Return value is 1 if we need to bring up the link, 0 otherwise. - * We assume that the kernel driver has already applied the - * pass_filter, so we won't get packets it rejected. - * We apply the active_filter to see if we want this packet to - * bring up the link. - */ -int -loop_frame( - unsigned char *frame, - int len) -{ - struct packet *pkt; - - /* dbglog("from loop: %P", frame, len); */ - if (len < PPP_HDRLEN) - return 0; - if ((PPP_PROTOCOL(frame) & 0x8000) != 0) - return 0; /* shouldn't get any of these anyway */ - if (!active_packet(frame, len)) - return 0; - - pkt = (struct packet *) malloc(sizeof(struct packet) + len); - if (pkt != NULL) { - pkt->length = len; - pkt->next = NULL; - memcpy(pkt->data, frame, len); - if (pend_q == NULL) - pend_q = pkt; - else - pend_qtail->next = pkt; - pend_qtail = pkt; - } - return 1; -} - -/* - * demand_rexmit - Resend all those frames which we got via the - * loopback, now that the real serial link is up. - */ -void -demand_rexmit( - int proto) -{ - struct packet *pkt, *prev, *nextpkt; - - prev = NULL; - pkt = pend_q; - pend_q = NULL; - for (; pkt != NULL; pkt = nextpkt) { - nextpkt = pkt->next; - if (PPP_PROTOCOL(pkt->data) == proto) { - output(0, pkt->data, pkt->length); - free(pkt); - } else { - if (prev == NULL) - pend_q = pkt; - else - prev->next = pkt; - prev = pkt; - } - } - pend_qtail = prev; - if (prev != NULL) - prev->next = NULL; -} - -/* - * Scan a packet to decide whether it is an "active" packet, - * that is, whether it is worth bringing up the link for. - */ -static int -active_packet( - unsigned char *p, - int len) -{ - int proto, i; - struct protent *protp; - - if (len < PPP_HDRLEN) - return 0; - proto = PPP_PROTOCOL(p); -#ifdef PPP_FILTER - if (active_filter.bf_len != 0 - && bpf_filter(active_filter.bf_insns, frame, len, len) == 0) - return 0; -#endif - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) { - if (!protp->enabled_flag) - return 0; - if (protp->active_pkt == NULL) - return 1; - return (*protp->active_pkt)(p, len); - } - } - return 0; /* not a supported protocol !!?? */ -} diff --git a/cpukit/pppd/fsm.c b/cpukit/pppd/fsm.c deleted file mode 100644 index 4ff17d8f95..0000000000 --- a/cpukit/pppd/fsm.c +++ /dev/null @@ -1,760 +0,0 @@ -/* - * fsm.c - {Link, IP} Control Protocol Finite State Machine. - * - * 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. - */ - -/* - * TODO: - * Randomize fsm id on link/init. - * Deal with variable outgoing MTU. - */ - -#include -#include -#include - -#include "pppd.h" -#include "fsm.h" - -static void fsm_timeout(void *); -static void fsm_rconfreq(fsm *, u_char, u_char *, int); -static void fsm_rconfack(fsm *, int, u_char *, int); -static void fsm_rconfnakrej(fsm *, int, int, u_char *, int); -static void fsm_rtermreq(fsm *, int, u_char *, int); -static void fsm_rtermack(fsm *); -static void fsm_rcoderej(fsm *, u_char *, int); -static void fsm_sconfreq(fsm *, int); - -#define PROTO_NAME(f) ((f)->callbacks->proto_name) - -int peer_mru[NUM_PPP]; - - -/* - * fsm_init - Initialize fsm. - * - * Initialize fsm state. - */ -void -fsm_init( - fsm *f) -{ - f->state = INITIAL; - f->flags = 0; - f->id = 100; /* XXX Start with random id? */ - f->timeouttime = DEFTIMEOUT; - f->maxconfreqtransmits = DEFMAXCONFREQS; - f->maxtermtransmits = DEFMAXTERMREQS; - f->maxnakloops = DEFMAXNAKLOOPS; - f->term_reason_len = 0; -} - - -/* - * fsm_lowerup - The lower layer is up. - */ -void -fsm_lowerup( - fsm *f) -{ - switch( f->state ){ - case INITIAL: - f->state = CLOSED; - break; - - case STARTING: - if( f->flags & OPT_SILENT ) - f->state = STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_lowerdown - The lower layer is down. - * - * Cancel all timeouts and inform upper layers. - */ -void -fsm_lowerdown( - fsm *f) -{ - switch( f->state ){ - case CLOSED: - f->state = INITIAL; - break; - - case STOPPED: - f->state = STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case CLOSING: - f->state = INITIAL; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case STOPPING: - case REQSENT: - case ACKRCVD: - case ACKSENT: - f->state = STARTING; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case OPENED: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - f->state = STARTING; - break; - - default: - FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_open - Link is allowed to come up. - */ -void -fsm_open( - fsm *f) -{ - switch( f->state ){ - case INITIAL: - f->state = STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case CLOSED: - if( f->flags & OPT_SILENT ) - f->state = STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - } - break; - - case CLOSING: - f->state = STOPPING; - /* fall through */ - case STOPPED: - case OPENED: - if( f->flags & OPT_RESTART ){ - fsm_lowerdown(f); - fsm_lowerup(f); - } - break; - } -} - - -/* - * fsm_close - Start closing connection. - * - * Cancel timeouts and either initiate close or possibly go directly to - * the CLOSED state. - */ -void -fsm_close( - fsm *f, - char *reason) -{ - f->term_reason = reason; - f->term_reason_len = (reason == NULL? 0: strlen(reason)); - switch( f->state ){ - case STARTING: - f->state = INITIAL; - break; - case STOPPED: - f->state = CLOSED; - break; - case STOPPING: - f->state = CLOSING; - break; - - case REQSENT: - case ACKRCVD: - case ACKSENT: - case OPENED: - if( f->state != OPENED ) - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - else if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers we're down */ - - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = CLOSING; - break; - } -} - - -/* - * fsm_timeout - Timeout expired. - */ -static void -fsm_timeout( - void *arg) -{ - fsm *f = (fsm *) arg; - - switch (f->state) { - case CLOSING: - case STOPPING: - if( f->retransmits <= 0 ){ - /* - * We've waited for an ack long enough. Peer probably heard us. - */ - f->state = (f->state == CLOSING)? CLOSED: STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - } else { - /* Send Terminate-Request */ - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - } - break; - - case REQSENT: - case ACKRCVD: - case ACKSENT: - if (f->retransmits <= 0) { - warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); - f->state = STOPPED; - if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) - (*f->callbacks->finished)(f); - - } else { - /* Retransmit the configure-request */ - if (f->callbacks->retransmit) - (*f->callbacks->retransmit)(f); - fsm_sconfreq(f, 1); /* Re-send Configure-Request */ - if( f->state == ACKRCVD ) - f->state = REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_input - Input packet. - */ -void -fsm_input( - fsm *f, - u_char *inpacket, - int l) -{ - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol)); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol)); - return; - } - if (len > l) { - FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol)); - return; - } - len -= HEADERLEN; /* subtract header length */ - - if( f->state == INITIAL || f->state == STARTING ){ - FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.", - f->protocol, f->state)); - return; - } - - /* - * Action depends on code. - */ - switch (code) { - case CONFREQ: - fsm_rconfreq(f, id, inp, len); - break; - - case CONFACK: - fsm_rconfack(f, id, inp, len); - break; - - case CONFNAK: - case CONFREJ: - fsm_rconfnakrej(f, code, id, inp, len); - break; - - case TERMREQ: - fsm_rtermreq(f, id, inp, len); - break; - - case TERMACK: - fsm_rtermack(f); - break; - - case CODEREJ: - fsm_rcoderej(f, inp, len); - break; - - default: - if( !f->callbacks->extcode - || !(*f->callbacks->extcode)(f, code, id, inp, len) ) - fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); - break; - } -} - - -/* - * fsm_rconfreq - Receive Configure-Request. - */ -static void -fsm_rconfreq( - fsm *f, - u_char id, - u_char *inp, - int len) -{ - int code, reject_if_disagree; - - switch( f->state ){ - case CLOSED: - /* Go away, we're closed */ - fsm_sdata(f, TERMACK, id, NULL, 0); - return; - case CLOSING: - case STOPPING: - return; - - case OPENED: - /* Go down and restart negotiation */ - if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - break; - - case STOPPED: - /* Negotiation started by our peer */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } - - /* - * Pass the requested configuration options - * to protocol-specific code for checking. - */ - if (f->callbacks->reqci){ /* Check CI */ - reject_if_disagree = (f->nakloops >= f->maxnakloops); - code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); - } else if (len) - code = CONFREJ; /* Reject all CI */ - else - code = CONFACK; - - /* send the Ack, Nak or Rej to the peer */ - fsm_sdata(f, code, id, inp, len); - - if (code == CONFACK) { - if (f->state == ACKRCVD) { - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = OPENED; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - } else { - f->state = ACKSENT; - ppp_delay(); - } - f->nakloops = 0; - - } else { - /* we sent CONFACK or CONFREJ */ - if (f->state != ACKRCVD) - f->state = REQSENT; - if( code == CONFNAK ) - ++f->nakloops; - } -} - - -/* - * fsm_rconfack - Receive Configure-Ack. - */ -static void -fsm_rconfack( - fsm *f, - int id, - u_char *inp, - int len) -{ - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): - (len == 0)) ){ - /* Ack is bad - ignore it */ - error("Received bad configure-ack: %P", inp, len); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case CLOSED: - case STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case REQSENT: - f->state = ACKRCVD; - f->retransmits = f->maxconfreqtransmits; - break; - - case ACKRCVD: - /* Huh? an extra valid Ack? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - break; - - case ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = OPENED; - f->retransmits = f->maxconfreqtransmits; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - break; - - case OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } -} - - -/* - * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - */ -static void -fsm_rconfnakrej( - fsm *f, - int code, int id, - u_char *inp, - int len) -{ - int (*proc)(fsm *, u_char *, int); - int ret; - - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci; - if (!proc || !(ret = proc(f, inp, len))) { - /* Nak/reject is bad - ignore it */ - error("Received bad configure-nak/rej: %P", inp, len); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case CLOSED: - case STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case REQSENT: - case ACKSENT: - /* They didn't agree to what we wanted - try another request */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - if (ret < 0) - f->state = STOPPED; /* kludge for stopping CCP */ - else - fsm_sconfreq(f, 0); /* Send Configure-Request */ - break; - - case ACKRCVD: - /* Got a Nak/reject when we had already had an Ack?? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - break; - - case OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } -} - - -/* - * fsm_rtermreq - Receive Terminate-Req. - */ -static void -fsm_rtermreq( - fsm *f, - int id, - u_char *p, - int len) -{ - switch (f->state) { - case ACKRCVD: - case ACKSENT: - f->state = REQSENT; /* Start over but keep trying */ - break; - - case OPENED: - if (len > 0) { - info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); - } else - info("%s terminated by peer", PROTO_NAME(f)); - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - f->retransmits = 0; - f->state = STOPPING; - TIMEOUT(fsm_timeout, f, f->timeouttime); - break; - } - - fsm_sdata(f, TERMACK, id, NULL, 0); -} - - -/* - * fsm_rtermack - Receive Terminate-Ack. - */ -static void -fsm_rtermack( - fsm *f) -{ - switch (f->state) { - case CLOSING: - UNTIMEOUT(fsm_timeout, f); - f->state = CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - case STOPPING: - UNTIMEOUT(fsm_timeout, f); - f->state = STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case ACKRCVD: - f->state = REQSENT; - break; - - case OPENED: - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); - break; - } -} - - -/* - * fsm_rcoderej - Receive an Code-Reject. - */ -static void -fsm_rcoderej( - fsm *f, - u_char *inp, - int len) -{ - u_char code, id; - - if (len < HEADERLEN) { - FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); - - if( f->state == ACKRCVD ) - f->state = REQSENT; -} - - -/* - * fsm_protreject - Peer doesn't speak this protocol. - * - * Treat this as a catastrophic error (RXJ-). - */ -void -fsm_protreject( - fsm *f) -{ - switch( f->state ){ - case CLOSING: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case CLOSED: - f->state = CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case STOPPING: - case REQSENT: - case ACKRCVD: - case ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case STOPPED: - f->state = STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case OPENED: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = STOPPING; - break; - - default: - FSMDEBUG(("%s: Protocol-reject event in state %d!", - PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_sconfreq - Send a Configure-Request. - */ -static void -fsm_sconfreq( - fsm *f, - int retransmit) -{ - u_char *outp; - int cilen; - - if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){ - /* Not currently negotiating - reset options */ - if( f->callbacks->resetci ) - (*f->callbacks->resetci)(f); - f->nakloops = 0; - } - - if( !retransmit ){ - /* New request - reset retransmission counter, use new ID */ - f->retransmits = f->maxconfreqtransmits; - f->reqid = ++f->id; - } - - f->seen_ack = 0; - - /* - * Make up the request packet - */ - outp = outpacket_buf + PPP_HDRLEN + HEADERLEN; - if( f->callbacks->cilen && f->callbacks->addci ){ - cilen = (*f->callbacks->cilen)(f); - if( cilen > peer_mru[f->unit] - HEADERLEN ) - cilen = peer_mru[f->unit] - HEADERLEN; - if (f->callbacks->addci) - (*f->callbacks->addci)(f, outp, &cilen); - } else - cilen = 0; - - /* send the request to our peer */ - fsm_sdata(f, CONFREQ, f->reqid, outp, cilen); - - /* start the retransmit timer */ - --f->retransmits; - TIMEOUT(fsm_timeout, f, f->timeouttime); -} - - -/* - * fsm_sdata - Send some data. - * - * Used for all packets sent to our peer by this module. - */ -void -fsm_sdata( - fsm *f, - u_char code, u_char id, - u_char *data, - int datalen) -{ - u_char *outp; - int outlen; - - /* Adjust length to be smaller than MTU */ - outp = outpacket_buf; - if (datalen > peer_mru[f->unit] - HEADERLEN) - datalen = peer_mru[f->unit] - HEADERLEN; - if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) - BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen); - outlen = datalen + HEADERLEN; - MAKEHEADER(outp, f->protocol); - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - output(f->unit, outpacket_buf, outlen + PPP_HDRLEN); -} diff --git a/cpukit/pppd/fsm.h b/cpukit/pppd/fsm.h deleted file mode 100644 index 6b829516c6..0000000000 --- a/cpukit/pppd/fsm.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. - * - * 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. - * - * $Id$ - */ - -/* - * Packet header = Code, id, length. - */ -#define HEADERLEN 4 - - -/* - * CP (LCP, IPCP, etc.) codes. - */ -#define CONFREQ 1 /* Configuration Request */ -#define CONFACK 2 /* Configuration Ack */ -#define CONFNAK 3 /* Configuration Nak */ -#define CONFREJ 4 /* Configuration Reject */ -#define TERMREQ 5 /* Termination Request */ -#define TERMACK 6 /* Termination Ack */ -#define CODEREJ 7 /* Code Reject */ - - -/* - * Each FSM is described by an fsm structure and fsm callbacks. - */ -typedef struct fsm { - int unit; /* Interface unit number */ - int protocol; /* Data Link Layer Protocol field value */ - int state; /* State */ - int flags; /* Contains option bits */ - u_char id; /* Current id */ - u_char reqid; /* Current request id */ - u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */ - int timeouttime; /* Timeout time in milliseconds */ - int maxconfreqtransmits; /* Maximum Configure-Request transmissions */ - int retransmits; /* Number of retransmissions left */ - int maxtermtransmits; /* Maximum Terminate-Request transmissions */ - int nakloops; /* Number of nak loops since last ack */ - int maxnakloops; /* Maximum number of nak loops tolerated */ - struct fsm_callbacks *callbacks; /* Callback routines */ - char *term_reason; /* Reason for closing protocol */ - int term_reason_len; /* Length of term_reason */ -} fsm; - - -typedef struct fsm_callbacks { - void (*resetci) /* Reset our Configuration Information */ - (fsm *); - int (*cilen) /* Length of our Configuration Information */ - (fsm *); - void (*addci) /* Add our Configuration Information */ - (fsm *, u_char *, int *); - int (*ackci) /* ACK our Configuration Information */ - (fsm *, u_char *, int); - int (*nakci) /* NAK our Configuration Information */ - (fsm *, u_char *, int); - int (*rejci) /* Reject our Configuration Information */ - (fsm *, u_char *, int); - int (*reqci) /* Request peer's Configuration Information */ - (fsm *, u_char *, int *, int); - void (*up) /* Called when fsm reaches OPENED state */ - (fsm *); - void (*down) /* Called when fsm leaves OPENED state */ - (fsm *); - void (*starting) /* Called when we want the lower layer */ - (fsm *); - void (*finished) /* Called when we don't want the lower layer */ - (fsm *); - void (*protreject) /* Called when Protocol-Reject received */ - (int); - void (*retransmit) /* Retransmission is necessary */ - (fsm *); - int (*extcode) /* Called when unknown code received */ - (fsm *, int, int, u_char *, int); - char *proto_name; /* String name for protocol (for messages) */ -} fsm_callbacks; - - -/* - * Link states. - */ -#define INITIAL 0 /* Down, hasn't been opened */ -#define STARTING 1 /* Down, been opened */ -#define CLOSED 2 /* Up, hasn't been opened */ -#define STOPPED 3 /* Open, waiting for down event */ -#define CLOSING 4 /* Terminating the connection, not open */ -#define STOPPING 5 /* Terminating, but open */ -#define REQSENT 6 /* We've sent a Config Request */ -#define ACKRCVD 7 /* We've received a Config Ack */ -#define ACKSENT 8 /* We've sent a Config Ack */ -#define OPENED 9 /* Connection available */ - - -/* - * Flags - indicate options controlling FSM operation - */ -#define OPT_PASSIVE 1 /* Don't die if we don't get a response */ -#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ -#define OPT_SILENT 4 /* Wait for peer to speak first */ - - -/* - * Timeouts. - */ -#define DEFTIMEOUT 5 /* Timeout time in seconds */ -#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ -#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ -#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ - - -/* - * Prototypes - */ -void fsm_init(fsm *); -void fsm_lowerup(fsm *); -void fsm_lowerdown(fsm *); -void fsm_open(fsm *); -void fsm_close(fsm *, char *); -void fsm_input(fsm *, u_char *, int); -void fsm_protreject(fsm *); -void fsm_sdata(fsm *, u_char, u_char, u_char *, int); - - -/* - * Variables - */ -extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ diff --git a/cpukit/pppd/ipcp.c b/cpukit/pppd/ipcp.c deleted file mode 100644 index a9a8f240ae..0000000000 --- a/cpukit/pppd/ipcp.c +++ /dev/null @@ -1,1768 +0,0 @@ -/* - * ipcp.c - PPP IP Control Protocol. - * - * 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. - */ - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" -#include "pathnames.h" - -#include - -/* global vars */ -ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ -ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ - -bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ - -/* Hook for a plugin to know when IP protocol has come up */ -void (*ip_up_hook)(void) = NULL; - -/* Hook for a plugin to know when IP protocol has come down */ -void (*ip_down_hook)(void) = NULL; - -/* local vars */ -static int default_route_set[NUM_PPP]; /* Have set up a default route */ -static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ -static bool usepeerdns; /* Ask peer for DNS addrs */ -static int ipcp_is_up; /* have called np_up() */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipcp_resetci(fsm *); /* Reset our CI */ -static int ipcp_cilen(fsm *); /* Return length of our CI */ -static void ipcp_addci(fsm *, u_char *, int *); /* Add our CI */ -static int ipcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */ -static int ipcp_nakci(fsm *, u_char *, int); /* Peer nak'd our CI */ -static int ipcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */ -static int ipcp_reqci(fsm *, u_char *, int *, int); /* Rcv CI */ -static void ipcp_up(fsm *); /* We're UP */ -static void ipcp_down(fsm *); /* We're DOWN */ -static void ipcp_finished(fsm *); /* Don't need lower layer */ - -fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ - -static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ - ipcp_resetci, /* Reset our Configuration Information */ - ipcp_cilen, /* Length of our Configuration Information */ - ipcp_addci, /* Add our Configuration Information */ - ipcp_ackci, /* ACK our Configuration Information */ - ipcp_nakci, /* NAK our Configuration Information */ - ipcp_rejci, /* Reject our Configuration Information */ - ipcp_reqci, /* Request peer's Configuration Information */ - ipcp_up, /* Called when fsm reaches OPENED state */ - ipcp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPCP" /* String name of protocol */ -}; - -/* - * Command-line options. - */ -static int setvjslots(char **); -static int setdnsaddr(char **); -static int setwinsaddr(char **); - -static option_t ipcp_option_list[] = { - { "noip", o_bool, &ipcp_protent.enabled_flag, - "Disable IP and IPCP", 0, NULL, 0, 0 }, - { "-ip", o_bool, &ipcp_protent.enabled_flag, - "Disable IP and IPCP", 0, NULL, 0, 0 }, - { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, - "Disable VJ compression", OPT_A2COPY, - &ipcp_allowoptions[0].neg_vj, 0, 0 }, - { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, - "Disable VJ compression", OPT_A2COPY, - &ipcp_allowoptions[0].neg_vj, 0, 0 }, - { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, - "Disable VJ connection-ID compression", OPT_A2COPY, - &ipcp_allowoptions[0].cflag, 0, 0 }, - { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, - "Disable VJ connection-ID compression", OPT_A2COPY, - &ipcp_allowoptions[0].cflag, 0, 0 }, - { "vj-max-slots", 1, setvjslots, - "Set maximum VJ header slots", 0, NULL, 0, 0 }, - { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, - "Accept peer's address for us", 1, NULL, 0, 0 }, - { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, - "Accept peer's address for it", 1, NULL, 0, 0 }, - { "ipparam", o_string, &ipparam, - "Set ip script parameter", 0, NULL, 0, 0 }, - { "noipdefault", o_bool, &disable_defaultip, - "Don't use name for default IP adrs", 1, NULL, 0, 0 }, - { "ms-dns", 1, setdnsaddr, - "DNS address for the peer's use", 0, NULL, 0, 0 }, - { "ms-wins", 1, setwinsaddr, - "Nameserver for SMB over TCP/IP for peer", 0, NULL, 0, 0 }, - { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, - "Set timeout for IPCP", 0, NULL, 0, 0 }, - { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, - "Set max #xmits for term-reqs", 0, NULL, 0, 0 }, - { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, - "Set max #xmits for conf-reqs", 0, NULL, 0, 0 }, - { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, - "Set max #conf-naks for IPCP", 0, NULL, 0, 0 }, - { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, - "Add default route", OPT_ENABLE|1, - &ipcp_allowoptions[0].default_route, 0, 0 }, - { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, - "disable defaultroute option", OPT_A2COPY, - &ipcp_wantoptions[0].default_route, 0, 0 }, - { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, - "disable defaultroute option", OPT_A2COPY, - &ipcp_wantoptions[0].default_route, 0, 0 }, - { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, - "Add proxy ARP entry", OPT_ENABLE|1, - &ipcp_allowoptions[0].proxy_arp, 0, 0 }, - { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, - "disable proxyarp option", OPT_A2COPY, - &ipcp_wantoptions[0].proxy_arp, 0, 0 }, - { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, - "disable proxyarp option", OPT_A2COPY, - &ipcp_wantoptions[0].proxy_arp, 0, 0 }, - { "usepeerdns", o_bool, &usepeerdns, - "Ask peer for DNS address(es)", 1, NULL, 0, 0 }, - { NULL, 0, NULL, NULL, 0, NULL, 0, 0 } -}; - -/* - * Protocol entry points from main code. - */ -static void ipcp_init(int); -static void ipcp_open(int); -static void ipcp_close(int, char *); -static void ipcp_lowerup(int); -static void ipcp_lowerdown(int); -static void ipcp_input(int, u_char *, int); -static void ipcp_protrej(int); -static int ipcp_printpkt(u_char *, int, - void (*)(void *, char *, ...), void *); -static void ip_check_options(void); -static int ip_demand_conf(int); -static int ip_active_pkt(u_char *, int); -static void create_resolv(uint32_t, uint32_t); - -struct protent ipcp_protent = { - PPP_IPCP, - ipcp_init, - ipcp_input, - ipcp_protrej, - ipcp_lowerup, - ipcp_lowerdown, - ipcp_open, - ipcp_close, - ipcp_printpkt, - NULL, - 1, - "IPCP", - "IP", - ipcp_option_list, - ip_check_options, - ip_demand_conf, - ip_active_pkt -}; - -static void ipcp_clear_addrs(int, uint32_t, uint32_t); - -/* - * Lengths of configuration options. - */ -#define CILEN_VOID 2 -#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ -#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ -#define CILEN_ADDR 6 /* new-style single address option */ -#define CILEN_ADDRS 10 /* old-style dual address option */ - - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -/* - * Make a string representation of a network IP address. - */ -char * -ip_ntoa( - uint32_t ipaddr) -{ - static char b[64]; - - slprintf(b, sizeof(b), "%I", ipaddr); - return b; -} - -/* - * Option parsing. - */ - -/* - * setvjslots - set maximum number of connection slots for VJ compression - */ -static int -setvjslots( - char **argv) -{ - int value; - - if (!int_option(*argv, &value)) - return 0; - if (value < 2 || value > 16) { - option_error("vj-max-slots value must be between 2 and 16"); - return 0; - } - ipcp_wantoptions [0].maxslotindex = - ipcp_allowoptions[0].maxslotindex = value - 1; - return 1; -} - -/* - * setdnsaddr - set the dns address(es) - */ -static int -setdnsaddr( - char **argv) -{ - uint32_t dns; - struct hostent *hp; - - dns = inet_addr(*argv); - if (dns == (uint32_t) -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-dns option", - *argv); - return 0; - } - dns = *(uint32_t *)hp->h_addr; - } - - /* if there is no primary then update it. */ - if (ipcp_allowoptions[0].dnsaddr[0] == 0) - ipcp_allowoptions[0].dnsaddr[0] = dns; - - /* always set the secondary address value to the same value. */ - ipcp_allowoptions[0].dnsaddr[1] = dns; - - return (1); -} - -/* - * setwinsaddr - set the wins address(es) - * This is primrarly used with the Samba package under UNIX or for pointing - * the caller to the existing WINS server on a Windows NT platform. - */ -static int -setwinsaddr( - char **argv) -{ - uint32_t wins; - struct hostent *hp; - - wins = inet_addr(*argv); - if (wins == (uint32_t) -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-wins option", - *argv); - return 0; - } - wins = *(uint32_t *)hp->h_addr; - } - - /* if there is no primary then update it. */ - if (ipcp_allowoptions[0].winsaddr[0] == 0) - ipcp_allowoptions[0].winsaddr[0] = wins; - - /* always set the secondary address value to the same value. */ - ipcp_allowoptions[0].winsaddr[1] = wins; - - return (1); -} - - -/* - * ipcp_init - Initialize IPCP. - */ -static void -ipcp_init( - int unit) -{ - fsm *f = &ipcp_fsm[unit]; - ipcp_options *wo = &ipcp_wantoptions[unit]; - ipcp_options *ao = &ipcp_allowoptions[unit]; - - f->unit = unit; - f->protocol = PPP_IPCP; - f->callbacks = &ipcp_callbacks; - fsm_init(&ipcp_fsm[unit]); - - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); - - wo->neg_addr = 1; - wo->neg_vj = 1; - wo->vj_protocol = IPCP_VJ_COMP; - wo->maxslotindex = MAX_STATES - 1; /* really max index */ - wo->cflag = 1; - - /* max slots and slot-id compression are currently hardwired in */ - /* ppp_if.c to 16 and 1, this needs to be changed (among other */ - /* things) gmc */ - - ao->neg_addr = 1; - ao->neg_vj = 1; - ao->maxslotindex = MAX_STATES - 1; - ao->cflag = 1; - - /* - * XXX These control whether the user may use the proxyarp - * and defaultroute options. - */ - ao->proxy_arp = 1; - ao->default_route = 1; -} - - -/* - * ipcp_open - IPCP is allowed to come up. - */ -static void -ipcp_open( - int unit) -{ - fsm_open(&ipcp_fsm[unit]); -} - - -/* - * ipcp_close - Take IPCP down. - */ -static void -ipcp_close( - int unit, - char *reason) -{ - fsm_close(&ipcp_fsm[unit], reason); -} - - -/* - * ipcp_lowerup - The lower layer is up. - */ -static void -ipcp_lowerup( - int unit) -{ - fsm_lowerup(&ipcp_fsm[unit]); -} - - -/* - * ipcp_lowerdown - The lower layer is down. - */ -static void -ipcp_lowerdown( - int unit) -{ - fsm_lowerdown(&ipcp_fsm[unit]); -} - - -/* - * ipcp_input - Input IPCP packet. - */ -static void -ipcp_input( - int unit, - u_char *p, - int len) -{ - fsm_input(&ipcp_fsm[unit], p, len); -} - - -/* - * ipcp_protrej - A Protocol-Reject was received for IPCP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void -ipcp_protrej( - int unit) -{ - fsm_lowerdown(&ipcp_fsm[unit]); -} - - -/* - * ipcp_resetci - Reset our CI. - * Called by fsm_sconfreq, Send Configure Request. - */ -static void -ipcp_resetci( - fsm *f) -{ - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - - wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; - if (wo->ouraddr == 0 || disable_defaultip) - wo->accept_local = 1; - if (wo->hisaddr == 0) - wo->accept_remote = 1; - wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */ - wo->req_dns2 = usepeerdns; - *go = *wo; - if (disable_defaultip) - go->ouraddr = 0; -} - - -/* - * ipcp_cilen - Return length of our CI. - * Called by fsm_sconfreq, Send Configure Request. - */ -static int -ipcp_cilen( - fsm *f) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - -#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) -#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) -#define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0) - - /* - * First see if we want to change our options to the old - * forms because we have received old forms from the peer. - */ - if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { - /* use the old style of address negotiation */ - go->neg_addr = 1; - go->old_addrs = 1; - } - if (wo->neg_vj && !go->neg_vj && !go->old_vj) { - /* try an older style of VJ negotiation */ - /* use the old style only if the peer did */ - if (ho->neg_vj && ho->old_vj) { - go->neg_vj = 1; - go->old_vj = 1; - go->vj_protocol = ho->vj_protocol; - } - } - - return (LENCIADDR(go->neg_addr, go->old_addrs) + - LENCIVJ(go->neg_vj, go->old_vj) + - LENCIDNS(go->req_dns1) + - LENCIDNS(go->req_dns2)) ; -} - - -/* - * ipcp_addci - Add our desired CIs to a packet. - * Called by fsm_sconfreq, Send Configure Request. - */ -static void -ipcp_addci( - fsm *f, - u_char *ucp, - int *lenp) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - int len = *lenp; - -#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if (len >= vjlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(vjlen, ucp); \ - PUTSHORT(val, ucp); \ - if (!old) { \ - PUTCHAR(maxslotindex, ucp); \ - PUTCHAR(cflag, ucp); \ - } \ - len -= vjlen; \ - } else \ - neg = 0; \ - } - -#define ADDCIADDR(opt, neg, old, val1, val2) \ - if (neg) { \ - int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - if (len >= addrlen) { \ - uint32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(addrlen, ucp); \ - l = ntohl(val1); \ - PUTLONG(l, ucp); \ - if (old) { \ - l = ntohl(val2); \ - PUTLONG(l, ucp); \ - } \ - len -= addrlen; \ - } else \ - neg = 0; \ - } - -#define ADDCIDNS(opt, neg, addr) \ - if (neg) { \ - if (len >= CILEN_ADDR) { \ - uint32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = ntohl(addr); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else \ - neg = 0; \ - } - - ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); - - *lenp -= len; -} - - -/* - * ipcp_ackci - Ack our CIs. - * Called by fsm_rconfack, Receive Configure ACK. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -ipcp_ackci( - fsm *f, - u_char *p, - int len) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_short cilen, citype, cishort; - uint32_t cilong; - u_char cimaxslotindex, cicflag; - - /* - * CIs must be in exactly the same order that we sent... - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - -#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if ((len -= vjlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != vjlen || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslotindex) \ - goto bad; \ - GETCHAR(cicflag, p); \ - if (cicflag != cflag) \ - goto bad; \ - } \ - } - -#define ACKCIADDR(opt, neg, old, val1, val2) \ - if (neg) { \ - int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - uint32_t l; \ - if ((len -= addrlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != addrlen || \ - citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (val1 != cilong) \ - goto bad; \ - if (old) { \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (val2 != cilong) \ - goto bad; \ - } \ - } - -#define ACKCIDNS(opt, neg, addr) \ - if (neg) { \ - uint32_t l; \ - if ((len -= CILEN_ADDR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (addr != cilong) \ - goto bad; \ - } - - ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); - -bad: - IPCPDEBUG(("ipcp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPCP is in the OPENED state. - * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int -ipcp_nakci( - fsm *f, - u_char *p, - int len) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char cimaxslotindex, cicflag; - u_char citype, cilen, *next; - u_short cishort; - uint32_t ciaddr1, ciaddr2, l, cidnsaddr; - ipcp_options no; /* options we've seen Naks for */ - ipcp_options try; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIADDR(opt, neg, old, code) \ - if (go->neg && \ - len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - ciaddr1 = htonl(l); \ - if (old) { \ - GETLONG(l, p); \ - ciaddr2 = htonl(l); \ - no.old_addrs = 1; \ - } else \ - ciaddr2 = 0; \ - no.neg = 1; \ - code \ - } - -#define NAKCIVJ(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } - -#define NAKCIDNS(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cidnsaddr = htonl(l); \ - no.neg = 1; \ - code \ - } - - /* - * Accept the peer's idea of {our,his} address, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs, - if (go->accept_local && ciaddr1) { /* Do we know our address? */ - try.ouraddr = ciaddr1; - } - if (go->accept_remote && ciaddr2) { /* Does he know his? */ - try.hisaddr = ciaddr2; - } - ); - - /* - * Accept the peer's value of maxslotindex provided that it - * is less than what we asked for. Turn off slot-ID compression - * if the peer wants. Send old-style compress-type option if - * the peer wants. - */ - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - if (cilen == CILEN_VJ) { - GETCHAR(cimaxslotindex, p); - GETCHAR(cicflag, p); - if (cishort == IPCP_VJ_COMP) { - try.old_vj = 0; - if (cimaxslotindex < go->maxslotindex) - try.maxslotindex = cimaxslotindex; - if (!cicflag) - try.cflag = 0; - } else { - try.neg_vj = 0; - } - } else { - if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { - try.old_vj = 1; - try.vj_protocol = cishort; - } else { - try.neg_vj = 0; - } - } - ); - - NAKCIDNS(CI_MS_DNS1, req_dns1, - try.dnsaddr[0] = cidnsaddr; - ); - - NAKCIDNS(CI_MS_DNS2, req_dns2, - try.dnsaddr[1] = cidnsaddr; - ); - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If they want to negotiate about IP addresses, we comply. - * If they want us to ask for compression, we refuse. - */ - while (len > CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if( (len -= cilen) < 0 ) - goto bad; - next = p + cilen - 2; - - switch (citype) { - case CI_COMPRESSTYPE: - if (go->neg_vj || no.neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) - goto bad; - no.neg_vj = 1; - break; - case CI_ADDRS: - if ((go->neg_addr && go->old_addrs) || no.old_addrs - || cilen != CILEN_ADDRS) - goto bad; - try.neg_addr = 1; - try.old_addrs = 1; - GETLONG(l, p); - ciaddr1 = htonl(l); - if (ciaddr1 && go->accept_local) - try.ouraddr = ciaddr1; - GETLONG(l, p); - ciaddr2 = htonl(l); - if (ciaddr2 && go->accept_remote) - try.hisaddr = ciaddr2; - no.old_addrs = 1; - break; - case CI_ADDR: - if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) - goto bad; - try.old_addrs = 0; - GETLONG(l, p); - ciaddr1 = htonl(l); - if (ciaddr1 && go->accept_local) - try.ouraddr = ciaddr1; - if (try.ouraddr != 0) - try.neg_addr = 1; - no.neg_addr = 1; - break; - } - p = next; - } - - /* - * OK, the Nak is good. Now we can update state. - * If there are any remaining options, we ignore them. - */ - if (f->state != OPENED) - *go = try; - - return 1; - -bad: - IPCPDEBUG(("ipcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * ipcp_rejci - Reject some of our CIs. - * Callback from fsm_rconfnakrej. - */ -static int -ipcp_rejci( - fsm *f, - u_char *p, - int len) -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char cimaxslotindex, ciflag, cilen; - u_short cishort; - uint32_t cilong; - ipcp_options try; /* options to request next time */ - - try = *go; - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIADDR(opt, neg, old, val1, val2) \ - if (go->neg && \ - len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ - p[1] == cilen && \ - p[0] == opt) { \ - uint32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val1) \ - goto bad; \ - if (old) { \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val2) \ - goto bad; \ - } \ - try.neg = 0; \ - } - -#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ - if (go->neg && \ - p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ - len >= p[1] && \ - p[0] == opt) { \ - len -= p[1]; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslot) \ - goto bad; \ - GETCHAR(ciflag, p); \ - if (ciflag != cflag) \ - goto bad; \ - } \ - try.neg = 0; \ - } - -#define REJCIDNS(opt, neg, dnsaddr) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - uint32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != dnsaddr) \ - goto bad; \ - try.neg = 0; \ - } - - - REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); - - REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != OPENED) - *go = try; - return 1; - -bad: - IPCPDEBUG(("ipcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * ipcp_reqci - Check the peer's requested CIs and send appropriate response. - * Callback from fsm_rconfreq, Receive Configure Request - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - */ -static int -ipcp_reqci( - fsm *f, - u_char *inp, /* Requested CIs */ - int *len, /* Length of requested CIs */ - int reject_if_disagree) -{ - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - ipcp_options *ao = &ipcp_allowoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ - u_short cishort; /* Parsed short value */ - uint32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ - u_char maxslotindex, cflag; - int d; - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPCPDEBUG(("ipcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_ADDRS: - if (!ao->neg_addr || - cilen != CILEN_ADDRS) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(uint32_t), p); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * If neither we nor he knows his address, reject the option. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - /* - * If he doesn't know our address, or if we both have our address - * but disagree about it, then NAK it with our idea. - */ - GETLONG(tl, p); /* Parse desination address (ours) */ - ciaddr2 = htonl(tl); - if (ciaddr2 != wo->ouraddr) { - if (ciaddr2 == 0 || !wo->accept_local) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(uint32_t), p); - tl = ntohl(wo->ouraddr); - PUTLONG(tl, p); - } - } else { - go->ouraddr = ciaddr2; /* accept peer's idea */ - } - } - - ho->neg_addr = 1; - ho->old_addrs = 1; - ho->hisaddr = ciaddr1; - ho->ouraddr = ciaddr2; - break; - - case CI_ADDR: - if (!ao->neg_addr || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(uint32_t), p); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * Don't ACK an address of 0.0.0.0 - reject it instead. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - ho->neg_addr = 1; - ho->hisaddr = ciaddr1; - break; - - case CI_MS_DNS1: - case CI_MS_DNS2: - /* Microsoft primary or secondary DNS request */ - d = citype == CI_MS_DNS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->dnsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (htonl(tl) != ao->dnsaddr[d]) { - DECPTR(sizeof(uint32_t), p); - tl = ntohl(ao->dnsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; - - case CI_MS_WINS1: - case CI_MS_WINS2: - /* Microsoft primary or secondary WINS request */ - d = citype == CI_MS_WINS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->winsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (htonl(tl) != ao->winsaddr[d]) { - DECPTR(sizeof(uint32_t), p); - tl = ntohl(ao->winsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; - - case CI_COMPRESSTYPE: - if (!ao->neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - if (!(cishort == IPCP_VJ_COMP || - (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - if (cilen == CILEN_VJ) { - GETCHAR(maxslotindex, p); - if (maxslotindex > ao->maxslotindex) { - orc = CONFNAK; - if (!reject_if_disagree){ - DECPTR(1, p); - PUTCHAR(ao->maxslotindex, p); - } - } - GETCHAR(cflag, p); - if (cflag && !ao->cflag) { - orc = CONFNAK; - if (!reject_if_disagree){ - DECPTR(1, p); - PUTCHAR(wo->cflag, p); - } - } - ho->maxslotindex = maxslotindex; - ho->cflag = cflag; - } else { - ho->old_vj = 1; - ho->maxslotindex = MAX_STATES - 1; - ho->cflag = 1; - } - break; - - default: - orc = CONFREJ; - break; - } -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) /* Getting fed up with sending NAKs? */ - orc = CONFREJ; /* Get tough if so */ - else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) - BCOPY(cip, ucp, cilen); /* Move it */ - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their address, and they didn't send their address, then we - * send a NAK with a CI_ADDR option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - if (rc != CONFREJ && !ho->neg_addr && - wo->req_addr && !reject_if_disagree) { - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_addr = 0; /* don't ask again */ - } - PUTCHAR(CI_ADDR, ucp); - PUTCHAR(CILEN_ADDR, ucp); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -/* - * ip_check_options - check that any IP-related options are OK, - * and assign appropriate defaults. - */ -static void -ip_check_options(void) -{ - struct hostent *hp; - uint32_t local; - ipcp_options *wo = &ipcp_wantoptions[0]; - - /* - * Default our local IP address based on our hostname. - * If local IP address already given, don't bother. - */ - if (wo->ouraddr == 0 && !disable_defaultip) { - /* - * Look up our hostname (possibly with domain name appended) - * and take the first IP address as our local IP address. - * If there isn't an IP address for our hostname, too bad. - */ - wo->accept_local = 1; /* don't insist on this default value */ - if ((hp = gethostbyname(hostname)) != NULL) { - local = *(uint32_t *)hp->h_addr; - if (local != 0 && !bad_ip_adrs(local)) - wo->ouraddr = local; - } - } -} - - -/* - * ip_demand_conf - configure the interface as though - * IPCP were up, for use with dial-on-demand. - */ -static int -ip_demand_conf( - int u) -{ - ipcp_options *wo = &ipcp_wantoptions[u]; - - if (wo->hisaddr == 0) { - /* make up an arbitrary address for the peer */ - wo->hisaddr = htonl(0x0a707070 + pppifunit); - wo->accept_remote = 1; - } - if (wo->ouraddr == 0) { - /* make up an arbitrary address for us */ - wo->ouraddr = htonl(0x0a404040 + pppifunit); - wo->accept_local = 1; - disable_defaultip = 1; /* don't tell the peer this address */ - } - if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) - return 0; - if (!sifup(u)) - return 0; - if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) - return 0; - if (wo->default_route) - if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) - default_route_set[u] = 1; - if (wo->proxy_arp) - if (sifproxyarp(u, wo->hisaddr)) - proxy_arp_set[u] = 1; - - notice("local IP address %I", wo->ouraddr); - notice("remote IP address %I", wo->hisaddr); - - return 1; -} - - -/* - * ipcp_up - IPCP has come UP. - * - * Configure the IP network interface appropriately and bring it up. - */ -static void -ipcp_up( - fsm *f) -{ - uint32_t mask; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - - IPCPDEBUG(("ipcp: up")); - - /* - * We must have a non-zero IP address for both ends of the link. - */ - if (!ho->neg_addr) - ho->hisaddr = wo->hisaddr; - - if (ho->hisaddr == 0) { - error("Could not determine remote IP address"); - ipcp_close(f->unit, "Could not determine remote IP address"); - return; - } - if (go->ouraddr == 0) { - error("Could not determine local IP address"); - ipcp_close(f->unit, "Could not determine local IP address"); - return; - } - - if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { - create_resolv(go->dnsaddr[0], go->dnsaddr[1]); - } - - /* - * Check that the peer is allowed to use the IP address it wants. - */ - if (!auth_ip_addr(f->unit, ho->hisaddr)) { - error("Peer is not authorized to use remote address %I", ho->hisaddr); - ipcp_close(f->unit, "Unauthorized remote IP address"); - return; - } - - /* set tcp compression */ - sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); - - /* - * If we are doing dial-on-demand, the interface is already - * configured, so we put out any saved-up packets, then set the - * interface to pass IP packets. - */ - if (demand) { - if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { - ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); - if (go->ouraddr != wo->ouraddr) { - warn("Local IP address changed to %I", go->ouraddr); - wo->ouraddr = go->ouraddr; - } - if (ho->hisaddr != wo->hisaddr) { - warn("Remote IP address changed to %I", ho->hisaddr); - wo->hisaddr = ho->hisaddr; - } - - /* Set the interface to the new addresses */ - mask = GetMask(go->ouraddr); - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - if (debug) - warn("Interface configuration failed"); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) - default_route_set[f->unit] = 1; - - /* Make a proxy ARP entry if requested. */ - if (ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(f->unit, ho->hisaddr)) - proxy_arp_set[f->unit] = 1; - - } - demand_rexmit(PPP_IP); - sifnpmode(f->unit, PPP_IP, NPMODE_PASS); - - } else { - /* - * Set IP addresses and (if specified) netmask. - */ - mask = GetMask(go->ouraddr); - -#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - if (debug) - warn("Interface configuration failed"); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - - /* bring the interface up for IP */ - if (!sifup(f->unit)) { - if (debug) - warn("Interface failed to come up"); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - -#if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - if (debug) - warn("Interface configuration failed"); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - sifnpmode(f->unit, PPP_IP, NPMODE_PASS); - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) - default_route_set[f->unit] = 1; - - /* Make a proxy ARP entry if requested. */ - if (ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(f->unit, ho->hisaddr)) - proxy_arp_set[f->unit] = 1; - - ipcp_wantoptions[0].ouraddr = go->ouraddr; - - notice("local IP address %I", go->ouraddr); - notice("remote IP address %I", ho->hisaddr); - if (go->dnsaddr[0]) - notice("primary DNS address %I", go->dnsaddr[0]); - if (go->dnsaddr[1]) - notice("secondary DNS address %I", go->dnsaddr[1]); - } - - np_up(f->unit, PPP_IP); - ipcp_is_up = 1; - - if (ip_up_hook) - ip_up_hook(); -} - - -/* - * ipcp_down - IPCP has gone DOWN. - * - * Take the IP network interface down, clear its addresses - * and delete routes through it. - */ -static void -ipcp_down( - fsm *f) -{ - IPCPDEBUG(("ipcp: down")); - /* XXX a bit IPv4-centric here, we only need to get the stats - * before the interface is marked down. */ - update_link_stats(f->unit); - if (ip_down_hook) - ip_down_hook(); - if (ipcp_is_up) { - ipcp_is_up = 0; - np_down(f->unit, PPP_IP); - } - sifvjcomp(f->unit, 0, 0, 0); - - /* - * If we are doing dial-on-demand, set the interface - * to queue up outgoing packets (for now). - */ - if (demand) { - sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE); - } else { - sifnpmode(f->unit, PPP_IP, NPMODE_DROP); - sifdown(f->unit); - ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, - ipcp_hisoptions[f->unit].hisaddr); - } -} - - -/* - * ipcp_clear_addrs() - clear the interface addresses, routes, - * proxy arp entries, etc. - */ -static void -ipcp_clear_addrs( - int unit, - uint32_t ouraddr, /* local address */ - uint32_t hisaddr /* remote address */) -{ - if (proxy_arp_set[unit]) { - cifproxyarp(unit, hisaddr); - proxy_arp_set[unit] = 0; - } - if (default_route_set[unit]) { - cifdefaultroute(unit, ouraddr, hisaddr); - default_route_set[unit] = 0; - } - cifaddr(unit, ouraddr, hisaddr); -} - - -/* - * ipcp_finished - possibly shut down the lower layers. - */ -static void -ipcp_finished( - fsm *f) -{ - np_finished(f->unit, PPP_IP); -} - -/* - * create_resolv - create the replacement resolv.conf file - */ -static void -create_resolv( - uint32_t peerdns1, uint32_t peerdns2) -{ - /* initialize values */ - rtems_bsdnet_nameserver_count = 0; - - /* check to see if primary was specified */ - if ( peerdns1 ) { - rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count].s_addr = peerdns1; - rtems_bsdnet_nameserver_count++; - } - - /* check to see if secondary was specified */ - if ( peerdns2 ) { - rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count].s_addr = peerdns2; - rtems_bsdnet_nameserver_count++; - } - - /* initialize resolver */ - __res_init(); -} - -/* - * ipcp_printpkt - print the contents of an IPCP packet. - */ -static char *ipcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int -ipcp_printpkt( - u_char *p, - int plen, - void (*printer)(void *, char *, ...), - void *arg) -{ - int code, id, len, olen; - u_char *pstart, *optend; - u_short cishort; - uint32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *)) - printer(arg, " %s", ipcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_ADDRS: - if (olen == CILEN_ADDRS) { - p += 2; - GETLONG(cilong, p); - printer(arg, "addrs %I", htonl(cilong)); - GETLONG(cilong, p); - printer(arg, " %I", htonl(cilong)); - } - break; - case CI_COMPRESSTYPE: - if (olen >= CILEN_COMPRESS) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "compress "); - switch (cishort) { - case IPCP_VJ_COMP: - printer(arg, "VJ"); - break; - case IPCP_VJ_COMP_OLD: - printer(arg, "old-VJ"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_ADDR: - if (olen == CILEN_ADDR) { - p += 2; - GETLONG(cilong, p); - printer(arg, "addr %I", htonl(cilong)); - } - break; - case CI_MS_DNS1: - case CI_MS_DNS2: - p += 2; - GETLONG(cilong, p); - printer(arg, "ms-dns%d %I", code - CI_MS_DNS1 + 1, - htonl(cilong)); - break; - case CI_MS_WINS1: - case CI_MS_WINS2: - p += 2; - GETLONG(cilong, p); - printer(arg, "ms-wins %I", htonl(cilong)); - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} - -/* - * ip_active_pkt - see if this IP packet is worth bringing the link up for. - * We don't bring the link up for IP fragments or for TCP FIN packets - * with no data. - */ -#define IP_HDRLEN 20 /* bytes */ -#define IP_OFFMASK 0x1fff -#define IPPROTO_TCP 6 -#define TCP_HDRLEN 20 -#define TH_FIN 0x01 - -/* - * We use these macros because the IP header may be at an odd address, - * and some compilers might use word loads to get th_off or ip_hl. - */ - -#define net_short(x) (((x)[0] << 8) + (x)[1]) -#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) -#define get_ipoff(x) net_short((unsigned char *)(x) + 6) -#define get_ipproto(x) (((unsigned char *)(x))[9]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - -static int -ip_active_pkt( - u_char *pkt, - int len) -{ - u_char *tcp; - int hlen; - - len -= PPP_HDRLEN; - pkt += PPP_HDRLEN; - if (len < IP_HDRLEN) - return 0; - if ((get_ipoff(pkt) & IP_OFFMASK) != 0) - return 0; - if (get_ipproto(pkt) != IPPROTO_TCP) - return 1; - hlen = get_iphl(pkt) * 4; - if (len < hlen + TCP_HDRLEN) - return 0; - tcp = pkt + hlen; - if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) - return 0; - return 1; -} diff --git a/cpukit/pppd/ipcp.h b/cpukit/pppd/ipcp.h deleted file mode 100644 index e841cf8b22..0000000000 --- a/cpukit/pppd/ipcp.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * ipcp.h - IP Control Protocol definitions. - * - * 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. - * - * $Id$ - */ - -/* - * Options. - */ -#define CI_ADDRS 1 /* IP Addresses */ -#define CI_COMPRESSTYPE 2 /* Compression Type */ -#define CI_ADDR 3 - -#define CI_MS_DNS1 129 /* Primary DNS value */ -#define CI_MS_WINS1 130 /* Primary WINS value */ -#define CI_MS_DNS2 131 /* Secondary DNS value */ -#define CI_MS_WINS2 132 /* Secondary WINS value */ - -#define MAX_STATES 16 /* from slcompress.h */ - -#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ -#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ -#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ - /* maxslot and slot number compression) */ - -#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/ -#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ - /* compression option*/ - -typedef struct ipcp_options { - bool neg_addr; /* Negotiate IP Address? */ - bool old_addrs; /* Use old (IP-Addresses) option? */ - bool req_addr; /* Ask peer to send IP address? */ - bool default_route; /* Assign default route through interface? */ - bool proxy_arp; /* Make proxy ARP entry for peer? */ - bool neg_vj; /* Van Jacobson Compression? */ - bool old_vj; /* use old (short) form of VJ option? */ - bool accept_local; /* accept peer's value for ouraddr */ - bool accept_remote; /* accept peer's value for hisaddr */ - bool req_dns1; /* Ask peer to send primary DNS address? */ - bool req_dns2; /* Ask peer to send secondary DNS address? */ - int vj_protocol; /* protocol value to use in VJ option */ - int maxslotindex; /* values for RFC1332 VJ compression neg. */ - bool cflag; - uint32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ - uint32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ - uint32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ -} ipcp_options; - -extern fsm ipcp_fsm[]; -extern ipcp_options ipcp_wantoptions[]; -extern ipcp_options ipcp_gotoptions[]; -extern ipcp_options ipcp_allowoptions[]; -extern ipcp_options ipcp_hisoptions[]; - -char *ip_ntoa(uint32_t); - -extern struct protent ipcp_protent; diff --git a/cpukit/pppd/lcp.c b/cpukit/pppd/lcp.c deleted file mode 100644 index e09e8fbfd5..0000000000 --- a/cpukit/pppd/lcp.c +++ /dev/null @@ -1,1949 +0,0 @@ -/* - * lcp.c - PPP Link Control Protocol. - * - * 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. - */ - -/* - * TODO: - */ - -#include -#include -#include - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" -#include "chap.h" -#include "magic.h" - -/* - * LCP-related command-line options. - */ -static int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ -static int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ -static bool lax_recv = false; /* accept control chars in asyncmap */ - -static int setescape(char **); - -static option_t lcp_option_list[] = { - /* LCP options */ - { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, - "Disable address/control compression", - OPT_A2COPY, &lcp_allowoptions[0].neg_accompression, 0, 0 }, - { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression, - "Disable address/control compression", - OPT_A2COPY, &lcp_allowoptions[0].neg_accompression, 0, 0 }, - { "default-asyncmap", o_bool, &lcp_wantoptions[0].neg_asyncmap, - "Disable asyncmap negotiation", - OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap, 0, 0 }, - { "-am", o_bool, &lcp_wantoptions[0].neg_asyncmap, - "Disable asyncmap negotiation", - OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap, 0, 0 }, - { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, - "Set asyncmap (for received packets)", - OPT_OR, &lcp_wantoptions[0].neg_asyncmap, 0, 0 }, - { "-as", o_uint32, &lcp_wantoptions[0].asyncmap, - "Set asyncmap (for received packets)", - OPT_OR, &lcp_wantoptions[0].neg_asyncmap, 0, 0 }, - { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, - "Disable magic number negotiation (looped-back line detection)", - OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber, 0, 0 }, - { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, - "Disable magic number negotiation (looped-back line detection)", - OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber, 0, 0 }, - { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru, - "Disable MRU negotiation (use default 1500)", - OPT_A2COPY, &lcp_allowoptions[0].neg_mru, 0, 0 }, - { "-mru", o_bool, &lcp_wantoptions[0].neg_mru, - "Disable MRU negotiation (use default 1500)", - OPT_A2COPY, &lcp_allowoptions[0].neg_mru, 0, 0 }, - { "mru", o_int, &lcp_wantoptions[0].mru, - "Set MRU (maximum received packet size) for negotiation", - 0, &lcp_wantoptions[0].neg_mru, 0, 0 }, - { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression, - "Disable protocol field compression", - OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression, 0, 0 }, - { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression, - "Disable protocol field compression", - OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression, 0, 0 }, - { "-p", o_bool, &lcp_wantoptions[0].passive, - "Set passive mode", 1, NULL, 0, 0 }, - { "passive", o_bool, &lcp_wantoptions[0].passive, - "Set passive mode", 1, NULL, 0, 0 }, - { "silent", o_bool, &lcp_wantoptions[0].silent, - "Set silent mode", 1, NULL, 0, 0 }, - { "escape", o_special, setescape, - "List of character codes to escape on transmission", 0, NULL, 0, 0 }, - { "lcp-echo-failure", o_int, &lcp_echo_fails, - "Set number of consecutive echo failures to indicate link failure", 0, NULL, 0, 0 }, - { "lcp-echo-interval", o_int, &lcp_echo_interval, - "Set time in seconds between LCP echo requests", 0, NULL, 0, 0 }, - { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, - "Set time in seconds between LCP retransmissions", 0, NULL, 0, 0 }, - { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, - "Set maximum number of LCP terminate-request transmissions", 0, NULL, 0, 0 }, - { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits, - "Set maximum number of LCP configure-request transmissions", 0, NULL, 0, 0 }, - { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, - "Set limit on number of LCP configure-naks", 0, NULL, 0, 0 }, - { "receive-all", o_bool, &lax_recv, - "Accept all received control characters", 1, NULL, 0, 0 }, - {NULL, 0, NULL, NULL, 0, NULL, 0, 0} -}; - -/* global vars */ -fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ -lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ -lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ -uint32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */ - -static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */ -static int lcp_echo_number = 0; /* ID number of next echo frame */ -static int lcp_echo_timer_running = 0; /* set if a timer is running */ - -static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void lcp_resetci(fsm *); /* Reset our CI */ -static int lcp_cilen(fsm *); /* Return length of our CI */ -static void lcp_addci(fsm *, u_char *, int *); /* Add our CI to pkt */ -static int lcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */ -static int lcp_nakci(fsm *, u_char *, int); /* Peer nak'd our CI */ -static int lcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */ -static int lcp_reqci(fsm *, u_char *, int *, int); /* Rcv peer CI */ -static void lcp_up(fsm *); /* We're UP */ -static void lcp_down(fsm *); /* We're DOWN */ -static void lcp_starting(fsm *); /* We need lower layer up */ -static void lcp_finished(fsm *); /* We need lower layer down */ -static int lcp_extcode(fsm *, int, int, u_char *, int); -static void lcp_rprotrej(fsm *, u_char *, int); - -/* - * routines to send LCP echos to peer - */ - -static void lcp_echo_lowerup(int); -static void lcp_echo_lowerdown(int); -static void LcpEchoTimeout(void *); -static void lcp_received_echo_reply(fsm *, int, u_char *, int); -static void LcpSendEchoRequest(fsm *); -static void LcpLinkFailure(fsm *); -static void LcpEchoCheck(fsm *); - -static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ - lcp_resetci, /* Reset our Configuration Information */ - lcp_cilen, /* Length of our Configuration Information */ - lcp_addci, /* Add our Configuration Information */ - lcp_ackci, /* ACK our Configuration Information */ - lcp_nakci, /* NAK our Configuration Information */ - lcp_rejci, /* Reject our Configuration Information */ - lcp_reqci, /* Request peer's Configuration Information */ - lcp_up, /* Called when fsm reaches OPENED state */ - lcp_down, /* Called when fsm leaves OPENED state */ - lcp_starting, /* Called when we want the lower layer up */ - lcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - lcp_extcode, /* Called to handle LCP-specific codes */ - "LCP" /* String name of protocol */ -}; - -/* - * Protocol entry points. - * Some of these are called directly. - */ - -static void lcp_init(int); -static void lcp_input(int, u_char *, int); -static void lcp_protrej(int); -static int lcp_printpkt(u_char *, int, - void (*)(void *, char *, ...), void *); - -struct protent lcp_protent = { - PPP_LCP, - lcp_init, - lcp_input, - lcp_protrej, - lcp_lowerup, - lcp_lowerdown, - lcp_open, - lcp_close, - lcp_printpkt, - NULL, - 1, - "LCP", - NULL, - lcp_option_list, - NULL, - NULL, - NULL -}; - -int lcp_loopbackfail = DEFLOOPBACKFAIL; - -/* - * Length of each type of configuration option (in octets) - */ -#define CILEN_VOID 2 -#define CILEN_CHAR 3 -#define CILEN_SHORT 4 /* CILEN_VOID + 2 */ -#define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ -#define CILEN_LONG 6 /* CILEN_VOID + 4 */ -#define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ -#define CILEN_CBCP 3 - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - - -/* - * setescape - add chars to the set we escape on transmission. - */ -static int -setescape( - char **argv) -{ - int n, ret; - char *p, *endp; - - p = *argv; - ret = 1; - while (*p) { - n = strtol(p, &endp, 16); - if (p == endp) { - option_error("escape parameter contains invalid hex number '%s'", - p); - return 0; - } - p = endp; - if (n < 0 || n == 0x5E || n > 0xFF) { - option_error("can't escape character 0x%x", n); - ret = 0; - } else - xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); - while (*p == ',' || *p == ' ') - ++p; - } - return ret; -} - -/* - * lcp_init - Initialize LCP. - */ -static void -lcp_init( - int unit) -{ - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - - f->unit = unit; - f->protocol = PPP_LCP; - f->callbacks = &lcp_callbacks; - - fsm_init(f); - - wo->passive = 0; - wo->silent = 0; - wo->restart = 0; /* Set to 1 in kernels or multi-line - implementations */ - wo->neg_mru = 1; - wo->mru = DEFMRU; - wo->neg_asyncmap = 1; - wo->asyncmap = 0; - wo->neg_chap = 0; /* Set to 1 on server */ - wo->neg_upap = 0; /* Set to 1 on server */ - wo->chap_mdtype = CHAP_DIGEST_MD5; - wo->neg_magicnumber = 1; - wo->neg_pcompression = 1; - wo->neg_accompression = 1; - wo->neg_lqr = 0; /* no LQR implementation yet */ - wo->neg_cbcp = 0; - - ao->neg_mru = 1; - ao->mru = MAXMRU; - ao->neg_asyncmap = 1; - ao->asyncmap = 0; - ao->neg_chap = 1; - ao->chap_mdtype = CHAP_DIGEST_MD5; - ao->neg_upap = 1; - ao->neg_magicnumber = 1; - ao->neg_pcompression = 1; - ao->neg_accompression = 1; - ao->neg_lqr = 0; /* no LQR implementation yet */ -#ifdef CBCP_SUPPORT - ao->neg_cbcp = 1; -#else - ao->neg_cbcp = 0; -#endif - - memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); - xmit_accm[unit][3] = 0x60000000; -} - - -/* - * lcp_open - LCP is allowed to come up. - */ -void -lcp_open( - int unit) -{ - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - - f->flags = 0; - if (wo->passive) - f->flags |= OPT_PASSIVE; - if (wo->silent) - f->flags |= OPT_SILENT; - fsm_open(f); -} - - -/* - * 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); -} - - -/* - * lcp_lowerup - The lower layer is up. - */ -void -lcp_lowerup( - int unit) -{ - lcp_options *wo = &lcp_wantoptions[unit]; - - /* - * Don't use A/C or protocol compression on transmission, - * but accept A/C and protocol compressed packets - * if we are going to ask for A/C and protocol compression. - */ - ppp_set_xaccm(unit, xmit_accm[unit]); - ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), - wo->neg_pcompression, wo->neg_accompression); - peer_mru[unit] = PPP_MRU; - lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0]; - - fsm_lowerup(&lcp_fsm[unit]); -} - - -/* - * lcp_lowerdown - The lower layer is down. - */ -void -lcp_lowerdown( - int unit) -{ - fsm_lowerdown(&lcp_fsm[unit]); -} - - -/* - * lcp_input - Input LCP packet. - */ -static void -lcp_input( - int unit, - u_char *p, - int len) -{ - fsm *f = &lcp_fsm[unit]; - - fsm_input(f, p, len); -} - - -/* - * lcp_extcode - Handle a LCP-specific code. - */ -static int -lcp_extcode( - fsm *f, - int code, int id, - u_char *inp, - int len) -{ - u_char *magp; - - switch( code ){ - case PROTREJ: - lcp_rprotrej(f, inp, len); - break; - - case ECHOREQ: - if (f->state != OPENED) - break; - magp = inp; - PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); - fsm_sdata(f, ECHOREP, id, inp, len); - break; - - case ECHOREP: - lcp_received_echo_reply(f, id, inp, len); - break; - - case DISCREQ: - break; - - default: - return 0; - } - return 1; -} - - -/* - * lcp_rprotrej - Receive an Protocol-Reject. - * - * Figure out which protocol is rejected and inform it. - */ -static void -lcp_rprotrej( - fsm *f, - u_char *inp, - int len) -{ - int i; - struct protent *protp; - u_short prot; - - if (len < 2) { - LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); - return; - } - - GETSHORT(prot, inp); - - /* - * Protocol-Reject packets received in any state other than the LCP - * OPENED state SHOULD be silently discarded. - */ - if( f->state != OPENED ){ - LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state)); - return; - } - - /* - * Upcall the proper Protocol-Reject routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol == prot && protp->enabled_flag) { - (*protp->protrej)(f->unit); - return; - } - - warn("Protocol-Reject for unsupported protocol 0x%x", prot); -} - - -/* - * lcp_protrej - A Protocol-Reject was received. - */ -/*ARGSUSED*/ -static void -lcp_protrej( - int unit) -{ - /* - * Can't reject LCP! - */ - error("Received Protocol-Reject for LCP!"); - fsm_protreject(&lcp_fsm[unit]); -} - - -/* - * lcp_sprotrej - Send a Protocol-Reject for some protocol. - */ -void -lcp_sprotrej( - int unit, - u_char *p, - int len) -{ - /* - * Send back the protocol and the information field of the - * rejected packet. We only get here if LCP is in the OPENED state. - */ - p += 2; - len -= 2; - - fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, - p, len); -} - - -/* - * lcp_resetci - Reset our CI. - */ -static void -lcp_resetci( - fsm *f) -{ - lcp_wantoptions[f->unit].magicnumber = magic(); - lcp_wantoptions[f->unit].numloops = 0; - lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit]; - peer_mru[f->unit] = PPP_MRU; - auth_reset(f->unit); -} - - -/* - * lcp_cilen - Return length of our CI. - */ -static int -lcp_cilen( - fsm *f) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - -#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) -#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) -#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) -#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) -#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) -#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) - /* - * NB: we only ask for one of CHAP and UPAP, even if we will - * accept either. - */ - return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) + - LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + - LENCICHAP(go->neg_chap) + - LENCISHORT(!go->neg_chap && go->neg_upap) + - LENCILQR(go->neg_lqr) + - LENCICBCP(go->neg_cbcp) + - LENCILONG(go->neg_magicnumber) + - LENCIVOID(go->neg_pcompression) + - LENCIVOID(go->neg_accompression)); -} - - -/* - * lcp_addci - Add our desired CIs to a packet. - */ -static void -lcp_addci( - fsm *f, - u_char *ucp, - int *lenp) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char *start_ucp = ucp; - -#define ADDCIVOID(opt, neg) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_VOID, ucp); \ - } -#define ADDCISHORT(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_SHORT, ucp); \ - PUTSHORT(val, ucp); \ - } -#define ADDCICHAP(opt, neg, val, digest) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAP, ucp); \ - PUTSHORT(val, ucp); \ - PUTCHAR(digest, ucp); \ - } -#define ADDCILONG(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LONG, ucp); \ - PUTLONG(val, ucp); \ - } -#define ADDCILQR(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LQR, ucp); \ - PUTSHORT(PPP_LQR, ucp); \ - PUTLONG(val, ucp); \ - } -#define ADDCICHAR(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR, ucp); \ - PUTCHAR(val, ucp); \ - } - - ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); - ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); - ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); - ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); - ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); - ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - - if (ucp - start_ucp != *lenp) { - /* this should never happen, because peer_mtu should be 1500 */ - error("Bug in lcp_addci: wrong length"); - } -} - - -/* - * lcp_ackci - Ack our CIs. - * This should not modify any state if the Ack is bad. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -lcp_ackci( - fsm *f, - u_char *p, - int len) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char cilen, citype, cichar; - u_short cishort; - uint32_t cilong; - - /* - * CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define ACKCIVOID(opt, neg) \ - if (neg) { \ - if ((len -= CILEN_VOID) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || \ - citype != opt) \ - goto bad; \ - } -#define ACKCISHORT(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_SHORT) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_SHORT || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - } -#define ACKCICHAR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_CHAR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAR || \ - citype != opt) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != val) \ - goto bad; \ - } -#define ACKCICHAP(opt, neg, val, digest) \ - if (neg) { \ - if ((len -= CILEN_CHAP) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAP || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != digest) \ - goto bad; \ - } -#define ACKCILONG(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LONG) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LONG || \ - citype != opt) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } -#define ACKCILQR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LQR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LQR || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != PPP_LQR) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } - - ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); - ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); - ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); - ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); - ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); - ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); -bad: - LCPDEBUG(("lcp_acki: received bad Ack!")); - return (0); -} - - -/* - * lcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if LCP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int -lcp_nakci( - fsm *f, - u_char *p, - int len) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *wo = &lcp_wantoptions[f->unit]; - u_char citype, cichar, *next; - u_short cishort; - uint32_t cilong; - lcp_options no; /* options we've seen Naks for */ - lcp_options try; /* options to request next time */ - int looped_back = 0; - int cilen; - - BZERO(&no, sizeof(no)); - try = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIVOID(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - no.neg = 1; \ - code \ - } -#define NAKCICHAP(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#define NAKCICHAR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAR && \ - p[1] == CILEN_CHAR && \ - p[0] == opt) { \ - len -= CILEN_CHAR; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#define NAKCISHORT(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#define NAKCILONG(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } -#define NAKCILQR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } - - /* - * We don't care if they want to send us smaller packets than - * we want. Therefore, accept any MRU less than what we asked for, - * but then ignore the new value when setting the MRU in the kernel. - * If they send us a bigger MRU than what we asked, accept it, up to - * the limit of the default MRU we'd get if we didn't negotiate. - */ - if (go->neg_mru && go->mru != DEFMRU) { - NAKCISHORT(CI_MRU, neg_mru, - if (cishort <= wo->mru || cishort <= DEFMRU) - try.mru = cishort; - ); - } - - /* - * Add any characters they want to our (receive-side) asyncmap. - */ - if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { - NAKCILONG(CI_ASYNCMAP, neg_asyncmap, - try.asyncmap = go->asyncmap | cilong; - ); - } - - /* - * If they've nak'd our authentication-protocol, check whether - * they are proposing a different protocol, or a different - * hash algorithm for CHAP. - */ - if ((go->neg_chap || go->neg_upap) - && len >= CILEN_SHORT - && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { - cilen = p[1]; - len -= cilen; - no.neg_chap = go->neg_chap; - no.neg_upap = go->neg_upap; - INCPTR(2, p); - GETSHORT(cishort, p); - if (cishort == PPP_PAP && cilen == CILEN_SHORT) { - /* - * If we were asking for CHAP, they obviously don't want to do it. - * If we weren't asking for CHAP, then we were asking for PAP, - * in which case this Nak is bad. - */ - if (!go->neg_chap) - goto bad; - try.neg_chap = 0; - - } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { - GETCHAR(cichar, p); - if (go->neg_chap) { - /* - * We were asking for CHAP/MD5; they must want a different - * algorithm. If they can't do MD5, we can ask for M$-CHAP - * if we support it, otherwise we'll have to stop - * asking for CHAP. - */ - if (cichar != go->chap_mdtype) { -#ifdef CHAPMS - if (cichar == CHAP_MICROSOFT) - go->chap_mdtype = CHAP_MICROSOFT; - else -#endif /* CHAPMS */ - try.neg_chap = 0; - } - } else { - /* - * Stop asking for PAP if we were asking for it. - */ - try.neg_upap = 0; - } - - } else { - /* - * We don't recognize what they're suggesting. - * Stop asking for what we were asking for. - */ - if (go->neg_chap) - try.neg_chap = 0; - else - try.neg_upap = 0; - p += cilen - CILEN_SHORT; - } - } - - /* - * If they can't cope with our link quality protocol, we'll have - * to stop asking for LQR. We haven't got any other protocol. - * If they Nak the reporting period, take their value XXX ? - */ - NAKCILQR(CI_QUALITY, neg_lqr, - if (cishort != PPP_LQR) - try.neg_lqr = 0; - else - try.lqr_period = cilong; - ); - - /* - * Only implementing CBCP...not the rest of the callback options - */ - NAKCICHAR(CI_CALLBACK, neg_cbcp, - try.neg_cbcp = 0; - ); - - /* - * Check for a looped-back line. - */ - NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, - try.magicnumber = magic(); - looped_back = 1; - ); - - /* - * Peer shouldn't send Nak for protocol compression or - * address/control compression requests; they should send - * a Reject instead. If they send a Nak, treat it as a Reject. - */ - NAKCIVOID(CI_PCOMPRESSION, neg_pcompression, - try.neg_pcompression = 0; - ); - NAKCIVOID(CI_ACCOMPRESSION, neg_accompression, - try.neg_accompression = 0; - ); - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If we see an option that we requested, or one we've already seen - * in this packet, then this packet is bad. - * If we wanted to respond by starting to negotiate on the requested - * option(s), we could, but we don't, because except for the - * authentication type and quality protocol, if we are not negotiating - * an option, it is because we were told not to. - * For the authentication type, the Nak from the peer means - * `let me authenticate myself with you' which is a bit pointless. - * For the quality protocol, the Nak means `ask me to send you quality - * reports', but if we didn't ask for them, we don't want them. - * An option we don't recognize represents the peer asking to - * negotiate some option we don't support, so ignore it. - */ - while (len > CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if (cilen < CILEN_VOID || (len -= cilen) < 0) - goto bad; - next = p + cilen - 2; - - switch (citype) { - case CI_MRU: - if ((go->neg_mru && go->mru != DEFMRU) - || no.neg_mru || cilen != CILEN_SHORT) - goto bad; - GETSHORT(cishort, p); - if (cishort < DEFMRU) - try.mru = cishort; - break; - case CI_ASYNCMAP: - if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) - || no.neg_asyncmap || cilen != CILEN_LONG) - goto bad; - break; - case CI_AUTHTYPE: - if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) - goto bad; - break; - case CI_MAGICNUMBER: - if (go->neg_magicnumber || no.neg_magicnumber || - cilen != CILEN_LONG) - goto bad; - break; - case CI_PCOMPRESSION: - if (go->neg_pcompression || no.neg_pcompression - || cilen != CILEN_VOID) - goto bad; - break; - case CI_ACCOMPRESSION: - if (go->neg_accompression || no.neg_accompression - || cilen != CILEN_VOID) - goto bad; - break; - case CI_QUALITY: - if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) - goto bad; - break; - } - p = next; - } - - /* - * OK, the Nak is good. Now we can update state. - * If there are any options left we ignore them. - */ - if (f->state != OPENED) { - if (looped_back) { - if (++try.numloops >= lcp_loopbackfail) { - notice("Serial line is looped back."); - lcp_close(f->unit, "Loopback detected"); - pppd_status = EXIT_LOOPBACK; - } - } else - try.numloops = 0; - *go = try; - } - - return 1; - -bad: - LCPDEBUG(("lcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * lcp_rejci - Peer has Rejected some of our CIs. - * This should not modify any state if the Reject is bad - * or if LCP is in the OPENED state. - * - * Returns: - * 0 - Reject was bad. - * 1 - Reject was good. - */ -static int -lcp_rejci( - fsm *f, - u_char *p, - int len) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char cichar; - u_short cishort; - uint32_t cilong; - lcp_options try; /* options to request next time */ - - try = *go; - - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIVOID(opt, neg) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - try.neg = 0; \ - } -#define REJCISHORT(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - try.neg = 0; \ - } -#define REJCICHAP(opt, neg, val, digest) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if (cishort != val || cichar != digest) \ - goto bad; \ - try.neg = 0; \ - try.neg_upap = 0; \ - } -#define REJCILONG(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cilong != val) \ - goto bad; \ - try.neg = 0; \ - } -#define REJCILQR(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cishort != PPP_LQR || cilong != val) \ - goto bad; \ - try.neg = 0; \ - } -#define REJCICBCP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CBCP && \ - p[1] == CILEN_CBCP && \ - p[0] == opt) { \ - len -= CILEN_CBCP; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if (cichar != val) \ - goto bad; \ - try.neg = 0; \ - } - - REJCISHORT(CI_MRU, neg_mru, go->mru); - REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); - REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype); - if (!go->neg_chap) { - REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); - } - REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); - REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); - REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); - REJCIVOID(CI_PCOMPRESSION, neg_pcompression); - REJCIVOID(CI_ACCOMPRESSION, neg_accompression); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != OPENED) - *go = try; - return 1; - -bad: - LCPDEBUG(("lcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * lcp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - */ -static int -lcp_reqci( - fsm *f, - u_char *inp, /* Requested CIs */ - int *lenp, /* Length of requested CIs */ - int reject_if_disagree) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *ho = &lcp_hisoptions[f->unit]; - lcp_options *ao = &lcp_allowoptions[f->unit]; - u_char *cip, *next; /* Pointer to current and next CIs */ - int cilen, citype, cichar; /* Parsed len, type, char value */ - u_short cishort; /* Parsed short value */ - uint32_t cilong; /* Parse long value */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *rejp; /* Pointer to next char in reject frame */ - u_char *nakp; /* Pointer to next char in Nak frame */ - int l = *lenp; /* Length left */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - nakp = nak_buffer; - rejp = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - LCPDEBUG(("lcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - citype = 0; - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_MRU: - if (!ao->neg_mru || /* Allow option? */ - cilen != CILEN_SHORT) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETSHORT(cishort, p); /* Parse MRU */ - - /* - * He must be able to receive at least our minimum. - * No need to check a maximum. If he sends a large number, - * we'll just ignore it. - */ - if (cishort < MINMRU) { - orc = CONFNAK; /* Nak CI */ - PUTCHAR(CI_MRU, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(MINMRU, nakp); /* Give him a hint */ - break; - } - ho->neg_mru = 1; /* Remember he sent MRU */ - ho->mru = cishort; /* And remember value */ - break; - - case CI_ASYNCMAP: - if (!ao->neg_asyncmap || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * Asyncmap must have set at least the bits - * which are set in lcp_allowoptions[unit].asyncmap. - */ - if ((ao->asyncmap & ~cilong) != 0) { - orc = CONFNAK; - PUTCHAR(CI_ASYNCMAP, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(ao->asyncmap | cilong, nakp); - break; - } - ho->neg_asyncmap = 1; - ho->asyncmap = cilong; - break; - - case CI_AUTHTYPE: - if (cilen < CILEN_SHORT || - !(ao->neg_upap || ao->neg_chap)) { - /* - * Reject the option if we're not willing to authenticate. - */ - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - /* - * Authtype must be PAP or CHAP. - * - * Note: if both ao->neg_upap and ao->neg_chap are set, - * and the peer sends a Configure-Request with two - * authenticate-protocol requests, one for CHAP and one - * for UPAP, then we will reject the second request. - * Whether we end up doing CHAP or UPAP depends then on - * the ordering of the CIs in the peer's Configure-Request. - */ - - if (cishort == PPP_PAP) { - if (ho->neg_chap || /* we've already accepted CHAP */ - cilen != CILEN_SHORT) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_upap) { /* we don't want to do PAP */ - orc = CONFNAK; /* NAK it and suggest CHAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - /* XXX if we can do CHAP_MICROSOFT as well, we should - probably put in another option saying so */ - break; - } - ho->neg_upap = 1; - break; - } - if (cishort == PPP_CHAP) { - if (ho->neg_upap || /* we've already accepted PAP */ - cilen != CILEN_CHAP) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_chap) { /* we don't want to do CHAP */ - orc = CONFNAK; /* NAK it and suggest PAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - break; - } - GETCHAR(cichar, p); /* get digest type*/ - if (cichar != CHAP_DIGEST_MD5 -#ifdef CHAPMS - && cichar != CHAP_MICROSOFT -#endif - ) { - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - break; - } - ho->chap_mdtype = cichar; /* save md type */ - ho->neg_chap = 1; - break; - } - - /* - * We don't recognize the protocol they're asking for. - * Nak it with something we're willing to do. - * (At this point we know ao->neg_upap || ao->neg_chap.) - */ - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - } else { - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - } - break; - - case CI_QUALITY: - if (!ao->neg_lqr || - cilen != CILEN_LQR) { - orc = CONFREJ; - break; - } - - GETSHORT(cishort, p); - GETLONG(cilong, p); - - /* - * Check the protocol and the reporting period. - * XXX When should we Nak this, and what with? - */ - if (cishort != PPP_LQR) { - orc = CONFNAK; - PUTCHAR(CI_QUALITY, nakp); - PUTCHAR(CILEN_LQR, nakp); - PUTSHORT(PPP_LQR, nakp); - PUTLONG(ao->lqr_period, nakp); - break; - } - break; - - case CI_MAGICNUMBER: - if (!(ao->neg_magicnumber || go->neg_magicnumber) || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * He must have a different magic number. - */ - if (go->neg_magicnumber && - cilong == go->magicnumber) { - cilong = magic(); /* Don't put magic() inside macro! */ - orc = CONFNAK; - PUTCHAR(CI_MAGICNUMBER, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(cilong, nakp); - break; - } - ho->neg_magicnumber = 1; - ho->magicnumber = cilong; - break; - - - case CI_PCOMPRESSION: - if (!ao->neg_pcompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_pcompression = 1; - break; - - case CI_ACCOMPRESSION: - if (!ao->neg_accompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_accompression = 1; - break; - - default: - LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype)); - orc = CONFREJ; - break; - } - -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree /* Getting fed up with sending NAKs? */ - && citype != CI_MAGICNUMBER) { - orc = CONFREJ; /* Get tough if so */ - } else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - rc = CONFNAK; - } - } - if (orc == CONFREJ) { /* Reject this CI */ - rc = CONFREJ; - if (cip != rejp) /* Need to move rejected CI? */ - BCOPY(cip, rejp, cilen); /* Move it */ - INCPTR(cilen, rejp); /* Update output pointer */ - } - } - - /* - * If we wanted to send additional NAKs (for unsent CIs), the - * code would go here. The extra NAKs would go at *nakp. - * At present there are no cases where we want to ask the - * peer to negotiate an option. - */ - - switch (rc) { - case CONFACK: - *lenp = next - inp; - break; - case CONFNAK: - /* - * Copy the Nak'd options from the nak_buffer to the caller's buffer. - */ - *lenp = nakp - nak_buffer; - BCOPY(nak_buffer, inp, *lenp); - break; - case CONFREJ: - *lenp = rejp - inp; - break; - } - - LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -/* - * lcp_up - LCP has come UP. - */ -static void -lcp_up( - fsm *f) -{ - lcp_options *wo = &lcp_wantoptions[f->unit]; - lcp_options *ho = &lcp_hisoptions[f->unit]; - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *ao = &lcp_allowoptions[f->unit]; - - if (!go->neg_magicnumber) - go->magicnumber = 0; - if (!ho->neg_magicnumber) - ho->magicnumber = 0; - - /* - * Set our MTU to the smaller of the MTU we wanted and - * the MRU our peer wanted. If we negotiated an MRU, - * set our MRU to the larger of value we wanted and - * the value we got in the negotiation. - */ - ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)), - (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), - ho->neg_pcompression, ho->neg_accompression); - ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU), - (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), - go->neg_pcompression, go->neg_accompression); - - if (ho->neg_mru) - peer_mru[f->unit] = ho->mru; - - lcp_echo_lowerup(f->unit); /* Enable echo messages */ - - link_established(f->unit); -} - - -/* - * lcp_down - LCP has gone DOWN. - * - * Alert other protocols. - */ -static void -lcp_down( - fsm *f) -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - - lcp_echo_lowerdown(f->unit); - - link_down(f->unit); - - ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(f->unit, PPP_MRU, - (go->neg_asyncmap? go->asyncmap: 0xffffffff), - go->neg_pcompression, go->neg_accompression); - peer_mru[f->unit] = PPP_MRU; -} - - -/* - * lcp_starting - LCP needs the lower layer up. - */ -static void -lcp_starting( - fsm *f) -{ - link_required(f->unit); -} - - -/* - * lcp_finished - LCP has finished with the lower layer. - */ -static void -lcp_finished( - fsm *f) -{ - link_terminated(f->unit); -} - - -/* - * lcp_printpkt - print the contents of an LCP packet. - */ -static char *lcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", "ProtRej", - "EchoReq", "EchoRep", "DiscReq" -}; - -static int -lcp_printpkt( - u_char *p, - int plen, - void (*printer)(void *, char *, ...), - void *arg) -{ - int code, id, len, olen; - u_char *pstart, *optend; - u_short cishort; - uint32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) - printer(arg, " %s", lcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_MRU: - if (olen == CILEN_SHORT) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "mru %d", cishort); - } - break; - case CI_ASYNCMAP: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "asyncmap 0x%x", cilong); - } - break; - case CI_AUTHTYPE: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "auth "); - GETSHORT(cishort, p); - switch (cishort) { - case PPP_PAP: - printer(arg, "pap"); - break; - case PPP_CHAP: - printer(arg, "chap"); - if (p < optend) { - switch (*p) { - case CHAP_DIGEST_MD5: - printer(arg, " MD5"); - ++p; - break; -#ifdef CHAPMS - case CHAP_MICROSOFT: - printer(arg, " m$oft"); - ++p; - break; -#endif - } - } - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_QUALITY: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "quality "); - GETSHORT(cishort, p); - switch (cishort) { - case PPP_LQR: - printer(arg, "lqr"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_CALLBACK: - if (olen >= CILEN_CHAR) { - p += 2; - printer(arg, "callback "); - GETCHAR(cishort, p); - switch (cishort) { - case CBCP_OPT: - printer(arg, "CBCP"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_MAGICNUMBER: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "magic 0x%x", cilong); - } - break; - case CI_PCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "pcomp"); - } - break; - case CI_ACCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "accomp"); - } - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - - case ECHOREQ: - case ECHOREP: - case DISCREQ: - if (len >= 4) { - GETLONG(cilong, p); - printer(arg, " magic=0x%x", cilong); - p += 4; - len -= 4; - } - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} - -/* - * Time to shut down the link because there is nothing out there. - */ - -static -void LcpLinkFailure ( - fsm *f) -{ - if (f->state == OPENED) { - info("No response to %d echo-requests", lcp_echos_pending); - notice("Serial link appears to be disconnected."); - lcp_close(f->unit, "Peer not responding"); - pppd_status = EXIT_PEER_DEAD; - } -} - -/* - * Timer expired for the LCP echo requests from this process. - */ - -static void -LcpEchoCheck ( - fsm *f) -{ - LcpSendEchoRequest (f); - if (f->state != OPENED) - return; - - /* - * Start the timer for the next interval. - */ - if (lcp_echo_timer_running) - warn("assertion lcp_echo_timer_running==0 failed"); - TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); - lcp_echo_timer_running = 1; -} - -/* - * LcpEchoTimeout - Timer expired on the LCP echo - */ - -static void -LcpEchoTimeout ( - void *arg) -{ - if (lcp_echo_timer_running != 0) { - lcp_echo_timer_running = 0; - LcpEchoCheck ((fsm *) arg); - } -} - -/* - * LcpEchoReply - LCP has received a reply to the echo - */ - -static void -lcp_received_echo_reply ( - fsm *f, - int id, - u_char *inp, - int len) -{ - uint32_t magic; - - /* Check the magic number - don't count replies from ourselves. */ - if (len < 4) { - dbglog("lcp: received short Echo-Reply, length %d", len); - return; - } - GETLONG(magic, inp); - if (lcp_gotoptions[f->unit].neg_magicnumber - && magic == lcp_gotoptions[f->unit].magicnumber) { - warn("appear to have received our own echo-reply!"); - return; - } - - /* Reset the number of outstanding echo frames */ - lcp_echos_pending = 0; -} - -/* - * LcpSendEchoRequest - Send an echo request frame to the peer - */ - -static void -LcpSendEchoRequest ( - fsm *f) -{ - uint32_t lcp_magic; - u_char pkt[4], *pktp; - - /* - * Detect the failure of the peer at this point. - */ - if (lcp_echo_fails != 0) { - if (lcp_echos_pending >= lcp_echo_fails) { - LcpLinkFailure(f); - lcp_echos_pending = 0; - } - } - - /* - * Make and send the echo request frame. - */ - if (f->state == OPENED) { - lcp_magic = lcp_gotoptions[f->unit].magicnumber; - pktp = pkt; - PUTLONG(lcp_magic, pktp); - fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt); - ++lcp_echos_pending; - } -} - -/* - * lcp_echo_lowerup - Start the timer for the LCP frame - */ - -static void -lcp_echo_lowerup ( - int unit) -{ - fsm *f = &lcp_fsm[unit]; - - /* Clear the parameters for generating echo frames */ - lcp_echos_pending = 0; - lcp_echo_number = 0; - lcp_echo_timer_running = 0; - - /* If a timeout interval is specified then start the timer */ - if (lcp_echo_interval != 0) - LcpEchoCheck (f); -} - -/* - * lcp_echo_lowerdown - Stop the timer for the LCP frame - */ - -static void -lcp_echo_lowerdown ( - int unit) -{ - fsm *f = &lcp_fsm[unit]; - - if (lcp_echo_timer_running != 0) { - UNTIMEOUT (LcpEchoTimeout, f); - lcp_echo_timer_running = 0; - } -} diff --git a/cpukit/pppd/lcp.h b/cpukit/pppd/lcp.h deleted file mode 100644 index 6231d270ae..0000000000 --- a/cpukit/pppd/lcp.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * lcp.h - Link Control Protocol definitions. - * - * 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. - * - * $Id$ - */ - -/* - * Options. - */ -#define CI_MRU 1 /* Maximum Receive Unit */ -#define CI_ASYNCMAP 2 /* Async Control Character Map */ -#define CI_AUTHTYPE 3 /* Authentication Type */ -#define CI_QUALITY 4 /* Quality Protocol */ -#define CI_MAGICNUMBER 5 /* Magic Number */ -#define CI_PCOMPRESSION 7 /* Protocol Field Compression */ -#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ -#define CI_CALLBACK 13 /* callback */ - -/* - * LCP-specific packet types. - */ -#define PROTREJ 8 /* Protocol Reject */ -#define ECHOREQ 9 /* Echo Request */ -#define ECHOREP 10 /* Echo Reply */ -#define DISCREQ 11 /* Discard Request */ -#define CBCP_OPT 6 /* Use callback control protocol */ - -/* - * The state of options is described by an lcp_options structure. - */ -typedef struct lcp_options { - bool passive; /* Don't die if we don't get a response */ - bool silent; /* Wait for the other end to start first */ - bool restart; /* Restart vs. exit after close */ - bool neg_mru; /* Negotiate the MRU? */ - bool neg_asyncmap; /* Negotiate the async map? */ - bool neg_upap; /* Ask for UPAP authentication? */ - bool neg_chap; /* Ask for CHAP authentication? */ - bool neg_magicnumber; /* Ask for magic number? */ - bool neg_pcompression; /* HDLC Protocol Field Compression? */ - bool neg_accompression; /* HDLC Address/Control Field Compression? */ - bool neg_lqr; /* Negotiate use of Link Quality Reports */ - bool neg_cbcp; /* Negotiate use of CBCP */ - int mru; /* Value of MRU */ - u_char chap_mdtype; /* which MD type (hashing algorithm) */ - uint32_t asyncmap; /* Value of async map */ - uint32_t magicnumber; - int numloops; /* Number of loops during magic number neg. */ - uint32_t lqr_period; /* Reporting period for LQR 1/100ths second */ -} lcp_options; - -extern fsm lcp_fsm[]; -extern lcp_options lcp_wantoptions[]; -extern lcp_options lcp_gotoptions[]; -extern lcp_options lcp_allowoptions[]; -extern lcp_options lcp_hisoptions[]; -extern uint32_t xmit_accm[][8]; - -#define DEFMRU 1500 /* Try for this */ -#define MINMRU 128 /* No MRUs below this */ -#define MAXMRU 16384 /* Normally limit MRU to this */ - -void lcp_open(int); -void lcp_close(int, char *); -void lcp_lowerup(int); -void lcp_lowerdown(int); -void lcp_sprotrej(int, u_char *, int); /* send protocol reject */ - -extern struct protent lcp_protent; - -/* Default number of times we receive our magic number from the peer - before deciding the link is looped-back. */ -#define DEFLOOPBACKFAIL 10 diff --git a/cpukit/pppd/magic.c b/cpukit/pppd/magic.c deleted file mode 100644 index 46add2f1c3..0000000000 --- a/cpukit/pppd/magic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * magic.c - PPP Magic Number routines. - * - * 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. - */ - -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "magic.h" - -/* - * magic_init - Initialize the magic number generator. - * - * Attempts to compute a random number seed which will not repeat. - * The current method uses the current hostid, current process ID - * and current time, currently. - */ -void -magic_init(void) -{ - long seed; - struct timeval t; - - gettimeofday(&t, NULL); - seed = get_host_seed() ^ t.tv_sec ^ t.tv_usec ^ getpid(); - srand48(seed); -} - -/* - * magic - Returns the next magic number. - */ -uint32_t -magic(void) -{ - return (uint32_t) mrand48(); -} diff --git a/cpukit/pppd/magic.h b/cpukit/pppd/magic.h deleted file mode 100644 index 572a550042..0000000000 --- a/cpukit/pppd/magic.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * magic.h - PPP Magic Number definitions. - * - * 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. - * - * $Id$ - */ - -void magic_init(void); /* Initialize the magic number generator */ -uint32_t magic(void); /* Returns the next magic number */ diff --git a/cpukit/pppd/options.c b/cpukit/pppd/options.c deleted file mode 100644 index 9086e554d9..0000000000 --- a/cpukit/pppd/options.c +++ /dev/null @@ -1,1515 +0,0 @@ -/* - * options.c - handles option processing for PPP. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PLUGIN -#include -#endif -#ifdef PPP_FILTER -#include -#include /* XXX: To get struct pcap */ -#endif - -#include "pppd.h" -#include "pathnames.h" -#include "patchlevel.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "upap.h" -#include "chap.h" -#include "ccp.h" - -#include - -/* - * Option variables and default values. - */ -#ifdef PPP_FILTER -int dflag = 0; /* Tell libpcap we want debugging */ -#endif -int debug = 0; /* Debug flag */ -int kdebugflag = 0; /* Tell kernel to print debug messages */ -int default_device = 1; /* Using /dev/tty or equivalent */ -char devnam[MAXPATHLEN]; /* Device name */ -int crtscts = 0; /* Use hardware flow control */ -bool modem = 1; /* Use modem control lines */ -int inspeed = 0; /* Input/Output speed requested */ -uint32_t netmask = 0; /* IP netmask to set on interface */ -bool lockflag = 0; /* Create lock file to lock the serial dev */ -bool nodetach = 0; /* Don't detach from controlling tty */ -bool updetach = 0; /* Detach once link is up */ -char *initializer = NULL; /* Script to initialize physical link */ -char *connect_script = NULL; /* Script to establish physical link */ -char *disconnect_script = NULL; /* Script to disestablish physical link */ -char *welcomer = NULL; /* Script to run after phys link estab. */ -char *ptycommand = NULL; /* Command to run on other side of pty */ -int maxconnect = 0; /* Maximum connect time */ -char user[MAXNAMELEN]; /* Username for PAP */ -char passwd[MAXSECRETLEN]; /* Password for PAP */ -bool persist = 0; /* Reopen link after it goes down */ -char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ -bool demand = 0; /* do dial-on-demand */ -char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ -int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ -int holdoff = 30; /* # seconds to pause before reconnecting */ -bool holdoff_specified; /* true if a holdoff value has been given */ -bool notty = 0; /* Stdin/out is not a tty */ -char *record_file = NULL; /* File to record chars sent/received */ -int using_pty = 0; -bool sync_serial = 0; /* Device is synchronous serial device */ -int log_to_fd = 1; /* send log messages to this fd too */ -int maxfail = 10; /* max # of unsuccessful connection attempts */ -char linkname[MAXPATHLEN]; /* logical name for link */ -bool tune_kernel; /* may alter kernel settings */ -int connect_delay = 1000; /* wait this many ms after connect script */ - -extern option_t auth_options[]; -extern struct stat devstat; -extern int prepass; /* Doing pre-pass to find device name */ - -struct option_info initializer_info; -struct option_info connect_script_info; -struct option_info disconnect_script_info; -struct option_info welcomer_info; -struct option_info devnam_info; -struct option_info ptycommand_info; - -#ifdef PPP_FILTER -struct bpf_program pass_filter;/* Filter program for packets to pass */ -struct bpf_program active_filter; /* Filter program for link-active pkts */ -pcap_t pc; /* Fake struct pcap so we can compile expr */ -#endif - -char *current_option; /* the name of the option being parsed */ -int privileged_option; /* set iff the current option came from root */ -char *option_source; /* string saying where the option came from */ -bool log_to_file; /* log_to_fd is a file opened by us */ - -/* - * Prototypes - */ -static int setdevname(char *); -static int setipaddr(char *); -static int setspeed(char *); -static int noopt(char **); -static int setdomain(char **); -static int setnetmask(char **); -static int setxonxoff(char **); -static int readfile(char **); -static int callfile(char **); -static void usage(void); -static int setlogfile(char **); -#ifdef PLUGIN -static int loadplugin(char **); -#endif - -#ifdef PPP_FILTER -static int setpassfilter(char **); -static int setactivefilter(char **); -#endif - -static option_t *find_option(char *name); -static int process_option(option_t *, char **); -static int n_arguments(option_t *); -static int number_option(char *, uint32_t *, int); - -/* - * Structure to store extra lists of options. - */ -struct option_list { - option_t *options; - struct option_list *next; -}; - -static struct option_list *extra_options = NULL; - -/* - * Valid arguments. - */ -option_t general_options[] = { - { "debug", o_int, &debug, - "Increase debugging level", OPT_INC|OPT_NOARG|1, NULL, 0, 0 }, - { "-d", o_int, &debug, - "Increase debugging level", OPT_INC|OPT_NOARG|1, NULL, 0, 0 }, - { "kdebug", o_int, &kdebugflag, - "Set kernel driver debug level", 0, NULL, 0, 0 }, - { "nodetach", o_bool, &nodetach, - "Don't detach from controlling tty", 1, NULL, 0, 0 }, - { "-detach", o_bool, &nodetach, - "Don't detach from controlling tty", 1, NULL, 0, 0 }, - { "updetach", o_bool, &updetach, - "Detach from controlling tty once link is up", 1, NULL, 0, 0 }, - { "holdoff", o_int, &holdoff, - "Set time in seconds before retrying connection", 0, NULL, 0, 0 }, - { "idle", o_int, &idle_time_limit, - "Set time in seconds before disconnecting idle link", 0, NULL, 0, 0 }, - { "lock", o_bool, &lockflag, - "Lock serial device with UUCP-style lock file", 1, NULL, 0, 0 }, - { "-all", o_special_noarg, noopt, - "Don't request/allow any LCP or IPCP options (useless)", 0, NULL, 0, 0 }, - { "init", o_string, &initializer, - "A program to initialize the device", - OPT_A2INFO | OPT_PRIVFIX, &initializer_info, 0, 0 }, - { "connect", o_string, &connect_script, - "A program to set up a connection", - OPT_A2INFO | OPT_PRIVFIX, &connect_script_info, 0, 0 }, - { "disconnect", o_string, &disconnect_script, - "Program to disconnect serial device", - OPT_A2INFO | OPT_PRIVFIX, &disconnect_script_info, 0, 0 }, - { "welcome", o_string, &welcomer, - "Script to welcome client", - OPT_A2INFO | OPT_PRIVFIX, &welcomer_info, 0, 0 }, - { "pty", o_string, &ptycommand, - "Script to run on pseudo-tty master side", - OPT_A2INFO | OPT_PRIVFIX | OPT_DEVNAM, &ptycommand_info, 0, 0 }, - { "notty", o_bool, ¬ty, - "Input/output is not a tty", OPT_DEVNAM | 1, NULL, 0, 0 }, - { "record", o_string, &record_file, - "Record characters sent/received to file", 0, NULL, 0, 0 }, - { "maxconnect", o_int, &maxconnect, - "Set connection time limit", OPT_LLIMIT|OPT_NOINCR|OPT_ZEROINF, NULL, 0, 0 }, - { "crtscts", o_int, &crtscts, - "Set hardware (RTS/CTS) flow control", OPT_NOARG|OPT_VAL(1), NULL, 0, 0 }, - { "nocrtscts", o_int, &crtscts, - "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1), NULL, 0, 0 }, - { "-crtscts", o_int, &crtscts, - "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1), NULL, 0, 0 }, - { "cdtrcts", o_int, &crtscts, - "Set alternate hardware (DTR/CTS) flow control", OPT_NOARG|OPT_VAL(2), NULL, 0, 0 }, - { "nocdtrcts", o_int, &crtscts, - "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1), NULL, 0, 0 }, - { "xonxoff", o_special_noarg, setxonxoff, - "Set software (XON/XOFF) flow control", 0, NULL, 0, 0 }, - { "domain", o_special, setdomain, - "Add given domain name to hostname", 0, NULL, 0, 0 }, - { "mtu", o_int, &lcp_allowoptions[0].mru, - "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU }, - { "netmask", o_special, setnetmask, - "set netmask", 0, NULL, 0, 0 }, - { "modem", o_bool, &modem, - "Use modem control lines", 1, NULL, 0, 0 }, - { "local", o_bool, &modem, - "Don't use modem control lines", 0, NULL, 0, 0 }, - { "file", o_special, readfile, - "Take options from a file", OPT_PREPASS, NULL, 0, 0 }, - { "call", o_special, callfile, - "Take options from a privileged file", OPT_PREPASS, NULL, 0, 0 }, - { "persist", o_bool, &persist, - "Keep on reopening connection after close", 1, NULL, 0, 0 }, - { "nopersist", o_bool, &persist, - "Turn off persist option", 0, NULL, 0, 0 }, - { "demand", o_bool, &demand, - "Dial on demand", OPT_INITONLY | 1, &persist, 0, 0 }, - { "sync", o_bool, &sync_serial, - "Use synchronous HDLC serial encoding", 1, NULL, 0, 0 }, - { "logfd", o_int, &log_to_fd, - "Send log messages to this file descriptor", 0, NULL, 0, 0 }, - { "logfile", o_special, setlogfile, - "Append log messages to this file", 0, NULL, 0, 0 }, - { "nolog", o_int, &log_to_fd, - "Don't send log messages to any file", - OPT_NOARG | OPT_VAL(-1), NULL, 0, 0 }, - { "nologfd", o_int, &log_to_fd, - "Don't send log messages to any file descriptor", - OPT_NOARG | OPT_VAL(-1), NULL, 0, 0 }, - { "linkname", o_string, linkname, - "Set logical name for link", - OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN, 0 }, - { "maxfail", o_int, &maxfail, - "Maximum number of unsuccessful connection attempts to allow", 0, NULL, 0, 0 }, - { "ktune", o_bool, &tune_kernel, - "Alter kernel settings as necessary", 1, NULL, 0, 0 }, - { "noktune", o_bool, &tune_kernel, - "Don't alter kernel settings", 0, NULL, 0, 0 }, - { "connect-delay", o_int, &connect_delay, - "Maximum time (in ms) to wait after connect script finishes", 0, NULL, 0, 0 }, -#ifdef PLUGIN - { "plugin", o_special, loadplugin, - "Load a plug-in module into pppd", OPT_PRIV, NULL, 0, 0 }, -#endif - -#ifdef PPP_FILTER - { "pdebug", o_int, &dflag, - "libpcap debugging", 0, NULL, 0, 0 }, - { "pass-filter", 1, setpassfilter, - "set filter for packets to pass", 0, NULL, 0, 0 }, - { "active-filter", 1, setactivefilter, - "set filter for active pkts", 0, NULL, 0, 0 }, -#endif - - { NULL, 0, NULL, NULL, 0, NULL, 0, 0 } -}; - -#ifndef IMPLEMENTATION -#define IMPLEMENTATION "" -#endif - -static char *usage_string = "\ -pppd version %s.%d%s\n\ -Usage: %s [ options ], where options are:\n\ - Communicate over the named device\n\ - Set the baud rate to \n\ - : Set the local and/or remote interface IP\n\ - addresses. Either one may be omitted.\n\ - asyncmap Set the desired async map to hex \n\ - auth Require authentication from peer\n\ - connect

Invoke shell command

to set up the serial line\n\ - crtscts Use hardware RTS/CTS flow control\n\ - defaultroute Add default route through interface\n\ - file Take options from file \n\ - modem Use modem control lines\n\ - mru Set MRU value to for negotiation\n\ -See pppd(8) for more options.\n\ -"; - -/* - * parse_args - parse a string of arguments from the command line. - * If prepass is true, we are scanning for the device name and only - * processing a few options, so error messages are suppressed. - */ -int -parse_args( - int argc, - char **argv) -{ - char *arg; - option_t *opt; - int ret; - - privileged_option = privileged; - option_source = "command line"; - while (argc > 0) { - arg = *argv++; - --argc; - - /* - * First see if it's an option in the new option list. - */ - opt = find_option(arg); - if (opt != NULL) { - int n = n_arguments(opt); - if (argc < n) { - option_error("too few parameters for option %s", arg); - return 0; - } - current_option = arg; - if (!process_option(opt, argv)) - return 0; - argc -= n; - argv += n; - continue; - } - - /* - * Maybe a tty name, speed or IP address? - */ - if ((ret = setdevname(arg)) == 0 - && (ret = setspeed(arg)) == 0 - && (ret = setipaddr(arg)) == 0 - && !prepass) { - option_error("unrecognized option '%s'", arg); - usage(); - return 0; - } - if (ret < 0) /* error */ - return 0; - } - return 1; -} - -#if 0 -/* - * scan_args - scan the command line arguments to get the tty name, - * if specified. Also checks whether the notty or pty option was given. - */ -void -scan_args(argc, argv) - int argc; - char **argv; -{ - char *arg; - option_t *opt; - - privileged_option = privileged; - while (argc > 0) { - arg = *argv++; - --argc; - - if (strcmp(arg, "notty") == 0 || strcmp(arg, "pty") == 0) - using_pty = 1; - - /* Skip options and their arguments */ - opt = find_option(arg); - if (opt != NULL) { - int n = n_arguments(opt); - argc -= n; - argv += n; - continue; - } - - /* Check if it's a tty name and copy it if so */ - (void) setdevname(arg, 1); - } -} -#endif - -/* - * options_from_file - Read a string of options from a file, - * and interpret them. - */ -int -options_from_file( - char *filename, - int must_exist, - int check_prot, - int priv) -{ - FILE *f; - int i, newline, ret, err; - option_t *opt; - int oldpriv; - char *oldsource; - char *argv[MAXARGS]; - char args[MAXARGS][MAXWORDLEN]; - char cmd[MAXWORDLEN]; - - f = fopen(filename, "r"); - err = errno; - if (f == NULL) { - if (!must_exist && err == ENOENT) - return 1; - errno = err; - option_error("Can't open options file %s: %m", filename); - return 0; - } - - oldpriv = privileged_option; - privileged_option = priv; - oldsource = option_source; - option_source = strdup(filename); - if (option_source == NULL) - option_source = "file"; - ret = 0; - while (getword(f, cmd, &newline, filename)) { - /* - * First see if it's a command. - */ - opt = find_option(cmd); - if (opt != NULL) { - int n = n_arguments(opt); - for (i = 0; i < n; ++i) { - if (!getword(f, args[i], &newline, filename)) { - option_error( - "In file %s: too few parameters for option '%s'", - filename, cmd); - goto err; - } - argv[i] = args[i]; - } - current_option = cmd; - if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) { - option_error("the %s option may not be used in the %s file", - cmd, filename); - goto err; - } - if (!process_option(opt, argv)) - goto err; - continue; - } - - /* - * Maybe a tty name, speed or IP address? - */ - if ((i = setdevname(cmd)) == 0 - && (i = setspeed(cmd)) == 0 - && (i = setipaddr(cmd)) == 0) { - option_error("In file %s: unrecognized option '%s'", - filename, cmd); - goto err; - } - if (i < 0) /* error */ - goto err; - } - ret = 1; - -err: - fclose(f); - privileged_option = oldpriv; - option_source = oldsource; - return ret; -} - -/* - * options_from_user - See if the use has a ~/.ppprc file, - * and if so, interpret options from it. - */ -int -options_from_user(void) -{ - return 0; -} - -/* - * options_for_tty - See if an options file exists for the serial - * device, and if so, interpret options from it. - */ -int -options_for_tty(void) -{ - char *dev, *path, *p; - int ret; - size_t pl; - - dev = devnam; - if (strncmp(dev, "/dev/", 5) == 0) - dev += 5; - if (dev[0] == 0 || strcmp(dev, "tty") == 0) - return 1; /* don't look for /etc/ppp/options.tty */ - pl = strlen(_PATH_TTYOPT) + strlen(dev) + 1; - path = malloc(pl); - if (path == NULL) - novm("tty init file name"); - slprintf(path, pl, "%s%s", _PATH_TTYOPT, dev); - /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */ - for (p = path + strlen(_PATH_TTYOPT); *p != 0; ++p) - if (*p == '/') - *p = '.'; - ret = options_from_file(path, 0, 0, 1); - free(path); - return ret; -} - -/* - * options_from_list - process a string of options in a wordlist. - */ -int -options_from_list( - struct wordlist *w, - int priv) -{ - char *argv[MAXARGS]; - option_t *opt; - int i, ret = 0; - - privileged_option = priv; - option_source = "secrets file"; - - while (w != NULL) { - /* - * First see if it's a command. - */ - opt = find_option(w->word); - if (opt != NULL) { - int n = n_arguments(opt); - struct wordlist *w0 = w; - for (i = 0; i < n; ++i) { - w = w->next; - if (w == NULL) { - option_error( - "In secrets file: too few parameters for option '%s'", - w0->word); - goto err; - } - argv[i] = w->word; - } - current_option = w0->word; - if (!process_option(opt, argv)) - goto err; - w = w->next; - continue; - } - - /* - * Maybe a tty name, speed or IP address? - */ - if ((i = setdevname(w->word)) == 0 - && (i = setspeed(w->word)) == 0 - && (i = setipaddr(w->word)) == 0) { - option_error("In secrets file: unrecognized option '%s'", - w->word); - goto err; - } - if (i < 0) /* error */ - goto err; - w = w->next; - } - ret = 1; - -err: - return ret; -} - -/* - * find_option - scan the option lists for the various protocols - * looking for an entry with the given name. - * This could be optimized by using a hash table. - */ -static option_t * -find_option(char *name) -{ - option_t *opt; - struct option_list *list; - int i; - - for (list = extra_options; list != NULL; list = list->next) - for (opt = list->options; opt->name != NULL; ++opt) - if (strcmp(name, opt->name) == 0) - return opt; - for (opt = general_options; opt->name != NULL; ++opt) - if (strcmp(name, opt->name) == 0) - return opt; - for (opt = auth_options; opt->name != NULL; ++opt) - if (strcmp(name, opt->name) == 0) - return opt; - for (i = 0; protocols[i] != NULL; ++i) - if ((opt = protocols[i]->options) != NULL) - for (; opt->name != NULL; ++opt) - if (strcmp(name, opt->name) == 0) - return opt; - return NULL; -} - -/* - * process_option - process one new-style option. - */ -static int -process_option( - option_t *opt, - char **argv) -{ - uint32_t v; - int iv, a; - char *sv; - int (*parser)(char **); - - if ((opt->flags & OPT_PREPASS) == 0 && prepass) - return 1; - if ((opt->flags & OPT_INITONLY) && pppd_phase != PHASE_INITIALIZE) { - option_error("it's too late to use the %s option", opt->name); - return 0; - } - if ((opt->flags & OPT_PRIV) && !privileged_option) { - option_error("using the %s option requires root privilege", opt->name); - return 0; - } - if ((opt->flags & OPT_ENABLE) && *(bool *)(opt->addr2) == 0) { - option_error("%s option is disabled", opt->name); - return 0; - } - if ((opt->flags & OPT_PRIVFIX) && !privileged_option) { - struct option_info *ip = (struct option_info *) opt->addr2; - if (ip && ip->priv) { - option_error("%s option cannot be overridden", opt->name); - return 0; - } - } - - switch (opt->type) { - case o_bool: - v = opt->flags & OPT_VALUE; - *(bool *)(opt->addr) = v; - if (opt->addr2 && (opt->flags & OPT_A2COPY)) - *(bool *)(opt->addr2) = v; - break; - - case o_int: - iv = 0; - if ((opt->flags & OPT_NOARG) == 0) { - if (!int_option(*argv, &iv)) - return 0; - if ((((opt->flags & OPT_LLIMIT) && iv < opt->lower_limit) - || ((opt->flags & OPT_ULIMIT) && iv > opt->upper_limit)) - && !((opt->flags & OPT_ZEROOK && iv == 0))) { - char *zok = (opt->flags & OPT_ZEROOK)? " zero or": ""; - switch (opt->flags & OPT_LIMITS) { - case OPT_LLIMIT: - option_error("%s value must be%s >= %d", - opt->name, zok, opt->lower_limit); - break; - case OPT_ULIMIT: - option_error("%s value must be%s <= %d", - opt->name, zok, opt->upper_limit); - break; - case OPT_LIMITS: - option_error("%s value must be%s between %d and %d", - opt->name, opt->lower_limit, opt->upper_limit); - break; - } - return 0; - } - } - a = opt->flags & OPT_VALUE; - if (a >= 128) - a -= 256; /* sign extend */ - iv += a; - if (opt->flags & OPT_INC) - iv += *(int *)(opt->addr); - if ((opt->flags & OPT_NOINCR) && !privileged_option) { - int oldv = *(int *)(opt->addr); - if ((opt->flags & OPT_ZEROINF) ? - (oldv != 0 && (iv == 0 || iv > oldv)) : (iv > oldv)) { - option_error("%s value cannot be increased", opt->name); - return 0; - } - } - *(int *)(opt->addr) = iv; - if (opt->addr2 && (opt->flags & OPT_A2COPY)) - *(int *)(opt->addr2) = iv; - break; - - case o_uint32: - if (opt->flags & OPT_NOARG) { - v = opt->flags & OPT_VALUE; - } else if (!number_option(*argv, &v, 16)) - return 0; - if (opt->flags & OPT_OR) - v |= *(uint32_t *)(opt->addr); - *(uint32_t *)(opt->addr) = v; - if (opt->addr2 && (opt->flags & OPT_A2COPY)) - *(uint32_t *)(opt->addr2) = v; - break; - - case o_string: - if (opt->flags & OPT_STATIC) { - strlcpy((char *)(opt->addr), *argv, opt->upper_limit); - } else { - sv = strdup(*argv); - if (sv == NULL) - novm("option argument"); - if ( *(char **)(opt->addr) != NULL ) { - free((void *)*(char **)(opt->addr)); - *(char **)(opt->addr) = NULL; - } - *(char **)(opt->addr) = sv; - } - break; - - case o_special_noarg: - case o_special: - parser = (int (*)(char **)) opt->addr; - if (!(*parser)(argv)) - return 0; - break; - } - - if (opt->addr2) { - if (opt->flags & OPT_A2INFO) { - struct option_info *ip = (struct option_info *) opt->addr2; - ip->priv = privileged_option; - ip->source = option_source; - } else if ((opt->flags & (OPT_A2COPY|OPT_ENABLE)) == 0) - *(bool *)(opt->addr2) = 1; - } - - return 1; -} - -/* - * n_arguments - tell how many arguments an option takes - */ -static int -n_arguments( - option_t *opt) -{ - return (opt->type == o_bool || opt->type == o_special_noarg - || (opt->flags & OPT_NOARG))? 0: 1; -} - -/* - * add_options - add a list of options to the set we grok. - */ -void -add_options( - option_t *opt) -{ - struct option_list *list; - - list = malloc(sizeof(*list)); - if (list == 0) - novm("option list entry"); - list->options = opt; - list->next = extra_options; - extra_options = list; -} - -/* - * usage - print out a message telling how to use the program. - */ -static void -usage(void) -{ - if (pppd_phase == PHASE_INITIALIZE) - fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION, - "rtems_pppd"); -} - -/* - * option_error - print a message about an error in an option. - * The message is logged, and also sent to - * stderr if pppd_phase == PHASE_INITIALIZE. - */ -void -option_error __V((char *fmt, ...)) -{ - va_list args; - char buf[256]; - -#if defined(__STDC__) - va_start(args, fmt); -#else - char *fmt; - va_start(args); - fmt = va_arg(args, char *); -#endif - if (prepass) { - va_end(args); - return; - } - vslprintf(buf, sizeof(buf), fmt, args); - va_end(args); - - fprintf(stderr, "pppd: %s\n", buf); -} - -/* - * Read a word from a file. - * Words are delimited by white-space or by quotes (" or '). - * Quotes, white-space and \ may be escaped with \. - * \ is ignored. - */ -int -getword( - FILE *f, - char *word, - int *newlinep, - char *filename) -{ - int c, len, escape; - int quoted, comment; - int value, digit, got, n; - -#define isoctal(c) ((c) >= '0' && (c) < '8') - - *newlinep = 0; - len = 0; - escape = 0; - comment = 0; - - /* - * First skip white-space and comments. - */ - for (;;) { - c = getc(f); - if (c == EOF) - break; - - /* - * A newline means the end of a comment; backslash-newline - * is ignored. Note that we cannot have escape && comment. - */ - if (c == '\n') { - if (!escape) { - *newlinep = 1; - comment = 0; - } else - escape = 0; - continue; - } - - /* - * Ignore characters other than newline in a comment. - */ - if (comment) - continue; - - /* - * If this character is escaped, we have a word start. - */ - if (escape) - break; - - /* - * If this is the escape character, look at the next character. - */ - if (c == '\\') { - escape = 1; - continue; - } - - /* - * If this is the start of a comment, ignore the rest of the line. - */ - if (c == '#') { - comment = 1; - continue; - } - - /* - * A non-whitespace character is the start of a word. - */ - if (!isspace(c)) - break; - } - - /* - * Save the delimiter for quoted strings. - */ - if (!escape && (c == '"' || c == '\'')) { - quoted = c; - c = getc(f); - } else - quoted = 0; - - /* - * Process characters until the end of the word. - */ - while (c != EOF) { - if (escape) { - /* - * This character is escaped: backslash-newline is ignored, - * various other characters indicate particular values - * as for C backslash-escapes. - */ - escape = 0; - if (c == '\n') { - c = getc(f); - continue; - } - - got = 0; - switch (c) { - case 'a': - value = '\a'; - break; - case 'b': - value = '\b'; - break; - case 'f': - value = '\f'; - break; - case 'n': - value = '\n'; - break; - case 'r': - value = '\r'; - break; - case 's': - value = ' '; - break; - case 't': - value = '\t'; - break; - - default: - if (isoctal(c)) { - /* - * \ddd octal sequence - */ - value = 0; - for (n = 0; n < 3 && isoctal(c); ++n) { - value = (value << 3) + (c & 07); - c = getc(f); - } - got = 1; - break; - } - - if (c == 'x') { - /* - * \x sequence - */ - value = 0; - c = getc(f); - for (n = 0; n < 2 && isxdigit(c); ++n) { - digit = toupper(c) - '0'; - if (digit > 10) - digit += '0' + 10 - 'A'; - value = (value << 4) + digit; - c = getc (f); - } - got = 1; - break; - } - - /* - * Otherwise the character stands for itself. - */ - value = c; - break; - } - - /* - * Store the resulting character for the escape sequence. - */ - if (len < MAXWORDLEN-1) - word[len] = value; - ++len; - - if (!got) - c = getc(f); - continue; - - } - - /* - * Not escaped: see if we've reached the end of the word. - */ - if (quoted) { - if (c == quoted) - break; - } else { - if (isspace(c) || c == '#') { - ungetc (c, f); - break; - } - } - - /* - * Backslash starts an escape sequence. - */ - if (c == '\\') { - escape = 1; - c = getc(f); - continue; - } - - /* - * An ordinary character: store it in the word and get another. - */ - if (len < MAXWORDLEN-1) - word[len] = c; - ++len; - - c = getc(f); - } - - /* - * End of the word: check for errors. - */ - if (c == EOF) { - if (ferror(f)) { - if (errno == 0) - errno = EIO; - option_error("Error reading %s: %m", filename); - die(1); - } - /* - * If len is zero, then we didn't find a word before the - * end of the file. - */ - if (len == 0) - return 0; - } - - /* - * Warn if the word was too long, and append a terminating null. - */ - if (len >= MAXWORDLEN) { - option_error("warning: word in file %s too long (%.20s...)", - filename, word); - len = MAXWORDLEN - 1; - } - word[len] = 0; - - return 1; - -#undef isoctal - -} - -/* - * number_option - parse an unsigned numeric parameter for an option. - */ -static int -number_option( - char *str, - uint32_t *valp, - int base) -{ - char *ptr; - - *valp = strtoul(str, &ptr, base); - if (ptr == str) { - option_error("invalid numeric parameter '%s' for %s option", - str, current_option); - return 0; - } - return 1; -} - - -/* - * int_option - like number_option, but valp is int *, - * the base is assumed to be 0, and *valp is not changed - * if there is an error. - */ -int -int_option( - char *str, - int *valp) -{ - uint32_t v; - - if (!number_option(str, &v, 0)) - return 0; - *valp = (int) v; - return 1; -} - - -/* - * The following procedures parse options. - */ - -/* - * readfile - take commands from a file. - */ -static int -readfile( - char **argv) -{ - return options_from_file(*argv, 1, 1, privileged_option); -} - -/* - * callfile - take commands from /etc/ppp/peers/. - * Name may not contain /../, start with / or ../, or end in /.. - */ -static int -callfile( - char **argv) -{ - char *fname, *arg, *p; - int l, ok; - - arg = *argv; - ok = 1; - if (arg[0] == '/' || arg[0] == 0) - ok = 0; - else { - for (p = arg; *p != 0; ) { - if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) { - ok = 0; - break; - } - while (*p != '/' && *p != 0) - ++p; - if (*p == '/') - ++p; - } - } - if (!ok) { - option_error("call option value may not contain .. or start with /"); - return 0; - } - - l = strlen(arg) + strlen(_PATH_PEERFILES) + 1; - if ((fname = (char *) malloc(l)) == NULL) - novm("call file name"); - slprintf(fname, l, "%s%s", _PATH_PEERFILES, arg); - - ok = options_from_file(fname, 1, 1, 1); - - free(fname); - return ok; -} - -#ifdef PPP_FILTER -/* - * setpdebug - Set libpcap debugging level. - */ -static int -setpdebug( - char **argv) -{ - return int_option(*argv, &dflag); -} - -/* - * setpassfilter - Set the pass filter for packets - */ -static int -setpassfilter( - char **argv) -{ - pc.linktype = DLT_PPP; - pc.snapshot = PPP_HDRLEN; - - if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0) - return 1; - option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc)); - return 0; -} - -/* - * setactivefilter - Set the active filter for packets - */ -static int -setactivefilter( - char **argv) -{ - pc.linktype = DLT_PPP; - pc.snapshot = PPP_HDRLEN; - - if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0) - return 1; - option_error("error in active-filter expression: %s\n", pcap_geterr(&pc)); - return 0; -} -#endif - -/* - * noopt - Disable all options. - */ -static int -noopt( - char **argv) -{ - BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); - BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); - BZERO((char *) &ipcp_wantoptions[0], sizeof (struct ipcp_options)); - BZERO((char *) &ipcp_allowoptions[0], sizeof (struct ipcp_options)); - - return (1); -} - -/* - * setdomain - Set domain name to append to hostname - */ -static int -setdomain( - char **argv) -{ - if (!privileged_option) { - option_error("using the domain option requires root privilege"); - return 0; - } - gethostname(hostname, MAXNAMELEN); - if (**argv != 0) { - if (**argv != '.') - strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); - strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); - } - hostname[MAXNAMELEN-1] = 0; - return (1); -} - - -/* - * setspeed - Set the speed. - */ -static int -setspeed( - char *arg) -{ - long spd; - uint32_t ret = 1; - speed_t spdValue = 0; - char *ptr; - - if ( !prepass ) { - spd = strtol(arg, &ptr, 0); - if (ptr == arg || *ptr != 0 || spd == 0) { - ret = 0; - } - else { - switch ( spd ) { - case 2400L: - spdValue = B2400; - break; - case 4800L: - spdValue = B4800; - break; - case 9600L: - spdValue = B9600; - break; - case 19200L: - spdValue = B19200; - break; - case 38400L: - spdValue = B38400; - break; - case 57600L: - spdValue = B57600; - break; - case 115200L: - spdValue = B115200; - break; - default: - ret = 0; - break; - } - - if ( spdValue ) { - inspeed = spdValue; - } - } - } - - return ( ret ); -} - - -/* - * setdevname - Set the device name. - */ -static int -setdevname( - char *cp) -{ - struct stat statbuf; - char dev[MAXPATHLEN]; - - if (*cp == 0) - return 0; - - if (strncmp("/dev/", cp, 5) != 0) { - strlcpy(dev, "/dev/", sizeof(dev)); - strlcat(dev, cp, sizeof(dev)); - cp = dev; - } - - /* - * Check if there is a character device by this name. - */ - if (stat(cp, &statbuf) < 0) { - if (errno == ENOENT) - return 0; - option_error("Couldn't stat %s: %m", cp); - return -1; - } - if (!S_ISCHR(statbuf.st_mode)) { - option_error("%s is not a character device", cp); - return -1; - } - - if (pppd_phase != PHASE_INITIALIZE) { - option_error("device name cannot be changed after initialization"); - return -1; - } else if (devnam_fixed) { - option_error("per-tty options file may not specify device name"); - return -1; - } - - if (devnam_info.priv && !privileged_option) { - option_error("device name cannot be overridden"); - return -1; - } - - strlcpy(devnam, cp, sizeof(devnam)); - devstat = statbuf; - default_device = 0; - devnam_info.priv = privileged_option; - devnam_info.source = option_source; - - return 1; -} - - -/* - * setipaddr - Set the IP address - */ -static int -setipaddr( - char *arg) -{ - struct hostent *hp; - char *colon; - uint32_t local, remote; - ipcp_options *wo = &ipcp_wantoptions[0]; - - /* - * IP address pair separated by ":". - */ - if ((colon = strchr(arg, ':')) == NULL) - return 0; - if (prepass) - return 1; - - /* - * If colon first character, then no local addr. - */ - if (colon != arg) { - *colon = '\0'; - if ((local = inet_addr(arg)) == (uint32_t) -1) { - if ((hp = gethostbyname(arg)) == NULL) { - option_error("unknown host: %s", arg); - return -1; - } else { - local = *(uint32_t *)hp->h_addr; - } - } - if (bad_ip_adrs(local)) { - option_error("bad local IP address %s", ip_ntoa(local)); - return -1; - } - if (local != 0) - wo->ouraddr = local; - *colon = ':'; - } - - /* - * If colon last character, then no remote addr. - */ - if (*++colon != '\0') { - if ((remote = inet_addr(colon)) == (uint32_t) -1) { - if ((hp = gethostbyname(colon)) == NULL) { - option_error("unknown host: %s", colon); - return -1; - } else { - remote = *(uint32_t *)hp->h_addr; - if (remote_name[0] == 0) - strlcpy(remote_name, colon, sizeof(remote_name)); - } - } - if (bad_ip_adrs(remote)) { - option_error("bad remote IP address %s", ip_ntoa(remote)); - return -1; - } - if (remote != 0) - wo->hisaddr = remote; - } - - return 1; -} - - -/* - * setnetmask - set the netmask to be used on the interface. - */ -static int -setnetmask( - char **argv) -{ - uint32_t mask, b; - int n; - char *p, *endp; - - /* - * Unfortunately, if we use inet_addr, we can't tell whether - * a result of all 1s is an error or a valid 255.255.255.255. - */ - p = *argv; - mask = 0; - for (n = 3;; --n) { - b = strtoul(p, &endp, 0); - if (endp == p) - break; - if (b > 255) { - if (n == 3) { - /* accept e.g. 0xffffff00 */ - p = endp; - mask = b; - } - break; - } - mask |= b << (n * 8); - p = endp; - if (*p != '.' || n == 0) - break; - ++p; - } - - mask = htonl(mask); - - if (*p != 0 || (netmask & ~mask) != 0) { - option_error("invalid netmask value '%s'", *argv); - return 0; - } - - netmask = mask; - return (1); -} - -static int -setxonxoff( - char **argv) -{ - lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ - lcp_wantoptions[0].neg_asyncmap = 1; - - crtscts = -2; - return (1); -} - -static int -setlogfile( - char **argv) -{ - int fd, err; - - fd = open(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644); - if (fd < 0 && errno == EEXIST) - fd = open(*argv, O_WRONLY | O_APPEND); - err = errno; - if (fd < 0) { - errno = err; - option_error("Can't open log file %s: %m", *argv); - return 0; - } - if (log_to_file && log_to_fd >= 0) - close(log_to_fd); - log_to_fd = fd; - log_to_file = 1; - return 1; -} - -#ifdef PLUGIN -static int -loadplugin( - char **argv) -{ - char *arg = *argv; - void *handle; - const char *err; - void (*init)(void); - - handle = dlopen(arg, RTLD_GLOBAL | RTLD_NOW); - if (handle == 0) { - err = dlerror(); - if (err != 0) - option_error("%s", err); - option_error("Couldn't load plugin %s", arg); - return 0; - } - init = dlsym(handle, "plugin_init"); - if (init == 0) { - option_error("%s has no initialization entry point", arg); - dlclose(handle); - return 0; - } - info("Plugin %s loaded.", arg); - (*init)(); - return 1; -} -#endif /* PLUGIN */ diff --git a/cpukit/pppd/patchlevel.h b/cpukit/pppd/patchlevel.h deleted file mode 100644 index 54d88b8a66..0000000000 --- a/cpukit/pppd/patchlevel.h +++ /dev/null @@ -1,6 +0,0 @@ -/* $Id$ */ -#define PATCHLEVEL 11 - -#define VERSION "2.3" -#define IMPLEMENTATION "" -#define DATE "23 December 1999" diff --git a/cpukit/pppd/pathnames.h b/cpukit/pppd/pathnames.h deleted file mode 100644 index 0a4f6e69f2..0000000000 --- a/cpukit/pppd/pathnames.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * define path names - * - * $Id$ - */ - -#ifdef HAVE_PATHS_H -#include - -#else -#ifndef _PATH_VARRUN -#define _PATH_VARRUN "/etc/ppp/" -#endif -#define _PATH_DEVNULL "/dev/null" -#endif - -#ifndef _ROOT_PATH -#define _ROOT_PATH -#endif - -#define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets" -#define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets" -#define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options" -#define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up" -#define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down" -#define _PATH_AUTHUP _ROOT_PATH "/etc/ppp/auth-up" -#define _PATH_AUTHDOWN _ROOT_PATH "/etc/ppp/auth-down" -#define _PATH_TTYOPT _ROOT_PATH "/etc/ppp/options." -#define _PATH_CONNERRS _ROOT_PATH "/etc/ppp/connect-errors" -#define _PATH_PEERFILES _ROOT_PATH "/etc/ppp/peers/" -#define _PATH_RESOLV _ROOT_PATH "/etc/ppp/resolv.conf" - -#define _PATH_USEROPT ".ppprc" - -#ifdef INET6 -#define _PATH_IPV6UP _ROOT_PATH "/etc/ppp/ipv6-up" -#define _PATH_IPV6DOWN _ROOT_PATH "/etc/ppp/ipv6-down" -#endif - -#ifdef IPX_CHANGE -#define _PATH_IPXUP _ROOT_PATH "/etc/ppp/ipx-up" -#define _PATH_IPXDOWN _ROOT_PATH "/etc/ppp/ipx-down" -#endif /* IPX_CHANGE */ diff --git a/cpukit/pppd/pppd.8 b/cpukit/pppd/pppd.8 deleted file mode 100644 index 38470381f0..0000000000 --- a/cpukit/pppd/pppd.8 +++ /dev/null @@ -1,1479 +0,0 @@ -.\" manual page [] for pppd 2.3 -.\" SH section heading -.\" SS subsection heading -.\" LP paragraph -.\" IP indented paragraph -.\" TP hanging label -.TH PPPD 8 -.SH NAME -pppd \- Point to Point Protocol daemon -.SH SYNOPSIS -.B pppd -[ -.I tty_name -] [ -.I speed -] [ -.I options -] -.SH DESCRIPTION -.LP -The Point-to-Point Protocol (PPP) provides a method for transmitting -datagrams over serial point-to-point links. PPP -is composed of three parts: a method for encapsulating datagrams over -serial links, an extensible Link Control Protocol (LCP), and -a family of Network Control Protocols (NCP) for establishing -and configuring different network-layer protocols. -.LP -The encapsulation scheme is provided by driver code in the kernel. -Pppd provides the basic LCP, authentication support, and an NCP for -establishing and configuring the Internet Protocol (IP) (called the IP -Control Protocol, IPCP). -.SH FREQUENTLY USED OPTIONS -.TP -.I -Communicate over the named device. The string "/dev/" is prepended if -necessary. If no device name is given, or if the name of the terminal -connected to the standard input is given, pppd will use that terminal, -and will not fork to put itself in the background. A value for this -option from a privileged source cannot be overridden by a -non-privileged user. -.TP -.I -Set the baud rate to (a decimal number). On systems such as -4.4BSD and NetBSD, any speed can be specified. Other systems -(e.g. SunOS) allow only a limited set of speeds. -.TP -.B asyncmap \fI -Set the async character map to . This map describes which -control characters cannot be successfully received over the serial -line. Pppd will ask the peer to send these characters as a 2-byte -escape sequence. The argument is a 32 bit hex number with each bit -representing a character to escape. Bit 0 (00000001) represents the -character 0x00; bit 31 (80000000) represents the character 0x1f or ^_. -If multiple \fIasyncmap\fR options are given, the values are ORed -together. If no \fIasyncmap\fR option is given, no async character -map will be negotiated for the receive direction; the peer should then -escape \fIall\fR control characters. To escape transmitted -characters, use the \fIescape\fR option. -.TP -.B auth -Require the peer to authenticate itself before allowing network -packets to be sent or received. This option is the default if the -system has a default route. If neither this option nor the -\fInoauth\fR option is specified, pppd will only allow the peer to use -IP addresses to which the system does not already have a route. -.TP -.B call \fIname -Read options from the file /etc/ppp/peers/\fIname\fR. This file may -contain privileged options, such as \fInoauth\fR, even if pppd -is not being run by root. The \fIname\fR string may not begin with / -or include .. as a pathname component. The format of the options file -is described below. -.TP -.B connect \fIscript -Use the executable or shell command specified by \fIscript\fR to set -up the serial line. This script would typically use the chat(8) -program to dial the modem and start the remote ppp session. A value -for this option from a privileged source cannot be overridden by a -non-privileged user. -.TP -.B crtscts -Use hardware flow control (i.e. RTS/CTS) to control the flow of -data on the serial port. If neither the \fIcrtscts\fR, the -\fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR option -is given, the hardware flow control setting for the serial port is -left unchanged. -Some serial ports (such as Macintosh serial ports) lack a true -RTS output. Such serial ports use this mode to implement -unidirectional flow control. The serial port will -suspend transmission when requested by the modem (via CTS) -but will be unable to request the modem stop sending to the -computer. This mode retains the ability to use DTR as -a modem control line. -.TP -.B defaultroute -Add a default route to the system routing tables, using the peer as -the gateway, when IPCP negotiation is successfully completed. -This entry is removed when the PPP connection is broken. This option -is privileged if the \fInodefaultroute\fR option has been specified. -.TP -.B disconnect \fIscript -Run the executable or shell command specified by \fIscript\fR after -pppd has terminated the link. This script could, for example, issue -commands to the modem to cause it to hang up if hardware modem control -signals were not available. The disconnect script is not run if the -modem has already hung up. A value for this option from a privileged -source cannot be overridden by a non-privileged user. -.TP -.B escape \fIxx,yy,... -Specifies that certain characters should be escaped on transmission -(regardless of whether the peer requests them to be escaped with its -async control character map). The characters to be escaped are -specified as a list of hex numbers separated by commas. Note that -almost any character can be specified for the \fIescape\fR option, -unlike the \fIasyncmap\fR option which only allows control characters -to be specified. The characters which may not be escaped are those -with hex values 0x20 - 0x3f or 0x5e. -.TP -.B file \fIname -Read options from file \fIname\fR (the format is described below). -The file must be readable by the user who has invoked pppd. -.TP -.B init \fIscript -Run the executable or shell command specified by \fIscript\fR to -initialize the serial line. This script would typically use the -chat(8) program to configure the modem to enable auto answer. A value -for this option from a privileged source cannot be overridden by a -non-privileged user. -.TP -.B lock -Specifies that pppd should create a UUCP-style lock file for the -serial device to ensure exclusive access to the device. -.TP -.B mru \fIn -Set the MRU [Maximum Receive Unit] value to \fIn\fR. Pppd -will ask the peer to send packets of no more than \fIn\fR bytes. The -minimum MRU value is 128. The default MRU value is 1500. A value of -296 is recommended for slow links (40 bytes for TCP/IP header + 256 -bytes of data). (Note that for IPv6 MRU must be at least 1280) -.TP -.B mtu \fIn -Set the MTU [Maximum Transmit Unit] value to \fIn\fR. Unless the -peer requests a smaller value via MRU negotiation, pppd will -request that the kernel networking code send data packets of no more -than \fIn\fR bytes through the PPP network interface. (Note that for -IPv6 MTU must be at least 1280) -.TP -.B passive -Enables the "passive" option in the LCP. With this option, pppd will -attempt to initiate a connection; if no reply is received from the -peer, pppd will then just wait passively for a valid LCP packet from -the peer, instead of exiting, as it would without this option. -.SH OPTIONS -.TP -.I \fB:\fI -Set the local and/or remote interface IP addresses. Either one may be -omitted. The IP addresses can be specified with a host name or in -decimal dot notation (e.g. 150.234.56.78). The default local -address is the (first) IP address of the system (unless the -\fInoipdefault\fR -option is given). The remote address will be obtained from the peer -if not specified in any option. Thus, in simple cases, this option is -not required. If a local and/or remote IP address is specified with -this option, pppd -will not accept a different value from the peer in the IPCP -negotiation, unless the \fIipcp-accept-local\fR and/or -\fIipcp-accept-remote\fR options are given, respectively. -.TP -.B ipv6 \fI\fR,\fI -Set the local and/or remote 64-bit interface identifier. Either one may be -omitted. The identifier must be specified in standard ascii notation of -IPv6 addresses (e.g. ::dead:beef). If the -\fIipv6cp-use-ipaddr\fR -option is given, the local identifier is the local IPv4 address (see above). -On systems which supports a unique persistent id, such as EUI-48 derived -from the Ethernet MAC address, \fIipv6cp-use-persistent\fR option can be -used to replace the \fIipv6 ,\fR option. Otherwise the -identifier is randomized. -.TP -.B active-filter \fIfilter-expression -Specifies a packet filter to be applied to data packets to determine -which packets are to be regarded as link activity, and therefore reset -the idle timer, or cause the link to be brought up in demand-dialling -mode. This option is useful in conjunction with the -\fBidle\fR option if there are packets being sent or received -regularly over the link (for example, routing information packets) -which would otherwise prevent the link from ever appearing to be idle. -The \fIfilter-expression\fR syntax is as described for tcpdump(1), -except that qualifiers which are inappropriate for a PPP link, such as -\fBether\fR and \fBarp\fR, are not permitted. Generally the filter -expression should be enclosed in single-quotes to prevent whitespace -in the expression from being interpreted by the shell. This option -is currently only available under NetBSD, and then only -if both the kernel and pppd were compiled with PPP_FILTER defined. -.TP -.B allow-ip \fIaddress(es) -Allow peers to use the given IP address or subnet without -authenticating themselves. The parameter is parsed as for each -element of the list of allowed IP addresses in the secrets files (see -the AUTHENTICATION section below). -.TP -.B bsdcomp \fInr,nt -Request that the peer compress packets that it sends, using the -BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and -agree to compress packets sent to the peer with a maximum code size of -\fInt\fR bits. If \fInt\fR is not specified, it defaults to the value -given for \fInr\fR. Values in the range 9 to 15 may be used for -\fInr\fR and \fInt\fR; larger values give better compression but -consume more kernel memory for compression dictionaries. -Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables -compression in the corresponding direction. Use \fInobsdcomp\fR or -\fIbsdcomp 0\fR to disable BSD-Compress compression entirely. -.TP -.B cdtrcts -Use a non-standard hardware flow control (i.e. DTR/CTS) to control -the flow of data on the serial port. If neither the \fIcrtscts\fR, -the \fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR -option is given, the hardware flow control setting for the serial -port is left unchanged. -Some serial ports (such as Macintosh serial ports) lack a true -RTS output. Such serial ports use this mode to implement true -bi-directional flow control. The sacrifice is that this flow -control mode does not permit using DTR as a modem control line. -.TP -.B chap-interval \fIn -If this option is given, pppd will rechallenge the peer every \fIn\fR -seconds. -.TP -.B chap-max-challenge \fIn -Set the maximum number of CHAP challenge transmissions to \fIn\fR -(default 10). -.TP -.B chap-restart \fIn -Set the CHAP restart interval (retransmission timeout for challenges) -to \fIn\fR seconds (default 3). -.TP -.B connect-delay \fIn -Wait for up \fIn\fR milliseconds after the connect script finishes for -a valid PPP packet from the peer. At the end of this time, or when a -valid PPP packet is received from the peer, pppd will commence -negotiation by sending its first LCP packet. The default value is -1000 (1 second). This wait period only applies if the \fBconnect\fR -or \fBpty\fR option is used. -.TP -.B debug -Enables connection debugging facilities. -If this option is given, pppd will log the contents of all -control packets sent or received in a readable form. The packets are -logged through syslog with facility \fIdaemon\fR and level -\fIdebug\fR. This information can be directed to a file by setting up -/etc/syslog.conf appropriately (see syslog.conf(5)). -.TP -.B default-asyncmap -Disable asyncmap negotiation, forcing all control characters to be -escaped for both the transmit and the receive direction. -.TP -.B default-mru -Disable MRU [Maximum Receive Unit] negotiation. With this option, -pppd will use the default MRU value of 1500 bytes for both the -transmit and receive direction. -.TP -.B deflate \fInr,nt -Request that the peer compress packets that it sends, using the -Deflate scheme, with a maximum window size of \fI2**nr\fR bytes, and -agree to compress packets sent to the peer with a maximum window size -of \fI2**nt\fR bytes. If \fInt\fR is not specified, it defaults to -the value given for \fInr\fR. Values in the range 8 to 15 may be used -for \fInr\fR and \fInt\fR; larger values give better compression but -consume more kernel memory for compression dictionaries. -Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables -compression in the corresponding direction. Use \fInodeflate\fR or -\fIdeflate 0\fR to disable Deflate compression entirely. (Note: pppd -requests Deflate compression in preference to BSD-Compress if the peer -can do either.) -.TP -.B demand -Initiate the link only on demand, i.e. when data traffic is present. -With this option, the remote IP address must be specified by the user -on the command line or in an options file. Pppd will initially -configure the interface and enable it for IP traffic without -connecting to the peer. When traffic is available, pppd will -connect to the peer and perform negotiation, authentication, etc. -When this is completed, pppd will commence passing data packets -(i.e., IP packets) across the link. - -The \fIdemand\fR option implies the \fIpersist\fR option. If this -behaviour is not desired, use the \fInopersist\fR option after the -\fIdemand\fR option. The \fIidle\fR and \fIholdoff\fR -options are also useful in conjuction with the \fIdemand\fR option. -.TP -.B domain \fId -Append the domain name \fId\fR to the local host name for authentication -purposes. For example, if gethostname() returns the name porsche, but -the fully qualified domain name is porsche.Quotron.COM, you could -specify \fIdomain Quotron.COM\fR. Pppd would then use the name -\fIporsche.Quotron.COM\fR for looking up secrets in the secrets file, -and as the default name to send to the peer when authenticating itself -to the peer. This option is privileged. -.TP -.B hide-password -When logging the contents of PAP packets, this option causes pppd to -exclude the password string from the log. This is the default. -.TP -.B holdoff \fIn -Specifies how many seconds to wait before re-initiating the link after -it terminates. This option only has any effect if the \fIpersist\fR -or \fIdemand\fR option is used. The holdoff period is not applied if -the link was terminated because it was idle. -.TP -.B idle \fIn -Specifies that pppd should disconnect if the link is idle for \fIn\fR -seconds. The link is idle when no data packets (i.e. IP packets) are -being sent or received. Note: it is not advisable to use this option -with the \fIpersist\fR option without the \fIdemand\fR option. -If the \fBactive-filter\fR -option is given, data packets which are rejected by the specified -activity filter also count as the link being idle. -.TP -.B ipcp-accept-local -With this option, pppd will accept the peer's idea of our local IP -address, even if the local IP address was specified in an option. -.TP -.B ipcp-accept-remote -With this option, pppd will accept the peer's idea of its (remote) IP -address, even if the remote IP address was specified in an option. -.TP -.B ipcp-max-configure \fIn -Set the maximum number of IPCP configure-request transmissions to -\fIn\fR (default 10). -.TP -.B ipcp-max-failure \fIn -Set the maximum number of IPCP configure-NAKs returned before starting -to send configure-Rejects instead to \fIn\fR (default 10). -.TP -.B ipcp-max-terminate \fIn -Set the maximum number of IPCP terminate-request transmissions to -\fIn\fR (default 3). -.TP -.B ipcp-restart \fIn -Set the IPCP restart interval (retransmission timeout) to \fIn\fR -seconds (default 3). -.TP -.B ipparam \fIstring -Provides an extra parameter to the ip-up and ip-down scripts. If this -option is given, the \fIstring\fR supplied is given as the 6th -parameter to those scripts. -.TP -.B ipv6cp-max-configure \fIn -Set the maximum number of IPv6CP configure-request transmissions to -\fIn\fR (default 10). -.TP -.B ipv6cp-max-failure \fIn -Set the maximum number of IPv6CP configure-NAKs returned before starting -to send configure-Rejects instead to \fIn\fR (default 10). -.TP -.B ipv6cp-max-terminate \fIn -Set the maximum number of IPv6CP terminate-request transmissions to -\fIn\fR (default 3). -.TP -.B ipv6cp-restart \fIn -Set the IPv6CP restart interval (retransmission timeout) to \fIn\fR -seconds (default 3). -.TP -.B ipx -Enable the IPXCP and IPX protocols. This option is presently only -supported under Linux, and only if your kernel has been configured to -include IPX support. -.TP -.B ipx-network \fIn -Set the IPX network number in the IPXCP configure request frame to -\fIn\fR, a hexadecimal number (without a leading 0x). There is no -valid default. If this option is not specified, the network number is -obtained from the peer. If the peer does not have the network number, -the IPX protocol will not be started. -.TP -.B ipx-node \fIn\fB:\fIm -Set the IPX node numbers. The two node numbers are separated from each -other with a colon character. The first number \fIn\fR is the local -node number. The second number \fIm\fR is the peer's node number. Each -node number is a hexadecimal number, at most 10 digits long. The node -numbers on the ipx-network must be unique. There is no valid -default. If this option is not specified then the node numbers are -obtained from the peer. -.TP -.B ipx-router-name \fI -Set the name of the router. This is a string and is sent to the peer -as information data. -.TP -.B ipx-routing \fIn -Set the routing protocol to be received by this option. More than one -instance of \fIipx-routing\fR may be specified. The '\fInone\fR' -option (0) may be specified as the only instance of ipx-routing. The -values may be \fI0\fR for \fINONE\fR, \fI2\fR for \fIRIP/SAP\fR, and -\fI4\fR for \fINLSP\fR. -.TP -.B ipxcp-accept-local -Accept the peer's NAK for the node number specified in the ipx-node -option. If a node number was specified, and non-zero, the default is -to insist that the value be used. If you include this option then you -will permit the peer to override the entry of the node number. -.TP -.B ipxcp-accept-network -Accept the peer's NAK for the network number specified in the -ipx-network option. If a network number was specified, and non-zero, the -default is to insist that the value be used. If you include this -option then you will permit the peer to override the entry of the node -number. -.TP -.B ipxcp-accept-remote -Use the peer's network number specified in the configure request -frame. If a node number was specified for the peer and this option was -not specified, the peer will be forced to use the value which you have -specified. -.TP -.B ipxcp-max-configure \fIn -Set the maximum number of IPXCP configure request frames which the -system will send to \fIn\fR. The default is 10. -.TP -.B ipxcp-max-failure \fIn -Set the maximum number of IPXCP NAK frames which the local system will -send before it rejects the options. The default value is 3. -.TP -.B ipxcp-max-terminate \fIn -Set the maximum nuber of IPXCP terminate request frames before the -local system considers that the peer is not listening to them. The -default value is 3. -.TP -.B kdebug \fIn -Enable debugging code in the kernel-level PPP driver. The argument -\fIn\fR is a number which is the sum of the following values: 1 to -enable general debug messages, 2 to request that the contents of -received packets be printed, and 4 to request that the contents of -transmitted packets be printed. On most systems, messages printed by -the kernel are logged by syslog(1) to a file as directed in the -/etc/syslog.conf configuration file. -.TP -.B ktune -Enables pppd to alter kernel settings as appropriate. Under Linux, -pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward -to 1) if the \fIproxyarp\fR option is used, and will enable the -dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to -1) in demand mode if the local address changes. -.TP -.B lcp-echo-failure \fIn -If this option is given, pppd will presume the peer to be dead -if \fIn\fR LCP echo-requests are sent without receiving a valid LCP -echo-reply. If this happens, pppd will terminate the -connection. Use of this option requires a non-zero value for the -\fIlcp-echo-interval\fR parameter. This option can be used to enable -pppd to terminate after the physical connection has been broken -(e.g., the modem has hung up) in situations where no hardware modem -control lines are available. -.TP -.B lcp-echo-interval \fIn -If this option is given, pppd will send an LCP echo-request frame to -the peer every \fIn\fR seconds. Normally the peer should respond to -the echo-request by sending an echo-reply. This option can be used -with the \fIlcp-echo-failure\fR option to detect that the peer is no -longer connected. -.TP -.B lcp-max-configure \fIn -Set the maximum number of LCP configure-request transmissions to -\fIn\fR (default 10). -.TP -.B lcp-max-failure \fIn -Set the maximum number of LCP configure-NAKs returned before starting -to send configure-Rejects instead to \fIn\fR (default 10). -.TP -.B lcp-max-terminate \fIn -Set the maximum number of LCP terminate-request transmissions to -\fIn\fR (default 3). -.TP -.B lcp-restart \fIn -Set the LCP restart interval (retransmission timeout) to \fIn\fR -seconds (default 3). -.TP -.B linkname \fIname\fR -Sets the logical name of the link to \fIname\fR. Pppd will create a -file named \fBppp-\fIname\fB.pid\fR in /var/run (or /etc/ppp on some -systems) containing its process ID. This can be useful in determining -which instance of pppd is responsible for the link to a given peer -system. This is a privileged option. -.TP -.B local -Don't use the modem control lines. With this option, pppd will ignore -the state of the CD (Carrier Detect) signal from the modem and will -not change the state of the DTR (Data Terminal Ready) signal. -.TP -.B logfd \fIn -Send log messages to file descriptor \fIn\fR. Pppd will send log -messages to at most one file or file descriptor (as well as sending -the log messages to syslog), so this option and the \fBlogfile\fR -option are mutually exclusive. The default is for pppd to send log -messages to stdout (file descriptor 1), unless the serial port is -already open on stdout. -.TP -.B logfile \fIfilename -Append log messages to the file \fIfilename\fR (as well as sending the -log messages to syslog). The file is opened with the privileges of -the user who invoked pppd, in append mode. -.TP -.B login -Use the system password database for authenticating the peer using -PAP, and record the user in the system wtmp file. Note that the peer -must have an entry in the /etc/ppp/pap-secrets file as well as the -system password database to be allowed access. -.TP -.B maxconnect \fIn -Terminate the connection when it has been available for network -traffic for \fIn\fR seconds (i.e. \fIn\fR seconds after the first -network control protocol comes up). -.TP -.B maxfail \fIn -Terminate after \fIn\fR consecutive failed connection attempts. A -value of 0 means no limit. The default value is 10. -.TP -.B modem -Use the modem control lines. This option is the default. With this -option, pppd will wait for the CD (Carrier Detect) signal from the -modem to be asserted when opening the serial device (unless a connect -script is specified), and it will drop the DTR (Data Terminal Ready) -signal briefly when the connection is terminated and before executing -the connect script. On Ultrix, this option implies hardware flow -control, as for the \fIcrtscts\fR option. -.TP -.B ms-dns \fI -If pppd is acting as a server for Microsoft Windows clients, this -option allows pppd to supply one or two DNS (Domain Name Server) -addresses to the clients. The first instance of this option specifies -the primary DNS address; the second instance (if given) specifies the -secondary DNS address. (This option was present in some older -versions of pppd under the name \fBdns-addr\fR.) -.TP -.B ms-wins \fI -If pppd is acting as a server for Microsoft Windows or "Samba" -clients, this option allows pppd to supply one or two WINS (Windows -Internet Name Services) server addresses to the clients. The first -instance of this option specifies the primary WINS address; the second -instance (if given) specifies the secondary WINS address. -.TP -.B name \fIname -Set the name of the local system for authentication purposes to -\fIname\fR. This is a privileged option. With this option, pppd will -use lines in the secrets files which have \fIname\fR as the second -field when looking for a secret to use in authenticating the peer. In -addition, unless overridden with the \fIuser\fR option, \fIname\fR -will be used as the name to send to the peer when authenticating the -local system to the peer. (Note that pppd does not append the domain -name to \fIname\fR.) -.TP -.B netmask \fIn -Set the interface netmask to \fIn\fR, a 32 bit netmask in "decimal dot" -notation (e.g. 255.255.255.0). If this option is given, the value -specified is ORed with the default netmask. The default netmask is -chosen based on the negotiated remote IP address; it is the -appropriate network mask for the class of the remote IP address, ORed -with the netmasks for any non point-to-point network interfaces in the -system which are on the same network. (Note: on some platforms, pppd -will always use 255.255.255.255 for the netmask, if that is the only -appropriate value for a point-to-point interface.) -.TP -.B noaccomp -Disable Address/Control compression in both directions (send and -receive). -.TP -.B noauth -Do not require the peer to authenticate itself. This option is -privileged. -.TP -.B nobsdcomp -Disables BSD-Compress compression; \fBpppd\fR will not request or -agree to compress packets using the BSD-Compress scheme. -.TP -.B noccp -Disable CCP (Compression Control Protocol) negotiation. This option -should only be required if the peer is buggy and gets confused by -requests from pppd for CCP negotiation. -.TP -.B nocrtscts -Disable hardware flow control (i.e. RTS/CTS) on the serial port. -If neither the \fIcrtscts\fR nor the \fInocrtscts\fR nor the -\fIcdtrcts\fR nor the \fInodtrcts\fR option is given, the hardware -flow control setting for the serial port is left unchanged. -.TP -.B nodtrcts -This option is a synonym for \fInocrtscts\fR. Either of these options will -disable both forms of hardware flow control. -.TP -.B nodefaultroute -Disable the \fIdefaultroute\fR option. The system administrator who -wishes to prevent users from creating default routes with pppd -can do so by placing this option in the /etc/ppp/options file. -.TP -.B nodeflate -Disables Deflate compression; pppd will not request or agree to -compress packets using the Deflate scheme. -.TP -.B nodetach -Don't detach from the controlling terminal. Without this option, if a -serial device other than the terminal on the standard input is -specified, pppd will fork to become a background process. -.TP -.B noip -Disable IPCP negotiation and IP communication. This option should -only be required if the peer is buggy and gets confused by requests -from pppd for IPCP negotiation. -.TP -.B noipv6 -Disable IPv6CP negotiation and IPv6 communication. This option should -only be required if the peer is buggy and gets confused by requests -from pppd for IPv6CP negotiation. -.TP -.B noipdefault -Disables the default behaviour when no local IP address is specified, -which is to determine (if possible) the local IP address from the -hostname. With this option, the peer will have to supply the local IP -address during IPCP negotiation (unless it specified explicitly on the -command line or in an options file). -.TP -.B noipx -Disable the IPXCP and IPX protocols. This option should only be -required if the peer is buggy and gets confused by requests from pppd -for IPXCP negotiation. -.TP -.B noktune -Opposite of the \fIktune\fR option; disables pppd from changing system -settings. -.TP -.B nolog -Do not send log messages to a file or file descriptor. This option -cancels the \fBlogfd\fR and \fBlogfile\fR options. -.B nomagic -Disable magic number negotiation. With this option, pppd cannot -detect a looped-back line. This option should only be needed if the -peer is buggy. -.TP -.B nopcomp -Disable protocol field compression negotiation in both the receive and -the transmit direction. -.TP -.B nopersist -Exit once a connection has been made and terminated. This is the -default unless the \fIpersist\fR or \fIdemand\fR option has been -specified. -.TP -.B nopredictor1 -Do not accept or agree to Predictor-1 compression. -.TP -.B noproxyarp -Disable the \fIproxyarp\fR option. The system administrator who -wishes to prevent users from creating proxy ARP entries with pppd can -do so by placing this option in the /etc/ppp/options file. -.TP -.B notty -Normally, pppd requires a terminal device. With this option, pppd -will allocate itself a pseudo-tty master/slave pair and use the slave -as its terminal device. Pppd will create a child process to act as a -`character shunt' to transfer characters between the pseudo-tty master -and its standard input and output. Thus pppd will transmit characters -on its standard output and receive characters on its standard input -even if they are not terminal devices. This option increases the -latency and CPU overhead of transferring data over the ppp interface -as all of the characters sent and received must flow through the -character shunt process. An explicit device name may not be given if -this option is used. -.TP -.B novj -Disable Van Jacobson style TCP/IP header compression in both the -transmit and the receive direction. -.TP -.B novjccomp -Disable the connection-ID compression option in Van Jacobson style -TCP/IP header compression. With this option, pppd will not omit the -connection-ID byte from Van Jacobson compressed TCP/IP headers, nor -ask the peer to do so. -.TP -.B papcrypt -Indicates that all secrets in the /etc/ppp/pap-secrets file which are -used for checking the identity of the peer are encrypted, and thus -pppd should not accept a password which, before encryption, is -identical to the secret from the /etc/ppp/pap-secrets file. -.TP -.B pap-max-authreq \fIn -Set the maximum number of PAP authenticate-request transmissions to -\fIn\fR (default 10). -.TP -.B pap-restart \fIn -Set the PAP restart interval (retransmission timeout) to \fIn\fR -seconds (default 3). -.TP -.B pap-timeout \fIn -Set the maximum time that pppd will wait for the peer to authenticate -itself with PAP to \fIn\fR seconds (0 means no limit). -.TP -.B pass-filter \fIfilter-expression -Specifies a packet filter to applied to data packets being sent or -received to determine which packets should be allowed to pass. -Packets which are rejected by the filter are silently discarded. This -option can be used to prevent specific network daemons (such as -routed) using up link bandwidth, or to provide a basic firewall -capability. -The \fIfilter-expression\fR syntax is as described for tcpdump(1), -except that qualifiers which are inappropriate for a PPP link, such as -\fBether\fR and \fBarp\fR, are not permitted. Generally the filter -expression should be enclosed in single-quotes to prevent whitespace -in the expression from being interpreted by the shell. Note that it -is possible to apply different constraints to incoming and outgoing -packets using the \fBinbound\fR and \fBoutbound\fR qualifiers. This -option is currently only available under NetBSD, and then only if both -the kernel and pppd were compiled with PPP_FILTER defined. -.TP -.B persist -Do not exit after a connection is terminated; instead try to reopen -the connection. -.TP -.B plugin \fIfilename -Load the shared library object file \fIfilename\fR as a plugin. This -is a privileged option. -.TP -.B predictor1 -Request that the peer compress frames that it sends using Predictor-1 -compression, and agree to compress transmitted frames with Predictor-1 -if requested. This option has no effect unless the kernel driver -supports Predictor-1 compression. -.TP -.B privgroup \fIgroup-name -Allows members of group \fIgroup-name\fR to use privileged options. -This is a privileged option. Use of this option requires care as -there is no guarantee that members of \fIgroup-name\fR cannot use pppd -to become root themselves. Consider it equivalent to putting the -members of \fIgroup-name\fR in the kmem or disk group. -.TP -.B proxyarp -Add an entry to this system's ARP [Address Resolution Protocol] table -with the IP address of the peer and the Ethernet address of this -system. This will have the effect of making the peer appear to other -systems to be on the local ethernet. -.TP -.B pty \fIscript -Specifies that the command \fIscript\fR is to be used to communicate -rather than a specific terminal device. Pppd will allocate itself a -pseudo-tty master/slave pair and use the slave as its terminal -device. The \fIscript\fR will be run in a child process with the -pseudo-tty master as its standard input and output. An explicit -device name may not be given if this option is used. (Note: if the -\fIrecord\fR option is used in conjuction with the \fIpty\fR option, -the child process will have pipes on its standard input and output.) -.TP -.B receive-all -With this option, pppd will accept all control characters from the -peer, including those marked in the receive asyncmap. Without this -option, pppd will discard those characters as specified in RFC1662. -This option should only be needed if the peer is buggy. -.TP -.B record \fIfilename -Specifies that pppd should record all characters sent and received to -a file named \fIfilename\fR. This file is opened in append mode, -using the user's user-ID and permissions. This option is implemented -using a pseudo-tty and a process to transfer characters between the -pseudo-tty and the real serial device, so it will increase the latency -and CPU overhead of transferring data over the ppp interface. The -characters are stored in a tagged format with timestamps, which can be -displayed in readable form using the pppdump(8) program. -.TP -.B remotename \fIname -Set the assumed name of the remote system for authentication purposes -to \fIname\fR. -.TP -.B refuse-chap -With this option, pppd will not agree to authenticate itself to the -peer using CHAP. -.TP -.B refuse-pap -With this option, pppd will not agree to authenticate itself to the -peer using PAP. -.TP -.B require-chap -Require the peer to authenticate itself using CHAP [Challenge -Handshake Authentication Protocol] authentication. -.TP -.B require-pap -Require the peer to authenticate itself using PAP [Password -Authentication Protocol] authentication. -.TP -.B show-password -When logging the contents of PAP packets, this option causes pppd to -show the password string in the log message. -.TP -.B silent -With this option, pppd will not transmit LCP packets to initiate a -connection until a valid LCP packet is received from the peer (as for -the `passive' option with ancient versions of pppd). -.TP -.B sync -Use synchronous HDLC serial encoding instead of asynchronous. -The device used by pppd with this option must have sync support. -Currently supports Microgate SyncLink adapters -under Linux and FreeBSD 2.2.8 and later. -.TP -.B updetach -With this option, pppd will detach from its controlling terminal once -it has successfully established the ppp connection (to the point where -the first network control protocol, usually the IP control protocol, -has come up). -.TP -.B usehostname -Enforce the use of the hostname (with domain name appended, if given) -as the name of the local system for authentication purposes (overrides -the \fIname\fR option). This option is not normally needed since the -\fIname\fR option is privileged. -.TP -.B usepeerdns -Ask the peer for up to 2 DNS server addresses. The addresses supplied -by the peer (if any) are passed to the /etc/ppp/ip-up script in the -environment variables DNS1 and DNS2. In addition, pppd will create an -/etc/ppp/resolv.conf file containing one or two nameserver lines with -the address(es) supplied by the peer. -.TP -.B user \fIname -Sets the name used for authenticating the local system to the peer to -\fIname\fR. -.TP -.B vj-max-slots \fIn -Sets the number of connection slots to be used by the Van Jacobson -TCP/IP header compression and decompression code to \fIn\fR, which -must be between 2 and 16 (inclusive). -.TP -.B welcome \fIscript -Run the executable or shell command specified by \fIscript\fR before -initiating PPP negotiation, after the connect script (if any) has -completed. A value for this option from a privileged source cannot be -overridden by a non-privileged user. -.TP -.B xonxoff -Use software flow control (i.e. XON/XOFF) to control the flow of data on -the serial port. -.SH OPTIONS FILES -Options can be taken from files as well as the command line. Pppd -reads options from the files /etc/ppp/options, ~/.ppprc and -/etc/ppp/options.\fIttyname\fR (in that order) before processing the -options on the command line. (In fact, the command-line options are -scanned to find the terminal name before the options.\fIttyname\fR -file is read.) In forming the name of the options.\fIttyname\fR file, -the initial /dev/ is removed from the terminal name, and any remaining -/ characters are replaced with dots. -.PP -An options file is parsed into a series of words, delimited by -whitespace. Whitespace can be included in a word by enclosing the -word in double-quotes ("). A backslash (\\) quotes the following character. -A hash (#) starts a comment, which continues until the end of the -line. There is no restriction on using the \fIfile\fR or \fIcall\fR -options within an options file. -.SH SECURITY -.I pppd -provides system administrators with sufficient access control that PPP -access to a server machine can be provided to legitimate users without -fear of compromising the security of the server or the network it's -on. This control is provided through restrictions on which IP -addresses the peer may use, based on its authenticated identity (if -any), and through restrictions on which options a non-privileged user -may use. Several of pppd's options are privileged, in particular -those which permit potentially insecure configurations; these options -are only accepted in files which are under the control of the system -administrator, or if pppd is being run by root. -.PP -The default behaviour of pppd is to allow an unauthenticated peer to -use a given IP address only if the system does not already have a -route to that IP address. For example, a system with a -permanent connection to the wider internet will normally have a -default route, and thus all peers will have to authenticate themselves -in order to set up a connection. On such a system, the \fIauth\fR -option is the default. On the other hand, a system where the -PPP link is the only connection to the internet will not normally have -a default route, so the peer will be able to use almost any IP address -without authenticating itself. -.PP -As indicated above, some security-sensitive options are privileged, -which means that they may not be used by an ordinary non-privileged -user running a setuid-root pppd, either on the command line, in the -user's ~/.ppprc file, or in an options file read using the \fIfile\fR -option. Privileged options may be used in /etc/ppp/options file or in -an options file read using the \fIcall\fR option. If pppd is being -run by the root user, privileged options can be used without -restriction. -.PP -When opening the device, pppd uses either the invoking user's user ID -or the root UID (that is, 0), depending on whether the device name was -specified by the user or the system administrator. If the device name -comes from a privileged source, that is, /etc/ppp/options or an -options file read using the \fIcall\fR option, pppd uses full root -privileges when opening the device. Thus, by creating an appropriate -file under /etc/ppp/peers, the system administrator can allow users to -establish a ppp connection via a device which they would not normally -have permission to access. Otherwise pppd uses the invoking user's -real UID when opening the device. -.SH AUTHENTICATION -Authentication is the process whereby one peer convinces the other of -its identity. This involves the first peer sending its name to the -other, together with some kind of secret information which could only -come from the genuine authorized user of that name. In such an -exchange, we will call the first peer the "client" and the other the -"server". The client has a name by which it identifies itself to the -server, and the server also has a name by which it identifies itself -to the client. Generally the genuine client shares some secret (or -password) with the server, and authenticates itself by proving that it -knows that secret. Very often, the names used for authentication -correspond to the internet hostnames of the peers, but this is not -essential. -.LP -At present, pppd supports two authentication protocols: the Password -Authentication Protocol (PAP) and the Challenge Handshake -Authentication Protocol (CHAP). PAP involves the client sending its -name and a cleartext password to the server to authenticate itself. -In contrast, the server initiates the CHAP authentication exchange by -sending a challenge to the client (the challenge packet includes the -server's name). The client must respond with a response which -includes its name plus a hash value derived from the shared secret and -the challenge, in order to prove that it knows the secret. -.LP -The PPP protocol, being symmetrical, allows both peers to require the -other to authenticate itself. In that case, two separate and -independent authentication exchanges will occur. The two exchanges -could use different authentication protocols, and in principle, -different names could be used in the two exchanges. -.LP -The default behaviour of pppd is to agree to authenticate if -requested, and to not require authentication from the peer. However, -pppd will not agree to authenticate itself with a particular protocol -if it has no secrets which could be used to do so. -.LP -Pppd stores secrets for use in authentication in secrets -files (/etc/ppp/pap-secrets for PAP, /etc/ppp/chap-secrets for CHAP). -Both secrets files have the same format. The secrets files can -contain secrets for pppd to use in authenticating itself to other -systems, as well as secrets for pppd to use when authenticating other -systems to itself. -.LP -Each line in a secrets file contains one secret. A given secret is -specific to a particular combination of client and server - it can -only be used by that client to authenticate itself to that server. -Thus each line in a secrets file has at least 3 fields: the name of -the client, the name of the server, and the secret. These fields may -be followed by a list of the IP addresses that the specified client -may use when connecting to the specified server. -.LP -A secrets file is parsed into words as for a options file, so the -client name, server name and secrets fields must each be one word, -with any embedded spaces or other special characters quoted or -escaped. Note that case is significant in the client and server names -and in the secret. -.LP -If the secret starts with an `@', what follows is assumed to be the -name of a file from which to read the secret. A "*" as the client or -server name matches any name. When selecting a secret, pppd takes the -best match, i.e. the match with the fewest wildcards. -.LP -Any following words on the same line are taken to be a list of -acceptable IP addresses for that client. If there are only 3 words on -the line, or if the first word is "-", then all IP addresses are -disallowed. To allow any address, use "*". A word starting with "!" -indicates that the specified address is \fInot\fR acceptable. An -address may be followed by "/" and a number \fIn\fR, to indicate a -whole subnet, i.e. all addresses which have the same value in the most -significant \fIn\fR bits. In this form, the address may be followed -by a plus sign ("+") to indicate that one address from the subnet is -authorized, based on the ppp network interface unit number in use. -In this case, the host part of the address will be set to the unit -number plus one. -.LP -Thus a secrets file contains both secrets for use in authenticating -other hosts, plus secrets which we use for authenticating ourselves to -others. When pppd is authenticating the peer (checking the peer's -identity), it chooses a secret with the peer's name in the first -field and the name of the local system in the second field. The -name of the local system defaults to the hostname, with the domain -name appended if the \fIdomain\fR option is used. This default can be -overridden with the \fIname\fR option, except when the -\fIusehostname\fR option is used. -.LP -When pppd is choosing a secret to use in authenticating itself to the -peer, it first determines what name it is going to use to identify -itself to the peer. This name can be specified by the user with the -\fIuser\fR option. If this option is not used, the name defaults to -the name of the local system, determined as described in the previous -paragraph. Then pppd looks for a secret with this name in the first -field and the peer's name in the second field. Pppd will know the -name of the peer if CHAP authentication is being used, because the -peer will have sent it in the challenge packet. However, if PAP is being -used, pppd will have to determine the peer's name from the options -specified by the user. The user can specify the peer's name directly -with the \fIremotename\fR option. Otherwise, if the remote IP address -was specified by a name (rather than in numeric form), that name will -be used as the peer's name. Failing that, pppd will use the null -string as the peer's name. -.LP -When authenticating the peer with PAP, the supplied password is first -compared with the secret from the secrets file. If the password -doesn't match the secret, the password is encrypted using crypt() and -checked against the secret again. Thus secrets for authenticating the -peer can be stored in encrypted form if desired. If the -\fIpapcrypt\fR option is given, the first (unencrypted) comparison is -omitted, for better security. -.LP -Furthermore, if the \fIlogin\fR option was specified, the username and -password are also checked against the system password database. Thus, -the system administrator can set up the pap-secrets file to allow PPP -access only to certain users, and to restrict the set of IP addresses -that each user can use. Typically, when using the \fIlogin\fR option, -the secret in /etc/ppp/pap-secrets would be "", which will match any -password supplied by the peer. This avoids the need to have the same -secret in two places. -.LP -Authentication must be satisfactorily completed before IPCP (or any -other Network Control Protocol) can be started. If the peer is -required to authenticate itself, and fails to do so, pppd will -terminated the link (by closing LCP). If IPCP negotiates an -unacceptable IP address for the remote host, IPCP will be closed. IP -packets can only be sent or received when IPCP is open. -.LP -In some cases it is desirable to allow some hosts which can't -authenticate themselves to connect and use one of a restricted set of -IP addresses, even when the local host generally requires -authentication. If the peer refuses to authenticate itself when -requested, pppd takes that as equivalent to authenticating with PAP -using the empty string for the username and password. Thus, by adding -a line to the pap-secrets file which specifies the empty string for -the client and password, it is possible to allow restricted access to -hosts which refuse to authenticate themselves. -.SH ROUTING -.LP -When IPCP negotiation is completed successfully, pppd will inform the -kernel of the local and remote IP addresses for the ppp interface. -This is sufficient to create a host route to the remote end of the -link, which will enable the peers to exchange IP packets. -Communication with other machines generally requires further -modification to routing tables and/or ARP (Address Resolution -Protocol) tables. In most cases the \fIdefaultroute\fR and/or -\fIproxyarp\fR options are sufficient for this, but in some cases -further intervention is required. The /etc/ppp/ip-up script can be -used for this. -.LP -Sometimes it is desirable to add a default route through the remote -host, as in the case of a machine whose only connection to the -Internet is through the ppp interface. The \fIdefaultroute\fR option -causes pppd to create such a default route when IPCP comes up, and -delete it when the link is terminated. -.LP -In some cases it is desirable to use proxy ARP, for example on a -server machine connected to a LAN, in order to allow other hosts to -communicate with the remote host. The \fIproxyarp\fR option causes -pppd to look for a network interface on the same subnet as the remote -host (an interface supporting broadcast and ARP, which is up and not a -point-to-point or loopback interface). If found, pppd creates a -permanent, published ARP entry with the IP address of the remote host -and the hardware address of the network interface found. -.LP -When the \fIdemand\fR option is used, the interface IP addresses have -already been set at the point when IPCP comes up. If pppd has not -been able to negotiate the same addresses that it used to configure -the interface (for example when the peer is an ISP that uses dynamic -IP address assignment), pppd has to change the interface IP addresses -to the negotiated addresses. This may disrupt existing connections, -and the use of demand dialling with peers that do dynamic IP address -assignment is not recommended. -.SH EXAMPLES -.LP -The following examples assume that the /etc/ppp/options file contains -the \fIauth\fR option (as in the default /etc/ppp/options file in the -ppp distribution). -.LP -Probably the most common use of pppd is to dial out to an ISP. This -can be done with a command such as -.IP -pppd call isp -.LP -where the /etc/ppp/peers/isp file is set up by the system -administrator to contain something like this: -.IP -ttyS0 19200 crtscts -.br -connect '/usr/sbin/chat -v -f /etc/ppp/chat-isp' -.br -noauth -.LP -In this example, we are using chat to dial the ISP's modem and go -through any logon sequence required. The /etc/ppp/chat-isp file -contains the script used by chat; it could for example contain -something like this: -.IP -ABORT "NO CARRIER" -.br -ABORT "NO DIALTONE" -.br -ABORT "ERROR" -.br -ABORT "NO ANSWER" -.br -ABORT "BUSY" -.br -ABORT "Username/Password Incorrect" -.br -"" "at" -.br -OK "at&d0&c1" -.br -OK "atdt2468135" -.br -"name:" "^Umyuserid" -.br -"word:" "\\qmypassword" -.br -"ispts" "\\q^Uppp" -.br -"~-^Uppp-~" -.LP -See the chat(8) man page for details of chat scripts. -.LP -Pppd can also be used to provide a dial-in ppp service for users. If -the users already have login accounts, the simplest way to set up the -ppp service is to let the users log in to their accounts and run pppd -(installed setuid-root) with a command such as -.IP -pppd proxyarp -.LP -To allow a user to use the PPP facilities, you need to allocate an IP -address for that user's machine and create an entry in -/etc/ppp/pap-secrets or /etc/ppp/chap-secrets (depending on which -authentication method the PPP implementation on the user's machine -supports), so that the user's -machine can authenticate itself. For example, if Joe has a machine -called "joespc" which is to be allowed to dial in to the machine -called "server" and use the IP address joespc.my.net, you would add an -entry like this to /etc/ppp/pap-secrets or /etc/ppp/chap-secrets: -.IP -joespc server "joe's secret" joespc.my.net -.LP -Alternatively, you can create a username called (for example) "ppp", -whose login shell is pppd and whose home directory is /etc/ppp. -Options to be used when pppd is run this way can be put in -/etc/ppp/.ppprc. -.LP -If your serial connection is any more complicated than a piece of -wire, you may need to arrange for some control characters to be -escaped. In particular, it is often useful to escape XON (^Q) and -XOFF (^S), using \fIasyncmap a0000\fR. If the path includes a telnet, -you probably should escape ^] as well (\fIasyncmap 200a0000\fR). If -the path includes an rlogin, you will need to use the \fIescape ff\fR -option on the end which is running the rlogin client, since many -rlogin implementations are not transparent; they will remove the -sequence [0xff, 0xff, 0x73, 0x73, followed by any 8 bytes] from the -stream. -.SH DIAGNOSTICS -.LP -Messages are sent to the syslog daemon using facility LOG_DAEMON. -(This can be overriden by recompiling pppd with the macro -LOG_PPP defined as the desired facility.) In order to see the error -and debug messages, you will need to edit your /etc/syslog.conf file -to direct the messages to the desired output device or file. -.LP -The \fIdebug\fR option causes the contents of all control packets sent -or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets. -This can be useful if the PPP negotiation does not succeed or if -authentication fails. -If debugging is enabled at compile time, the \fIdebug\fR option also -causes other debugging messages to be logged. -.LP -Debugging can also be enabled or disabled by sending a SIGUSR1 signal -to the pppd process. This signal acts as a toggle. -.SH EXIT STATUS -The exit status of pppd is set to indicate whether any error was -detected, or the reason for the link being terminated. The values -used are: -.TP -.B 0 -Pppd has detached, or otherwise the connection was successfully -established and terminated at the peer's request. -.TP -.B 1 -An immediately fatal error of some kind occurred, such as an essential -system call failing, or running out of virtual memory. -.TP -.B 2 -An error was detected in processing the options given, such as two -mutually exclusive options being used. -.TP -.B 3 -Pppd is not setuid-root and the invoking user is not root. -.TP -.B 4 -The kernel does not support PPP, for example, the PPP kernel driver is -not included or cannot be loaded. -.TP -.B 5 -Pppd terminated because it was sent a SIGINT, SIGTERM or SIGHUP -signal. -.TP -.B 6 -The serial port could not be locked. -.TP -.B 7 -The serial port could not be opened. -.TP -.B 8 -The connect script failed (returned a non-zero exit status). -.TP -.B 9 -The command specified as the argument to the \fIpty\fR option could -not be run. -.TP -.B 10 -The PPP negotiation failed, that is, it didn't reach the point where -at least one network protocol (e.g. IP) was running. -.TP -.B 11 -The peer system failed (or refused) to authenticate itself. -.TP -.B 12 -The link was established successfully and terminated because it was -idle. -.TP -.B 13 -The link was established successfully and terminated because the -connect time limit was reached. -.TP -.B 14 -Callback was negotiated and an incoming call should arrive shortly. -.TP -.B 15 -The link was terminated because the peer is not responding to echo -requests. -.TP -.B 16 -The link was terminated by the modem hanging up. -.TP -.B 17 -The PPP negotiation failed because serial loopback was detected. -.TP -.B 18 -The init script failed (returned a non-zero exit status). -.TP -.B 19 -We failed to authenticate ourselves to the peer. -.SH SCRIPTS -Pppd invokes scripts at various stages in its processing which can be -used to perform site-specific ancillary processing. These scripts are -usually shell scripts, but could be executable code files instead. -Pppd does not wait for the scripts to finish. The scripts are -executed as root (with the real and effective user-id set to 0), so -that they can do things such as update routing tables or run -privileged daemons. Be careful that the contents of these scripts do -not compromise your system's security. Pppd runs the scripts with -standard input, output and error redirected to /dev/null, and with an -environment that is empty except for some environment variables that -give information about the link. The environment variables that pppd -sets are: -.TP -.B DEVICE -The name of the serial tty device being used. -.TP -.B IFNAME -The name of the network interface being used. -.TP -.B IPLOCAL -The IP address for the local end of the link. This is only set when -IPCP has come up. -.TP -.B IPREMOTE -The IP address for the remote end of the link. This is only set when -IPCP has come up. -.TP -.B PEERNAME -The authenticated name of the peer. This is only set if the peer -authenticates itself. -.TP -.B SPEED -The baud rate of the tty device. -.TP -.B ORIG_UID -The real user-id of the user who invoked pppd. -.TP -.B PPPLOGNAME -The username of the real user-id that invoked pppd. This is always set. -.P -For the ip-down and auth-down scripts, pppd also sets the following -variables giving statistics for the connection: -.TP -.B CONNECT_TIME -The number of seconds from when the PPP negotiation started until the -connection was terminated. -.TP -.B BYTES_SENT -The number of bytes sent (at the level of the serial port) during the -connection. -.TP -.B BYTES_RCVD -The number of bytes received (at the level of the serial port) during -the connection. -.TP -.B LINKNAME -The logical name of the link, set with the \fIlinkname\fR option. -.P -Pppd invokes the following scripts, if they exist. It is not an error -if they don't exist. -.TP -.B /etc/ppp/auth-up -A program or script which is executed after the remote system -successfully authenticates itself. It is executed with the parameters -.IP -\fIinterface-name peer-name user-name tty-device speed\fR -.IP -Note that this script is not executed if the peer doesn't authenticate -itself, for example when the \fInoauth\fR option is used. -.TP -.B /etc/ppp/auth-down -A program or script which is executed when the link goes down, if -/etc/ppp/auth-up was previously executed. It is executed in the same -manner with the same parameters as /etc/ppp/auth-up. -.TP -.B /etc/ppp/ip-up -A program or script which is executed when the link is available for -sending and receiving IP packets (that is, IPCP has come up). It is -executed with the parameters -.IP -\fIinterface-name tty-device speed local-IP-address -remote-IP-address ipparam\fR -.TP -.B /etc/ppp/ip-down -A program or script which is executed when the link is no longer -available for sending and receiving IP packets. This script can be -used for undoing the effects of the /etc/ppp/ip-up script. It is -invoked in the same manner and with the same parameters as the ip-up -script. -.TP -.B /etc/ppp/ipv6-up -Like /etc/ppp/ip-up, except that it is executed when the link is available -for sending and receiving IPv6 packets. It is executed with the parameters -.IP -\fIinterface-name tty-device speed local-link-local-address -remote-link-local-address ipparam\fR -.TP -.B /etc/ppp/ipv6-down -Similar to /etc/ppp/ip-down, but it is executed when IPv6 packets can no -longer be transmitted on the link. It is executed with the same parameters -as the ipv6-up script. -.TP -.B /etc/ppp/ipx-up -A program or script which is executed when the link is available for -sending and receiving IPX packets (that is, IPXCP has come up). It is -executed with the parameters -.IP -\fIinterface-name tty-device speed network-number local-IPX-node-address -remote-IPX-node-address local-IPX-routing-protocol remote-IPX-routing-protocol -local-IPX-router-name remote-IPX-router-name ipparam pppd-pid\fR -.IP -The local-IPX-routing-protocol and remote-IPX-routing-protocol field -may be one of the following: -.IP -NONE to indicate that there is no routing protocol -.br -RIP to indicate that RIP/SAP should be used -.br -NLSP to indicate that Novell NLSP should be used -.br -RIP NLSP to indicate that both RIP/SAP and NLSP should be used -.TP -.B /etc/ppp/ipx-down -A program or script which is executed when the link is no longer -available for sending and receiving IPX packets. This script can be -used for undoing the effects of the /etc/ppp/ipx-up script. It is -invoked in the same manner and with the same parameters as the ipx-up -script. -.SH FILES -.TP -.B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others) -Process-ID for pppd process on ppp interface unit \fIn\fR. -.TP -.B /var/run/ppp-\fIname\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp-\fIname\fB.pid \fR(others) -Process-ID for pppd process for logical link \fIname\fR (see the -\fIlinkname\fR option). -.TP -.B /etc/ppp/pap-secrets -Usernames, passwords and IP addresses for PAP authentication. This -file should be owned by root and not readable or writable by any other -user. Pppd will log a warning if this is not the case. -.TP -.B /etc/ppp/chap-secrets -Names, secrets and IP addresses for CHAP authentication. As for -/etc/ppp/pap-secrets, this file should be owned by root and not -readable or writable by any other user. Pppd will log a warning if -this is not the case. -.TP -.B /etc/ppp/options -System default options for pppd, read before user default options or -command-line options. -.TP -.B ~/.ppprc -User default options, read before /etc/ppp/options.\fIttyname\fR. -.TP -.B /etc/ppp/options.\fIttyname -System default options for the serial port being used, read after -~/.ppprc. In forming the \fIttyname\fR part of this -filename, an initial /dev/ is stripped from the port name (if -present), and any slashes in the remaining part are converted to -dots. -.TP -.B /etc/ppp/peers -A directory containing options files which may contain privileged -options, even if pppd was invoked by a user other than root. The -system administrator can create options files in this directory to -permit non-privileged users to dial out without requiring the peer to -authenticate, but only to certain trusted peers. -.SH SEE ALSO -.TP -.B RFC1144 -Jacobson, V. -\fICompressing TCP/IP headers for low-speed serial links.\fR -February 1990. -.TP -.B RFC1321 -Rivest, R. -.I The MD5 Message-Digest Algorithm. -April 1992. -.TP -.B RFC1332 -McGregor, G. -.I PPP Internet Protocol Control Protocol (IPCP). -May 1992. -.TP -.B RFC1334 -Lloyd, B.; Simpson, W.A. -.I PPP authentication protocols. -October 1992. -.TP -.B RFC1661 -Simpson, W.A. -.I The Point\-to\-Point Protocol (PPP). -July 1994. -.TP -.B RFC1662 -Simpson, W.A. -.I PPP in HDLC-like Framing. -July 1994. -.TP -.B RFC2472 -Haskin, D. -.I IP Version 6 over PPP -December 1998. -.SH NOTES -The following signals have the specified effect when sent to pppd. -.TP -.B SIGINT, SIGTERM -These signals cause pppd to terminate the link (by closing LCP), -restore the serial device settings, and exit. -.TP -.B SIGHUP -This signal causes pppd to terminate the link, restore the serial -device settings, and close the serial device. If the \fIpersist\fR or -\fIdemand\fR option has been specified, pppd will try to reopen the -serial device and start another connection (after the holdoff period). -Otherwise pppd will exit. If this signal is received during the -holdoff period, it causes pppd to end the holdoff period immediately. -.TP -.B SIGUSR1 -This signal toggles the state of the \fIdebug\fR option. -.TP -.B SIGUSR2 -This signal causes pppd to renegotiate compression. This can be -useful to re-enable compression after it has been disabled as a result -of a fatal decompression error. (Fatal decompression errors generally -indicate a bug in one or other implementation.) - -.SH AUTHORS -Paul Mackerras (Paul.Mackerras@cs.anu.edu.au), based on earlier work by -Drew Perkins, -Brad Clements, -Karl Fox, -Greg Christy, -and -Brad Parker. diff --git a/cpukit/pppd/pppd.h b/cpukit/pppd/pppd.h deleted file mode 100644 index d1408a16a6..0000000000 --- a/cpukit/pppd/pppd.h +++ /dev/null @@ -1,655 +0,0 @@ -/* - * pppd.h - PPP daemon global declarations. - * - * 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. - * - * $Id$ - */ - -#ifndef __PPPD_H__ -#define __PPPD_H__ - -#include /* bool */ -#include /* for FILE */ -#include /* for NGROUPS_MAX */ -#include -#include /* for uint32_t, if defined */ -#include /* for struct timeval */ -#include -#include -#include - -#if defined(__STDC__) -#include -#define __V(x) x -#else -#include -#define __V(x) (va_alist) va_dcl -#define const -#define volatile -#endif - -#ifdef INET6 -#include "eui64.h" -#endif - -/* - * Limits. - */ - -#define NUM_PPP 1 /* One PPP interface supported (per process) */ -#define MAXWORDLEN 1024 /* max length of word in file (incl null) */ -#define MAXARGS 1 /* max # args to a command */ -#define MAXNAMELEN 256 /* max length of hostname or name for auth */ -#define MAXSECRETLEN 256 /* max length of password or secret */ - -/* - * Option descriptor structure. - */ - -enum opt_type { - o_special_noarg = 0, - o_special = 1, - o_bool, - o_int, - o_uint32, - o_string, -}; - -typedef struct { - char *name; /* name of the option */ - enum opt_type type; - void *addr; - char *description; - uint32_t flags; - void *addr2; - int upper_limit; - int lower_limit; -} option_t; - -/* Values for flags */ -#define OPT_VALUE 0xffL /* mask for presupplied value */ -#define OPT_HEX 0x100L /* int option is in hex */ -#define OPT_NOARG 0x200L /* option doesn't take argument */ -#define OPT_OR 0x400L /* OR in argument to value */ -#define OPT_INC 0x800L /* increment value */ -#define OPT_PRIV 0x1000L /* privileged option */ -#define OPT_STATIC 0x2000L /* string option goes into static array */ -#define OPT_LLIMIT 0x4000L /* check value against lower limit */ -#define OPT_ULIMIT 0x8000L /* check value against upper limit */ -#define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT) -#define OPT_ZEROOK 0x10000L /* 0 value is OK even if not within limits */ -#define OPT_NOINCR 0x20000L /* value mustn't be increased */ -#define OPT_ZEROINF 0x40000L /* with OPT_NOINCR, 0 == infinity */ -#define OPT_A2INFO 0x100000L /* addr2 -> option_info to update */ -#define OPT_A2COPY 0x200000L /* addr2 -> second location to rcv value */ -#define OPT_ENABLE 0x400000L /* use *addr2 as enable for option */ -#define OPT_PRIVFIX 0x800000L /* can't be overridden if noauth */ -#define OPT_PREPASS 0x1000000L /* do this opt in pre-pass to find device */ -#define OPT_INITONLY 0x2000000L /* option can only be set in init phase */ -#define OPT_DEVEQUIV 0x4000000L /* equiv to device name */ -#define OPT_DEVNAM (OPT_PREPASS | OPT_INITONLY | OPT_DEVEQUIV) - -#define OPT_VAL(x) ((x) & OPT_VALUE) - -#ifndef GIDSET_TYPE -#define GIDSET_TYPE gid_t -#endif - -/* Structure representing a list of permitted IP addresses. */ -struct permitted_ip { - int permit; /* 1 = permit, 0 = forbid */ - uint32_t base; /* match if (addr & mask) == base */ - uint32_t mask; /* base and mask are in network byte order */ -}; - -/* - * Unfortunately, the linux kernel driver uses a different structure - * for statistics from the rest of the ports. - * This structure serves as a common representation for the bits - * pppd needs. - */ -struct pppd_stats { - unsigned int bytes_in; - unsigned int bytes_out; -}; - -/* Used for storing a sequence of words. Usually malloced. */ -struct wordlist { - struct wordlist *next; - char *word; -}; - -/* - * Global variables. - */ - -extern int pppd_kill_link; /* Signal to terminate processing loop */ -extern int hungup; /* Physical layer has disconnected */ -extern int pppifunit; /* Interface unit number */ -extern char ifname[]; /* Interface name */ -extern int pppd_ttyfd; /* Serial device file descriptor */ -extern char hostname[]; /* Our hostname */ -extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ -extern int pppd_phase; /* Current state of link - see values below */ -extern int baud_rate; /* Current link speed in bits/sec */ -extern int redirect_stderr;/* Connector's stderr should go to file */ -extern char peer_authname[];/* Authenticated name of peer */ -extern int privileged; /* We were run by real-uid root */ -extern int need_holdoff; /* Need holdoff period after link terminates */ -extern char **script_env; /* Environment variables for scripts */ -extern int detached; /* Have detached from controlling tty */ -extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */ -extern int ngroups; /* How many groups valid in groups */ -extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */ -extern int using_pty; /* using pty as device (notty or pty opt.) */ -extern int log_to_fd; /* logging to this fd as well as syslog */ -extern char *no_ppp_msg; /* message to print if ppp not in kernel */ -extern volatile int pppd_status; /* exit status for pppd */ -extern int devnam_fixed; /* can no longer change devnam */ -extern int unsuccess; /* # unsuccessful connection attempts */ -extern int do_callback; /* set if we want to do callback next */ -extern int doing_callback; /* set if this is a callback */ -extern dialerfp pppd_dialer; /* script dialer function callback */ - -/* Values for do_callback and doing_callback */ -#define CALLBACK_DIALIN 1 /* we are expecting the call back */ -#define CALLBACK_DIALOUT 2 /* we are dialling out to call back */ - -/* - * Variables set by command-line options. - */ - -extern int debug; /* Debug flag */ -extern int kdebugflag; /* Tell kernel to print debug messages */ -extern int default_device; /* Using /dev/tty or equivalent */ -extern char devnam[MAXPATHLEN]; /* Device name */ -extern int crtscts; /* Use hardware flow control */ -extern bool modem; /* Use modem control lines */ -extern int inspeed; /* Input/Output speed requested */ -extern uint32_t netmask; /* IP netmask to set on interface */ -extern bool lockflag; /* Create lock file to lock the serial dev */ -extern bool nodetach; /* Don't detach from controlling tty */ -extern bool updetach; /* Detach from controlling tty when link up */ -extern char *initializer; /* Script to initialize physical link */ -extern char *connect_script; /* Script to establish physical link */ -extern char *disconnect_script; /* Script to disestablish physical link */ -extern char *welcomer; /* Script to welcome client after connection */ -extern char *ptycommand; /* Command to run on other side of pty */ -extern int maxconnect; /* Maximum connect time (seconds) */ -extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */ -extern char passwd[MAXSECRETLEN]; /* Password for PAP or CHAP */ -extern bool auth_required; /* Peer is required to authenticate */ -extern bool persist; /* Reopen link after it goes down */ -extern bool uselogin; /* Use /etc/passwd for checking PAP */ -extern char our_name[MAXNAMELEN];/* Our name for authentication purposes */ -extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -extern bool explicit_remote;/* remote_name specified with remotename opt */ -extern bool demand; /* Do dial-on-demand */ -extern char *ipparam; /* Extra parameter for ip up/down scripts */ -extern bool cryptpap; /* Others' PAP passwords are encrypted */ -extern int idle_time_limit;/* Shut down link if idle for this long */ -extern int holdoff; /* Dead time before restarting */ -extern bool holdoff_specified; /* true if user gave a holdoff value */ -extern bool notty; /* Stdin/out is not a tty */ -extern char *record_file; /* File to record chars sent/received */ -extern bool sync_serial; /* Device is synchronous serial device */ -extern int maxfail; /* Max # of unsuccessful connection attempts */ -extern char linkname[MAXPATHLEN]; /* logical name for link */ -extern bool tune_kernel; /* May alter kernel settings as necessary */ -extern int connect_delay; /* Time to delay after connect script */ - -#ifdef PPP_FILTER -extern struct bpf_program pass_filter; /* Filter for pkts to pass */ -extern struct bpf_program active_filter; /* Filter for link-active pkts */ -#endif - -#ifdef MSLANMAN -extern bool ms_lanman; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -extern char *current_option; /* the name of the option being parsed */ -extern int privileged_option; /* set iff the current option came from root */ -extern char *option_source; /* string saying where the option came from */ - -/* - * Values for phase. - */ -#define PHASE_DEAD 0 -#define PHASE_INITIALIZE 1 -#define PHASE_SERIALCONN 2 -#define PHASE_DORMANT 3 -#define PHASE_ESTABLISH 4 -#define PHASE_AUTHENTICATE 5 -#define PHASE_CALLBACK 6 -#define PHASE_NETWORK 7 -#define PHASE_RUNNING 8 -#define PHASE_TERMINATE 9 -#define PHASE_DISCONNECT 10 -#define PHASE_HOLDOFF 11 - -/* - * The following struct gives the addresses of procedures to call - * for a particular protocol. - */ -struct protent { - u_short protocol; /* PPP protocol number */ - /* Initialization procedure */ - void (*init)(int unit); - /* Process a received packet */ - void (*input)(int unit, u_char *pkt, int len); - /* Process a received protocol-reject */ - void (*protrej)(int unit); - /* Lower layer has come up */ - void (*lowerup)(int unit); - /* Lower layer has gone down */ - void (*lowerdown)(int unit); - /* Open the protocol */ - void (*open)(int unit); - /* Close the protocol */ - void (*close)(int unit, char *reason); - /* Print a packet in readable form */ - int (*printpkt)(u_char *pkt, int len, - void (*printer)(void *, char *, ...), - void *arg); - /* Process a received data packet */ - void (*datainput)(int unit, u_char *pkt, int len); - bool enabled_flag; /* 0 iff protocol is disabled */ - char *name; /* Text name of protocol */ - char *data_name; /* Text name of corresponding data protocol */ - option_t *options; /* List of command-line options */ - /* Check requested options, assign defaults */ - void (*check_options)(void); - /* Configure interface for demand-dial */ - int (*demand_conf)(int unit); - /* Say whether to bring up link for this pkt */ - int (*active_pkt)(u_char *pkt, int len); -}; - -/* Table of pointers to supported protocols */ -extern struct protent *protocols[]; - -/* - * Prototypes. - */ - -/* Procedures exported from main.c. */ -void die(int); /* Cleanup and exit */ -void quit(void); /* like die(1) */ -void novm(char *); /* Say we ran out of memory, and die */ -void ppptimeout(void (*func)(void *), void *arg, int t); - /* Call func(arg) after t seconds */ -void pppuntimeout(void (*func)(void *), void *arg); - /* Cancel call to func(arg) */ -void update_link_stats(int); /* Get stats at link termination */ -void new_phase(int); /* signal start of new phase */ - -/* Procedures exported from utils.c. */ -void log_packet(u_char *, int, char *, int); - /* Format a packet and log it with syslog */ -void print_string(void *, int, void (*) (void *, char *, ...), - void *); /* Format a string for output */ -int slprintf(char *, int, char *, ...); /* sprintf++ */ -int vslprintf(char *, int, char *, va_list); /* vsprintf++ */ -size_t strlcpy(char *, const char *, size_t); /* safe strcpy */ -size_t strlcat(char *, const char *, size_t); /* safe strncpy */ -void pppd_dbglog(char *, ...); /* log a debug message */ -void pppd_info(char *, ...); /* log an informational message */ -void pppd_notice(char *, ...); /* log a notice-level message */ -void pppd_warn(char *, ...); /* log a warning message */ -void pppd_error(char *, ...); /* log an error message */ -void pppd_fatal(char *, ...); /* log an error message and die(1) */ - -#define dbglog pppd_dbglog -#define info pppd_info -#define notice pppd_notice -#define warn pppd_warn -#define error pppd_error -#define fatal pppd_fatal - -/* Procedures exported from auth.c */ -void link_required(int); /* we are starting to use the link */ -void link_terminated(int); /* we are finished with the link */ -void link_down(int); /* the LCP layer has left the Opened state */ -void link_established(int); /* the link is up; authenticate now */ -void start_networks(void); /* start all the network control protos */ -void np_up(int, int); /* a network protocol has come up */ -void np_down(int, int); /* a network protocol has gone down */ -void np_finished(int, int); /* a network protocol no longer needs link */ -void auth_peer_fail(int, int); - /* peer failed to authenticate itself */ -void auth_peer_success(int, int, char *, int); - /* peer successfully authenticated itself */ -void auth_withpeer_fail(int, int); - /* we failed to authenticate ourselves */ -void auth_withpeer_success(int, int); - /* we successfully authenticated ourselves */ -int auth_check_options(void); - /* check authentication options supplied */ -void auth_reset(int); /* check what secrets we have */ -int check_passwd(int, char *, int, char *, int, char **); - /* Check peer-supplied username/password */ -int get_secret(int, char *, char *, unsigned char *, int *, int); - /* get "secret" for chap */ -int auth_ip_addr(int, uint32_t); - /* check if IP address is authorized */ -int bad_ip_adrs(uint32_t); - /* check if IP address is unreasonable */ - -/* Procedures exported from demand.c */ -void demand_conf(void); /* config interface(s) for demand-dial */ -void demand_block(void); /* set all NPs to queue up packets */ -void demand_unblock(void); /* set all NPs to pass packets */ -void demand_discard(void); /* set all NPs to discard packets */ -void demand_rexmit(int); /* retransmit saved frames for an NP */ -int loop_chars(unsigned char *, int); /* process chars from loopback */ -int loop_frame(unsigned char *, int); /* should we bring link up? */ - -/* Procedures exported from sys-*.c */ -void sys_init(void); /* Do system-dependent initialization */ -void sys_cleanup(void); /* Restore system state before exiting */ -int sys_check_options(void); /* Check options specified */ -void sys_close(void); /* Clean up in a child before execing */ -int ppp_available(void); /* Test whether ppp kernel support exists */ -int open_ppp_loopback(void); /* Open loopback for demand-dialling */ -int establish_ppp(int); /* Turn serial port into a ppp interface */ -void restore_loop(void); /* Transfer ppp unit back to loopback */ -void disestablish_ppp(int); /* Restore port to normal operation */ -void clean_check(void); /* Check if line was 8-bit clean */ -void set_up_tty(int, int); /* Set up port's speed, parameters, etc. */ -void restore_tty(int); /* Restore port's original parameters */ -void setdtr(int, int); /* Raise or lower port's DTR line */ -void output(int, u_char *, int); /* Output a PPP packet */ -void wait_input(struct timeval *); /* Wait for input, with timeout */ - -void ppp_delay(void); /* delay task for a little while */ -int read_packet(u_char *); /* Read PPP packet */ -int get_loop_output(void); /* Read pkts from loopback */ -void ppp_send_config(int, int, uint32_t, int, int); - /* Configure i/f transmit parameters */ -void ppp_set_xaccm(int, ext_accm); - /* Set extended transmit ACCM */ -void ppp_recv_config(int, int, uint32_t, int, int); - /* Configure i/f receive parameters */ -int ccp_test(int, u_char *, int, int); - /* Test support for compression scheme */ -void ccp_flags_set(int, int, int); - /* Set kernel CCP state */ -int ccp_fatal_error(int); /* Test for fatal decomp error in kernel */ -int get_idle_time(int, struct ppp_idle *); - /* Find out how long link has been idle */ -int get_ppp_stats(int, struct pppd_stats *); - /* Return link statistics */ -int sifvjcomp(int, int, int, int); - /* Configure VJ TCP header compression */ -int sifup(int); /* Configure i/f up for one protocol */ -int sifnpmode(int u, int proto, enum NPmode mode); - /* Set mode for handling packets for proto */ -int sifdown(int); /* Configure i/f down for one protocol */ -int sifaddr(int, uint32_t, uint32_t, uint32_t); - /* Configure IPv4 addresses for i/f */ -int cifaddr(int, uint32_t, uint32_t); - /* Reset i/f IP addresses */ -#ifdef INET6 -int sif6addr(int, eui64_t, eui64_t); - /* Configure IPv6 addresses for i/f */ -int cif6addr(int, eui64_t, eui64_t); - /* Remove an IPv6 address from i/f */ -#endif -int sifdefaultroute(int, uint32_t, uint32_t); - /* Create default route through i/f */ -int cifdefaultroute(int, uint32_t, uint32_t); - /* Delete default route through i/f */ -int sifproxyarp(int, uint32_t); - /* Add proxy ARP entry for peer */ -int cifproxyarp(int, uint32_t); - /* Delete proxy ARP entry for peer */ -uint32_t GetMask(uint32_t); /* Get appropriate netmask for address */ -int lock(char *); /* Create lock file for device */ -int relock(int); /* Rewrite lock file with new pid */ -void unlock(void); /* Delete previously-created lock file */ -void logwtmp(const char *, const char *, const char *); - /* Write entry to wtmp file */ -int get_host_seed(void); /* Get host-dependent random number seed */ -int have_route_to(uint32_t); /* Check if route to addr exists */ -#ifdef PPP_FILTER -int set_filters(struct bpf_program *pass, struct bpf_program *active); - /* Set filter programs in kernel */ -#endif -#ifdef IPX_CHANGE -int sipxfaddr(int, unsigned long, unsigned char *); -int cipxfaddr(int); -#endif - -/* Procedures exported from options.c */ -int parse_args(int argc, char **argv); - /* Parse options from arguments given */ -int options_from_file(char *filename, int must_exist, int check_prot, - int privileged); - /* Parse options from an options file */ -int options_from_user(void); /* Parse options from user's .ppprc */ -int options_for_tty(void); /* Parse options from /etc/ppp/options.tty */ -int options_from_list(struct wordlist *, int privileged); - /* Parse options from a wordlist */ -int getword(FILE *f, char *word, int *newlinep, char *filename); - /* Read a word from a file */ -void option_error(char *fmt, ...); - /* Print an error message about an option */ -int int_option(char *, int *); - /* Simplified number_option for decimal ints */ -void add_options(option_t *); /* Add extra options */ - -/* - * This structure is used to store information about certain - * options, such as where the option value came from (/etc/ppp/options, - * command line, etc.) and whether it came from a privileged source. - */ - -struct option_info { - int priv; /* was value set by sysadmin? */ - char *source; /* where option came from */ -}; - -extern struct option_info devnam_info; -extern struct option_info initializer_info; -extern struct option_info connect_script_info; -extern struct option_info disconnect_script_info; -extern struct option_info welcomer_info; -extern struct option_info ptycommand_info; - -/* - * Hooks to enable plugins to change various things. - */ -extern int (*new_phase_hook)(int); -extern int (*idle_time_hook)(struct ppp_idle *); -extern int (*holdoff_hook)(void); -extern int (*pap_check_hook)(void); -extern int (*pap_auth_hook)(char *user, char *passwd/*, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts*/); -extern void (*pap_logout_hook)(void); -extern int (*pap_passwd_hook)(char *user, char *passwd); -extern void (*ip_up_hook)(void); -extern void (*ip_down_hook)(void); -extern void (*auth_linkup_hook)(void); -extern void (*auth_linkdown_hook)(void); - -/* - * Inline versions of get/put char/short/long. - * Pointer is advanced; we assume that both arguments - * are lvalues and will already be in registers. - * cp MUST be u_char *. - */ -#define GETCHAR(c, cp) { \ - (c) = *(cp)++; \ -} -#define PUTCHAR(c, cp) { \ - *(cp)++ = (u_char) (c); \ -} - - -#define GETSHORT(s, cp) { \ - (s) = *(cp)++ << 8; \ - (s) |= *(cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s); \ -} - -#define GETLONG(l, cp) { \ - (l) = *(cp)++ << 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; \ -} -#define PUTLONG(l, cp) { \ - *(cp)++ = (u_char) ((l) >> 24); \ - *(cp)++ = (u_char) ((l) >> 16); \ - *(cp)++ = (u_char) ((l) >> 8); \ - *(cp)++ = (u_char) (l); \ -} - -#define INCPTR(n, cp) ((cp) += (n)) -#define DECPTR(n, cp) ((cp) -= (n)) - -/* - * System dependent definitions for user-level 4.3BSD UNIX implementation. - */ - -#define TIMEOUT(r, f, t) ppptimeout((r), (f), (t)) -#define UNTIMEOUT(r, f) pppuntimeout((r), (f)) - -#define BCOPY(s, d, l) memcpy(d, s, l) -#define BZERO(s, n) memset(s, 0, n) - -#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); } - -/* - * MAKEHEADER - Add Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } - -/* - * Exit status values. - */ -#define EXIT_OK 0 -#define EXIT_FATAL_ERROR 1 -#define EXIT_OPTION_ERROR 2 -#define EXIT_NOT_ROOT 3 -#define EXIT_NO_KERNEL_SUPPORT 4 -#define EXIT_USER_REQUEST 5 -#define EXIT_LOCK_FAILED 6 -#define EXIT_OPEN_FAILED 7 -#define EXIT_CONNECT_FAILED 8 -#define EXIT_PTYCMD_FAILED 9 -#define EXIT_NEGOTIATION_FAILED 10 -#define EXIT_PEER_AUTH_FAILED 11 -#define EXIT_IDLE_TIMEOUT 12 -#define EXIT_CONNECT_TIME 13 -#define EXIT_CALLBACK 14 -#define EXIT_PEER_DEAD 15 -#define EXIT_HANGUP 16 -#define EXIT_LOOPBACK 17 -#define EXIT_INIT_FAILED 18 -#define EXIT_AUTH_TOPEER_FAILED 19 - -/* - * Debug macros. Slightly useful for finding bugs in pppd, not particularly - * useful for finding out why your connection isn't being established. - */ - -#ifdef DEBUGALL -#define DEBUGMAIN 1 -#define DEBUGFSM 1 -#define DEBUGLCP 1 -#define DEBUGIPCP 1 -#define DEBUGIPV6CP 1 -#define DEBUGUPAP 1 -#define DEBUGCHAP 1 -#endif -#define DEBUGMAIN 1 -#define DEBUGUPAP 1 -#define DEBUGCHAP 1 - - -#ifdef DEBUGMAIN -#define MAINDEBUG(x) if (debug) dbglog x -#else -#define MAINDEBUG(x) -#endif - -#ifdef DEBUGSYS -#define SYSDEBUG(x) if (debug) dbglog x -#else -#define SYSDEBUG(x) -#endif - -#ifdef DEBUGFSM -#define FSMDEBUG(x) if (debug) dbglog x -#else -#define FSMDEBUG(x) -#endif - -#ifdef DEBUGLCP -#define LCPDEBUG(x) if (debug) dbglog x -#else -#define LCPDEBUG(x) -#endif - -#ifdef DEBUGIPCP -#define IPCPDEBUG(x) if (debug) dbglog x -#else -#define IPCPDEBUG(x) -#endif - -#ifdef DEBUGIPV6CP -#define IPV6CPDEBUG(x) if (debug) dbglog x -#else -#define IPV6CPDEBUG(x) -#endif - -#ifdef DEBUGUPAP -#define UPAPDEBUG(x) if (debug) dbglog x -#else -#define UPAPDEBUG(x) -#endif - -#ifdef DEBUGCHAP -#define CHAPDEBUG(x) if (debug) dbglog x -#else -#define CHAPDEBUG(x) -#endif - -#ifdef DEBUGIPXCP -#define IPXCPDEBUG(x) if (debug) dbglog x -#else -#define IPXCPDEBUG(x) -#endif - -#ifndef SIGTYPE -#if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) -#define SIGTYPE void -#else -#define SIGTYPE int -#endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */ -#endif /* SIGTYPE */ - -#endif /* __PPP_H__ */ diff --git a/cpukit/pppd/rtemsmain.c b/cpukit/pppd/rtemsmain.c deleted file mode 100644 index 71cf94f297..0000000000 --- a/cpukit/pppd/rtemsmain.c +++ /dev/null @@ -1,892 +0,0 @@ -/* - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "pppd.h" -#include "magic.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#ifdef INET6 -#include "ipv6cp.h" -#endif -#include "upap.h" -#include "chap.h" -#include "ccp.h" -#include "pathnames.h" -#include "patchlevel.h" -#include - -#ifdef CBCP_SUPPORT -#include "cbcp.h" -#endif - -#ifdef IPX_CHANGE -#include "ipxcp.h" -#endif /* IPX_CHANGE */ -#ifdef AT_CHANGE -#include "atcp.h" -#endif - -/* interface vars */ -char ifname[32]; /* Interface name */ -int pppifunit; /* Interface unit number */ - -char hostname[MAXNAMELEN]; /* Our hostname */ -static char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ - -int pppd_ttyfd; /* Serial port file descriptor */ -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 detached; /* have detached from terminal */ -struct stat devstat; /* result of stat() on devnam */ -int prepass = 0; /* doing prepass to find device name */ -int devnam_fixed; /* set while in options.ttyxx file */ -volatile int pppd_status; /* exit status for pppd */ -int unsuccess; /* # unsuccessful connection attempts */ -int do_callback; /* != 0 if we should do callback next */ -int doing_callback; /* != 0 if we are doing callback */ -char *callback_script; /* script for doing callback */ -dialerfp pppd_dialer; - -int (*holdoff_hook)(void) = NULL; -int (*new_phase_hook)(int) = NULL; - -static int fd_ppp = -1; /* fd for talking PPP */ -static int pty_master; /* fd for master side of pty */ -static int pty_slave; /* fd for slave side of pty */ -static int real_ttyfd; /* fd for actual serial port (not pty) */ - -int pppd_phase; /* where the link is at */ -int pppd_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"; - -static struct timeval start_time; /* Time when link was started. */ - -struct pppd_stats link_stats; -int link_connect_time; -int link_stats_valid; - -/* Prototypes for procedures local to this file. */ - -static void cleanup(void); -static void close_tty(void); -static void get_input(void); -static void calltimeout(void); -static struct timeval *timeleft(struct timeval *); -static void holdoff_end(void *); -static int device_script(int, int, char *); - -extern char *ttyname(int); -extern char *getlogin(void); -int pppdmain(int, char *[]); - -/* - * PPP Data Link Layer "protocol" table. - * One entry per supported protocol. - * The last entry must be NULL. - */ -struct protent *protocols[] = { - &lcp_protent, - &pap_protent, - &chap_protent, -#ifdef CBCP_SUPPORT - &cbcp_protent, -#endif - &ipcp_protent, -#ifdef INET6 - &ipv6cp_protent, -#endif - &ccp_protent, -#ifdef IPX_CHANGE - &ipxcp_protent, -#endif -#ifdef AT_CHANGE - &atcp_protent, -#endif - NULL -}; - -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; -} - -/* - * holdoff_end - called via a timeout when the holdoff period ends. - */ -static void -holdoff_end( - void *arg) -{ - new_phase(PHASE_DORMANT); -} - -/* List of protocol names, to make our messages a little more informative. */ -struct protocol_list { - u_short proto; - const char *name; -} protocol_list[] = { - { 0x21, "IP" }, - { 0x23, "OSI Network Layer" }, - { 0x25, "Xerox NS IDP" }, - { 0x27, "DECnet Phase IV" }, - { 0x29, "Appletalk" }, - { 0x2b, "Novell IPX" }, - { 0x2d, "VJ compressed TCP/IP" }, - { 0x2f, "VJ uncompressed TCP/IP" }, - { 0x31, "Bridging PDU" }, - { 0x33, "Stream Protocol ST-II" }, - { 0x35, "Banyan Vines" }, - { 0x39, "AppleTalk EDDP" }, - { 0x3b, "AppleTalk SmartBuffered" }, - { 0x3d, "Multi-Link" }, - { 0x3f, "NETBIOS Framing" }, - { 0x41, "Cisco Systems" }, - { 0x43, "Ascom Timeplex" }, - { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, - { 0x47, "DCA Remote Lan" }, - { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, - { 0x4b, "SNA over 802.2" }, - { 0x4d, "SNA" }, - { 0x4f, "IP6 Header Compression" }, - { 0x6f, "Stampede Bridging" }, - { 0xfb, "single-link compression" }, - { 0xfd, "1st choice compression" }, - { 0x0201, "802.1d Hello Packets" }, - { 0x0203, "IBM Source Routing BPDU" }, - { 0x0205, "DEC LANBridge100 Spanning Tree" }, - { 0x0231, "Luxcom" }, - { 0x0233, "Sigma Network Systems" }, - { 0x8021, "Internet Protocol Control Protocol" }, - { 0x8023, "OSI Network Layer Control Protocol" }, - { 0x8025, "Xerox NS IDP Control Protocol" }, - { 0x8027, "DECnet Phase IV Control Protocol" }, - { 0x8029, "Appletalk Control Protocol" }, - { 0x802b, "Novell IPX Control Protocol" }, - { 0x8031, "Bridging NCP" }, - { 0x8033, "Stream Protocol Control Protocol" }, - { 0x8035, "Banyan Vines Control Protocol" }, - { 0x803d, "Multi-Link Control Protocol" }, - { 0x803f, "NETBIOS Framing Control Protocol" }, - { 0x8041, "Cisco Systems Control Protocol" }, - { 0x8043, "Ascom Timeplex" }, - { 0x8045, "Fujitsu LBLB Control Protocol" }, - { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, - { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, - { 0x804b, "SNA over 802.2 Control Protocol" }, - { 0x804d, "SNA Control Protocol" }, - { 0x804f, "IP6 Header Compression Control Protocol" }, - { 0x006f, "Stampede Bridging Control Protocol" }, - { 0x80fb, "Single Link Compression Control Protocol" }, - { 0x80fd, "Compression Control Protocol" }, - { 0xc021, "Link Control Protocol" }, - { 0xc023, "Password Authentication Protocol" }, - { 0xc025, "Link Quality Report" }, - { 0xc027, "Shiva Password Authentication Protocol" }, - { 0xc029, "CallBack Control Protocol (CBCP)" }, - { 0xc081, "Container Control Protocol" }, - { 0xc223, "Challenge Handshake Authentication Protocol" }, - { 0xc281, "Proprietary Authentication Protocol" }, - { 0, NULL }, -}; - -/* - * protocol_name - find a name for a PPP protocol. - */ -static const char * -protocol_name( - int proto) -{ - struct protocol_list *lp; - - for (lp = protocol_list; lp->proto != 0; ++lp) - if (proto == lp->proto) - return lp->name; - return NULL; -} - -/* - * get_input - called when incoming data is available. - */ -static void -get_input(void) -{ - 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) { - notice("Modem hangup"); - hungup = 1; - pppd_status = EXIT_HANGUP; - lcp_lowerdown(0); /* serial link is no longer available */ - link_terminated(0); - return; - } - - if (debug /*&& (debugflags & DBG_INPACKET)*/) - dbglog("rcvd %P", p, len); - - if (len < PPP_HDRLEN) { - MAINDEBUG(("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(("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 (pppd_phase <= PHASE_AUTHENTICATE - && !(protocol == PPP_LCP || protocol == PPP_LQR - || protocol == PPP_PAP || protocol == PPP_CHAP)) { - MAINDEBUG(("get_input: discarding proto 0x%x in phase %d", - protocol, pppd_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) { - const char *pname = protocol_name(protocol); - if (pname != NULL) - warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); - else - warn("Unsupported protocol 0x%x received", protocol); - } - lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); - - return; -} - -/* - * new_phase - signal the start of a new phase of pppd's operation. - */ -void -new_phase( - int p) -{ - pppd_phase = p; - if (new_phase_hook) - (*new_phase_hook)(p); -} - -/* - * die - clean up state and exit with the specified status. - */ -void -die( - int status) -{ - cleanup(); -} - -/* - * cleanup - restore anything which needs to be restored before we exit - */ -/* ARGSUSED */ -static void -cleanup(void) -{ - sys_cleanup(); - - if (fd_ppp >= 0) - disestablish_ppp(pppd_ttyfd); - if (real_ttyfd >= 0) - close_tty(); - - sys_close(); -} - -/* - * close_tty - restore the terminal device and close it. - */ -static void -close_tty(void) -{ - /* drop dtr to hang up */ - if (!default_device && modem) { - setdtr(real_ttyfd, 0); - /* - * This sleep is in case the serial port has CLOCAL set by default, - * and consequently will reassert DTR when we close the device. - */ - sleep(1); - } - - restore_tty(real_ttyfd); - - close(real_ttyfd); - real_ttyfd = -1; -} - -/* - * update_link_stats - get stats at link termination. - */ -void -update_link_stats( - int u) -{ - struct timeval now; - char numbuf[32]; - - if (!get_ppp_stats(u, &link_stats) - || gettimeofday(&now, NULL) < 0) - return; - link_connect_time = now.tv_sec - start_time.tv_sec; - link_stats_valid = 1; - - slprintf(numbuf, sizeof(numbuf), "%d", link_connect_time); - slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_out); - slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_in); -} - -struct callout { - struct timeval c_time; /* time at which to call routine */ - void *c_arg; /* argument to routine */ - void (*c_func)(void *); /* routine */ - struct callout *c_next; -}; - -static struct callout *callout = NULL; /* Callout list */ -static struct timeval timenow; /* Current time */ - -/* - * timeout - Schedule a timeout. - * - * Note that this timeout takes the number of seconds, NOT hz (as in - * the kernel). - */ -void -ppptimeout( - void (*func)(void *), - void *arg, - int time) -{ - struct callout *newp, *p, **pp; - - MAINDEBUG(("Timeout %p:%p in %d seconds.", func, arg, time)); - - /* - * Allocate timeout. - */ - if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) - fatal("Out of memory in timeout()!"); - newp->c_arg = arg; - newp->c_func = func; - gettimeofday(&timenow, NULL); - newp->c_time.tv_sec = timenow.tv_sec + time; - newp->c_time.tv_usec = timenow.tv_usec; - - /* - * Find correct place and link it in. - */ - for (pp = &callout; (p = *pp); pp = &p->c_next) - if (newp->c_time.tv_sec < p->c_time.tv_sec - || (newp->c_time.tv_sec == p->c_time.tv_sec - && newp->c_time.tv_usec < p->c_time.tv_usec)) - break; - newp->c_next = p; - *pp = newp; -} - - -/* - * untimeout - Unschedule a timeout. - */ -void -pppuntimeout( - void (*func)(void *), - void *arg) -{ - struct callout **copp, *freep; - - MAINDEBUG(("Untimeout %p:%p.", func, arg)); - - /* - * Find first matching timeout and remove it from the list. - */ - for (copp = &callout; (freep = *copp); copp = &freep->c_next) - if (freep->c_func == func && freep->c_arg == arg) { - *copp = freep->c_next; - free((char *) freep); - break; - } -} - - -/* - * calltimeout - Call any timeout routines which are now due. - */ -static void -calltimeout(void) -{ - struct callout *p; - - while (callout != NULL) { - p = callout; - - if (gettimeofday(&timenow, NULL) < 0) - fatal("Failed to get time of day: %m"); - if (!(p->c_time.tv_sec < timenow.tv_sec - || (p->c_time.tv_sec == timenow.tv_sec - && p->c_time.tv_usec <= timenow.tv_usec))) - break; /* no, it's not time yet */ - - callout = p->c_next; - (*p->c_func)(p->c_arg); - - free((char *) p); - } -} - - -/* - * timeleft - return the length of time until the next timeout is due. - */ -static struct timeval * -timeleft( - struct timeval *tvp) -{ - if (callout == NULL) - return NULL; - - gettimeofday(&timenow, NULL); - tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; - tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; - if (tvp->tv_usec < 0) { - tvp->tv_usec += 1000000; - tvp->tv_sec -= 1; - } - if (tvp->tv_sec < 0) - tvp->tv_sec = tvp->tv_usec = 0; - - return tvp; -} - -/* - * device_script - run a program to talk to the serial device - * (e.g. to run the connector or disconnector script). - */ -static int device_script(int fd, int mode, char *program) -{ - int iReturn = -1; - char pScript[128]; - - /* copyt script into temporary location */ - strcpy(pScript, program); - - /* check to see if dialer was initialized */ - if ( !pppd_dialer ) { - /* set default dialer to chatmain */ - pppd_dialer = chatmain; - } - - /* check to see if dialer is set */ - if ( pppd_dialer ) { - /* call the dialer */ - iReturn = (*pppd_dialer)(fd, mode, program); - } - - return ( -iReturn ); -} - -/* - * novm - log an error message saying we ran out of memory, and die. - */ -void -novm( - char *msg) -{ - fatal("Virtual memory exhausted allocating %s\n", msg); -} diff --git a/cpukit/pppd/rtemspppd.c b/cpukit/pppd/rtemspppd.c deleted file mode 100644 index e6b1b18639..0000000000 --- a/cpukit/pppd/rtemspppd.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * COPYRIGHT (c) 2001, Michael Siers . - * Poliac Research, Burnsville, Minnesota USA. - * COPYRIGHT (c) 2001, On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * $Id$ - */ - -#include -#include -#include "pppd.h" -#include - - -/* define pppd function prototypes */ -extern void pppasyncattach(void); -extern int pppdmain(int, char **); - -/* define global variables */ -rtems_id rtems_pppd_taskid; -rtems_pppd_hookfunction rtems_pppd_errorfp; -rtems_pppd_hookfunction rtems_pppd_exitfp; - - -static rtems_task pppTask(rtems_task_argument arg) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - rtems_option options; - rtems_event_set in; - rtems_event_set out; - int iStatus; - - /* call function to setup ppp line discipline */ - pppasyncattach(); - - /* enter processing loop */ - in = (RTEMS_EVENT_29 | RTEMS_EVENT_30); - options = (RTEMS_EVENT_ANY | RTEMS_WAIT); - while ( sc == RTEMS_SUCCESSFUL ) { - /* wait for the next event */ - sc = rtems_event_receive(in, options, RTEMS_NO_TIMEOUT, &out); - if ( sc == RTEMS_SUCCESSFUL ) { - /* determine which event was sent */ - if ( out & RTEMS_EVENT_29 ) { - /* terminate event received */ - /* set value to break out of event loop */ - sc = RTEMS_UNSATISFIED; - } - else if ( out & RTEMS_EVENT_30 ) { - /* connect request */ - /* execute the pppd main code */ - iStatus = pppdmain(0, NULL); - if ( iStatus == EXIT_OK ) { - /* check exit callback */ - if ( rtems_pppd_exitfp ) { - (*rtems_pppd_exitfp)(); - } - } - else { - /* check error callback */ - if ( rtems_pppd_errorfp ) { - (*rtems_pppd_errorfp)(); - } - } - } - } - } - - /* terminate myself */ - rtems_pppd_taskid = 0; - rtems_task_exit(); -} - -int rtems_pppd_initialize(void) -{ - int iReturn = (int)-1; - rtems_task_priority priority = 100; - rtems_status_code status; - rtems_name taskName; - - /* determine priority value */ - if ( rtems_bsdnet_config.network_task_priority ) { - priority = rtems_bsdnet_config.network_task_priority; - } - - /* initialize the exit hook */ - rtems_pppd_exitfp = (rtems_pppd_hookfunction)0; - - /* create the rtems task */ - taskName = rtems_build_name( 'p', 'p', 'p', 'd' ); - status = rtems_task_create(taskName, priority, 8192, - (RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0)), - RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL, - &rtems_pppd_taskid); - if ( status == RTEMS_SUCCESSFUL ) { - status = rtems_task_start(rtems_pppd_taskid, pppTask, 0); - if ( status == RTEMS_SUCCESSFUL ) { - iReturn = rtems_pppd_reset_options(); - } - } - - return ( iReturn ); -} - -int rtems_pppd_terminate(void) -{ - /* send terminate signal to pppd task */ - rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_29); - - /* call the disconnect function */ - rtems_pppd_disconnect(); - - return ( 0 ); -} - -int rtems_pppd_reset_options(void) -{ - int i; - struct protent *protp; - - /* - * 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); - - return ( 0 ); -} - -int rtems_pppd_set_hook(int id, rtems_pppd_hookfunction hookfp) -{ - int iReturn = (int)0; - - switch ( id ) { - case RTEMS_PPPD_LINKUP_HOOK: - auth_linkup_hook = hookfp; - break; - case RTEMS_PPPD_LINKDOWN_HOOK: - auth_linkdown_hook = hookfp; - break; - case RTEMS_PPPD_IPUP_HOOK: - ip_up_hook = hookfp; - break; - case RTEMS_PPPD_IPDOWN_HOOK: - ip_down_hook = hookfp; - break; - case RTEMS_PPPD_ERROR_HOOK: - rtems_pppd_errorfp = hookfp; - break; - case RTEMS_PPPD_EXIT_HOOK: - rtems_pppd_exitfp = hookfp; - break; - default: - iReturn = (int)-1; - break; - } - - return ( iReturn ); -} - -int rtems_pppd_set_dialer(rtems_pppd_dialerfunction dialerfp) -{ - pppd_dialer = dialerfp; - return ( (int)0 ); -} - -int rtems_pppd_set_option(const char *pOption, const char *pValue) -{ - int iReturn = (int)0; - int prevPhase; - struct wordlist option; - struct wordlist value; - - if ( pOption != (const char *)0 ) { - /* initialize the values */ - option.word = (char *)pOption; - option.next = (struct wordlist *)0; - if ( pValue != (const char *)0 ) { - option.next = &value; - value.word = (char *)pValue; - value.next = (struct wordlist *)0; - } - - /* save current phase value */ - prevPhase = pppd_phase; - pppd_phase = PHASE_INITIALIZE; - - /* process option and reset phase value */ - iReturn = options_from_list(&option, 1); - pppd_phase = prevPhase; - } - - return ( iReturn ); -} - -int rtems_pppd_connect(void) -{ - /* send connect signal to pppd task */ - rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_30); - - return ( 0 ); -} - -static void timeout_terminate(void *arg) -{ - /* set pppd global variables to disconnect */ - persist = 0; - pppd_kill_link = 1; -} - -int rtems_pppd_disconnect(void) -{ - /* need to wait a little time before we can bring the link down */ - /* set up time out in 1 seconds */ - TIMEOUT(timeout_terminate, NULL, 1); - - /* send event to wake up the pppd code */ - /* pretend its a serial interrput */ - rtems_event_send(rtems_pppd_taskid, RTEMS_EVENT_31); - - return ( 0 ); -} diff --git a/cpukit/pppd/sys-rtems.c b/cpukit/pppd/sys-rtems.c deleted file mode 100644 index f973795b2c..0000000000 --- a/cpukit/pppd/sys-rtems.c +++ /dev/null @@ -1,1321 +0,0 @@ -/* - * sys-bsd.c - System-dependent procedures for setting up - * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.) - * - * Copyright (c) 1989 Carnegie Mellon University. - * Copyright (c) 1995 The Australian National 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 and The Australian National University. - * The names of the Universities 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PPP_FILTER -#include -#endif - -#include -#include -#include -#include -#include -#include - -#if RTM_VERSION >= 3 -#include -#if defined(NetBSD) && (NetBSD >= 199703) -#include -#else /* NetBSD 1.2D or later */ -#include -#endif -#endif - -#include -#include -#include -extern int rtems_bsdnet_microseconds_per_tick; -extern rtems_id rtems_pppd_taskid; - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" - -static int initdisc = -1; /* Initial TTY discipline for ppp_fd */ -static int initfdflags = -1; /* Initial file descriptor flags for ppp_fd */ -static int ppp_fd = -1; /* fd which is set to PPP discipline */ -static int rtm_seq; - -static int restore_term; /* 1 => we've munged the terminal */ -static struct termios inittermios; /* Initial TTY termios */ -static struct winsize wsinfo; /* Initial window size info */ - -static int loop_slave = -1; -static int loop_master; - -static unsigned char inbuf[512]; /* buffer for chars read from loopback */ - -static int sockfd; /* socket for doing interface ioctls */ - -static int if_is_up; /* the interface is currently up */ -static uint32_t ifaddrs[2]; /* local and remote addresses we set */ -static uint32_t default_route_gateway; /* gateway addr for default route */ -static uint32_t proxy_arp_addr; /* remote addr for proxy arp */ - -/* Prototypes for procedures local to this file. */ -static int dodefaultroute(uint32_t, int); -static int get_ether_addr(uint32_t, struct sockaddr_dl *); - - -/* - * sys_init - System-dependent initialization. - */ -void -sys_init(void) -{ - /* Get an internet socket for doing socket ioctl's on. */ - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - fatal("Couldn't create IP socket: %m"); -} - -/* - * sys_cleanup - restore any system state we modified before exiting: - * mark the interface down, delete default route and/or proxy arp entry. - * This should call die() because it's called from die(). - */ -void -sys_cleanup(void) -{ - struct ifreq ifr; - - if (if_is_up) { - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0 - && ((ifr.ifr_flags & IFF_UP) != 0)) { - ifr.ifr_flags &= ~IFF_UP; - ioctl(sockfd, SIOCSIFFLAGS, &ifr); - } - } - if (ifaddrs[0] != 0) - cifaddr(0, ifaddrs[0], ifaddrs[1]); - if (default_route_gateway) - cifdefaultroute(0, 0, default_route_gateway); - if (proxy_arp_addr) - cifproxyarp(0, proxy_arp_addr); -} - -/* - * sys_close - Clean up in a child process before execing. - */ -void -sys_close(void) -{ - close(sockfd); - if (loop_slave >= 0) { - close(loop_slave); - close(loop_master); - } -} - -/* - * sys_check_options - check the options that the user specified - */ -int -sys_check_options(void) -{ - return 1; -} - -/* - * ppp_available - check whether the system has any ppp interfaces - * (in fact we check whether we can do an ioctl on ppp0). - */ -int -ppp_available(void) -{ - int s, ok; - struct ifreq ifr; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - return 1; /* can't tell */ - - strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; - close(s); - - return ok; -} - -/* - * establish_ppp - Turn the serial port into a ppp interface. - */ -int -establish_ppp( - int fd) -{ - int taskid = (int)rtems_pppd_taskid; - int pppdisc = PPPDISC; - int x; - - if (demand) { - /* - * Demand mode - prime the old ppp device to relinquish the unit. - */ - if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0) - fatal("ioctl(transfer ppp unit): %m"); - } - - /* - * Save the old line discipline of fd, and set it to PPP. - */ - if (ioctl(fd, TIOCGETD, &initdisc) < 0) - fatal("ioctl(TIOCGETD): %m"); - if (ioctl(fd, TIOCSETD, &pppdisc) < 0) - fatal("ioctl(TIOCSETD): %m"); - - /* set pppd taskid into the driver */ - ioctl(fd, PPPIOCSTASK, &taskid); - - if (!demand) { - /* - * Find out which interface we were given. - */ - if (ioctl(fd, PPPIOCGUNIT, &pppifunit) < 0) - fatal("ioctl(PPPIOCGUNIT): %m"); - } else { - /* - * Check that we got the same unit again. - */ - if (ioctl(fd, PPPIOCGUNIT, &x) < 0) - fatal("ioctl(PPPIOCGUNIT): %m"); - if (x != pppifunit) - fatal("transfer_ppp failed: wanted unit %d, got %d", pppifunit, x); - x = TTYDISC; - ioctl(loop_slave, TIOCSETD, &x); - } - - ppp_fd = fd; - - /* - * Enable debug in the driver if requested. - */ - if (kdebugflag) { - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - warn("ioctl (PPPIOCGFLAGS): %m"); - } else { - x |= (kdebugflag & 0xFF) * SC_DEBUG; - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) - warn("ioctl(PPPIOCSFLAGS): %m"); - } - } - - /* - * Set device for non-blocking reads. - */ - if ((initfdflags = fcntl(fd, F_GETFL)) == -1 - || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { - warn("Couldn't set device to non-blocking mode: %m"); - } - - return fd; -} - -/* - * restore_loop - reattach the ppp unit to the loopback. - */ -void -restore_loop(void) -{ - int x; - - /* - * Transfer the ppp interface back to the loopback. - */ - if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0) - fatal("ioctl(transfer ppp unit): %m"); - x = PPPDISC; - if (ioctl(loop_slave, TIOCSETD, &x) < 0) - fatal("ioctl(TIOCSETD): %m"); - - /* - * Check that we got the same unit again. - */ - if (ioctl(loop_slave, PPPIOCGUNIT, &x) < 0) - fatal("ioctl(PPPIOCGUNIT): %m"); - if (x != pppifunit) - fatal("transfer_ppp failed: wanted unit %d, got %d", pppifunit, x); - ppp_fd = loop_slave; -} - - -/* - * disestablish_ppp - Restore the serial port to normal operation. - * This shouldn't call die() because it's called from die(). - */ -void -disestablish_ppp( - int fd) -{ - int taskid = (int)0; - - /* clear pppd taskid from the driver */ - ioctl(fd, PPPIOCSTASK, &taskid); - - /* Reset non-blocking mode on fd. */ - if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0) - warn("Couldn't restore device fd flags: %m"); - initfdflags = -1; - - /* Restore old line discipline. */ - if (initdisc >= 0 && ioctl(fd, TIOCSETD, &initdisc) < 0) - error("ioctl(TIOCSETD): %m"); - initdisc = -1; - - if (fd == ppp_fd) - ppp_fd = -1; -} - -/* - * Check whether the link seems not to be 8-bit clean. - */ -void -clean_check(void) -{ - int x; - char *s; - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { - s = NULL; - switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { - case SC_RCV_B7_0: - s = "bit 7 set to 1"; - break; - case SC_RCV_B7_1: - s = "bit 7 set to 0"; - break; - case SC_RCV_EVNP: - s = "odd parity"; - break; - case SC_RCV_ODDP: - s = "even parity"; - break; - } - if (s != NULL) { - warn("Serial link is not 8-bit clean:"); - warn("All received characters had %s", s); - } - } -} - -/* - * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, - * at the requested speed, etc. If `local' is true, set CLOCAL - * regardless of whether the modem option was specified. - * - * For *BSD, we assume that speed_t values numerically equal bits/second. - */ -void -set_up_tty( - int fd, int local) -{ - struct termios tios; - - if (tcgetattr(fd, &tios) < 0) - fatal("tcgetattr: %m"); - - if (!restore_term) { - inittermios = tios; - ioctl(fd, TIOCGWINSZ, &wsinfo); - } - - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); - if (crtscts > 0 && !local) { - if (crtscts == 2) { -#ifdef CDTRCTS - tios.c_cflag |= CDTRCTS; -#endif - } else - tios.c_cflag |= CRTSCTS; - } else if (crtscts < 0) { - tios.c_cflag &= ~CRTSCTS; -#ifdef CDTRCTS - tios.c_cflag &= ~CDTRCTS; -#endif - } - - tios.c_cflag |= CS8 | CREAD | HUPCL; - if (local || !modem) - tios.c_cflag |= CLOCAL; - tios.c_iflag = IGNBRK | IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - tios.c_cc[VMIN] = 1; - tios.c_cc[VTIME] = 0; - - if (crtscts == -2) { - tios.c_iflag |= IXON | IXOFF; - tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ - tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ - } - - if (inspeed) { - cfsetospeed(&tios, inspeed); - cfsetispeed(&tios, inspeed); - } else { - inspeed = cfgetospeed(&tios); - /* - * We can't proceed if the serial port speed is 0, - * since that implies that the serial port is disabled. - */ - if (inspeed == 0) - fatal("Baud rate for %s is 0; need explicit baud rate", devnam); - } - baud_rate = inspeed; - -/* if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { */ - if (tcsetattr(fd, TCSADRAIN, &tios) < 0) { - fatal("tcsetattr: %m"); - } - - restore_term = 1; -} - -/* - * restore_tty - restore the terminal to the saved settings. - */ -void -restore_tty( - int fd) -{ - if (restore_term) { - if (!default_device) { - /* - * Turn off echoing, because otherwise we can get into - * a loop with the tty and the modem echoing to each other. - * We presume we are the sole user of this tty device, so - * when we close it, it will revert to its defaults anyway. - */ - inittermios.c_lflag &= ~(ECHO | ECHONL); - } -/* if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) { */ - if (tcsetattr(fd, TCSADRAIN, &inittermios) < 0) { - if (errno != ENXIO) - warn("tcsetattr: %m"); - } - ioctl(fd, TIOCSWINSZ, &wsinfo); - restore_term = 0; - } -} - -/* - * setdtr - control the DTR line on the serial port. - * This is called from die(), so it shouldn't call die(). - */ -void -setdtr( - int fd, int on ) -{ - int modembits = TIOCM_DTR; - - ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); -} - - -/* - * open_ppp_loopback - open the device we use for getting - * packets in demand mode, and connect it to a ppp interface. - * Here we use a pty. - */ -int -open_ppp_loopback(void) -{ - return loop_master; -} - - -/* - * output - Output PPP packet. - */ -void -output( - int unit, - u_char *p, - int len) -{ - if (debug) - dbglog("sent %P", p, len); -/* printf("sent packet [%d]\n", len); */ - - if (write(pppd_ttyfd, p, len) < 0) { - if (errno != EIO) - error("write: %m"); - } -} - -void -ppp_delay(void) -{ - rtems_interval ticks; - - /* recommended delay to help negotiation */ - ticks = 300000/rtems_bsdnet_microseconds_per_tick; - rtems_task_wake_after(ticks); -} - -/* - * wait_input - wait until there is data available, - * for the length of time specified by *timo (indefinite - * if timo is NULL). - */ -void -wait_input( - struct timeval *timo) -{ - rtems_event_set events; - rtems_interval ticks = 0; - rtems_option wait = RTEMS_WAIT; - - if(timo) { - if(timo->tv_sec == 0 && timo->tv_usec == 0) - wait = RTEMS_NO_WAIT; - else { - ticks = (timo->tv_sec * 1000000 + timo->tv_usec) / - rtems_bsdnet_microseconds_per_tick; - if(ticks <= 0) - ticks = 1; - } - } - rtems_event_receive(RTEMS_EVENT_31, RTEMS_EVENT_ANY | wait, ticks, &events); -} - -/* - * read_packet - get a PPP packet from the serial device. - */ -int -read_packet( - u_char *buf) -{ - int len; - - if ((len = read(pppd_ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) { - if (errno == EWOULDBLOCK || errno == EINTR) len = -1; - /*fatal("read: %m"); */ - } - -/* printf("read packet [%d]\n", len); */ - return len; -} - - -/* - * get_loop_output - read characters from the loopback, form them - * into frames, and detect when we want to bring the real link up. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -get_loop_output(void) -{ - int rv = 0; - int n; - - while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) { - if (loop_chars(inbuf, n)) - rv = 1; - } - - if (n == 0) - fatal("eof on loopback"); - if (errno != EWOULDBLOCK) - fatal("read from loopback: %m"); - - return rv; -} - - -/* - * ppp_send_config - configure the transmit characteristics of - * the ppp interface. - */ -void -ppp_send_config( - int unit, - int mtu, - uint32_t asyncmap, - int pcomp, - int accomp) -{ - u_int x; - struct ifreq ifr; - - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) - fatal("ioctl(SIOCSIFMTU): %m"); - - if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) - fatal("ioctl(PPPIOCSASYNCMAP): %m"); - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) - fatal("ioctl (PPPIOCGFLAGS): %m"); - x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT; - x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC; -/* x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC; */ - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) - fatal("ioctl(PPPIOCSFLAGS): %m"); -} - - -/* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. - */ -void -ppp_set_xaccm( - int unit, - ext_accm accm) -{ - if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) - warn("ioctl(set extended ACCM): %m"); -} - - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -void -ppp_recv_config( - int unit, - int mru, - uint32_t asyncmap, - int pcomp, int accomp) -{ - int x; - - if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) - fatal("ioctl(PPPIOCSMRU): %m"); - if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) - fatal("ioctl(PPPIOCSRASYNCMAP): %m"); - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) - fatal("ioctl (PPPIOCGFLAGS): %m"); - x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) - fatal("ioctl(PPPIOCSFLAGS): %m"); -} - -/* - * ccp_test - ask kernel whether a given compression method - * is acceptable for use. Returns 1 if the method and parameters - * are OK, 0 if the method is known but the parameters are not OK - * (e.g. code size should be reduced), or -1 if the method is unknown. - */ -int -ccp_test( - int unit, u_char *opt_ptr, int opt_len, int for_transmit) -{ - struct ppp_option_data data; - - data.ptr = opt_ptr; - data.length = opt_len; - data.transmit = for_transmit; - if (ioctl(pppd_ttyfd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0) - return 1; - return (errno == ENOBUFS)? 0: -1; -} - -/* - * ccp_flags_set - inform kernel about the current state of CCP. - */ -void -ccp_flags_set( - int unit, int isopen, int isup) -{ - int x; - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - error("ioctl (PPPIOCGFLAGS): %m"); - return; - } - x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN; - x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP; - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) - error("ioctl(PPPIOCSFLAGS): %m"); -} - -/* - * ccp_fatal_error - returns 1 if decompression was disabled as a - * result of an error detected after decompression of a packet, - * 0 otherwise. This is necessary because of patent nonsense. - */ -int -ccp_fatal_error( - int unit) -{ - int x; - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - error("ioctl(PPPIOCGFLAGS): %m"); - return 0; - } - return x & SC_DC_FERROR; -} - -/* - * get_idle_time - return how long the link has been idle. - */ -int -get_idle_time( - int u, - struct ppp_idle *ip) -{ - return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0; -} - -/* - * get_ppp_stats - return statistics for the link. - */ -int -get_ppp_stats( - int u, - struct pppd_stats *stats) -{ - struct ifpppstatsreq req; - - memset (&req, 0, sizeof (req)); - strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name)); - if (ioctl(sockfd, SIOCGPPPSTATS, &req) < 0) { - error("Couldn't get PPP statistics: %m"); - return 0; - } - stats->bytes_in = req.stats.p.ppp_ibytes; - stats->bytes_out = req.stats.p.ppp_obytes; - return 1; -} - - -#ifdef PPP_FILTER -/* - * set_filters - transfer the pass and active filters to the kernel. - */ -int -set_filters( - struct bpf_program *pass, struct bpf_program *active) -{ - int ret = 1; - - if (pass->bf_len > 0) { - if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) { - error("Couldn't set pass-filter in kernel: %m"); - ret = 0; - } - } - if (active->bf_len > 0) { - if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) { - error("Couldn't set active-filter in kernel: %m"); - ret = 0; - } - } - return ret; -} -#endif - -/* - * sifvjcomp - config tcp header compression - */ -int -sifvjcomp( - int u, int vjcomp, int cidcomp, int maxcid) -{ - u_int x; - - if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { - error("ioctl (PPPIOCGFLAGS): %m"); - return 0; - } - x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP; - x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID; - if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { - error("ioctl(PPPIOCSFLAGS): %m"); - return 0; - } - if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { - error("ioctl(PPPIOCSMAXCID): %m"); - return 0; - } - return 1; -} - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int -sifup( - int u) -{ - struct ifreq ifr; - - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - error("ioctl (SIOCGIFFLAGS): %m"); - return 0; - } - ifr.ifr_flags |= IFF_UP; - if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - error("ioctl(SIOCSIFFLAGS): %m"); - return 0; - } - if_is_up = 1; - return 1; -} - -/* - * sifnpmode - Set the mode for handling packets for a given NP. - */ -int -sifnpmode( - int u, - int proto, - enum NPmode mode) -{ - struct npioctl npi; - - npi.protocol = proto; - npi.mode = mode; - if (ioctl(ppp_fd, PPPIOCSNPMODE, &npi) < 0) { - error("ioctl(set NP %d mode to %d): %m", proto, mode); - return 0; - } - return 1; -} - -/* - * sifdown - Config the interface down and disable IP. - */ -int -sifdown( - int u) -{ - struct ifreq ifr; - int rv; - struct npioctl npi; - - rv = 1; - npi.protocol = PPP_IP; - npi.mode = NPMODE_ERROR; - ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi); - /* ignore errors, because ppp_fd might have been closed by now. */ - - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - error("ioctl (SIOCGIFFLAGS): %m"); - rv = 0; - } else { - ifr.ifr_flags &= ~IFF_UP; - if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - error("ioctl(SIOCSIFFLAGS): %m"); - rv = 0; - } else - if_is_up = 0; - } - return rv; -} - -/* - * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, - * if it exists. - */ -#define SET_SA_FAMILY(addr, family) \ - BZERO((char *) &(addr), sizeof(addr)); \ - addr.sa_family = (family); \ - addr.sa_len = sizeof(addr); - -/* - * sifaddr - Config the interface IP addresses and netmask. - */ -int -sifaddr( - int u, - uint32_t o, uint32_t h, uint32_t m ) -{ - struct ifaliasreq ifra; - struct ifreq ifr; - - strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); - SET_SA_FAMILY(ifra.ifra_addr, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; - SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; - if (m != 0) { - SET_SA_FAMILY(ifra.ifra_mask, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m; - } else - BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); - BZERO(&ifr, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) { - if (errno != EADDRNOTAVAIL) - warn("Couldn't remove interface address: %m"); - } - if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) { - if (errno != EEXIST) { - error("Couldn't set interface address: %m"); - return 0; - } - warn("Couldn't set interface address: Address %I already exists", o); - } - ifaddrs[0] = o; - ifaddrs[1] = h; - return 1; -} - -/* - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ -int -cifaddr( - int u, - uint32_t o, uint32_t h ) -{ - struct ifaliasreq ifra; - - ifaddrs[0] = 0; - strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); - SET_SA_FAMILY(ifra.ifra_addr, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; - SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); - ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; - BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); - if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) { - if (errno != EADDRNOTAVAIL) - warn("Couldn't delete interface address: %m"); - return 0; - } - return 1; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ -int -sifdefaultroute( - int u, - uint32_t l, uint32_t g) -{ - return dodefaultroute(g, 's'); -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ -int -cifdefaultroute( - int u, - uint32_t l, uint32_t g) -{ - return dodefaultroute(g, 'c'); -} - -/* - * dodefaultroute - talk to a routing socket to add/delete a default route. - */ -static int -dodefaultroute( - uint32_t g, - int cmd) -{ -/* int status; */ - struct sockaddr_in address; - struct sockaddr_in netmask; - struct sockaddr_in gateway; - - memset((void *) &address, 0, sizeof(address)); - address.sin_len = sizeof address; - address.sin_family = AF_INET; - address.sin_addr.s_addr = INADDR_ANY; - - memset((void *) &netmask, 0, sizeof(netmask)); - netmask.sin_len = sizeof netmask; - netmask.sin_addr.s_addr = INADDR_ANY; - netmask.sin_family = AF_INET; - - if (cmd=='s') { - memset((void *) &gateway, 0, sizeof(gateway)); - gateway.sin_len = sizeof gateway; - gateway.sin_family = AF_INET; - gateway.sin_addr.s_addr = g; - - rtems_bsdnet_rtrequest(RTM_ADD, - (struct sockaddr *)&address, - (struct sockaddr *)&gateway, - (struct sockaddr *)&netmask, - (RTF_UP|RTF_GATEWAY|RTF_STATIC), NULL); - } - else { - memset((void *) &gateway, 0, sizeof(gateway)); - gateway.sin_len = sizeof gateway; - gateway.sin_family = AF_INET; - gateway.sin_addr.s_addr = INADDR_ANY; - - rtems_bsdnet_rtrequest(RTM_DELETE, - (struct sockaddr *)&address, - (struct sockaddr *)&gateway, - (struct sockaddr *)&netmask, - (RTF_UP|RTF_STATIC), NULL); - } - - default_route_gateway = (cmd == 's')? g: 0; - - return 1; -} - -#if RTM_VERSION >= 3 - -/* - * sifproxyarp - Make a proxy ARP entry for the peer. - */ -static struct { - struct rt_msghdr hdr; - struct sockaddr_inarp dst; - struct sockaddr_dl hwa; - char extra[128]; -} arpmsg; - -static int arpmsg_valid; - -int -sifproxyarp( - int unit, - uint32_t hisaddr) -{ - int routes; - - /* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - memset(&arpmsg, 0, sizeof(arpmsg)); - if (!get_ether_addr(hisaddr, &arpmsg.hwa)) { - error("Cannot determine ethernet address for proxy ARP"); - return 0; - } - - if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { - error("Couldn't add proxy arp entry: socket: %m"); - return 0; - } - - arpmsg.hdr.rtm_type = RTM_ADD; - arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC; - arpmsg.hdr.rtm_version = RTM_VERSION; - arpmsg.hdr.rtm_seq = ++rtm_seq; - arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; - arpmsg.hdr.rtm_inits = RTV_EXPIRE; - arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp); - arpmsg.dst.sin_family = AF_INET; - arpmsg.dst.sin_addr.s_addr = hisaddr; - arpmsg.dst.sin_other = SIN_PROXY; - - arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg - + arpmsg.hwa.sdl_len; - if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { - error("Couldn't add proxy arp entry: %m"); - close(routes); - return 0; - } - - close(routes); - arpmsg_valid = 1; - proxy_arp_addr = hisaddr; - return 1; -} - -/* - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ -int -cifproxyarp( - int unit, - uint32_t hisaddr) -{ - int routes; - - if (!arpmsg_valid) - return 0; - arpmsg_valid = 0; - - arpmsg.hdr.rtm_type = RTM_DELETE; - arpmsg.hdr.rtm_seq = ++rtm_seq; - - if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { - error("Couldn't delete proxy arp entry: socket: %m"); - return 0; - } - - if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { - error("Couldn't delete proxy arp entry: %m"); - close(routes); - return 0; - } - - close(routes); - proxy_arp_addr = 0; - return 1; -} - -#else /* RTM_VERSION */ - -/* - * sifproxyarp - Make a proxy ARP entry for the peer. - */ -int -sifproxyarp( - int unit, - uint32_t hisaddr) -{ - struct arpreq arpreq; - struct { - struct sockaddr_dl sdl; - char space[128]; - } dls; - - BZERO(&arpreq, sizeof(arpreq)); - - /* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - if (!get_ether_addr(hisaddr, &dls.sdl)) { - error("Cannot determine ethernet address for proxy ARP"); - return 0; - } - - arpreq.arp_ha.sa_len = sizeof(struct sockaddr); - arpreq.arp_ha.sa_family = AF_UNSPEC; - BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; - if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { - error("Couldn't add proxy arp entry: %m"); - return 0; - } - - proxy_arp_addr = hisaddr; - return 1; -} - -/* - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ -int -cifproxyarp( - int unit, - uint32_t hisaddr) -{ - struct arpreq arpreq; - - BZERO(&arpreq, sizeof(arpreq)); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; - if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) { - warn("Couldn't delete proxy arp entry: %m"); - return 0; - } - proxy_arp_addr = 0; - return 1; -} -#endif /* RTM_VERSION */ - - -/* - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. - */ -#define MAX_IFS 32 - -static int -get_ether_addr( - uint32_t ipaddr, - struct sockaddr_dl *hwaddr) -{ - struct ifreq *ifr, *ifend, *ifp; - uint32_t ina, mask; - struct sockaddr_dl *dla; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { - error("ioctl(SIOCGIFCONF): %m"); - return 0; - } - - /* - * Scan through looking for an interface with an Internet - * address on the same subnet as `ipaddr'. - */ - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *) - ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) { - if (ifr->ifr_addr.sa_family == AF_INET) { - ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - /* - * Check that the interface is up, and not point-to-point - * or loopback. - */ - if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) - continue; - if ((ifreq.ifr_flags & - (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) - != (IFF_UP|IFF_BROADCAST)) - continue; - /* - * Get its netmask and check that it's on the right subnet. - */ - if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; - if ((ipaddr & mask) != (ina & mask)) - continue; - - break; - } - } - - if (ifr >= ifend) - return 0; - info("found interface %s for proxy arp", ifr->ifr_name); - - /* - * Now scan through again looking for a link-level address - * for this interface. - */ - ifp = ifr; - for (ifr = ifc.ifc_req; ifr < ifend; ) { - if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0 - && ifr->ifr_addr.sa_family == AF_LINK) { - /* - * Found the link-level address - copy it out - */ - dla = (struct sockaddr_dl *) &ifr->ifr_addr; - BCOPY(dla, hwaddr, dla->sdl_len); - return 1; - } - ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len); - } - - return 0; -} - -/* - * Return user specified netmask, modified by any mask we might determine - * for address `addr' (in network byte order). - * Here we scan through the system's list of interfaces, looking for - * any non-point-to-point interfaces which might appear to be on the same - * network as `addr'. If we find any, we OR in their netmask to the - * user-specified netmask. - */ -uint32_t -GetMask( - uint32_t addr) -{ - uint32_t mask, nmask, ina; - struct ifreq *ifr, *ifend, ifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - - addr = ntohl(addr); - if (IN_CLASSA(addr)) /* determine network mask for address class */ - nmask = IN_CLASSA_NET; - else if (IN_CLASSB(addr)) - nmask = IN_CLASSB_NET; - else - nmask = IN_CLASSC_NET; - /* class D nets are disallowed by bad_ip_adrs */ - mask = netmask | htonl(nmask); - - /* - * Scan through the system's network interfaces. - */ - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { - warn("ioctl(SIOCGIFCONF): %m"); - return mask; - } - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *) - ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) { - /* - * Check the interface's internet address. - */ - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - if ((ntohl(ina) & nmask) != (addr & nmask)) - continue; - /* - * Check that the interface is up, and not point-to-point or loopback. - */ - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) - continue; - if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) - != IFF_UP) - continue; - /* - * Get its netmask and OR it into our mask. - */ - if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr; - } - - return mask; -} - -/* - * have_route_to - determine if the system has any route to - * a given IP address. - * For demand mode to work properly, we have to ignore routes - * through our own interface. - */ -int have_route_to(uint32_t addr) -{ - return -1; -} - -/* - * Use the hostid as part of the random number seed. - */ -int -get_host_seed(void) -{ - return 17; -} diff --git a/cpukit/pppd/upap.c b/cpukit/pppd/upap.c deleted file mode 100644 index 55700c5bda..0000000000 --- a/cpukit/pppd/upap.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * upap.c - User/Password Authentication Protocol. - * - * 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. - */ - -/* - * TODO: - */ - -#include -#include - -#include "pppd.h" -#include "upap.h" - -static bool hide_password = true; - -/* - * Command-line options. - */ -static option_t pap_option_list[] = { - { "hide-password", o_bool, &hide_password, - "Don't output passwords to log", 1, NULL, 0, 0 }, - { "show-password", o_bool, &hide_password, - "Show password string in debug log messages", 0, NULL, 0, 0 }, - { "pap-restart", o_int, &upap[0].us_timeouttime, - "Set retransmit timeout for PAP", 0, NULL, 0, 0 }, - { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, - "Set max number of transmissions for auth-reqs", 0, NULL, 0, 0 }, - { "pap-timeout", o_int, &upap[0].us_reqtimeout, - "Set time limit for peer PAP authentication", 0, NULL, 0, 0 }, - { NULL, 0, NULL, NULL, 0, NULL, 0, 0 } -}; - -/* - * Protocol entry points. - */ -static void upap_init(int); -static void upap_lowerup(int); -static void upap_lowerdown(int); -static void upap_input(int, u_char *, int); -static void upap_protrej(int); -static int upap_printpkt(u_char *, int, - void (*)(void *, char *, ...), void *); - -struct protent pap_protent = { - PPP_PAP, - upap_init, - upap_input, - upap_protrej, - upap_lowerup, - upap_lowerdown, - NULL, - NULL, - upap_printpkt, - NULL, - 1, - "PAP", - NULL, - pap_option_list, - NULL, - NULL, - NULL -}; - -upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ - -static void upap_timeout(void *); -static void upap_reqtimeout(void *); -static void upap_rauthreq(upap_state *, u_char *, int, int); -static void upap_rauthack(upap_state *, u_char *, int, int); -static void upap_rauthnak(upap_state *, u_char *, int, int); -static void upap_sauthreq(upap_state *); -static void upap_sresp(upap_state *, u_char, u_char, char *, int); - - -/* - * upap_init - Initialize a UPAP unit. - */ -static void -upap_init(int unit) -{ - upap_state *u = &upap[unit]; - - u->us_unit = unit; - u->us_user = NULL; - u->us_userlen = 0; - u->us_passwd = NULL; - u->us_passwdlen = 0; - u->us_clientstate = UPAPCS_INITIAL; - u->us_serverstate = UPAPSS_INITIAL; - u->us_id = 0; - u->us_timeouttime = UPAP_DEFTIMEOUT; - u->us_maxtransmits = 10; - u->us_reqtimeout = UPAP_DEFREQTIME; -} - - -/* - * upap_authwithpeer - Authenticate us with our peer (start client). - * - * Set new state and send authenticate's. - */ -void -upap_authwithpeer( - int unit, - char *user, - char *password) -{ - upap_state *u = &upap[unit]; - - /* Save the username and password we're given */ - u->us_user = user; - u->us_userlen = strlen(user); - u->us_passwd = password; - u->us_passwdlen = strlen(password); - u->us_transmits = 0; - - /* Lower layer up yet? */ - if (u->us_clientstate == UPAPCS_INITIAL || - u->us_clientstate == UPAPCS_PENDING) { - u->us_clientstate = UPAPCS_PENDING; - return; - } - - upap_sauthreq(u); /* Start protocol */ -} - - -/* - * upap_authpeer - Authenticate our peer (start server). - * - * Set new state. - */ -void -upap_authpeer(int unit) -{ - upap_state *u = &upap[unit]; - - /* Lower layer up yet? */ - if (u->us_serverstate == UPAPSS_INITIAL || - u->us_serverstate == UPAPSS_PENDING) { - u->us_serverstate = UPAPSS_PENDING; - return; - } - - u->us_serverstate = UPAPSS_LISTEN; - if (u->us_reqtimeout > 0) - TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); -} - - -/* - * upap_timeout - Retransmission timer for sending auth-reqs expired. - */ -static void -upap_timeout(void *arg) -{ - upap_state *u = (upap_state *) arg; - - if (u->us_clientstate != UPAPCS_AUTHREQ) - return; - - if (u->us_transmits >= u->us_maxtransmits) { - /* give up in disgust */ - error("No response to PAP authenticate-requests"); - u->us_clientstate = UPAPCS_BADAUTH; - auth_withpeer_fail(u->us_unit, PPP_PAP); - return; - } - - upap_sauthreq(u); /* Send Authenticate-Request */ -} - - -/* - * upap_reqtimeout - Give up waiting for the peer to send an auth-req. - */ -static void -upap_reqtimeout(void *arg) -{ - upap_state *u = (upap_state *) arg; - - if (u->us_serverstate != UPAPSS_LISTEN) - return; /* huh?? */ - - auth_peer_fail(u->us_unit, PPP_PAP); - u->us_serverstate = UPAPSS_BADAUTH; -} - - -/* - * upap_lowerup - The lower layer is up. - * - * Start authenticating if pending. - */ -static void -upap_lowerup(int unit) -{ - upap_state *u = &upap[unit]; - - if (u->us_clientstate == UPAPCS_INITIAL) - u->us_clientstate = UPAPCS_CLOSED; - else if (u->us_clientstate == UPAPCS_PENDING) { - upap_sauthreq(u); /* send an auth-request */ - } - - if (u->us_serverstate == UPAPSS_INITIAL) - u->us_serverstate = UPAPSS_CLOSED; - else if (u->us_serverstate == UPAPSS_PENDING) { - u->us_serverstate = UPAPSS_LISTEN; - if (u->us_reqtimeout > 0) - TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); - } -} - - -/* - * upap_lowerdown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void -upap_lowerdown(int unit) -{ - upap_state *u = &upap[unit]; - - if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ - UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ - if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) - UNTIMEOUT(upap_reqtimeout, u); - - u->us_clientstate = UPAPCS_INITIAL; - u->us_serverstate = UPAPSS_INITIAL; -} - - -/* - * upap_protrej - Peer doesn't speak this protocol. - * - * This shouldn't happen. In any case, pretend lower layer went down. - */ -static void -upap_protrej(int unit) -{ - upap_state *u = &upap[unit]; - - if (u->us_clientstate == UPAPCS_AUTHREQ) { - error("PAP authentication failed due to protocol-reject"); - auth_withpeer_fail(unit, PPP_PAP); - } - if (u->us_serverstate == UPAPSS_LISTEN) { - error("PAP authentication of peer failed (protocol-reject)"); - auth_peer_fail(unit, PPP_PAP); - } - upap_lowerdown(unit); -} - - -/* - * upap_input - Input UPAP packet. - */ -static void -upap_input( - int unit, - u_char *inpacket, - int l) -{ - upap_state *u = &upap[unit]; - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < UPAP_HEADERLEN) { - UPAPDEBUG(("pap_input: rcvd short header.")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < UPAP_HEADERLEN) { - UPAPDEBUG(("pap_input: rcvd illegal length.")); - return; - } - if (len > l) { - UPAPDEBUG(("pap_input: rcvd short packet.")); - return; - } - len -= UPAP_HEADERLEN; - - /* - * Action depends on code. - */ - switch (code) { - case UPAP_AUTHREQ: - upap_rauthreq(u, inp, id, len); - break; - - case UPAP_AUTHACK: - upap_rauthack(u, inp, id, len); - break; - - case UPAP_AUTHNAK: - upap_rauthnak(u, inp, id, len); - break; - - default: /* XXX Need code reject */ - break; - } -} - - -/* - * upap_rauth - Receive Authenticate. - */ -static void -upap_rauthreq( - upap_state *u, - u_char *inp, - int id, - int len) -{ - u_char ruserlen, rpasswdlen; - char *ruser, *rpasswd; - int retcode; - char *msg; - int msglen; - - if (u->us_serverstate < UPAPSS_LISTEN) - return; - - /* - * If we receive a duplicate authenticate-request, we are - * supposed to return the same status as for the first request. - */ - if (u->us_serverstate == UPAPSS_OPEN) { - upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ - return; - } - if (u->us_serverstate == UPAPSS_BADAUTH) { - upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ - return; - } - - /* - * Parse user/passwd. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - GETCHAR(ruserlen, inp); - len -= sizeof (u_char) + ruserlen + sizeof (u_char); - if (len < 0) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - ruser = (char *) inp; - INCPTR(ruserlen, inp); - GETCHAR(rpasswdlen, inp); - if (len < rpasswdlen) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - rpasswd = (char *) inp; - - /* - * Check the username and password given. - */ - retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, - rpasswdlen, &msg); - BZERO(rpasswd, rpasswdlen); - msglen = strlen(msg); - if (msglen > 255) - msglen = 255; - - upap_sresp(u, retcode, id, msg, msglen); - - if (retcode == UPAP_AUTHACK) { - u->us_serverstate = UPAPSS_OPEN; - auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen); - } else { - u->us_serverstate = UPAPSS_BADAUTH; - auth_peer_fail(u->us_unit, PPP_PAP); - } - - if (u->us_reqtimeout > 0) - UNTIMEOUT(upap_reqtimeout, u); -} - - -/* - * upap_rauthack - Receive Authenticate-Ack. - */ -static void -upap_rauthack( - upap_state *u, - u_char *inp, - int id, - int len) -{ - u_char msglen; - char *msg; - - if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauthack: ignoring missing msg-length.")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(("pap_rauthack: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - u->us_clientstate = UPAPCS_OPEN; - - auth_withpeer_success(u->us_unit, PPP_PAP); -} - - -/* - * upap_rauthnak - Receive Authenticate-Nakk. - */ -static void -upap_rauthnak( - upap_state *u, - u_char *inp, - int id, - int len) -{ - u_char msglen; - char *msg; - - if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length.")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(("pap_rauthnak: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - u->us_clientstate = UPAPCS_BADAUTH; - - error("PAP authentication failed"); - auth_withpeer_fail(u->us_unit, PPP_PAP); -} - - -/* - * upap_sauthreq - Send an Authenticate-Request. - */ -static void -upap_sauthreq(upap_state *u) -{ - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + - u->us_userlen + u->us_passwdlen; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(UPAP_AUTHREQ, outp); - PUTCHAR(++u->us_id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(u->us_userlen, outp); - BCOPY(u->us_user, outp, u->us_userlen); - INCPTR(u->us_userlen, outp); - PUTCHAR(u->us_passwdlen, outp); - BCOPY(u->us_passwd, outp, u->us_passwdlen); - - output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); - - TIMEOUT(upap_timeout, u, u->us_timeouttime); - ++u->us_transmits; - u->us_clientstate = UPAPCS_AUTHREQ; -} - - -/* - * upap_sresp - Send a response (ack or nak). - */ -static void -upap_sresp( - upap_state *u, - u_char code, u_char id, - char *msg, - int msglen) -{ - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - outp = outpacket_buf; - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(msglen, outp); - BCOPY(msg, outp, msglen); - output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); -} - -/* - * upap_printpkt - print the contents of a PAP packet. - */ -static char *upap_codenames[] = { - "AuthReq", "AuthAck", "AuthNak" -}; - -static int -upap_printpkt( - u_char *p, - int plen, - void (*printer)(void *, char *, ...), - void *arg) -{ - int code, id, len; - int mlen, ulen, wlen; - char *user, *pwd, *msg; - u_char *pstart; - - if (plen < UPAP_HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < UPAP_HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *)) - printer(arg, " %s", upap_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= UPAP_HEADERLEN; - switch (code) { - case UPAP_AUTHREQ: - if (len < 1) - break; - ulen = p[0]; - if (len < ulen + 2) - break; - wlen = p[ulen + 1]; - if (len < ulen + wlen + 2) - break; - user = (char *) (p + 1); - pwd = (char *) (p + ulen + 2); - p += ulen + wlen + 2; - len -= ulen + wlen + 2; - printer(arg, " user="); - print_string(user, ulen, printer, arg); - printer(arg, " password="); - if (!hide_password) - print_string(pwd, wlen, printer, arg); - else - printer(arg, ""); - break; - case UPAP_AUTHACK: - case UPAP_AUTHNAK: - if (len < 1) - break; - mlen = p[0]; - if (len < mlen + 1) - break; - msg = (char *) (p + 1); - p += mlen + 1; - len -= mlen + 1; - printer(arg, " "); - print_string(msg, mlen, printer, arg); - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} diff --git a/cpukit/pppd/upap.h b/cpukit/pppd/upap.h deleted file mode 100644 index 6ba0900f1a..0000000000 --- a/cpukit/pppd/upap.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * upap.h - User/Password Authentication Protocol definitions. - * - * 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. - * - * $Id$ - */ - -/* - * Packet header = Code, id, length. - */ -#define UPAP_HEADERLEN 4 - - -/* - * UPAP codes. - */ -#define UPAP_AUTHREQ 1 /* Authenticate-Request */ -#define UPAP_AUTHACK 2 /* Authenticate-Ack */ -#define UPAP_AUTHNAK 3 /* Authenticate-Nak */ - - -/* - * Each interface is described by upap structure. - */ -typedef struct upap_state { - int us_unit; /* Interface unit number */ - char *us_user; /* User */ - int us_userlen; /* User length */ - char *us_passwd; /* Password */ - int us_passwdlen; /* Password length */ - int us_clientstate; /* Client state */ - int us_serverstate; /* Server state */ - u_char us_id; /* Current id */ - int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ - int us_transmits; /* Number of auth-reqs sent */ - int us_maxtransmits; /* Maximum number of auth-reqs to send */ - int us_reqtimeout; /* Time to wait for auth-req from peer */ -} upap_state; - - -/* - * Client states. - */ -#define UPAPCS_INITIAL 0 /* Connection down */ -#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPCS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ -#define UPAPCS_OPEN 4 /* We've received an Ack */ -#define UPAPCS_BADAUTH 5 /* We've received a Nak */ - -/* - * Server states. - */ -#define UPAPSS_INITIAL 0 /* Connection down */ -#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPSS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ -#define UPAPSS_OPEN 4 /* We've sent an Ack */ -#define UPAPSS_BADAUTH 5 /* We've sent a Nak */ - - -/* - * Timeouts. - */ -#define UPAP_DEFTIMEOUT 5 /* Timeout (seconds) for retransmitting req */ -#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ - -extern upap_state upap[]; - -void upap_authwithpeer(int, char *, char *); -void upap_authpeer(int); - -extern struct protent pap_protent; diff --git a/cpukit/pppd/utils.c b/cpukit/pppd/utils.c deleted file mode 100644 index cb1dab3728..0000000000 --- a/cpukit/pppd/utils.c +++ /dev/null @@ -1,823 +0,0 @@ -/* - * utils.c - various utility functions used in pppd. - * - * Copyright (c) 1999 The Australian National 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 the Australian National 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef SVR4 -#include -#endif - -#include "pppd.h" - -static void pr_log(void *, char *, ...); -static void logit(int, char *, va_list); -static void vslp_printer(void *, char *, ...); -static void format_packet(u_char *, int, void (*) (void *, char *, ...), - void *); - -struct buffer_info { - char *ptr; - int len; -}; - -/* - * slprintf - format a message into a buffer. Like sprintf except we - * also specify the length of the output buffer, and we handle - * %r (recursive format), %m (error message), %v (visible string), - * %q (quoted string), %t (current time) and %I (IP address) formats. - * Doesn't do floating-point formats. - * Returns the number of chars put into buf. - */ -int -slprintf __V((char *buf, int buflen, char *fmt, ...)) -{ - va_list args; - int n; - -#if defined(__STDC__) - va_start(args, fmt); -#else - char *buf; - int buflen; - char *fmt; - va_start(args); - buf = va_arg(args, char *); - buflen = va_arg(args, int); - fmt = va_arg(args, char *); -#endif - n = vslprintf(buf, buflen, fmt, args); - va_end(args); - return n; -} - -/* - * vslprintf - like slprintf, takes a va_list instead of a list of args. - */ -#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) - -int -vslprintf( - char *buf, - int buflen, - char *fmt, - va_list args) -{ - int c, i, n; - int width, prec, fillch; - int base, len, neg, quoted; - uintptr_t val = 0; - char *str, *f, *buf0; - unsigned char *p; - char num[32]; - time_t t; - uint32_t ip; - static char hexchars[] = "0123456789abcdef"; - struct buffer_info bufinfo; - - buf0 = buf; - --buflen; - while (buflen > 0) { - for (f = fmt; *f != '%' && *f != 0; ++f) - ; - if (f > fmt) { - len = f - fmt; - if (len > buflen) - len = buflen; - memcpy(buf, fmt, len); - buf += len; - buflen -= len; - fmt = f; - } - if (*fmt == 0) - break; - c = *++fmt; - width = 0; - prec = -1; - fillch = ' '; - if (c == '0') { - fillch = '0'; - c = *++fmt; - } - if (c == '*') { - width = va_arg(args, int); - c = *++fmt; - } else { - while (isdigit(c)) { - width = width * 10 + c - '0'; - c = *++fmt; - } - } - if (c == '.') { - c = *++fmt; - if (c == '*') { - prec = va_arg(args, int); - c = *++fmt; - } else { - prec = 0; - while (isdigit(c)) { - prec = prec * 10 + c - '0'; - c = *++fmt; - } - } - } - str = 0; - base = 0; - neg = 0; - ++fmt; - switch (c) { - case 'd': - i = va_arg(args, int); - if (i < 0) { - neg = 1; - val = -i; - } else - val = i; - base = 10; - break; - case 'o': - val = va_arg(args, unsigned int); - base = 8; - break; - case 'x': - case 'X': - val = va_arg(args, unsigned int); - base = 16; - break; - case 'p': - val = (uintptr_t) va_arg(args, void *); - base = 16; - neg = 2; - break; - case 's': - str = va_arg(args, char *); - break; - case 'c': - num[0] = va_arg(args, int); - num[1] = 0; - str = num; - break; - case 'm': - str = strerror(errno); - break; - case 'I': - ip = va_arg(args, uint32_t); - ip = ntohl(ip); - slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, - (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); - str = num; - break; - case 'r': - f = va_arg(args, char *); -#if !defined(__PPC__) - n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list)); -#else - /* HACK: On the powerpc, a va_list is an array of 1 structure */ - n = vslprintf(buf, buflen + 1, f, va_arg(args, void *)); -#endif - buf += n; - buflen -= n; - continue; - case 't': - time(&t); - str = ctime(&t); - str += 4; /* chop off the day name */ - str[15] = 0; /* chop off year and newline */ - break; - case 'v': /* "visible" string */ - case 'q': /* quoted string */ - quoted = c == 'q'; - p = va_arg(args, unsigned char *); - if (fillch == '0' && prec >= 0) { - n = prec; - } else { - n = strlen((char *)p); - if (prec >= 0 && n > prec) - n = prec; - } - while (n > 0 && buflen > 0) { - c = *p++; - --n; - if (!quoted && c >= 0x80) { - OUTCHAR('M'); - OUTCHAR('-'); - c -= 0x80; - } - if (quoted && (c == '"' || c == '\\')) - OUTCHAR('\\'); - if (c < 0x20 || (0x7f <= c && c < 0xa0)) { - if (quoted) { - OUTCHAR('\\'); - switch (c) { - case '\t': OUTCHAR('t'); break; - case '\n': OUTCHAR('n'); break; - case '\b': OUTCHAR('b'); break; - case '\f': OUTCHAR('f'); break; - default: - OUTCHAR('x'); - OUTCHAR(hexchars[c >> 4]); - OUTCHAR(hexchars[c & 0xf]); - } - } else { - if (c == '\t') - OUTCHAR(c); - else { - OUTCHAR('^'); - OUTCHAR(c ^ 0x40); - } - } - } else - OUTCHAR(c); - } - continue; - case 'P': /* print PPP packet */ - bufinfo.ptr = buf; - bufinfo.len = buflen + 1; - p = va_arg(args, unsigned char *); - n = va_arg(args, int); - format_packet(p, n, vslp_printer, &bufinfo); - buf = bufinfo.ptr; - buflen = bufinfo.len - 1; - continue; - case 'B': - p = va_arg(args, unsigned char *); - for (n = prec; n > 0; --n) { - c = *p++; - if (fillch == ' ') - OUTCHAR(' '); - OUTCHAR(hexchars[(c >> 4) & 0xf]); - OUTCHAR(hexchars[c & 0xf]); - } - continue; - default: - *buf++ = '%'; - if (c != '%') - --fmt; /* so %z outputs %z etc. */ - --buflen; - continue; - } - if (base != 0) { - str = num + sizeof(num); - *--str = 0; - while (str > num + neg) { - *--str = hexchars[val % base]; - val = val / base; - if (--prec <= 0 && val == 0) - break; - } - switch (neg) { - case 1: - *--str = '-'; - break; - case 2: - *--str = 'x'; - *--str = '0'; - break; - } - len = num + sizeof(num) - 1 - str; - } else { - len = strlen(str); - if (prec >= 0 && len > prec) - len = prec; - } - if (width > 0) { - if (width > buflen) - width = buflen; - if ((n = width - len) > 0) { - buflen -= n; - for (; n > 0; --n) - *buf++ = fillch; - } - } - if (len > buflen) - len = buflen; - memcpy(buf, str, len); - buf += len; - buflen -= len; - } - *buf = 0; - return buf - buf0; -} - -/* - * vslp_printer - used in processing a %P format - */ -static void -vslp_printer __V((void *arg, char *fmt, ...)) -{ - int n; - va_list pvar; - struct buffer_info *bi; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - void *arg; - char *fmt; - va_start(pvar); - arg = va_arg(pvar, void *); - fmt = va_arg(pvar, char *); -#endif - - bi = (struct buffer_info *) arg; - n = vslprintf(bi->ptr, bi->len, fmt, pvar); - va_end(pvar); - - bi->ptr += n; - bi->len -= n; -} - -/* - * log_packet - format a packet and log it. - */ - -char line[256]; /* line to be logged accumulated here */ -char *linep; - -void -log_packet( - u_char *p, - int len, - char *prefix, - int level) -{ - strlcpy(line, prefix, sizeof(line)); - linep = line + strlen(line); - format_packet(p, len, pr_log, NULL); -} - -/* - * format_packet - make a readable representation of a packet, - * calling `printer(arg, format, ...)' to output it. - */ -static void -format_packet( - u_char *p, - int len, - void (*printer)(void *, char *, ...), - void *arg) -{ - int i, n; - u_short proto; - struct protent *protp; - - if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { - p += 2; - GETSHORT(proto, p); - len -= PPP_HDRLEN; - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (proto == protp->protocol) - break; - if (protp != NULL) { - printer(arg, "[%s", protp->name); - n = (*protp->printpkt)(p, len, printer, arg); - printer(arg, "]"); - p += n; - len -= n; - } else { - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (proto == (protp->protocol & ~0x8000)) - break; - if (protp != 0 && protp->data_name != 0) { - printer(arg, "[%s data]", protp->data_name); - if (len > 8) - printer(arg, "%.8B ...", p); - else - printer(arg, "%.*B", len, p); - len = 0; - } else - printer(arg, "[proto=0x%x]", proto); - } - } - - if (len > 32) - printer(arg, "%.32B ...", p); - else - printer(arg, "%.*B", len, p); -} - -static void -pr_log __V((void *arg, char *fmt, ...)) -{ - int n; - va_list pvar; - char buf[256]; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - void *arg; - char *fmt; - va_start(pvar); - arg = va_arg(pvar, void *); - fmt = va_arg(pvar, char *); -#endif - - n = vslprintf(buf, sizeof(buf), fmt, pvar); - va_end(pvar); - - if (linep + n + 1 > line + sizeof(line)) { - linep = line; - } - strlcpy(linep, buf, line + sizeof(line) - linep); - linep += n; -} - -/* - * print_string - print a readable representation of a string using - * printer. - */ -void -print_string( - void *p_arg, - int len, - void (*printer)(void *, char *, ...), - void *arg) -{ - int c; - unsigned char *p = (unsigned char *)p_arg; - - printer(arg, "\""); - for (; len > 0; --len) { - c = *p++; - if (' ' <= c && c <= '~') { - if (c == '\\' || c == '"') - printer(arg, "\\"); - printer(arg, "%c", c); - } else { - switch (c) { - case '\n': - printer(arg, "\\n"); - break; - case '\r': - printer(arg, "\\r"); - break; - case '\t': - printer(arg, "\\t"); - break; - default: - printer(arg, "\\%.3o", c); - } - } - } - printer(arg, "\""); -} - -/* - * logit - does the hard work for fatal et al. - */ -static void -logit( - int level, - char *fmt, - va_list args) -{ - int n; - char buf[256]; - - n = vslprintf(buf, sizeof(buf), fmt, args); -/* if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { */ - if (log_to_fd >= 0 && (debug)) { - if (buf[n-1] != '\n') - buf[n++] = '\n'; - if (write(log_to_fd, buf, n) != n) - log_to_fd = -1; - } -} - -/* - * fatal - log an error message and die horribly. - */ -void -pppd_fatal __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_ERR, fmt, pvar); - va_end(pvar); - - die(1); /* as promised */ -} - -/* - * error - log an error message. - */ -void -pppd_error __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_ERR, fmt, pvar); - va_end(pvar); -} - -/* - * warn - log a warning message. - */ -void -pppd_warn __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_WARNING, fmt, pvar); - va_end(pvar); -} - -/* - * notice - log a notice-level message. - */ -void -pppd_notice __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_NOTICE, fmt, pvar); - va_end(pvar); -} - -/* - * info - log an informational message. - */ -void -pppd_info __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_INFO, fmt, pvar); - va_end(pvar); -} - -/* - * dbglog - log a debug message. - */ -void -pppd_dbglog __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_DEBUG, fmt, pvar); - va_end(pvar); -} - -/* Procedures for locking the serial device using a lock file. */ -#ifndef LOCK_DIR -#ifdef _linux_ -#define LOCK_DIR "/var/lock" -#else -#ifdef SVR4 -#define LOCK_DIR "/var/spool/locks" -#else -#define LOCK_DIR "/var/spool/lock" -#endif -#endif -#endif /* LOCK_DIR */ - -static char lock_file[MAXPATHLEN]; - -/* - * lock - create a lock file for the named device - */ -int -lock(char *dev) -{ -#ifdef LOCKLIB - int result; - - result = mklock (dev, (void *) 0); - if (result == 0) { - strlcpy(lock_file, sizeof(lock_file), dev); - return 0; - } - - if (result > 0) - notice("Device %s is locked by pid %d", dev, result); - else - error("Can't create lock file %s", lock_file); - return -1; - -#else /* LOCKLIB */ - - char lock_buffer[12]; - int fd, pid, n; - -#ifdef SVR4 - struct stat sbuf; - - if (stat(dev, &sbuf) < 0) { - error("Can't get device number for %s: %m", dev); - return -1; - } - if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { - error("Can't lock %s: not a character device", dev); - return -1; - } - slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", - LOCK_DIR, major(sbuf.st_dev), - major(sbuf.st_rdev), minor(sbuf.st_rdev)); -#else - char *p; - - if ((p = strrchr(dev, '/')) != NULL) - dev = p + 1; - slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); -#endif - - while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { - if (errno != EEXIST) { - error("Can't create lock file %s: %m", lock_file); - break; - } - - /* Read the lock file to find out who has the device locked. */ - fd = open(lock_file, O_RDONLY, 0); - if (fd < 0) { - if (errno == ENOENT) /* This is just a timing problem. */ - continue; - error("Can't open existing lock file %s: %m", lock_file); - break; - } -#ifndef LOCK_BINARY - n = read(fd, lock_buffer, 11); -#else - n = read(fd, &pid, sizeof(pid)); -#endif /* LOCK_BINARY */ - close(fd); - fd = -1; - if (n <= 0) { - error("Can't read pid from lock file %s", lock_file); - break; - } - - /* See if the process still exists. */ -#ifndef LOCK_BINARY - lock_buffer[n] = 0; - pid = atoi(lock_buffer); -#endif /* LOCK_BINARY */ - if (pid == getpid()) - return 1; /* somebody else locked it for us */ - if (pid == 0 - || (kill(pid, 0) == -1 && errno == ESRCH)) { - if (unlink (lock_file) == 0) { - notice("Removed stale lock on %s (pid %d)", dev, pid); - continue; - } - warn("Couldn't remove stale lock on %s", dev); - } else - notice("Device %s is locked by pid %d", dev, pid); - break; - } - - if (fd < 0) { - lock_file[0] = 0; - return -1; - } - - pid = getpid(); -#ifndef LOCK_BINARY - slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); -#else - write(fd, &pid, sizeof (pid)); -#endif - close(fd); - return 0; - -#endif -} - -/* - * relock - called to update our lockfile when we are about to detach, - * thus changing our pid (we fork, the child carries on, and the parent dies). - * Note that this is called by the parent, with pid equal to the pid - * of the child. This avoids a potential race which would exist if - * we had the child rewrite the lockfile (the parent might die first, - * and another process could think the lock was stale if it checked - * between when the parent died and the child rewrote the lockfile). - */ -int -relock(int pid) -{ -#ifdef LOCKLIB - /* XXX is there a way to do this? */ - return -1; -#else /* LOCKLIB */ - - int fd; - char lock_buffer[12]; - - if (lock_file[0] == 0) - return -1; - fd = open(lock_file, O_WRONLY, 0); - if (fd < 0) { - error("Couldn't reopen lock file %s: %m", lock_file); - lock_file[0] = 0; - return -1; - } - -#ifndef LOCK_BINARY - slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); -#else - write(fd, &pid, sizeof(pid)); -#endif /* LOCK_BINARY */ - close(fd); - return 0; - -#endif /* LOCKLIB */ -} - -/* - * unlock - remove our lockfile - */ -void -unlock(void) -{ - if (lock_file[0]) { -#ifdef LOCKLIB - (void) rmlock(lock_file, (void *) 0); -#else - unlink(lock_file); -#endif - lock_file[0] = 0; - } -} diff --git a/spec/build/cpukit/grp.yml b/spec/build/cpukit/grp.yml index 91fa2d9625..8816576c3f 100644 --- a/spec/build/cpukit/grp.yml +++ b/spec/build/cpukit/grp.yml @@ -23,8 +23,6 @@ links: uid: libmghttpd - role: build-dependency uid: libnfs -- role: build-dependency - uid: libpppd - role: build-dependency uid: librtemscpu - role: build-dependency diff --git a/spec/build/cpukit/libpppd.yml b/spec/build/cpukit/libpppd.yml deleted file mode 100644 index d67b93aef8..0000000000 --- a/spec/build/cpukit/libpppd.yml +++ /dev/null @@ -1,33 +0,0 @@ -SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause -build-type: library -cflags: [] -copyrights: -- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) -cppflags: [] -cxxflags: [] -enabled-by: -- RTEMS_NETWORKING -includes: -- cpukit/libnetworking -install: [] -install-path: ${BSP_LIBDIR} -links: [] -source: -- cpukit/pppd/auth.c -- cpukit/pppd/ccp.c -- cpukit/pppd/chap.c -- cpukit/pppd/chap_ms.c -- cpukit/pppd/chat.c -- cpukit/pppd/demand.c -- cpukit/pppd/fsm.c -- cpukit/pppd/ipcp.c -- cpukit/pppd/lcp.c -- cpukit/pppd/magic.c -- cpukit/pppd/options.c -- cpukit/pppd/rtemsmain.c -- cpukit/pppd/rtemspppd.c -- cpukit/pppd/sys-rtems.c -- cpukit/pppd/upap.c -- cpukit/pppd/utils.c -target: pppd -type: build diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index 3c20afaf2b..6de764cd04 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -157,7 +157,6 @@ install: - cpukit/include/rtems/rtems-rfs-shell.h - cpukit/include/rtems/rtems-rfs.h - cpukit/include/rtems/rtemsdialer.h - - cpukit/include/rtems/rtemspppd.h - cpukit/include/rtems/scheduler.h - cpukit/include/rtems/serdbg.h - cpukit/include/rtems/serdbgcnf.h -- cgit v1.2.3