From eb75ae05c6cedad9f559aeb1a2398ce1d1bdf323 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 16 May 2012 02:02:02 +0200 Subject: [PATCH 001/320] Early development stage of an attempt to port PPPd 2.4.5 to lwIP. PPPoE works, PPPoS code is not ported at all. I am using the RP-PPPoE server to do my tests using the following configuration: $ cat /etc/ppp/pppoe-server-options debug login lcp-echo-interval 10 lcp-echo-failure 10 ms-dns 192.168.4.130 ms-dns 192.168.4.231 netmask 255.255.255.0 defaultroute noipdefault usepeerdns $ cat /etc/ppp/allip 192.168.4.1-200 $ pppoe-server -C isp -L 192.168.4.254 -p /etc/ppp/allip -I tap0 Plus the usual auth-lines in /etc/ppp/pap-secrets and /etc/ppp/chap-secrets . And the unix port minimal "echo" project slightly modified to use the "tcpip" API, so with threads, which I am going to commit with NO_SYS as a -Dmacro. It still use some of the linux'ism, such as syslog() and crypt(), I do not want to drop the syslog() supports at the moment, this is pretty useful to debug, and we may just convert the way the syslog() is done to provide a trace feature to our PPP users, as a compile-time option. --- src/netif/ppp/auth.c | 2694 ++++++++++----- src/netif/ppp/auth.h | 111 - src/netif/ppp/cbcp.h | 26 + src/netif/ppp/ccp.c | 1680 ++++++++++ src/netif/ppp/ccp.h | 52 + src/netif/ppp/chap-md5.c | 119 + src/netif/ppp/chap-md5.h | 31 + src/netif/ppp/chap-new.c | 658 ++++ src/netif/ppp/chap-new.h | 130 + src/netif/ppp/chap.c | 908 ----- src/netif/ppp/chap.h | 150 - src/netif/ppp/chap_ms.c | 943 ++++++ src/netif/ppp/chap_ms.h | 109 + src/netif/ppp/chpms.c | 396 --- src/netif/ppp/chpms.h | 64 - src/netif/ppp/demand.c | 366 +++ src/netif/ppp/eap.c | 2430 ++++++++++++++ src/netif/ppp/eap.h | 158 + src/netif/ppp/ecp.c | 175 + src/netif/ppp/ecp.h | 45 + src/netif/ppp/eui64.h | 114 + src/netif/ppp/fsm.c | 1284 ++++---- src/netif/ppp/fsm.h | 237 +- src/netif/ppp/ipcp.c | 3122 +++++++++++------- src/netif/ppp/ipcp.h | 154 +- src/netif/ppp/ipv6cp.h | 171 + src/netif/ppp/ipxcp.c | 1600 +++++++++ src/netif/ppp/ipxcp.h | 94 + src/netif/ppp/lcp.c | 3584 +++++++++++--------- src/netif/ppp/lcp.h | 222 +- src/netif/ppp/linux/if_ppp.h | 178 + src/netif/ppp/linux/if_pppol2tp.h | 65 + src/netif/ppp/linux/ppp-comp.h | 213 ++ src/netif/ppp/linux/ppp_defs.h | 195 ++ src/netif/ppp/magic.c | 157 +- src/netif/ppp/magic.h | 96 +- src/netif/ppp/md4.c | 301 ++ src/netif/ppp/md4.h | 64 + src/netif/ppp/md5.c | 131 +- src/netif/ppp/md5.h | 30 +- src/netif/ppp/mppe.h | 121 + src/netif/ppp/multilink.c | 595 ++++ src/netif/ppp/net/if_ppp.h | 156 + src/netif/ppp/net/ppp-comp.h | 179 + src/netif/ppp/net/ppp_defs.h | 197 ++ src/netif/ppp/net/pppio.h | 107 + src/netif/ppp/net/slcompress.h | 148 + src/netif/ppp/{vj.h => net/vjcompress.h} | 104 +- src/netif/ppp/options.c | 1627 +++++++++ src/netif/ppp/pap.c | 628 ---- src/netif/ppp/pap.h | 118 - src/netif/ppp/patchlevel.h | 2 + src/netif/ppp/pathnames.h | 65 + src/netif/ppp/ppp.c | 3832 +++++++++++----------- src/netif/ppp/ppp.h | 201 -- src/netif/ppp/ppp_impl.h | 363 -- src/netif/ppp/ppp_oe.c | 85 +- src/netif/ppp/pppcrypt.c | 195 ++ src/netif/ppp/pppcrypt.h | 48 + src/netif/ppp/pppd.h | 913 ++++++ src/netif/ppp/pppdebug.h | 25 +- src/netif/ppp/pppmy.c | 1110 +++++++ src/netif/ppp/pppmy.h | 121 + src/netif/ppp/randm.c | 249 -- src/netif/ppp/randm.h | 81 - src/netif/ppp/readme.txt | 21 - src/netif/ppp/session.c | 423 +++ src/netif/ppp/session.h | 91 + src/netif/ppp/sha1.c | 172 + src/netif/ppp/sha1.h | 31 + src/netif/ppp/spinlock.c | 476 +++ src/netif/ppp/spinlock.h | 59 + src/netif/ppp/sys-linux.c | 2922 +++++++++++++++++ src/netif/ppp/tdb.c | 2011 ++++++++++++ src/netif/ppp/tdb.h | 164 + src/netif/ppp/tty.c | 1264 +++++++ src/netif/ppp/upap.c | 684 ++++ src/netif/ppp/upap.h | 110 + src/netif/ppp/utils.c | 1056 ++++++ src/netif/ppp/vj.c | 652 ---- 80 files changed, 33979 insertions(+), 10684 deletions(-) delete mode 100644 src/netif/ppp/auth.h create mode 100644 src/netif/ppp/cbcp.h create mode 100644 src/netif/ppp/ccp.c create mode 100644 src/netif/ppp/ccp.h create mode 100644 src/netif/ppp/chap-md5.c create mode 100644 src/netif/ppp/chap-md5.h create mode 100644 src/netif/ppp/chap-new.c create mode 100644 src/netif/ppp/chap-new.h delete mode 100644 src/netif/ppp/chap.c delete mode 100644 src/netif/ppp/chap.h create mode 100644 src/netif/ppp/chap_ms.c create mode 100644 src/netif/ppp/chap_ms.h delete mode 100644 src/netif/ppp/chpms.c delete mode 100644 src/netif/ppp/chpms.h create mode 100644 src/netif/ppp/demand.c create mode 100644 src/netif/ppp/eap.c create mode 100644 src/netif/ppp/eap.h create mode 100644 src/netif/ppp/ecp.c create mode 100644 src/netif/ppp/ecp.h create mode 100644 src/netif/ppp/eui64.h create mode 100644 src/netif/ppp/ipv6cp.h create mode 100644 src/netif/ppp/ipxcp.c create mode 100644 src/netif/ppp/ipxcp.h create mode 100644 src/netif/ppp/linux/if_ppp.h create mode 100644 src/netif/ppp/linux/if_pppol2tp.h create mode 100644 src/netif/ppp/linux/ppp-comp.h create mode 100644 src/netif/ppp/linux/ppp_defs.h create mode 100644 src/netif/ppp/md4.c create mode 100644 src/netif/ppp/md4.h create mode 100644 src/netif/ppp/mppe.h create mode 100644 src/netif/ppp/multilink.c create mode 100644 src/netif/ppp/net/if_ppp.h create mode 100644 src/netif/ppp/net/ppp-comp.h create mode 100644 src/netif/ppp/net/ppp_defs.h create mode 100644 src/netif/ppp/net/pppio.h create mode 100644 src/netif/ppp/net/slcompress.h rename src/netif/ppp/{vj.h => net/vjcompress.h} (59%) create mode 100644 src/netif/ppp/options.c delete mode 100644 src/netif/ppp/pap.c delete mode 100644 src/netif/ppp/pap.h create mode 100644 src/netif/ppp/patchlevel.h create mode 100644 src/netif/ppp/pathnames.h delete mode 100644 src/netif/ppp/ppp.h delete mode 100644 src/netif/ppp/ppp_impl.h create mode 100644 src/netif/ppp/pppcrypt.c create mode 100644 src/netif/ppp/pppcrypt.h create mode 100644 src/netif/ppp/pppd.h create mode 100644 src/netif/ppp/pppmy.c create mode 100644 src/netif/ppp/pppmy.h delete mode 100644 src/netif/ppp/randm.c delete mode 100644 src/netif/ppp/randm.h delete mode 100644 src/netif/ppp/readme.txt create mode 100644 src/netif/ppp/session.c create mode 100644 src/netif/ppp/session.h create mode 100644 src/netif/ppp/sha1.c create mode 100644 src/netif/ppp/sha1.h create mode 100644 src/netif/ppp/spinlock.c create mode 100644 src/netif/ppp/spinlock.h create mode 100644 src/netif/ppp/sys-linux.c create mode 100644 src/netif/ppp/tdb.c create mode 100644 src/netif/ppp/tdb.h create mode 100644 src/netif/ppp/tty.c create mode 100644 src/netif/ppp/upap.c create mode 100644 src/netif/ppp/upap.h create mode 100644 src/netif/ppp/utils.c delete mode 100644 src/netif/ppp/vj.c diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 0fd87a37..9e105c0a 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1,124 +1,155 @@ -/***************************************************************************** -* auth.c - Network Authentication and Phase Control program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-08 Guy Lancaster , Global Election Systems Inc. -* Ported from public pppd code. -*****************************************************************************/ /* * auth.c - PPP authentication and phase control. * - * Copyright (c) 1993 The Australian National University. - * All rights reserved. + * Copyright (c) 1993-2002 Paul Mackerras. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 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. + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Derived from main.c, which is: + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "lwip/opt.h" +#include "pppmy.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#define RCSID "$Id: auth.c,v 1.117 2008/07/01 12:27:56 paulus Exp $" -#include "ppp_impl.h" -#include "pppdebug.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(_PATH_LASTLOG) && defined(__linux__) +#include +#endif +#include +#include +#include + + +#ifdef HAS_SHADOW +#include +#ifndef PW_PPP +#define PW_PPP PW_LOGIN +#endif +#endif +#include + +#include "pppd.h" #include "fsm.h" #include "lcp.h" -#include "pap.h" -#include "chap.h" -#include "auth.h" +#include "ccp.h" +#include "ecp.h" #include "ipcp.h" - +#include "upap.h" +#include "chap-new.h" +#include "eap.h" #if CBCP_SUPPORT #include "cbcp.h" -#endif /* CBCP_SUPPORT */ +#endif +#include "pathnames.h" +#include "session.h" -#include "lwip/inet.h" +static const char rcsid[] = RCSID; -#include - -#if 0 /* UNUSED */ /* Bits in scan_authfile return value */ -#define NONWILD_SERVER 1 -#define NONWILD_CLIENT 2 +#define NONWILD_SERVER 1 +#define NONWILD_CLIENT 2 -#define ISWILD(word) (word[0] == '*' && word[1] == 0) -#endif /* UNUSED */ +#define ISWILD(word) (word[0] == '*' && word[1] == 0) -#if PAP_SUPPORT || CHAP_SUPPORT /* The name by which the peer authenticated itself to us. */ -static char peer_authname[MAXNAMELEN]; -#endif /* PAP_SUPPORT || CHAP_SUPPORT */ +char peer_authname[MAXNAMELEN]; /* Records which authentication operations haven't completed yet. */ static int auth_pending[NUM_PPP]; -/* Set if we have successfully called plogin() */ -static int logged_in; - -/* Set if we have run the /etc/ppp/auth-up script. */ -static int did_authup; /* @todo, we don't need this in lwip*/ +/* Records which authentication operations have been completed. */ +int auth_done[NUM_PPP]; /* List of addresses which the peer may use. */ -static struct wordlist *addresses[NUM_PPP]; +static struct permitted_ip *addresses[NUM_PPP]; -#if 0 /* UNUSED */ /* Wordlist giving addresses which the peer may use without authenticating itself. */ static struct wordlist *noauth_addrs; +/* Remote telephone number, if available */ +char remote_number[MAXNAMELEN]; + +/* Wordlist giving remote telephone numbers which may connect. */ +static struct wordlist *permitted_numbers; + /* Extra options to apply, from the secrets file entry for the peer. */ static struct wordlist *extra_options; -#endif /* UNUSED */ /* Number of network protocols which we have opened. */ static int num_np_open; @@ -126,12 +157,9 @@ static int num_np_open; /* Number of network protocols which have come up. */ static int num_np_up; -#if PAP_SUPPORT || CHAP_SUPPORT /* Set if we got the contents of passwd[] from the pap-secrets file. */ static int passwd_from_file; -#endif /* PAP_SUPPORT || CHAP_SUPPORT */ -#if 0 /* UNUSED */ /* Set if we require authentication only because we have a default route. */ static bool default_auth; @@ -143,8 +171,8 @@ int (*pap_check_hook) __P((void)) = NULL; /* Hook for a plugin to check the PAP user and password */ int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts)) = NULL; + struct wordlist **paddrs, + struct wordlist **popts)) = NULL; /* Hook for a plugin to know about the PAP user logout */ void (*pap_logout_hook) __P((void)) = NULL; @@ -152,6 +180,31 @@ void (*pap_logout_hook) __P((void)) = NULL; /* Hook for a plugin to get the PAP password for authenticating us */ int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; +/* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ +int (*chap_check_hook) __P((void)) = NULL; + +/* Hook for a plugin to get the CHAP password for authenticating us */ +int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL; + +/* Hook for a plugin to say whether it is OK if the peer + refuses to authenticate. */ +int (*null_auth_hook) __P((struct wordlist **paddrs, + struct wordlist **popts)) = NULL; + +int (*allowed_address_hook) __P((u_int32_t addr)) = NULL; + +#ifdef HAVE_MULTILINK +/* Hook for plugin to hear when an interface joins a multilink bundle */ +void (*multilink_join_hook) __P((void)) = NULL; +#endif + +/* A notifier for when the peer has authenticated itself, + and we are proceeding to the network phase. */ +struct notifier *auth_up_notifier = NULL; + +/* A notifier for when the link goes down. */ +struct notifier *link_down_notifier = NULL; + /* * This is used to ensure that we don't start an auth-up/down * script while one is already running. @@ -167,272 +220,512 @@ static pid_t auth_script_pid = 0; /* * Option variables. - * lwip: some of these are present in the ppp_settings structure */ -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 */ +bool uselogin = 0; /* Use /etc/passwd for checking PAP */ +bool session_mgmt = 0; /* Do session management (login records) */ +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 refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ +#ifdef CHAPMS +bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ +bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#else +bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ +bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#endif +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 */ +bool explicit_user = 0; /* Set if "user" option supplied */ +bool explicit_passwd = 0; /* Set if "password" option supplied */ +char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -#endif /* UNUSED */ +static char *uafname; /* name of most recent +ua file */ -/* Bits in auth_pending[] */ -#define PAP_WITHPEER 1 -#define PAP_PEER 2 -#define CHAP_WITHPEER 4 -#define CHAP_PEER 8 - -/* @todo, move this somewhere */ -/* Used for storing a sequence of words. Usually malloced. */ -struct wordlist { - struct wordlist *next; - char word[1]; -}; - - -extern char *crypt (const char *, const char *); +extern char *crypt __P((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 *); -#if 0 -static int plogin (char *, char *, char **, int *); +static void network_phase __P((int)); +static void check_idle __P((void *)); +static void connect_time_expired __P((void *)); +static int null_login __P((int)); +static int get_pap_passwd __P((char *)); +static int have_pap_secret __P((int *)); +static int have_chap_secret __P((char *, char *, int, int *)); +static int have_srp_secret __P((char *client, char *server, int need_ip, + int *lacks_ipp)); +static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); +static int scan_authfile __P((FILE *, char *, char *, char *, + struct wordlist **, struct wordlist **, + char *, int)); +static void free_wordlist __P((struct wordlist *)); +static void auth_script __P((char *)); +static void auth_script_done __P((void *)); +static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *)); +static int some_ip_ok __P((struct wordlist *)); +static int setupapfile __P((char **)); +static int privgroup __P((char **)); +static int set_noauth_addr __P((char **)); +static int set_permitted_number __P((char **)); +static void check_access __P((FILE *, char *)); +static int wordlist_count __P((struct wordlist *)); + +#ifdef MAXOCTETS +static void check_maxoctets __P((void *)); #endif -static void plogout (void); -static int null_login (int); -static int get_pap_passwd (int, char *, char *); -static int have_pap_secret (void); -static int have_chap_secret (char *, char *, u32_t); -static int ip_addr_check (u32_t, struct wordlist *); -#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ -static int scan_authfile (FILE *, char *, char *, char *, - struct wordlist **, struct wordlist **, - char *); -static void free_wordlist (struct wordlist *); -static void auth_script (char *); -static void auth_script_done (void *); -static void set_allowed_addrs (int unit, struct wordlist *addrs); -static int some_ip_ok (struct wordlist *); -static int setupapfile (char **); -static int privgroup (char **); -static int set_noauth_addr (char **); -static void check_access (FILE *, char *); -#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ - -#if 0 /* UNUSED */ /* * Authentication-related options. */ option_t auth_options[] = { + { "auth", o_bool, &auth_required, + "Require authentication from peer", OPT_PRIO | 1 }, + { "noauth", o_bool, &auth_required, + "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV, + &allow_any_ip }, { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", 1, &auth_required }, + "Require PAP authentication from peer", + OPT_PRIOSUB | 1, &auth_required }, { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", 1, &auth_required }, + "Require PAP authentication from peer", + OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, + { "require-chap", o_bool, &auth_required, + "Require CHAP authentication from peer", + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, + &lcp_wantoptions[0].chap_mdtype }, + { "+chap", o_bool, &auth_required, + "Require CHAP authentication from peer", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, + &lcp_wantoptions[0].chap_mdtype }, +#ifdef CHAPMS + { "require-mschap", o_bool, &auth_required, + "Require MS-CHAP authentication from peer", + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, + &lcp_wantoptions[0].chap_mdtype }, + { "+mschap", o_bool, &auth_required, + "Require MS-CHAP authentication from peer", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, + &lcp_wantoptions[0].chap_mdtype }, + { "require-mschap-v2", o_bool, &auth_required, + "Require MS-CHAPv2 authentication from peer", + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, + &lcp_wantoptions[0].chap_mdtype }, + { "+mschap-v2", o_bool, &auth_required, + "Require MS-CHAPv2 authentication from peer", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, + &lcp_wantoptions[0].chap_mdtype }, +#endif + { "refuse-pap", o_bool, &refuse_pap, "Don't agree to auth to peer with PAP", 1 }, { "-pap", o_bool, &refuse_pap, - "Don't allow PAP authentication with peer", 1 }, - { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap, - "Require CHAP authentication from peer", 1, &auth_required }, - { "+chap", o_bool, &lcp_wantoptions[0].neg_chap, - "Require CHAP authentication from peer", 1, &auth_required }, + "Don't allow PAP authentication with peer", OPT_ALIAS | 1 }, { "refuse-chap", o_bool, &refuse_chap, - "Don't agree to auth to peer with CHAP", 1 }, + "Don't agree to auth to peer with CHAP", + OPT_A2CLRB | MDTYPE_MD5, + &lcp_allowoptions[0].chap_mdtype }, { "-chap", o_bool, &refuse_chap, - "Don't allow CHAP authentication with peer", 1 }, + "Don't allow CHAP authentication with peer", + OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5, + &lcp_allowoptions[0].chap_mdtype }, +#ifdef CHAPMS + { "refuse-mschap", o_bool, &refuse_mschap, + "Don't agree to auth to peer with MS-CHAP", + OPT_A2CLRB | MDTYPE_MICROSOFT, + &lcp_allowoptions[0].chap_mdtype }, + { "-mschap", o_bool, &refuse_mschap, + "Don't allow MS-CHAP authentication with peer", + OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT, + &lcp_allowoptions[0].chap_mdtype }, + { "refuse-mschap-v2", o_bool, &refuse_mschap_v2, + "Don't agree to auth to peer with MS-CHAPv2", + OPT_A2CLRB | MDTYPE_MICROSOFT_V2, + &lcp_allowoptions[0].chap_mdtype }, + { "-mschap-v2", o_bool, &refuse_mschap_v2, + "Don't allow MS-CHAPv2 authentication with peer", + OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, + &lcp_allowoptions[0].chap_mdtype }, +#endif + + { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, + "Require EAP authentication from peer", OPT_PRIOSUB | 1, + &auth_required }, + { "refuse-eap", o_bool, &refuse_eap, + "Don't agree to authenticate to peer with EAP", 1 }, + { "name", o_string, our_name, "Set local name for authentication", - OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN }, + OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, + + { "+ua", o_special, (void *)setupapfile, + "Get PAP user and password from file", + OPT_PRIO | OPT_A2STRVAL, &uafname }, + { "user", o_string, user, - "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN }, + "Set name for auth with peer", OPT_PRIO | OPT_STATIC, + &explicit_user, MAXNAMELEN }, + + { "password", o_string, passwd, + "Password for authenticating us to the peer", + OPT_PRIO | OPT_STATIC | OPT_HIDE, + &explicit_passwd, MAXSECRETLEN }, + { "usehostname", o_bool, &usehostname, "Must use hostname for authentication", 1 }, + { "remotename", o_string, remote_name, - "Set remote name for authentication", OPT_STATIC, + "Set remote name for authentication", OPT_PRIO | OPT_STATIC, &explicit_remote, MAXNAMELEN }, - { "auth", o_bool, &auth_required, - "Require authentication from peer", 1 }, - { "noauth", o_bool, &auth_required, - "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip }, - { "login", o_bool, &uselogin, - "Use system password database for PAP", 1 }, + + { "login", o_bool, &uselogin, + "Use system password database for PAP", OPT_A2COPY | 1 , + &session_mgmt }, + { "enable-session", o_bool, &session_mgmt, + "Enable session accounting for remote peers", OPT_PRIV | 1 }, + { "papcrypt", o_bool, &cryptpap, "PAP passwords are encrypted", 1 }, - { "+ua", o_special, (void *)setupapfile, - "Get PAP user and password from file" }, - { "password", o_string, passwd, - "Password for authenticating us to the peer", OPT_STATIC, - NULL, MAXSECRETLEN }, + { "privgroup", o_special, (void *)privgroup, - "Allow group members to use privileged options", OPT_PRIV }, + "Allow group members to use privileged options", OPT_PRIV | OPT_A2LIST }, + { "allow-ip", o_special, (void *)set_noauth_addr, "Set IP address(es) which can be used without authentication", - OPT_PRIV }, + OPT_PRIV | OPT_A2LIST }, + + { "remotenumber", o_string, remote_number, + "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC, + NULL, MAXNAMELEN }, + + { "allow-number", o_special, (void *)set_permitted_number, + "Set telephone number(s) which are allowed to connect", + OPT_PRIV | OPT_A2LIST }, + { NULL } }; -#endif /* UNUSED */ -#if 0 /* UNUSED */ + /* * setupapfile - specifies UPAP info for authenticating with peer. */ static int -setupapfile(char **argv) +setupapfile(argv) + char **argv; { - FILE * ufile; + FILE *ufile; int l; + uid_t euid; + char u[MAXNAMELEN], p[MAXSECRETLEN]; + char *fname; lcp_allowoptions[0].neg_upap = 1; /* open user info file */ - seteuid(getuid()); - ufile = fopen(*argv, "r"); - seteuid(0); - if (ufile == NULL) { - option_error("unable to open user login data file %s", *argv); - return 0; + fname = strdup(*argv); + if (fname == NULL) + novm("+ua file name"); + euid = geteuid(); + if (seteuid(getuid()) == -1) { + option_error("unable to reset uid before opening %s: %m", fname); + return 0; } - check_access(ufile, *argv); + ufile = fopen(fname, "r"); + if (seteuid(euid) == -1) + fatal("unable to regain privileges: %m"); + if (ufile == NULL) { + option_error("unable to open user login data file %s", fname); + return 0; + } + check_access(ufile, fname); + uafname = fname; /* get username */ - if (fgets(user, MAXNAMELEN - 1, ufile) == NULL - || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){ - option_error("unable to read user login data file %s", *argv); - return 0; + if (fgets(u, MAXNAMELEN - 1, ufile) == NULL + || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) { + fclose(ufile); + option_error("unable to read user login data file %s", fname); + return 0; } fclose(ufile); /* get rid of newlines */ - l = strlen(user); - if (l > 0 && user[l-1] == '\n') - user[l-1] = 0; - l = strlen(passwd); - if (l > 0 && passwd[l-1] == '\n') - passwd[l-1] = 0; + l = strlen(u); + if (l > 0 && u[l-1] == '\n') + u[l-1] = 0; + l = strlen(p); + if (l > 0 && p[l-1] == '\n') + p[l-1] = 0; + + if (override_value("user", option_priority, fname)) { + strlcpy(user, u, sizeof(user)); + explicit_user = 1; + } + if (override_value("passwd", option_priority, fname)) { + strlcpy(passwd, p, sizeof(passwd)); + explicit_passwd = 1; + } return (1); } -#endif /* UNUSED */ -#if 0 /* UNUSED */ + /* * privgroup - allow members of the group to have privileged access. */ static int -privgroup(char **argv) +privgroup(argv) + char **argv; { struct group *g; int i; g = getgrnam(*argv); if (g == 0) { - option_error("group %s is unknown", *argv); - return 0; + option_error("group %s is unknown", *argv); + return 0; } for (i = 0; i < ngroups; ++i) { - if (groups[i] == g->gr_gid) { - privileged = 1; - break; - } + if (groups[i] == g->gr_gid) { + privileged = 1; + break; + } } return 1; } -#endif -#if 0 /* UNUSED */ + /* * set_noauth_addr - set address(es) that can be used without authentication. * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. */ static int -set_noauth_addr(char **argv) +set_noauth_addr(argv) + char **argv; { char *addr = *argv; - int l = strlen(addr); + int l = strlen(addr) + 1; struct wordlist *wp; - wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l + 1); + wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); if (wp == NULL) - novm("allow-ip argument"); + novm("allow-ip argument"); wp->word = (char *) (wp + 1); wp->next = noauth_addrs; BCOPY(addr, wp->word, l); noauth_addrs = wp; return 1; } -#endif /* UNUSED */ + + +/* + * set_permitted_number - set remote telephone number(s) that may connect. + */ +static int +set_permitted_number(argv) + char **argv; +{ + char *number = *argv; + int l = strlen(number) + 1; + struct wordlist *wp; + + wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); + if (wp == NULL) + novm("allow-number argument"); + wp->word = (char *) (wp + 1); + wp->next = permitted_numbers; + BCOPY(number, wp->word, l); + permitted_numbers = wp; + return 1; +} + /* * 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) +link_required(unit) + int unit; { - LWIP_UNUSED_ARG(unit); - - AUTHDEBUG(LOG_INFO, ("link_required: %d\n", unit)); } +#if 0 +/* + * Bring the link up to the point of being able to do ppp. + */ +void start_link(unit) + int unit; +{ + char *msg; + + new_phase(PHASE_SERIALCONN); + + hungup = 0; + devfd = the_channel->connect(); + msg = "Connect script failed"; + if (devfd < 0) + goto fail; + + /* set up the serial device as a ppp interface */ + /* + * N.B. we used to do tdb_writelock/tdb_writeunlock around this + * (from establish_ppp to set_ifunit). However, we won't be + * doing the set_ifunit in multilink mode, which is the only time + * we need the atomicity that the tdb_writelock/tdb_writeunlock + * gives us. Thus we don't need the tdb_writelock/tdb_writeunlock. + */ + fd_ppp = the_channel->establish_ppp(devfd); + msg = "ppp establishment failed"; + if (fd_ppp < 0) { + status = EXIT_FATAL_ERROR; + goto disconnect; + } + + if (!demand && ifunit >= 0) + set_ifunit(1); + + /* + * Start opening the connection and wait for + * incoming events (reply, timeout, etc.). + */ + if (ifunit >= 0) + notice("Connect: %s <--> %s", ifname, ppp_devnam); + else + notice("Starting negotiation on %s", ppp_devnam); + add_fd(fd_ppp); + + status = EXIT_NEGOTIATION_FAILED; + new_phase(PHASE_ESTABLISH); + + lcp_lowerup(0); + return; + + disconnect: + new_phase(PHASE_DISCONNECT); + if (the_channel->disconnect) + the_channel->disconnect(); + + fail: + new_phase(PHASE_DEAD); + if (the_channel->cleanup) + (*the_channel->cleanup)(); +} +#endif + /* * LCP has terminated the link; go to the Dead phase and take the * physical layer down. */ void -link_terminated(int unit) +link_terminated(unit) + int unit; { - AUTHDEBUG(LOG_INFO, ("link_terminated: %d\n", unit)); - if (lcp_phase[unit] == PHASE_DEAD) { - return; - } - if (logged_in) { - plogout(); - } - lcp_phase[unit] = PHASE_DEAD; - AUTHDEBUG(LOG_NOTICE, ("Connection terminated.\n")); - pppLinkTerminated(unit); + if (phase == PHASE_DEAD || phase == PHASE_MASTER) + return; + new_phase(PHASE_DISCONNECT); + + if (pap_logout_hook) { + pap_logout_hook(); + } + session_end(devnam); + + if (!doing_multilink) { + notice("Connection terminated."); + print_link_stats(); + } else + notice("Link terminated."); + + lcp_lowerdown(0); + +#if 0 + /* + * Delete pid files before disestablishing ppp. Otherwise it + * can happen that another pppd gets the same unit and then + * we delete its pid file. + */ + if (!doing_multilink && !demand) + remove_pidfiles(); + + /* + * 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. + */ + if (fd_ppp >= 0) { + remove_fd(fd_ppp); + clean_check(); + the_channel->disestablish_ppp(devfd); + if (doing_multilink) + mp_exit_bundle(); + fd_ppp = -1; + } + if (!hungup) + lcp_lowerdown(0); + if (!doing_multilink && !demand) + script_unsetenv("IFNAME"); + + /* + * Run disconnector script, if requested. + * XXX we may not be able to do this if the line has hung up! + */ + if (devfd >= 0 && the_channel->disconnect) { + the_channel->disconnect(); + devfd = -1; + } + if (the_channel->cleanup) + (*the_channel->cleanup)(); + + if (doing_multilink && multilink_master) { + if (!bundle_terminating) + new_phase(PHASE_MASTER); + else + mp_bundle_terminated(); + } else + new_phase(PHASE_DEAD); +#endif } /* * LCP has gone down; it will either die or try to re-establish. */ void -link_down(int unit) +link_down(unit) + int unit; { - int i; - struct protent *protp; - - AUTHDEBUG(LOG_INFO, ("link_down: %d\n", unit)); - - if (did_authup) { - /* XXX Do link down processing. */ - did_authup = 0; - } - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (!protp->enabled_flag) { - continue; + if (auth_state != s_down) { + notify(link_down_notifier, 0); + auth_state = s_down; + if (auth_script_state == s_up && auth_script_pid == 0) { + update_link_stats(unit); + auth_script_state = s_down; + auth_script(_PATH_AUTHDOWN); + } } - if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) { - (*protp->lowerdown)(unit); + if (!doing_multilink) { + upper_layers_down(unit); + if (phase != PHASE_DEAD && phase != PHASE_MASTER) + new_phase(PHASE_ESTABLISH); } - if (protp->protocol < 0xC000 && protp->close != NULL) { - (*protp->close)(unit, "LCP down"); - } - } - num_np_open = 0; /* number of network protocols we have opened */ - num_np_up = 0; /* Number of network protocols which have come up */ + /* XXX if doing_multilink, should do something to stop + network-layer traffic on the link */ +} - if (lcp_phase[unit] != PHASE_DEAD) { - lcp_phase[unit] = PHASE_TERMINATE; - } - pppLinkDown(unit); +void upper_layers_down(int unit) +{ + int i; + struct protent *protp; + + 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; } /* @@ -440,384 +733,595 @@ link_down(int unit) * Proceed to the Dead, Authenticate or Network phase as appropriate. */ void -link_established(int unit) +link_established(unit) + int unit; { - int auth; - int i; - struct protent *protp; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *go = &lcp_gotoptions[unit]; -#if PAP_SUPPORT || CHAP_SUPPORT - lcp_options *ho = &lcp_hisoptions[unit]; -#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + 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; + + printf("AUTH: link_established() called"); - AUTHDEBUG(LOG_INFO, ("link_established: unit %d; Lowering up all protocols...\n", unit)); - /* - * Tell higher-level protocols that LCP is up. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) { - (*protp->lowerup)(unit); - } - } - if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) { /* - * We wanted the peer to authenticate itself, and it refused: - * treat it as though it authenticated with PAP using a username - * of "" and a password of "". If that's not OK, boot it out. + * Tell higher-level protocols that LCP is up. */ - if (!wo->neg_upap || !null_login(unit)) { - AUTHDEBUG(LOG_WARNING, ("peer refused to authenticate\n")); - lcp_close(unit, "peer refused to authenticate"); - return; + if (!doing_multilink) { + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol != PPP_LCP && protp->enabled_flag + && protp->lowerup != NULL) + (*protp->lowerup)(unit); } - } - lcp_phase[unit] = PHASE_AUTHENTICATE; - auth = 0; -#if CHAP_SUPPORT - if (go->neg_chap) { - ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype); - auth |= CHAP_PEER; - } -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT && CHAP_SUPPORT - else -#endif /* PAP_SUPPORT && CHAP_SUPPORT */ -#if PAP_SUPPORT - if (go->neg_upap) { - upap_authpeer(unit); - auth |= PAP_PEER; - } -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - if (ho->neg_chap) { - ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype); - auth |= CHAP_WITHPEER; - } -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT && CHAP_SUPPORT - else -#endif /* PAP_SUPPORT && CHAP_SUPPORT */ -#if PAP_SUPPORT - if (ho->neg_upap) { - if (ppp_settings.passwd[0] == 0) { - passwd_from_file = 1; - if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd)) { - AUTHDEBUG(LOG_ERR, ("No secret found for PAP login\n")); - } + if (!auth_required && noauth_addrs != NULL) + set_allowed_addrs(unit, NULL, NULL); + + if (auth_required && !(go->neg_upap || go->neg_chap || go->neg_eap)) { + /* + * 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, NULL, NULL); + } else if (!wo->neg_upap || uselogin || !null_login(unit)) { + warn("peer refused to authenticate: terminating link"); + status = EXIT_PEER_AUTH_FAILED; + lcp_close(unit, "peer refused to authenticate"); + return; + } } - upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); - auth |= PAP_WITHPEER; - } -#endif /* PAP_SUPPORT */ - auth_pending[unit] = auth; - if (!auth) { - network_phase(unit); - } + new_phase(PHASE_AUTHENTICATE); + auth = 0; + if (go->neg_eap) { + eap_authpeer(unit, our_name); + auth |= EAP_PEER; + } else if (go->neg_chap) { + chap_auth_peer(unit, our_name, CHAP_DIGEST(go->chap_mdtype)); + auth |= CHAP_PEER; + } else if (go->neg_upap) { + upap_authpeer(unit); + auth |= PAP_PEER; + } + if (ho->neg_eap) { + eap_authwithpeer(unit, user); + auth |= EAP_WITHPEER; + } else if (ho->neg_chap) { + chap_auth_with_peer(unit, user, CHAP_DIGEST(ho->chap_mdtype)); + auth |= CHAP_WITHPEER; + } else if (ho->neg_upap) { +#if 0 + /* If a blank password was explicitly given as an option, trust + the user and don't try to look up one. */ + if (passwd[0] == 0 && !explicit_passwd) { + passwd_from_file = 1; + if (!get_pap_passwd(passwd)) + error("No secret found for PAP login"); + } + upap_authwithpeer(unit, user, passwd); +#endif + upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); + auth |= PAP_WITHPEER; + } + auth_pending[unit] = auth; + auth_done[unit] = 0; + + if (!auth) + network_phase(unit); } /* * Proceed to the network phase. */ static void -network_phase(int unit) +network_phase(unit) + int unit; { - int i; - struct protent *protp; - lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *go = &lcp_gotoptions[unit]; - /* - * If the peer had to authenticate, run the auth-up script now. - */ - if ((go->neg_chap || go->neg_upap) && !did_authup) { - /* XXX Do setup for peer authentication. */ - did_authup = 1; - } + /* Log calling number. */ + if (*remote_number) + notice("peer from calling number %q authorized", remote_number); + + /* + * If the peer had to authenticate, run the auth-up script now. + */ + if (go->neg_chap || go->neg_upap || go->neg_eap) { + notify(auth_up_notifier, 0); + auth_state = s_up; + if (auth_script_state == s_down && auth_script_pid == 0) { + auth_script_state = s_up; + auth_script(_PATH_AUTHUP); + } + } #if CBCP_SUPPORT - /* - * If we negotiated callback, do it now. - */ - if (go->neg_cbcp) { - lcp_phase[unit] = PHASE_CALLBACK; - (*cbcp_protent.open)(unit); - return; - } -#endif /* CBCP_SUPPORT */ - - lcp_phase[unit] = PHASE_NETWORK; - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) { - (*protp->open)(unit); - if (protp->protocol != PPP_CCP) { - ++num_np_open; - } + /* + * If we negotiated callback, do it now. + */ + if (go->neg_cbcp) { + new_phase(PHASE_CALLBACK); + (*cbcp_protent.open)(unit); + return; } - } +#endif - if (num_np_open == 0) { - /* nothing to do */ - lcp_close(0, "No network protocols running"); - } + /* + * 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(unit); +} + +void +start_networks(unit) + int unit; +{ + int i; + struct protent *protp; + int ecp_required, mppe_required; + + new_phase(PHASE_NETWORK); + +#ifdef HAVE_MULTILINK + if (multilink) { + if (mp_join_bundle()) { + if (multilink_join_hook) + (*multilink_join_hook)(); + if (updetach && !nodetach) + detach(); + return; + } + } +#endif /* HAVE_MULTILINK */ + +#ifdef PPP_FILTER + if (!demand) + set_filters(&pass_filter, &active_filter); +#endif + /* Start CCP and ECP */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP) + && protp->enabled_flag && protp->open != NULL) + (*protp->open)(0); + + /* + * Bring up other network protocols iff encryption is not required. + */ + ecp_required = ecp_gotoptions[unit].required; + mppe_required = ccp_gotoptions[unit].mppe; + if (!ecp_required && !mppe_required) + continue_networks(unit); +} + +void +continue_networks(unit) + int unit; +{ + int i; + struct protent *protp; + + /* + * Start the "real" network protocols. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol < 0xC000 + && protp->protocol != PPP_CCP && protp->protocol != PPP_ECP + && protp->enabled_flag && protp->open != NULL) { + (*protp->open)(0); + ++num_np_open; + } + + if (num_np_open == 0) + /* nothing to do */ + lcp_close(0, "No network protocols running"); } -/* @todo: add void start_networks(void) here (pppd 2.3.11) */ /* * The peer has failed to authenticate himself using `protocol'. */ void -auth_peer_fail(int unit, u16_t protocol) +auth_peer_fail(unit, protocol) + int unit, protocol; { - LWIP_UNUSED_ARG(protocol); - - AUTHDEBUG(LOG_INFO, ("auth_peer_fail: %d proto=%X\n", unit, protocol)); - /* - * Authentication failure: take the link down - */ - lcp_close(unit, "Authentication failed"); + /* + * Authentication failure: take the link down + */ + status = EXIT_PEER_AUTH_FAILED; + lcp_close(unit, "Authentication failed"); } - -#if PAP_SUPPORT || CHAP_SUPPORT /* * The peer has been successfully authenticated using `protocol'. */ void -auth_peer_success(int unit, u16_t protocol, char *name, int namelen) +auth_peer_success(unit, protocol, prot_flavor, name, namelen) + int unit, protocol, prot_flavor; + char *name; + int namelen; { - int pbit; + int bit; - AUTHDEBUG(LOG_INFO, ("auth_peer_success: %d proto=%X\n", unit, protocol)); - switch (protocol) { + switch (protocol) { case PPP_CHAP: - pbit = CHAP_PEER; - break; + bit = CHAP_PEER; + switch (prot_flavor) { + case CHAP_MD5: + bit |= CHAP_MD5_PEER; + break; +#ifdef CHAPMS + case CHAP_MICROSOFT: + bit |= CHAP_MS_PEER; + break; + case CHAP_MICROSOFT_V2: + bit |= CHAP_MS2_PEER; + break; +#endif + } + break; case PPP_PAP: - pbit = PAP_PEER; - break; + bit = PAP_PEER; + break; + case PPP_EAP: + bit = EAP_PEER; + break; default: - AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol)); - return; - } + warn("auth_peer_success: unknown protocol %x", protocol); + return; + } - /* - * Save the authenticated name of the peer for later. - */ - if (namelen > (int)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] &= ~pbit) == 0) { - network_phase(unit); - } + /* + * 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; + script_setenv("PEERNAME", peer_authname, 0); + + /* Save the authentication method for later. */ + auth_done[unit] |= bit; + + /* + * 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, u16_t protocol) +auth_withpeer_fail(unit, protocol) + int unit, protocol; { - int errCode = PPPERR_AUTHFAIL; - - LWIP_UNUSED_ARG(protocol); - - AUTHDEBUG(LOG_INFO, ("auth_withpeer_fail: %d proto=%X\n", unit, protocol)); - if (passwd_from_file) { - BZERO(ppp_settings.passwd, MAXSECRETLEN); - } - - /* - * We've failed to authenticate ourselves to our peer. - * He'll probably take the link down, and there's not much - * we can do except wait for that. - */ - pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode); - lcp_close(unit, "Failed to authenticate ourselves to peer"); + 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. + */ + status = EXIT_AUTH_TOPEER_FAILED; + lcp_close(unit, "Failed to authenticate ourselves to peer"); } /* * We have successfully authenticated ourselves with the peer using `protocol'. */ void -auth_withpeer_success(int unit, u16_t protocol) +auth_withpeer_success(unit, protocol, prot_flavor) + int unit, protocol, prot_flavor; { - int pbit; + int bit; + const char *prot = ""; - AUTHDEBUG(LOG_INFO, ("auth_withpeer_success: %d proto=%X\n", unit, protocol)); - switch (protocol) { + switch (protocol) { case PPP_CHAP: - pbit = CHAP_WITHPEER; - break; + bit = CHAP_WITHPEER; + prot = "CHAP"; + switch (prot_flavor) { + case CHAP_MD5: + bit |= CHAP_MD5_WITHPEER; + break; +#ifdef CHAPMS + case CHAP_MICROSOFT: + bit |= CHAP_MS_WITHPEER; + break; + case CHAP_MICROSOFT_V2: + bit |= CHAP_MS2_WITHPEER; + break; +#endif + } + break; case PPP_PAP: - if (passwd_from_file) { - BZERO(ppp_settings.passwd, MAXSECRETLEN); - } - pbit = PAP_WITHPEER; - break; + if (passwd_from_file) + BZERO(passwd, MAXSECRETLEN); + bit = PAP_WITHPEER; + prot = "PAP"; + break; + case PPP_EAP: + bit = EAP_WITHPEER; + prot = "EAP"; + break; default: - AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol)); - pbit = 0; - } + 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] &= ~pbit) == 0) { - network_phase(unit); - } + notice("%s authentication succeeded", prot); + + /* Save the authentication method for later. */ + auth_done[unit] |= bit; + + /* + * 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); } -#endif /* PAP_SUPPORT || CHAP_SUPPORT */ /* * np_up - a network protocol has come up. */ void -np_up(int unit, u16_t proto) +np_up(unit, proto) + int unit, proto; { - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(proto); + int tlim; - AUTHDEBUG(LOG_INFO, ("np_up: %d proto=%X\n", unit, proto)); - if (num_np_up == 0) { - AUTHDEBUG(LOG_INFO, ("np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit)); - /* - * At this point we consider that the link has come up successfully. - */ - if (ppp_settings.idle_time_limit > 0) { - TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit); - } + if (num_np_up == 0) { + /* + * At this point we consider that the link has come up successfully. + */ + status = EXIT_OK; + unsuccess = 0; + new_phase(PHASE_RUNNING); - /* - * Set a timeout to close the connection once the maximum - * connect time has expired. - */ - if (ppp_settings.maxconnect > 0) { - TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect); + 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); + +#ifdef MAXOCTETS + if (maxoctets > 0) + TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); +#endif + + /* + * Detach now, if the updetach option was given. + */ + if (updetach && !nodetach) + detach(); } - } - ++num_np_up; + ++num_np_up; } /* * np_down - a network protocol has gone down. */ void -np_down(int unit, u16_t proto) +np_down(unit, proto) + int unit, proto; { - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(proto); - - AUTHDEBUG(LOG_INFO, ("np_down: %d proto=%X\n", unit, proto)); - if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) { - UNTIMEOUT(check_idle, NULL); - } + if (--num_np_up == 0) { + UNTIMEOUT(check_idle, NULL); + UNTIMEOUT(connect_time_expired, NULL); +#ifdef MAXOCTETS + UNTIMEOUT(check_maxoctets, NULL); +#endif + new_phase(PHASE_NETWORK); + } } /* * np_finished - a network protocol has finished using the link. */ void -np_finished(int unit, u16_t proto) +np_finished(unit, proto) + int unit, proto; { - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(proto); - - AUTHDEBUG(LOG_INFO, ("np_finished: %d proto=%X\n", unit, proto)); - if (--num_np_open <= 0) { - /* no further use for the link: shut up shop. */ - lcp_close(0, "No network protocols running"); - } + if (--num_np_open <= 0) { + /* no further use for the link: shut up shop. */ + lcp_close(0, "No network protocols running"); + } } +#ifdef MAXOCTETS +static void +check_maxoctets(arg) + void *arg; +{ + unsigned int used; + + update_link_stats(ifunit); + link_stats_valid=0; + + switch(maxoctets_dir) { + case PPP_OCTETS_DIRECTION_IN: + used = link_stats.bytes_in; + break; + case PPP_OCTETS_DIRECTION_OUT: + used = link_stats.bytes_out; + break; + case PPP_OCTETS_DIRECTION_MAXOVERAL: + case PPP_OCTETS_DIRECTION_MAXSESSION: + used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out; + break; + default: + used = link_stats.bytes_in+link_stats.bytes_out; + break; + } + if (used > maxoctets) { + notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); + status = EXIT_TRAFFIC_LIMIT; + lcp_close(0, "Traffic limit"); + need_holdoff = 0; + } else { + TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); + } +} +#endif + /* * check_idle - check whether the link has been idle for long * enough that we can shut it down. */ static void -check_idle(void *arg) +check_idle(arg) + void *arg; { - struct ppp_idle idle; - u_short itime; - - LWIP_UNUSED_ARG(arg); - if (!get_idle_time(0, &idle)) { - return; - } - itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); - if (itime >= ppp_settings.idle_time_limit) { - /* link is idle: shut it down. */ - AUTHDEBUG(LOG_INFO, ("Terminating connection due to lack of activity.\n")); - lcp_close(0, "Link inactive"); - } else { - TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime); - } + 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."); + status = EXIT_IDLE_TIMEOUT; + lcp_close(0, "Link inactive"); + need_holdoff = 0; + } else { + TIMEOUT(check_idle, NULL, tlim); + } } /* * connect_time_expired - log a message and close the connection. */ static void -connect_time_expired(void *arg) +connect_time_expired(arg) + void *arg; { - LWIP_UNUSED_ARG(arg); - - AUTHDEBUG(LOG_INFO, ("Connect time expired\n")); - lcp_close(0, "Connect time expired"); /* Close connection */ + info("Connect time expired"); + status = EXIT_CONNECT_TIME; + lcp_close(0, "Connect time expired"); /* Close connection */ } -#if 0 /* UNUSED */ /* * auth_check_options - called to check authentication options. */ void -auth_check_options(void) +auth_check_options() { - lcp_options *wo = &lcp_wantoptions[0]; - int can_auth; - ipcp_options *ipwo = &ipcp_wantoptions[0]; - u32_t remote; + lcp_options *wo = &lcp_wantoptions[0]; + int can_auth; + int lacks_ip; - /* Default our_name to hostname, and user to our_name */ - if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) { - strcpy(ppp_settings.our_name, ppp_settings.hostname); - } + /* Default our_name to hostname, and user to our_name */ + if (our_name[0] == 0 || usehostname) + strlcpy(our_name, hostname, sizeof(our_name)); + /* If a blank username was explicitly given as an option, trust + the user and don't use our_name */ + if (user[0] == 0 && !explicit_user) + strlcpy(user, our_name, sizeof(user)); - if (ppp_settings.user[0] == 0) { - strcpy(ppp_settings.user, ppp_settings.our_name); - } + /* + * 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) { + auth_required = 1; + default_auth = 1; + } - /* If authentication is required, ask peer for CHAP or PAP. */ - if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) { - wo->neg_chap = 1; - wo->neg_upap = 1; - } - - /* - * Check whether we have appropriate secrets to use - * to authenticate the peer. - */ - can_auth = wo->neg_upap && have_pap_secret(); - if (!can_auth && wo->neg_chap) { - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote); - } + /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ + if (wo->chap_mdtype) + wo->neg_chap = 1; - if (ppp_settings.auth_required && !can_auth) { - ppp_panic("No auth secret"); - } + /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ + if (auth_required) { + allow_any_ip = 0; + if (!wo->neg_chap && !wo->neg_upap && !wo->neg_eap) { + wo->neg_chap = chap_mdtype_all != MDTYPE_NONE; + wo->chap_mdtype = chap_mdtype_all; + wo->neg_upap = 1; + wo->neg_eap = 1; + } + } else { + wo->neg_chap = 0; + wo->chap_mdtype = MDTYPE_NONE; + wo->neg_upap = 0; + wo->neg_eap = 0; + } + + /* + * Check whether we have appropriate secrets to use + * to authenticate the peer. Note that EAP can authenticate by way + * of a CHAP-like exchanges as well as SRP. + */ + lacks_ip = 0; + can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); + if (!can_auth && (wo->neg_chap || wo->neg_eap)) { + can_auth = have_chap_secret((explicit_remote? remote_name: NULL), + our_name, 1, &lacks_ip); + } + if (!can_auth && wo->neg_eap) { + can_auth = have_srp_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.)"); + + exit(1); + } + + /* + * Early check for remote number authorization. + */ + if (!auth_number()) { + warn("calling number %q is not authorized", remote_number); + exit(EXIT_CNID_AUTH_FAILED); + } } -#endif /* UNUSED */ /* * auth_reset - called when LCP is starting negotiations to recheck @@ -825,176 +1329,172 @@ auth_check_options(void) * to use for authenticating ourselves and/or the peer. */ void -auth_reset(int unit) +auth_reset(unit) + int unit; { - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[0]; - ipcp_options *ipwo = &ipcp_wantoptions[0]; - u32_t remote; + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *ao = &lcp_allowoptions[unit]; + int hadchap; - AUTHDEBUG(LOG_INFO, ("auth_reset: %d\n", unit)); - ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL)); - ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/; + hadchap = -1; + ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); + ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2) + && (passwd[0] != 0 || + (hadchap = have_chap_secret(user, (explicit_remote? remote_name: + NULL), 0, NULL))); + ao->neg_eap = !refuse_eap && ( + passwd[0] != 0 || + (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, + (explicit_remote? remote_name: NULL), 0, NULL))) || + have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); - if (go->neg_upap && !have_pap_secret()) { - go->neg_upap = 0; - } - if (go->neg_chap) { - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) { - go->neg_chap = 0; + hadchap = -1; + if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) + go->neg_upap = 0; + if (go->neg_chap) { + if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), + our_name, 1, NULL))) + go->neg_chap = 0; } - } + if (go->neg_eap && + (hadchap == 0 || (hadchap == -1 && + !have_chap_secret((explicit_remote? remote_name: NULL), our_name, + 1, NULL))) && + !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, + NULL)) + go->neg_eap = 0; } -#if PAP_SUPPORT + /* * 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. + * UPAP_AUTHNAK: Authentication failed. + * UPAP_AUTHACK: Authentication succeeded. * In either case, msg points to an appropriate message. */ -u_char -check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen) +int +check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) + int unit; + char *auser; + int userlen; + char *apasswd; + int passwdlen; + char **msg; { -#if 1 /* XXX Assume all entries OK. */ - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(auser); - LWIP_UNUSED_ARG(userlen); - LWIP_UNUSED_ARG(apasswd); - LWIP_UNUSED_ARG(passwdlen); - LWIP_UNUSED_ARG(msglen); - *msg = (char *) 0; - return UPAP_AUTHACK; /* XXX Assume all entries OK. */ -#else - u_char ret = 0; - struct wordlist *addrs = NULL; - char passwd[256], user[256]; - char secret[MAXWORDLEN]; - static u_short attempts = 0; - - /* - * Make copies of apasswd and auser, then null-terminate them. - */ - BCOPY(apasswd, passwd, passwdlen); - passwd[passwdlen] = '\0'; - BCOPY(auser, user, userlen); - user[userlen] = '\0'; - *msg = (char *) 0; + int ret; + char *filename; + FILE *f; + struct wordlist *addrs = NULL, *opts = NULL; + char passwd[256], user[256]; + char secret[MAXWORDLEN]; + static int attempts = 0; - /* XXX Validate user name and password. */ - ret = UPAP_AUTHACK; /* XXX Assume all entries OK. */ - - if (ret == UPAP_AUTHNAK) { - if (*msg == (char *) 0) { - *msg = "Login incorrect"; - } - *msglen = strlen(*msg); /* - * Frustrate passwd stealer programs. - * Allow 10 tries, but start backing off after 3 (stolen from login). - * On 10'th, drop the connection. + * Make copies of apasswd and auser, then null-terminate them. + * If there are unprintable characters in the password, make + * them visible. */ - if (attempts++ >= 10) { - AUTHDEBUG(LOG_WARNING, ("%d LOGIN FAILURES BY %s\n", attempts, user)); - /*ppp_panic("Excess Bad Logins");*/ + slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd); + slprintf(user, sizeof(user), "%.*v", userlen, auser); + *msg = ""; + + /* + * Check if a plugin wants to handle this. + */ + if (pap_auth_hook) { + ret = (*pap_auth_hook)(user, passwd, msg, &addrs, &opts); + if (ret >= 0) { + /* note: set_allowed_addrs() saves opts (but not addrs): + don't free it! */ + if (ret) + set_allowed_addrs(unit, addrs, opts); + else if (opts != 0) + free_wordlist(opts); + if (addrs != 0) + free_wordlist(addrs); + BZERO(passwd, sizeof(passwd)); + return ret? UPAP_AUTHACK: UPAP_AUTHNAK; + } } - if (attempts > 3) { - /* @todo: this was sleep(), i.e. seconds, not milliseconds - * I don't think we really need this in lwIP - we would block tcpip_thread! - */ - /*sys_msleep((attempts - 3) * 5);*/ + + /* + * Open the file of pap secrets and scan for a suitable secret + * for authenticating this user. + */ + filename = _PATH_UPAPFILE; + addrs = opts = NULL; + ret = UPAP_AUTHNAK; + f = fopen(filename, "r"); + if (f == NULL) { + error("Can't open PAP password file %s: %m", filename); + + } else { + check_access(f, filename); + if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename, 0) < 0) { + warn("no PAP secret found for %s", user); + } else { + /* + * If the secret is "@login", it means to check + * the password against the login database. + */ + int login_secret = strcmp(secret, "@login") == 0; + ret = UPAP_AUTHACK; + if (uselogin || login_secret) { + /* login option or secret is @login */ + if (session_full(user, passwd, devnam, msg) == 0) { + ret = UPAP_AUTHNAK; + } + } else if (session_mgmt) { + if (session_check(user, NULL, devnam, NULL) == 0) { + warn("Peer %q failed PAP Session verification", user); + ret = UPAP_AUTHNAK; + } + } + if (secret[0] != 0 && !login_secret) { + /* password given in pap-secrets - must match */ + if ((cryptpap || strcmp(passwd, secret) != 0) + && strcmp(crypt(passwd, secret), secret) != 0) + ret = UPAP_AUTHNAK; + } + } + fclose(f); } - if (addrs != NULL) { - free_wordlist(addrs); + + if (ret == UPAP_AUTHNAK) { + if (**msg == 0) + *msg = "Login incorrect"; + /* + * XXX can we ever get here more than once?? + * Frustrate passwd stealer programs. + * Allow 10 tries, but start backing off after 3 (stolen from login). + * On 10'th, drop the connection. + */ + if (attempts++ >= 10) { + warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); + lcp_close(unit, "login failed"); + } + if (attempts > 3) + sleep((u_int) (attempts - 3) * 5); + if (opts != NULL) + free_wordlist(opts); + + } else { + attempts = 0; /* Reset count */ + if (**msg == 0) + *msg = "Login ok"; + set_allowed_addrs(unit, addrs, opts); } - } else { - attempts = 0; /* Reset count */ - if (*msg == (char *) 0) { - *msg = "Login ok"; - } - *msglen = strlen(*msg); - set_allowed_addrs(unit, addrs); - } - BZERO(passwd, sizeof(passwd)); - BZERO(secret, sizeof(secret)); + if (addrs != NULL) + free_wordlist(addrs); + BZERO(passwd, sizeof(passwd)); + BZERO(secret, sizeof(secret)); - return ret; -#endif -} -#endif /* PAP_SUPPORT */ - -#if 0 /* UNUSED */ -/* - * This function is needed for PAM. - */ - -#ifdef USE_PAM - -/* lwip does not support PAM*/ - -#endif /* USE_PAM */ - -#endif /* UNUSED */ - - -#if 0 /* UNUSED */ -/* - * plogin - Check the user name and password against the system - * password database, and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Login failed. - * UPAP_AUTHACK: Login succeeded. - * In either case, msg points to an appropriate message. - */ -static int -plogin(char *user, char *passwd, char **msg, int *msglen) -{ - - LWIP_UNUSED_ARG(user); - LWIP_UNUSED_ARG(passwd); - LWIP_UNUSED_ARG(msg); - LWIP_UNUSED_ARG(msglen); - - - /* The new lines are here align the file when - * compared against the pppd 2.3.11 code */ - - - - - - - - - - - - - - - - - /* XXX Fail until we decide that we want to support logins. */ - return (UPAP_AUTHNAK); -} -#endif - - - -/* - * plogout - Logout the user. - */ -static void -plogout(void) -{ - logged_in = 0; + return ret; } /* @@ -1003,11 +1503,47 @@ plogout(void) * and return 1. */ static int -null_login(int unit) +null_login(unit) + int unit; { - LWIP_UNUSED_ARG(unit); - /* XXX Fail until we decide that we want to support logins. */ - return 0; + char *filename; + FILE *f; + int i, ret; + struct wordlist *addrs, *opts; + char secret[MAXWORDLEN]; + + /* + * Check if a plugin wants to handle this. + */ + ret = -1; + if (null_auth_hook) + ret = (*null_auth_hook)(&addrs, &opts); + + /* + * Open the file of pap secrets and scan for a suitable secret. + */ + if (ret <= 0) { + filename = _PATH_UPAPFILE; + addrs = NULL; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + check_access(f, filename); + + i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0); + ret = i >= 0 && secret[0] == 0; + BZERO(secret, sizeof(secret)); + fclose(f); + } + + if (ret) + set_allowed_addrs(unit, addrs, opts); + else if (opts != 0) + free_wordlist(opts); + if (addrs != 0) + free_wordlist(addrs); + + return ret; } @@ -1015,38 +1551,84 @@ null_login(int unit) * 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(int unit, char *user, char *passwd) +get_pap_passwd(passwd) + char *passwd; { - LWIP_UNUSED_ARG(unit); -/* normally we would reject PAP if no password is provided, - but this causes problems with some providers (like CHT in Taiwan) - who incorrectly request PAP and expect a bogus/empty password, so - always provide a default user/passwd of "none"/"none" + char *filename; + FILE *f; + int ret; + char secret[MAXWORDLEN]; - @todo: This should be configured by the user, instead of being hardcoded here! -*/ - if(user) { - strcpy(user, "none"); - } - if(passwd) { - strcpy(passwd, "none"); - } - return 1; + /* + * Check whether a plugin wants to supply this. + */ + if (pap_passwd_hook) { + ret = (*pap_passwd_hook)(user, passwd); + if (ret >= 0) + return ret; + } + + filename = _PATH_UPAPFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + check_access(f, filename); + ret = scan_authfile(f, user, + (remote_name[0]? remote_name: NULL), + secret, NULL, NULL, filename, 0); + fclose(f); + if (ret < 0) + return 0; + if (passwd != NULL) + strlcpy(passwd, secret, MAXSECRETLEN); + BZERO(secret, sizeof(secret)); + return 1; } + /* * 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(void) +have_pap_secret(lacks_ipp) + int *lacks_ipp; { - /* XXX Fail until we set up our passwords. */ - return 0; + FILE *f; + int ret; + char *filename; + struct wordlist *addrs; + + /* let the plugin decide, if there is one */ + if (pap_check_hook) { + ret = (*pap_check_hook)(); + if (ret >= 0) + return ret; + } + + filename = _PATH_UPAPFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + + ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name, + NULL, &addrs, NULL, filename, 0); + fclose(f); + if (ret >= 0 && !some_ip_ok(addrs)) { + if (lacks_ipp != 0) + *lacks_ipp = 1; + ret = -1; + } + if (addrs != 0) + free_wordlist(addrs); + + return ret >= 0; } + /* * have_chap_secret - check whether we have a CHAP file with a * secret that we could possibly use for authenticating `client' @@ -1054,16 +1636,89 @@ have_pap_secret(void) * know the identity yet. */ static int -have_chap_secret(char *client, char *server, u32_t remote) +have_chap_secret(client, server, need_ip, lacks_ipp) + char *client; + char *server; + int need_ip; + int *lacks_ipp; { - LWIP_UNUSED_ARG(client); - LWIP_UNUSED_ARG(server); - LWIP_UNUSED_ARG(remote); + FILE *f; + int ret; + char *filename; + struct wordlist *addrs; - /* XXX Fail until we set up our passwords. */ - return 0; + if (chap_check_hook) { + ret = (*chap_check_hook)(); + if (ret >= 0) { + return ret; + } + } + + filename = _PATH_CHAPFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + + if (client != NULL && client[0] == 0) + client = NULL; + else if (server != NULL && server[0] == 0) + server = NULL; + + ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); + fclose(f); + if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { + if (lacks_ipp != 0) + *lacks_ipp = 1; + ret = -1; + } + if (addrs != 0) + free_wordlist(addrs); + + return ret >= 0; } -#if CHAP_SUPPORT + + +/* + * have_srp_secret - check whether we have a SRP 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_srp_secret(client, server, need_ip, lacks_ipp) + char *client; + char *server; + int need_ip; + int *lacks_ipp; +{ + FILE *f; + int ret; + char *filename; + struct wordlist *addrs; + + filename = _PATH_SRPFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + + if (client != NULL && client[0] == 0) + client = NULL; + else if (server != NULL && server[0] == 0) + server = NULL; + + ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); + fclose(f); + if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { + if (lacks_ipp != 0) + *lacks_ipp = 1; + ret = -1; + } + if (addrs != 0) + free_wordlist(addrs); + + return ret >= 0; +} + /* * get_secret - open the CHAP secret file and return the secret @@ -1071,128 +1726,311 @@ have_chap_secret(char *client, char *server, u32_t remote) * (We could be either client or server). */ int -get_secret(int unit, char *client, char *server, char *secret, int *secret_len, int save_addrs) +get_secret(unit, client, server, secret, secret_len, am_server) + int unit; + char *client; + char *server; + char *secret; + int *secret_len; + int am_server; { -#if 1 - int len; - struct wordlist *addrs; + FILE *f; + int ret, len; + char *filename; + struct wordlist *addrs, *opts; + char secbuf[MAXWORDLEN]; - LWIP_UNUSED_ARG(unit); - LWIP_UNUSED_ARG(server); - LWIP_UNUSED_ARG(save_addrs); + if (!am_server && passwd[0] != 0) { + strlcpy(secbuf, passwd, sizeof(secbuf)); + } else if (!am_server && chap_passwd_hook) { + if ( (*chap_passwd_hook)(client, secbuf) < 0) { + error("Unable to obtain CHAP password for %s on %s from plugin", + client, server); + return 0; + } + } else { + filename = _PATH_CHAPFILE; + addrs = NULL; + secbuf[0] = 0; - addrs = NULL; + f = fopen(filename, "r"); + if (f == NULL) { + error("Can't open chap secret file %s: %m", filename); + return 0; + } + check_access(f, filename); - if(!client || !client[0] || strcmp(client, ppp_settings.user)) { - return 0; - } + ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0); + fclose(f); + if (ret < 0) + return 0; - len = (int)strlen(ppp_settings.passwd); - if (len > MAXSECRETLEN) { - AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server)); - len = MAXSECRETLEN; - } + if (am_server) + set_allowed_addrs(unit, addrs, opts); + else if (opts != 0) + free_wordlist(opts); + if (addrs != 0) + free_wordlist(addrs); + } - BCOPY(ppp_settings.passwd, secret, len); - *secret_len = len; + 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; -#else - int ret = 0, len; - struct wordlist *addrs; - char secbuf[MAXWORDLEN]; - - addrs = NULL; - secbuf[0] = 0; - - /* XXX Find secret. */ - if (ret < 0) { - return 0; - } - - if (save_addrs) { - set_allowed_addrs(unit, addrs); - } - - len = strlen(secbuf); - if (len > MAXSECRETLEN) { - AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server)); - len = MAXSECRETLEN; - } - - BCOPY(secbuf, secret, len); - BZERO(secbuf, sizeof(secbuf)); - *secret_len = len; - - return 1; -#endif + return 1; } -#endif /* CHAP_SUPPORT */ -#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ +/* + * get_srp_secret - open the SRP secret file and return the secret + * for authenticating the given client on the given server. + * (We could be either client or server). + */ +int +get_srp_secret(unit, client, server, secret, am_server) + int unit; + char *client; + char *server; + char *secret; + int am_server; +{ + FILE *fp; + int ret; + char *filename; + struct wordlist *addrs, *opts; + + if (!am_server && passwd[0] != '\0') { + strlcpy(secret, passwd, MAXWORDLEN); + } else { + filename = _PATH_SRPFILE; + addrs = NULL; + + fp = fopen(filename, "r"); + if (fp == NULL) { + error("Can't open srp secret file %s: %m", filename); + return 0; + } + check_access(fp, filename); + + secret[0] = '\0'; + ret = scan_authfile(fp, client, server, secret, &addrs, &opts, + filename, am_server); + fclose(fp); + if (ret < 0) + return 0; + + if (am_server) + set_allowed_addrs(unit, addrs, opts); + else if (opts != NULL) + free_wordlist(opts); + if (addrs != NULL) + free_wordlist(addrs); + } + + 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) +set_allowed_addrs(unit, addrs, opts) + int unit; + struct wordlist *addrs; + struct wordlist *opts; { - if (addresses[unit] != NULL) { - free_wordlist(addresses[unit]); - } - addresses[unit] = addrs; - -#if 0 - /* - * If there's only one authorized address we might as well - * ask our peer for that one right away - */ - if (addrs != NULL && addrs->next == NULL) { - char *p = addrs->word; - struct ipcp_options *wo = &ipcp_wantoptions[unit]; - u32_t a; + int n; + struct wordlist *ap, **plink; + struct permitted_ip *ip; + char *ptr_word, *ptr_mask; struct hostent *hp; - - if (wo->hisaddr == 0 && *p != '!' && *p != '-' && strchr(p, '/') == NULL) { - hp = gethostbyname(p); - if (hp != NULL && hp->h_addrtype == AF_INET) { - a = *(u32_t *)hp->h_addr; - } else { - a = inet_addr(p); - } - if (a != (u32_t) -1) { - wo->hisaddr = a; - } + struct netent *np; + u_int32_t a, mask, ah, offset; + struct ipcp_options *wo = &ipcp_wantoptions[unit]; + u_int32_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. + */ + n = wordlist_count(addrs) + wordlist_count(noauth_addrs); + if (n == 0) + return; + ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); + if (ip == 0) + return; + + /* temporarily append the noauth_addrs list to addrs */ + for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) + ; + *plink = noauth_addrs; + + 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 = ~ (u_int32_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 = ifunit + 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 = *(u_int32_t *)hp->h_addr; + } else { + np = getnetbyname (ptr_word); + if (np != NULL && np->n_addrtype == AF_INET) { + a = htonl ((u_int32_t)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 == (u_int32_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", + ifunit, ptr_word); + continue; + } + a = htonl((ntohl(a) & mask) + offset); + mask = ~(u_int32_t)0; + } + ip[n].mask = htonl(mask); + ip[n].base = a & ip[n].mask; + ++n; + if (~mask == 0 && suggested_ip == 0) + suggested_ip = a; + } + *plink = NULL; + + 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; + /* + * Do we insist on this address? No, if there are other + * addresses authorized than the suggested one. + */ + if (n > 1) + wo->accept_remote = 1; } - } -#endif } -#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ /* * 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, u32_t addr) +auth_ip_addr(unit, addr) + int unit; + u_int32_t addr; { - return ip_addr_check(addr, addresses[unit]); + int ok; + + /* don't allow loopback or multicast address */ + if (bad_ip_adrs(addr)) + return 0; + + if (allowed_address_hook) { + ok = allowed_address_hook(addr); + if (ok >= 0) return ok; + } + + 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 || privileged || !have_route_to(addr); } -static int /* @todo: integrate this funtion into auth_ip_addr()*/ -ip_addr_check(u32_t addr, struct wordlist *addrs) +static int +ip_addr_check(addr, addrs) + u_int32_t addr; + struct permitted_ip *addrs; { - /* don't allow loopback or multicast address */ - if (bad_ip_adrs(addr)) { - return 0; - } - - if (addrs == NULL) { - return !ppp_settings.auth_required; /* no addresses authorized */ - } - - /* XXX All other addresses allowed. */ - return 1; + for (; ; ++addrs) + if ((addr & addrs->mask) == addrs->base) + return addrs->permit; } /* @@ -1201,47 +2039,78 @@ ip_addr_check(u32_t addr, struct wordlist *addrs) * addr is in network byte order. */ int -bad_ip_adrs(u32_t addr) +bad_ip_adrs(addr) + u_int32_t addr; { - addr = ntohl(addr); - return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET - || IN_MULTICAST(addr) || IN_BADCLASS(addr); + addr = ntohl(addr); + return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET + || IN_MULTICAST(addr) || IN_BADCLASS(addr); } -#if 0 /* UNUSED */ /* PAP_SUPPORT || CHAP_SUPPORT */ /* * some_ip_ok - check a wordlist to see if it authorizes any * IP address(es). */ static int -some_ip_ok(struct wordlist *addrs) +some_ip_ok(addrs) + struct wordlist *addrs; { for (; addrs != 0; addrs = addrs->next) { - if (addrs->word[0] == '-') - break; - if (addrs->word[0] != '!') - return 1; /* some IP address is allowed */ + if (addrs->word[0] == '-') + break; + if (addrs->word[0] != '!') + return 1; /* some IP address is allowed */ } return 0; } +/* + * auth_number - check whether the remote number is allowed to connect. + * Returns 1 if authorized, 0 otherwise. + */ +int +auth_number() +{ + struct wordlist *wp = permitted_numbers; + int l; + + /* Allow all if no authorization list. */ + if (!wp) + return 1; + + /* Allow if we have a match in the authorization list. */ + while (wp) { + /* trailing '*' wildcard */ + l = strlen(wp->word); + if ((wp->word)[l - 1] == '*') + l--; + if (!strncasecmp(wp->word, remote_number, l)) + return 1; + wp = wp->next; + } + + return 0; +} + /* * check_access - complain if a secret file has too-liberal permissions. */ static void -check_access(FILE *f, char *filename) +check_access(f, filename) + FILE *f; + char *filename; { struct stat sbuf; if (fstat(fileno(f), &sbuf) < 0) { - warn("cannot stat secret file %s: %m", filename); + warn("cannot stat secret file %s: %m", filename); } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - warn("Warning - secret file %s has world and/or group access", - filename); + warn("Warning - secret file %s has world and/or group access", + filename); } } - +/* FIXME: useless ! */ /* * scan_authfile - Scan an authorization file for a secret suitable * for authenticating `client' on `server'. The return value is -1 @@ -1253,26 +2122,197 @@ check_access(FILE *f, char *filename) * following words (extra options) are placed in a wordlist and * returned in *opts. * We assume secret is NULL or points to MAXWORDLEN bytes of space. + * Flags are non-zero if we need two colons in the secret in order to + * match. */ static int -scan_authfile(FILE *f, char *client, char *server, char *secret, struct wordlist **addrs, struct wordlist **opts, char *filename) +scan_authfile(f, client, server, secret, addrs, opts, filename, flags) + FILE *f; + char *client; + char *server; + char *secret; + struct wordlist **addrs; + struct wordlist **opts; + char *filename; + int flags; { - /* We do not (currently) need this in lwip */ - return 0; /* dummy */ + int newline, xxx; + int got_flag, best_flag; + FILE *sf; + struct wordlist *ap, *addr_list, *alist, **app; + char word[MAXWORDLEN]; + char atfile[MAXWORDLEN]; + char lsecret[MAXWORDLEN]; + char *cp; + + if (addrs != NULL) + *addrs = NULL; + if (opts != NULL) + *opts = NULL; + addr_list = NULL; + if (!getword(f, word, &newline, filename)) + return -1; /* file is empty??? */ + newline = 1; + best_flag = -1; + for (;;) { + /* + * Skip until we find a word at the start of a line. + */ + while (!newline && getword(f, word, &newline, filename)) + ; + if (!newline) + break; /* got to end of file */ + + /* + * Got a client - check if it's a match or a wildcard. + */ + got_flag = 0; + if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { + newline = 0; + continue; + } + if (!ISWILD(word)) + got_flag = NONWILD_CLIENT; + + /* + * Now get a server and check if it matches. + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + if (!ISWILD(word)) { + if (server != NULL && strcmp(word, server) != 0) + continue; + got_flag |= NONWILD_SERVER; + } + + /* + * Got some sort of a match - see if it's better than what + * we have already. + */ + if (got_flag <= best_flag) + continue; + + /* + * Get the secret. + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + + /* + * SRP-SHA1 authenticator should never be reading secrets from + * a file. (Authenticatee may, though.) + */ + if (flags && ((cp = strchr(word, ':')) == NULL || + strchr(cp + 1, ':') == NULL)) + continue; + + if (secret != NULL) { + /* + * Special syntax: @/pathname means read secret from file. + */ + if (word[0] == '@' && word[1] == '/') { + strlcpy(atfile, word+1, sizeof(atfile)); + if ((sf = fopen(atfile, "r")) == NULL) { + warn("can't open indirect secret file %s", atfile); + continue; + } + check_access(sf, atfile); + if (!getword(sf, word, &xxx, atfile)) { + warn("no secret in indirect secret file %s", atfile); + fclose(sf); + continue; + } + fclose(sf); + } + strlcpy(lsecret, word, sizeof(lsecret)); + } + + /* + * Now read address authorization info and make a wordlist. + */ + app = &alist; + for (;;) { + if (!getword(f, word, &newline, filename) || newline) + break; + ap = (struct wordlist *) + malloc(sizeof(struct wordlist) + strlen(word) + 1); + if (ap == NULL) + novm("authorized addresses"); + ap->word = (char *) (ap + 1); + strcpy(ap->word, word); + *app = ap; + app = &ap->next; + } + *app = NULL; + + /* + * This is the best so far; remember it. + */ + best_flag = got_flag; + if (addr_list) + free_wordlist(addr_list); + addr_list = alist; + if (secret != NULL) + strlcpy(secret, lsecret, MAXWORDLEN); + + if (!newline) + break; + } + + /* scan for a -- word indicating the start of options */ + for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) + if (strcmp(ap->word, "--") == 0) + break; + /* ap = start of options */ + if (ap != NULL) { + ap = ap->next; /* first option */ + free(*app); /* free the "--" word */ + *app = NULL; /* terminate addr list */ + } + if (opts != NULL) + *opts = ap; + else if (ap != NULL) + free_wordlist(ap); + if (addrs != NULL) + *addrs = addr_list; + else if (addr_list != NULL) + free_wordlist(addr_list); + + return best_flag; } + +/* + * wordlist_count - return the number of items in a wordlist + */ +static int +wordlist_count(wp) + struct wordlist *wp; +{ + int n; + + for (n = 0; wp != NULL; wp = wp->next) + ++n; + return n; +} + /* * free_wordlist - release memory allocated for a wordlist. */ static void -free_wordlist(struct wordlist *wp) +free_wordlist(wp) + struct wordlist *wp; { - struct wordlist *next; + struct wordlist *next; - while (wp != NULL) { - next = wp->next; - free(wp); - wp = next; - } + while (wp != NULL) { + next = wp->next; + free(wp); + wp = next; + } } /* @@ -1280,22 +2320,23 @@ free_wordlist(struct wordlist *wp) * has finished. */ static void -auth_script_done(void *arg) +auth_script_done(arg) + void *arg; { auth_script_pid = 0; switch (auth_script_state) { case s_up: - if (auth_state == s_down) { - auth_script_state = s_down; - auth_script(_PATH_AUTHDOWN); - } - break; + if (auth_state == s_down) { + auth_script_state = s_down; + auth_script(_PATH_AUTHDOWN); + } + break; case s_down: - if (auth_state == s_up) { - auth_script_state = s_up; - auth_script(_PATH_AUTHUP); - } - break; + if (auth_state == s_up) { + auth_script_state = s_up; + auth_script(_PATH_AUTHUP); + } + break; } } @@ -1304,7 +2345,8 @@ auth_script_done(void *arg) * interface-name peer-name real-user tty speed */ static void -auth_script(char *script) +auth_script(script) + char *script; { char strspeed[32]; struct passwd *pw; @@ -1313,10 +2355,10 @@ auth_script(char *script) char *argv[8]; if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) - user_name = pw->pw_name; + user_name = pw->pw_name; else { - slprintf(struid, sizeof(struid), "%d", getuid()); - user_name = struid; + slprintf(struid, sizeof(struid), "%d", getuid()); + user_name = struid; } slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); @@ -1328,7 +2370,5 @@ auth_script(char *script) argv[5] = strspeed; argv[6] = NULL; - auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL); + auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0); } -#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ -#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/auth.h b/src/netif/ppp/auth.h deleted file mode 100644 index a8069ec4..00000000 --- a/src/netif/ppp/auth.h +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************** -* auth.h - PPP Authentication and phase control header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-04 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD pppd.h. -*****************************************************************************/ -/* - * 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. - * - */ - -#ifndef AUTH_H -#define AUTH_H - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ - -/* we are starting to use the link */ -void link_required (int); - -/* we are finished with the link */ -void link_terminated (int); - -/* the LCP layer has left the Opened state */ -void link_down (int); - -/* the link is up; authenticate now */ -void link_established (int); - -/* a network protocol has come up */ -void np_up (int, u16_t); - -/* a network protocol has gone down */ -void np_down (int, u16_t); - -/* a network protocol no longer needs link */ -void np_finished (int, u16_t); - -/* peer failed to authenticate itself */ -void auth_peer_fail (int, u16_t); - -/* peer successfully authenticated itself */ -void auth_peer_success (int, u16_t, char *, int); - -/* we failed to authenticate ourselves */ -void auth_withpeer_fail (int, u16_t); - -/* we successfully authenticated ourselves */ -void auth_withpeer_success (int, u16_t); - -/* check authentication options supplied */ -void auth_check_options (void); - -/* check what secrets we have */ -void auth_reset (int); - -/* Check peer-supplied username/password */ -u_char check_passwd (int, char *, int, char *, int, char **, int *); - -/* get "secret" for chap */ -int get_secret (int, char *, char *, char *, int *, int); - -/* check if IP address is authorized */ -int auth_ip_addr (int, u32_t); - -/* check if IP address is unreasonable */ -int bad_ip_adrs (u32_t); - -#endif /* AUTH_H */ diff --git a/src/netif/ppp/cbcp.h b/src/netif/ppp/cbcp.h new file mode 100644 index 00000000..c2ab3f68 --- /dev/null +++ b/src/netif/ppp/cbcp.h @@ -0,0 +1,26 @@ +#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/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c new file mode 100644 index 00000000..df07a387 --- /dev/null +++ b/src/netif/ppp/ccp.c @@ -0,0 +1,1680 @@ +/* + * ccp.c - PPP Compression Control Protocol. + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $" + +#include +#include + +#include "pppd.h" +#include "fsm.h" +#include "ccp.h" +#include + +#ifdef MPPE +#include "chap_ms.h" /* mppe_xxxx_key, mppe_keys_set */ +#include "lcp.h" /* lcp_close(), lcp_fsm */ +#endif + +static const char rcsid[] = RCSID; + +/* + * Unfortunately there is a bug in zlib which means that using a + * size of 8 (window size = 256) for Deflate compression will cause + * buffer overruns and kernel crashes in the deflate module. + * Until this is fixed we only accept sizes in the range 9 .. 15. + * Thanks to James Carlson for pointing this out. + */ +#define DEFLATE_MIN_WORKS 9 + +/* + * Command-line options. + */ +static int setbsdcomp __P((char **)); +static int setdeflate __P((char **)); +static char bsd_value[8]; +static char deflate_value[8]; + +/* + * Option variables. + */ +#ifdef MPPE +bool refuse_mppe_stateful = 1; /* Allow stateful mode? */ +#endif + +static option_t ccp_option_list[] = { + { "noccp", o_bool, &ccp_protent.enabled_flag, + "Disable CCP negotiation" }, + { "-ccp", o_bool, &ccp_protent.enabled_flag, + "Disable CCP negotiation", OPT_ALIAS }, + + { "bsdcomp", o_special, (void *)setbsdcomp, + "Request BSD-Compress packet compression", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, + { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, + "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].bsd_compress }, + { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, + "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].bsd_compress }, + + { "deflate", o_special, (void *)setdeflate, + "request Deflate compression", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, + { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, + "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].deflate }, + { "-deflate", o_bool, &ccp_wantoptions[0].deflate, + "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].deflate }, + + { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, + "don't use draft deflate #", OPT_A2COPY, + &ccp_allowoptions[0].deflate_draft }, + + { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "request Predictor-1", OPT_PRIO | 1 }, + { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].predictor_1 }, + { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].predictor_1 }, + +#ifdef MPPE + /* MPPE options are symmetrical ... we only set wantoptions here */ + { "require-mppe", o_bool, &ccp_wantoptions[0].mppe, + "require MPPE encryption", + OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, + { "+mppe", o_bool, &ccp_wantoptions[0].mppe, + "require MPPE encryption", + OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, + { "nomppe", o_bool, &ccp_wantoptions[0].mppe, + "don't allow MPPE encryption", OPT_PRIO }, + { "-mppe", o_bool, &ccp_wantoptions[0].mppe, + "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO }, + + /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */ + { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 40-bit encryption", + OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, + { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 40-bit encryption", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + + { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 128-bit encryption", + OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 128-bit encryption", + OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, + { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 128-bit encryption", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + + /* strange one; we always request stateless, but will we allow stateful? */ + { "mppe-stateful", o_bool, &refuse_mppe_stateful, + "allow MPPE stateful mode", OPT_PRIO }, + { "nomppe-stateful", o_bool, &refuse_mppe_stateful, + "disallow MPPE stateful mode", OPT_PRIO | 1 }, +#endif /* MPPE */ + + { NULL } +}; + +/* + * Protocol entry points from main code. + */ +static void ccp_init __P((int unit)); +static void ccp_open __P((int unit)); +static void ccp_close __P((int unit, char *)); +static void ccp_lowerup __P((int unit)); +static void ccp_lowerdown __P((int)); +static void ccp_input __P((int unit, u_char *pkt, int len)); +static void ccp_protrej __P((int unit)); +static int ccp_printpkt __P((u_char *pkt, int len, + void (*printer) __P((void *, char *, ...)), + void *arg)); +static void ccp_datainput __P((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 __P((fsm *)); +static int ccp_cilen __P((fsm *)); +static void ccp_addci __P((fsm *, u_char *, int *)); +static int ccp_ackci __P((fsm *, u_char *, int)); +static int ccp_nakci __P((fsm *, u_char *, int, int)); +static int ccp_rejci __P((fsm *, u_char *, int)); +static int ccp_reqci __P((fsm *, u_char *, int *, int)); +static void ccp_up __P((fsm *)); +static void ccp_down __P((fsm *)); +static int ccp_extcode __P((fsm *, int, int, u_char *, int)); +static void ccp_rack_timeout __P((void *)); +static char *method_name __P((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 \ + || (opt).mppe) + +/* + * 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(argv) + 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; + slprintf(bsd_value, sizeof(bsd_value), + rbits == abits? "%d": "%d,%d", rbits, abits); + + return 1; +} + +static int +setdeflate(argv) + 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 == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { + if (rbits == DEFLATE_MIN_SIZE) + rbits = DEFLATE_MIN_WORKS; + if (abits == DEFLATE_MIN_SIZE) + abits = DEFLATE_MIN_WORKS; + warn("deflate option value of %d changed to %d to avoid zlib bug", + DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); + } + 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; + slprintf(deflate_value, sizeof(deflate_value), + rbits == abits? "%d": "%d,%d", rbits, abits); + + return 1; +} + +/* + * ccp_init - initialize CCP. + */ +static void +ccp_init(unit) + 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(unit) + 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(unit, reason) + 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(unit) + int unit; +{ + fsm_lowerup(&ccp_fsm[unit]); +} + +/* + * ccp_lowerdown - we may not transmit CCP packets. + */ +static void +ccp_lowerdown(unit) + int unit; +{ + fsm_lowerdown(&ccp_fsm[unit]); +} + +/* + * ccp_input - process a received CCP packet. + */ +static void +ccp_input(unit, p, len) + 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."); +#ifdef MPPE + if (ccp_gotoptions[unit].mppe) { + error("MPPE disabled, closing LCP"); + lcp_close(unit, "MPPE disabled by peer"); + } +#endif + } + + /* + * 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(f, code, id, p, len) + fsm *f; + int code, 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(unit) + int unit; +{ + ccp_flags_set(unit, 0, 0); + fsm_lowerdown(&ccp_fsm[unit]); + +#ifdef MPPE + if (ccp_gotoptions[unit].mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(unit, "MPPE required but peer negotiation failed"); + } +#endif + +} + +/* + * ccp_resetci - initialize at start of negotiation. + */ +static void +ccp_resetci(f) + fsm *f; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + u_char opt_buf[CCP_MAX_OPTION_LENGTH]; + + *go = ccp_wantoptions[f->unit]; + all_rejected[f->unit] = 0; + +#ifdef MPPE + if (go->mppe) { + ccp_options *ao = &ccp_allowoptions[f->unit]; + int auth_mschap_bits = auth_done[f->unit]; + int numbits; + + /* + * Start with a basic sanity check: mschap[v2] auth must be in + * exactly one direction. RFC 3079 says that the keys are + * 'derived from the credentials of the peer that initiated the call', + * however the PPP protocol doesn't have such a concept, and pppd + * cannot get this info externally. Instead we do the best we can. + * NB: If MPPE is required, all other compression opts are invalid. + * So, we return right away if we can't do it. + */ + + /* Leave only the mschap auth bits set */ + auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER | + CHAP_MS2_WITHPEER | CHAP_MS2_PEER); + /* Count the mschap auths */ + auth_mschap_bits >>= CHAP_MS_SHIFT; + numbits = 0; + do { + numbits += auth_mschap_bits & 1; + auth_mschap_bits >>= 1; + } while (auth_mschap_bits); + if (numbits > 1) { + error("MPPE required, but auth done in both directions."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + if (!numbits) { + error("MPPE required, but MS-CHAP[v2] auth not performed."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* A plugin (eg radius) may not have obtained key material. */ + if (!mppe_keys_set) { + error("MPPE required, but keys are not available. " + "Possible plugin problem?"); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* LM auth not supported for MPPE */ + if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) { + /* This might be noise */ + if (go->mppe & MPPE_OPT_40) { + notice("Disabling 40-bit MPPE; MS-CHAP LM not supported"); + go->mppe &= ~MPPE_OPT_40; + ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40; + } + } + + /* Last check: can we actually negotiate something? */ + if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) { + /* Could be misconfig, could be 40-bit disabled above. */ + error("MPPE required, but both 40-bit and 128-bit disabled."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* sync options */ + ao->mppe = go->mppe; + /* MPPE is not compatible with other compression types */ + ao->bsd_compress = go->bsd_compress = 0; + ao->predictor_1 = go->predictor_1 = 0; + ao->predictor_2 = go->predictor_2 = 0; + ao->deflate = go->deflate = 0; + } +#endif /* MPPE */ + + /* + * Check whether the kernel knows about the various + * compression methods we might request. + */ +#ifdef MPPE + if (go->mppe) { + opt_buf[0] = CI_MPPE; + opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + /* Key material unimportant here. */ + if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) { + error("MPPE required, but kernel has no support."); + lcp_close(f->unit, "MPPE required but not available"); + } + } +#endif + 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_WORKS); + 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_WORKS); + 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(f) + 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) + + (go->mppe? CILEN_MPPE: 0); +} + +/* + * ccp_addci - put our requests in a packet. + */ +static void +ccp_addci(f, p, lenp) + 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. + */ +#ifdef MPPE + if (go->mppe) { + u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; + + p[0] = opt_buf[0] = CI_MPPE; + p[1] = opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &p[2]); + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN); + res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0); + if (res > 0) + p += CILEN_MPPE; + else + /* This shouldn't happen, we've already tested it! */ + lcp_close(f->unit, "MPPE required but not available in kernel"); + } +#endif + 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; + if (p != p0) { + p += CILEN_DEFLATE; + } else { + for (;;) { + if (go->deflate_size < DEFLATE_MIN_WORKS) { + go->deflate = 0; + break; + } + res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); + if (res > 0) { + p += CILEN_DEFLATE; + break; + } else if (res < 0) { + 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 (;;) { + if (go->bsd_bits < BSD_MIN_BITS) { + go->bsd_compress = 0; + break; + } + res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); + if (res > 0) { + p += CILEN_BSD_COMPRESS; + break; + } else if (res < 0) { + 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(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + u_char *p0 = p; + +#ifdef MPPE + if (go->mppe) { + u_char opt_buf[CILEN_MPPE]; + + opt_buf[0] = CI_MPPE; + opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE)) + return 0; + p += CILEN_MPPE; + len -= CILEN_MPPE; + /* XXX Cope with first/fast ack */ + if (len == 0) + return 1; + } +#endif + 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(f, p, len, treat_as_reject) + fsm *f; + u_char *p; + int len; + int treat_as_reject; +{ + 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; + +#ifdef MPPE + if (go->mppe && len >= CILEN_MPPE + && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { + no.mppe = 1; + /* + * Peer wants us to use a different strength or other setting. + * Fail if we aren't willing to use his suggestion. + */ + MPPE_CI_TO_OPTS(&p[2], try.mppe); + if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) { + error("Refusing MPPE stateful mode offered by peer"); + try.mppe = 0; + } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) { + /* Peer must have set options we didn't request (suggest) */ + try.mppe = 0; + } + + if (!try.mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(f->unit, "MPPE required but peer negotiation failed"); + } + } +#endif /* MPPE */ + 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_WORKS + || 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(f, p, len) + 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; + +#ifdef MPPE + if (go->mppe && len >= CILEN_MPPE + && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { + error("MPPE required but peer refused"); + lcp_close(f->unit, "MPPE required but peer refused"); + p += CILEN_MPPE; + len -= CILEN_MPPE; + } +#endif + if (go->deflate_correct && len >= CILEN_DEFLATE + && p[0] == CI_DEFLATE && 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_correct = 0; + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + } + if (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(f, p, lenp, dont_nak) + 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]; +#ifdef MPPE + bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */ + /* CI_MPPE, or due to other options? */ +#endif + + 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) { +#ifdef MPPE + case CI_MPPE: + if (!ao->mppe || clen != CILEN_MPPE) { + newret = CONFREJ; + break; + } + MPPE_CI_TO_OPTS(&p[2], ho->mppe); + + /* Nak if anything unsupported or unknown are set. */ + if (ho->mppe & MPPE_OPT_UNSUPPORTED) { + newret = CONFNAK; + ho->mppe &= ~MPPE_OPT_UNSUPPORTED; + } + if (ho->mppe & MPPE_OPT_UNKNOWN) { + newret = CONFNAK; + ho->mppe &= ~MPPE_OPT_UNKNOWN; + } + + /* Check state opt */ + if (ho->mppe & MPPE_OPT_STATEFUL) { + /* + * We can Nak and request stateless, but it's a + * lot easier to just assume the peer will request + * it if he can do it; stateful mode is bad over + * the Internet -- which is where we expect MPPE. + */ + if (refuse_mppe_stateful) { + error("Refusing MPPE stateful mode offered by peer"); + newret = CONFREJ; + break; + } + } + + /* Find out which of {S,L} are set. */ + if ((ho->mppe & MPPE_OPT_128) + && (ho->mppe & MPPE_OPT_40)) { + /* Both are set, negotiate the strongest. */ + newret = CONFNAK; + if (ao->mppe & MPPE_OPT_128) + ho->mppe &= ~MPPE_OPT_40; + else if (ao->mppe & MPPE_OPT_40) + ho->mppe &= ~MPPE_OPT_128; + else { + newret = CONFREJ; + break; + } + } else if (ho->mppe & MPPE_OPT_128) { + if (!(ao->mppe & MPPE_OPT_128)) { + newret = CONFREJ; + break; + } + } else if (ho->mppe & MPPE_OPT_40) { + if (!(ao->mppe & MPPE_OPT_40)) { + newret = CONFREJ; + break; + } + } else { + /* Neither are set. */ + /* We cannot accept this. */ + newret = CONFNAK; + /* Give the peer our idea of what can be used, + so it can choose and confirm */ + ho->mppe = ao->mppe; + } + + /* rebuild the opts */ + MPPE_OPTS_TO_CI(ho->mppe, &p[2]); + if (newret == CONFACK) { + u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; + int mtu; + + BCOPY(p, opt_buf, CILEN_MPPE); + BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE], + MPPE_MAX_KEY_LEN); + if (ccp_test(f->unit, opt_buf, + CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) { + /* This shouldn't happen, we've already tested it! */ + error("MPPE required, but kernel has no support."); + lcp_close(f->unit, "MPPE required but not available"); + newret = CONFREJ; + break; + } + /* + * We need to decrease the interface MTU by MPPE_PAD + * because MPPE frames **grow**. The kernel [must] + * allocate MPPE_PAD extra bytes in xmit buffers. + */ + mtu = netif_get_mtu(f->unit); + if (mtu) + netif_set_mtu(f->unit, mtu - MPPE_PAD); + else + newret = CONFREJ; + } + + /* + * We have accepted MPPE or are willing to negotiate + * MPPE parameters. A CONFREJ is due to subsequent + * (non-MPPE) processing. + */ + rej_for_ci_mppe = 0; + break; +#endif /* MPPE */ + 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_WORKS) { + 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_WORKS || 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; + } +#ifdef MPPE + if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(f->unit, "MPPE required but peer negotiation failed"); + } +#endif + return ret; +} + +/* + * Make a string name for a compression method (or 2). + */ +static char * +method_name(opt, opt2) + ccp_options *opt, *opt2; +{ + static char result[64]; + + if (!ANY_COMPRESS(*opt)) + return "(none)"; + switch (opt->method) { +#ifdef MPPE + case CI_MPPE: + { + char *p = result; + char *q = result + sizeof(result); /* 1 past result */ + + slprintf(p, q - p, "MPPE "); + p += 5; + if (opt->mppe & MPPE_OPT_128) { + slprintf(p, q - p, "128-bit "); + p += 8; + } + if (opt->mppe & MPPE_OPT_40) { + slprintf(p, q - p, "40-bit "); + p += 7; + } + if (opt->mppe & MPPE_OPT_STATEFUL) + slprintf(p, q - p, "stateful"); + else + slprintf(p, q - p, "stateless"); + + break; + } +#endif + 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(f) + 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)); +#ifdef MPPE + if (go->mppe) { + BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN); + BZERO(mppe_send_key, MPPE_MAX_KEY_LEN); + continue_networks(f->unit); /* Bring up IP et al */ + } +#endif +} + +/* + * CCP has gone down - inform the kernel driver. + */ +static void +ccp_down(f) + 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); +#ifdef MPPE + if (ccp_gotoptions[f->unit].mppe) { + ccp_gotoptions[f->unit].mppe = 0; + if (lcp_fsm[f->unit].state == OPENED) { + /* If LCP is not already going down, make sure it does. */ + error("MPPE disabled"); + lcp_close(f->unit, "MPPE disabled"); + } + } +#endif +} + +/* + * 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(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((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) { +#ifdef MPPE + case CI_MPPE: + if (optlen >= CILEN_MPPE) { + u_char mppe_opts; + + MPPE_CI_TO_OPTS(&p[2], mppe_opts); + printer(arg, "mppe %s %s %s %s %s %s%s", + (p[2] & MPPE_H_BIT)? "+H": "-H", + (p[5] & MPPE_M_BIT)? "+M": "-M", + (p[5] & MPPE_S_BIT)? "+S": "-S", + (p[5] & MPPE_L_BIT)? "+L": "-L", + (p[5] & MPPE_D_BIT)? "+D": "-D", + (p[5] & MPPE_C_BIT)? "+C": "-C", + (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": ""); + if (mppe_opts & MPPE_OPT_UNKNOWN) + printer(arg, " (%.2x %.2x %.2x %.2x)", + p[2], p[3], p[4], p[5]); + p += CILEN_MPPE; + } + break; +#endif + 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((char *)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(unit, pkt, len) + 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"); +#ifdef MPPE + /* + * If we were doing MPPE, we must also take the link down. + */ + if (ccp_gotoptions[unit].mppe) { + error("Too many MPPE errors, closing LCP"); + lcp_close(unit, "Too many MPPE errors"); + } +#endif + } 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(arg) + 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/src/netif/ppp/ccp.h b/src/netif/ppp/ccp.h new file mode 100644 index 00000000..6f4a2fee --- /dev/null +++ b/src/netif/ppp/ccp.h @@ -0,0 +1,52 @@ +/* + * ccp.h - Definitions for PPP Compression Control Protocol. + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $ + */ + +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? */ + bool mppe; /* do MPPE? */ + 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/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c new file mode 100644 index 00000000..513fe430 --- /dev/null +++ b/src/netif/ppp/chap-md5.c @@ -0,0 +1,119 @@ +/* + * chap-md5.c - New CHAP/MD5 implementation. + * + * Copyright (c) 2003 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: chap-md5.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" + +#include +#include +#include "pppd.h" +#include "chap-new.h" +#include "chap-md5.h" +#include "magic.h" +#include "md5.h" + +#define MD5_HASH_SIZE 16 +#define MD5_MIN_CHALLENGE 16 +#define MD5_MAX_CHALLENGE 24 + +static void +chap_md5_generate_challenge(unsigned char *cp) +{ + int clen; + + clen = (int)(drand48() * (MD5_MAX_CHALLENGE - MD5_MIN_CHALLENGE)) + + MD5_MIN_CHALLENGE; + *cp++ = clen; + random_bytes(cp, clen); +} + +static int +chap_md5_verify_response(int id, char *name, + unsigned char *secret, int secret_len, + unsigned char *challenge, unsigned char *response, + char *message, int message_space) +{ + MD5_CTX ctx; + unsigned char idbyte = id; + unsigned char hash[MD5_HASH_SIZE]; + int challenge_len, response_len; + + challenge_len = *challenge++; + response_len = *response++; + if (response_len == MD5_HASH_SIZE) { + /* Generate hash of ID, secret, challenge */ + MD5_Init(&ctx); + MD5_Update(&ctx, &idbyte, 1); + MD5_Update(&ctx, secret, secret_len); + MD5_Update(&ctx, challenge, challenge_len); + MD5_Final(hash, &ctx); + + /* Test if our hash matches the peer's response */ + if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { + slprintf(message, message_space, "Access granted"); + return 1; + } + } + slprintf(message, message_space, "Access denied"); + return 0; +} + +static void +chap_md5_make_response(unsigned char *response, int id, char *our_name, + unsigned char *challenge, char *secret, int secret_len, + unsigned char *private) +{ + MD5_CTX ctx; + unsigned char idbyte = id; + int challenge_len = *challenge++; + + MD5_Init(&ctx); + MD5_Update(&ctx, &idbyte, 1); + MD5_Update(&ctx, (u_char *)secret, secret_len); + MD5_Update(&ctx, challenge, challenge_len); + MD5_Final(&response[1], &ctx); + response[0] = MD5_HASH_SIZE; +} + +static struct chap_digest_type md5_digest = { + CHAP_MD5, /* code */ + chap_md5_generate_challenge, + chap_md5_verify_response, + chap_md5_make_response, + NULL, /* check_success */ + NULL, /* handle_failure */ +}; + +void +chap_md5_init(void) +{ + chap_register_digest(&md5_digest); +} diff --git a/src/netif/ppp/chap-md5.h b/src/netif/ppp/chap-md5.h new file mode 100644 index 00000000..30d06588 --- /dev/null +++ b/src/netif/ppp/chap-md5.h @@ -0,0 +1,31 @@ +/* + * chap-md5.h - New CHAP/MD5 implementation. + * + * Copyright (c) 2003 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +extern void chap_md5_init(void); diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c new file mode 100644 index 00000000..e2fb031b --- /dev/null +++ b/src/netif/ppp/chap-new.c @@ -0,0 +1,658 @@ +/* + * chap-new.c - New CHAP implementation. + * + * Copyright (c) 2003 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $" + +#include +#include +#include "pppd.h" +#include "session.h" +#include "chap-new.h" +#include "chap-md5.h" + +#ifdef CHAPMS +#include "chap_ms.h" +#define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) +#else +#define MDTYPE_ALL (MDTYPE_MD5) +#endif + +int chap_mdtype_all = MDTYPE_ALL; + +/* Hook for a plugin to validate CHAP challenge */ +int (*chap_verify_hook)(char *name, char *ourname, int id, + struct chap_digest_type *digest, + unsigned char *challenge, unsigned char *response, + char *message, int message_space) = NULL; + +/* + * Option variables. + */ +int chap_timeout_time = 3; +int chap_max_transmits = 10; +int chap_rechallenge_time = 0; + +/* + * Command-line options. + */ +static option_t chap_option_list[] = { + { "chap-restart", o_int, &chap_timeout_time, + "Set timeout for CHAP", OPT_PRIO }, + { "chap-max-challenge", o_int, &chap_max_transmits, + "Set max #xmits for challenge", OPT_PRIO }, + { "chap-interval", o_int, &chap_rechallenge_time, + "Set interval for rechallenge", OPT_PRIO }, + { NULL } +}; + +/* + * Internal state. + */ +static struct chap_client_state { + int flags; + char *name; + struct chap_digest_type *digest; + unsigned char priv[64]; /* private area for digest's use */ +} client; + +/* + * These limits apply to challenge and response packets we send. + * The +4 is the +1 that we actually need rounded up. + */ +#define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) +#define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) + +static struct chap_server_state { + int flags; + int id; + char *name; + struct chap_digest_type *digest; + int challenge_xmits; + int challenge_pktlen; + unsigned char challenge[CHAL_MAX_PKTLEN]; + char message[256]; +} server; + +/* Values for flags in chap_client_state and chap_server_state */ +#define LOWERUP 1 +#define AUTH_STARTED 2 +#define AUTH_DONE 4 +#define AUTH_FAILED 8 +#define TIMEOUT_PENDING 0x10 +#define CHALLENGE_VALID 0x20 + +/* + * Prototypes. + */ +static void chap_init(int unit); +static void chap_lowerup(int unit); +static void chap_lowerdown(int unit); +static void chap_timeout(void *arg); +static void chap_generate_challenge(struct chap_server_state *ss); +static void chap_handle_response(struct chap_server_state *ss, int code, + unsigned char *pkt, int len); +static int chap_verify_response(char *name, char *ourname, int id, + struct chap_digest_type *digest, + unsigned char *challenge, unsigned char *response, + char *message, int message_space); +static void chap_respond(struct chap_client_state *cs, int id, + unsigned char *pkt, int len); +static void chap_handle_status(struct chap_client_state *cs, int code, int id, + unsigned char *pkt, int len); +static void chap_protrej(int unit); +static void chap_input(int unit, unsigned char *pkt, int pktlen); +static int chap_print_pkt(unsigned char *p, int plen, + void (*printer) __P((void *, char *, ...)), void *arg); + +/* List of digest types that we know about */ +static struct chap_digest_type *chap_digests; + +/* + * chap_init - reset to initial state. + */ +static void +chap_init(int unit) +{ + memset(&client, 0, sizeof(client)); + memset(&server, 0, sizeof(server)); + + chap_md5_init(); +#ifdef CHAPMS + chapms_init(); +#endif +} + +/* + * Add a new digest type to the list. + */ +void +chap_register_digest(struct chap_digest_type *dp) +{ + dp->next = chap_digests; + chap_digests = dp; +} + +/* + * chap_lowerup - we can start doing stuff now. + */ +static void +chap_lowerup(int unit) +{ + struct chap_client_state *cs = &client; + struct chap_server_state *ss = &server; + + cs->flags |= LOWERUP; + ss->flags |= LOWERUP; + if (ss->flags & AUTH_STARTED) + chap_timeout(ss); +} + +static void +chap_lowerdown(int unit) +{ + struct chap_client_state *cs = &client; + struct chap_server_state *ss = &server; + + cs->flags = 0; + if (ss->flags & TIMEOUT_PENDING) + UNTIMEOUT(chap_timeout, ss); + ss->flags = 0; +} + +/* + * chap_auth_peer - Start authenticating the peer. + * If the lower layer is already up, we start sending challenges, + * otherwise we wait for the lower layer to come up. + */ +void +chap_auth_peer(int unit, char *our_name, int digest_code) +{ + struct chap_server_state *ss = &server; + struct chap_digest_type *dp; + + if (ss->flags & AUTH_STARTED) { + error("CHAP: peer authentication already started!"); + return; + } + for (dp = chap_digests; dp != NULL; dp = dp->next) + if (dp->code == digest_code) + break; + if (dp == NULL) + fatal("CHAP digest 0x%x requested but not available", + digest_code); + + ss->digest = dp; + ss->name = our_name; + /* Start with a random ID value */ + ss->id = (unsigned char)(drand48() * 256); + ss->flags |= AUTH_STARTED; + if (ss->flags & LOWERUP) + chap_timeout(ss); +} + +/* + * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. + * There isn't much to do until we receive a challenge. + */ +void +chap_auth_with_peer(int unit, char *our_name, int digest_code) +{ + struct chap_client_state *cs = &client; + struct chap_digest_type *dp; + + if (cs->flags & AUTH_STARTED) { + error("CHAP: authentication with peer already started!"); + return; + } + for (dp = chap_digests; dp != NULL; dp = dp->next) + if (dp->code == digest_code) + break; + if (dp == NULL) + fatal("CHAP digest 0x%x requested but not available", + digest_code); + + cs->digest = dp; + cs->name = our_name; + cs->flags |= AUTH_STARTED; +} + +/* + * chap_timeout - It's time to send another challenge to the peer. + * This could be either a retransmission of a previous challenge, + * or a new challenge to start re-authentication. + */ +static void +chap_timeout(void *arg) +{ + struct chap_server_state *ss = arg; + + ss->flags &= ~TIMEOUT_PENDING; + if ((ss->flags & CHALLENGE_VALID) == 0) { + ss->challenge_xmits = 0; + chap_generate_challenge(ss); + ss->flags |= CHALLENGE_VALID; + } else if (ss->challenge_xmits >= chap_max_transmits) { + ss->flags &= ~CHALLENGE_VALID; + ss->flags |= AUTH_DONE | AUTH_FAILED; + auth_peer_fail(0, PPP_CHAP); + return; + } + + output(0, ss->challenge, ss->challenge_pktlen); + ++ss->challenge_xmits; + ss->flags |= TIMEOUT_PENDING; + TIMEOUT(chap_timeout, arg, chap_timeout_time); +} + +/* + * chap_generate_challenge - generate a challenge string and format + * the challenge packet in ss->challenge_pkt. + */ +static void +chap_generate_challenge(struct chap_server_state *ss) +{ + int clen = 1, nlen, len; + unsigned char *p; + + p = ss->challenge; + MAKEHEADER(p, PPP_CHAP); + p += CHAP_HDRLEN; + ss->digest->generate_challenge(p); + clen = *p; + nlen = strlen(ss->name); + memcpy(p + 1 + clen, ss->name, nlen); + + len = CHAP_HDRLEN + 1 + clen + nlen; + ss->challenge_pktlen = PPP_HDRLEN + len; + + p = ss->challenge + PPP_HDRLEN; + p[0] = CHAP_CHALLENGE; + p[1] = ++ss->id; + p[2] = len >> 8; + p[3] = len; +} + +/* + * chap_handle_response - check the response to our challenge. + */ +static void +chap_handle_response(struct chap_server_state *ss, int id, + unsigned char *pkt, int len) +{ + int response_len, ok, mlen; + unsigned char *response, *p; + char *name = NULL; /* initialized to shut gcc up */ + int (*verifier)(char *, char *, int, struct chap_digest_type *, + unsigned char *, unsigned char *, char *, int); + char rname[MAXNAMELEN+1]; + + if ((ss->flags & LOWERUP) == 0) + return; + if (id != ss->challenge[PPP_HDRLEN+1] || len < 2) + return; + if (ss->flags & CHALLENGE_VALID) { + response = pkt; + GETCHAR(response_len, pkt); + len -= response_len + 1; /* length of name */ + name = (char *)pkt + response_len; + if (len < 0) + return; + + if (ss->flags & TIMEOUT_PENDING) { + ss->flags &= ~TIMEOUT_PENDING; + UNTIMEOUT(chap_timeout, ss); + } + + if (explicit_remote) { + name = remote_name; + } else { + /* Null terminate and clean remote name. */ + slprintf(rname, sizeof(rname), "%.*v", len, name); + name = rname; + } + + if (chap_verify_hook) + verifier = chap_verify_hook; + else + verifier = chap_verify_response; + ok = (*verifier)(name, ss->name, id, ss->digest, + ss->challenge + PPP_HDRLEN + CHAP_HDRLEN, + response, ss->message, sizeof(ss->message)); + if (!ok || !auth_number()) { + ss->flags |= AUTH_FAILED; + warn("Peer %q failed CHAP authentication", name); + } + } else if ((ss->flags & AUTH_DONE) == 0) + return; + + /* send the response */ + p = outpacket_buf; + MAKEHEADER(p, PPP_CHAP); + mlen = strlen(ss->message); + len = CHAP_HDRLEN + mlen; + p[0] = (ss->flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; + p[1] = id; + p[2] = len >> 8; + p[3] = len; + if (mlen > 0) + memcpy(p + CHAP_HDRLEN, ss->message, mlen); + output(0, outpacket_buf, PPP_HDRLEN + len); + + if (ss->flags & CHALLENGE_VALID) { + ss->flags &= ~CHALLENGE_VALID; + if (!(ss->flags & AUTH_DONE) && !(ss->flags & AUTH_FAILED)) { + /* + * Auth is OK, so now we need to check session restrictions + * to ensure everything is OK, but only if we used a + * plugin, and only if we're configured to check. This + * allows us to do PAM checks on PPP servers that + * authenticate against ActiveDirectory, and use AD for + * account info (like when using Winbind integrated with + * PAM). + */ + if (session_mgmt && + session_check(name, NULL, devnam, NULL) == 0) { + ss->flags |= AUTH_FAILED; + warn("Peer %q failed CHAP Session verification", name); + } + } + if (ss->flags & AUTH_FAILED) { + auth_peer_fail(0, PPP_CHAP); + } else { + if ((ss->flags & AUTH_DONE) == 0) + auth_peer_success(0, PPP_CHAP, + ss->digest->code, + name, strlen(name)); + if (chap_rechallenge_time) { + ss->flags |= TIMEOUT_PENDING; + TIMEOUT(chap_timeout, ss, + chap_rechallenge_time); + } + } + ss->flags |= AUTH_DONE; + } +} + +/* + * chap_verify_response - check whether the peer's response matches + * what we think it should be. Returns 1 if it does (authentication + * succeeded), or 0 if it doesn't. + */ +static int +chap_verify_response(char *name, char *ourname, int id, + struct chap_digest_type *digest, + unsigned char *challenge, unsigned char *response, + char *message, int message_space) +{ + int ok; + unsigned char secret[MAXSECRETLEN]; + int secret_len; + + /* Get the secret that the peer is supposed to know */ + if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) { + error("No CHAP secret found for authenticating %q", name); + return 0; + } + + ok = digest->verify_response(id, name, secret, secret_len, challenge, + response, message, message_space); + memset(secret, 0, sizeof(secret)); + + return ok; +} + +/* + * chap_respond - Generate and send a response to a challenge. + */ +static void +chap_respond(struct chap_client_state *cs, int id, + unsigned char *pkt, int len) +{ + int clen, nlen; + int secret_len; + unsigned char *p; + unsigned char response[RESP_MAX_PKTLEN]; + char rname[MAXNAMELEN+1]; + char secret[MAXSECRETLEN+1]; + + if ((cs->flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) + return; /* not ready */ + if (len < 2 || len < pkt[0] + 1) + return; /* too short */ + clen = pkt[0]; + nlen = len - (clen + 1); + + /* Null terminate and clean remote name. */ + slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); + + /* Microsoft doesn't send their name back in the PPP packet */ + if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) + strlcpy(rname, remote_name, sizeof(rname)); + + /* get secret for authenticating ourselves with the specified host */ + if (!get_secret(0, cs->name, rname, 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", rname); + } + + p = response; + MAKEHEADER(p, PPP_CHAP); + p += CHAP_HDRLEN; + + cs->digest->make_response(p, id, cs->name, pkt, + secret, secret_len, cs->priv); + memset(secret, 0, secret_len); + + clen = *p; + nlen = strlen(cs->name); + memcpy(p + clen + 1, cs->name, nlen); + + p = response + PPP_HDRLEN; + len = CHAP_HDRLEN + clen + 1 + nlen; + p[0] = CHAP_RESPONSE; + p[1] = id; + p[2] = len >> 8; + p[3] = len; + + output(0, response, PPP_HDRLEN + len); +} + +static void +chap_handle_status(struct chap_client_state *cs, int code, int id, + unsigned char *pkt, int len) +{ + const char *msg = NULL; + + if ((cs->flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) + != (AUTH_STARTED|LOWERUP)) + return; + cs->flags |= AUTH_DONE; + + if (code == CHAP_SUCCESS) { + /* used for MS-CHAP v2 mutual auth, yuck */ + if (cs->digest->check_success != NULL) { + if (!(*cs->digest->check_success)(pkt, len, cs->priv)) + code = CHAP_FAILURE; + } else + msg = "CHAP authentication succeeded"; + } else { + if (cs->digest->handle_failure != NULL) + (*cs->digest->handle_failure)(pkt, len); + else + msg = "CHAP authentication failed"; + } + if (msg) { + if (len > 0) + info("%s: %.*v", msg, len, pkt); + else + info("%s", msg); + } + if (code == CHAP_SUCCESS) + auth_withpeer_success(0, PPP_CHAP, cs->digest->code); + else { + cs->flags |= AUTH_FAILED; + error("CHAP authentication failed"); + auth_withpeer_fail(0, PPP_CHAP); + } +} + +static void +chap_input(int unit, unsigned char *pkt, int pktlen) +{ + struct chap_client_state *cs = &client; + struct chap_server_state *ss = &server; + unsigned char code, id; + int len; + + if (pktlen < CHAP_HDRLEN) + return; + GETCHAR(code, pkt); + GETCHAR(id, pkt); + GETSHORT(len, pkt); + if (len < CHAP_HDRLEN || len > pktlen) + return; + len -= CHAP_HDRLEN; + + switch (code) { + case CHAP_CHALLENGE: + chap_respond(cs, id, pkt, len); + break; + case CHAP_RESPONSE: + chap_handle_response(ss, id, pkt, len); + break; + case CHAP_FAILURE: + case CHAP_SUCCESS: + chap_handle_status(cs, code, id, pkt, len); + break; + } +} + +static void +chap_protrej(int unit) +{ + struct chap_client_state *cs = &client; + struct chap_server_state *ss = &server; + + if (ss->flags & TIMEOUT_PENDING) { + ss->flags &= ~TIMEOUT_PENDING; + UNTIMEOUT(chap_timeout, ss); + } + if (ss->flags & AUTH_STARTED) { + ss->flags = 0; + auth_peer_fail(0, PPP_CHAP); + } + if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { + cs->flags &= ~AUTH_STARTED; + error("CHAP authentication failed due to protocol-reject"); + auth_withpeer_fail(0, PPP_CHAP); + } +} + +/* + * chap_print_pkt - print the contents of a CHAP packet. + */ +static char *chap_code_names[] = { + "Challenge", "Response", "Success", "Failure" +}; + +static int +chap_print_pkt(unsigned char *p, int plen, + void (*printer) __P((void *, char *, ...)), void *arg) +{ + int code, id, len; + int clen, nlen; + unsigned char x; + + if (plen < CHAP_HDRLEN) + return 0; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < CHAP_HDRLEN || len > plen) + return 0; + + if (code >= 1 && code <= sizeof(chap_code_names) / sizeof(char *)) + printer(arg, " %s", chap_code_names[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= CHAP_HDRLEN; + 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_HDRLEN; +} + +struct protent chap_protent = { + PPP_CHAP, + chap_init, + chap_input, + chap_protrej, + chap_lowerup, + chap_lowerdown, + NULL, /* open */ + NULL, /* close */ + chap_print_pkt, + NULL, /* datainput */ + 1, /* enabled_flag */ + "CHAP", /* name */ + NULL, /* data_name */ + chap_option_list, + NULL, /* check_options */ +}; diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h new file mode 100644 index 00000000..48235d40 --- /dev/null +++ b/src/netif/ppp/chap-new.h @@ -0,0 +1,130 @@ +/* + * chap-new.c - New CHAP implementation. + * + * Copyright (c) 2003 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * CHAP packets begin with a standard header with code, id, len (2 bytes). + */ +#define CHAP_HDRLEN 4 + +/* + * Values for the code field. + */ +#define CHAP_CHALLENGE 1 +#define CHAP_RESPONSE 2 +#define CHAP_SUCCESS 3 +#define CHAP_FAILURE 4 + +/* + * CHAP digest codes. + */ +#define CHAP_MD5 5 +#define CHAP_MICROSOFT 0x80 +#define CHAP_MICROSOFT_V2 0x81 + +/* + * Semi-arbitrary limits on challenge and response fields. + */ +#define MAX_CHALLENGE_LEN 64 +#define MAX_RESPONSE_LEN 64 + +/* bitmask of supported algorithms */ +#define MDTYPE_MICROSOFT_V2 0x1 +#define MDTYPE_MICROSOFT 0x2 +#define MDTYPE_MD5 0x4 +#define MDTYPE_NONE 0 + +/* hashes supported by this instance of pppd */ +extern int chap_mdtype_all; + +/* Return the digest alg. ID for the most preferred digest type. */ +#define CHAP_DIGEST(mdtype) \ + ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ + ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \ + ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \ + 0 + +/* Return the bit flag (lsb set) for our most preferred digest type. */ +#define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype) + +/* Return the bit flag for a given digest algorithm ID. */ +#define CHAP_MDTYPE_D(digest) \ + ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \ + ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \ + ((digest) == CHAP_MD5)? MDTYPE_MD5: \ + 0 + +/* Can we do the requested digest? */ +#define CHAP_CANDIGEST(mdtype, digest) \ + ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \ + ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \ + ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ + 0 + +/* + * The code for each digest type has to supply one of these. + */ +struct chap_digest_type { + int code; + + /* + * Note: challenge and response arguments below are formatted as + * a length byte followed by the actual challenge/response data. + */ + void (*generate_challenge)(unsigned char *challenge); + int (*verify_response)(int id, char *name, + unsigned char *secret, int secret_len, + unsigned char *challenge, unsigned char *response, + char *message, int message_space); + void (*make_response)(unsigned char *response, int id, char *our_name, + unsigned char *challenge, char *secret, int secret_len, + unsigned char *priv); + int (*check_success)(unsigned char *pkt, int len, unsigned char *priv); + void (*handle_failure)(unsigned char *pkt, int len); + + struct chap_digest_type *next; +}; + +/* Hook for a plugin to validate CHAP challenge */ +extern int (*chap_verify_hook)(char *name, char *ourname, int id, + struct chap_digest_type *digest, + unsigned char *challenge, unsigned char *response, + char *message, int message_space); + +/* Called by digest code to register a digest type */ +extern void chap_register_digest(struct chap_digest_type *); + +/* Called by authentication code to start authenticating the peer. */ +extern void chap_auth_peer(int unit, char *our_name, int digest_code); + +/* Called by auth. code to start authenticating us to the peer. */ +extern void chap_auth_with_peer(int unit, char *our_name, int digest_code); + +/* Represents the CHAP protocol to the main pppd code */ +extern struct protent chap_protent; diff --git a/src/netif/ppp/chap.c b/src/netif/ppp/chap.c deleted file mode 100644 index f10e27d2..00000000 --- a/src/netif/ppp/chap.c +++ /dev/null @@ -1,908 +0,0 @@ -/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/ -/***************************************************************************** -* chap.c - Network Challenge Handshake Authentication Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-04 Guy Lancaster , Global Election Systems Inc. -* Original based on BSD chap.c. -*****************************************************************************/ -/* - * 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. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "magic.h" -#include "randm.h" -#include "auth.h" -#include "md5.h" -#include "chap.h" -#include "chpms.h" - -#include - -#if 0 /* UNUSED */ -/* - * Command-line options. - */ -static option_t chap_option_list[] = { - { "chap-restart", o_int, &chap[0].timeouttime, - "Set timeout for CHAP" }, - { "chap-max-challenge", o_int, &chap[0].max_transmits, - "Set max #xmits for challenge" }, - { "chap-interval", o_int, &chap[0].chal_interval, - "Set interval for rechallenge" }, -#ifdef MSLANMAN - { "ms-lanman", o_bool, &ms_lanman, - "Use LanMan passwd when using MS-CHAP", 1 }, -#endif - { NULL } -}; -#endif /* UNUSED */ - -/* - * 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); -#if PPP_ADDITIONAL_CALLBACKS -static int ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *); -#endif - -struct protent chap_protent = { - PPP_CHAP, - ChapInit, - ChapInput, - ChapProtocolReject, - ChapLowerUp, - ChapLowerDown, - NULL, - NULL, -#if PPP_ADDITIONAL_CALLBACKS - ChapPrintPkt, - NULL, -#endif /* PPP_ADDITIONAL_CALLBACKS */ - 1, - "CHAP", -#if PPP_ADDITIONAL_CALLBACKS - NULL, - NULL, - NULL -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -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 *, u_char, int); -static void ChapRechallenge (void *); -static void ChapReceiveResponse (chap_state *, u_char *, int, int); -static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len); -static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len); -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, u_char 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, u_char 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 */ - CHAPDEBUG(LOG_ERR, ("Peer failed to respond to CHAP challenge\n")); - 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); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */ - } - 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(LOG_INFO, ("ChapInput: rcvd short header.\n")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < CHAP_HEADERLEN) { - CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd illegal length.\n")); - return; - } - if (len > packet_len) { - CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short packet.\n")); - 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? */ - CHAPDEBUG(LOG_WARNING, ("Unknown CHAP code (%d) received.\n", code)); - break; - } -} - - -/* - * ChapReceiveChallenge - Receive Challenge and send Response. - */ -static void -ChapReceiveChallenge(chap_state *cstate, u_char *inp, u_char id, int len) -{ - int rchallenge_len; - u_char *rchallenge; - int secret_len; - char secret[MAXSECRETLEN]; - char rhostname[256]; - MD5_CTX mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; - - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: Rcvd id %d.\n", id)); - if (cstate->clientstate == CHAPCS_CLOSED || - cstate->clientstate == CHAPCS_PENDING) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: in state %d\n", - cstate->clientstate)); - return; - } - - if (len < 2) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n")); - return; - } - - GETCHAR(rchallenge_len, inp); - len -= sizeof (u_char) + rchallenge_len; /* now name field length */ - if (len < 0) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n")); - return; - } - rchallenge = inp; - INCPTR(rchallenge_len, inp); - - if (len >= (int)sizeof(rhostname)) { - len = sizeof(rhostname) - 1; - } - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: received name field '%s'\n", - rhostname)); - - /* Microsoft doesn't send their name back in the PPP packet */ - if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) { - strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname)); - rhostname[sizeof(rhostname) - 1] = 0; - CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: using '%s' as remote name\n", - 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 */ - CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating us to %s\n", - 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, (u_char*)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; - -#if MSCHAP_SUPPORT - case CHAP_MICROSOFT: - ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); - break; -#endif - - default: - CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", 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; - char secret[MAXSECRETLEN]; - u_char hash[MD5_SIGNATURE_SIZE]; - - CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: Rcvd id %d.\n", id)); - - if (cstate->serverstate == CHAPSS_CLOSED || - cstate->serverstate == CHAPSS_PENDING) { - CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: in state %d\n", - 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(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n")); - 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(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n")); - return; - } - - UNTIMEOUT(ChapChallengeTimeout, cstate); - - if (len >= (int)sizeof(rhostname)) { - len = sizeof(rhostname) - 1; - } - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: received name field: %s\n", - rhostname)); - - /* - * Get secret for authenticating them with us, - * do the hash ourselves, and compare the result. - */ - code = CHAP_FAILURE; - if (!get_secret(cstate->unit, rhostname, cstate->chal_name, - secret, &secret_len, 1)) { - CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating %s\n", - 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, (u_char*)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(LOG_INFO, ("unknown digest type %d\n", 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); - } - } else { - CHAPDEBUG(LOG_ERR, ("CHAP peer authentication failed\n")); - 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) -{ - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(inp); - - CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: Rcvd id %d.\n", id)); - - 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(LOG_INFO, ("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) -{ - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(inp); - - CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: Rcvd id %d.\n", id)); - - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: in state %d\n", - cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) { - PRINTMSG(inp, len); - } - - CHAPDEBUG(LOG_ERR, ("CHAP authentication failed\n")); - auth_withpeer_fail(cstate->unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */ -} - - -/* - * 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 = (int)strlen(cstate->chal_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len; - outp = outpacket_buf[cstate->unit]; - - 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 */ - - pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); - - CHAPDEBUG(LOG_INFO, ("ChapSendChallenge: Sent id %d.\n", cstate->chal_id)); - - 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]; /* @todo: this can be a char*, no strcpy needed */ - - if (code == CHAP_SUCCESS) { - strcpy(msg, "Welcome!"); - } else { - strcpy(msg, "I don't like you. Go 'way."); - } - msglen = (int)strlen(msg); - - outlen = CHAP_HEADERLEN + msglen; - outp = outpacket_buf[cstate->unit]; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ - - PUTCHAR(code, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - BCOPY(msg, outp, msglen); - pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); - - CHAPDEBUG(LOG_INFO, ("ChapSendStatus: Sent code %d, id %d.\n", code, - cstate->chal_id)); -} - -/* - * 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) - ((((magic() >> 16) * - (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16) - + MIN_CHALLENGE_LENGTH); - LWIP_ASSERT("chal_len <= 0xff", chal_len <= 0xffff); - cstate->chal_len = (u_char)chal_len; - cstate->chal_id = ++cstate->id; - cstate->chal_transmits = 0; - - /* generate a random string */ - for (i = 0; i < chal_len; i++ ) { - *ptr++ = (char) (magic() & 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 = (int)strlen(cstate->resp_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len; - outp = outpacket_buf[cstate->unit]; - - 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 */ - pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); - - cstate->clientstate = CHAPCS_RESPONSE; - TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime); - ++cstate->resp_transmits; -} - -#if PPP_ADDITIONAL_CALLBACKS -static char *ChapCodenames[] = { - "Challenge", "Response", "Success", "Failure" -}; -/* - * ChapPrintPkt - print the contents of a CHAP packet. - */ -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 = %.*Z", nlen, p); - break; - case CHAP_FAILURE: - case CHAP_SUCCESS: - printer(arg, " %.*Z", len, p); - break; - default: - for (clen = len; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, " %.2x", x); - } - } - - return len + CHAP_HEADERLEN; -} -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -#endif /* CHAP_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/chap.h b/src/netif/ppp/chap.h deleted file mode 100644 index fedcab8d..00000000 --- a/src/netif/ppp/chap.h +++ /dev/null @@ -1,150 +0,0 @@ -/***************************************************************************** -* chap.h - Network Challenge Handshake Authentication Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-03 Guy Lancaster , Global Election Systems Inc. -* Original built from BSD network code. -******************************************************************************/ -/* - * 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: chap.h,v 1.6 2010/01/24 13:19:34 goldsimon Exp $ - */ - -#ifndef CHAP_H -#define CHAP_H - -/* 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 32 -#define MAX_CHALLENGE_LENGTH 64 -#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 */ - -extern chap_state chap[]; - -void ChapAuthWithPeer (int, char *, u_char); -void ChapAuthPeer (int, char *, u_char); - -extern struct protent chap_protent; - -#endif /* CHAP_H */ diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c new file mode 100644 index 00000000..0d3b5347 --- /dev/null +++ b/src/netif/ppp/chap_ms.c @@ -0,0 +1,943 @@ +/* + * chap_ms.c - Microsoft MS-CHAP compatible implementation. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * 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 + */ + +/* + * Modifications by Frank Cusack, frank@google.com, March 2002. + * + * Implemented MS-CHAPv2 functionality, heavily based on sample + * implementation in RFC 2759. Implemented MPPE functionality, + * heavily based on sample implementation in RFC 3079. + * + * Copyright (c) 2002 Google, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $" + +#ifdef CHAPMS + +#include +#include +#include +#include +#include +#include +#include + +#include "pppd.h" +#include "chap-new.h" +#include "chap_ms.h" +#include "md4.h" +#include "sha1.h" +#include "pppcrypt.h" +#include "magic.h" + +static const char rcsid[] = RCSID; + + +static void ascii2unicode __P((char[], int, u_char[])); +static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); +static void ChallengeResponse __P((u_char *, u_char *, u_char[24])); +static void ChapMS_NT __P((u_char *, char *, int, u_char[24])); +static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int, + u_char[24])); +static void GenerateAuthenticatorResponsePlain + __P((char*, int, u_char[24], u_char[16], u_char *, + char *, u_char[41])); +#ifdef MSLANMAN +static void ChapMS_LANMan __P((u_char *, char *, int, u_char *)); +#endif + +#ifdef MPPE +static void Set_Start_Key __P((u_char *, char *, int)); +static void SetMasterKeys __P((char *, int, u_char[24], int)); +#endif + +#ifdef MSLANMAN +bool ms_lanman = 0; /* Use LanMan password instead of NT */ + /* Has meaning only with MS-CHAP challenges */ +#endif + +#ifdef MPPE +u_char mppe_send_key[MPPE_MAX_KEY_LEN]; +u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; +int mppe_keys_set = 0; /* Have the MPPE keys been set? */ + +#ifdef DEBUGMPPEKEY +/* For MPPE debug */ +/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */ +static char *mschap_challenge = NULL; +/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */ +static char *mschap2_peer_challenge = NULL; +#endif + +#include "fsm.h" /* Need to poke MPPE options */ +#include "ccp.h" +#include +#endif + +/* + * Command-line options. + */ +static option_t chapms_option_list[] = { +#ifdef MSLANMAN + { "ms-lanman", o_bool, &ms_lanman, + "Use LanMan passwd when using MS-CHAP", 1 }, +#endif +#ifdef DEBUGMPPEKEY + { "mschap-challenge", o_string, &mschap_challenge, + "specify CHAP challenge" }, + { "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, + "specify CHAP peer challenge" }, +#endif + { NULL } +}; + +/* + * chapms_generate_challenge - generate a challenge for MS-CHAP. + * For MS-CHAP the challenge length is fixed at 8 bytes. + * The length goes in challenge[0] and the actual challenge starts + * at challenge[1]. + */ +static void +chapms_generate_challenge(unsigned char *challenge) +{ + *challenge++ = 8; +#ifdef DEBUGMPPEKEY + if (mschap_challenge && strlen(mschap_challenge) == 8) + memcpy(challenge, mschap_challenge, 8); + else +#endif + random_bytes(challenge, 8); +} + +static void +chapms2_generate_challenge(unsigned char *challenge) +{ + *challenge++ = 16; +#ifdef DEBUGMPPEKEY + if (mschap_challenge && strlen(mschap_challenge) == 16) + memcpy(challenge, mschap_challenge, 16); + else +#endif + random_bytes(challenge, 16); +} + +static int +chapms_verify_response(int id, char *name, + unsigned char *secret, int secret_len, + unsigned char *challenge, unsigned char *response, + char *message, int message_space) +{ + unsigned char md[MS_CHAP_RESPONSE_LEN]; + int diff; + int challenge_len, response_len; + + challenge_len = *challenge++; /* skip length, is 8 */ + response_len = *response++; + if (response_len != MS_CHAP_RESPONSE_LEN) + goto bad; + +#ifndef MSLANMAN + if (!response[MS_CHAP_USENT]) { + /* Should really propagate this into the error packet. */ + notice("Peer request for LANMAN auth not supported"); + goto bad; + } +#endif + + /* Generate the expected response. */ + ChapMS(challenge, (char *)secret, secret_len, md); + +#ifdef MSLANMAN + /* Determine which part of response to verify against */ + if (!response[MS_CHAP_USENT]) + diff = memcmp(&response[MS_CHAP_LANMANRESP], + &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN); + else +#endif + diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP], + MS_CHAP_NTRESP_LEN); + + if (diff == 0) { + slprintf(message, message_space, "Access granted"); + return 1; + } + + bad: + /* See comments below for MS-CHAP V2 */ + slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", + challenge_len, challenge); + return 0; +} + +static int +chapms2_verify_response(int id, char *name, + unsigned char *secret, int secret_len, + unsigned char *challenge, unsigned char *response, + char *message, int message_space) +{ + unsigned char md[MS_CHAP2_RESPONSE_LEN]; + char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; + int challenge_len, response_len; + + challenge_len = *challenge++; /* skip length, is 16 */ + response_len = *response++; + if (response_len != MS_CHAP2_RESPONSE_LEN) + goto bad; /* not even the right length */ + + /* Generate the expected response and our mutual auth. */ + ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name, + (char *)secret, secret_len, md, + (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); + + /* compare MDs and send the appropriate status */ + /* + * Per RFC 2759, success message must be formatted as + * "S= M=" + * where + * is the Authenticator Response (mutual auth) + * is a text message + * + * However, some versions of Windows (win98 tested) do not know + * about the M= part (required per RFC 2759) and flag + * it as an error (reported incorrectly as an encryption error + * to the user). Since the RFC requires it, and it can be + * useful information, we supply it if the peer is a conforming + * system. Luckily (?), win98 sets the Flags field to 0x04 + * (contrary to RFC requirements) so we can use that to + * distinguish between conforming and non-conforming systems. + * + * Special thanks to Alex Swiridov for + * help debugging this. + */ + if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], + MS_CHAP2_NTRESP_LEN) == 0) { + if (response[MS_CHAP2_FLAGS]) + slprintf(message, message_space, "S=%s", saresponse); + else + slprintf(message, message_space, "S=%s M=%s", + saresponse, "Access granted"); + return 1; + } + + bad: + /* + * Failure message must be formatted as + * "E=e R=r C=c V=v M=m" + * where + * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE) + * r = retry (we use 1, ok to retry) + * c = challenge to use for next response, we reuse previous + * v = Change Password version supported, we use 0 + * m = text message + * + * The M=m part is only for MS-CHAPv2. Neither win2k nor + * win98 (others untested) display the message to the user anyway. + * They also both ignore the E=e code. + * + * Note that it's safe to reuse the same challenge as we don't + * actually accept another response based on the error message + * (and no clients try to resend a response anyway). + * + * Basically, this whole bit is useless code, even the small + * implementation here is only because of overspecification. + */ + slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", + challenge_len, challenge, "Access denied"); + return 0; +} + +static void +chapms_make_response(unsigned char *response, int id, char *our_name, + unsigned char *challenge, char *secret, int secret_len, + unsigned char *private) +{ + challenge++; /* skip length, should be 8 */ + *response++ = MS_CHAP_RESPONSE_LEN; + ChapMS(challenge, secret, secret_len, response); +} + +static void +chapms2_make_response(unsigned char *response, int id, char *our_name, + unsigned char *challenge, char *secret, int secret_len, + unsigned char *private) +{ + challenge++; /* skip length, should be 16 */ + *response++ = MS_CHAP2_RESPONSE_LEN; + ChapMS2(challenge, +#ifdef DEBUGMPPEKEY + mschap2_peer_challenge, +#else + NULL, +#endif + our_name, secret, secret_len, response, private, + MS_CHAP2_AUTHENTICATEE); +} + +static int +chapms2_check_success(unsigned char *msg, int len, unsigned char *private) +{ + if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || + strncmp((char *)msg, "S=", 2) != 0) { + /* Packet does not start with "S=" */ + error("MS-CHAPv2 Success packet is badly formed."); + return 0; + } + msg += 2; + len -= 2; + if (len < MS_AUTH_RESPONSE_LENGTH + || memcmp(msg, private, MS_AUTH_RESPONSE_LENGTH)) { + /* Authenticator Response did not match expected. */ + error("MS-CHAPv2 mutual authentication failed."); + return 0; + } + /* Authenticator Response matches. */ + msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */ + len -= MS_AUTH_RESPONSE_LENGTH; + if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) { + msg += 3; /* Eat the delimiter */ + } else if (len) { + /* Packet has extra text which does not begin " M=" */ + error("MS-CHAPv2 Success packet is badly formed."); + return 0; + } + return 1; +} + +static void +chapms_handle_failure(unsigned char *inp, int len) +{ + int err; + char *p, *msg; + + /* We want a null-terminated string for strxxx(). */ + msg = malloc(len + 1); + if (!msg) { + notice("Out of memory in chapms_handle_failure"); + return; + } + BCOPY(inp, msg, len); + msg[len] = 0; + p = msg; + + /* + * Deal with MS-CHAP formatted failure messages; just print the + * M= part (if any). For MS-CHAP we're not really supposed + * to use M=, but it shouldn't hurt. See + * chapms[2]_verify_response. + */ + if (!strncmp(p, "E=", 2)) + err = strtol(p+2, NULL, 10); /* Remember the error code. */ + else + goto print_msg; /* Message is badly formatted. */ + + if (len && ((p = strstr(p, " M=")) != NULL)) { + /* M= field found. */ + p += 3; + } else { + /* No M=; use the error code. */ + switch (err) { + case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS: + p = "E=646 Restricted logon hours"; + break; + + case MS_CHAP_ERROR_ACCT_DISABLED: + p = "E=647 Account disabled"; + break; + + case MS_CHAP_ERROR_PASSWD_EXPIRED: + p = "E=648 Password expired"; + break; + + case MS_CHAP_ERROR_NO_DIALIN_PERMISSION: + p = "E=649 No dialin permission"; + break; + + case MS_CHAP_ERROR_AUTHENTICATION_FAILURE: + p = "E=691 Authentication failure"; + break; + + case MS_CHAP_ERROR_CHANGING_PASSWORD: + /* Should never see this, we don't support Change Password. */ + p = "E=709 Error changing password"; + break; + + default: + free(msg); + error("Unknown MS-CHAP authentication failure: %.*v", + len, inp); + return; + } + } +print_msg: + if (p != NULL) + error("MS-CHAP authentication failed: %v", p); + free(msg); +} + +static void +ChallengeResponse(u_char *challenge, + u_char PasswordHash[MD4_SIGNATURE_SIZE], + u_char response[24]) +{ + u_char ZPasswordHash[21]; + + BZERO(ZPasswordHash, sizeof(ZPasswordHash)); + BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE); + +#if 0 + dbglog("ChallengeResponse - ZPasswordHash %.*B", + sizeof(ZPasswordHash), ZPasswordHash); +#endif + + (void) DesSetkey(ZPasswordHash + 0); + DesEncrypt(challenge, response + 0); + (void) DesSetkey(ZPasswordHash + 7); + DesEncrypt(challenge, response + 8); + (void) DesSetkey(ZPasswordHash + 14); + DesEncrypt(challenge, response + 16); + +#if 0 + dbglog("ChallengeResponse - response %.24B", response); +#endif +} + +void +ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, + char *username, u_char Challenge[8]) + +{ + SHA1_CTX sha1Context; + u_char sha1Hash[SHA1_SIGNATURE_SIZE]; + char *user; + + /* remove domain from "domain\username" */ + if ((user = strrchr(username, '\\')) != NULL) + ++user; + else + user = username; + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PeerChallenge, 16); + SHA1_Update(&sha1Context, rchallenge, 16); + SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user)); + SHA1_Final(sha1Hash, &sha1Context); + + BCOPY(sha1Hash, Challenge, 8); +} + +/* + * Convert the ASCII version of the password to Unicode. + * This implicitly supports 8-bit ISO8859/1 characters. + * This gives us the little-endian representation, which + * is assumed by all M$ CHAP RFCs. (Unicode byte ordering + * is machine-dependent.) + */ +static void +ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) +{ + int i; + + BZERO(unicode, ascii_len * 2); + for (i = 0; i < ascii_len; i++) + unicode[i * 2] = (u_char) ascii[i]; +} + +static void +NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) +{ +#ifdef __NetBSD__ + /* NetBSD uses the libc md4 routines which take bytes instead of bits */ + int mdlen = secret_len; +#else + int mdlen = secret_len * 8; +#endif + MD4_CTX md4Context; + + MD4Init(&md4Context); + /* MD4Update can take at most 64 bytes at a time */ + while (mdlen > 512) { + MD4Update(&md4Context, secret, 512); + secret += 64; + mdlen -= 512; + } + MD4Update(&md4Context, secret, mdlen); + MD4Final(hash, &md4Context); + +} + +static void +ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, + u_char NTResponse[24]) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + + /* Hash the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + + ChallengeResponse(rchallenge, PasswordHash, NTResponse); +} + +static void +ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, + char *secret, int secret_len, u_char NTResponse[24]) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char Challenge[8]; + + ChallengeHash(PeerChallenge, rchallenge, username, Challenge); + + /* Hash the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + + ChallengeResponse(Challenge, PasswordHash, NTResponse); +} + +#ifdef MSLANMAN +static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ + +static void +ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, + unsigned char *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]); + (void) DesSetkey(UcasePassword + 0); + DesEncrypt( StdText, PasswordHash + 0 ); + (void) DesSetkey(UcasePassword + 7); + DesEncrypt( StdText, PasswordHash + 8 ); + ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); +} +#endif + + +void +GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) +{ + /* + * "Magic" constants used in response generation, from RFC 2759. + */ + u_char Magic1[39] = /* "Magic server to client signing constant" */ + { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; + u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ + { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, + 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E }; + + int i; + SHA1_CTX sha1Context; + u_char Digest[SHA1_SIGNATURE_SIZE]; + u_char Challenge[8]; + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, NTResponse, 24); + SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); + SHA1_Final(Digest, &sha1Context); + + ChallengeHash(PeerChallenge, rchallenge, username, Challenge); + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, Digest, sizeof(Digest)); + SHA1_Update(&sha1Context, Challenge, sizeof(Challenge)); + SHA1_Update(&sha1Context, Magic2, sizeof(Magic2)); + SHA1_Final(Digest, &sha1Context); + + /* Convert to ASCII hex string. */ + for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) + sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); +} + + +static void +GenerateAuthenticatorResponsePlain + (char *secret, int secret_len, + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), + PasswordHashHash); + + GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge, + rchallenge, username, authResponse); +} + + +#ifdef MPPE +/* + * Set mppe_xxxx_key from the NTPasswordHashHash. + * RFC 2548 (RADIUS support) requires us to export this function (ugh). + */ +void +mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) +{ + SHA1_CTX sha1Context; + u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, rchallenge, 8); + SHA1_Final(Digest, &sha1Context); + + /* Same key in both directions. */ + BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); + BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); + + mppe_keys_set = 1; +} + +/* + * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) + */ +static void +Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); + + mppe_set_keys(rchallenge, PasswordHashHash); +} + +/* + * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) + * + * This helper function used in the Winbind module, which gets the + * NTHashHash from the server. + */ +void +mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], int IsServer) +{ + SHA1_CTX sha1Context; + u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + + u_char SHApad1[40] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u_char SHApad2[40] = + { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 }; + + /* "This is the MPPE Master Key" */ + u_char Magic1[27] = + { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; + /* "On the client side, this is the send key; " + "on the server side, it is the receive key." */ + u_char Magic2[84] = + { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, + 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, + 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x2e }; + /* "On the client side, this is the receive key; " + "on the server side, it is the send key." */ + u_char Magic3[84] = + { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, + 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, + 0x6b, 0x65, 0x79, 0x2e }; + u_char *s; + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, NTResponse, 24); + SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); + SHA1_Final(MasterKey, &sha1Context); + + /* + * generate send key + */ + if (IsServer) + s = Magic3; + else + s = Magic2; + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, MasterKey, 16); + SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); + SHA1_Update(&sha1Context, s, 84); + SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); + SHA1_Final(Digest, &sha1Context); + + BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); + + /* + * generate recv key + */ + if (IsServer) + s = Magic2; + else + s = Magic3; + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, MasterKey, 16); + SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); + SHA1_Update(&sha1Context, s, 84); + SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); + SHA1_Final(Digest, &sha1Context); + + BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); + + mppe_keys_set = 1; +} + +/* + * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) + */ +static void +SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); + mppe_set_keys2(PasswordHashHash, NTResponse, IsServer); +} + +#endif /* MPPE */ + + +void +ChapMS(u_char *rchallenge, char *secret, int secret_len, + unsigned char *response) +{ + BZERO(response, MS_CHAP_RESPONSE_LEN); + + ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); + +#ifdef MSLANMAN + ChapMS_LANMan(rchallenge, secret, secret_len, + &response[MS_CHAP_LANMANRESP]); + + /* preferred method is set by option */ + response[MS_CHAP_USENT] = !ms_lanman; +#else + response[MS_CHAP_USENT] = 1; +#endif + +#ifdef MPPE + Set_Start_Key(rchallenge, secret, secret_len); +#endif +} + + +/* + * If PeerChallenge is NULL, one is generated and the PeerChallenge + * field of response is filled in. Call this way when generating a response. + * If PeerChallenge is supplied, it is copied into the PeerChallenge field. + * Call this way when verifying a response (or debugging). + * Do not call with PeerChallenge = response. + * + * The PeerChallenge field of response is then used for calculation of the + * Authenticator Response. + */ +void +ChapMS2(u_char *rchallenge, u_char *PeerChallenge, + char *user, char *secret, int secret_len, unsigned char *response, + u_char authResponse[], int authenticator) +{ + /* ARGSUSED */ + u_char *p = &response[MS_CHAP2_PEER_CHALLENGE]; + int i; + + BZERO(response, MS_CHAP2_RESPONSE_LEN); + + /* Generate the Peer-Challenge if requested, or copy it if supplied. */ + if (!PeerChallenge) + for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++) + *p++ = (u_char) (drand48() * 0xff); + else + BCOPY(PeerChallenge, &response[MS_CHAP2_PEER_CHALLENGE], + MS_CHAP2_PEER_CHAL_LEN); + + /* Generate the NT-Response */ + ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, + secret, secret_len, &response[MS_CHAP2_NTRESP]); + + /* Generate the Authenticator Response. */ + GenerateAuthenticatorResponsePlain(secret, secret_len, + &response[MS_CHAP2_NTRESP], + &response[MS_CHAP2_PEER_CHALLENGE], + rchallenge, user, authResponse); + +#ifdef MPPE + SetMasterKeys(secret, secret_len, + &response[MS_CHAP2_NTRESP], authenticator); +#endif +} + +#ifdef MPPE +/* + * Set MPPE options from plugins. + */ +void +set_mppe_enc_types(int policy, int types) +{ + /* Early exit for unknown policies. */ + if (policy != MPPE_ENC_POL_ENC_ALLOWED || + policy != MPPE_ENC_POL_ENC_REQUIRED) + return; + + /* Don't modify MPPE if it's optional and wasn't already configured. */ + if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe) + return; + + /* + * Disable undesirable encryption types. Note that we don't ENABLE + * any encryption types, to avoid overriding manual configuration. + */ + switch(types) { + case MPPE_ENC_TYPES_RC4_40: + ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */ + break; + case MPPE_ENC_TYPES_RC4_128: + ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */ + break; + default: + break; + } +} +#endif /* MPPE */ + +static struct chap_digest_type chapms_digest = { + CHAP_MICROSOFT, /* code */ + chapms_generate_challenge, + chapms_verify_response, + chapms_make_response, + NULL, /* check_success */ + chapms_handle_failure, +}; + +static struct chap_digest_type chapms2_digest = { + CHAP_MICROSOFT_V2, /* code */ + chapms2_generate_challenge, + chapms2_verify_response, + chapms2_make_response, + chapms2_check_success, + chapms_handle_failure, +}; + +void +chapms_init(void) +{ + chap_register_digest(&chapms_digest); + chap_register_digest(&chapms2_digest); + add_options(chapms_option_list); +} + +#endif /* CHAPMS */ diff --git a/src/netif/ppp/chap_ms.h b/src/netif/ppp/chap_ms.h new file mode 100644 index 00000000..040d80ad --- /dev/null +++ b/src/netif/ppp/chap_ms.h @@ -0,0 +1,109 @@ +/* + * chap_ms.h - Challenge Handshake Authentication Protocol definitions. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ + */ + +#ifndef __CHAPMS_INCLUDE__ + +#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ +#define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */ + +#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ +#define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */ +#define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */ + /* as ASCII */ + +/* E=eeeeeeeeee error codes for MS-CHAP failure messages. */ +#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646 +#define MS_CHAP_ERROR_ACCT_DISABLED 647 +#define MS_CHAP_ERROR_PASSWD_EXPIRED 648 +#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649 +#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691 +#define MS_CHAP_ERROR_CHANGING_PASSWORD 709 + +/* + * Offsets within the response field for MS-CHAP + */ +#define MS_CHAP_LANMANRESP 0 +#define MS_CHAP_LANMANRESP_LEN 24 +#define MS_CHAP_NTRESP 24 +#define MS_CHAP_NTRESP_LEN 24 +#define MS_CHAP_USENT 48 + +/* + * Offsets within the response field for MS-CHAP2 + */ +#define MS_CHAP2_PEER_CHALLENGE 0 +#define MS_CHAP2_PEER_CHAL_LEN 16 +#define MS_CHAP2_RESERVED_LEN 8 +#define MS_CHAP2_NTRESP 24 +#define MS_CHAP2_NTRESP_LEN 24 +#define MS_CHAP2_FLAGS 48 + +#ifdef MPPE +#include "mppe.h" /* MPPE_MAX_KEY_LEN */ +extern u_char mppe_send_key[MPPE_MAX_KEY_LEN]; +extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; +extern int mppe_keys_set; + +/* These values are the RADIUS attribute values--see RFC 2548. */ +#define MPPE_ENC_POL_ENC_ALLOWED 1 +#define MPPE_ENC_POL_ENC_REQUIRED 2 +#define MPPE_ENC_TYPES_RC4_40 2 +#define MPPE_ENC_TYPES_RC4_128 4 + +/* used by plugins (using above values) */ +extern void set_mppe_enc_types(int, int); +#endif + +/* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */ +#define MS_CHAP2_AUTHENTICATEE 0 +#define MS_CHAP2_AUTHENTICATOR 1 + +void ChapMS __P((u_char *, char *, int, u_char *)); +void ChapMS2 __P((u_char *, u_char *, char *, char *, int, + u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int)); +#ifdef MPPE +void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE])); +void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], int IsServer); +#endif + +void ChallengeHash __P((u_char[16], u_char *, char *, u_char[8])); + +void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]); + +void chapms_init(void); + +#define __CHAPMS_INCLUDE__ +#endif /* __CHAPMS_INCLUDE__ */ diff --git a/src/netif/ppp/chpms.c b/src/netif/ppp/chpms.c deleted file mode 100644 index 81a887b8..00000000 --- a/src/netif/ppp/chpms.c +++ /dev/null @@ -1,396 +0,0 @@ -/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/ -/*** The original PPPD code is written in a way to require either the UNIX DES - encryption functions encrypt(3) and setkey(3) or the DES library libdes. - Since both is not included in lwIP, MSCHAP currently does not work! */ -/***************************************************************************** -* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-08 Guy Lancaster , Global Election Systems Inc. -* Original based on BSD chap_ms.c. -*****************************************************************************/ -/* - * 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 USE_CRYPT - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "md4.h" -#ifndef USE_CRYPT -#include "des.h" -#endif -#include "chap.h" -#include "chpms.h" - -#include - - -/*************************/ -/*** LOCAL DEFINITIONS ***/ -/*************************/ - - -/************************/ -/*** LOCAL DATA TYPES ***/ -/************************/ -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. */ - - - -/***********************************/ -/*** LOCAL FUNCTION DECLARATIONS ***/ -/***********************************/ - -/* XXX Don't know what to do with these. */ -extern void setkey(const char *); -extern void encrypt(char *, int); - -static void DesEncrypt (u_char *, u_char *, u_char *); -static void MakeKey (u_char *, u_char *); - -#ifdef USE_CRYPT -static void Expand (u_char *, u_char *); -static void Collapse (u_char *, u_char *); -#endif - -static void ChallengeResponse( - u_char *challenge, /* IN 8 octets */ - u_char *pwHash, /* IN 16 octets */ - u_char *response /* OUT 24 octets */ -); -static void ChapMS_NT( - char *rchallenge, - int rchallenge_len, - char *secret, - int secret_len, - MS_ChapResponse *response -); -static u_char Get7Bits( - u_char *input, - int startBit -); - -static void -ChallengeResponse( u_char *challenge, /* IN 8 octets */ - u_char *pwHash, /* IN 16 octets */ - u_char *response /* OUT 24 octets */) -{ - u_char ZPasswordHash[21]; - - BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - BCOPY(pwHash, ZPasswordHash, 16); - -#if 0 - log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG); -#endif - - DesEncrypt(challenge, ZPasswordHash + 0, response + 0); - DesEncrypt(challenge, ZPasswordHash + 7, response + 8); - DesEncrypt(challenge, ZPasswordHash + 14, response + 16); - -#if 0 - log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG); -#endif -} - - -#ifdef USE_CRYPT -static void -DesEncrypt( 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((char*)crypt_key); - -#if 0 - CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n", - clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); -#endif - - Expand(clear, des_input); - encrypt((char*)des_input, 0); - Collapse(des_input, cipher); - -#if 0 - CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n", - cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); -#endif -} - -#else /* USE_CRYPT */ - -static void -DesEncrypt( 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 : %02X%02X%02X%02X%02X%02X%02X%02X\n", - clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); -#endif - - des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1); - -#if 0 - CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n", - cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); -#endif -} - -#endif /* USE_CRYPT */ - - -static u_char -Get7Bits( 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(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(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( 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 : %02X%02X%02X%02X%02X%02X%02X\n", - key[0], key[1], key[2], key[3], key[4], key[5], key[6])); - CHAPDEBUG(LOG_INFO, ("MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n", - des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7])); -#endif -} - -static void -ChapMS_NT( char *rchallenge, - int rchallenge_len, - char *secret, - int secret_len, - MS_ChapResponse *response) -{ - int i; - MDstruct md4Context; - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - static int low_byte_first = -1; - - LWIP_UNUSED_ARG(rchallenge_len); - - /* 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]; - } - MDbegin(&md4Context); - MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */ - - if (low_byte_first == -1) { - low_byte_first = (PP_HTONS((unsigned short int)1) != 1); - } - if (low_byte_first == 0) { - /* @todo: arg type - u_long* or u_int* ? */ - MDreverse((unsigned int*)&md4Context); /* sfb 961105 */ - } - - MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */ - - ChallengeResponse((u_char*)rchallenge, (u_char*)md4Context.buffer, response->NTResp); -} - -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void -ChapMS_LANMan( 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[16]; - - /* 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( chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, int secret_len) -{ - MS_ChapResponse response; -#ifdef MSLANMAN - extern int ms_lanman; -#endif - -#if 0 - CHAPDEBUG(LOG_INFO, ("ChapMS: secret is '%.*s'\n", 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 /* MSCHAP_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/chpms.h b/src/netif/ppp/chpms.h deleted file mode 100644 index df070fb3..00000000 --- a/src/netif/ppp/chpms.h +++ /dev/null @@ -1,64 +0,0 @@ -/***************************************************************************** -* chpms.h - Network Microsoft Challenge Handshake Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-01-30 Guy Lancaster , Global Election Systems Inc. -* Original built from BSD network code. -******************************************************************************/ -/* - * 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: chpms.h,v 1.5 2007/12/19 20:47:23 fbernon Exp $ - */ - -#ifndef CHPMS_H -#define CHPMS_H - -#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */ - -void ChapMS (chap_state *, char *, int, char *, int); - -#endif /* CHPMS_H */ diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c new file mode 100644 index 00000000..fd24b8bb --- /dev/null +++ b/src/netif/ppp/demand.c @@ -0,0 +1,366 @@ +/* + * demand.c - Support routines for demand-dialling. + * + * Copyright (c) 1996-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: demand.c,v 1.20 2005/08/25 12:14:18 paulus Exp $" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef PPP_FILTER +#include +#endif + +#include "pppd.h" +#include "fsm.h" +#include "ipcp.h" +#include "lcp.h" + +static const char rcsid[] = RCSID; + +char *frame; +int framelen; +int framemax; +int escape_flag; +int flush_flag; +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 __P((unsigned char *, int)); + +/* + * demand_conf - configure the interface for doing dial-on-demand. + */ +void +demand_conf() +{ + 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; + + netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU)); + if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0 + || ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0) + fatal("Couldn't set up demand-dialled PPP interface: %m"); + +#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() +{ + 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() +{ + 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() +{ + 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(p, n) + 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((unsigned char *)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(frame, len) + 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(proto) + 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(p, len) + unsigned char *p; + int len; +{ + int proto, i; + struct protent *protp; + + if (len < PPP_HDRLEN) + return 0; + proto = PPP_PROTOCOL(p); +#ifdef PPP_FILTER + p[0] = 1; /* outbound packet indicator */ + if ((pass_filter.bf_len != 0 + && bpf_filter(pass_filter.bf_insns, p, len, len) == 0) + || (active_filter.bf_len != 0 + && bpf_filter(active_filter.bf_insns, p, len, len) == 0)) { + p[0] = 0xff; + return 0; + } + p[0] = 0xff; +#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/src/netif/ppp/eap.c b/src/netif/ppp/eap.c new file mode 100644 index 00000000..76404281 --- /dev/null +++ b/src/netif/ppp/eap.c @@ -0,0 +1,2430 @@ +/* + * eap.c - Extensible Authentication Protocol for PPP (RFC 2284) + * + * Copyright (c) 2001 by Sun Microsystems, Inc. + * All rights reserved. + * + * Non-exclusive rights to redistribute, modify, translate, and use + * this software in source and binary forms, in whole or in part, is + * hereby granted, provided that the above copyright notice is + * duplicated in any source form, and that neither the name of the + * copyright holder nor the author is used to endorse or promote + * products derived from this software. + * + * 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. + * + * Original version by James Carlson + * + * This implementation of EAP supports MD5-Challenge and SRP-SHA1 + * authentication styles. Note that support of MD5-Challenge is a + * requirement of RFC 2284, and that it's essentially just a + * reimplementation of regular RFC 1994 CHAP using EAP messages. + * + * As an authenticator ("server"), there are multiple phases for each + * style. In the first phase of each style, the unauthenticated peer + * name is queried using the EAP Identity request type. If the + * "remotename" option is used, then this phase is skipped, because + * the peer's name is presumed to be known. + * + * For MD5-Challenge, there are two phases, and the second phase + * consists of sending the challenge itself and handling the + * associated response. + * + * For SRP-SHA1, there are four phases. The second sends 's', 'N', + * and 'g'. The reply contains 'A'. The third sends 'B', and the + * reply contains 'M1'. The forth sends the 'M2' value. + * + * As an authenticatee ("client"), there's just a single phase -- + * responding to the queries generated by the peer. EAP is an + * authenticator-driven protocol. + * + * Based on draft-ietf-pppext-eap-srp-03.txt. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" + +/* + * TODO: + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pppd.h" +#include "pathnames.h" +#include "md5.h" +#include "eap.h" + +#ifdef USE_SRP +#include +#include +#include +#include "pppcrypt.h" +#endif /* USE_SRP */ + +#ifndef SHA_DIGESTSIZE +#define SHA_DIGESTSIZE 20 +#endif + +static const char rcsid[] = RCSID; + +eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */ +#ifdef USE_SRP +static char *pn_secret = NULL; /* Pseudonym generating secret */ +#endif + +/* + * Command-line options. + */ +static option_t eap_option_list[] = { + { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout, + "Set retransmit timeout for EAP Requests (server)" }, + { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests, + "Set max number of EAP Requests sent (server)" }, + { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout, + "Set time limit for peer EAP authentication" }, + { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests, + "Set max number of EAP Requests allows (client)" }, + { "eap-interval", o_int, &eap_states[0].es_rechallenge, + "Set interval for EAP rechallenge" }, +#ifdef USE_SRP + { "srp-interval", o_int, &eap_states[0].es_lwrechallenge, + "Set interval for SRP lightweight rechallenge" }, + { "srp-pn-secret", o_string, &pn_secret, + "Long term pseudonym generation secret" }, + { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo, + "Use pseudonym if offered one by server", 1 }, +#endif + { NULL } +}; + +/* + * Protocol entry points. + */ +static void eap_init __P((int unit)); +static void eap_input __P((int unit, u_char *inp, int inlen)); +static void eap_protrej __P((int unit)); +static void eap_lowerup __P((int unit)); +static void eap_lowerdown __P((int unit)); +static int eap_printpkt __P((u_char *inp, int inlen, + void (*)(void *arg, char *fmt, ...), void *arg)); + +struct protent eap_protent = { + PPP_EAP, /* protocol number */ + eap_init, /* initialization procedure */ + eap_input, /* process a received packet */ + eap_protrej, /* process a received protocol-reject */ + eap_lowerup, /* lower layer has gone up */ + eap_lowerdown, /* lower layer has gone down */ + NULL, /* open the protocol */ + NULL, /* close the protocol */ + eap_printpkt, /* print a packet in readable form */ + NULL, /* process a received data packet */ + 1, /* protocol enabled */ + "EAP", /* text name of protocol */ + NULL, /* text name of corresponding data protocol */ + eap_option_list, /* list of command-line options */ + NULL, /* check requested options; assign defaults */ + NULL, /* configure interface for demand-dial */ + NULL /* say whether to bring up link for this pkt */ +}; + +/* + * A well-known 2048 bit modulus. + */ +static const u_char wkmodulus[] = { + 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, + 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, + 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, + 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50, + 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, + 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D, + 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, + 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50, + 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, + 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, + 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, + 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, + 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, + 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74, + 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, + 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B, + 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, + 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81, + 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, + 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, + 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, + 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA, + 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, + 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6, + 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, + 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8, + 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, + 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, + 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, + 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, + 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, + 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 +}; + +/* Local forward declarations. */ +static void eap_server_timeout __P((void *arg)); + +/* + * Convert EAP state code to printable string for debug. + */ +static const char * +eap_state_name(esc) +enum eap_state_code esc; +{ + static const char *state_names[] = { EAP_STATES }; + + return (state_names[(int)esc]); +} + +/* + * eap_init - Initialize state for an EAP user. This is currently + * called once by main() during start-up. + */ +static void +eap_init(unit) +int unit; +{ + eap_state *esp = &eap_states[unit]; + + BZERO(esp, sizeof (*esp)); + esp->es_unit = unit; + esp->es_server.ea_timeout = EAP_DEFTIMEOUT; + esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS; + esp->es_server.ea_id = (u_char)(drand48() * 0x100); + esp->es_client.ea_timeout = EAP_DEFREQTIME; + esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; +} + +/* + * eap_client_timeout - Give up waiting for the peer to send any + * Request messages. + */ +static void +eap_client_timeout(arg) +void *arg; +{ + eap_state *esp = (eap_state *) arg; + + if (!eap_client_active(esp)) + return; + + error("EAP: timeout waiting for Request from peer"); + auth_withpeer_fail(esp->es_unit, PPP_EAP); + esp->es_client.ea_state = eapBadAuth; +} + +/* + * eap_authwithpeer - Authenticate to our peer (behave as client). + * + * Start client state and wait for requests. This is called only + * after eap_lowerup. + */ +void +eap_authwithpeer(unit, localname) +int unit; +char *localname; +{ + eap_state *esp = &eap_states[unit]; + + /* Save the peer name we're given */ + esp->es_client.ea_name = localname; + esp->es_client.ea_namelen = strlen(localname); + + esp->es_client.ea_state = eapListen; + + /* + * Start a timer so that if the other end just goes + * silent, we don't sit here waiting forever. + */ + if (esp->es_client.ea_timeout > 0) + TIMEOUT(eap_client_timeout, (void *)esp, + esp->es_client.ea_timeout); +} + +/* + * Format a standard EAP Failure message and send it to the peer. + * (Server operation) + */ +static void +eap_send_failure(esp) +eap_state *esp; +{ + u_char *outp; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_FAILURE, outp); + esp->es_server.ea_id++; + PUTCHAR(esp->es_server.ea_id, outp); + PUTSHORT(EAP_HEADERLEN, outp); + + output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); + + esp->es_server.ea_state = eapBadAuth; + auth_peer_fail(esp->es_unit, PPP_EAP); +} + +/* + * Format a standard EAP Success message and send it to the peer. + * (Server operation) + */ +static void +eap_send_success(esp) +eap_state *esp; +{ + u_char *outp; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_SUCCESS, outp); + esp->es_server.ea_id++; + PUTCHAR(esp->es_server.ea_id, outp); + PUTSHORT(EAP_HEADERLEN, outp); + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); + + auth_peer_success(esp->es_unit, PPP_EAP, 0, + esp->es_server.ea_peer, esp->es_server.ea_peerlen); +} + +#ifdef USE_SRP +/* + * Set DES key according to pseudonym-generating secret and current + * date. + */ +static bool +pncrypt_setkey(int timeoffs) +{ + struct tm *tp; + char tbuf[9]; + SHA1_CTX ctxt; + u_char dig[SHA_DIGESTSIZE]; + time_t reftime; + + if (pn_secret == NULL) + return (0); + reftime = time(NULL) + timeoffs; + tp = localtime(&reftime); + SHA1Init(&ctxt); + SHA1Update(&ctxt, pn_secret, strlen(pn_secret)); + strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); + SHA1Update(&ctxt, tbuf, strlen(tbuf)); + SHA1Final(dig, &ctxt); + return (DesSetkey(dig)); +} + +static char base64[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +struct b64state { + u_int32_t bs_bits; + int bs_offs; +}; + +static int +b64enc(bs, inp, inlen, outp) +struct b64state *bs; +u_char *inp; +int inlen; +u_char *outp; +{ + int outlen = 0; + + while (inlen > 0) { + bs->bs_bits = (bs->bs_bits << 8) | *inp++; + inlen--; + bs->bs_offs += 8; + if (bs->bs_offs >= 24) { + *outp++ = base64[(bs->bs_bits >> 18) & 0x3F]; + *outp++ = base64[(bs->bs_bits >> 12) & 0x3F]; + *outp++ = base64[(bs->bs_bits >> 6) & 0x3F]; + *outp++ = base64[bs->bs_bits & 0x3F]; + outlen += 4; + bs->bs_offs = 0; + bs->bs_bits = 0; + } + } + return (outlen); +} + +static int +b64flush(bs, outp) +struct b64state *bs; +u_char *outp; +{ + int outlen = 0; + + if (bs->bs_offs == 8) { + *outp++ = base64[(bs->bs_bits >> 2) & 0x3F]; + *outp++ = base64[(bs->bs_bits << 4) & 0x3F]; + outlen = 2; + } else if (bs->bs_offs == 16) { + *outp++ = base64[(bs->bs_bits >> 10) & 0x3F]; + *outp++ = base64[(bs->bs_bits >> 4) & 0x3F]; + *outp++ = base64[(bs->bs_bits << 2) & 0x3F]; + outlen = 3; + } + bs->bs_offs = 0; + bs->bs_bits = 0; + return (outlen); +} + +static int +b64dec(bs, inp, inlen, outp) +struct b64state *bs; +u_char *inp; +int inlen; +u_char *outp; +{ + int outlen = 0; + char *cp; + + while (inlen > 0) { + if ((cp = strchr(base64, *inp++)) == NULL) + break; + bs->bs_bits = (bs->bs_bits << 6) | (cp - base64); + inlen--; + bs->bs_offs += 6; + if (bs->bs_offs >= 8) { + *outp++ = bs->bs_bits >> (bs->bs_offs - 8); + outlen++; + bs->bs_offs -= 8; + } + } + return (outlen); +} +#endif /* USE_SRP */ + +/* + * Assume that current waiting server state is complete and figure + * next state to use based on available authentication data. 'status' + * indicates if there was an error in handling the last query. It is + * 0 for success and non-zero for failure. + */ +static void +eap_figure_next_state(esp, status) +eap_state *esp; +int status; +{ +#ifdef USE_SRP + unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp; + struct t_pw tpw; + struct t_confent *tce, mytce; + char *cp, *cp2; + struct t_server *ts; + int id, i, plen, toffs; + u_char vals[2]; + struct b64state bs; +#endif /* USE_SRP */ + + esp->es_server.ea_timeout = esp->es_savedtime; + switch (esp->es_server.ea_state) { + case eapBadAuth: + return; + + case eapIdentify: +#ifdef USE_SRP + /* Discard any previous session. */ + ts = (struct t_server *)esp->es_server.ea_session; + if (ts != NULL) { + t_serverclose(ts); + esp->es_server.ea_session = NULL; + esp->es_server.ea_skey = NULL; + } +#endif /* USE_SRP */ + if (status != 0) { + esp->es_server.ea_state = eapBadAuth; + break; + } +#ifdef USE_SRP + /* If we've got a pseudonym, try to decode to real name. */ + if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN && + strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID, + SRP_PSEUDO_LEN) == 0 && + (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 < + sizeof (secbuf)) { + BZERO(&bs, sizeof (bs)); + plen = b64dec(&bs, + esp->es_server.ea_peer + SRP_PSEUDO_LEN, + esp->es_server.ea_peerlen - SRP_PSEUDO_LEN, + secbuf); + toffs = 0; + for (i = 0; i < 5; i++) { + pncrypt_setkey(toffs); + toffs -= 86400; + if (!DesDecrypt(secbuf, clear)) { + dbglog("no DES here; cannot decode " + "pseudonym"); + return; + } + id = *(unsigned char *)clear; + if (id + 1 <= plen && id + 9 > plen) + break; + } + if (plen % 8 == 0 && i < 5) { + /* + * Note that this is always shorter than the + * original stored string, so there's no need + * to realloc. + */ + if ((i = plen = *(unsigned char *)clear) > 7) + i = 7; + esp->es_server.ea_peerlen = plen; + dp = (unsigned char *)esp->es_server.ea_peer; + BCOPY(clear + 1, dp, i); + plen -= i; + dp += i; + sp = secbuf + 8; + while (plen > 0) { + (void) DesDecrypt(sp, dp); + sp += 8; + dp += 8; + plen -= 8; + } + esp->es_server.ea_peer[ + esp->es_server.ea_peerlen] = '\0'; + dbglog("decoded pseudonym to \"%.*q\"", + esp->es_server.ea_peerlen, + esp->es_server.ea_peer); + } else { + dbglog("failed to decode real name"); + /* Stay in eapIdentfy state; requery */ + break; + } + } + /* Look up user in secrets database. */ + if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer, + esp->es_server.ea_name, (char *)secbuf, 1) != 0) { + /* Set up default in case SRP entry is bad */ + esp->es_server.ea_state = eapMD5Chall; + /* Get t_confent based on index in srp-secrets */ + id = strtol((char *)secbuf, &cp, 10); + if (*cp++ != ':' || id < 0) + break; + if (id == 0) { + mytce.index = 0; + mytce.modulus.data = (u_char *)wkmodulus; + mytce.modulus.len = sizeof (wkmodulus); + mytce.generator.data = (u_char *)"\002"; + mytce.generator.len = 1; + tce = &mytce; + } else if ((tce = gettcid(id)) != NULL) { + /* + * Client will have to verify this modulus/ + * generator combination, and that will take + * a while. Lengthen the timeout here. + */ + if (esp->es_server.ea_timeout > 0 && + esp->es_server.ea_timeout < 30) + esp->es_server.ea_timeout = 30; + } else { + break; + } + if ((cp2 = strchr(cp, ':')) == NULL) + break; + *cp2++ = '\0'; + tpw.pebuf.name = esp->es_server.ea_peer; + tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf, + cp); + tpw.pebuf.password.data = tpw.pwbuf; + tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf, + cp2); + tpw.pebuf.salt.data = tpw.saltbuf; + if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL) + break; + esp->es_server.ea_session = (void *)ts; + esp->es_server.ea_state = eapSRP1; + vals[0] = esp->es_server.ea_id + 1; + vals[1] = EAPT_SRP; + t_serveraddexdata(ts, vals, 2); + /* Generate B; must call before t_servergetkey() */ + t_servergenexp(ts); + break; + } +#endif /* USE_SRP */ + esp->es_server.ea_state = eapMD5Chall; + break; + + case eapSRP1: +#ifdef USE_SRP + ts = (struct t_server *)esp->es_server.ea_session; + if (ts != NULL && status != 0) { + t_serverclose(ts); + esp->es_server.ea_session = NULL; + esp->es_server.ea_skey = NULL; + } +#endif /* USE_SRP */ + if (status == 1) { + esp->es_server.ea_state = eapMD5Chall; + } else if (status != 0 || esp->es_server.ea_session == NULL) { + esp->es_server.ea_state = eapBadAuth; + } else { + esp->es_server.ea_state = eapSRP2; + } + break; + + case eapSRP2: +#ifdef USE_SRP + ts = (struct t_server *)esp->es_server.ea_session; + if (ts != NULL && status != 0) { + t_serverclose(ts); + esp->es_server.ea_session = NULL; + esp->es_server.ea_skey = NULL; + } +#endif /* USE_SRP */ + if (status != 0 || esp->es_server.ea_session == NULL) { + esp->es_server.ea_state = eapBadAuth; + } else { + esp->es_server.ea_state = eapSRP3; + } + break; + + case eapSRP3: + case eapSRP4: +#ifdef USE_SRP + ts = (struct t_server *)esp->es_server.ea_session; + if (ts != NULL && status != 0) { + t_serverclose(ts); + esp->es_server.ea_session = NULL; + esp->es_server.ea_skey = NULL; + } +#endif /* USE_SRP */ + if (status != 0 || esp->es_server.ea_session == NULL) { + esp->es_server.ea_state = eapBadAuth; + } else { + esp->es_server.ea_state = eapOpen; + } + break; + + case eapMD5Chall: + if (status != 0) { + esp->es_server.ea_state = eapBadAuth; + } else { + esp->es_server.ea_state = eapOpen; + } + break; + + default: + esp->es_server.ea_state = eapBadAuth; + break; + } + if (esp->es_server.ea_state == eapBadAuth) + eap_send_failure(esp); +} + +/* + * Format an EAP Request message and send it to the peer. Message + * type depends on current state. (Server operation) + */ +static void +eap_send_request(esp) +eap_state *esp; +{ + u_char *outp; + u_char *lenloc; + u_char *ptr; + int outlen; + int challen; + char *str; +#ifdef USE_SRP + struct t_server *ts; + u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp; + int i, j; + struct b64state b64; + SHA1_CTX ctxt; +#endif /* USE_SRP */ + + /* Handle both initial auth and restart */ + if (esp->es_server.ea_state < eapIdentify && + esp->es_server.ea_state != eapInitial) { + esp->es_server.ea_state = eapIdentify; + if (explicit_remote) { + /* + * If we already know the peer's + * unauthenticated name, then there's no + * reason to ask. Go to next state instead. + */ + esp->es_server.ea_peer = remote_name; + esp->es_server.ea_peerlen = strlen(remote_name); + eap_figure_next_state(esp, 0); + } + } + + if (esp->es_server.ea_maxrequests > 0 && + esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) { + if (esp->es_server.ea_responses > 0) + error("EAP: too many Requests sent"); + else + error("EAP: no response to Requests"); + eap_send_failure(esp); + return; + } + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_REQUEST, outp); + PUTCHAR(esp->es_server.ea_id, outp); + lenloc = outp; + INCPTR(2, outp); + + switch (esp->es_server.ea_state) { + case eapIdentify: + PUTCHAR(EAPT_IDENTITY, outp); + str = "Name"; + challen = strlen(str); + BCOPY(str, outp, challen); + INCPTR(challen, outp); + break; + + case eapMD5Chall: + PUTCHAR(EAPT_MD5CHAP, outp); + /* + * pick a random challenge length between + * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH + */ + challen = (drand48() * + (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) + + MIN_CHALLENGE_LENGTH; + PUTCHAR(challen, outp); + esp->es_challen = challen; + ptr = esp->es_challenge; + while (--challen >= 0) + *ptr++ = (u_char) (drand48() * 0x100); + BCOPY(esp->es_challenge, outp, esp->es_challen); + INCPTR(esp->es_challen, outp); + BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); + INCPTR(esp->es_server.ea_namelen, outp); + break; + +#ifdef USE_SRP + case eapSRP1: + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_CHALLENGE, outp); + + PUTCHAR(esp->es_server.ea_namelen, outp); + BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); + INCPTR(esp->es_server.ea_namelen, outp); + + ts = (struct t_server *)esp->es_server.ea_session; + assert(ts != NULL); + PUTCHAR(ts->s.len, outp); + BCOPY(ts->s.data, outp, ts->s.len); + INCPTR(ts->s.len, outp); + + if (ts->g.len == 1 && ts->g.data[0] == 2) { + PUTCHAR(0, outp); + } else { + PUTCHAR(ts->g.len, outp); + BCOPY(ts->g.data, outp, ts->g.len); + INCPTR(ts->g.len, outp); + } + + if (ts->n.len != sizeof (wkmodulus) || + BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) { + BCOPY(ts->n.data, outp, ts->n.len); + INCPTR(ts->n.len, outp); + } + break; + + case eapSRP2: + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_SKEY, outp); + + ts = (struct t_server *)esp->es_server.ea_session; + assert(ts != NULL); + BCOPY(ts->B.data, outp, ts->B.len); + INCPTR(ts->B.len, outp); + break; + + case eapSRP3: + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_SVALIDATOR, outp); + PUTLONG(SRPVAL_EBIT, outp); + ts = (struct t_server *)esp->es_server.ea_session; + assert(ts != NULL); + BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE); + INCPTR(SHA_DIGESTSIZE, outp); + + if (pncrypt_setkey(0)) { + /* Generate pseudonym */ + optr = outp; + cp = (unsigned char *)esp->es_server.ea_peer; + if ((j = i = esp->es_server.ea_peerlen) > 7) + j = 7; + clear[0] = i; + BCOPY(cp, clear + 1, j); + i -= j; + cp += j; + if (!DesEncrypt(clear, cipher)) { + dbglog("no DES here; not generating pseudonym"); + break; + } + BZERO(&b64, sizeof (b64)); + outp++; /* space for pseudonym length */ + outp += b64enc(&b64, cipher, 8, outp); + while (i >= 8) { + (void) DesEncrypt(cp, cipher); + outp += b64enc(&b64, cipher, 8, outp); + cp += 8; + i -= 8; + } + if (i > 0) { + BCOPY(cp, clear, i); + cp += i; + while (i < 8) { + *cp++ = drand48() * 0x100; + i++; + } + (void) DesEncrypt(clear, cipher); + outp += b64enc(&b64, cipher, 8, outp); + } + outp += b64flush(&b64, outp); + + /* Set length and pad out to next 20 octet boundary */ + i = outp - optr - 1; + *optr = i; + i %= SHA_DIGESTSIZE; + if (i != 0) { + while (i < SHA_DIGESTSIZE) { + *outp++ = drand48() * 0x100; + i++; + } + } + + /* Obscure the pseudonym with SHA1 hash */ + SHA1Init(&ctxt); + SHA1Update(&ctxt, &esp->es_server.ea_id, 1); + SHA1Update(&ctxt, esp->es_server.ea_skey, + SESSION_KEY_LEN); + SHA1Update(&ctxt, esp->es_server.ea_peer, + esp->es_server.ea_peerlen); + while (optr < outp) { + SHA1Final(dig, &ctxt); + cp = dig; + while (cp < dig + SHA_DIGESTSIZE) + *optr++ ^= *cp++; + SHA1Init(&ctxt); + SHA1Update(&ctxt, &esp->es_server.ea_id, 1); + SHA1Update(&ctxt, esp->es_server.ea_skey, + SESSION_KEY_LEN); + SHA1Update(&ctxt, optr - SHA_DIGESTSIZE, + SHA_DIGESTSIZE); + } + } + break; + + case eapSRP4: + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_LWRECHALLENGE, outp); + challen = MIN_CHALLENGE_LENGTH + + ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48()); + esp->es_challen = challen; + ptr = esp->es_challenge; + while (--challen >= 0) + *ptr++ = drand48() * 0x100; + BCOPY(esp->es_challenge, outp, esp->es_challen); + INCPTR(esp->es_challen, outp); + break; +#endif /* USE_SRP */ + + default: + return; + } + + outlen = (outp - outpacket_buf) - PPP_HDRLEN; + PUTSHORT(outlen, lenloc); + + output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); + + esp->es_server.ea_requests++; + + if (esp->es_server.ea_timeout > 0) + TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); +} + +/* + * eap_authpeer - Authenticate our peer (behave as server). + * + * Start server state and send first request. This is called only + * after eap_lowerup. + */ +void +eap_authpeer(unit, localname) +int unit; +char *localname; +{ + eap_state *esp = &eap_states[unit]; + + /* Save the name we're given. */ + esp->es_server.ea_name = localname; + esp->es_server.ea_namelen = strlen(localname); + + esp->es_savedtime = esp->es_server.ea_timeout; + + /* Lower layer up yet? */ + if (esp->es_server.ea_state == eapInitial || + esp->es_server.ea_state == eapPending) { + esp->es_server.ea_state = eapPending; + return; + } + + esp->es_server.ea_state = eapPending; + + /* ID number not updated here intentionally; hashed into M1 */ + eap_send_request(esp); +} + +/* + * eap_server_timeout - Retransmission timer for sending Requests + * expired. + */ +static void +eap_server_timeout(arg) +void *arg; +{ + eap_state *esp = (eap_state *) arg; + + if (!eap_server_active(esp)) + return; + + /* EAP ID number must not change on timeout. */ + eap_send_request(esp); +} + +/* + * When it's time to send rechallenge the peer, this timeout is + * called. Once the rechallenge is successful, the response handler + * will restart the timer. If it fails, then the link is dropped. + */ +static void +eap_rechallenge(arg) +void *arg; +{ + eap_state *esp = (eap_state *)arg; + + if (esp->es_server.ea_state != eapOpen && + esp->es_server.ea_state != eapSRP4) + return; + + esp->es_server.ea_requests = 0; + esp->es_server.ea_state = eapIdentify; + eap_figure_next_state(esp, 0); + esp->es_server.ea_id++; + eap_send_request(esp); +} + +static void +srp_lwrechallenge(arg) +void *arg; +{ + eap_state *esp = (eap_state *)arg; + + if (esp->es_server.ea_state != eapOpen || + esp->es_server.ea_type != EAPT_SRP) + return; + + esp->es_server.ea_requests = 0; + esp->es_server.ea_state = eapSRP4; + esp->es_server.ea_id++; + eap_send_request(esp); +} + +/* + * eap_lowerup - The lower layer is now up. + * + * This is called before either eap_authpeer or eap_authwithpeer. See + * link_established() in auth.c. All that's necessary here is to + * return to closed state so that those two routines will do the right + * thing. + */ +static void +eap_lowerup(unit) +int unit; +{ + eap_state *esp = &eap_states[unit]; + + /* Discard any (possibly authenticated) peer name. */ + if (esp->es_server.ea_peer != NULL && + esp->es_server.ea_peer != remote_name) + free(esp->es_server.ea_peer); + esp->es_server.ea_peer = NULL; + if (esp->es_client.ea_peer != NULL) + free(esp->es_client.ea_peer); + esp->es_client.ea_peer = NULL; + + esp->es_client.ea_state = eapClosed; + esp->es_server.ea_state = eapClosed; +} + +/* + * eap_lowerdown - The lower layer is now down. + * + * Cancel all timeouts and return to initial state. + */ +static void +eap_lowerdown(unit) +int unit; +{ + eap_state *esp = &eap_states[unit]; + + if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, (void *)esp); + } + if (eap_server_active(esp)) { + if (esp->es_server.ea_timeout > 0) { + UNTIMEOUT(eap_server_timeout, (void *)esp); + } + } else { + if ((esp->es_server.ea_state == eapOpen || + esp->es_server.ea_state == eapSRP4) && + esp->es_rechallenge > 0) { + UNTIMEOUT(eap_rechallenge, (void *)esp); + } + if (esp->es_server.ea_state == eapOpen && + esp->es_lwrechallenge > 0) { + UNTIMEOUT(srp_lwrechallenge, (void *)esp); + } + } + + esp->es_client.ea_state = esp->es_server.ea_state = eapInitial; + esp->es_client.ea_requests = esp->es_server.ea_requests = 0; +} + +/* + * eap_protrej - Peer doesn't speak this protocol. + * + * This shouldn't happen. If it does, it represents authentication + * failure. + */ +static void +eap_protrej(unit) +int unit; +{ + eap_state *esp = &eap_states[unit]; + + if (eap_client_active(esp)) { + error("EAP authentication failed due to Protocol-Reject"); + auth_withpeer_fail(unit, PPP_EAP); + } + if (eap_server_active(esp)) { + error("EAP authentication of peer failed on Protocol-Reject"); + auth_peer_fail(unit, PPP_EAP); + } + eap_lowerdown(unit); +} + +/* + * Format and send a regular EAP Response message. + */ +static void +eap_send_response(esp, id, typenum, str, lenstr) +eap_state *esp; +u_char id; +u_char typenum; +u_char *str; +int lenstr; +{ + u_char *outp; + int msglen; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + esp->es_client.ea_id = id; + msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; + PUTSHORT(msglen, outp); + PUTCHAR(typenum, outp); + if (lenstr > 0) { + BCOPY(str, outp, lenstr); + } + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); +} + +/* + * Format and send an MD5-Challenge EAP Response message. + */ +static void +eap_chap_response(esp, id, hash, name, namelen) +eap_state *esp; +u_char id; +u_char *hash; +char *name; +int namelen; +{ + u_char *outp; + int msglen; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + esp->es_client.ea_id = id; + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + + namelen; + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_MD5CHAP, outp); + PUTCHAR(MD5_SIGNATURE_SIZE, outp); + BCOPY(hash, outp, MD5_SIGNATURE_SIZE); + INCPTR(MD5_SIGNATURE_SIZE, outp); + if (namelen > 0) { + BCOPY(name, outp, namelen); + } + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); +} + +#ifdef USE_SRP +/* + * Format and send a SRP EAP Response message. + */ +static void +eap_srp_response(esp, id, subtypenum, str, lenstr) +eap_state *esp; +u_char id; +u_char subtypenum; +u_char *str; +int lenstr; +{ + u_char *outp; + int msglen; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + esp->es_client.ea_id = id; + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(subtypenum, outp); + if (lenstr > 0) { + BCOPY(str, outp, lenstr); + } + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); +} + +/* + * Format and send a SRP EAP Client Validator Response message. + */ +static void +eap_srpval_response(esp, id, flags, str) +eap_state *esp; +u_char id; +u_int32_t flags; +u_char *str; +{ + u_char *outp; + int msglen; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + esp->es_client.ea_id = id; + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) + + SHA_DIGESTSIZE; + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_CVALIDATOR, outp); + PUTLONG(flags, outp); + BCOPY(str, outp, SHA_DIGESTSIZE); + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); +} +#endif /* USE_SRP */ + +static void +eap_send_nak(esp, id, type) +eap_state *esp; +u_char id; +u_char type; +{ + u_char *outp; + int msglen; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + esp->es_client.ea_id = id; + msglen = EAP_HEADERLEN + 2 * sizeof (u_char); + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_NAK, outp); + PUTCHAR(type, outp); + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); +} + +#ifdef USE_SRP +static char * +name_of_pn_file() +{ + char *user, *path, *file; + struct passwd *pw; + size_t pl; + static bool pnlogged = 0; + + pw = getpwuid(getuid()); + if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) { + errno = EINVAL; + return (NULL); + } + file = _PATH_PSEUDONYM; + pl = strlen(user) + strlen(file) + 2; + path = malloc(pl); + if (path == NULL) + return (NULL); + (void) slprintf(path, pl, "%s/%s", user, file); + if (!pnlogged) { + dbglog("pseudonym file: %s", path); + pnlogged = 1; + } + return (path); +} + +static int +open_pn_file(modebits) +mode_t modebits; +{ + char *path; + int fd, err; + + if ((path = name_of_pn_file()) == NULL) + return (-1); + fd = open(path, modebits, S_IRUSR | S_IWUSR); + err = errno; + free(path); + errno = err; + return (fd); +} + +static void +remove_pn_file() +{ + char *path; + + if ((path = name_of_pn_file()) != NULL) { + (void) unlink(path); + (void) free(path); + } +} + +static void +write_pseudonym(esp, inp, len, id) +eap_state *esp; +u_char *inp; +int len, id; +{ + u_char val; + u_char *datp, *digp; + SHA1_CTX ctxt; + u_char dig[SHA_DIGESTSIZE]; + int dsize, fd, olen = len; + + /* + * Do the decoding by working backwards. This eliminates the need + * to save the decoded output in a separate buffer. + */ + val = id; + while (len > 0) { + if ((dsize = len % SHA_DIGESTSIZE) == 0) + dsize = SHA_DIGESTSIZE; + len -= dsize; + datp = inp + len; + SHA1Init(&ctxt); + SHA1Update(&ctxt, &val, 1); + SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN); + if (len > 0) { + SHA1Update(&ctxt, datp, SHA_DIGESTSIZE); + } else { + SHA1Update(&ctxt, esp->es_client.ea_name, + esp->es_client.ea_namelen); + } + SHA1Final(dig, &ctxt); + for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++) + *datp++ ^= *digp; + } + + /* Now check that the result is sane */ + if (olen <= 0 || *inp + 1 > olen) { + dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp); + return; + } + + /* Save it away */ + fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC); + if (fd < 0) { + dbglog("EAP: error saving pseudonym: %m"); + return; + } + len = write(fd, inp + 1, *inp); + if (close(fd) != -1 && len == *inp) { + dbglog("EAP: saved pseudonym"); + esp->es_usedpseudo = 0; + } else { + dbglog("EAP: failed to save pseudonym"); + remove_pn_file(); + } +} +#endif /* USE_SRP */ + +/* + * eap_request - Receive EAP Request message (client mode). + */ +static void +eap_request(esp, inp, id, len) +eap_state *esp; +u_char *inp; +int id; +int len; +{ + u_char typenum; + u_char vallen; + int secret_len; + char secret[MAXWORDLEN]; + char rhostname[256]; + MD5_CTX mdContext; + u_char hash[MD5_SIGNATURE_SIZE]; +#ifdef USE_SRP + struct t_client *tc; + struct t_num sval, gval, Nval, *Ap, Bval; + u_char vals[2]; + SHA1_CTX ctxt; + u_char dig[SHA_DIGESTSIZE]; + int fd; +#endif /* USE_SRP */ + + /* + * Note: we update es_client.ea_id *only if* a Response + * message is being generated. Otherwise, we leave it the + * same for duplicate detection purposes. + */ + + esp->es_client.ea_requests++; + if (esp->es_client.ea_maxrequests != 0 && + esp->es_client.ea_requests > esp->es_client.ea_maxrequests) { + info("EAP: received too many Request messages"); + if (esp->es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, (void *)esp); + } + auth_withpeer_fail(esp->es_unit, PPP_EAP); + return; + } + + if (len <= 0) { + error("EAP: empty Request message discarded"); + return; + } + + GETCHAR(typenum, inp); + len--; + + switch (typenum) { + case EAPT_IDENTITY: + if (len > 0) + info("EAP: Identity prompt \"%.*q\"", len, inp); +#ifdef USE_SRP + if (esp->es_usepseudo && + (esp->es_usedpseudo == 0 || + (esp->es_usedpseudo == 1 && + id == esp->es_client.ea_id))) { + esp->es_usedpseudo = 1; + /* Try to get a pseudonym */ + if ((fd = open_pn_file(O_RDONLY)) >= 0) { + strcpy(rhostname, SRP_PSEUDO_ID); + len = read(fd, rhostname + SRP_PSEUDO_LEN, + sizeof (rhostname) - SRP_PSEUDO_LEN); + /* XXX NAI unsupported */ + if (len > 0) { + eap_send_response(esp, id, typenum, + rhostname, len + SRP_PSEUDO_LEN); + } + (void) close(fd); + if (len > 0) + break; + } + } + /* Stop using pseudonym now. */ + if (esp->es_usepseudo && esp->es_usedpseudo != 2) { + remove_pn_file(); + esp->es_usedpseudo = 2; + } +#endif /* USE_SRP */ + eap_send_response(esp, id, typenum, esp->es_client.ea_name, + esp->es_client.ea_namelen); + break; + + case EAPT_NOTIFICATION: + if (len > 0) + info("EAP: Notification \"%.*q\"", len, inp); + eap_send_response(esp, id, typenum, NULL, 0); + break; + + case EAPT_NAK: + /* + * Avoid the temptation to send Response Nak in reply + * to Request Nak here. It can only lead to trouble. + */ + warn("EAP: unexpected Nak in Request; ignored"); + /* Return because we're waiting for something real. */ + return; + + case EAPT_MD5CHAP: + if (len < 1) { + error("EAP: received MD5-Challenge with no data"); + /* Bogus request; wait for something real. */ + return; + } + GETCHAR(vallen, inp); + len--; + if (vallen < 8 || vallen > len) { + error("EAP: MD5-Challenge with bad length %d (8..%d)", + vallen, len); + /* Try something better. */ + eap_send_nak(esp, id, EAPT_SRP); + break; + } + + /* Not so likely to happen. */ + if (vallen >= len + sizeof (rhostname)) { + dbglog("EAP: trimming really long peer name down"); + BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); + rhostname[sizeof (rhostname) - 1] = '\0'; + } else { + BCOPY(inp + vallen, rhostname, len - vallen); + rhostname[len - vallen] = '\0'; + } + + /* In case the remote doesn't give us his name. */ + if (explicit_remote || + (remote_name[0] != '\0' && vallen == len)) + strlcpy(rhostname, remote_name, sizeof (rhostname)); + + /* + * Get the secret for authenticating ourselves with + * the specified host. + */ + if (!get_secret(esp->es_unit, esp->es_client.ea_name, + rhostname, secret, &secret_len, 0)) { + dbglog("EAP: no MD5 secret for auth to %q", rhostname); + eap_send_nak(esp, id, EAPT_SRP); + break; + } + MD5_Init(&mdContext); + typenum = id; + MD5_Update(&mdContext, &typenum, 1); + MD5_Update(&mdContext, (u_char *)secret, secret_len); + BZERO(secret, sizeof (secret)); + MD5_Update(&mdContext, inp, vallen); + MD5_Final(hash, &mdContext); + eap_chap_response(esp, id, hash, esp->es_client.ea_name, + esp->es_client.ea_namelen); + break; + +#ifdef USE_SRP + case EAPT_SRP: + if (len < 1) { + error("EAP: received empty SRP Request"); + /* Bogus request; wait for something real. */ + return; + } + + /* Get subtype */ + GETCHAR(vallen, inp); + len--; + switch (vallen) { + case EAPSRP_CHALLENGE: + tc = NULL; + if (esp->es_client.ea_session != NULL) { + tc = (struct t_client *)esp->es_client. + ea_session; + /* + * If this is a new challenge, then start + * over with a new client session context. + * Otherwise, just resend last response. + */ + if (id != esp->es_client.ea_id) { + t_clientclose(tc); + esp->es_client.ea_session = NULL; + tc = NULL; + } + } + /* No session key just yet */ + esp->es_client.ea_skey = NULL; + if (tc == NULL) { + GETCHAR(vallen, inp); + len--; + if (vallen >= len) { + error("EAP: badly-formed SRP Challenge" + " (name)"); + /* Ignore badly-formed messages */ + return; + } + BCOPY(inp, rhostname, vallen); + rhostname[vallen] = '\0'; + INCPTR(vallen, inp); + len -= vallen; + + /* + * In case the remote doesn't give us his name, + * use configured name. + */ + if (explicit_remote || + (remote_name[0] != '\0' && vallen == 0)) { + strlcpy(rhostname, remote_name, + sizeof (rhostname)); + } + + if (esp->es_client.ea_peer != NULL) + free(esp->es_client.ea_peer); + esp->es_client.ea_peer = strdup(rhostname); + esp->es_client.ea_peerlen = strlen(rhostname); + + GETCHAR(vallen, inp); + len--; + if (vallen >= len) { + error("EAP: badly-formed SRP Challenge" + " (s)"); + /* Ignore badly-formed messages */ + return; + } + sval.data = inp; + sval.len = vallen; + INCPTR(vallen, inp); + len -= vallen; + + GETCHAR(vallen, inp); + len--; + if (vallen > len) { + error("EAP: badly-formed SRP Challenge" + " (g)"); + /* Ignore badly-formed messages */ + return; + } + /* If no generator present, then use value 2 */ + if (vallen == 0) { + gval.data = (u_char *)"\002"; + gval.len = 1; + } else { + gval.data = inp; + gval.len = vallen; + } + INCPTR(vallen, inp); + len -= vallen; + + /* + * If no modulus present, then use well-known + * value. + */ + if (len == 0) { + Nval.data = (u_char *)wkmodulus; + Nval.len = sizeof (wkmodulus); + } else { + Nval.data = inp; + Nval.len = len; + } + tc = t_clientopen(esp->es_client.ea_name, + &Nval, &gval, &sval); + if (tc == NULL) { + eap_send_nak(esp, id, EAPT_MD5CHAP); + break; + } + esp->es_client.ea_session = (void *)tc; + + /* Add Challenge ID & type to verifier */ + vals[0] = id; + vals[1] = EAPT_SRP; + t_clientaddexdata(tc, vals, 2); + } + Ap = t_clientgenexp(tc); + eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data, + Ap->len); + break; + + case EAPSRP_SKEY: + tc = (struct t_client *)esp->es_client.ea_session; + if (tc == NULL) { + warn("EAP: peer sent Subtype 2 without 1"); + eap_send_nak(esp, id, EAPT_MD5CHAP); + break; + } + if (esp->es_client.ea_skey != NULL) { + /* + * ID number should not change here. Warn + * if it does (but otherwise ignore). + */ + if (id != esp->es_client.ea_id) { + warn("EAP: ID changed from %d to %d " + "in SRP Subtype 2 rexmit", + esp->es_client.ea_id, id); + } + } else { + if (get_srp_secret(esp->es_unit, + esp->es_client.ea_name, + esp->es_client.ea_peer, secret, 0) == 0) { + /* + * Can't work with this peer because + * the secret is missing. Just give + * up. + */ + eap_send_nak(esp, id, EAPT_MD5CHAP); + break; + } + Bval.data = inp; + Bval.len = len; + t_clientpasswd(tc, secret); + BZERO(secret, sizeof (secret)); + esp->es_client.ea_skey = + t_clientgetkey(tc, &Bval); + if (esp->es_client.ea_skey == NULL) { + /* Server is rogue; stop now */ + error("EAP: SRP server is rogue"); + goto client_failure; + } + } + eap_srpval_response(esp, id, SRPVAL_EBIT, + t_clientresponse(tc)); + break; + + case EAPSRP_SVALIDATOR: + tc = (struct t_client *)esp->es_client.ea_session; + if (tc == NULL || esp->es_client.ea_skey == NULL) { + warn("EAP: peer sent Subtype 3 without 1/2"); + eap_send_nak(esp, id, EAPT_MD5CHAP); + break; + } + /* + * If we're already open, then this ought to be a + * duplicate. Otherwise, check that the server is + * who we think it is. + */ + if (esp->es_client.ea_state == eapOpen) { + if (id != esp->es_client.ea_id) { + warn("EAP: ID changed from %d to %d " + "in SRP Subtype 3 rexmit", + esp->es_client.ea_id, id); + } + } else { + len -= sizeof (u_int32_t) + SHA_DIGESTSIZE; + if (len < 0 || t_clientverify(tc, inp + + sizeof (u_int32_t)) != 0) { + error("EAP: SRP server verification " + "failed"); + goto client_failure; + } + GETLONG(esp->es_client.ea_keyflags, inp); + /* Save pseudonym if user wants it. */ + if (len > 0 && esp->es_usepseudo) { + INCPTR(SHA_DIGESTSIZE, inp); + write_pseudonym(esp, inp, len, id); + } + } + /* + * We've verified our peer. We're now mostly done, + * except for waiting on the regular EAP Success + * message. + */ + eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0); + break; + + case EAPSRP_LWRECHALLENGE: + if (len < 4) { + warn("EAP: malformed Lightweight rechallenge"); + return; + } + SHA1Init(&ctxt); + vals[0] = id; + SHA1Update(&ctxt, vals, 1); + SHA1Update(&ctxt, esp->es_client.ea_skey, + SESSION_KEY_LEN); + SHA1Update(&ctxt, inp, len); + SHA1Update(&ctxt, esp->es_client.ea_name, + esp->es_client.ea_namelen); + SHA1Final(dig, &ctxt); + eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig, + SHA_DIGESTSIZE); + break; + + default: + error("EAP: unknown SRP Subtype %d", vallen); + eap_send_nak(esp, id, EAPT_MD5CHAP); + break; + } + break; +#endif /* USE_SRP */ + + default: + info("EAP: unknown authentication type %d; Naking", typenum); + eap_send_nak(esp, id, EAPT_SRP); + break; + } + + if (esp->es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, (void *)esp); + TIMEOUT(eap_client_timeout, (void *)esp, + esp->es_client.ea_timeout); + } + return; + +#ifdef USE_SRP +client_failure: + esp->es_client.ea_state = eapBadAuth; + if (esp->es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, (void *)esp); + } + esp->es_client.ea_session = NULL; + t_clientclose(tc); + auth_withpeer_fail(esp->es_unit, PPP_EAP); +#endif /* USE_SRP */ +} + +/* + * eap_response - Receive EAP Response message (server mode). + */ +static void +eap_response(esp, inp, id, len) +eap_state *esp; +u_char *inp; +int id; +int len; +{ + u_char typenum; + u_char vallen; + int secret_len; + char secret[MAXSECRETLEN]; + char rhostname[256]; + MD5_CTX mdContext; + u_char hash[MD5_SIGNATURE_SIZE]; +#ifdef USE_SRP + struct t_server *ts; + struct t_num A; + SHA1_CTX ctxt; + u_char dig[SHA_DIGESTSIZE]; +#endif /* USE_SRP */ + + if (esp->es_server.ea_id != id) { + dbglog("EAP: discarding Response %d; expected ID %d", id, + esp->es_server.ea_id); + return; + } + + esp->es_server.ea_responses++; + + if (len <= 0) { + error("EAP: empty Response message discarded"); + return; + } + + GETCHAR(typenum, inp); + len--; + + switch (typenum) { + case EAPT_IDENTITY: + if (esp->es_server.ea_state != eapIdentify) { + dbglog("EAP discarding unwanted Identify \"%.q\"", len, + inp); + break; + } + info("EAP: unauthenticated peer name \"%.*q\"", len, inp); + if (esp->es_server.ea_peer != NULL && + esp->es_server.ea_peer != remote_name) + free(esp->es_server.ea_peer); + esp->es_server.ea_peer = malloc(len + 1); + if (esp->es_server.ea_peer == NULL) { + esp->es_server.ea_peerlen = 0; + eap_figure_next_state(esp, 1); + break; + } + BCOPY(inp, esp->es_server.ea_peer, len); + esp->es_server.ea_peer[len] = '\0'; + esp->es_server.ea_peerlen = len; + eap_figure_next_state(esp, 0); + break; + + case EAPT_NOTIFICATION: + dbglog("EAP unexpected Notification; response discarded"); + break; + + case EAPT_NAK: + if (len < 1) { + info("EAP: Nak Response with no suggested protocol"); + eap_figure_next_state(esp, 1); + break; + } + + GETCHAR(vallen, inp); + len--; + + if (!explicit_remote && esp->es_server.ea_state == eapIdentify){ + /* Peer cannot Nak Identify Request */ + eap_figure_next_state(esp, 1); + break; + } + + switch (vallen) { + case EAPT_SRP: + /* Run through SRP validator selection again. */ + esp->es_server.ea_state = eapIdentify; + eap_figure_next_state(esp, 0); + break; + + case EAPT_MD5CHAP: + esp->es_server.ea_state = eapMD5Chall; + break; + + default: + dbglog("EAP: peer requesting unknown Type %d", vallen); + switch (esp->es_server.ea_state) { + case eapSRP1: + case eapSRP2: + case eapSRP3: + esp->es_server.ea_state = eapMD5Chall; + break; + case eapMD5Chall: + case eapSRP4: + esp->es_server.ea_state = eapIdentify; + eap_figure_next_state(esp, 0); + break; + default: + break; + } + break; + } + break; + + case EAPT_MD5CHAP: + if (esp->es_server.ea_state != eapMD5Chall) { + error("EAP: unexpected MD5-Response"); + eap_figure_next_state(esp, 1); + break; + } + if (len < 1) { + error("EAP: received MD5-Response with no data"); + eap_figure_next_state(esp, 1); + break; + } + GETCHAR(vallen, inp); + len--; + if (vallen != 16 || vallen > len) { + error("EAP: MD5-Response with bad length %d", vallen); + eap_figure_next_state(esp, 1); + break; + } + + /* Not so likely to happen. */ + if (vallen >= len + sizeof (rhostname)) { + dbglog("EAP: trimming really long peer name down"); + BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); + rhostname[sizeof (rhostname) - 1] = '\0'; + } else { + BCOPY(inp + vallen, rhostname, len - vallen); + rhostname[len - vallen] = '\0'; + } + + /* In case the remote doesn't give us his name. */ + if (explicit_remote || + (remote_name[0] != '\0' && vallen == len)) + strlcpy(rhostname, remote_name, sizeof (rhostname)); + + /* + * Get the secret for authenticating the specified + * host. + */ + if (!get_secret(esp->es_unit, rhostname, + esp->es_server.ea_name, secret, &secret_len, 1)) { + dbglog("EAP: no MD5 secret for auth of %q", rhostname); + eap_send_failure(esp); + break; + } + MD5_Init(&mdContext); + MD5_Update(&mdContext, &esp->es_server.ea_id, 1); + MD5_Update(&mdContext, (u_char *)secret, secret_len); + BZERO(secret, sizeof (secret)); + MD5_Update(&mdContext, esp->es_challenge, esp->es_challen); + MD5_Final(hash, &mdContext); + if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { + eap_send_failure(esp); + break; + } + esp->es_server.ea_type = EAPT_MD5CHAP; + eap_send_success(esp); + eap_figure_next_state(esp, 0); + if (esp->es_rechallenge != 0) + TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge); + break; + +#ifdef USE_SRP + case EAPT_SRP: + if (len < 1) { + error("EAP: empty SRP Response"); + eap_figure_next_state(esp, 1); + break; + } + GETCHAR(typenum, inp); + len--; + switch (typenum) { + case EAPSRP_CKEY: + if (esp->es_server.ea_state != eapSRP1) { + error("EAP: unexpected SRP Subtype 1 Response"); + eap_figure_next_state(esp, 1); + break; + } + A.data = inp; + A.len = len; + ts = (struct t_server *)esp->es_server.ea_session; + assert(ts != NULL); + esp->es_server.ea_skey = t_servergetkey(ts, &A); + if (esp->es_server.ea_skey == NULL) { + /* Client's A value is bogus; terminate now */ + error("EAP: bogus A value from client"); + eap_send_failure(esp); + } else { + eap_figure_next_state(esp, 0); + } + break; + + case EAPSRP_CVALIDATOR: + if (esp->es_server.ea_state != eapSRP2) { + error("EAP: unexpected SRP Subtype 2 Response"); + eap_figure_next_state(esp, 1); + break; + } + if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) { + error("EAP: M1 length %d < %d", len, + sizeof (u_int32_t) + SHA_DIGESTSIZE); + eap_figure_next_state(esp, 1); + break; + } + GETLONG(esp->es_server.ea_keyflags, inp); + ts = (struct t_server *)esp->es_server.ea_session; + assert(ts != NULL); + if (t_serververify(ts, inp)) { + info("EAP: unable to validate client identity"); + eap_send_failure(esp); + break; + } + eap_figure_next_state(esp, 0); + break; + + case EAPSRP_ACK: + if (esp->es_server.ea_state != eapSRP3) { + error("EAP: unexpected SRP Subtype 3 Response"); + eap_send_failure(esp); + break; + } + esp->es_server.ea_type = EAPT_SRP; + eap_send_success(esp); + eap_figure_next_state(esp, 0); + if (esp->es_rechallenge != 0) + TIMEOUT(eap_rechallenge, esp, + esp->es_rechallenge); + if (esp->es_lwrechallenge != 0) + TIMEOUT(srp_lwrechallenge, esp, + esp->es_lwrechallenge); + break; + + case EAPSRP_LWRECHALLENGE: + if (esp->es_server.ea_state != eapSRP4) { + info("EAP: unexpected SRP Subtype 4 Response"); + return; + } + if (len != SHA_DIGESTSIZE) { + error("EAP: bad Lightweight rechallenge " + "response"); + return; + } + SHA1Init(&ctxt); + vallen = id; + SHA1Update(&ctxt, &vallen, 1); + SHA1Update(&ctxt, esp->es_server.ea_skey, + SESSION_KEY_LEN); + SHA1Update(&ctxt, esp->es_challenge, esp->es_challen); + SHA1Update(&ctxt, esp->es_server.ea_peer, + esp->es_server.ea_peerlen); + SHA1Final(dig, &ctxt); + if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { + error("EAP: failed Lightweight rechallenge"); + eap_send_failure(esp); + break; + } + esp->es_server.ea_state = eapOpen; + if (esp->es_lwrechallenge != 0) + TIMEOUT(srp_lwrechallenge, esp, + esp->es_lwrechallenge); + break; + } + break; +#endif /* USE_SRP */ + + default: + /* This can't happen. */ + error("EAP: unknown Response type %d; ignored", typenum); + return; + } + + if (esp->es_server.ea_timeout > 0) { + UNTIMEOUT(eap_server_timeout, (void *)esp); + } + + if (esp->es_server.ea_state != eapBadAuth && + esp->es_server.ea_state != eapOpen) { + esp->es_server.ea_id++; + eap_send_request(esp); + } +} + +/* + * eap_success - Receive EAP Success message (client mode). + */ +static void +eap_success(esp, inp, id, len) +eap_state *esp; +u_char *inp; +int id; +int len; +{ + if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) { + dbglog("EAP unexpected success message in state %s (%d)", + eap_state_name(esp->es_client.ea_state), + esp->es_client.ea_state); + return; + } + + if (esp->es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, (void *)esp); + } + + if (len > 0) { + /* This is odd. The spec doesn't allow for this. */ + PRINTMSG(inp, len); + } + + esp->es_client.ea_state = eapOpen; + auth_withpeer_success(esp->es_unit, PPP_EAP, 0); +} + +/* + * eap_failure - Receive EAP Failure message (client mode). + */ +static void +eap_failure(esp, inp, id, len) +eap_state *esp; +u_char *inp; +int id; +int len; +{ + if (!eap_client_active(esp)) { + dbglog("EAP unexpected failure message in state %s (%d)", + eap_state_name(esp->es_client.ea_state), + esp->es_client.ea_state); + } + + if (esp->es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, (void *)esp); + } + + if (len > 0) { + /* This is odd. The spec doesn't allow for this. */ + PRINTMSG(inp, len); + } + + esp->es_client.ea_state = eapBadAuth; + + error("EAP: peer reports authentication failure"); + auth_withpeer_fail(esp->es_unit, PPP_EAP); +} + +/* + * eap_input - Handle received EAP message. + */ +static void +eap_input(unit, inp, inlen) +int unit; +u_char *inp; +int inlen; +{ + eap_state *esp = &eap_states[unit]; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). If packet too short, + * drop it. + */ + if (inlen < EAP_HEADERLEN) { + error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < EAP_HEADERLEN || len > inlen) { + error("EAP: packet has illegal length field %d (%d..%d)", len, + EAP_HEADERLEN, inlen); + return; + } + len -= EAP_HEADERLEN; + + /* Dispatch based on message code */ + switch (code) { + case EAP_REQUEST: + eap_request(esp, inp, id, len); + break; + + case EAP_RESPONSE: + eap_response(esp, inp, id, len); + break; + + case EAP_SUCCESS: + eap_success(esp, inp, id, len); + break; + + case EAP_FAILURE: + eap_failure(esp, inp, id, len); + break; + + default: /* XXX Need code reject */ + /* Note: it's not legal to send EAP Nak here. */ + warn("EAP: unknown code %d received", code); + break; + } +} + +/* + * eap_printpkt - print the contents of an EAP packet. + */ +static char *eap_codenames[] = { + "Request", "Response", "Success", "Failure" +}; + +static char *eap_typenames[] = { + "Identity", "Notification", "Nak", "MD5-Challenge", + "OTP", "Generic-Token", NULL, NULL, + "RSA", "DSS", "KEA", "KEA-Validate", + "TLS", "Defender", "Windows 2000", "Arcot", + "Cisco", "Nokia", "SRP" +}; + +static int +eap_printpkt(inp, inlen, printer, arg) +u_char *inp; +int inlen; +void (*printer) __P((void *, char *, ...)); +void *arg; +{ + int code, id, len, rtype, vallen; + u_char *pstart; + u_int32_t uval; + + if (inlen < EAP_HEADERLEN) + return (0); + pstart = inp; + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < EAP_HEADERLEN || len > inlen) + return (0); + + if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *)) + printer(arg, " %s", eap_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= EAP_HEADERLEN; + switch (code) { + case EAP_REQUEST: + if (len < 1) { + printer(arg, " "); + break; + } + GETCHAR(rtype, inp); + len--; + if (rtype >= 1 && + rtype <= sizeof (eap_typenames) / sizeof (char *)) + printer(arg, " %s", eap_typenames[rtype-1]); + else + printer(arg, " type=0x%x", rtype); + switch (rtype) { + case EAPT_IDENTITY: + case EAPT_NOTIFICATION: + if (len > 0) { + printer(arg, " "); + INCPTR(len, inp); + len = 0; + } else { + printer(arg, " "); + } + break; + + case EAPT_MD5CHAP: + if (len <= 0) + break; + GETCHAR(vallen, inp); + len--; + if (vallen > len) + goto truncated; + printer(arg, " ", vallen, inp); + INCPTR(vallen, inp); + len -= vallen; + if (len > 0) { + printer(arg, " "); + INCPTR(len, inp); + len = 0; + } else { + printer(arg, " "); + } + break; + + case EAPT_SRP: + if (len < 3) + goto truncated; + GETCHAR(vallen, inp); + len--; + printer(arg, "-%d", vallen); + switch (vallen) { + case EAPSRP_CHALLENGE: + GETCHAR(vallen, inp); + len--; + if (vallen >= len) + goto truncated; + if (vallen > 0) { + printer(arg, " "); + } else { + printer(arg, " "); + } + INCPTR(vallen, inp); + len -= vallen; + GETCHAR(vallen, inp); + len--; + if (vallen >= len) + goto truncated; + printer(arg, " ", vallen, inp); + INCPTR(vallen, inp); + len -= vallen; + GETCHAR(vallen, inp); + len--; + if (vallen > len) + goto truncated; + if (vallen == 0) { + printer(arg, " "); + } else { + printer(arg, " ", vallen, inp); + } + INCPTR(vallen, inp); + len -= vallen; + if (len == 0) { + printer(arg, " "); + } else { + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + } + break; + + case EAPSRP_SKEY: + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + break; + + case EAPSRP_SVALIDATOR: + if (len < sizeof (u_int32_t)) + break; + GETLONG(uval, inp); + len -= sizeof (u_int32_t); + if (uval & SRPVAL_EBIT) { + printer(arg, " E"); + uval &= ~SRPVAL_EBIT; + } + if (uval != 0) { + printer(arg, " f<%X>", uval); + } + if ((vallen = len) > SHA_DIGESTSIZE) + vallen = SHA_DIGESTSIZE; + printer(arg, " ", len, inp, + len < SHA_DIGESTSIZE ? "?" : ""); + INCPTR(vallen, inp); + len -= vallen; + if (len > 0) { + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + } + break; + + case EAPSRP_LWRECHALLENGE: + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + break; + } + break; + } + break; + + case EAP_RESPONSE: + if (len < 1) + break; + GETCHAR(rtype, inp); + len--; + if (rtype >= 1 && + rtype <= sizeof (eap_typenames) / sizeof (char *)) + printer(arg, " %s", eap_typenames[rtype-1]); + else + printer(arg, " type=0x%x", rtype); + switch (rtype) { + case EAPT_IDENTITY: + if (len > 0) { + printer(arg, " "); + INCPTR(len, inp); + len = 0; + } + break; + + case EAPT_NAK: + if (len <= 0) { + printer(arg, " "); + break; + } + GETCHAR(rtype, inp); + len--; + printer(arg, " = 1 && + rtype < sizeof (eap_typenames) / sizeof (char *)) + printer(arg, " (%s)", eap_typenames[rtype-1]); + printer(arg, ">"); + break; + + case EAPT_MD5CHAP: + if (len <= 0) { + printer(arg, " "); + break; + } + GETCHAR(vallen, inp); + len--; + if (vallen > len) + goto truncated; + printer(arg, " ", vallen, inp); + INCPTR(vallen, inp); + len -= vallen; + if (len > 0) { + printer(arg, " "); + INCPTR(len, inp); + len = 0; + } else { + printer(arg, " "); + } + break; + + case EAPT_SRP: + if (len < 1) + goto truncated; + GETCHAR(vallen, inp); + len--; + printer(arg, "-%d", vallen); + switch (vallen) { + case EAPSRP_CKEY: + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + break; + + case EAPSRP_CVALIDATOR: + if (len < sizeof (u_int32_t)) + break; + GETLONG(uval, inp); + len -= sizeof (u_int32_t); + if (uval & SRPVAL_EBIT) { + printer(arg, " E"); + uval &= ~SRPVAL_EBIT; + } + if (uval != 0) { + printer(arg, " f<%X>", uval); + } + printer(arg, " ", len, inp, + len == SHA_DIGESTSIZE ? "" : "?"); + INCPTR(len, inp); + len = 0; + break; + + case EAPSRP_ACK: + break; + + case EAPSRP_LWRECHALLENGE: + printer(arg, " ", len, inp, + len == SHA_DIGESTSIZE ? "" : "?"); + if ((vallen = len) > SHA_DIGESTSIZE) + vallen = SHA_DIGESTSIZE; + INCPTR(vallen, inp); + len -= vallen; + break; + } + break; + } + break; + + case EAP_SUCCESS: /* No payload expected for these! */ + case EAP_FAILURE: + break; + + truncated: + printer(arg, " "); + break; + } + + if (len > 8) + printer(arg, "%8B...", inp); + else if (len > 0) + printer(arg, "%.*B", len, inp); + INCPTR(len, inp); + + return (inp - pstart); +} diff --git a/src/netif/ppp/eap.h b/src/netif/ppp/eap.h new file mode 100644 index 00000000..199d1849 --- /dev/null +++ b/src/netif/ppp/eap.h @@ -0,0 +1,158 @@ +/* + * eap.h - Extensible Authentication Protocol for PPP (RFC 2284) + * + * Copyright (c) 2001 by Sun Microsystems, Inc. + * All rights reserved. + * + * Non-exclusive rights to redistribute, modify, translate, and use + * this software in source and binary forms, in whole or in part, is + * hereby granted, provided that the above copyright notice is + * duplicated in any source form, and that neither the name of the + * copyright holder nor the author is used to endorse or promote + * products derived from this software. + * + * 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. + * + * Original version by James Carlson + * + * $Id: eap.h,v 1.2 2003/06/11 23:56:26 paulus Exp $ + */ + +#ifndef PPP_EAP_H +#define PPP_EAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Packet header = Code, id, length. + */ +#define EAP_HEADERLEN 4 + + +/* EAP message codes. */ +#define EAP_REQUEST 1 +#define EAP_RESPONSE 2 +#define EAP_SUCCESS 3 +#define EAP_FAILURE 4 + +/* EAP types */ +#define EAPT_IDENTITY 1 +#define EAPT_NOTIFICATION 2 +#define EAPT_NAK 3 /* (response only) */ +#define EAPT_MD5CHAP 4 +#define EAPT_OTP 5 /* One-Time Password; RFC 1938 */ +#define EAPT_TOKEN 6 /* Generic Token Card */ +/* 7 and 8 are unassigned. */ +#define EAPT_RSA 9 /* RSA Public Key Authentication */ +#define EAPT_DSS 10 /* DSS Unilateral */ +#define EAPT_KEA 11 /* KEA */ +#define EAPT_KEA_VALIDATE 12 /* KEA-VALIDATE */ +#define EAPT_TLS 13 /* EAP-TLS */ +#define EAPT_DEFENDER 14 /* Defender Token (AXENT) */ +#define EAPT_W2K 15 /* Windows 2000 EAP */ +#define EAPT_ARCOT 16 /* Arcot Systems */ +#define EAPT_CISCOWIRELESS 17 /* Cisco Wireless */ +#define EAPT_NOKIACARD 18 /* Nokia IP smart card */ +#define EAPT_SRP 19 /* Secure Remote Password */ +/* 20 is deprecated */ + +/* EAP SRP-SHA1 Subtypes */ +#define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */ +#define EAPSRP_CKEY 1 /* Response 1 - Client Key */ +#define EAPSRP_SKEY 2 /* Request 2 - Server Key */ +#define EAPSRP_CVALIDATOR 2 /* Response 2 - Client Validator */ +#define EAPSRP_SVALIDATOR 3 /* Request 3 - Server Validator */ +#define EAPSRP_ACK 3 /* Response 3 - final ack */ +#define EAPSRP_LWRECHALLENGE 4 /* Req/resp 4 - Lightweight rechal */ + +#define SRPVAL_EBIT 0x00000001 /* Use shared key for ECP */ + +#define SRP_PSEUDO_ID "pseudo_" +#define SRP_PSEUDO_LEN 7 + +#define MD5_SIGNATURE_SIZE 16 +#define MIN_CHALLENGE_LENGTH 16 +#define MAX_CHALLENGE_LENGTH 24 + +enum eap_state_code { + eapInitial = 0, /* No EAP authentication yet requested */ + eapPending, /* Waiting for LCP (no timer) */ + eapClosed, /* Authentication not in use */ + eapListen, /* Client ready (and timer running) */ + eapIdentify, /* EAP Identify sent */ + eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ + eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ + eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ + eapMD5Chall, /* Sent MD5-Challenge */ + eapOpen, /* Completed authentication */ + eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ + eapBadAuth /* Failed authentication */ +}; + +#define EAP_STATES \ + "Initial", "Pending", "Closed", "Listen", "Identify", \ + "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" + +#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) +#define eap_server_active(esp) \ + ((esp)->es_server.ea_state >= eapIdentify && \ + (esp)->es_server.ea_state <= eapMD5Chall) + +struct eap_auth { + char *ea_name; /* Our name */ + char *ea_peer; /* Peer's name */ + void *ea_session; /* Authentication library linkage */ + u_char *ea_skey; /* Shared encryption key */ + int ea_timeout; /* Time to wait (for retransmit/fail) */ + int ea_maxrequests; /* Max Requests allowed */ + u_short ea_namelen; /* Length of our name */ + u_short ea_peerlen; /* Length of peer's name */ + enum eap_state_code ea_state; + u_char ea_id; /* Current id */ + u_char ea_requests; /* Number of Requests sent/received */ + u_char ea_responses; /* Number of Responses */ + u_char ea_type; /* One of EAPT_* */ + u_int32_t ea_keyflags; /* SRP shared key usage flags */ +}; + +/* + * Complete EAP state for one PPP session. + */ +typedef struct eap_state { + int es_unit; /* Interface unit number */ + struct eap_auth es_client; /* Client (authenticatee) data */ + struct eap_auth es_server; /* Server (authenticator) data */ + int es_savedtime; /* Saved timeout */ + int es_rechallenge; /* EAP rechallenge interval */ + int es_lwrechallenge; /* SRP lightweight rechallenge inter */ + bool es_usepseudo; /* Use SRP Pseudonym if offered one */ + int es_usedpseudo; /* Set if we already sent PN */ + int es_challen; /* Length of challenge string */ + u_char es_challenge[MAX_CHALLENGE_LENGTH]; +} eap_state; + +/* + * Timeouts. + */ +#define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ +#define EAP_DEFTRANSMITS 10 /* max # times to transmit */ +#define EAP_DEFREQTIME 20 /* Time to wait for peer request */ +#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ + +extern eap_state eap_states[]; + +void eap_authwithpeer __P((int unit, char *localname)); +void eap_authpeer __P((int unit, char *localname)); + +extern struct protent eap_protent; + +#ifdef __cplusplus +} +#endif + +#endif /* PPP_EAP_H */ + diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c new file mode 100644 index 00000000..8f6bc502 --- /dev/null +++ b/src/netif/ppp/ecp.c @@ -0,0 +1,175 @@ +/* + * ecp.c - PPP Encryption Control Protocol. + * + * Copyright (c) 2002 Google, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Derived from ccp.c, which is: + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $" + +static const char rcsid[] = RCSID; + +#include + +#include "pppd.h" +#include "fsm.h" +#include "ecp.h" + +static option_t ecp_option_list[] = { + { "noecp", o_bool, &ecp_protent.enabled_flag, + "Disable ECP negotiation" }, + { "-ecp", o_bool, &ecp_protent.enabled_flag, + "Disable ECP negotiation", OPT_ALIAS }, + + { NULL } +}; + +/* + * Protocol entry points from main code. + */ +static void ecp_init __P((int unit)); +/* +static void ecp_open __P((int unit)); +static void ecp_close __P((int unit, char *)); +static void ecp_lowerup __P((int unit)); +static void ecp_lowerdown __P((int)); +static void ecp_input __P((int unit, u_char *pkt, int len)); +static void ecp_protrej __P((int unit)); +*/ +static int ecp_printpkt __P((u_char *pkt, int len, + void (*printer) __P((void *, char *, ...)), + void *arg)); +/* +static void ecp_datainput __P((int unit, u_char *pkt, int len)); +*/ + +struct protent ecp_protent = { + PPP_ECP, + ecp_init, + NULL, /* ecp_input, */ + NULL, /* ecp_protrej, */ + NULL, /* ecp_lowerup, */ + NULL, /* ecp_lowerdown, */ + NULL, /* ecp_open, */ + NULL, /* ecp_close, */ + ecp_printpkt, + NULL, /* ecp_datainput, */ + 0, + "ECP", + "Encrypted", + ecp_option_list, + NULL, + NULL, + NULL +}; + +fsm ecp_fsm[NUM_PPP]; +ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */ +ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ +ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */ +ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */ + +static fsm_callbacks ecp_callbacks = { + NULL, /* ecp_resetci, */ + NULL, /* ecp_cilen, */ + NULL, /* ecp_addci, */ + NULL, /* ecp_ackci, */ + NULL, /* ecp_nakci, */ + NULL, /* ecp_rejci, */ + NULL, /* ecp_reqci, */ + NULL, /* ecp_up, */ + NULL, /* ecp_down, */ + NULL, + NULL, + NULL, + NULL, + NULL, /* ecp_extcode, */ + "ECP" +}; + +/* + * ecp_init - initialize ECP. + */ +static void +ecp_init(unit) + int unit; +{ + fsm *f = &ecp_fsm[unit]; + + f->unit = unit; + f->protocol = PPP_ECP; + f->callbacks = &ecp_callbacks; + fsm_init(f); + + memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options)); + +} + + +static int +ecp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + return 0; +} + diff --git a/src/netif/ppp/ecp.h b/src/netif/ppp/ecp.h new file mode 100644 index 00000000..df6e3ca1 --- /dev/null +++ b/src/netif/ppp/ecp.h @@ -0,0 +1,45 @@ +/* + * ecp.h - Definitions for PPP Encryption Control Protocol. + * + * Copyright (c) 2002 Google, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ + */ + +typedef struct ecp_options { + bool required; /* Is ECP required? */ + unsigned enctype; /* Encryption type */ +} ecp_options; + +extern fsm ecp_fsm[]; +extern ecp_options ecp_wantoptions[]; +extern ecp_options ecp_gotoptions[]; +extern ecp_options ecp_allowoptions[]; +extern ecp_options ecp_hisoptions[]; + +extern struct protent ecp_protent; diff --git a/src/netif/ppp/eui64.h b/src/netif/ppp/eui64.h new file mode 100644 index 00000000..0f6b6fd4 --- /dev/null +++ b/src/netif/ppp/eui64.h @@ -0,0 +1,114 @@ +/* + * eui64.h - EUI64 routines for IPv6CP. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $ +*/ + +#ifndef __EUI64_H__ +#define __EUI64_H__ + +#if !defined(INET6) +#error "this file should only be included when INET6 is defined" +#endif /* not defined(INET6) */ + +#if defined(SOL2) +#include + +typedef union { + uint8_t e8[8]; /* lower 64-bit IPv6 address */ + uint32_t e32[2]; /* lower 64-bit IPv6 address */ +} eui64_t; + +/* + * Declare the two below, since in.h only defines them when _KERNEL + * is declared - which shouldn't be true when dealing with user-land programs + */ +#define s6_addr8 _S6_un._S6_u8 +#define s6_addr32 _S6_un._S6_u32 + +#else /* else if not defined(SOL2) */ + +/* + * TODO: + * + * Maybe this should be done by processing struct in6_addr directly... + */ +typedef union +{ + u_int8_t e8[8]; + u_int16_t e16[4]; + u_int32_t e32[2]; +} eui64_t; + +#endif /* defined(SOL2) */ + +#define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) +#define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ + ((e).e32[1] == (o).e32[1])) +#define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; + +#define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) + +#define eui64_magic(e) do { \ + (e).e32[0] = magic(); \ + (e).e32[1] = magic(); \ + (e).e8[0] &= ~2; \ + } while (0) +#define eui64_magic_nz(x) do { \ + eui64_magic(x); \ + } while (eui64_iszero(x)) +#define eui64_magic_ne(x, y) do { \ + eui64_magic(x); \ + } while (eui64_equals(x, y)) + +#define eui64_get(ll, cp) do { \ + eui64_copy((*cp), (ll)); \ + (cp) += sizeof(eui64_t); \ + } while (0) + +#define eui64_put(ll, cp) do { \ + eui64_copy((ll), (*cp)); \ + (cp) += sizeof(eui64_t); \ + } while (0) + +#define eui64_set32(e, l) do { \ + (e).e32[0] = 0; \ + (e).e32[1] = htonl(l); \ + } while (0) +#define eui64_setlo32(e, l) eui64_set32(e, l) + +char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */ + +#endif /* __EUI64_H__ */ + diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index e8a254ed..33cea3a7 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -1,96 +1,74 @@ -/***************************************************************************** -* fsm.c - Network Control Protocol Finite State Machine program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-01 Guy Lancaster , Global Election Systems Inc. -* Original based on BSD fsm.c. -*****************************************************************************/ /* * fsm.c - {Link, IP} Control Protocol Finite State Machine. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "lwip/opt.h" + +#define RCSID "$Id: fsm.c,v 1.23 2004/11/13 02:28:15 paulus Exp $" + /* * TODO: * Randomize fsm id on link/init. * Deal with variable outgoing MTU. */ -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" +#include +#include +#include +#include "pppd.h" #include "fsm.h" -#include +static const char rcsid[] = RCSID; -#if PPP_DEBUG -static const char *ppperr_strerr[] = { - "LS_INITIAL", /* LS_INITIAL 0 */ - "LS_STARTING", /* LS_STARTING 1 */ - "LS_CLOSED", /* LS_CLOSED 2 */ - "LS_STOPPED", /* LS_STOPPED 3 */ - "LS_CLOSING", /* LS_CLOSING 4 */ - "LS_STOPPING", /* LS_STOPPING 5 */ - "LS_REQSENT", /* LS_REQSENT 6 */ - "LS_ACKRCVD", /* LS_ACKRCVD 7 */ - "LS_ACKSENT", /* LS_ACKSENT 8 */ - "LS_OPENED" /* LS_OPENED 9 */ -}; -#endif /* PPP_DEBUG */ +static void fsm_timeout __P((void *)); +static void fsm_rconfreq __P((fsm *, int, u_char *, int)); +static void fsm_rconfack __P((fsm *, int, u_char *, int)); +static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int)); +static void fsm_rtermreq __P((fsm *, int, u_char *, int)); +static void fsm_rtermack __P((fsm *)); +static void fsm_rcoderej __P((fsm *, u_char *, int)); +static void fsm_sconfreq __P((fsm *, int)); -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) +#define PROTO_NAME(f) ((f)->callbacks->proto_name) int peer_mru[NUM_PPP]; @@ -101,16 +79,17 @@ int peer_mru[NUM_PPP]; * Initialize fsm state. */ void -fsm_init(fsm *f) +fsm_init(f) + fsm *f; { - f->state = LS_INITIAL; - f->flags = 0; - f->id = 0; /* XXX Start with random id? */ - f->timeouttime = FSM_DEFTIMEOUT; - f->maxconfreqtransmits = FSM_DEFMAXCONFREQS; - f->maxtermtransmits = FSM_DEFMAXTERMREQS; - f->maxnakloops = FSM_DEFMAXNAKLOOPS; - f->term_reason_len = 0; + f->state = INITIAL; + f->flags = 0; + f->id = 0; /* XXX Start with random id? */ + f->timeouttime = DEFTIMEOUT; + f->maxconfreqtransmits = DEFMAXCONFREQS; + f->maxtermtransmits = DEFMAXTERMREQS; + f->maxnakloops = DEFMAXNAKLOOPS; + f->term_reason_len = 0; } @@ -118,34 +97,27 @@ fsm_init(fsm *f) * fsm_lowerup - The lower layer is up. */ void -fsm_lowerup(fsm *f) +fsm_lowerup(f) + fsm *f; { - int oldState = f->state; + switch( f->state ){ + case INITIAL: + f->state = CLOSED; + break; - LWIP_UNUSED_ARG(oldState); - - switch( f->state ) { - case LS_INITIAL: - f->state = LS_CLOSED; - break; - - case LS_STARTING: - if( f->flags & OPT_SILENT ) { - f->state = LS_STOPPED; - } else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = LS_REQSENT; - } - 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(LOG_INFO, ("%s: Up event in state %d (%s)!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } - - FSMDEBUG(LOG_INFO, ("%s: lowerup state %d (%s) -> %d (%s)\n", - PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); + FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); + } } @@ -155,51 +127,42 @@ fsm_lowerup(fsm *f) * Cancel all timeouts and inform upper layers. */ void -fsm_lowerdown(fsm *f) +fsm_lowerdown(f) + fsm *f; { - int oldState = f->state; + switch( f->state ){ + case CLOSED: + f->state = INITIAL; + break; - LWIP_UNUSED_ARG(oldState); + case STOPPED: + f->state = STARTING; + if( f->callbacks->starting ) + (*f->callbacks->starting)(f); + break; - switch( f->state ) { - case LS_CLOSED: - f->state = LS_INITIAL; - break; + case CLOSING: + f->state = INITIAL; + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + break; - case LS_STOPPED: - f->state = LS_STARTING; - if( f->callbacks->starting ) { - (*f->callbacks->starting)(f); - } - break; + case STOPPING: + case REQSENT: + case ACKRCVD: + case ACKSENT: + f->state = STARTING; + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + break; - case LS_CLOSING: - f->state = LS_INITIAL; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case LS_STOPPING: - case LS_REQSENT: - case LS_ACKRCVD: - case LS_ACKSENT: - f->state = LS_STARTING; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case LS_OPENED: - if( f->callbacks->down ) { - (*f->callbacks->down)(f); - } - f->state = LS_STARTING; - break; + case OPENED: + if( f->callbacks->down ) + (*f->callbacks->down)(f); + f->state = STARTING; + break; default: - FSMDEBUG(LOG_INFO, ("%s: Down event in state %d (%s)!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } - - FSMDEBUG(LOG_INFO, ("%s: lowerdown state %d (%s) -> %d (%s)\n", - PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); + FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); + } } @@ -207,47 +170,39 @@ fsm_lowerdown(fsm *f) * fsm_open - Link is allowed to come up. */ void -fsm_open(fsm *f) +fsm_open(f) + fsm *f; { - int oldState = f->state; + switch( f->state ){ + case INITIAL: + f->state = STARTING; + if( f->callbacks->starting ) + (*f->callbacks->starting)(f); + break; - LWIP_UNUSED_ARG(oldState); + case CLOSED: + if( f->flags & OPT_SILENT ) + f->state = STOPPED; + else { + /* Send an initial configure-request */ + fsm_sconfreq(f, 0); + f->state = REQSENT; + } + break; - switch( f->state ) { - case LS_INITIAL: - f->state = LS_STARTING; - if( f->callbacks->starting ) { - (*f->callbacks->starting)(f); - } - break; - - case LS_CLOSED: - if( f->flags & OPT_SILENT ) { - f->state = LS_STOPPED; - } else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = LS_REQSENT; - } - break; - - case LS_CLOSING: - f->state = LS_STOPPING; - /* fall through */ - case LS_STOPPED: - case LS_OPENED: - if( f->flags & OPT_RESTART ) { - fsm_lowerdown(f); - fsm_lowerup(f); - } - break; - } - - FSMDEBUG(LOG_INFO, ("%s: open state %d (%s) -> %d (%s)\n", - PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); + case CLOSING: + f->state = STOPPING; + /* fall through */ + case STOPPED: + case OPENED: + if( f->flags & OPT_RESTART ){ + fsm_lowerdown(f); + fsm_lowerup(f); + } + break; + } } -#if 0 /* backport pppd 2.4.4b1; */ /* * terminate_layer - Start process of shutting down the FSM * @@ -255,60 +210,69 @@ fsm_open(fsm *f) * send a terminate-request message as configured. */ static void -terminate_layer(fsm *f, int nextstate) +terminate_layer(f, nextstate) + fsm *f; + int nextstate; { - /* @todo */ + 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 and send Terminate-Request */ + f->retransmits = f->maxtermtransmits; + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + + if (f->retransmits == 0) { + /* + * User asked for no terminate requests at all; just close it. + * We've already fired off one Terminate-Request just to be nice + * to the peer, but we're not going to wait for a reply. + */ + f->state = nextstate == CLOSING ? CLOSED : STOPPED; + if( f->callbacks->finished ) + (*f->callbacks->finished)(f); + return; + } + + TIMEOUT(fsm_timeout, f, f->timeouttime); + --f->retransmits; + + f->state = nextstate; } -#endif /* * fsm_close - Start closing connection. * * Cancel timeouts and either initiate close or possibly go directly to - * the LS_CLOSED state. + * the CLOSED state. */ void -fsm_close(fsm *f, char *reason) +fsm_close(f, reason) + fsm *f; + char *reason; { - int oldState = f->state; + 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; - LWIP_UNUSED_ARG(oldState); - - f->term_reason = reason; - f->term_reason_len = (reason == NULL ? 0 : (int)strlen(reason)); - switch( f->state ) { - case LS_STARTING: - f->state = LS_INITIAL; - break; - case LS_STOPPED: - f->state = LS_CLOSED; - break; - case LS_STOPPING: - f->state = LS_CLOSING; - break; - - case LS_REQSENT: - case LS_ACKRCVD: - case LS_ACKSENT: - case LS_OPENED: - if( f->state != LS_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 = LS_CLOSING; - break; - } - - FSMDEBUG(LOG_INFO, ("%s: close reason=%s state %d (%s) -> %d (%s)\n", - PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); + case REQSENT: + case ACKRCVD: + case ACKSENT: + case OPENED: + terminate_layer(f, CLOSING); + break; + } } @@ -316,62 +280,52 @@ fsm_close(fsm *f, char *reason) * fsm_timeout - Timeout expired. */ static void -fsm_timeout(void *arg) +fsm_timeout(arg) + void *arg; { - fsm *f = (fsm *) arg; + fsm *f = (fsm *) arg; - switch (f->state) { - case LS_CLOSING: - case LS_STOPPING: - if( f->retransmits <= 0 ) { - FSMDEBUG(LOG_WARNING, ("%s: timeout sending Terminate-Request state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - /* - * We've waited for an ack long enough. Peer probably heard us. - */ - f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - } else { - FSMDEBUG(LOG_WARNING, ("%s: timeout resending Terminate-Requests state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - /* 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; + 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 LS_REQSENT: - case LS_ACKRCVD: - case LS_ACKSENT: - if (f->retransmits <= 0) { - FSMDEBUG(LOG_WARNING, ("%s: timeout sending Config-Requests state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - f->state = LS_STOPPED; - if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - } else { - FSMDEBUG(LOG_WARNING, ("%s: timeout resending Config-Request state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - /* Retransmit the configure-request */ - if (f->callbacks->retransmit) { - (*f->callbacks->retransmit)(f); - } - fsm_sconfreq(f, 1); /* Re-send Configure-Request */ - if( f->state == LS_ACKRCVD ) { - f->state = LS_REQSENT; - } - } - 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(LOG_INFO, ("%s: UNHANDLED timeout event in state %d (%s)!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } + FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); + } } @@ -379,79 +333,80 @@ fsm_timeout(void *arg) * fsm_input - Input packet. */ void -fsm_input(fsm *f, u_char *inpacket, int l) +fsm_input(f, inpacket, l) + fsm *f; + u_char *inpacket; + int l; { - u_char *inp = inpacket; - u_char code, id; - int len; + u_char *inp; + u_char code, id; + int len; - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - if (l < HEADERLEN) { - FSMDEBUG(LOG_WARNING, ("fsm_input(%x): Rcvd short header.\n", - f->protocol)); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < HEADERLEN) { - FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd illegal length.\n", - f->protocol)); - return; - } - if (len > l) { - FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd short packet.\n", - f->protocol)); - return; - } - len -= HEADERLEN; /* subtract header length */ + printf("fsm_input: l = %d\n", l); - if( f->state == LS_INITIAL || f->state == LS_STARTING ) { - FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd packet in state %d (%s).\n", - f->protocol, f->state, ppperr_strerr[f->state])); - return; - } - FSMDEBUG(LOG_INFO, ("fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l)); - /* - * Action depends on code. - */ - switch (code) { + /* + * 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; + fsm_rconfreq(f, id, inp, len); + break; case CONFACK: - fsm_rconfack(f, id, inp, len); - break; + fsm_rconfack(f, id, inp, len); + break; case CONFNAK: case CONFREJ: - fsm_rconfnakrej(f, code, id, inp, len); - break; + fsm_rconfnakrej(f, code, id, inp, len); + break; case TERMREQ: - fsm_rtermreq(f, id, inp, len); - break; + fsm_rtermreq(f, id, inp, len); + break; case TERMACK: - fsm_rtermack(f); - break; + fsm_rtermack(f); + break; case CODEREJ: - fsm_rcoderej(f, inp, len); - break; + fsm_rcoderej(f, inp, len); + break; default: - FSMDEBUG(LOG_INFO, ("fsm_input(%s): default: \n", PROTO_NAME(f))); - if( !f->callbacks->extcode || - !(*f->callbacks->extcode)(f, code, id, inp, len) ) { - fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); - } - break; - } + if( !f->callbacks->extcode + || !(*f->callbacks->extcode)(f, code, id, inp, len) ) + fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); + break; + } } @@ -459,72 +414,73 @@ fsm_input(fsm *f, u_char *inpacket, int l) * fsm_rconfreq - Receive Configure-Request. */ static void -fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) +fsm_rconfreq(f, id, inp, len) + fsm *f; + u_char id; + u_char *inp; + int len; { - int code, reject_if_disagree; + int code, reject_if_disagree; - FSMDEBUG(LOG_INFO, ("fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n", - PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); - switch( f->state ) { - case LS_CLOSED: - /* Go away, we're closed */ - fsm_sdata(f, TERMACK, id, NULL, 0); - return; - case LS_CLOSING: - case LS_STOPPING: - return; + printf("fsm_rconfreq() called, f->state = %d\n"); - case LS_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; + 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 */ + f->state = REQSENT; + 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); + + printf("fsm_rconfreq() code = %d, f->state = %d\n", code, f->state); + 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; + f->nakloops = 0; - case LS_STOPPED: - /* Negotiation started by our peer */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = LS_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, (u_char)code, id, inp, len); - - if (code == CONFACK) { - if (f->state == LS_ACKRCVD) { - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = LS_OPENED; - if (f->callbacks->up) { - (*f->callbacks->up)(f); /* Inform upper layers */ - } } else { - f->state = LS_ACKSENT; + /* we sent CONFACK or CONFREJ */ + if (f->state != ACKRCVD) + f->state = REQSENT; + if( code == CONFNAK ) + ++f->nakloops; } - f->nakloops = 0; - } else { - /* we sent CONFACK or CONFREJ */ - if (f->state != LS_ACKRCVD) { - f->state = LS_REQSENT; - } - if( code == CONFNAK ) { - ++f->nakloops; - } - } } @@ -532,58 +488,57 @@ fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) * fsm_rconfack - Receive Configure-Ack. */ static void -fsm_rconfack(fsm *f, int id, u_char *inp, int len) +fsm_rconfack(f, id, inp, len) + fsm *f; + int id; + u_char *inp; + int len; { - FSMDEBUG(LOG_INFO, ("fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n", - PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); - - 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 */ - FSMDEBUG(LOG_INFO, ("%s: received bad Ack (length %d)\n", - PROTO_NAME(f), len)); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case LS_CLOSED: - case LS_STOPPED: - fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); - break; - - case LS_REQSENT: - f->state = LS_ACKRCVD; - f->retransmits = f->maxconfreqtransmits; - break; - - case LS_ACKRCVD: - /* Huh? an extra valid Ack? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = LS_REQSENT; - break; - - case LS_ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = LS_OPENED; - f->retransmits = f->maxconfreqtransmits; - if (f->callbacks->up) { - (*f->callbacks->up)(f); /* Inform upper layers */ - } - break; - - case LS_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 = LS_REQSENT; - break; - } + 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; + f->rnakloops = 0; + + 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; + } } @@ -591,59 +546,68 @@ fsm_rconfack(fsm *f, int id, u_char *inp, int len) * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. */ static void -fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) +fsm_rconfnakrej(f, code, id, inp, len) + fsm *f; + int code, id; + u_char *inp; + int len; { - int (*proc) (fsm *, u_char *, int); - int ret; + int ret; + int treat_as_reject; - FSMDEBUG(LOG_INFO, ("fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n", - PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + if (id != f->reqid || f->seen_ack) /* Expected id? */ + return; /* Nope, toss... */ - 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 */ - FSMDEBUG(LOG_INFO, ("%s: received bad %s (length %d)\n", - PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len)); - return; - } - f->seen_ack = 1; + if (code == CONFNAK) { + ++f->rnakloops; + treat_as_reject = (f->rnakloops >= f->maxnakloops); + if (f->callbacks->nakci == NULL + || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) { + error("Received bad configure-nak: %P", inp, len); + return; + } + } else { + f->rnakloops = 0; + if (f->callbacks->rejci == NULL + || !(ret = f->callbacks->rejci(f, inp, len))) { + error("Received bad configure-rej: %P", inp, len); + return; + } + } - switch (f->state) { - case LS_CLOSED: - case LS_STOPPED: - fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); - break; - - case LS_REQSENT: - case LS_ACKSENT: - /* They didn't agree to what we wanted - try another request */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - if (ret < 0) { - f->state = LS_STOPPED; /* kludge for stopping CCP */ - } else { - fsm_sconfreq(f, 0); /* Send Configure-Request */ - } - break; - - case LS_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 = LS_REQSENT; - break; - - case LS_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 = LS_REQSENT; - break; - } + 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; + } } @@ -651,35 +615,32 @@ fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) * fsm_rtermreq - Receive Terminate-Req. */ static void -fsm_rtermreq(fsm *f, int id, u_char *p, int len) +fsm_rtermreq(f, id, p, len) + fsm *f; + int id; + u_char *p; + int len; { - LWIP_UNUSED_ARG(p); + switch (f->state) { + case ACKRCVD: + case ACKSENT: + f->state = REQSENT; /* Start over but keep trying */ + break; - FSMDEBUG(LOG_INFO, ("fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n", - PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + 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)); + f->retransmits = 0; + f->state = STOPPING; + if (f->callbacks->down) + (*f->callbacks->down)(f); /* Inform upper layers */ + TIMEOUT(fsm_timeout, f, f->timeouttime); + break; + } - switch (f->state) { - case LS_ACKRCVD: - case LS_ACKSENT: - f->state = LS_REQSENT; /* Start over but keep trying */ - break; - - case LS_OPENED: - if (len > 0) { - FSMDEBUG(LOG_INFO, ("%s terminated by peer (%p)\n", PROTO_NAME(f), p)); - } else { - FSMDEBUG(LOG_INFO, ("%s terminated by peer\n", PROTO_NAME(f))); - } - if (f->callbacks->down) { - (*f->callbacks->down)(f); /* Inform upper layers */ - } - f->retransmits = 0; - f->state = LS_STOPPING; - TIMEOUT(fsm_timeout, f, f->timeouttime); - break; - } - - fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); + fsm_sdata(f, TERMACK, id, NULL, 0); } @@ -687,42 +648,34 @@ fsm_rtermreq(fsm *f, int id, u_char *p, int len) * fsm_rtermack - Receive Terminate-Ack. */ static void -fsm_rtermack(fsm *f) +fsm_rtermack(f) + fsm *f; { - FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - - switch (f->state) { - case LS_CLOSING: - UNTIMEOUT(fsm_timeout, f); - f->state = LS_CLOSED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - break; + 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 LS_STOPPING: - UNTIMEOUT(fsm_timeout, f); - f->state = LS_STOPPED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - break; - - case LS_ACKRCVD: - f->state = LS_REQSENT; - break; - - case LS_OPENED: - if (f->callbacks->down) { - (*f->callbacks->down)(f); /* Inform upper layers */ - } - fsm_sconfreq(f, 0); - break; - default: - FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): UNHANDLED state=%d (%s)!!!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - } + case ACKRCVD: + f->state = REQSENT; + break; + + case OPENED: + if (f->callbacks->down) + (*f->callbacks->down)(f); /* Inform upper layers */ + fsm_sconfreq(f, 0); + f->state = REQSENT; + break; + } } @@ -730,25 +683,23 @@ fsm_rtermack(fsm *f) * fsm_rcoderej - Receive an Code-Reject. */ static void -fsm_rcoderej(fsm *f, u_char *inp, int len) +fsm_rcoderej(f, inp, len) + fsm *f; + u_char *inp; + int len; { - u_char code, id; - - FSMDEBUG(LOG_INFO, ("fsm_rcoderej(%s): state=%d (%s)\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); - - if (len < HEADERLEN) { - FSMDEBUG(LOG_INFO, ("fsm_rcoderej: Rcvd short Code-Reject packet!\n")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - FSMDEBUG(LOG_WARNING, ("%s: Rcvd Code-Reject for code %d, id %d\n", - PROTO_NAME(f), code, id)); - - if( f->state == LS_ACKRCVD ) { - f->state = LS_REQSENT; - } + 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; } @@ -758,49 +709,38 @@ fsm_rcoderej(fsm *f, u_char *inp, int len) * Treat this as a catastrophic error (RXJ-). */ void -fsm_protreject(fsm *f) +fsm_protreject(f) + fsm *f; { - switch( f->state ) { - case LS_CLOSING: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case LS_CLOSED: - f->state = LS_CLOSED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - break; + 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 LS_STOPPING: - case LS_REQSENT: - case LS_ACKRCVD: - case LS_ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case LS_STOPPED: - f->state = LS_STOPPED; - if( f->callbacks->finished ) { - (*f->callbacks->finished)(f); - } - break; - - case LS_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; + 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: + terminate_layer(f, STOPPING); + break; - f->state = LS_STOPPING; - break; - default: - FSMDEBUG(LOG_INFO, ("%s: Protocol-reject event in state %d (%s)!\n", - PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + FSMDEBUG(("%s: Protocol-reject event in state %d!", + PROTO_NAME(f), f->state)); } } @@ -809,52 +749,48 @@ fsm_protreject(fsm *f) * fsm_sconfreq - Send a Configure-Request. */ static void -fsm_sconfreq(fsm *f, int retransmit) +fsm_sconfreq(f, retransmit) + fsm *f; + int retransmit; { - u_char *outp; - int cilen; - - if( f->state != LS_REQSENT && f->state != LS_ACKRCVD && f->state != LS_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[f->unit] + PPP_HDRLEN + HEADERLEN; - if( f->callbacks->cilen && f->callbacks->addci ) { - cilen = (*f->callbacks->cilen)(f); - if( cilen > peer_mru[f->unit] - (int)HEADERLEN ) { - cilen = peer_mru[f->unit] - HEADERLEN; - } - if (f->callbacks->addci) { - (*f->callbacks->addci)(f, outp, &cilen); - } - } else { - cilen = 0; - } + u_char *outp; + int cilen; - /* 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); - - FSMDEBUG(LOG_INFO, ("%s: sending Configure-Request, id %d\n", - PROTO_NAME(f), f->reqid)); + 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; + f->rnakloops = 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); } @@ -864,27 +800,25 @@ fsm_sconfreq(fsm *f, int retransmit) * 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) +fsm_sdata(f, code, id, data, datalen) + fsm *f; + u_char code, id; + u_char *data; + int datalen; { - u_char *outp; - int outlen; + u_char *outp; + int outlen; - /* Adjust length to be smaller than MTU */ - outp = outpacket_buf[f->unit]; - if (datalen > peer_mru[f->unit] - (int)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); - pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN); - FSMDEBUG(LOG_INFO, ("fsm_sdata(%s): Sent code %d,%d,%d.\n", - PROTO_NAME(f), code, id, 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); } - -#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index 8d41b5f5..87a78d38 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -1,157 +1,168 @@ -/***************************************************************************** -* fsm.h - Network Control Protocol Finite State Machine header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original based on BSD code. -*****************************************************************************/ /* * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * $Id: fsm.h,v 1.5 2009/12/31 17:08:08 goldsimon Exp $ + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $ */ -#ifndef FSM_H -#define FSM_H - /* - * LCP Packet header = Code, id, length. + * Packet header = Code, id, length. */ -#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) +#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 */ +#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 */ - u_short 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 */ + 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 rnakloops; /* Number of naks received */ + 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)(fsm*); /* Reset our Configuration Information */ - int (*cilen)(fsm*); /* Length of our Configuration Information */ - void (*addci)(fsm*, u_char*, int*); /* Add our Configuration Information */ - int (*ackci)(fsm*, u_char*, int); /* ACK our Configuration Information */ - int (*nakci)(fsm*, u_char*, int); /* NAK our Configuration Information */ - int (*rejci)(fsm*, u_char*, int); /* Reject our Configuration Information */ - int (*reqci)(fsm*, u_char*, int*, int); /* Request peer's Configuration Information */ - void (*up)(fsm*); /* Called when fsm reaches LS_OPENED state */ - void (*down)(fsm*); /* Called when fsm leaves LS_OPENED state */ - void (*starting)(fsm*); /* Called when we want the lower layer */ - void (*finished)(fsm*); /* Called when we don't want the lower layer */ - void (*protreject)(int); /* Called when Protocol-Reject received */ - void (*retransmit)(fsm*); /* Retransmission is necessary */ - int (*extcode)(fsm*, int, u_char, u_char*, int); /* Called when unknown code received */ - char *proto_name; /* String name for protocol (for messages) */ + void (*resetci) /* Reset our Configuration Information */ + __P((fsm *)); + int (*cilen) /* Length of our Configuration Information */ + __P((fsm *)); + void (*addci) /* Add our Configuration Information */ + __P((fsm *, u_char *, int *)); + int (*ackci) /* ACK our Configuration Information */ + __P((fsm *, u_char *, int)); + int (*nakci) /* NAK our Configuration Information */ + __P((fsm *, u_char *, int, int)); + int (*rejci) /* Reject our Configuration Information */ + __P((fsm *, u_char *, int)); + int (*reqci) /* Request peer's Configuration Information */ + __P((fsm *, u_char *, int *, int)); + void (*up) /* Called when fsm reaches OPENED state */ + __P((fsm *)); + void (*down) /* Called when fsm leaves OPENED state */ + __P((fsm *)); + void (*starting) /* Called when we want the lower layer */ + __P((fsm *)); + void (*finished) /* Called when we don't want the lower layer */ + __P((fsm *)); + void (*protreject) /* Called when Protocol-Reject received */ + __P((int)); + void (*retransmit) /* Retransmission is necessary */ + __P((fsm *)); + int (*extcode) /* Called when unknown code received */ + __P((fsm *, int, int, u_char *, int)); + char *proto_name; /* String name for protocol (for messages) */ } fsm_callbacks; /* * Link states. */ -#define LS_INITIAL 0 /* Down, hasn't been opened */ -#define LS_STARTING 1 /* Down, been opened */ -#define LS_CLOSED 2 /* Up, hasn't been opened */ -#define LS_STOPPED 3 /* Open, waiting for down event */ -#define LS_CLOSING 4 /* Terminating the connection, not open */ -#define LS_STOPPING 5 /* Terminating, but open */ -#define LS_REQSENT 6 /* We've sent a Config Request */ -#define LS_ACKRCVD 7 /* We've received a Config Ack */ -#define LS_ACKSENT 8 /* We've sent a Config Ack */ -#define LS_OPENED 9 /* Connection available */ +#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 */ +#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 3 /* 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); +void fsm_init __P((fsm *)); +void fsm_lowerup __P((fsm *)); +void fsm_lowerdown __P((fsm *)); +void fsm_open __P((fsm *)); +void fsm_close __P((fsm *, char *)); +void fsm_input __P((fsm *, u_char *, int)); +void fsm_protreject __P((fsm *)); +void fsm_sdata __P((fsm *, int, int, u_char *, int)); /* * Variables */ -extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ - -#endif /* FSM_H */ +extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index f0ab2e0e..f2bafe70 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1,213 +1,615 @@ -/** In contrast to pppd 2.3.1, DNS support has been added, proxy-ARP and - dial-on-demand has been stripped. */ -/***************************************************************************** -* ipcp.c - Network PPP IP Control Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-08 Guy Lancaster , Global Election Systems Inc. -* Original. -*****************************************************************************/ /* * ipcp.c - PPP IP Control Protocol. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "lwip/opt.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#define RCSID "$Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp $" -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "auth.h" -#include "fsm.h" -#include "vj.h" -#include "ipcp.h" - -#include "lwip/inet.h" +/* + * TODO: + */ +#include #include +#include +#include +#include +#include +#include +#include +#include -/* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */ +#include "pppd.h" +#include "fsm.h" +#include "ipcp.h" +#include "pathnames.h" + +static const char rcsid[] = RCSID; /* 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_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 */ +ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ + +u_int32_t netmask = 0; /* IP netmask to set on interface */ + +bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ +bool noremoteip = 0; /* Let him have no IP address */ + +/* Hook for a plugin to know when IP protocol has come up */ +void (*ip_up_hook) __P((void)) = NULL; + +/* Hook for a plugin to know when IP protocol has come down */ +void (*ip_down_hook) __P((void)) = NULL; + +/* Hook for a plugin to choose the remote IP address */ +void (*ip_choose_hook) __P((u_int32_t *)) = NULL; + +/* Notifiers for when IPCP goes up and down */ +struct notifier *ip_up_notifier = NULL; +struct notifier *ip_down_notifier = NULL; /* local vars */ -static int default_route_set[NUM_PPP]; /* Have set up a default route */ -static int cis_received[NUM_PPP]; /* # Conf-Reqs received */ - +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() */ +static int ipcp_is_open; /* haven't called np_finished() */ +static bool ask_for_local; /* request our address from peer */ +static char vj_value[8]; /* string form of vj option value */ +static char netmask_str[20]; /* string form of netmask value */ /* * 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 */ -#if PPP_ADDITIONAL_CALLBACKS -static void ipcp_script (fsm *, char *); /* Run an up/down script */ -#endif -static void ipcp_finished (fsm *); /* Don't need lower layer */ - - -fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ +static void ipcp_resetci __P((fsm *)); /* Reset our CI */ +static int ipcp_cilen __P((fsm *)); /* Return length of our CI */ +static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ +static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ +static int ipcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ +static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ +static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ +static void ipcp_up __P((fsm *)); /* We're UP */ +static void ipcp_down __P((fsm *)); /* We're DOWN */ +static void ipcp_finished __P((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 LS_OPENED state */ - ipcp_down, /* Called when fsm leaves LS_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 */ + 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 __P((char **)); +static int setdnsaddr __P((char **)); +static int setwinsaddr __P((char **)); +static int setnetmask __P((char **)); +int setipaddr __P((char *, char **, int)); +static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); + +static option_t ipcp_option_list[] = { + { "noip", o_bool, &ipcp_protent.enabled_flag, + "Disable IP and IPCP" }, + { "-ip", o_bool, &ipcp_protent.enabled_flag, + "Disable IP and IPCP", OPT_ALIAS }, + + { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, + "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj }, + { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, + "Disable VJ compression", OPT_ALIAS | OPT_A2CLR, + &ipcp_allowoptions[0].neg_vj }, + + { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, + "Disable VJ connection-ID compression", OPT_A2CLR, + &ipcp_allowoptions[0].cflag }, + { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, + "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR, + &ipcp_allowoptions[0].cflag }, + + { "vj-max-slots", o_special, (void *)setvjslots, + "Set maximum VJ header slots", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value }, + + { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, + "Accept peer's address for us", 1 }, + { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, + "Accept peer's address for it", 1 }, + + { "ipparam", o_string, &ipparam, + "Set ip script parameter", OPT_PRIO }, + + { "noipdefault", o_bool, &disable_defaultip, + "Don't use name for default IP adrs", 1 }, + + { "ms-dns", 1, (void *)setdnsaddr, + "DNS address for the peer's use" }, + { "ms-wins", 1, (void *)setwinsaddr, + "Nameserver for SMB over TCP/IP for peer" }, + + { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, + "Set timeout for IPCP", OPT_PRIO }, + { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, + "Set max #xmits for term-reqs", OPT_PRIO }, + { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, + "Set max #xmits for conf-reqs", OPT_PRIO }, + { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, + "Set max #conf-naks for IPCP", OPT_PRIO }, + + { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, + "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route }, + { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, + "disable defaultroute option", OPT_A2CLR, + &ipcp_wantoptions[0].default_route }, + { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, + "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, + &ipcp_wantoptions[0].default_route }, + + { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, + "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, + { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, + "disable proxyarp option", OPT_A2CLR, + &ipcp_wantoptions[0].proxy_arp }, + { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, + "disable proxyarp option", OPT_ALIAS | OPT_A2CLR, + &ipcp_wantoptions[0].proxy_arp }, + + { "usepeerdns", o_bool, &usepeerdns, + "Ask peer for DNS address(es)", 1 }, + + { "netmask", o_special, (void *)setnetmask, + "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, + + { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs, + "Disable old-style IP-Addresses usage", OPT_A2CLR, + &ipcp_allowoptions[0].old_addrs }, + { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr, + "Disable IP-Address usage", OPT_A2CLR, + &ipcp_allowoptions[0].neg_addr }, +#ifdef __linux__ + { "noremoteip", o_bool, &noremoteip, + "Allow peer to have no IP address", 1 }, +#endif + { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr, + "Don't send our IP address to peer", OPT_A2CLR, + &ipcp_wantoptions[0].old_addrs}, + + { "IP addresses", o_wild, (void *) &setipaddr, + "set local and remote IP addresses", + OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, + + { NULL } }; /* * 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 void ipcp_init __P((int)); +static void ipcp_open __P((int)); +static void ipcp_close __P((int, char *)); +static void ipcp_lowerup __P((int)); +static void ipcp_lowerdown __P((int)); +static void ipcp_input __P((int, u_char *, int)); +static void ipcp_protrej __P((int)); +static int ipcp_printpkt __P((u_char *, int, + void (*) __P((void *, char *, ...)), void *)); +static void ip_check_options __P((void)); +static int ip_demand_conf __P((int)); +static int ip_active_pkt __P((u_char *, int)); +static void create_resolv __P((u_int32_t, u_int32_t)); struct protent ipcp_protent = { - PPP_IPCP, - ipcp_init, - ipcp_input, - ipcp_protrej, - ipcp_lowerup, - ipcp_lowerdown, - ipcp_open, - ipcp_close, -#if PPP_ADDITIONAL_CALLBACKS - ipcp_printpkt, - NULL, -#endif /* PPP_ADDITIONAL_CALLBACKS */ - 1, - "IPCP", -#if PPP_ADDITIONAL_CALLBACKS - ip_check_options, - NULL, - ip_active_pkt -#endif /* PPP_ADDITIONAL_CALLBACKS */ + 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); +static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t)); +static void ipcp_script __P((char *, int)); /* Run an up/down script */ +static void ipcp_script_done __P((void *)); /* * 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 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") +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + +/* + * This state variable is used to ensure that we don't + * run an ipcp-up/down script while one is already running. + */ +static enum script_state { + s_down, + s_up, +} ipcp_script_state; +static pid_t ipcp_script_pid; + +/* + * Make a string representation of a network IP address. + */ +char * +ip_ntoa(ipaddr) +u_int32_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(argv) + 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; + slprintf(vj_value, sizeof(vj_value), "%d", value); + return 1; +} + +/* + * setdnsaddr - set the dns address(es) + */ +static int +setdnsaddr(argv) + char **argv; +{ + u_int32_t dns; + struct hostent *hp; + + dns = inet_addr(*argv); + if (dns == (u_int32_t) -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-dns option", + *argv); + return 0; + } + dns = *(u_int32_t *)hp->h_addr; + } + + /* We take the last 2 values given, the 2nd-last as the primary + and the last as the secondary. If only one is given it + becomes both primary and secondary. */ + if (ipcp_allowoptions[0].dnsaddr[1] == 0) + ipcp_allowoptions[0].dnsaddr[0] = dns; + else + ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1]; + + /* always set the secondary address 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(argv) + char **argv; +{ + u_int32_t wins; + struct hostent *hp; + + wins = inet_addr(*argv); + if (wins == (u_int32_t) -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-wins option", + *argv); + return 0; + } + wins = *(u_int32_t *)hp->h_addr; + } + + /* We take the last 2 values given, the 2nd-last as the primary + and the last as the secondary. If only one is given it + becomes both primary and secondary. */ + if (ipcp_allowoptions[0].winsaddr[1] == 0) + ipcp_allowoptions[0].winsaddr[0] = wins; + else + ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1]; + + /* always set the secondary address value. */ + ipcp_allowoptions[0].winsaddr[1] = wins; + + return (1); +} + +/* + * setipaddr - Set the IP address + * If doit is 0, the call is to check whether this option is + * potentially an IP address specification. + * Not static so that plugins can call it to set the addresses + */ +int +setipaddr(arg, argv, doit) + char *arg; + char **argv; + int doit; +{ + struct hostent *hp; + char *colon; + u_int32_t local, remote; + ipcp_options *wo = &ipcp_wantoptions[0]; + static int prio_local = 0, prio_remote = 0; + + /* + * IP address pair separated by ":". + */ + if ((colon = strchr(arg, ':')) == NULL) + return 0; + if (!doit) + return 1; + + /* + * If colon first character, then no local addr. + */ + if (colon != arg && option_priority >= prio_local) { + *colon = '\0'; + if ((local = inet_addr(arg)) == (u_int32_t) -1) { + if ((hp = gethostbyname(arg)) == NULL) { + option_error("unknown host: %s", arg); + return 0; + } + local = *(u_int32_t *)hp->h_addr; + } + if (bad_ip_adrs(local)) { + option_error("bad local IP address %s", ip_ntoa(local)); + return 0; + } + if (local != 0) + wo->ouraddr = local; + *colon = ':'; + prio_local = option_priority; + } + + /* + * If colon last character, then no remote addr. + */ + if (*++colon != '\0' && option_priority >= prio_remote) { + if ((remote = inet_addr(colon)) == (u_int32_t) -1) { + if ((hp = gethostbyname(colon)) == NULL) { + option_error("unknown host: %s", colon); + return 0; + } + remote = *(u_int32_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 0; + } + if (remote != 0) + wo->hisaddr = remote; + prio_remote = option_priority; + } + + return 1; +} + +static void +printipaddr(opt, printer, arg) + option_t *opt; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + ipcp_options *wo = &ipcp_wantoptions[0]; + + if (wo->ouraddr != 0) + printer(arg, "%I", wo->ouraddr); + printer(arg, ":"); + if (wo->hisaddr != 0) + printer(arg, "%I", wo->hisaddr); +} + +/* + * setnetmask - set the netmask to be used on the interface. + */ +static int +setnetmask(argv) + char **argv; +{ + u_int32_t mask; + int n; + char *p; + + /* + * 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; + n = parse_dotted_ip(p, &mask); + + mask = htonl(mask); + + if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) { + option_error("invalid netmask value '%s'", *argv); + return 0; + } + + netmask = mask; + slprintf(netmask_str, sizeof(netmask_str), "%I", mask); + + return (1); +} + +int +parse_dotted_ip(p, vp) + char *p; + u_int32_t *vp; +{ + int n; + u_int32_t v, b; + char *endp, *p0 = p; + + v = 0; + for (n = 3;; --n) { + b = strtoul(p, &endp, 0); + if (endp == p) + return 0; + if (b > 255) { + if (n < 3) + return 0; + /* accept e.g. 0xffffff00 */ + *vp = b; + return endp - p0; + } + v |= b << (n * 8); + p = endp; + if (n == 0) + break; + if (*p != '.') + return 0; + ++p; + } + *vp = v; + return p - p0; +} /* * ipcp_init - Initialize IPCP. */ static void -ipcp_init(int unit) +ipcp_init(unit) + int unit; { - fsm *f = &ipcp_fsm[unit]; - ipcp_options *wo = &ipcp_wantoptions[unit]; - ipcp_options *ao = &ipcp_allowoptions[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]); + 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)); + /* + * Some 3G modems use repeated IPCP NAKs as a way of stalling + * until they can contact a server on the network, so we increase + * the default number of NAKs we accept before we start treating + * them as rejects. + */ + f->maxnakloops = 100; - wo->neg_addr = 1; - wo->ouraddr = 0; -#if VJ_SUPPORT - wo->neg_vj = 1; -#else /* VJ_SUPPORT */ - wo->neg_vj = 0; -#endif /* VJ_SUPPORT */ - wo->vj_protocol = IPCP_VJ_COMP; - wo->maxslotindex = MAX_SLOTS - 1; - wo->cflag = 0; - wo->default_route = 1; + memset(wo, 0, sizeof(*wo)); + memset(ao, 0, sizeof(*ao)); - ao->neg_addr = 1; -#if VJ_SUPPORT - ao->neg_vj = 1; -#else /* VJ_SUPPORT */ - ao->neg_vj = 0; -#endif /* VJ_SUPPORT */ - ao->maxslotindex = MAX_SLOTS - 1; - ao->cflag = 1; - ao->default_route = 1; + wo->neg_addr = wo->old_addrs = 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 = ao->old_addrs = 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; } @@ -215,9 +617,11 @@ ipcp_init(int unit) * ipcp_open - IPCP is allowed to come up. */ static void -ipcp_open(int unit) +ipcp_open(unit) + int unit; { - fsm_open(&ipcp_fsm[unit]); + fsm_open(&ipcp_fsm[unit]); + ipcp_is_open = 1; } @@ -225,9 +629,11 @@ ipcp_open(int unit) * ipcp_close - Take IPCP down. */ static void -ipcp_close(int unit, char *reason) +ipcp_close(unit, reason) + int unit; + char *reason; { - fsm_close(&ipcp_fsm[unit], reason); + fsm_close(&ipcp_fsm[unit], reason); } @@ -235,9 +641,10 @@ ipcp_close(int unit, char *reason) * ipcp_lowerup - The lower layer is up. */ static void -ipcp_lowerup(int unit) +ipcp_lowerup(unit) + int unit; { - fsm_lowerup(&ipcp_fsm[unit]); + fsm_lowerup(&ipcp_fsm[unit]); } @@ -245,9 +652,10 @@ ipcp_lowerup(int unit) * ipcp_lowerdown - The lower layer is down. */ static void -ipcp_lowerdown(int unit) +ipcp_lowerdown(unit) + int unit; { - fsm_lowerdown(&ipcp_fsm[unit]); + fsm_lowerdown(&ipcp_fsm[unit]); } @@ -255,9 +663,12 @@ ipcp_lowerdown(int unit) * ipcp_input - Input IPCP packet. */ static void -ipcp_input(int unit, u_char *p, int len) +ipcp_input(unit, p, len) + int unit; + u_char *p; + int len; { - fsm_input(&ipcp_fsm[unit], p, len); + fsm_input(&ipcp_fsm[unit], p, len); } @@ -267,948 +678,1084 @@ ipcp_input(int unit, u_char *p, int len) * Pretend the lower layer went down, so we shut up. */ static void -ipcp_protrej(int unit) +ipcp_protrej(unit) + int unit; { - fsm_lowerdown(&ipcp_fsm[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_resetci(f) + fsm *f; { - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - - wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; - if (wo->ouraddr == 0) { - wo->accept_local = 1; - } - if (wo->hisaddr == 0) { - wo->accept_remote = 1; - } - /* Request DNS addresses from the peer */ - wo->req_dns1 = ppp_settings.usepeerdns; - wo->req_dns2 = ppp_settings.usepeerdns; - ipcp_gotoptions[f->unit] = *wo; - cis_received[f->unit] = 0; + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + ipcp_options *go = &ipcp_gotoptions[f->unit]; + ipcp_options *ao = &ipcp_allowoptions[f->unit]; + + wo->req_addr = (wo->neg_addr || wo->old_addrs) && + (ao->neg_addr || ao->old_addrs); + if (wo->ouraddr == 0) + 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 (!ask_for_local) + go->ouraddr = 0; + if (ip_choose_hook) { + ip_choose_hook(&wo->hisaddr); + if (wo->hisaddr) { + wo->accept_remote = 0; + } + } + BZERO(&ipcp_hisoptions[f->unit], sizeof(ipcp_options)); } /* * ipcp_cilen - Return length of our CI. + * Called by fsm_sconfreq, Send Configure Request. */ static int -ipcp_cilen(fsm *f) +ipcp_cilen(f) + fsm *f; { - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; + 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) +#define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) +#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) +#define LENCIADDR(neg) (neg ? CILEN_ADDR : 0) +#define LENCIDNS(neg) LENCIADDR(neg) +#define LENCIWINS(neg) LENCIADDR(neg) - /* - * 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 */ - if (cis_received[f->unit] == 0) { - /* keep trying the new style until we see some CI from the peer */ - go->neg_vj = 1; - } else { - /* 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; - } + /* + * First see if we want to change our options to the old + * forms because we have received old forms from the peer. + */ + if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) + go->neg_addr = 0; + 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)); + return (LENCIADDRS(!go->neg_addr && go->old_addrs) + + LENCIVJ(go->neg_vj, go->old_vj) + + LENCIADDR(go->neg_addr) + + LENCIDNS(go->req_dns1) + + LENCIDNS(go->req_dns2) + + LENCIWINS(go->winsaddr[0]) + + LENCIWINS(go->winsaddr[1])) ; } /* * 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_addci(f, ucp, lenp) + fsm *f; + u_char *ucp; + int *lenp; { - ipcp_options *go = &ipcp_gotoptions[f->unit]; - int len = *lenp; + ipcp_options *go = &ipcp_gotoptions[f->unit]; + int len = *lenp; + +#define ADDCIADDRS(opt, neg, val1, val2) \ + if (neg) { \ + if (len >= CILEN_ADDRS) { \ + u_int32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDRS, ucp); \ + l = ntohl(val1); \ + PUTLONG(l, ucp); \ + l = ntohl(val2); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDRS; \ + } else \ + go->old_addrs = 0; \ + } #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; \ - } \ - } + 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) { \ - u32_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 ADDCIADDR(opt, neg, val) \ + if (neg) { \ + if (len >= CILEN_ADDR) { \ + u_int32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDR, ucp); \ + l = ntohl(val); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDR; \ + } else \ + neg = 0; \ + } #define ADDCIDNS(opt, neg, addr) \ - if (neg) { \ - if (len >= CILEN_ADDR) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = ntohl(addr); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else { \ - neg = 0; \ - } \ - } + if (neg) { \ + if (len >= CILEN_ADDR) { \ + u_int32_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); +#define ADDCIWINS(opt, addr) \ + if (addr) { \ + if (len >= CILEN_ADDR) { \ + u_int32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDR, ucp); \ + l = ntohl(addr); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDR; \ + } else \ + addr = 0; \ + } - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); + ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, + go->hisaddr); - ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); + ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); - ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); - *lenp -= len; + ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); + + ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + + ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]); + + ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]); + + *lenp -= len; } /* * ipcp_ackci - Ack our CIs. + * Called by fsm_rconfack, Receive Configure ACK. * * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. + * 0 - Ack was bad. + * 1 - Ack was good. */ static int -ipcp_ackci(fsm *f, u_char *p, int len) +ipcp_ackci(f, p, len) + fsm *f; + u_char *p; + int len; { - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_short cilen, citype, cishort; - u32_t cilong; - u_char cimaxslotindex, cicflag; + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_short cilen, citype, cishort; + u_int32_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. - */ + /* + * 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 ACKCIADDRS(opt, neg, val1, val2) \ + if (neg) { \ + u_int32_t l; \ + if ((len -= CILEN_ADDRS) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_ADDRS || \ + citype != opt) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val1 != cilong) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val2 != cilong) \ + goto 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); \ - u32_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; \ - } \ - } \ - } + 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, val) \ + if (neg) { \ + u_int32_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 (val != cilong) \ + goto bad; \ + } #define ACKCIDNS(opt, neg, addr) \ - if (neg) { \ - u32_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; \ - } \ - } + if (neg) { \ + u_int32_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); + ACKCIADDRS(CI_ADDRS, !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); + 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]); + ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); - ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) { - goto bad; - } - return (1); + 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(LOG_INFO, ("ipcp_ackci: received bad Ack!\n")); - return (0); + 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 LS_OPENED state. + * 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. + * 0 - Nak was bad. + * 1 - Nak was good. */ static int -ipcp_nakci(fsm *f, u_char *p, int len) +ipcp_nakci(f, p, len, treat_as_reject) + fsm *f; + u_char *p; + int len; + int treat_as_reject; { - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char cimaxslotindex, cicflag; - u_char citype, cilen, *next; - u_short cishort; - u32_t ciaddr1, ciaddr2, l, cidnsaddr; - ipcp_options no; /* options we've seen Naks for */ - ipcp_options try; /* options to request next time */ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_char cimaxslotindex, cicflag; + u_char citype, cilen, *next; + u_short cishort; + u_int32_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; + 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 \ - } + /* + * 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 NAKCIADDRS(opt, neg, code) \ + if ((neg) && \ + (cilen = p[1]) == CILEN_ADDRS && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + ciaddr1 = htonl(l); \ + GETLONG(l, p); \ + ciaddr2 = htonl(l); \ + no.old_addrs = 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 \ - } - + 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 NAKCIADDR(opt, neg, code) \ + if (go->neg && \ + (cilen = p[1]) == CILEN_ADDR && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + ciaddr1 = htonl(l); \ + 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; - IPCPDEBUG(LOG_INFO, ("local IP address %s\n", - inet_ntoa(ciaddr1))); + 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 \ } - if (go->accept_remote && ciaddr2) { /* Does he know his? */ - try.hisaddr = ciaddr2; - IPCPDEBUG(LOG_INFO, ("remote IP address %s\n", - inet_ntoa(ciaddr2))); + + /* + * Accept the peer's idea of {our,his} address, if different + * from our idea, only if the accept_{local,remote} flag is set. + */ + NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, + if (treat_as_reject) { + try.old_addrs = 0; + } else { + if (go->accept_local && ciaddr1) { + /* take his idea of our address */ + try.ouraddr = ciaddr1; + } + if (go->accept_remote && ciaddr2) { + /* take his idea of his address */ + 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 (treat_as_reject) { + try.neg_vj = 0; + } else 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; + } + } + ); + + NAKCIADDR(CI_ADDR, neg_addr, + if (treat_as_reject) { + try.neg_addr = 0; + try.old_addrs = 0; + } else if (go->accept_local && ciaddr1) { + /* take his idea of our address */ + try.ouraddr = ciaddr1; + } + ); + + NAKCIDNS(CI_MS_DNS1, req_dns1, + if (treat_as_reject) { + try.req_dns1 = 0; + } else { + try.dnsaddr[0] = cidnsaddr; + } + ); + + NAKCIDNS(CI_MS_DNS2, req_dns2, + if (treat_as_reject) { + try.req_dns2 = 0; + } else { + 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. + * If they want us to ask for ms-dns, we do that, since some + * peers get huffy if we don't. + */ + 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_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 = 0; + 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; + case CI_MS_DNS1: + if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR) + goto bad; + GETLONG(l, p); + try.dnsaddr[0] = htonl(l); + try.req_dns1 = 1; + no.req_dns1 = 1; + break; + case CI_MS_DNS2: + if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR) + goto bad; + GETLONG(l, p); + try.dnsaddr[1] = htonl(l); + try.req_dns2 = 1; + no.req_dns2 = 1; + break; + case CI_MS_WINS1: + case CI_MS_WINS2: + if (cilen != CILEN_ADDR) + goto bad; + GETLONG(l, p); + ciaddr1 = htonl(l); + if (ciaddr1) + try.winsaddr[citype == CI_MS_WINS2] = ciaddr1; + break; + } + p = next; } - ); - /* - * 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; - } - } - ); + /* + * 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; - NAKCIDNS(CI_MS_DNS1, req_dns1, - try.dnsaddr[0] = cidnsaddr; - IPCPDEBUG(LOG_INFO, ("primary DNS address %s\n", inet_ntoa(cidnsaddr))); - ); - - NAKCIDNS(CI_MS_DNS2, req_dns2, - try.dnsaddr[1] = cidnsaddr; - IPCPDEBUG(LOG_INFO, ("secondary DNS address %s\n", inet_ntoa(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; - } - - /* If there is still anything left, this packet is bad. */ - if (len != 0) { - goto bad; - } - - /* - * OK, the Nak is good. Now we can update state. - */ - if (f->state != LS_OPENED) { - *go = try; - } - - return 1; + return 1; bad: - IPCPDEBUG(LOG_INFO, ("ipcp_nakci: received bad Nak!\n")); - return 0; + 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_rejci(f, p, len) + fsm *f; + u_char *p; + int len; { - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char cimaxslotindex, ciflag, cilen; - u_short cishort; - u32_t cilong; - ipcp_options try; /* options to request next time */ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_char cimaxslotindex, ciflag, cilen; + u_short cishort; + u_int32_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) { \ - u32_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; \ - } + 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 REJCIADDRS(opt, neg, val1, val2) \ + if ((neg) && \ + (cilen = p[1]) == CILEN_ADDRS && \ + len >= cilen && \ + p[0] == opt) { \ + u_int32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val1) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val2) \ + goto bad; \ + try.old_addrs = 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; \ - } + 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 REJCIADDR(opt, neg, val) \ + if (go->neg && \ + (cilen = p[1]) == CILEN_ADDR && \ + len >= cilen && \ + p[0] == opt) { \ + u_int32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val) \ + goto bad; \ + try.neg = 0; \ + } #define REJCIDNS(opt, neg, dnsaddr) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != dnsaddr) { \ - goto bad; \ - } \ - try.neg = 0; \ - } + if (go->neg && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + u_int32_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); +#define REJCIWINS(opt, addr) \ + if (addr && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + u_int32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != addr) \ + goto bad; \ + try.winsaddr[opt == CI_MS_WINS2] = 0; \ + } - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); + REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, + go->ouraddr, go->hisaddr); - REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); + REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); - REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); + REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) { - goto bad; - } - /* - * Now we can update state. - */ - if (f->state != LS_OPENED) { - *go = try; - } - return 1; + REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); + + REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); + + REJCIWINS(CI_MS_WINS1, go->winsaddr[0]); + + REJCIWINS(CI_MS_WINS2, go->winsaddr[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(LOG_INFO, ("ipcp_rejci: received bad Reject!\n")); - return 0; + 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_reqci(f, inp, len, reject_if_disagree) + 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]; -#ifdef OLD_CI_ADDRS - ipcp_options *go = &ipcp_gotoptions[f->unit]; -#endif - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ - u_short cishort; /* Parsed short value */ - u32_t tl, ciaddr1; /* Parsed address values */ -#ifdef OLD_CI_ADDRS - u32_t ciaddr2; /* Parsed address values */ -#endif - 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; + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + ipcp_options *ho = &ipcp_hisoptions[f->unit]; + ipcp_options *ao = &ipcp_allowoptions[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 */ + u_int32_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; - cis_received[f->unit] = 1; - - /* - * 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(LOG_INFO, ("ipcp_reqci: bad CI length!\n")); - orc = CONFREJ; /* Reject bad CI */ - cilen = (u_short)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 */ -#ifdef OLD_CI_ADDRS /* Need to save space... */ - case CI_ADDRS: - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received ADDRS\n")); - 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); - IPCPDEBUG(LOG_INFO, ("his addr %s\n", inet_ntoa(ciaddr1))); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_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); - IPCPDEBUG(LOG_INFO, ("our addr %s\n", inet_ntoa(ciaddr2))); - if (ciaddr2 != wo->ouraddr) { - if (ciaddr2 == 0 || !wo->accept_local) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_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; -#endif - - case CI_ADDR: - if (!ao->neg_addr) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR not allowed\n")); - orc = CONFREJ; /* Reject CI */ - break; - } else if (cilen != CILEN_ADDR) { /* Check CI length */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR bad len\n")); - 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(u32_t), p); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1))); - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * Don't ACK an address of 0.0.0.0 - reject it instead. - */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1))); - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - ho->neg_addr = 1; - ho->hisaddr = ciaddr1; - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: ADDR %s\n", inet_ntoa(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 */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting DNS%d Request\n", d+1)); - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (htonl(tl) != ao->dnsaddr[d]) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking DNS%d Request %s\n", - d+1, inet_ntoa(tl))); - DECPTR(sizeof(u32_t), p); - tl = ntohl(ao->dnsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received DNS%d Request\n", d+1)); - break; - - case CI_MS_WINS1: - case CI_MS_WINS2: - /* Microsoft primary or secondary WINS request */ - d = citype == CI_MS_WINS2; - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received WINS%d Request\n", d+1)); - - /* 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(u32_t), p); - tl = ntohl(ao->winsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; - - case CI_COMPRESSTYPE: - if (!ao->neg_vj) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n")); - orc = CONFREJ; - break; - } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen)); - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - if (!(cishort == IPCP_VJ_COMP || - (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort)); - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - if (cilen == CILEN_VJ) { - GETCHAR(maxslotindex, p); - if (maxslotindex > ao->maxslotindex) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ max slot %d\n", maxslotindex)); - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(1, p); - PUTCHAR(ao->maxslotindex, p); - } - } - GETCHAR(cflag, p); - if (cflag && !ao->cflag) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ cflag %d\n", 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_SLOTS - 1; - ho->cflag = 1; - } - IPCPDEBUG(LOG_INFO, ( - "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n", - ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag)); - break; - - default: - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting unknown CI type %d\n", 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? */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting too many naks\n")); - 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 */ - } + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); - /* Need to move CI? */ - if (ucp != cip) { - BCOPY(cip, ucp, cilen); /* Move it */ + /* + * 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->old_addrs || ho->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(u_int32_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(u_int32_t), p); + tl = ntohl(wo->ouraddr); + PUTLONG(tl, p); + } + } else { + wo->ouraddr = ciaddr2; /* accept peer's idea */ + } + } + + ho->old_addrs = 1; + ho->hisaddr = ciaddr1; + ho->ouraddr = ciaddr2; + break; + + case CI_ADDR: + if (!ao->neg_addr || ho->old_addrs || + 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(u_int32_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(u_int32_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(u_int32_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); } - /* 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) { - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Requesting peer address\n")); - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_addr = 0; /* don't ask again */ + /* + * 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 && !ho->old_addrs && + wo->req_addr && !reject_if_disagree && !noremoteip) { + 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); } - PUTCHAR(CI_ADDR, ucp); - PUTCHAR(CILEN_ADDR, ucp); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, ucp); - } - *len = (int)(ucp - inp); /* Compute output length */ - IPCPDEBUG(LOG_INFO, ("ipcp_reqci: returning Configure-%s\n", CODENAME(rc))); - return (rc); /* Return final code */ + *len = ucp - inp; /* Compute output length */ + IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); + return (rc); /* Return final code */ } -#if 0 /* * ip_check_options - check that any IP-related options are OK, * and assign appropriate defaults. */ static void -ip_check_options(u_long localAddr) +ip_check_options() { - ipcp_options *wo = &ipcp_wantoptions[0]; + struct hostent *hp; + u_int32_t local; + ipcp_options *wo = &ipcp_wantoptions[0]; - /* - * Load our default IP address but allow the remote host to give us - * a new address. - */ - if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) { - wo->accept_local = 1; /* don't insist on this default value */ - wo->ouraddr = htonl(localAddr); - } + /* + * 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 = *(u_int32_t *)hp->h_addr; + if (local != 0 && !bad_ip_adrs(local)) + wo->ouraddr = local; + } + } + ask_for_local = wo->ouraddr != 0 || !disable_defaultip; +} + + +/* + * ip_demand_conf - configure the interface as though + * IPCP were up, for use with dial-on-demand. + */ +static int +ip_demand_conf(u) + int u; +{ + ipcp_options *wo = &ipcp_wantoptions[u]; + + if (wo->hisaddr == 0 && !noremoteip) { + /* make up an arbitrary address for the peer */ + wo->hisaddr = htonl(0x0a707070 + ifunit); + wo->accept_remote = 1; + } + if (wo->ouraddr == 0) { + /* make up an arbitrary address for us */ + wo->ouraddr = htonl(0x0a404040 + ifunit); + wo->accept_local = 1; + ask_for_local = 0; /* don't tell the peer this address */ + } + if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) + return 0; + ipcp_script(_PATH_IPPREUP, 1); + 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); + if (wo->hisaddr) + notice("remote IP address %I", wo->hisaddr); + + return 1; } -#endif /* @@ -1217,86 +1764,188 @@ ip_check_options(u_long localAddr) * Configure the IP network interface appropriately and bring it up. */ static void -ipcp_up(fsm *f) +ipcp_up(f) + fsm *f; { - u32_t mask; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; + u_int32_t mask; + ipcp_options *ho = &ipcp_hisoptions[f->unit]; + ipcp_options *go = &ipcp_gotoptions[f->unit]; + ipcp_options *wo = &ipcp_wantoptions[f->unit]; - np_up(f->unit, PPP_IP); - IPCPDEBUG(LOG_INFO, ("ipcp: up\n")); + 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; - } + /* + * We must have a non-zero IP address for both ends of the link. + */ + if (!ho->neg_addr && !ho->old_addrs) + ho->hisaddr = wo->hisaddr; - if (ho->hisaddr == 0) { - IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n")); - ipcp_close(f->unit, "Could not determine remote IP address"); - return; - } - if (go->ouraddr == 0) { - IPCPDEBUG(LOG_ERR, ("Could not determine local IP address\n")); - ipcp_close(f->unit, "Could not determine local IP address"); - return; - } - - if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { - /*pppGotDNSAddrs(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)) { - IPCPDEBUG(LOG_ERR, ("Peer is not authorized to use remote address %s\n", - inet_ntoa(ho->hisaddr))); - ipcp_close(f->unit, "Unauthorized remote IP address"); - return; - } - - /* set tcp compression */ - sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); - - /* - * Set IP addresses and (if specified) netmask. - */ - mask = GetMask(go->ouraddr); - - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) { - IPCPDEBUG(LOG_WARNING, ("sifaddr failed\n")); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - - /* bring the interface up for IP */ - if (!sifup(f->unit)) { - IPCPDEBUG(LOG_WARNING, ("sifup failed\n")); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - - 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; + if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) + && wo->ouraddr != 0) { + error("Peer refused to agree to our IP address"); + ipcp_close(f->unit, "Refused our 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 (ho->hisaddr == 0 && !noremoteip) { + ho->hisaddr = htonl(0x0a404040 + ifunit); + warn("Could not determine remote IP address: defaulting to %I", + ho->hisaddr); + } + script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); + if (ho->hisaddr != 0) + script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); - IPCPDEBUG(LOG_NOTICE, ("local IP address %s\n", inet_ntoa(go->ouraddr))); - IPCPDEBUG(LOG_NOTICE, ("remote IP address %s\n", inet_ntoa(ho->hisaddr))); - if (go->dnsaddr[0]) { - IPCPDEBUG(LOG_NOTICE, ("primary DNS address %s\n", inet_ntoa(go->dnsaddr[0]))); - } - if (go->dnsaddr[1]) { - IPCPDEBUG(LOG_NOTICE, ("secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1]))); - } + if (!go->req_dns1) + go->dnsaddr[0] = 0; + if (!go->req_dns2) + go->dnsaddr[1] = 0; + if (go->dnsaddr[0]) + script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); + if (go->dnsaddr[1]) + script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); + if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + script_setenv("USEPEERDNS", "1", 0); + create_resolv(go->dnsaddr[0], go->dnsaddr[1]); + } + +/* FIXME: check why it fails, just to know */ +#if 0 /* Unused */ + /* + * Check that the peer is allowed to use the IP address it wants. + */ + if (ho->hisaddr != 0 && !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; + } +#endif /* Unused */ + + /* 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); + script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); + wo->ouraddr = go->ouraddr; + } else + script_unsetenv("OLDIPLOCAL"); + if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) { + warn("Remote IP address changed to %I", ho->hisaddr); + script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); + wo->hisaddr = ho->hisaddr; + } else + script_unsetenv("OLDIPREMOTE"); + + /* 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 (ho->hisaddr != 0 && 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 + + /* run the pre-up script, if any, and wait for it to finish */ + ipcp_script(_PATH_IPPREUP, 1); + + /* 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 (ho->hisaddr != 0 && 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); + if (ho->hisaddr != 0) + 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]); + } + + reset_link_stats(f->unit); + + np_up(f->unit, PPP_IP); + ipcp_is_up = 1; + + notify(ip_up_notifier, 0); + if (ip_up_hook) + ip_up_hook(); + + /* + * Execute the ip-up script, like this: + * /etc/ppp/ip-up interface tty speed local-IP remote-IP + */ + if (ipcp_script_state == s_down && ipcp_script_pid == 0) { + ipcp_script_state = s_up; + ipcp_script(_PATH_IPUP, 0); + } } @@ -1307,32 +1956,68 @@ ipcp_up(fsm *f) * and delete routes through it. */ static void -ipcp_down(fsm *f) +ipcp_down(f) + fsm *f; { - IPCPDEBUG(LOG_INFO, ("ipcp: down\n")); - np_down(f->unit, PPP_IP); - sifvjcomp(f->unit, 0, 0, 0); + IPCPDEBUG(("ipcp: down")); + /* XXX a bit IPv4-centric here, we only need to get the stats + * before the interface is marked down. */ + /* XXX more correct: we must get the stats before running the notifiers, + * at least for the radius plugin */ + update_link_stats(f->unit); + notify(ip_down_notifier, 0); + 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); - sifdown(f->unit); - ipcp_clear_addrs(f->unit); + print_link_stats(); /* _after_ running the notifiers and ip_down_hook(), + * because print_link_stats() sets link_stats_valid + * to 0 (zero) */ + + /* + * 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); + } + + /* Execute the ip-down script */ + if (ipcp_script_state == s_up && ipcp_script_pid == 0) { + ipcp_script_state = s_down; + ipcp_script(_PATH_IPDOWN, 0); + } } /* - * ipcp_clear_addrs() - clear the interface addresses, routes, etc. + * ipcp_clear_addrs() - clear the interface addresses, routes, + * proxy arp entries, etc. */ static void -ipcp_clear_addrs(int unit) +ipcp_clear_addrs(unit, ouraddr, hisaddr) + int unit; + u_int32_t ouraddr; /* local address */ + u_int32_t hisaddr; /* remote address */ { - u32_t ouraddr, hisaddr; - - ouraddr = ipcp_gotoptions[unit].ouraddr; - hisaddr = ipcp_hisoptions[unit].hisaddr; - if (default_route_set[unit]) { - cifdefaultroute(unit, ouraddr, hisaddr); - default_route_set[unit] = 0; - } - cifaddr(unit, ouraddr, hisaddr); + 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); } @@ -1340,20 +2025,225 @@ ipcp_clear_addrs(int unit) * ipcp_finished - possibly shut down the lower layers. */ static void -ipcp_finished(fsm *f) +ipcp_finished(f) + fsm *f; { - np_finished(f->unit, PPP_IP); + if (ipcp_is_open) { + ipcp_is_open = 0; + np_finished(f->unit, PPP_IP); + } } -#if PPP_ADDITIONAL_CALLBACKS -static int -ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) + +/* + * ipcp_script_done - called when the ip-up or ip-down script + * has finished. + */ +static void +ipcp_script_done(arg) + void *arg; { - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(plen); - LWIP_UNUSED_ARG(printer); - LWIP_UNUSED_ARG(arg); - return 0; + ipcp_script_pid = 0; + switch (ipcp_script_state) { + case s_up: + if (ipcp_fsm[0].state != OPENED) { + ipcp_script_state = s_down; + ipcp_script(_PATH_IPDOWN, 0); + } + break; + case s_down: + if (ipcp_fsm[0].state == OPENED) { + ipcp_script_state = s_up; + ipcp_script(_PATH_IPUP, 0); + } + break; + } +} + + +/* + * ipcp_script - Execute a script with arguments + * interface-name tty-name speed local-IP remote-IP. + */ +static void +ipcp_script(script, wait) + char *script; + int wait; +{ + char strspeed[32], strlocal[32], strremote[32]; + char *argv[8]; + + slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); + slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr); + slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr); + + argv[0] = script; + argv[1] = ifname; + argv[2] = devnam; + argv[3] = strspeed; + argv[4] = strlocal; + argv[5] = strremote; + argv[6] = ipparam; + argv[7] = NULL; + if (wait) + run_program(script, argv, 0, NULL, NULL, 1); + else + ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done, + NULL, 0); +} + +/* + * create_resolv - create the replacement resolv.conf file + */ +static void +create_resolv(peerdns1, peerdns2) + u_int32_t peerdns1, peerdns2; +{ + FILE *f; + + f = fopen(_PATH_RESOLV, "w"); + if (f == NULL) { + error("Failed to create %s: %m", _PATH_RESOLV); + return; + } + + if (peerdns1) + fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1)); + + if (peerdns2) + fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2)); + + if (ferror(f)) + error("Write failed to %s: %m", _PATH_RESOLV); + + fclose(f); +} + +/* + * ipcp_printpkt - print the contents of an IPCP packet. + */ +static char *ipcp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej" +}; + +static int +ipcp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + u_int32_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: 2), + 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((char *)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; } /* @@ -1361,51 +2251,47 @@ ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void * * 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 +#define IP_HDRLEN 20 /* bytes */ +#define IP_OFFMASK 0x1fff +#ifndef IPPROTO_TCP +#define IPPROTO_TCP 6 +#endif +#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]) +#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) +ip_active_pkt(pkt, len) + u_char *pkt; + int len; { - u_char *tcp; - int hlen; + 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) { + 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; - } - 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; } -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index de03f460..6cf14c99 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -1,98 +1,88 @@ -/***************************************************************************** -* ipcp.h - PPP IP NCP: Internet Protocol Network Control Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-04 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ /* * ipcp.h - IP Control Protocol definitions. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * $Id: ipcp.h,v 1.4 2010/01/18 20:49:43 goldsimon Exp $ + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipcp.h,v 1.14 2002/12/04 23:03:32 paulus Exp $ */ -#ifndef IPCP_H -#define IPCP_H - /* * Options. */ -#define CI_ADDRS 1 /* IP Addresses */ -#define CI_COMPRESSTYPE 2 /* Compression Type */ -#define CI_ADDR 3 +#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 128 /* Primary WINS value */ -#define CI_MS_DNS2 131 /* Secondary DNS value */ -#define CI_MS_WINS2 130 /* Secondary WINS value */ +#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 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 MAX_STATES 16 /* from slcompress.h */ -#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 */ +#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 { - u_int neg_addr : 1; /* Negotiate IP Address? */ - u_int old_addrs : 1; /* Use old (IP-Addresses) option? */ - u_int req_addr : 1; /* Ask peer to send IP address? */ - u_int default_route : 1; /* Assign default route through interface? */ - u_int proxy_arp : 1; /* Make proxy ARP entry for peer? */ - u_int neg_vj : 1; /* Van Jacobson Compression? */ - u_int old_vj : 1; /* use old (short) form of VJ option? */ - u_int accept_local : 1; /* accept peer's value for ouraddr */ - u_int accept_remote : 1; /* accept peer's value for hisaddr */ - u_int req_dns1 : 1; /* Ask peer to send primary DNS address? */ - u_int req_dns2 : 1; /* Ask peer to send secondary DNS address? */ - u_short vj_protocol; /* protocol value to use in VJ option */ - u_char maxslotindex; /* VJ slots - 1. */ - u_char cflag; /* VJ slot compression flag. */ - u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ - u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ - u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ + 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; + u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ + u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ + u_int32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ } ipcp_options; extern fsm ipcp_fsm[]; @@ -101,6 +91,6 @@ extern ipcp_options ipcp_gotoptions[]; extern ipcp_options ipcp_allowoptions[]; extern ipcp_options ipcp_hisoptions[]; -extern struct protent ipcp_protent; +char *ip_ntoa __P((u_int32_t)); -#endif /* IPCP_H */ +extern struct protent ipcp_protent; diff --git a/src/netif/ppp/ipv6cp.h b/src/netif/ppp/ipv6cp.h new file mode 100644 index 00000000..cc4568de --- /dev/null +++ b/src/netif/ppp/ipv6cp.h @@ -0,0 +1,171 @@ +/* + * ipv6cp.h - PPP IPV6 Control Protocol. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* Original version, based on RFC2023 : + + Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt + Économique ayant pour membres BULL S.A. et l'INRIA). + + Ce logiciel informatique est disponible aux conditions + usuelles dans la recherche, c'est-à-dire qu'il peut + être utilisé, copié, modifié, distribué à l'unique + condition que ce texte soit conservé afin que + l'origine de ce logiciel soit reconnue. + + Le nom de l'Institut National de Recherche en Informatique + et en Automatique (INRIA), de l'IMAG, ou d'une personne morale + ou physique ayant participé à l'élaboration de ce logiciel ne peut + être utilisé sans son accord préalable explicite. + + Ce logiciel est fourni tel quel sans aucune garantie, + support ou responsabilité d'aucune sorte. + Ce logiciel est dérivé de sources d'origine + "University of California at Berkeley" et + "Digital Equipment Corporation" couvertes par des copyrights. + + L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) + est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National + Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant + sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). + + This work has been done in the context of GIE DYADE (joint R & D venture + between BULL S.A. and INRIA). + + This software is available with usual "research" terms + with the aim of retain credits of the software. + Permission to use, copy, modify and distribute this software for any + purpose and without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies, + and the name of INRIA, IMAG, or any contributor not be used in advertising + or publicity pertaining to this material without the prior explicit + permission. The software is provided "as is" without any + warranties, support or liabilities of any kind. + This software is derived from source code from + "University of California at Berkeley" and + "Digital Equipment Corporation" protected by copyrights. + + Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) + is a federation of seven research units funded by the CNRS, National + Polytechnic Institute of Grenoble and University Joseph Fourier. + The research unit in Software, Systems, Networks (LSR) is member of IMAG. +*/ + +/* + * Derived from : + * + * + * ipcp.h - IP Control Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $ + */ + +/* + * Options. + */ +#define CI_IFACEID 1 /* Interface Identifier */ +#define CI_COMPRESSTYPE 2 /* Compression Type */ + +/* No compression types yet defined. + *#define IPV6CP_COMP 0x004f + */ +typedef struct ipv6cp_options { + int neg_ifaceid; /* Negotiate interface identifier? */ + int req_ifaceid; /* Ask peer to send interface identifier? */ + int accept_local; /* accept peer's value for iface id? */ + int opt_local; /* ourtoken set by option */ + int opt_remote; /* histoken set by option */ + int use_ip; /* use IP as interface identifier */ +#if defined(SOL2) || defined(__linux__) + int use_persistent; /* use uniquely persistent value for address */ +#endif /* defined(SOL2) */ + int neg_vj; /* Van Jacobson Compression? */ + u_short vj_protocol; /* protocol value to use in VJ option */ + eui64_t ourid, hisid; /* Interface identifiers */ +} ipv6cp_options; + +extern fsm ipv6cp_fsm[]; +extern ipv6cp_options ipv6cp_wantoptions[]; +extern ipv6cp_options ipv6cp_gotoptions[]; +extern ipv6cp_options ipv6cp_allowoptions[]; +extern ipv6cp_options ipv6cp_hisoptions[]; + +extern struct protent ipv6cp_protent; diff --git a/src/netif/ppp/ipxcp.c b/src/netif/ppp/ipxcp.c new file mode 100644 index 00000000..8c8ba69a --- /dev/null +++ b/src/netif/ppp/ipxcp.c @@ -0,0 +1,1600 @@ +/* + * ipxcp.c - PPP IPX Control Protocol. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#ifdef IPX_CHANGE + +#define RCSID "$Id: ipxcp.c,v 1.24 2005/08/25 23:59:34 paulus Exp $" + +/* + * TODO: + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pppd.h" +#include "fsm.h" +#include "ipxcp.h" +#include "pathnames.h" +#include "magic.h" + +static const char rcsid[] = RCSID; + +/* global vars */ +ipxcp_options ipxcp_wantoptions[NUM_PPP]; /* Options that we want to request */ +ipxcp_options ipxcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ +ipxcp_options ipxcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ +ipxcp_options ipxcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ + +#define wo (&ipxcp_wantoptions[0]) +#define ao (&ipxcp_allowoptions[0]) +#define go (&ipxcp_gotoptions[0]) +#define ho (&ipxcp_hisoptions[0]) + +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void ipxcp_resetci __P((fsm *)); /* Reset our CI */ +static int ipxcp_cilen __P((fsm *)); /* Return length of our CI */ +static void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ +static int ipxcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ +static int ipxcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ +static int ipxcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ +static int ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ +static void ipxcp_up __P((fsm *)); /* We're UP */ +static void ipxcp_down __P((fsm *)); /* We're DOWN */ +static void ipxcp_finished __P((fsm *)); /* Don't need lower layer */ +static void ipxcp_script __P((fsm *, char *)); /* Run an up/down script */ + +fsm ipxcp_fsm[NUM_PPP]; /* IPXCP fsm structure */ + +static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */ + ipxcp_resetci, /* Reset our Configuration Information */ + ipxcp_cilen, /* Length of our Configuration Information */ + ipxcp_addci, /* Add our Configuration Information */ + ipxcp_ackci, /* ACK our Configuration Information */ + ipxcp_nakci, /* NAK our Configuration Information */ + ipxcp_rejci, /* Reject our Configuration Information */ + ipxcp_reqci, /* Request peer's Configuration Information */ + ipxcp_up, /* Called when fsm reaches OPENED state */ + ipxcp_down, /* Called when fsm leaves OPENED state */ + NULL, /* Called when we want the lower layer up */ + ipxcp_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 */ + "IPXCP" /* String name of protocol */ +}; + +/* + * Command-line options. + */ +static int setipxnode __P((char **)); +static void printipxnode __P((option_t *, + void (*)(void *, char *, ...), void *)); +static int setipxname __P((char **)); + +static option_t ipxcp_option_list[] = { + { "ipx", o_bool, &ipxcp_protent.enabled_flag, + "Enable IPXCP (and IPX)", OPT_PRIO | 1 }, + { "+ipx", o_bool, &ipxcp_protent.enabled_flag, + "Enable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS | 1 }, + { "noipx", o_bool, &ipxcp_protent.enabled_flag, + "Disable IPXCP (and IPX)", OPT_PRIOSUB }, + { "-ipx", o_bool, &ipxcp_protent.enabled_flag, + "Disable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS }, + + { "ipx-network", o_uint32, &ipxcp_wantoptions[0].our_network, + "Set our IPX network number", OPT_PRIO, &ipxcp_wantoptions[0].neg_nn }, + + { "ipxcp-accept-network", o_bool, &ipxcp_wantoptions[0].accept_network, + "Accept peer IPX network number", 1, + &ipxcp_allowoptions[0].accept_network }, + + { "ipx-node", o_special, (void *)setipxnode, + "Set IPX node number", OPT_A2PRINTER, (void *)printipxnode }, + + { "ipxcp-accept-local", o_bool, &ipxcp_wantoptions[0].accept_local, + "Accept our IPX address", 1, + &ipxcp_allowoptions[0].accept_local }, + + { "ipxcp-accept-remote", o_bool, &ipxcp_wantoptions[0].accept_remote, + "Accept peer's IPX address", 1, + &ipxcp_allowoptions[0].accept_remote }, + + { "ipx-routing", o_int, &ipxcp_wantoptions[0].router, + "Set IPX routing proto number", OPT_PRIO, + &ipxcp_wantoptions[0].neg_router }, + + { "ipx-router-name", o_special, setipxname, + "Set IPX router name", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, + &ipxcp_wantoptions[0].name }, + + { "ipxcp-restart", o_int, &ipxcp_fsm[0].timeouttime, + "Set timeout for IPXCP", OPT_PRIO }, + { "ipxcp-max-terminate", o_int, &ipxcp_fsm[0].maxtermtransmits, + "Set max #xmits for IPXCP term-reqs", OPT_PRIO }, + { "ipxcp-max-configure", o_int, &ipxcp_fsm[0].maxconfreqtransmits, + "Set max #xmits for IPXCP conf-reqs", OPT_PRIO }, + { "ipxcp-max-failure", o_int, &ipxcp_fsm[0].maxnakloops, + "Set max #conf-naks for IPXCP", OPT_PRIO }, + + { NULL } +}; + +/* + * Protocol entry points. + */ + +static void ipxcp_init __P((int)); +static void ipxcp_open __P((int)); +static void ipxcp_close __P((int, char *)); +static void ipxcp_lowerup __P((int)); +static void ipxcp_lowerdown __P((int)); +static void ipxcp_input __P((int, u_char *, int)); +static void ipxcp_protrej __P((int)); +static int ipxcp_printpkt __P((u_char *, int, + void (*) __P((void *, char *, ...)), void *)); + +struct protent ipxcp_protent = { + PPP_IPXCP, + ipxcp_init, + ipxcp_input, + ipxcp_protrej, + ipxcp_lowerup, + ipxcp_lowerdown, + ipxcp_open, + ipxcp_close, + ipxcp_printpkt, + NULL, + 0, + "IPXCP", + "IPX", + ipxcp_option_list, + NULL, + NULL, + NULL +}; + +/* + * Lengths of configuration options. + */ + +#define CILEN_VOID 2 +#define CILEN_COMPLETE 2 /* length of complete option */ +#define CILEN_NETN 6 /* network number length option */ +#define CILEN_NODEN 8 /* node number length option */ +#define CILEN_PROTOCOL 4 /* Minimum length of routing protocol */ +#define CILEN_NAME 3 /* Minimum length of router name */ +#define CILEN_COMPRESS 4 /* Minimum length of compression protocol */ + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + +static int ipxcp_is_up; + +static char *ipx_ntoa __P((u_int32_t)); + +/* Used in printing the node number */ +#define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5] + +/* Used to generate the proper bit mask */ +#define BIT(num) (1 << (num)) + +/* + * Convert from internal to external notation + */ + +static short int +to_external(internal) +short int internal; +{ + short int external; + + if (internal & BIT(IPX_NONE) ) + external = IPX_NONE; + else + external = RIP_SAP; + + return external; +} + +/* + * Make a string representation of a network IP address. + */ + +static char * +ipx_ntoa(ipxaddr) +u_int32_t ipxaddr; +{ + static char b[64]; + slprintf(b, sizeof(b), "%x", ipxaddr); + return b; +} + + +static u_char * +setipxnodevalue(src,dst) +u_char *src, *dst; +{ + int indx; + int item; + + for (;;) { + if (!isxdigit (*src)) + break; + + for (indx = 0; indx < 5; ++indx) { + dst[indx] <<= 4; + dst[indx] |= (dst[indx + 1] >> 4) & 0x0F; + } + + item = toupper (*src) - '0'; + if (item > 9) + item -= 7; + + dst[5] = (dst[5] << 4) | item; + ++src; + } + return src; +} + +static int ipx_prio_our, ipx_prio_his; + +static int +setipxnode(argv) + char **argv; +{ + u_char *end; + int have_his = 0; + u_char our_node[6]; + u_char his_node[6]; + + memset (our_node, 0, 6); + memset (his_node, 0, 6); + + end = setipxnodevalue (*argv, our_node); + if (*end == ':') { + have_his = 1; + end = setipxnodevalue (++end, his_node); + } + + if (*end == '\0') { + ipxcp_wantoptions[0].neg_node = 1; + if (option_priority >= ipx_prio_our) { + memcpy(&ipxcp_wantoptions[0].our_node[0], our_node, 6); + ipx_prio_our = option_priority; + } + if (have_his && option_priority >= ipx_prio_his) { + memcpy(&ipxcp_wantoptions[0].his_node[0], his_node, 6); + ipx_prio_his = option_priority; + } + return 1; + } + + option_error("invalid parameter '%s' for ipx-node option", *argv); + return 0; +} + +static void +printipxnode(opt, printer, arg) + option_t *opt; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + unsigned char *p; + + p = ipxcp_wantoptions[0].our_node; + if (ipx_prio_our) + printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x", + p[0], p[1], p[2], p[3], p[4], p[5]); + printer(arg, ":"); + p = ipxcp_wantoptions[0].his_node; + if (ipx_prio_his) + printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x", + p[0], p[1], p[2], p[3], p[4], p[5]); +} + +static int +setipxname (argv) + char **argv; +{ + u_char *dest = ipxcp_wantoptions[0].name; + char *src = *argv; + int count; + char ch; + + ipxcp_wantoptions[0].neg_name = 1; + ipxcp_allowoptions[0].neg_name = 1; + memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name)); + + count = 0; + while (*src) { + ch = *src++; + if (! isalnum (ch) && ch != '_') { + option_error("IPX router name must be alphanumeric or _"); + return 0; + } + + if (count >= sizeof (ipxcp_wantoptions[0].name) - 1) { + option_error("IPX router name is limited to %d characters", + sizeof (ipxcp_wantoptions[0].name) - 1); + return 0; + } + + dest[count++] = toupper (ch); + } + dest[count] = 0; + + return 1; +} + +/* + * ipxcp_init - Initialize IPXCP. + */ +static void +ipxcp_init(unit) + int unit; +{ + fsm *f = &ipxcp_fsm[unit]; + + f->unit = unit; + f->protocol = PPP_IPXCP; + f->callbacks = &ipxcp_callbacks; + fsm_init(&ipxcp_fsm[unit]); + + memset (wo->name, 0, sizeof (wo->name)); + memset (wo->our_node, 0, sizeof (wo->our_node)); + memset (wo->his_node, 0, sizeof (wo->his_node)); + + wo->neg_nn = 1; + wo->neg_complete = 1; + wo->network = 0; + + ao->neg_node = 1; + ao->neg_nn = 1; + ao->neg_name = 1; + ao->neg_complete = 1; + ao->neg_router = 1; + + ao->accept_local = 0; + ao->accept_remote = 0; + ao->accept_network = 0; + + wo->tried_rip = 0; + wo->tried_nlsp = 0; +} + +/* + * Copy the node number + */ + +static void +copy_node (src, dst) +u_char *src, *dst; +{ + memcpy (dst, src, sizeof (ipxcp_wantoptions[0].our_node)); +} + +/* + * Compare node numbers + */ + +static int +compare_node (src, dst) +u_char *src, *dst; +{ + return memcmp (dst, src, sizeof (ipxcp_wantoptions[0].our_node)) == 0; +} + +/* + * Is the node number zero? + */ + +static int +zero_node (node) +u_char *node; +{ + int indx; + for (indx = 0; indx < sizeof (ipxcp_wantoptions[0].our_node); ++indx) + if (node [indx] != 0) + return 0; + return 1; +} + +/* + * Increment the node number + */ + +static void +inc_node (node) +u_char *node; +{ + u_char *outp; + u_int32_t magic_num; + + outp = node; + magic_num = magic(); + *outp++ = '\0'; + *outp++ = '\0'; + PUTLONG (magic_num, outp); +} + +/* + * ipxcp_open - IPXCP is allowed to come up. + */ +static void +ipxcp_open(unit) + int unit; +{ + fsm_open(&ipxcp_fsm[unit]); +} + +/* + * ipxcp_close - Take IPXCP down. + */ +static void +ipxcp_close(unit, reason) + int unit; + char *reason; +{ + fsm_close(&ipxcp_fsm[unit], reason); +} + + +/* + * ipxcp_lowerup - The lower layer is up. + */ +static void +ipxcp_lowerup(unit) + int unit; +{ + fsm_lowerup(&ipxcp_fsm[unit]); +} + + +/* + * ipxcp_lowerdown - The lower layer is down. + */ +static void +ipxcp_lowerdown(unit) + int unit; +{ + fsm_lowerdown(&ipxcp_fsm[unit]); +} + + +/* + * ipxcp_input - Input IPXCP packet. + */ +static void +ipxcp_input(unit, p, len) + int unit; + u_char *p; + int len; +{ + fsm_input(&ipxcp_fsm[unit], p, len); +} + + +/* + * ipxcp_protrej - A Protocol-Reject was received for IPXCP. + * + * Pretend the lower layer went down, so we shut up. + */ +static void +ipxcp_protrej(unit) + int unit; +{ + fsm_lowerdown(&ipxcp_fsm[unit]); +} + + +/* + * ipxcp_resetci - Reset our CI. + */ +static void +ipxcp_resetci(f) + fsm *f; +{ + wo->req_node = wo->neg_node && ao->neg_node; + wo->req_nn = wo->neg_nn && ao->neg_nn; + + if (wo->our_network == 0) { + wo->neg_node = 1; + ao->accept_network = 1; + } +/* + * If our node number is zero then change it. + */ + if (zero_node (wo->our_node)) { + inc_node (wo->our_node); + ao->accept_local = 1; + wo->neg_node = 1; + } +/* + * If his node number is zero then change it. + */ + if (zero_node (wo->his_node)) { + inc_node (wo->his_node); + ao->accept_remote = 1; + } +/* + * If no routing agent was specified then we do RIP/SAP according to the + * RFC documents. If you have specified something then OK. Otherwise, we + * do RIP/SAP. + */ + if (ao->router == 0) { + ao->router |= BIT(RIP_SAP); + wo->router |= BIT(RIP_SAP); + } + + /* Always specify a routing protocol unless it was REJected. */ + wo->neg_router = 1; +/* + * Start with these default values + */ + *go = *wo; +} + +/* + * ipxcp_cilen - Return length of our CI. + */ + +static int +ipxcp_cilen(f) + fsm *f; +{ + int len; + + len = go->neg_nn ? CILEN_NETN : 0; + len += go->neg_node ? CILEN_NODEN : 0; + len += go->neg_name ? CILEN_NAME + strlen ((char *)go->name) - 1 : 0; + + /* RFC says that defaults should not be included. */ + if (go->neg_router && to_external(go->router) != RIP_SAP) + len += CILEN_PROTOCOL; + + return (len); +} + + +/* + * ipxcp_addci - Add our desired CIs to a packet. + */ +static void +ipxcp_addci(f, ucp, lenp) + fsm *f; + u_char *ucp; + int *lenp; +{ +/* + * Add the options to the record. + */ + if (go->neg_nn) { + PUTCHAR (IPX_NETWORK_NUMBER, ucp); + PUTCHAR (CILEN_NETN, ucp); + PUTLONG (go->our_network, ucp); + } + + if (go->neg_node) { + int indx; + PUTCHAR (IPX_NODE_NUMBER, ucp); + PUTCHAR (CILEN_NODEN, ucp); + for (indx = 0; indx < sizeof (go->our_node); ++indx) + PUTCHAR (go->our_node[indx], ucp); + } + + if (go->neg_name) { + int cilen = strlen ((char *)go->name); + int indx; + PUTCHAR (IPX_ROUTER_NAME, ucp); + PUTCHAR (CILEN_NAME + cilen - 1, ucp); + for (indx = 0; indx < cilen; ++indx) + PUTCHAR (go->name [indx], ucp); + } + + if (go->neg_router) { + short external = to_external (go->router); + if (external != RIP_SAP) { + PUTCHAR (IPX_ROUTER_PROTOCOL, ucp); + PUTCHAR (CILEN_PROTOCOL, ucp); + PUTSHORT (external, ucp); + } + } +} + +/* + * ipxcp_ackci - Ack our CIs. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int +ipxcp_ackci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + u_short cilen, citype, cishort; + u_char cichar; + u_int32_t cilong; + +#define ACKCIVOID(opt, neg) \ + if (neg) { \ + if ((len -= CILEN_VOID) < 0) \ + break; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_VOID || \ + citype != opt) \ + break; \ + } + +#define ACKCICOMPLETE(opt,neg) ACKCIVOID(opt, neg) + +#define ACKCICHARS(opt, neg, val, cnt) \ + if (neg) { \ + int indx, count = cnt; \ + len -= (count + 2); \ + if (len < 0) \ + break; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != (count + 2) || \ + citype != opt) \ + break; \ + for (indx = 0; indx < count; ++indx) {\ + GETCHAR(cichar, p); \ + if (cichar != ((u_char *) &val)[indx]) \ + break; \ + }\ + if (indx != count) \ + break; \ + } + +#define ACKCINODE(opt,neg,val) ACKCICHARS(opt,neg,val,sizeof(val)) +#define ACKCINAME(opt,neg,val) ACKCICHARS(opt,neg,val,strlen((char *)val)) + +#define ACKCINETWORK(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_NETN) < 0) \ + break; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_NETN || \ + citype != opt) \ + break; \ + GETLONG(cilong, p); \ + if (cilong != val) \ + break; \ + } + +#define ACKCIPROTO(opt, neg, val) \ + if (neg) { \ + if (len < 2) \ + break; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_PROTOCOL || citype != opt) \ + break; \ + len -= cilen; \ + if (len < 0) \ + break; \ + GETSHORT(cishort, p); \ + if (cishort != to_external (val) || cishort == RIP_SAP) \ + break; \ + } +/* + * Process the ACK frame in the order in which the frame was assembled + */ + do { + ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network); + ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node); + ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name); + if (len > 0) + ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); +/* + * This is the end of the record. + */ + if (len == 0) + return (1); + } while (0); +/* + * The frame is invalid + */ + IPXCPDEBUG(("ipxcp_ackci: received bad Ack!")); + return (0); +} + +/* + * ipxcp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if IPXCP is in the OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ + +static int +ipxcp_nakci(f, p, len, treat_as_reject) + fsm *f; + u_char *p; + int len; + int treat_as_reject; +{ + u_char citype, cilen, *next; + u_short s; + u_int32_t l; + ipxcp_options no; /* options we've seen Naks for */ + ipxcp_options try; /* options to request next time */ + + BZERO(&no, sizeof(no)); + try = *go; + + while (len >= CILEN_VOID) { + GETCHAR (citype, p); + GETCHAR (cilen, p); + len -= cilen; + if (cilen < CILEN_VOID || len < 0) + goto bad; + next = &p [cilen - CILEN_VOID]; + + switch (citype) { + case IPX_NETWORK_NUMBER: + if (!go->neg_nn || no.neg_nn || (cilen != CILEN_NETN)) + goto bad; + no.neg_nn = 1; + + GETLONG(l, p); + if (treat_as_reject) + try.neg_nn = 0; + else if (l && ao->accept_network) + try.our_network = l; + break; + + case IPX_NODE_NUMBER: + if (!go->neg_node || no.neg_node || (cilen != CILEN_NODEN)) + goto bad; + no.neg_node = 1; + + if (treat_as_reject) + try.neg_node = 0; + else if (!zero_node (p) && ao->accept_local && + ! compare_node (p, ho->his_node)) + copy_node (p, try.our_node); + break; + + /* This has never been sent. Ignore the NAK frame */ + case IPX_COMPRESSION_PROTOCOL: + goto bad; + + case IPX_ROUTER_PROTOCOL: + if (!go->neg_router || (cilen < CILEN_PROTOCOL)) + goto bad; + + GETSHORT (s, p); + if (s > 15) /* This is just bad, but ignore for now. */ + break; + + s = BIT(s); + if (no.router & s) /* duplicate NAKs are always bad */ + goto bad; + + if (no.router == 0) /* Reset on first NAK only */ + try.router = 0; + + no.router |= s; + try.router |= s; + try.neg_router = 1; + break; + + /* These, according to the RFC, must never be NAKed. */ + case IPX_ROUTER_NAME: + case IPX_COMPLETE: + goto bad; + + /* These are for options which we have not seen. */ + default: + break; + } + p = next; + } + + /* + * Do not permit the peer to force a router protocol which we do not + * support. However, default to the condition that will accept "NONE". + */ + try.router &= (ao->router | BIT(IPX_NONE)); + if (try.router == 0 && ao->router != 0) + try.router = BIT(IPX_NONE); + + if (try.router != 0) + try.neg_router = 1; + + /* + * OK, the Nak is good. Now we can update state. + * If there are any options left, we ignore them. + */ + if (f->state != OPENED) + *go = try; + + return 1; + +bad: + IPXCPDEBUG(("ipxcp_nakci: received bad Nak!")); + return 0; +} + +/* + * ipxcp_rejci - Reject some of our CIs. + */ +static int +ipxcp_rejci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + u_short cilen, citype, cishort; + u_char cichar; + u_int32_t cilong; + ipxcp_options try; /* options to request next time */ + +#define REJCINETWORK(opt, neg, val) \ + if (neg && p[0] == opt) { \ + if ((len -= CILEN_NETN) < 0) \ + break; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_NETN || \ + citype != opt) \ + break; \ + GETLONG(cilong, p); \ + if (cilong != val) \ + break; \ + neg = 0; \ + } + +#define REJCICHARS(opt, neg, val, cnt) \ + if (neg && p[0] == opt) { \ + int indx, count = cnt; \ + len -= (count + 2); \ + if (len < 0) \ + break; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != (count + 2) || \ + citype != opt) \ + break; \ + for (indx = 0; indx < count; ++indx) {\ + GETCHAR(cichar, p); \ + if (cichar != ((u_char *) &val)[indx]) \ + break; \ + }\ + if (indx != count) \ + break; \ + neg = 0; \ + } + +#define REJCINODE(opt,neg,val) REJCICHARS(opt,neg,val,sizeof(val)) +#define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen((char *)val)) + +#define REJCIVOID(opt, neg) \ + if (neg && p[0] == opt) { \ + if ((len -= CILEN_VOID) < 0) \ + break; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_VOID || citype != opt) \ + break; \ + neg = 0; \ + } + +/* a reject for RIP/SAP is invalid since we don't send it and you can't + reject something which is not sent. (You can NAK, but you can't REJ.) */ +#define REJCIPROTO(opt, neg, val, bit) \ + if (neg && p[0] == opt) { \ + if ((len -= CILEN_PROTOCOL) < 0) \ + break; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_PROTOCOL) \ + break; \ + GETSHORT(cishort, p); \ + if (cishort != to_external (val) || cishort == RIP_SAP) \ + break; \ + neg = 0; \ + } +/* + * 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. + */ + try = *go; + + do { + REJCINETWORK (IPX_NETWORK_NUMBER, try.neg_nn, try.our_network); + REJCINODE (IPX_NODE_NUMBER, try.neg_node, try.our_node); + REJCINAME (IPX_ROUTER_NAME, try.neg_name, try.name); + REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 0); +/* + * This is the end of the record. + */ + if (len == 0) { + if (f->state != OPENED) + *go = try; + return (1); + } + } while (0); +/* + * The frame is invalid at this point. + */ + IPXCPDEBUG(("ipxcp_rejci: received bad Reject!")); + return 0; +} + +/* + * ipxcp_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 +ipxcp_reqci(f, inp, len, reject_if_disagree) + fsm *f; + u_char *inp; /* Requested CIs */ + int *len; /* Length of requested CIs */ + int reject_if_disagree; +{ + u_char *cip, *next; /* Pointer to current and next CIs */ + u_short cilen, citype; /* Parsed len, type */ + u_short cishort; /* Parsed short value */ + u_int32_t cinetwork; /* 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 */ + + /* + * 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? */ + IPXCPDEBUG(("ipxcp_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 */ +/* + * The network number must match. Choose the larger of the two. + */ + case IPX_NETWORK_NUMBER: + /* if we wont negotiate the network number or the length is wrong + then reject the option */ + if ( !ao->neg_nn || cilen != CILEN_NETN ) { + orc = CONFREJ; + break; + } + GETLONG(cinetwork, p); + + /* If the network numbers match then acknowledge them. */ + if (cinetwork != 0) { + ho->his_network = cinetwork; + ho->neg_nn = 1; + if (wo->our_network == cinetwork) + break; +/* + * If the network number is not given or we don't accept their change or + * the network number is too small then NAK it. + */ + if (! ao->accept_network || cinetwork < wo->our_network) { + DECPTR (sizeof (u_int32_t), p); + PUTLONG (wo->our_network, p); + orc = CONFNAK; + } + break; + } +/* + * The peer sent '0' for the network. Give it ours if we have one. + */ + if (go->our_network != 0) { + DECPTR (sizeof (u_int32_t), p); + PUTLONG (wo->our_network, p); + orc = CONFNAK; +/* + * We don't have one. Reject the value. + */ + } else + orc = CONFREJ; + + break; +/* + * The node number is required + */ + case IPX_NODE_NUMBER: + /* if we wont negotiate the node number or the length is wrong + then reject the option */ + if ( cilen != CILEN_NODEN ) { + orc = CONFREJ; + break; + } + + copy_node (p, ho->his_node); + ho->neg_node = 1; +/* + * If the remote does not have a number and we do then NAK it with the value + * which we have for it. (We never have a default value of zero.) + */ + if (zero_node (ho->his_node)) { + orc = CONFNAK; + copy_node (wo->his_node, p); + INCPTR (sizeof (wo->his_node), p); + break; + } +/* + * If you have given me the expected network node number then I'll accept + * it now. + */ + if (compare_node (wo->his_node, ho->his_node)) { + orc = CONFACK; + ho->neg_node = 1; + INCPTR (sizeof (wo->his_node), p); + break; + } +/* + * If his node number is the same as ours then ask him to try the next + * value. + */ + if (compare_node (ho->his_node, go->our_node)) { + inc_node (ho->his_node); + orc = CONFNAK; + copy_node (ho->his_node, p); + INCPTR (sizeof (wo->his_node), p); + break; + } +/* + * If we don't accept a new value then NAK it. + */ + if (! ao->accept_remote) { + copy_node (wo->his_node, p); + INCPTR (sizeof (wo->his_node), p); + orc = CONFNAK; + break; + } + orc = CONFACK; + ho->neg_node = 1; + INCPTR (sizeof (wo->his_node), p); + break; +/* + * Compression is not desired at this time. It is always rejected. + */ + case IPX_COMPRESSION_PROTOCOL: + orc = CONFREJ; + break; +/* + * The routing protocol is a bitmask of various types. Any combination + * of the values RIP_SAP and NLSP are permissible. 'IPX_NONE' for no + * routing protocol must be specified only once. + */ + case IPX_ROUTER_PROTOCOL: + if ( !ao->neg_router || cilen < CILEN_PROTOCOL ) { + orc = CONFREJ; + break; + } + + GETSHORT (cishort, p); + + if (wo->neg_router == 0) { + wo->neg_router = 1; + wo->router = BIT(IPX_NONE); + } + + if ((cishort == IPX_NONE && ho->router != 0) || + (ho->router & BIT(IPX_NONE))) { + orc = CONFREJ; + break; + } + + cishort = BIT(cishort); + if (ho->router & cishort) { + orc = CONFREJ; + break; + } + + ho->router |= cishort; + ho->neg_router = 1; + + /* Finally do not allow a router protocol which we do not + support. */ + + if ((cishort & (ao->router | BIT(IPX_NONE))) == 0) { + int protocol; + + if (cishort == BIT(NLSP) && + (ao->router & BIT(RIP_SAP)) && + !wo->tried_rip) { + protocol = RIP_SAP; + wo->tried_rip = 1; + } else + protocol = IPX_NONE; + + DECPTR (sizeof (u_int16_t), p); + PUTSHORT (protocol, p); + orc = CONFNAK; + } + break; +/* + * The router name is advisorary. Just accept it if it is not too large. + */ + case IPX_ROUTER_NAME: + if (cilen >= CILEN_NAME) { + int name_size = cilen - CILEN_NAME; + if (name_size > sizeof (ho->name)) + name_size = sizeof (ho->name) - 1; + memset (ho->name, 0, sizeof (ho->name)); + memcpy (ho->name, p, name_size); + ho->name [name_size] = '\0'; + ho->neg_name = 1; + orc = CONFACK; + break; + } + orc = CONFREJ; + break; +/* + * This is advisorary. + */ + case IPX_COMPLETE: + if (cilen != CILEN_COMPLETE) + orc = CONFREJ; + else { + ho->neg_complete = 1; + orc = CONFACK; + } + break; +/* + * All other entries are not known at this time. + */ + 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 */ + 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 IPX_NODE_NUMBER option appended. We assume the + * input buffer is long enough that we can append the extra + * option safely. + */ + + if (rc != CONFREJ && !ho->neg_node && + wo->req_nn && !reject_if_disagree) { + if (rc == CONFACK) { + rc = CONFNAK; + wo->req_nn = 0; /* don't ask again */ + ucp = inp; /* reset pointer */ + } + + if (zero_node (wo->his_node)) + inc_node (wo->his_node); + + PUTCHAR (IPX_NODE_NUMBER, ucp); + PUTCHAR (CILEN_NODEN, ucp); + copy_node (wo->his_node, ucp); + INCPTR (sizeof (wo->his_node), ucp); + } + + *len = ucp - inp; /* Compute output length */ + IPXCPDEBUG(("ipxcp: returning Configure-%s", CODENAME(rc))); + return (rc); /* Return final code */ +} + +/* + * ipxcp_up - IPXCP has come UP. + * + * Configure the IP network interface appropriately and bring it up. + */ + +static void +ipxcp_up(f) + fsm *f; +{ + int unit = f->unit; + + IPXCPDEBUG(("ipxcp: up")); + + /* The default router protocol is RIP/SAP. */ + if (ho->router == 0) + ho->router = BIT(RIP_SAP); + + if (go->router == 0) + go->router = BIT(RIP_SAP); + + /* Fetch the network number */ + if (!ho->neg_nn) + ho->his_network = wo->his_network; + + if (!ho->neg_node) + copy_node (wo->his_node, ho->his_node); + + if (!wo->neg_node && !go->neg_node) + copy_node (wo->our_node, go->our_node); + + if (zero_node (go->our_node)) { + static char errmsg[] = "Could not determine local IPX node address"; + if (debug) + error(errmsg); + ipxcp_close(f->unit, errmsg); + return; + } + + go->network = go->our_network; + if (ho->his_network != 0 && ho->his_network > go->network) + go->network = ho->his_network; + + if (go->network == 0) { + static char errmsg[] = "Can not determine network number"; + if (debug) + error(errmsg); + ipxcp_close (unit, errmsg); + return; + } + + /* bring the interface up */ + if (!sifup(unit)) { + if (debug) + warn("sifup failed (IPX)"); + ipxcp_close(unit, "Interface configuration failed"); + return; + } + ipxcp_is_up = 1; + + /* set the network number for IPX */ + if (!sipxfaddr(unit, go->network, go->our_node)) { + if (debug) + warn("sipxfaddr failed"); + ipxcp_close(unit, "Interface configuration failed"); + return; + } + + np_up(f->unit, PPP_IPX); + + /* + * Execute the ipx-up script, like this: + * /etc/ppp/ipx-up interface tty speed local-IPX remote-IPX + */ + + ipxcp_script (f, _PATH_IPXUP); +} + +/* + * ipxcp_down - IPXCP has gone DOWN. + * + * Take the IP network interface down, clear its addresses + * and delete routes through it. + */ + +static void +ipxcp_down(f) + fsm *f; +{ + IPXCPDEBUG(("ipxcp: down")); + + if (!ipxcp_is_up) + return; + ipxcp_is_up = 0; + np_down(f->unit, PPP_IPX); + cipxfaddr(f->unit); + sifnpmode(f->unit, PPP_IPX, NPMODE_DROP); + sifdown(f->unit); + ipxcp_script (f, _PATH_IPXDOWN); +} + + +/* + * ipxcp_finished - possibly shut down the lower layers. + */ +static void +ipxcp_finished(f) + fsm *f; +{ + np_finished(f->unit, PPP_IPX); +} + + +/* + * ipxcp_script - Execute a script with arguments + * interface-name tty-name speed local-IPX remote-IPX networks. + */ +static void +ipxcp_script(f, script) + fsm *f; + char *script; +{ + char strspeed[32], strlocal[32], strremote[32]; + char strnetwork[32], strpid[32]; + char *argv[14], strproto_lcl[32], strproto_rmt[32]; + + slprintf(strpid, sizeof(strpid), "%d", getpid()); + slprintf(strspeed, sizeof(strspeed),"%d", baud_rate); + + strproto_lcl[0] = '\0'; + if (go->neg_router && ((go->router & BIT(IPX_NONE)) == 0)) { + if (go->router & BIT(RIP_SAP)) + strlcpy (strproto_lcl, "RIP ", sizeof(strproto_lcl)); + if (go->router & BIT(NLSP)) + strlcat (strproto_lcl, "NLSP ", sizeof(strproto_lcl)); + } + + if (strproto_lcl[0] == '\0') + strlcpy (strproto_lcl, "NONE ", sizeof(strproto_lcl)); + + strproto_lcl[strlen (strproto_lcl)-1] = '\0'; + + strproto_rmt[0] = '\0'; + if (ho->neg_router && ((ho->router & BIT(IPX_NONE)) == 0)) { + if (ho->router & BIT(RIP_SAP)) + strlcpy (strproto_rmt, "RIP ", sizeof(strproto_rmt)); + if (ho->router & BIT(NLSP)) + strlcat (strproto_rmt, "NLSP ", sizeof(strproto_rmt)); + } + + if (strproto_rmt[0] == '\0') + strlcpy (strproto_rmt, "NONE ", sizeof(strproto_rmt)); + + strproto_rmt[strlen (strproto_rmt)-1] = '\0'; + + strlcpy (strnetwork, ipx_ntoa (go->network), sizeof(strnetwork)); + + slprintf (strlocal, sizeof(strlocal), "%0.6B", go->our_node); + + slprintf (strremote, sizeof(strremote), "%0.6B", ho->his_node); + + argv[0] = script; + argv[1] = ifname; + argv[2] = devnam; + argv[3] = strspeed; + argv[4] = strnetwork; + argv[5] = strlocal; + argv[6] = strremote; + argv[7] = strproto_lcl; + argv[8] = strproto_rmt; + argv[9] = (char *)go->name; + argv[10] = (char *)ho->name; + argv[11] = ipparam; + argv[12] = strpid; + argv[13] = NULL; + run_program(script, argv, 0, NULL, NULL, 0); +} + +/* + * ipxcp_printpkt - print the contents of an IPXCP packet. + */ +static char *ipxcp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej" +}; + +static int +ipxcp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + u_int32_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(ipxcp_codenames) / sizeof(char *)) + printer(arg, " %s", ipxcp_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 < CILEN_VOID || olen > len) { + break; + } + printer(arg, " <"); + len -= olen; + optend = p + olen; + switch (code) { + case IPX_NETWORK_NUMBER: + if (olen == CILEN_NETN) { + p += 2; + GETLONG(cilong, p); + printer (arg, "network %s", ipx_ntoa (cilong)); + } + break; + case IPX_NODE_NUMBER: + if (olen == CILEN_NODEN) { + p += 2; + printer (arg, "node "); + while (p < optend) { + GETCHAR(code, p); + printer(arg, "%.2x", (int) (unsigned int) (unsigned char) code); + } + } + break; + case IPX_COMPRESSION_PROTOCOL: + if (olen == CILEN_COMPRESS) { + p += 2; + GETSHORT (cishort, p); + printer (arg, "compression %d", (int) cishort); + } + break; + case IPX_ROUTER_PROTOCOL: + if (olen == CILEN_PROTOCOL) { + p += 2; + GETSHORT (cishort, p); + printer (arg, "router proto %d", (int) cishort); + } + break; + case IPX_ROUTER_NAME: + if (olen >= CILEN_NAME) { + p += 2; + printer (arg, "router name \""); + while (p < optend) { + GETCHAR(code, p); + if (code >= 0x20 && code <= 0x7E) + printer (arg, "%c", (int) (unsigned int) (unsigned char) code); + else + printer (arg, " \\%.2x", (int) (unsigned int) (unsigned char) code); + } + printer (arg, "\""); + } + break; + case IPX_COMPLETE: + if (olen == CILEN_COMPLETE) { + p += 2; + printer (arg, "complete"); + } + break; + default: + break; + } + + while (p < optend) { + GETCHAR(code, p); + printer(arg, " %.2x", (int) (unsigned int) (unsigned char) code); + } + printer(arg, ">"); + } + break; + + case TERMACK: + case TERMREQ: + if (len > 0 && *p >= ' ' && *p < 0x7f) { + printer(arg, " "); + print_string((char *)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", (int) (unsigned int) (unsigned char) code); + } + + return p - pstart; +} +#endif /* ifdef IPX_CHANGE */ diff --git a/src/netif/ppp/ipxcp.h b/src/netif/ppp/ipxcp.h new file mode 100644 index 00000000..396b6bba --- /dev/null +++ b/src/netif/ppp/ipxcp.h @@ -0,0 +1,94 @@ +/* + * ipxcp.h - IPX Control Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipxcp.h,v 1.5 2002/12/04 23:03:32 paulus Exp $ + */ + +/* + * Options. + */ +#define IPX_NETWORK_NUMBER 1 /* IPX Network Number */ +#define IPX_NODE_NUMBER 2 +#define IPX_COMPRESSION_PROTOCOL 3 +#define IPX_ROUTER_PROTOCOL 4 +#define IPX_ROUTER_NAME 5 +#define IPX_COMPLETE 6 + +/* Values for the router protocol */ +#define IPX_NONE 0 +#define RIP_SAP 2 +#define NLSP 4 + +typedef struct ipxcp_options { + bool neg_node; /* Negotiate IPX node number? */ + bool req_node; /* Ask peer to send IPX node number? */ + + bool neg_nn; /* Negotiate IPX network number? */ + bool req_nn; /* Ask peer to send IPX network number */ + + bool neg_name; /* Negotiate IPX router name */ + bool neg_complete; /* Negotiate completion */ + bool neg_router; /* Negotiate IPX router number */ + + bool accept_local; /* accept peer's value for ournode */ + bool accept_remote; /* accept peer's value for hisnode */ + bool accept_network; /* accept network number */ + + bool tried_nlsp; /* I have suggested NLSP already */ + bool tried_rip; /* I have suggested RIP/SAP already */ + + u_int32_t his_network; /* base network number */ + u_int32_t our_network; /* our value for network number */ + u_int32_t network; /* the final network number */ + + u_char his_node[6]; /* peer's node number */ + u_char our_node[6]; /* our node number */ + u_char name [48]; /* name of the router */ + int router; /* routing protocol */ +} ipxcp_options; + +extern fsm ipxcp_fsm[]; +extern ipxcp_options ipxcp_wantoptions[]; +extern ipxcp_options ipxcp_gotoptions[]; +extern ipxcp_options ipxcp_allowoptions[]; +extern ipxcp_options ipxcp_hisoptions[]; + +extern struct protent ipxcp_protent; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 54f758aa..2a68b669 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1,159 +1,251 @@ -/***************************************************************************** -* lcp.c - Network Link Control Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-01 Guy Lancaster , Global Election Systems Inc. -* Original. -*****************************************************************************/ - /* * lcp.c - PPP Link Control Protocol. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - #include "lwip/opt.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#define RCSID "$Id: lcp.c,v 1.76 2006/05/22 00:04:07 paulus Exp $" -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "fsm.h" -#include "chap.h" -#include "magic.h" -#include "auth.h" -#include "lcp.h" +/* + * TODO: + */ +#include #include +#include -#if PPPOE_SUPPORT -#include "netif/ppp_oe.h" -#else -#define PPPOE_MAXMTU PPP_MAXMRU -#endif +#include "pppd.h" +#include "fsm.h" +#include "lcp.h" +#include "chap-new.h" +#include "magic.h" + +static const char rcsid[] = RCSID; + +/* + * When the link comes up we want to be able to wait for a short while, + * or until seeing some input from the peer, before starting to send + * configure-requests. We do this by delaying the fsm_lowerup call. + */ +/* steal a bit in fsm flags word */ +#define DELAYED_UP 0x100 + +static void lcp_delayed_up __P((void *)); -#if 0 /* UNUSED */ /* * LCP-related command-line options. */ -int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ -int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ -bool lax_recv = 0; /* accept control chars in asyncmap */ +int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ +int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +bool lax_recv = 0; /* accept control chars in asyncmap */ +bool noendpoint = 0; /* don't send/accept endpoint discriminator */ -static int setescape (char **); +static int noopt __P((char **)); + +#ifdef HAVE_MULTILINK +static int setendpoint __P((char **)); +static void printendpoint __P((option_t *, void (*)(void *, char *, ...), + void *)); +#endif /* HAVE_MULTILINK */ static option_t lcp_option_list[] = { /* LCP options */ - /* list stripped for simplicity */ + { "-all", o_special_noarg, (void *)noopt, + "Don't request/allow any LCP options" }, + + { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, + "Disable address/control compression", + OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, + { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression, + "Disable address/control compression", + OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, + + { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, + "Set asyncmap (for received packets)", + OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, + { "-as", o_uint32, &lcp_wantoptions[0].asyncmap, + "Set asyncmap (for received packets)", + OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, + { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, + "Disable asyncmap negotiation", + OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, + &lcp_allowoptions[0].neg_asyncmap }, + { "-am", o_uint32, &lcp_wantoptions[0].asyncmap, + "Disable asyncmap negotiation", + OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, + &lcp_allowoptions[0].neg_asyncmap }, + + { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, + "Disable magic number negotiation (looped-back line detection)", + OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, + { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, + "Disable magic number negotiation (looped-back line detection)", + OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, + + { "mru", o_int, &lcp_wantoptions[0].mru, + "Set MRU (maximum received packet size) for negotiation", + OPT_PRIO, &lcp_wantoptions[0].neg_mru }, + { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru, + "Disable MRU negotiation (use default 1500)", + OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, + { "-mru", o_bool, &lcp_wantoptions[0].neg_mru, + "Disable MRU negotiation (use default 1500)", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, + + { "mtu", o_int, &lcp_allowoptions[0].mru, + "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU }, + + { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression, + "Disable protocol field compression", + OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, + { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression, + "Disable protocol field compression", + OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, + + { "passive", o_bool, &lcp_wantoptions[0].passive, + "Set passive mode", 1 }, + { "-p", o_bool, &lcp_wantoptions[0].passive, + "Set passive mode", OPT_ALIAS | 1 }, + + { "silent", o_bool, &lcp_wantoptions[0].silent, + "Set silent mode", 1 }, + + { "lcp-echo-failure", o_int, &lcp_echo_fails, + "Set number of consecutive echo failures to indicate link failure", + OPT_PRIO }, + { "lcp-echo-interval", o_int, &lcp_echo_interval, + "Set time in seconds between LCP echo requests", OPT_PRIO }, + { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, + "Set time in seconds between LCP retransmissions", OPT_PRIO }, + { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, + "Set maximum number of LCP terminate-request transmissions", OPT_PRIO }, + { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits, + "Set maximum number of LCP configure-request transmissions", OPT_PRIO }, + { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, + "Set limit on number of LCP configure-naks", OPT_PRIO }, + + { "receive-all", o_bool, &lax_recv, + "Accept all received control characters", 1 }, + +#ifdef HAVE_MULTILINK + { "mrru", o_int, &lcp_wantoptions[0].mrru, + "Maximum received packet size for multilink bundle", + OPT_PRIO, &lcp_wantoptions[0].neg_mrru }, + + { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, + "Use short sequence numbers in multilink headers", + OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf }, + { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, + "Don't use short sequence numbers in multilink headers", + OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf }, + + { "endpoint", o_special, (void *) setendpoint, + "Endpoint discriminator for multilink", + OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint }, +#endif /* HAVE_MULTILINK */ + + { "noendpoint", o_bool, &noendpoint, + "Don't send or accept multilink endpoint discriminator", 1 }, + {NULL} }; -#endif /* UNUSED */ - -/* options */ -LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */ -static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ -static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ /* global vars */ -static 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 */ -ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */ +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 */ -static u32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */ -static u32_t lcp_echo_number = 0; /* ID number of next echo frame */ -static u32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */ +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 */ -/* @todo: do we really need such a large buffer? The typical 1500 bytes seem too much. */ -static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ +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, u_char, u_char*, int); -static void lcp_rprotrej (fsm*, u_char*, int); +static void lcp_resetci __P((fsm *)); /* Reset our CI */ +static int lcp_cilen __P((fsm *)); /* Return length of our CI */ +static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */ +static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ +static int lcp_nakci __P((fsm *, u_char *, int, int)); /* Peer nak'd our CI */ +static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ +static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */ +static void lcp_up __P((fsm *)); /* We're UP */ +static void lcp_down __P((fsm *)); /* We're DOWN */ +static void lcp_starting __P((fsm *)); /* We need lower layer up */ +static void lcp_finished __P((fsm *)); /* We need lower layer down */ +static int lcp_extcode __P((fsm *, int, int, u_char *, int)); +static void lcp_rprotrej __P((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 void lcp_echo_lowerup __P((int)); +static void lcp_echo_lowerdown __P((int)); +static void LcpEchoTimeout __P((void *)); +static void lcp_received_echo_reply __P((fsm *, int, u_char *, int)); +static void LcpSendEchoRequest __P((fsm *)); +static void LcpLinkFailure __P((fsm *)); +static void LcpEchoCheck __P((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 LS_OPENED state */ - lcp_down, /* Called when fsm leaves LS_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 */ +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 */ }; /* @@ -161,8 +253,11 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ * Some of these are called directly. */ -static void lcp_input (int, u_char *, int); -static void lcp_protrej (int); +static void lcp_init __P((int)); +static void lcp_input __P((int, u_char *, int)); +static void lcp_protrej __P((int)); +static int lcp_printpkt __P((u_char *, int, + void (*) __P((void *, char *, ...)), void *)); struct protent lcp_protent = { PPP_LCP, @@ -173,17 +268,15 @@ struct protent lcp_protent = { lcp_lowerdown, lcp_open, lcp_close, -#if PPP_ADDITIONAL_CALLBACKS lcp_printpkt, NULL, -#endif /* PPP_ADDITIONAL_CALLBACKS */ 1, "LCP", -#if PPP_ADDITIONAL_CALLBACKS + NULL, + lcp_option_list, NULL, NULL, NULL -#endif /* PPP_ADDITIONAL_CALLBACKS */ }; int lcp_loopbackfail = DEFLOOPBACKFAIL; @@ -191,110 +284,90 @@ 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 + sizeof(short) */ -#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ -#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ -#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ -#define CILEN_CBCP 3 +#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") +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") -#if 0 /* UNUSED */ /* - * setescape - add chars to the set we escape on transmission. + * noopt - Disable all options (why?). */ static int -setescape(argv) +noopt(argv) char **argv; { - int n, ret; - char *p, *endp; + BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); + BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); - 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; + return (1); } -#endif /* UNUSED */ + +#ifdef HAVE_MULTILINK +static int +setendpoint(argv) + char **argv; +{ + if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { + lcp_wantoptions[0].neg_endpoint = 1; + return 1; + } + option_error("Can't parse '%s' as an endpoint discriminator", *argv); + return 0; +} + +static void +printendpoint(opt, printer, arg) + option_t *opt; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint)); +} +#endif /* HAVE_MULTILINK */ /* * lcp_init - Initialize LCP. */ -void -lcp_init(int unit) +static void +lcp_init(unit) + int unit; { - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *ao = &lcp_allowoptions[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; + f->unit = unit; + f->protocol = PPP_LCP; + f->callbacks = &lcp_callbacks; - fsm_init(f); + 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 = PPP_DEFMRU; - wo->neg_asyncmap = 1; - wo->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */ - 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; + BZERO(wo, sizeof(*wo)); + wo->neg_mru = 1; + wo->mru = DEFMRU; + wo->neg_asyncmap = 1; + wo->neg_magicnumber = 1; + wo->neg_pcompression = 1; + wo->neg_accompression = 1; - ao->neg_mru = 1; - ao->mru = PPP_MAXMRU; - ao->neg_asyncmap = 1; - ao->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */ - ao->neg_chap = (CHAP_SUPPORT != 0); - ao->chap_mdtype = CHAP_DIGEST_MD5; - ao->neg_upap = (PAP_SUPPORT != 0); - ao->neg_magicnumber = 1; - ao->neg_pcompression = 1; - ao->neg_accompression = 1; - ao->neg_lqr = 0; /* no LQR implementation yet */ - ao->neg_cbcp = (CBCP_SUPPORT != 0); - - /* - * Set transmit escape for the flag and escape characters plus anything - * set for the allowable options. - */ - memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); - xmit_accm[unit][15] = 0x60; - xmit_accm[unit][0] = (u_char)((ao->asyncmap & 0xFF)); - xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF); - xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF); - xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF); - LCPDEBUG(LOG_INFO, ("lcp_init: xmit_accm=%X %X %X %X\n", - xmit_accm[unit][0], - xmit_accm[unit][1], - xmit_accm[unit][2], - xmit_accm[unit][3])); - - lcp_phase[unit] = PHASE_INITIALIZE; + BZERO(ao, sizeof(*ao)); + ao->neg_mru = 1; + ao->mru = MAXMRU; + ao->neg_asyncmap = 1; + ao->neg_chap = 1; + ao->chap_mdtype = chap_mdtype_all; + ao->neg_upap = 1; + ao->neg_eap = 1; + ao->neg_magicnumber = 1; + ao->neg_pcompression = 1; + ao->neg_accompression = 1; + ao->neg_endpoint = 1; } @@ -302,21 +375,18 @@ lcp_init(int unit) * lcp_open - LCP is allowed to come up. */ void -lcp_open(int unit) +lcp_open(unit) + int unit; { - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[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_phase[unit] = PHASE_ESTABLISH; + f->flags &= ~(OPT_PASSIVE | OPT_SILENT); + if (wo->passive) + f->flags |= OPT_PASSIVE; + if (wo->silent) + f->flags |= OPT_SILENT; + fsm_open(f); } @@ -324,25 +394,26 @@ lcp_open(int unit) * lcp_close - Take LCP down. */ void -lcp_close(int unit, char *reason) +lcp_close(unit, reason) + int unit; + char *reason; { - fsm *f = &lcp_fsm[unit]; + fsm *f = &lcp_fsm[unit]; - if (lcp_phase[unit] != PHASE_DEAD) { - lcp_phase[unit] = PHASE_TERMINATE; - } - if (f->state == LS_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 an - * lcp_close() in passive/silent mode when a connection hasn't - * been established. - */ - f->state = LS_CLOSED; - lcp_finished(f); - } else { - fsm_close(f, reason); - } + if (phase != PHASE_DEAD && phase != PHASE_MASTER) + 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(f, reason); } @@ -350,31 +421,28 @@ lcp_close(int unit, char *reason) * lcp_lowerup - The lower layer is up. */ void -lcp_lowerup(int unit) +lcp_lowerup(unit) + int unit; { - lcp_options *wo = &lcp_wantoptions[unit]; + lcp_options *wo = &lcp_wantoptions[unit]; + fsm *f = &lcp_fsm[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, 0xffffffffl, 0, 0); - ppp_recv_config(unit, PPP_MRU, 0x00000000l, - wo->neg_pcompression, wo->neg_accompression); - peer_mru[unit] = PPP_MRU; - lcp_allowoptions[unit].asyncmap = (u_long)xmit_accm[unit][0] - | ((u_long)xmit_accm[unit][1] << 8) - | ((u_long)xmit_accm[unit][2] << 16) - | ((u_long)xmit_accm[unit][3] << 24); - LCPDEBUG(LOG_INFO, ("lcp_lowerup: asyncmap=%X %X %X %X\n", - xmit_accm[unit][3], - xmit_accm[unit][2], - xmit_accm[unit][1], - xmit_accm[unit][0])); + /* + * 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. + */ + if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0 + || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), + wo->neg_pcompression, wo->neg_accompression) < 0) + return; + peer_mru[unit] = PPP_MRU; - fsm_lowerup(&lcp_fsm[unit]); + if (listen_time != 0) { + f->flags |= DELAYED_UP; + TIMEOUTMS(lcp_delayed_up, f, listen_time); + } else + fsm_lowerup(f); } @@ -382,9 +450,31 @@ lcp_lowerup(int unit) * lcp_lowerdown - The lower layer is down. */ void -lcp_lowerdown(int unit) +lcp_lowerdown(unit) + int unit; { - fsm_lowerdown(&lcp_fsm[unit]); + fsm *f = &lcp_fsm[unit]; + + if (f->flags & DELAYED_UP) + f->flags &= ~DELAYED_UP; + else + fsm_lowerdown(&lcp_fsm[unit]); +} + + +/* + * lcp_delayed_up - Bring the lower layer up now. + */ +static void +lcp_delayed_up(arg) + void *arg; +{ + fsm *f = arg; + + if (f->flags & DELAYED_UP) { + f->flags &= ~DELAYED_UP; + fsm_lowerup(f); + } } @@ -392,107 +482,130 @@ lcp_lowerdown(int unit) * lcp_input - Input LCP packet. */ static void -lcp_input(int unit, u_char *p, int len) +lcp_input(unit, p, len) + int unit; + u_char *p; + int len; { - fsm *f = &lcp_fsm[unit]; + fsm *f = &lcp_fsm[unit]; - fsm_input(f, p, len); + if (f->flags & DELAYED_UP) { + f->flags &= ~DELAYED_UP; + fsm_lowerup(f); + } + fsm_input(f, p, len); } - /* * lcp_extcode - Handle a LCP-specific code. */ static int -lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len) +lcp_extcode(f, code, id, inp, len) + fsm *f; + int code, id; + u_char *inp; + int len; { - u_char *magp; + u_char *magp; - switch( code ){ + switch( code ){ case PROTREJ: - lcp_rprotrej(f, inp, len); - break; - + lcp_rprotrej(f, inp, len); + break; + case ECHOREQ: - if (f->state != LS_OPENED) { - break; - } - LCPDEBUG(LOG_INFO, ("lcp: Echo-Request, Rcvd id %d\n", id)); - magp = inp; - PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); - fsm_sdata(f, ECHOREP, id, inp, len); - break; - + 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; + lcp_received_echo_reply(f, id, inp, len); + break; case DISCREQ: - break; + case IDENTIF: + case TIMEREM: + break; default: - return 0; - } - return 1; + 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) +lcp_rprotrej(f, inp, len) + fsm *f; + u_char *inp; + int len; { - int i; - struct protent *protp; - u_short prot; + int i; + struct protent *protp; + u_short prot; + const char *pname; - if (len < (int)sizeof (u_short)) { - LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd short Protocol-Reject packet!\n")); - return; - } - - GETSHORT(prot, inp); - - LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n", prot)); - - /* - * Protocol-Reject packets received in any state other than the LCP - * LS_OPENED state SHOULD be silently discarded. - */ - if( f->state != LS_OPENED ) { - LCPDEBUG(LOG_INFO, ("Protocol-Reject discarded: LCP in state %d\n", f->state)); - return; - } - - /* - * Upcall the proper Protocol-Reject routine. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol == prot && protp->enabled_flag) { - (*protp->protrej)(f->unit); - return; + if (len < 2) { + LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); + return; } - } - LCPDEBUG(LOG_WARNING, ("Protocol-Reject for unsupported protocol 0x%x\n", prot)); + 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; + } + + pname = protocol_name(prot); + + /* + * Upcall the proper Protocol-Reject routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol == prot && protp->enabled_flag) { + if (pname == NULL) + dbglog("Protocol-Reject for 0x%x received", prot); + else + dbglog("Protocol-Reject for '%s' (0x%x) received", pname, + prot); + (*protp->protrej)(f->unit); + return; + } + + if (pname == NULL) + warn("Protocol-Reject for unsupported protocol 0x%x", prot); + else + warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname, + prot); } /* * lcp_protrej - A Protocol-Reject was received. */ +/*ARGSUSED*/ static void -lcp_protrej(int unit) +lcp_protrej(unit) + int unit; { - LWIP_UNUSED_ARG(unit); - /* - * Can't reject LCP! - */ - LCPDEBUG(LOG_WARNING, ("lcp_protrej: Received Protocol-Reject for LCP!\n")); - fsm_protreject(&lcp_fsm[unit]); + /* + * Can't reject LCP! + */ + error("Received Protocol-Reject for LCP!"); + fsm_protreject(&lcp_fsm[unit]); } @@ -500,14 +613,20 @@ lcp_protrej(int unit) * lcp_sprotrej - Send a Protocol-Reject for some protocol. */ void -lcp_sprotrej(int unit, u_char *p, int len) +lcp_sprotrej(unit, p, len) + 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 LS_OPENED state. - */ + /* + * 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); + fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, + p, len); } @@ -515,13 +634,25 @@ lcp_sprotrej(int unit, u_char *p, int len) * lcp_resetci - Reset our CI. */ static void -lcp_resetci(fsm *f) +lcp_resetci(f) + 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_options *wo = &lcp_wantoptions[f->unit]; + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *ao = &lcp_allowoptions[f->unit]; + + wo->magicnumber = magic(); + wo->numloops = 0; + *go = *wo; + if (!multilink) { + go->neg_mrru = 0; + go->neg_ssnhf = 0; + go->neg_endpoint = 0; + } + if (noendpoint) + ao->neg_endpoint = 0; + peer_mru[f->unit] = PPP_MRU; + auth_reset(f->unit); } @@ -529,29 +660,35 @@ lcp_resetci(fsm *f) * lcp_cilen - Return length of our CI. */ static int -lcp_cilen(fsm *f) +lcp_cilen(f) + fsm *f; { - lcp_options *go = &lcp_gotoptions[f->unit]; + 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 != PPP_DEFMRU) + - LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) + - 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)); +#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, UPAP, or EAP, even if we will + * accept more than one. We prefer EAP first, then CHAP, then + * PAP. + */ + return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) + + LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + + LENCISHORT(go->neg_eap) + + LENCICHAP(!go->neg_eap && go->neg_chap) + + LENCISHORT(!go->neg_eap && !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) + + LENCISHORT(go->neg_mrru) + + LENCIVOID(go->neg_ssnhf) + + (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); } @@ -559,69 +696,82 @@ lcp_cilen(fsm *f) * lcp_addci - Add our desired CIs to a packet. */ static void -lcp_addci(fsm *f, u_char *ucp, int *lenp) +lcp_addci(f, ucp, lenp) + fsm *f; + u_char *ucp; + int *lenp; { - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char *start_ucp = ucp; + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char *start_ucp = ucp; #define ADDCIVOID(opt, neg) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: opt=%d\n", opt)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_VOID, ucp); \ - } + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_VOID, ucp); \ + } #define ADDCISHORT(opt, neg, val) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: INT opt=%d %X\n", opt, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_SHORT, ucp); \ - PUTSHORT(val, ucp); \ - } -#define ADDCICHAP(opt, neg, val, digest) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: CHAP opt=%d %X\n", opt, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAP, ucp); \ - PUTSHORT(val, ucp); \ - PUTCHAR(digest, ucp); \ - } + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_SHORT, ucp); \ + PUTSHORT(val, ucp); \ + } +#define ADDCICHAP(opt, neg, val) \ + if (neg) { \ + PUTCHAR((opt), ucp); \ + PUTCHAR(CILEN_CHAP, ucp); \ + PUTSHORT(PPP_CHAP, ucp); \ + PUTCHAR((CHAP_DIGEST(val)), ucp); \ + } #define ADDCILONG(opt, neg, val) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: L opt=%d %lX\n", opt, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LONG, ucp); \ - PUTLONG(val, ucp); \ - } + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_LONG, ucp); \ + PUTLONG(val, ucp); \ + } #define ADDCILQR(opt, neg, val) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: LQR opt=%d %lX\n", opt, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LQR, ucp); \ - PUTSHORT(PPP_LQR, ucp); \ - PUTLONG(val, ucp); \ - } + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_LQR, ucp); \ + PUTSHORT(PPP_LQR, ucp); \ + PUTLONG(val, ucp); \ + } #define ADDCICHAR(opt, neg, val) \ - if (neg) { \ - LCPDEBUG(LOG_INFO, ("lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR, ucp); \ - PUTCHAR(val, ucp); \ - } + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAR, ucp); \ + PUTCHAR(val, ucp); \ + } +#define ADDCIENDP(opt, neg, class, val, len) \ + if (neg) { \ + int i; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAR + len, ucp); \ + PUTCHAR(class, ucp); \ + for (i = 0; i < len; ++i) \ + PUTCHAR(val[i], ucp); \ + } - ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); - ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, 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); + ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); + ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, + go->asyncmap); + ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); + ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); + ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !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); + ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); + ADDCIVOID(CI_SSNHF, go->neg_ssnhf); + ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, + go->endpoint.value, go->endpoint.length); - if (ucp - start_ucp != *lenp) { - /* this should never happen, because peer_mtu should be 1500 */ - LCPDEBUG(LOG_ERR, ("Bug in lcp_addci: wrong length\n")); - } + if (ucp - start_ucp != *lenp) { + /* this should never happen, because peer_mtu should be 1500 */ + error("Bug in lcp_addci: wrong length"); + } } @@ -630,585 +780,707 @@ lcp_addci(fsm *f, u_char *ucp, int *lenp) * This should not modify any state if the Ack is bad. * * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. + * 0 - Ack was bad. + * 1 - Ack was good. */ static int -lcp_ackci(fsm *f, u_char *p, int len) +lcp_ackci(f, p, len) + fsm *f; + u_char *p; + int len; { - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char cilen, citype, cichar; - u_short cishort; - u32_t cilong; + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char cilen, citype, cichar; + u_short cishort; + u_int32_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. - */ + /* + * 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; \ - } + 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; \ - } + 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; \ - } + 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) \ + 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 != PPP_CHAP) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != (CHAP_DIGEST(val))) \ + 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; \ - } + 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; \ - } + 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; \ + } +#define ACKCIENDP(opt, neg, class, val, vlen) \ + if (neg) { \ + int i; \ + if ((len -= CILEN_CHAR + vlen) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAR + vlen || \ + citype != opt) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != class) \ + goto bad; \ + for (i = 0; i < vlen; ++i) { \ + GETCHAR(cichar, p); \ + if (cichar != val[i]) \ + goto bad; \ + } \ + } - ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); - ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, 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); + ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); + ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, + go->asyncmap); + ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); + ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); + ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !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); + ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); + ACKCIVOID(CI_SSNHF, go->neg_ssnhf); + ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, + go->endpoint.value, go->endpoint.length); - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) { - goto bad; - } - LCPDEBUG(LOG_INFO, ("lcp_acki: Ack\n")); - return (1); + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + return (1); bad: - LCPDEBUG(LOG_WARNING, ("lcp_acki: received bad Ack!\n")); - return (0); + 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 LS_OPENED state. + * or if LCP is in the OPENED state. * * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. + * 0 - Nak was bad. + * 1 - Nak was good. */ static int -lcp_nakci(fsm *f, u_char *p, int len) +lcp_nakci(f, p, len, treat_as_reject) + fsm *f; + u_char *p; + int len; + int treat_as_reject; { - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *wo = &lcp_wantoptions[f->unit]; - u_char citype, cichar, *next; - u_short cishort; - u32_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; + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *wo = &lcp_wantoptions[f->unit]; + u_char citype, cichar, *next; + u_short cishort; + u_int32_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; + 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 \ - } + /* + * 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) \ + if (go->neg && \ + len >= CILEN_VOID && \ + p[1] == CILEN_VOID && \ + p[0] == opt) { \ + len -= CILEN_VOID; \ + INCPTR(CILEN_VOID, p); \ + no.neg = 1; \ + try.neg = 0; \ + } #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 \ - } + 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 \ - } + 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 \ - } + 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 \ - } + 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 != PPP_DEFMRU) { - NAKCISHORT(CI_MRU, neg_mru, - if (cishort <= wo->mru || cishort < PPP_DEFMRU) { - try.mru = cishort; - } - ); - } - - /* - * Add any characters they want to our (receive-side) asyncmap. - */ - if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) { - 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'll have to stop - * asking for CHAP. - */ - if (cichar != go->chap_mdtype) { - 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 (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 \ } - } - - /* - * 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; +#define NAKCIENDP(opt, neg) \ + if (go->neg && \ + len >= CILEN_CHAR && \ + p[0] == opt && \ + p[1] >= CILEN_CHAR && \ + p[1] <= len) { \ + len -= p[1]; \ + INCPTR(p[1], p); \ + no.neg = 1; \ + try.neg = 0; \ } - ); - /* - * 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; + /* + * NOTE! There must be no assignments to individual fields of *go in + * the code below. Any such assignment is a BUG! + */ + /* + * 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; + ); } - next = p + cilen - 2; - switch (citype) { - case CI_MRU: - if ((go->neg_mru && go->mru != PPP_DEFMRU) - || no.neg_mru || cilen != CILEN_SHORT) { - goto bad; - } - GETSHORT(cishort, p); - if (cishort < PPP_DEFMRU) { - try.mru = cishort; - } - break; - case CI_ASYNCMAP: - if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) - || 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; + /* + * 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; + ); } - p = next; - } - /* If there is still anything left, this packet is bad. */ - if (len != 0) { - goto bad; - } + /* + * 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 || go->neg_eap) + && 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; + no.neg_eap = go->neg_eap; + INCPTR(2, p); + GETSHORT(cishort, p); + if (cishort == PPP_PAP && cilen == CILEN_SHORT) { + /* If we were asking for EAP, then we need to stop that. */ + if (go->neg_eap) + try.neg_eap = 0; - /* - * OK, the Nak is good. Now we can update state. - */ - if (f->state != LS_OPENED) { - if (looped_back) { - if (++try.numloops >= lcp_loopbackfail) { - LCPDEBUG(LOG_NOTICE, ("Serial line is looped back.\n")); - lcp_close(f->unit, "Loopback detected"); - } - } else { - try.numloops = 0; + /* If we were asking for CHAP, then we need to stop that. */ + else if (go->neg_chap) + try.neg_chap = 0; + /* + * If we weren't asking for CHAP or EAP, then we were asking for + * PAP, in which case this Nak is bad. + */ + else + goto bad; + + } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { + GETCHAR(cichar, p); + /* Stop asking for EAP, if we were. */ + if (go->neg_eap) { + try.neg_eap = 0; + /* Try to set up to use their suggestion, if possible */ + if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) + try.chap_mdtype = CHAP_MDTYPE_D(cichar); + } else if (go->neg_chap) { + /* + * We were asking for our preferred algorithm, they must + * want something different. + */ + if (cichar != CHAP_DIGEST(go->chap_mdtype)) { + if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) { + /* Use their suggestion if we support it ... */ + try.chap_mdtype = CHAP_MDTYPE_D(cichar); + } else { + /* ... otherwise, try our next-preferred algorithm. */ + try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype)); + if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */ + try.neg_chap = 0; + } + } else { + /* + * Whoops, they Nak'd our algorithm of choice + * but then suggested it back to us. + */ + goto bad; + } + } else { + /* + * Stop asking for PAP if we were asking for it. + */ + try.neg_upap = 0; + } + + } else { + + /* + * If we were asking for EAP, and they're Conf-Naking EAP, + * well, that's just strange. Nobody should do that. + */ + if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap) + dbglog("Unexpected Conf-Nak for EAP"); + + /* + * We don't recognize what they're suggesting. + * Stop asking for what we were asking for. + */ + if (go->neg_eap) + try.neg_eap = 0; + else if (go->neg_chap) + try.neg_chap = 0; + else + try.neg_upap = 0; + p += cilen - CILEN_SHORT; + } } - *go = try; - } - return 1; + /* + * 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); + NAKCIVOID(CI_ACCOMPRESSION, neg_accompression); + + /* + * Nak for MRRU option - accept their value if it is smaller + * than the one we want. + */ + if (go->neg_mrru) { + NAKCISHORT(CI_MRRU, neg_mrru, + if (treat_as_reject) + try.neg_mrru = 0; + else if (cishort <= wo->mrru) + try.mrru = cishort; + ); + } + + /* + * Nak for short sequence numbers shouldn't be sent, treat it + * like a reject. + */ + NAKCIVOID(CI_SSNHF, neg_ssnhf); + + /* + * Nak of the endpoint discriminator option is not permitted, + * treat it like a reject. + */ + NAKCIENDP(CI_EPDISC, neg_endpoint); + + /* + * 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.neg_mru = 1; + 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 || + go->neg_eap || no.neg_eap) + 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; + case CI_MRRU: + if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) + goto bad; + break; + case CI_SSNHF: + if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) + goto bad; + try.neg_ssnhf = 1; + break; + case CI_EPDISC: + if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR) + 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."); + status = EXIT_LOOPBACK; + lcp_close(f->unit, "Loopback detected"); + } + } else + try.numloops = 0; + *go = try; + } + + return 1; bad: - LCPDEBUG(LOG_WARNING, ("lcp_nakci: received bad Nak!\n")); - return 0; + 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 LS_OPENED state. + * or if LCP is in the OPENED state. * * Returns: - * 0 - Reject was bad. - * 1 - Reject was good. + * 0 - Reject was bad. + * 1 - Reject was good. */ static int -lcp_rejci(fsm *f, u_char *p, int len) +lcp_rejci(f, p, len) + fsm *f; + u_char *p; + int len; { - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char cichar; - u_short cishort; - u32_t cilong; - lcp_options try; /* options to request next time */ + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char cichar; + u_short cishort; + u_int32_t cilong; + lcp_options try; /* options to request next time */ - try = *go; + 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. - */ + /* + * 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; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: void opt %d rejected\n", opt)); \ - } + 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; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: short opt %d rejected\n", opt)); \ - } -#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; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: chap opt %d rejected\n", opt)); \ - } + 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) \ + 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 != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ + goto bad; \ + try.neg = 0; \ + try.neg_eap = 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; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: long opt %d rejected\n", opt)); \ - } + 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; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: LQR opt %d rejected\n", opt)); \ - } + 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; \ - LCPDEBUG(LOG_INFO, ("lcp_rejci: Callback opt %d rejected\n", opt)); \ - } - - 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 != LS_OPENED) { - *go = try; - } - return 1; - + 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; \ + } +#define REJCIENDP(opt, neg, class, val, vlen) \ + if (go->neg && \ + len >= CILEN_CHAR + vlen && \ + p[0] == opt && \ + p[1] == CILEN_CHAR + vlen) { \ + int i; \ + len -= CILEN_CHAR + vlen; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + if (cichar != class) \ + goto bad; \ + for (i = 0; i < vlen; ++i) { \ + GETCHAR(cichar, p); \ + if (cichar != val[i]) \ + goto bad; \ + } \ + try.neg = 0; \ + } + + REJCISHORT(CI_MRU, neg_mru, go->mru); + REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); + REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP); + if (!go->neg_eap) { + REJCICHAP(CI_AUTHTYPE, neg_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); + REJCISHORT(CI_MRRU, neg_mrru, go->mrru); + REJCIVOID(CI_SSNHF, neg_ssnhf); + REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class, + go->endpoint.value, go->endpoint.length); + + /* + * 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(LOG_WARNING, ("lcp_rejci: received bad Reject!\n")); - return 0; + LCPDEBUG(("lcp_rejci: received bad Reject!")); + return 0; } @@ -1220,416 +1492,390 @@ bad: * 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_reqci(f, inp, lenp, reject_if_disagree) + 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; /* Parsed len, type */ - u_char cichar; /* Parsed char value */ - u_short cishort; /* Parsed short value */ - u32_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 */ -#if TRACELCP > 0 - char traceBuf[80]; - size_t traceNdx = 0; -#endif + 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 */ + u_int32_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)); + /* + * 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(LOG_WARNING, ("lcp_reqci: bad CI length!\n")); - 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 */ + /* + * 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? */ - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - not allowed\n")); - orc = CONFREJ; /* Reject CI */ - break; - } else if (cilen != CILEN_SHORT) { /* Check CI length */ - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - bad length\n")); - orc = CONFREJ; /* Reject CI */ - break; - } - GETSHORT(cishort, p); /* Parse MRU */ + 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 < PPP_MINMRU) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak - MRU too small\n")); - orc = CONFNAK; /* Nak CI */ - PUTCHAR(CI_MRU, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_MINMRU, nakp); /* Give him a hint */ - break; - } - ho->neg_mru = 1; /* Remember he sent MRU */ - ho->mru = cishort; /* And remember value */ -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort); - traceNdx = strlen(traceBuf); -#endif - break; + /* + * 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) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP not allowed\n")); - orc = CONFREJ; - break; - } else if (cilen != CILEN_LONG) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP bad length\n")); - 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) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", - cilong, ao->asyncmap)); - orc = CONFNAK; - PUTCHAR(CI_ASYNCMAP, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(ao->asyncmap | cilong, nakp); - break; - } - ho->neg_asyncmap = 1; - ho->asyncmap = cilong; -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong); - traceNdx = strlen(traceBuf); -#endif - break; + case CI_ASYNCMAP: + if (!ao->neg_asyncmap || + cilen != CILEN_LONG) { + orc = CONFREJ; + break; + } + GETLONG(cilong, p); - case CI_AUTHTYPE: - if (cilen < CILEN_SHORT) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE missing arg\n")); - orc = CONFREJ; - break; - } else if (!(ao->neg_upap || ao->neg_chap)) { - /* - * Reject the option if we're not willing to authenticate. - */ - LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE not allowed\n")); - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - /* - * Authtype must be UPAP 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 */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP already accepted\n")); - orc = CONFREJ; - break; - } else if (cilen != CILEN_SHORT) { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP bad len\n")); - orc = CONFREJ; - break; - } - if (!ao->neg_upap) { /* we don't want to do PAP */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE PAP not allowed\n")); - orc = CONFNAK; /* NAK it and suggest CHAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - break; - } - ho->neg_upap = 1; -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort); - traceNdx = strlen(traceBuf); -#endif - break; - } - if (cishort == PPP_CHAP) { - if (ho->neg_upap) { /* we've already accepted PAP */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n")); - orc = CONFREJ; - break; - } else if (cilen != CILEN_CHAP) { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP bad len\n")); - orc = CONFREJ; - break; - } - if (!ao->neg_chap) { /* we don't want to do CHAP */ - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP not allowed\n")); - 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 -#if MSCHAP_SUPPORT - && cichar != CHAP_MICROSOFT -#endif - ) { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", (int)cichar)); - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - break; - } -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, (int)cichar); - traceNdx = strlen(traceBuf); -#endif - 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) { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort)); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - } else { - LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort)); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - } - break; - - case CI_QUALITY: - GETSHORT(cishort, p); - GETLONG(cilong, p); -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong); - traceNdx = strlen(traceBuf); -#endif + /* + * 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; - if (!ao->neg_lqr || - cilen != CILEN_LQR) { - orc = CONFREJ; - break; - } - - /* - * 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); -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong); - traceNdx = strlen(traceBuf); -#endif + case CI_AUTHTYPE: + if (cilen < CILEN_SHORT || + !(ao->neg_upap || ao->neg_chap || ao->neg_eap)) { + /* + * Reject the option if we're not willing to authenticate. + */ + dbglog("No auth is possible"); + orc = CONFREJ; + break; + } + GETSHORT(cishort, 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 TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION"); - traceNdx = strlen(traceBuf); -#endif - if (!ao->neg_pcompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_pcompression = 1; - break; - - case CI_ACCOMPRESSION: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION"); - traceNdx = strlen(traceBuf); -#endif - if (!ao->neg_accompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_accompression = 1; - break; - - case CI_MRRU: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU"); - traceNdx = strlen(traceBuf); -#endif - orc = CONFREJ; - break; - - case CI_SSNHF: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF"); - traceNdx = strlen(traceBuf); -#endif - orc = CONFREJ; - break; - - case CI_EPDISC: -#if TRACELCP > 0 - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC"); - traceNdx = strlen(traceBuf); -#endif - orc = CONFREJ; - break; - - default: -#if TRACELCP - snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype); - traceNdx = strlen(traceBuf); -#endif - orc = CONFREJ; - break; + /* + * Authtype must be PAP, CHAP, or EAP. + * + * Note: if more than one of ao->neg_upap, ao->neg_chap, and + * ao->neg_eap are set, and the peer sends a Configure-Request + * with two or more authenticate-protocol requests, then we will + * reject the second request. + * Whether we end up doing CHAP, UPAP, or EAP depends then on + * the ordering of the CIs in the peer's Configure-Request. + */ + + if (cishort == PPP_PAP) { + /* we've already accepted CHAP or EAP */ + if (ho->neg_chap || ho->neg_eap || + 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 or EAP */ + PUTCHAR(CI_AUTHTYPE, nakp); + if (ao->neg_eap) { + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_EAP, nakp); + } else { + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); + } + break; + } + ho->neg_upap = 1; + break; + } + if (cishort == PPP_CHAP) { + /* we've already accepted PAP or EAP */ + if (ho->neg_upap || ho->neg_eap || + 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 EAP or PAP */ + PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CILEN_SHORT, nakp); + if (ao->neg_eap) { + PUTSHORT(PPP_EAP, nakp); + } else { + PUTSHORT(PPP_PAP, nakp); + } + break; + } + GETCHAR(cichar, p); /* get digest type */ + if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) { + /* + * We can't/won't do the requested type, + * suggest something else. + */ + orc = CONFNAK; + PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); + break; + } + ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */ + ho->neg_chap = 1; + break; + } + if (cishort == PPP_EAP) { + /* we've already accepted CHAP or PAP */ + if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) { + LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting...")); + orc = CONFREJ; + break; + } + if (!ao->neg_eap) { /* we don't want to do EAP */ + orc = CONFNAK; /* NAK it and suggest CHAP or PAP */ + PUTCHAR(CI_AUTHTYPE, nakp); + if (ao->neg_chap) { + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); + } else { + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_PAP, nakp); + } + break; + } + ho->neg_eap = 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 || + * ao->neg_eap.) + */ + orc = CONFNAK; + PUTCHAR(CI_AUTHTYPE, nakp); + if (ao->neg_eap) { + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_EAP, nakp); + } else if (ao->neg_chap) { + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(CHAP_DIGEST(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; + + case CI_MRRU: + if (!ao->neg_mrru || !multilink || + cilen != CILEN_SHORT) { + orc = CONFREJ; + break; + } + + GETSHORT(cishort, p); + /* possibly should insist on a minimum/maximum MRRU here */ + ho->neg_mrru = 1; + ho->mrru = cishort; + break; + + case CI_SSNHF: + if (!ao->neg_ssnhf || !multilink || + cilen != CILEN_VOID) { + orc = CONFREJ; + break; + } + ho->neg_ssnhf = 1; + break; + + case CI_EPDISC: + if (!ao->neg_endpoint || + cilen < CILEN_CHAR || + cilen > CILEN_CHAR + MAX_ENDP_LEN) { + orc = CONFREJ; + break; + } + GETCHAR(cichar, p); + cilen -= CILEN_CHAR; + ho->neg_endpoint = 1; + ho->endpoint.class = cichar; + ho->endpoint.length = cilen; + BCOPY(p, ho->endpoint.value, cilen); + INCPTR(cilen, p); + 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 */ + } } - endswitch: -#if TRACELCP - if (traceNdx >= 80 - 32) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: rcvd%s\n", traceBuf)); - traceNdx = 0; - } -#endif - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) { /* but prior CI wasnt? */ - continue; /* Don't send this one */ - } + /* + * 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. + */ - 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) { + switch (rc) { case CONFACK: - *lenp = (int)(next - inp); - break; + *lenp = next - inp; + break; case CONFNAK: - /* - * Copy the Nak'd options from the nak_buffer to the caller's buffer. - */ - *lenp = (int)(nakp - nak_buffer); - BCOPY(nak_buffer, inp, *lenp); - break; + /* + * 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 = (int)(rejp - inp); - break; - } + *lenp = rejp - inp; + break; + } -#if TRACELCP > 0 - if (traceNdx > 0) { - LCPDEBUG(LOG_INFO, ("lcp_reqci: %s\n", traceBuf)); - } -#endif - LCPDEBUG(LOG_INFO, ("lcp_reqci: returning CONF%s.\n", CODENAME(rc))); - return (rc); /* Return final code */ + LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); + return (rc); /* Return final code */ } @@ -1637,45 +1883,50 @@ lcp_reqci(fsm *f, * lcp_up - LCP has come UP. */ static void -lcp_up(fsm *f) +lcp_up(f) + 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]; + 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]; + int mtu, mru; - if (!go->neg_magicnumber) { - go->magicnumber = 0; - } - if (!ho->neg_magicnumber) { - ho->magicnumber = 0; - } + printf("LCP IS UP !\n"); - /* - * 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, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)), - (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl), - ho->neg_pcompression, ho->neg_accompression); - /* - * If the asyncmap hasn't been negotiated, we really should - * set the receive asyncmap to ffffffff, but we set it to 0 - * for backwards contemptibility. - */ - ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU), - (go->neg_asyncmap? go->asyncmap: 0x00000000), - go->neg_pcompression, go->neg_accompression); + if (!go->neg_magicnumber) + go->magicnumber = 0; + if (!ho->neg_magicnumber) + ho->magicnumber = 0; - if (ho->neg_mru) { - peer_mru[f->unit] = ho->mru; - } + /* + * 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. + * Note on the MTU: the link MTU can be the MRU the peer wanted, + * the interface MTU is set to the lowest of that, the + * MTU we want to use, and our link MRU. + */ + mtu = ho->neg_mru? ho->mru: PPP_MRU; + mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; +#ifdef HAVE_MULTILINK + if (!(multilink && go->neg_mrru && ho->neg_mrru)) +#endif /* HAVE_MULTILINK */ + netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru)); + ppp_send_config(f->unit, mtu, + (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), + ho->neg_pcompression, ho->neg_accompression); + ppp_recv_config(f->unit, mru, + (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), + go->neg_pcompression, go->neg_accompression); - lcp_echo_lowerup(f->unit); /* Enable echo messages */ + if (ho->neg_mru) + peer_mru[f->unit] = ho->mru; - link_established(f->unit); /* The link is up; authenticate now */ + lcp_echo_lowerup(f->unit); /* Enable echo messages */ + + link_established(f->unit); } @@ -1685,19 +1936,20 @@ lcp_up(fsm *f) * Alert other protocols. */ static void -lcp_down(fsm *f) +lcp_down(f) + fsm *f; { - lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_echo_lowerdown(f->unit); + lcp_echo_lowerdown(f->unit); - link_down(f->unit); + link_down(f->unit); - ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0); - ppp_recv_config(f->unit, PPP_MRU, - (go->neg_asyncmap? go->asyncmap: 0x00000000), - go->neg_pcompression, go->neg_accompression); - peer_mru[f->unit] = PPP_MRU; + 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; } @@ -1705,9 +1957,10 @@ lcp_down(fsm *f) * lcp_starting - LCP needs the lower layer up. */ static void -lcp_starting(fsm *f) +lcp_starting(f) + fsm *f; { - link_required(f->unit); /* lwip: currently does nothing */ + link_required(f->unit); } @@ -1715,47 +1968,10 @@ lcp_starting(fsm *f) * lcp_finished - LCP has finished with the lower layer. */ static void -lcp_finished(fsm *f) +lcp_finished(f) + fsm *f; { - link_terminated(f->unit); /* we are finished with the link */ -} - - -#if PPP_ADDITIONAL_CALLBACKS -/* - * print_string - print a readable representation of a string using - * printer. - */ -static void -print_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg) -{ - int c; - - 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, "\""); + link_terminated(f->unit); } @@ -1763,269 +1979,362 @@ print_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg * lcp_printpkt - print the contents of an LCP packet. */ static char *lcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", "ProtRej", - "EchoReq", "EchoRep", "DiscReq" + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej", "ProtRej", + "EchoReq", "EchoRep", "DiscReq", "Ident", + "TimeRem" }; static int -lcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) +lcp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; { - int code, id, len, olen; - u_char *pstart, *optend; - u_short cishort; - u32_t cilong; + int code, id, len, olen, i; + u_char *pstart, *optend; + u_short cishort; + u_int32_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 (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) { + 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%lx", 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"); - 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 "); - GETSHORT(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; - + /* 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_MD5: + printer(arg, " MD5"); + ++p; + break; + case CHAP_MICROSOFT: + printer(arg, " MS"); + ++p; + break; + + case CHAP_MICROSOFT_V2: + printer(arg, " MS-v2"); + ++p; + break; + } + } + break; + case PPP_EAP: + printer(arg, "eap"); + 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; + case CI_MRRU: + if (olen == CILEN_SHORT) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "mrru %d", cishort); + } + break; + case CI_SSNHF: + if (olen == CILEN_VOID) { + p += 2; + printer(arg, "ssnhf"); + } + break; + case CI_EPDISC: +#ifdef HAVE_MULTILINK + if (olen >= CILEN_CHAR) { + struct epdisc epd; + p += 2; + GETCHAR(epd.class, p); + epd.length = olen - CILEN_CHAR; + if (epd.length > MAX_ENDP_LEN) + epd.length = MAX_ENDP_LEN; + if (epd.length > 0) { + BCOPY(p, epd.value, epd.length); + p += epd.length; + } + printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); + } +#else + printer(arg, "endpoint"); +#endif + 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((char*)p, len, printer, arg); - p += len; - len = 0; - } - break; - + if (len > 0 && *p >= ' ' && *p < 0x7f) { + printer(arg, " "); + print_string((char *)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; - } + if (len >= 4) { + GETLONG(cilong, p); + printer(arg, " magic=0x%x", cilong); + len -= 4; + } + break; - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } + case IDENTIF: + case TIMEREM: + if (len >= 4) { + GETLONG(cilong, p); + printer(arg, " magic=0x%x", cilong); + len -= 4; + } + if (code == TIMEREM) { + if (len < 4) + break; + GETLONG(cilong, p); + printer(arg, " seconds=%u", cilong); + len -= 4; + } + if (len > 0) { + printer(arg, " "); + print_string((char *)p, len, printer, arg); + p += len; + len = 0; + } + break; + } - return (int)(p - pstart); + /* print the rest of the bytes in the packet */ + for (i = 0; i < len && i < 32; ++i) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + if (i < len) { + printer(arg, " ..."); + p += len - i; + } + + return p - pstart; } -#endif /* PPP_ADDITIONAL_CALLBACKS */ /* * Time to shut down the link because there is nothing out there. */ -static void -LcpLinkFailure (fsm *f) + +static +void LcpLinkFailure (f) + fsm *f; { - if (f->state == LS_OPENED) { - LCPDEBUG(LOG_INFO, ("No response to %d echo-requests\n", lcp_echos_pending)); - LCPDEBUG(LOG_NOTICE, ("Serial link appears to be disconnected.\n")); - lcp_close(f->unit, "Peer not responding"); - } + if (f->state == OPENED) { + info("No response to %d echo-requests", lcp_echos_pending); + notice("Serial link appears to be disconnected."); + status = EXIT_PEER_DEAD; + lcp_close(f->unit, "Peer not responding"); + } } /* * Timer expired for the LCP echo requests from this process. */ + static void -LcpEchoCheck (fsm *f) +LcpEchoCheck (f) + fsm *f; { - LcpSendEchoRequest (f); + LcpSendEchoRequest (f); + if (f->state != OPENED) + return; - /* - * Start the timer for the next interval. - */ - LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0); - - TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); - lcp_echo_timer_running = 1; + /* + * 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) +LcpEchoTimeout (arg) + void *arg; { - if (lcp_echo_timer_running != 0) { - lcp_echo_timer_running = 0; - LcpEchoCheck ((fsm *) 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) +lcp_received_echo_reply (f, id, inp, len) + fsm *f; + int id; + u_char *inp; + int len; { - u32_t magic; + u_int32_t magic; - LWIP_UNUSED_ARG(id); + /* 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; + } - /* Check the magic number - don't count replies from ourselves. */ - if (len < 4) { - LCPDEBUG(LOG_WARNING, ("lcp: received short Echo-Reply, length %d\n", len)); - return; - } - GETLONG(magic, inp); - if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) { - LCPDEBUG(LOG_WARNING, ("appear to have received our own echo-reply!\n")); - return; - } - - /* Reset the number of outstanding echo frames */ - lcp_echos_pending = 0; + /* 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) +LcpSendEchoRequest (f) + fsm *f; { - u32_t lcp_magic; - u_char pkt[4], *pktp; + u_int32_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; + /* + * 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 == LS_OPENED) { - lcp_magic = lcp_gotoptions[f->unit].magicnumber; - pktp = pkt; - PUTLONG(lcp_magic, pktp); - fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt)); - ++lcp_echos_pending; - } + /* + * 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; + } } /* @@ -2033,19 +2342,19 @@ LcpSendEchoRequest (fsm *f) */ static void -lcp_echo_lowerup (int unit) +lcp_echo_lowerup (unit) + int unit; { - fsm *f = &lcp_fsm[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); - } + /* 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); } /* @@ -2053,14 +2362,13 @@ lcp_echo_lowerup (int unit) */ static void -lcp_echo_lowerdown (int unit) +lcp_echo_lowerdown (unit) + int unit; { - fsm *f = &lcp_fsm[unit]; + fsm *f = &lcp_fsm[unit]; - if (lcp_echo_timer_running != 0) { - UNTIMEOUT (LcpEchoTimeout, f); - lcp_echo_timer_running = 0; - } + if (lcp_echo_timer_running != 0) { + UNTIMEOUT (LcpEchoTimeout, f); + lcp_echo_timer_running = 0; + } } - -#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index b9201eeb..d5f8aee0 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -1,151 +1,135 @@ -/***************************************************************************** -* lcp.h - Network Link Control Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ /* * lcp.h - Link Control Protocol definitions. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * $Id: lcp.h,v 1.4 2010/01/18 20:49:43 goldsimon Exp $ + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: lcp.h,v 1.20 2004/11/14 22:53:42 carlsonj Exp $ */ -#ifndef LCP_H -#define LCP_H /* * 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 */ -#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ -#define CI_SSNHF 18 /* short sequence numbers for multilink */ -#define CI_EPDISC 19 /* endpoint discriminator */ +#define CI_VENDOR 0 /* Vendor Specific */ +#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_FCSALTERN 9 /* FCS-Alternatives */ +#define CI_SDP 10 /* Self-Describing-Pad */ +#define CI_NUMBERED 11 /* Numbered-Mode */ +#define CI_CALLBACK 13 /* callback */ +#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ +#define CI_SSNHF 18 /* short sequence numbers for multilink */ +#define CI_EPDISC 19 /* endpoint discriminator */ +#define CI_MPPLUS 22 /* Multi-Link-Plus-Procedure */ +#define CI_LDISC 23 /* Link-Discriminator */ +#define CI_LCPAUTH 24 /* LCP Authentication */ +#define CI_COBS 25 /* Consistent Overhead Byte Stuffing */ +#define CI_PREFELIS 26 /* Prefix Elision */ +#define CI_MPHDRFMT 27 /* MP Header Format */ +#define CI_I18N 28 /* Internationalization */ +#define CI_SDL 29 /* Simple Data Link */ /* * LCP-specific packet types (code numbers). */ -#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 */ +#define PROTREJ 8 /* Protocol Reject */ +#define ECHOREQ 9 /* Echo Request */ +#define ECHOREP 10 /* Echo Reply */ +#define DISCREQ 11 /* Discard Request */ +#define IDENTIF 12 /* Identification */ +#define TIMEREM 13 /* Time Remaining */ + +/* Value used as data for CI_CALLBACK option */ +#define CBCP_OPT 6 /* Use callback control protocol */ /* * The state of options is described by an lcp_options structure. */ typedef struct lcp_options { - u_int passive : 1; /* Don't die if we don't get a response */ - u_int silent : 1; /* Wait for the other end to start first */ - u_int restart : 1; /* Restart vs. exit after close */ - u_int neg_mru : 1; /* Negotiate the MRU? */ - u_int neg_asyncmap : 1; /* Negotiate the async map? */ - u_int neg_upap : 1; /* Ask for UPAP authentication? */ - u_int neg_chap : 1; /* Ask for CHAP authentication? */ - u_int neg_magicnumber : 1; /* Ask for magic number? */ - u_int neg_pcompression : 1; /* HDLC Protocol Field Compression? */ - u_int neg_accompression : 1; /* HDLC Address/Control Field Compression? */ - u_int neg_lqr : 1; /* Negotiate use of Link Quality Reports */ - u_int neg_cbcp : 1; /* Negotiate use of CBCP */ -#ifdef PPP_MULTILINK - u_int neg_mrru : 1; /* Negotiate multilink MRRU */ - u_int neg_ssnhf : 1; /* Negotiate short sequence numbers */ - u_int neg_endpoint : 1; /* Negotiate endpoint discriminator */ -#endif - u_short mru; /* Value of MRU */ -#ifdef PPP_MULTILINK - u_short mrru; /* Value of MRRU, and multilink enable */ -#endif - u_char chap_mdtype; /* which MD type (hashing algorithm) */ - u32_t asyncmap; /* Value of async map */ - u32_t magicnumber; - int numloops; /* Number of loops during magic number neg. */ - u32_t lqr_period; /* Reporting period for LQR 1/100ths second */ -#ifdef PPP_MULTILINK - struct epdisc endpoint; /* endpoint discriminator */ -#endif + 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_eap; /* Ask for EAP 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 */ + bool neg_mrru; /* negotiate multilink MRRU */ + bool neg_ssnhf; /* negotiate short sequence numbers */ + bool neg_endpoint; /* negotiate endpoint discriminator */ + int mru; /* Value of MRU */ + int mrru; /* Value of MRRU, and multilink enable */ + u_char chap_mdtype; /* which MD types (hashing algorithm) */ + u_int32_t asyncmap; /* Value of async map */ + u_int32_t magicnumber; + int numloops; /* Number of loops during magic number neg. */ + u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ + struct epdisc endpoint; /* endpoint discriminator */ } lcp_options; -/* - * Values for phase from BSD pppd.h based on RFC 1661. - */ -typedef enum { - PHASE_DEAD = 0, - PHASE_INITIALIZE, - PHASE_ESTABLISH, - PHASE_AUTHENTICATE, - PHASE_CALLBACK, - PHASE_NETWORK, - PHASE_TERMINATE -} LinkPhase; - - - -extern LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */ +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 ext_accm xmit_accm[]; +#define DEFMRU 1500 /* Try for this */ +#define MINMRU 128 /* No MRUs below this */ +#define MAXMRU 16384 /* Normally limit MRU to this */ -void lcp_init (int); -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 */ +void lcp_open __P((int)); +void lcp_close __P((int, char *)); +void lcp_lowerup __P((int)); +void lcp_lowerdown __P((int)); +void lcp_sprotrej __P((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 - -#endif /* LCP_H */ +#define DEFLOOPBACKFAIL 10 diff --git a/src/netif/ppp/linux/if_ppp.h b/src/netif/ppp/linux/if_ppp.h new file mode 100644 index 00000000..1101fc78 --- /dev/null +++ b/src/netif/ppp/linux/if_ppp.h @@ -0,0 +1,178 @@ +/* $Id: if_ppp.h,v 1.23 2002/12/06 09:49:15 paulus Exp $ */ + +/* + * if_ppp.h - Point-to-Point Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* + * ==FILEVERSION 20000724== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. + * if_ppp.h is shipped with a PPP distribution as well as with the kernel; + * if everyone increases the FILEVERSION number above, then scripts + * can do the right thing when deciding whether to install a new if_ppp.h + * file. Don't change the format of that line otherwise, so the + * installation script can recognize it. + */ + +#ifndef _IF_PPP_H_ +#define _IF_PPP_H_ + +/* + * Packet sizes + */ + +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#define PPP_MAXMRU 65000 /* Largest MRU we allow */ +#define PROTO_IPX 0x002b /* protocol numbers */ +#define PROTO_DNA_RT 0x0027 /* DNA Routing */ + + +/* + * Bit definitions for flags. + */ + +#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */ +#define SC_COMP_AC 0x00000002 /* header compression (output) */ +#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */ +#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */ +#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */ +#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */ +#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */ +#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */ +#define SC_ENABLE_IP 0x00000100 /* IP packets may be exchanged */ +#define SC_LOOP_TRAFFIC 0x00000200 /* send traffic to pppd */ +#define SC_MULTILINK 0x00000400 /* do multilink encapsulation */ +#define SC_MP_SHORTSEQ 0x00000800 /* use short MP sequence numbers */ +#define SC_COMP_RUN 0x00001000 /* compressor has been inited */ +#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */ +#define SC_MP_XSHORTSEQ 0x00004000 /* transmit short MP seq numbers */ +#define SC_DEBUG 0x00010000 /* enable debug messages */ +#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */ +#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ +#define SC_LOG_RAWIN 0x00080000 /* log all chars received */ +#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ +#define SC_SYNC 0x00200000 /* synchronous serial mode */ +#define SC_MASK 0x0f200fff /* bits that user can change */ + +/* state bits */ +#define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */ +#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ +#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ +#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */ +#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ +#define SC_DC_FERROR 0x00800000 /* fatal decomp error detected */ +#define SC_DC_ERROR 0x00400000 /* non-fatal decomp error detected */ + +/* + * Ioctl definitions. + */ + +struct npioctl { + int protocol; /* PPP protocol, e.g. PPP_IP */ + enum NPmode mode; +}; + +/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ +struct ppp_option_data { + __u8 *ptr; + __u32 length; + int transmit; +}; + +struct ifpppstatsreq { + struct ifreq b; + struct ppp_stats stats; /* statistic information */ +}; + +struct ifpppcstatsreq { + struct ifreq b; + struct ppp_comp_stats stats; +}; + +#define ifr__name b.ifr_ifrn.ifrn_name +#define stats_ptr b.ifr_ifru.ifru_data + +/* + * Ioctl definitions. + */ + +#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */ +#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */ +#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */ +#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */ +#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */ +#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */ +#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */ +#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */ +#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */ +#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */ +#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */ +#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */ +#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */ +#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data) +#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */ +#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */ +#define PPPIOCSPASS _IOW('t', 71, struct sock_fprog) /* set pass filter */ +#define PPPIOCSACTIVE _IOW('t', 70, struct sock_fprog) /* set active filt */ +#define PPPIOCGDEBUG _IOR('t', 65, int) /* Read debug level */ +#define PPPIOCSDEBUG _IOW('t', 64, int) /* Set debug level */ +#define PPPIOCGIDLE _IOR('t', 63, struct ppp_idle) /* get idle time */ +#define PPPIOCNEWUNIT _IOWR('t', 62, int) /* create new ppp unit */ +#define PPPIOCATTACH _IOW('t', 61, int) /* attach to ppp unit */ +#define PPPIOCDETACH _IOW('t', 60, int) /* detach from ppp unit/chan */ +#define PPPIOCSMRRU _IOW('t', 59, int) /* set multilink MRU */ +#define PPPIOCCONNECT _IOW('t', 58, int) /* connect channel to unit */ +#define PPPIOCDISCONN _IO('t', 57) /* disconnect channel */ +#define PPPIOCATTCHAN _IOW('t', 56, int) /* attach to ppp channel */ +#define PPPIOCGCHAN _IOR('t', 55, int) /* get ppp channel number */ + +#define SIOCGPPPSTATS (SIOCDEVPRIVATE + 0) +#define SIOCGPPPVER (SIOCDEVPRIVATE + 1) /* NEVER change this!! */ +#define SIOCGPPPCSTATS (SIOCDEVPRIVATE + 2) + +#if !defined(ifr_mtu) +#define ifr_mtu ifr_ifru.ifru_metric +#endif + +#endif /* _IF_PPP_H_ */ diff --git a/src/netif/ppp/linux/if_pppol2tp.h b/src/netif/ppp/linux/if_pppol2tp.h new file mode 100644 index 00000000..4113d6ad --- /dev/null +++ b/src/netif/ppp/linux/if_pppol2tp.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Linux PPP over L2TP (PPPoL2TP) Socket Implementation (RFC 2661) + * + * This file supplies definitions required by the PPP over L2TP driver + * (pppol2tp.c). All version information wrt this file is located in pppol2tp.c + * + * License: + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#ifndef __LINUX_IF_PPPOL2TP_H +#define __LINUX_IF_PPPOL2TP_H + +#include + +/* Structure used to connect() the socket to a particular tunnel UDP + * socket. + */ +struct pppol2tp_addr +{ + pid_t pid; /* pid that owns the fd. + * 0 => current */ + int fd; /* FD of UDP socket to use */ + + struct sockaddr_in addr; /* IP address and port to send to */ + + __u16 s_tunnel, s_session; /* For matching incoming packets */ + __u16 d_tunnel, d_session; /* For sending outgoing packets */ +}; + +/* Socket options: + * DEBUG - bitmask of debug message categories + * SENDSEQ - 0 => don't send packets with sequence numbers + * 1 => send packets with sequence numbers + * RECVSEQ - 0 => receive packet sequence numbers are optional + * 1 => drop receive packets without sequence numbers + * LNSMODE - 0 => act as LAC. + * 1 => act as LNS. + * REORDERTO - reorder timeout (in millisecs). If 0, don't try to reorder. + */ +enum { + PPPOL2TP_SO_DEBUG = 1, + PPPOL2TP_SO_RECVSEQ = 2, + PPPOL2TP_SO_SENDSEQ = 3, + PPPOL2TP_SO_LNSMODE = 4, + PPPOL2TP_SO_REORDERTO = 5, +}; + +/* Debug message categories for the DEBUG socket option */ +enum { + PPPOL2TP_MSG_DEBUG = (1 << 0), /* verbose debug (if + * compiled in) */ + PPPOL2TP_MSG_CONTROL = (1 << 1), /* userspace - kernel + * interface */ + PPPOL2TP_MSG_SEQ = (1 << 2), /* sequence numbers */ + PPPOL2TP_MSG_DATA = (1 << 3), /* data packets */ +}; + + + +#endif diff --git a/src/netif/ppp/linux/ppp-comp.h b/src/netif/ppp/linux/ppp-comp.h new file mode 100644 index 00000000..d30cacbd --- /dev/null +++ b/src/netif/ppp/linux/ppp-comp.h @@ -0,0 +1,213 @@ +/* + * ppp-comp.h - Definitions for doing PPP packet compression. + * + * Copyright (c) 1984 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ppp-comp.h,v 1.10 2002/12/06 09:49:15 paulus Exp $ + */ + +/* + * ==FILEVERSION 20020319== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. + * ppp-comp.h is shipped with a PPP distribution as well as with the kernel; + * if everyone increases the FILEVERSION number above, then scripts + * can do the right thing when deciding whether to install a new ppp-comp.h + * file. Don't change the format of that line otherwise, so the + * installation script can recognize it. + */ + +#ifndef _NET_PPP_COMP_H +#define _NET_PPP_COMP_H + +/* + * The following symbols control whether we include code for + * various compression methods. + */ + +#ifndef DO_BSD_COMPRESS +#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ +#endif +#ifndef DO_DEFLATE +#define DO_DEFLATE 1 /* by default, include Deflate */ +#endif +#define DO_PREDICTOR_1 0 +#define DO_PREDICTOR_2 0 + +/* + * Structure giving methods for compression/decompression. + */ + +struct compressor { + int compress_proto; /* CCP compression protocol number */ + + /* Allocate space for a compressor (transmit side) */ + void *(*comp_alloc) (unsigned char *options, int opt_len); + + /* Free space used by a compressor */ + void (*comp_free) (void *state); + + /* Initialize a compressor */ + int (*comp_init) (void *state, unsigned char *options, + int opt_len, int unit, int opthdr, int debug); + + /* Reset a compressor */ + void (*comp_reset) (void *state); + + /* Compress a packet */ + int (*compress) (void *state, unsigned char *rptr, + unsigned char *obuf, int isize, int osize); + + /* Return compression statistics */ + void (*comp_stat) (void *state, struct compstat *stats); + + /* Allocate space for a decompressor (receive side) */ + void *(*decomp_alloc) (unsigned char *options, int opt_len); + + /* Free space used by a decompressor */ + void (*decomp_free) (void *state); + + /* Initialize a decompressor */ + int (*decomp_init) (void *state, unsigned char *options, + int opt_len, int unit, int opthdr, int mru, + int debug); + + /* Reset a decompressor */ + void (*decomp_reset) (void *state); + + /* Decompress a packet. */ + int (*decompress) (void *state, unsigned char *ibuf, int isize, + unsigned char *obuf, int osize); + + /* Update state for an incompressible packet received */ + void (*incomp) (void *state, unsigned char *ibuf, int icnt); + + /* Return decompression statistics */ + void (*decomp_stat) (void *state, struct compstat *stats); +}; + +/* + * The return value from decompress routine is the length of the + * decompressed packet if successful, otherwise DECOMP_ERROR + * or DECOMP_FATALERROR if an error occurred. + * + * We need to make this distinction so that we can disable certain + * useful functionality, namely sending a CCP reset-request as a result + * of an error detected after decompression. This is to avoid infringing + * a patent held by Motorola. + * Don't you just lurve software patents. + */ + +#define DECOMP_ERROR -1 /* error detected before decomp. */ +#define DECOMP_FATALERROR -2 /* error detected after decomp. */ + +/* + * CCP codes. + */ + +#define CCP_CONFREQ 1 +#define CCP_CONFACK 2 +#define CCP_TERMREQ 5 +#define CCP_TERMACK 6 +#define CCP_RESETREQ 14 +#define CCP_RESETACK 15 + +/* + * Max # bytes for a CCP option + */ + +#define CCP_MAX_OPTION_LENGTH 32 + +/* + * Parts of a CCP packet. + */ + +#define CCP_CODE(dp) ((dp)[0]) +#define CCP_ID(dp) ((dp)[1]) +#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) +#define CCP_HDRLEN 4 + +#define CCP_OPT_CODE(dp) ((dp)[0]) +#define CCP_OPT_LENGTH(dp) ((dp)[1]) +#define CCP_OPT_MINLEN 2 + +/* + * Definitions for BSD-Compress. + */ + +#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ +#define CILEN_BSD_COMPRESS 3 /* length of config. option */ + +/* Macros for handling the 3rd byte of the BSD-Compress config option. */ +#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ +#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ +#define BSD_CURRENT_VERSION 1 /* current version number */ +#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) + +#define BSD_MIN_BITS 9 /* smallest code size supported */ +#define BSD_MAX_BITS 15 /* largest code size supported */ + +/* + * Definitions for Deflate. + */ + +#define CI_DEFLATE 26 /* config option for Deflate */ +#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ +#define CILEN_DEFLATE 4 /* length of its config option */ + +#define DEFLATE_MIN_SIZE 8 +#define DEFLATE_MAX_SIZE 15 +#define DEFLATE_METHOD_VAL 8 +#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) +#define DEFLATE_METHOD(x) ((x) & 0x0F) +#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ + + DEFLATE_METHOD_VAL) +#define DEFLATE_CHK_SEQUENCE 0 + +/* + * Definitions for MPPE. + */ + +#define CI_MPPE 18 /* config option for MPPE */ +#define CILEN_MPPE 6 /* length of config option */ + +/* + * Definitions for other, as yet unsupported, compression methods. + */ + +#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ +#define CILEN_PREDICTOR_1 2 /* length of its config option */ +#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ +#define CILEN_PREDICTOR_2 2 /* length of its config option */ + +#endif /* _NET_PPP_COMP_H */ diff --git a/src/netif/ppp/linux/ppp_defs.h b/src/netif/ppp/linux/ppp_defs.h new file mode 100644 index 00000000..314339e9 --- /dev/null +++ b/src/netif/ppp/linux/ppp_defs.h @@ -0,0 +1,195 @@ +/* $Id: ppp_defs.h,v 1.11 2002/12/06 09:49:15 paulus Exp $ */ + +/* + * ppp_defs.h - PPP definitions. + * + * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * ==FILEVERSION 20020521== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. + * ppp_defs.h is shipped with a PPP distribution as well as with the kernel; + * if everyone increases the FILEVERSION number above, then scripts + * can do the right thing when deciding whether to install a new ppp_defs.h + * file. Don't change the format of that line otherwise, so the + * installation script can recognize it. + */ + +#ifndef _PPP_DEFS_H_ +#define _PPP_DEFS_H_ + +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ +#define PPP_MRU 1500 /* default MRU = max length of info field */ + +#define PPP_ADDRESS(p) (((__u8 *)(p))[0]) +#define PPP_CONTROL(p) (((__u8 *)(p))[1]) +#define PPP_PROTOCOL(p) ((((__u8 *)(p))[2] << 8) + ((__u8 *)(p))[3]) + +/* + * Significant octet values. + */ +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_FLAG 0x7e /* Flag Sequence */ +#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ +#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* + * Protocol field values. + */ +#define PPP_IP 0x21 /* Internet Protocol */ +#define PPP_AT 0x29 /* AppleTalk Protocol */ +#define PPP_IPX 0x2b /* IPX protocol */ +#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ +#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ +#define PPP_MP 0x3d /* Multilink protocol */ +#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ +#define PPP_COMPFRAG 0xfb /* fragment compressed below bundle */ +#define PPP_COMP 0xfd /* compressed packet */ +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ +#define PPP_IPXCP 0x802b /* IPX Control Protocol */ +#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#define PPP_CCPFRAG 0x80fb /* CCP at link level (below MP bundle) */ +#define PPP_CCP 0x80fd /* Compression Control Protocol */ +#define PPP_ECPFRAG 0x8055 /* ECP at link level (below MP bundle) */ +#define PPP_ECP 0x8053 /* Encryption Control Protocol */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ +#define PPP_CBCP 0xc029 /* Callback Control Protocol */ + +/* + * Values for FCS calculations. + */ + +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +/* + * Extended asyncmap - allows any character to be escaped. + */ + +typedef __u32 ext_accm[8]; + +/* + * What to do with network protocol (NP) packets. + */ +enum NPmode { + NPMODE_PASS, /* pass the packet through */ + NPMODE_DROP, /* silently drop the packet */ + NPMODE_ERROR, /* return an error */ + NPMODE_QUEUE /* save it up for later. */ +}; + +/* + * Statistics for LQRP and pppstats + */ +struct pppstat { + __u32 ppp_discards; /* # frames discarded */ + + __u32 ppp_ibytes; /* bytes received */ + __u32 ppp_ioctects; /* bytes received not in error */ + __u32 ppp_ipackets; /* packets received */ + __u32 ppp_ierrors; /* receive errors */ + __u32 ppp_ilqrs; /* # LQR frames received */ + + __u32 ppp_obytes; /* raw bytes sent */ + __u32 ppp_ooctects; /* frame bytes sent */ + __u32 ppp_opackets; /* packets sent */ + __u32 ppp_oerrors; /* transmit errors */ + __u32 ppp_olqrs; /* # LQR frames sent */ +}; + +struct vjstat { + __u32 vjs_packets; /* outbound packets */ + __u32 vjs_compressed; /* outbound compressed packets */ + __u32 vjs_searches; /* searches for connection state */ + __u32 vjs_misses; /* times couldn't find conn. state */ + __u32 vjs_uncompressedin; /* inbound uncompressed packets */ + __u32 vjs_compressedin; /* inbound compressed packets */ + __u32 vjs_errorin; /* inbound unknown type packets */ + __u32 vjs_tossed; /* inbound packets tossed because of error */ +}; + +struct compstat { + __u32 unc_bytes; /* total uncompressed bytes */ + __u32 unc_packets; /* total uncompressed packets */ + __u32 comp_bytes; /* compressed bytes */ + __u32 comp_packets; /* compressed packets */ + __u32 inc_bytes; /* incompressible bytes */ + __u32 inc_packets; /* incompressible packets */ + + /* the compression ratio is defined as in_count / bytes_out */ + __u32 in_count; /* Bytes received */ + __u32 bytes_out; /* Bytes transmitted */ + + double ratio; /* not computed in kernel. */ +}; + +struct ppp_stats { + struct pppstat p; /* basic PPP statistics */ + struct vjstat vj; /* VJ header compression statistics */ +}; + +struct ppp_comp_stats { + struct compstat c; /* packet compression statistics */ + struct compstat d; /* packet decompression statistics */ +}; + +/* + * The following structure records the time in seconds since + * the last NP packet was sent or received. + */ +struct ppp_idle { + time_t xmit_idle; /* time since last NP packet sent */ + time_t recv_idle; /* time since last NP packet received */ +}; + +#ifndef __P +#ifdef __STDC__ +#define __P(x) x +#else +#define __P(x) () +#endif +#endif + +#endif /* _PPP_DEFS_H_ */ diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 3732a424..7e0a8ce0 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -1,80 +1,125 @@ -/***************************************************************************** -* magic.c - Network Random Number Generator program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-04 Guy Lancaster , Global Election Systems Inc. -* Original based on BSD magic.c. -*****************************************************************************/ /* * magic.c - PPP Magic Number routines. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "lwip/opt.h" -#if PPP_SUPPORT +#define RCSID "$Id: magic.c,v 1.11 2003/06/11 23:56:26 paulus Exp $" -#include "ppp_impl.h" -#include "randm.h" +#include +#include +#include +#include +#include + +#include "pppd.h" #include "magic.h" +static const char rcsid[] = RCSID; + +extern long mrand48 __P((void)); +extern void srand48 __P((long)); /* - * magicInit - Initialize the magic number generator. + * magic_init - Initialize the magic number generator. * - * Since we use another random number generator that has its own - * initialization, we do nothing here. + * 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 magicInit() +void +magic_init() { - return; + 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. */ -u32_t magic() +u_int32_t +magic() { - return avRandom(); + return (u_int32_t) mrand48(); } -#endif /* PPP_SUPPORT */ +/* + * random_bytes - Fill a buffer with random bytes. + */ +void +random_bytes(unsigned char *buf, int len) +{ + int i; + + for (i = 0; i < len; ++i) + buf[i] = mrand48() >> 24; +} + +#ifdef NO_DRAND48 +/* + * Substitute procedures for those systems which don't have + * drand48 et al. + */ + +double +drand48() +{ + return (double)random() / (double)0x7fffffffL; /* 2**31-1 */ +} + +long +mrand48() +{ + return random(); +} + +void +srand48(seedval) +long seedval; +{ + srandom((int)seedval); +} + +#endif diff --git a/src/netif/ppp/magic.h b/src/netif/ppp/magic.h index eba70d20..c81213b4 100644 --- a/src/netif/ppp/magic.h +++ b/src/netif/ppp/magic.h @@ -1,63 +1,49 @@ -/***************************************************************************** -* magic.h - Network Random Number Generator header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-04 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ /* * magic.h - PPP Magic Number definitions. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * $Id: magic.h,v 1.3 2010/01/18 20:49:43 goldsimon Exp $ + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $ */ -#ifndef MAGIC_H -#define MAGIC_H +void magic_init __P((void)); /* Initialize the magic number generator */ +u_int32_t magic __P((void)); /* Returns the next magic number */ -/* Initialize the magic number generator */ -void magicInit(void); - -/* Returns the next magic number */ -u32_t magic(void); - -#endif /* MAGIC_H */ +/* Fill buffer with random bytes */ +void random_bytes __P((unsigned char *buf, int len)); diff --git a/src/netif/ppp/md4.c b/src/netif/ppp/md4.c new file mode 100644 index 00000000..f0831a92 --- /dev/null +++ b/src/netif/ppp/md4.c @@ -0,0 +1,301 @@ +/* +** ******************************************************************** +** md4.c -- Implementation of MD4 Message Digest Algorithm ** +** Updated: 2/16/90 by Ronald L. Rivest ** +** (C) 1990 RSA Data Security, Inc. ** +** ******************************************************************** +*/ + +#include "lwip/opt.h" + +/* +** To use MD4: +** -- Include md4.h in your program +** -- Declare an MDstruct MD to hold the state of the digest +** computation. +** -- Initialize MD using MDbegin(&MD) +** -- For each full block (64 bytes) X you wish to process, call +** MD4Update(&MD,X,512) +** (512 is the number of bits in a full block.) +** -- For the last block (less than 64 bytes) you wish to process, +** MD4Update(&MD,X,n) +** where n is the number of bits in the partial block. A partial +** block terminates the computation, so every MD computation +** should terminate by processing a partial block, even if it +** has n = 0. +** -- The message digest is available in MD.buffer[0] ... +** MD.buffer[3]. (Least-significant byte of each word +** should be output first.) +** -- You can print out the digest using MDprint(&MD) +*/ + +/* Implementation notes: +** This implementation assumes that ints are 32-bit quantities. +*/ + +#define TRUE 1 +#define FALSE 0 + +/* Compile-time includes +*/ +#include +#include "md4.h" +#include "pppd.h" + +/* Compile-time declarations of MD4 "magic constants". +*/ +#define I0 0x67452301 /* Initial values for MD buffer */ +#define I1 0xefcdab89 +#define I2 0x98badcfe +#define I3 0x10325476 +#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ +#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ +/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 +** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. +** Table 2, page 660. +*/ + +#define fs1 3 /* round 1 shift amounts */ +#define fs2 7 +#define fs3 11 +#define fs4 19 +#define gs1 3 /* round 2 shift amounts */ +#define gs2 5 +#define gs3 9 +#define gs4 13 +#define hs1 3 /* round 3 shift amounts */ +#define hs2 9 +#define hs3 11 +#define hs4 15 + +/* Compile-time macro declarations for MD4. +** Note: The "rot" operator uses the variable "tmp". +** It assumes tmp is declared as unsigned int, so that the >> +** operator will shift in zeros rather than extending the sign bit. +*/ +#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) +#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) +#define h(X,Y,Z) (X^Y^Z) +#define rot(X,S) (tmp=X,(tmp<>(32-S))) +#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) +#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) +#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) + +/* MD4print(MDp) +** Print message digest buffer MDp as 32 hexadecimal digits. +** Order is from low-order byte of buffer[0] to high-order byte of +** buffer[3]. +** Each byte is printed with high-order hexadecimal digit first. +** This is a user-callable routine. +*/ +void +MD4Print(MDp) +MD4_CTX *MDp; +{ + int i,j; + for (i=0;i<4;i++) + for (j=0;j<32;j=j+8) + printf("%02x",(MDp->buffer[i]>>j) & 0xFF); +} + +/* MD4Init(MDp) +** Initialize message digest buffer MDp. +** This is a user-callable routine. +*/ +void +MD4Init(MDp) +MD4_CTX *MDp; +{ + int i; + MDp->buffer[0] = I0; + MDp->buffer[1] = I1; + MDp->buffer[2] = I2; + MDp->buffer[3] = I3; + for (i=0;i<8;i++) MDp->count[i] = 0; + MDp->done = 0; +} + +/* MDblock(MDp,X) +** Update message digest buffer MDp->buffer using 16-word data block X. +** Assumes all 16 words of X are full of data. +** Does not update MDp->count. +** This routine is not user-callable. +*/ +static void +MDblock(MDp,Xb) +MD4_CTX *MDp; +unsigned char *Xb; +{ + register unsigned int tmp, A, B, C, D; + unsigned int X[16]; + int i; + + for (i = 0; i < 16; ++i) { + X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); + Xb += 4; + } + + A = MDp->buffer[0]; + B = MDp->buffer[1]; + C = MDp->buffer[2]; + D = MDp->buffer[3]; + /* Update the message digest buffer */ + ff(A , B , C , D , 0 , fs1); /* Round 1 */ + ff(D , A , B , C , 1 , fs2); + ff(C , D , A , B , 2 , fs3); + ff(B , C , D , A , 3 , fs4); + ff(A , B , C , D , 4 , fs1); + ff(D , A , B , C , 5 , fs2); + ff(C , D , A , B , 6 , fs3); + ff(B , C , D , A , 7 , fs4); + ff(A , B , C , D , 8 , fs1); + ff(D , A , B , C , 9 , fs2); + ff(C , D , A , B , 10 , fs3); + ff(B , C , D , A , 11 , fs4); + ff(A , B , C , D , 12 , fs1); + ff(D , A , B , C , 13 , fs2); + ff(C , D , A , B , 14 , fs3); + ff(B , C , D , A , 15 , fs4); + gg(A , B , C , D , 0 , gs1); /* Round 2 */ + gg(D , A , B , C , 4 , gs2); + gg(C , D , A , B , 8 , gs3); + gg(B , C , D , A , 12 , gs4); + gg(A , B , C , D , 1 , gs1); + gg(D , A , B , C , 5 , gs2); + gg(C , D , A , B , 9 , gs3); + gg(B , C , D , A , 13 , gs4); + gg(A , B , C , D , 2 , gs1); + gg(D , A , B , C , 6 , gs2); + gg(C , D , A , B , 10 , gs3); + gg(B , C , D , A , 14 , gs4); + gg(A , B , C , D , 3 , gs1); + gg(D , A , B , C , 7 , gs2); + gg(C , D , A , B , 11 , gs3); + gg(B , C , D , A , 15 , gs4); + hh(A , B , C , D , 0 , hs1); /* Round 3 */ + hh(D , A , B , C , 8 , hs2); + hh(C , D , A , B , 4 , hs3); + hh(B , C , D , A , 12 , hs4); + hh(A , B , C , D , 2 , hs1); + hh(D , A , B , C , 10 , hs2); + hh(C , D , A , B , 6 , hs3); + hh(B , C , D , A , 14 , hs4); + hh(A , B , C , D , 1 , hs1); + hh(D , A , B , C , 9 , hs2); + hh(C , D , A , B , 5 , hs3); + hh(B , C , D , A , 13 , hs4); + hh(A , B , C , D , 3 , hs1); + hh(D , A , B , C , 11 , hs2); + hh(C , D , A , B , 7 , hs3); + hh(B , C , D , A , 15 , hs4); + MDp->buffer[0] += A; + MDp->buffer[1] += B; + MDp->buffer[2] += C; + MDp->buffer[3] += D; +} + +/* MD4Update(MDp,X,count) +** Input: X -- a pointer to an array of unsigned characters. +** count -- the number of bits of X to use. +** (if not a multiple of 8, uses high bits of last byte.) +** Update MDp using the number of bits of X given by count. +** This is the basic input routine for an MD4 user. +** The routine completes the MD computation when count < 512, so +** every MD computation should end with one call to MD4Update with a +** count less than 512. A call with count 0 will be ignored if the +** MD has already been terminated (done != 0), so an extra call with +** count 0 can be given as a "courtesy close" to force termination +** if desired. +*/ +void +MD4Update(MDp,X,count) +MD4_CTX *MDp; +unsigned char *X; +unsigned int count; +{ + unsigned int i, tmp, bit, byte, mask; + unsigned char XX[64]; + unsigned char *p; + + /* return with no error if this is a courtesy close with count + ** zero and MDp->done is true. + */ + if (count == 0 && MDp->done) return; + /* check to see if MD is already done and report error */ + if (MDp->done) + { printf("\nError: MD4Update MD already done."); return; } + + /* Add count to MDp->count */ + tmp = count; + p = MDp->count; + while (tmp) + { tmp += *p; + *p++ = tmp; + tmp = tmp >> 8; + } + + /* Process data */ + if (count == 512) + { /* Full block of data to handle */ + MDblock(MDp,X); + } + else if (count > 512) /* Check for count too large */ + { + printf("\nError: MD4Update called with illegal count value %d.", + count); + return; + } + else /* partial block -- must be last block so finish up */ + { + /* Find out how many bytes and residual bits there are */ + byte = count >> 3; + bit = count & 7; + /* Copy X into XX since we need to modify it */ + if (count) + for (i=0;i<=byte;i++) XX[i] = X[i]; + for (i=byte+1;i<64;i++) XX[i] = 0; + /* Add padding '1' bit and low-order zeros in last byte */ + mask = 1 << (7 - bit); + XX[byte] = (XX[byte] | mask) & ~( mask - 1); + /* If room for bit count, finish up with this block */ + if (byte <= 55) + { + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,XX); + } + else /* need to do two blocks to finish up */ + { + MDblock(MDp,XX); + for (i=0;i<56;i++) XX[i] = 0; + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,XX); + } + /* Set flag saying we're done with MD computation */ + MDp->done = 1; + } +} + +/* +** Finish up MD4 computation and return message digest. +*/ +void +MD4Final(buf, MD) +unsigned char *buf; +MD4_CTX *MD; +{ + int i, j; + unsigned int w; + + MD4Update(MD, NULL, 0); + for (i = 0; i < 4; ++i) { + w = MD->buffer[i]; + for (j = 0; j < 4; ++j) { + *buf++ = w; + w >>= 8; + } + } +} + +/* +** End of md4.c +****************************(cut)***********************************/ diff --git a/src/netif/ppp/md4.h b/src/netif/ppp/md4.h new file mode 100644 index 00000000..80e8f9a2 --- /dev/null +++ b/src/netif/ppp/md4.h @@ -0,0 +1,64 @@ + +/* +** ******************************************************************** +** md4.h -- Header file for implementation of ** +** MD4 Message Digest Algorithm ** +** Updated: 2/13/90 by Ronald L. Rivest ** +** (C) 1990 RSA Data Security, Inc. ** +** ******************************************************************** +*/ + +#ifndef __P +# if defined(__STDC__) || defined(__GNUC__) +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + + +/* MDstruct is the data structure for a message digest computation. +*/ +typedef struct { + unsigned int buffer[4]; /* Holds 4-word result of MD computation */ + unsigned char count[8]; /* Number of bits processed so far */ + unsigned int done; /* Nonzero means MD computation finished */ +} MD4_CTX; + +/* MD4Init(MD4_CTX *) +** Initialize the MD4_CTX prepatory to doing a message digest +** computation. +*/ +extern void MD4Init __P((MD4_CTX *MD)); + +/* MD4Update(MD,X,count) +** Input: X -- a pointer to an array of unsigned characters. +** count -- the number of bits of X to use (an unsigned int). +** Updates MD using the first "count" bits of X. +** The array pointed to by X is not modified. +** If count is not a multiple of 8, MD4Update uses high bits of +** last byte. +** This is the basic input routine for a user. +** The routine terminates the MD computation when count < 512, so +** every MD computation should end with one call to MD4Update with a +** count less than 512. Zero is OK for a count. +*/ +extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); + +/* MD4Print(MD) +** Prints message digest buffer MD as 32 hexadecimal digits. +** Order is from low-order byte of buffer[0] to high-order byte +** of buffer[3]. +** Each byte is printed with high-order hexadecimal digit first. +*/ +extern void MD4Print __P((MD4_CTX *)); + +/* MD4Final(buf, MD) +** Returns message digest from MD and terminates the message +** digest computation. +*/ +extern void MD4Final __P((unsigned char *, MD4_CTX *)); + +/* +** End of md4.h +****************************(cut)***********************************/ diff --git a/src/netif/ppp/md5.c b/src/netif/ppp/md5.c index dc3cc751..11de7b6d 100644 --- a/src/netif/ppp/md5.c +++ b/src/netif/ppp/md5.c @@ -1,3 +1,5 @@ + + /* *********************************************************************** ** md5.c -- the source code for MD5 routines ** @@ -7,6 +9,8 @@ *********************************************************************** */ +#include "lwip/opt.h" + /* *********************************************************************** ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** @@ -31,32 +35,22 @@ *********************************************************************** */ -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if CHAP_SUPPORT || MD5_SUPPORT - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "md5.h" - #include +#include "md5.h" /* *********************************************************************** ** Message-digest routines: ** ** To form the message digest for a message M ** - ** (1) Initialize a context buffer mdContext using MD5Init ** - ** (2) Call MD5Update on mdContext and M ** - ** (3) Call MD5Final on mdContext ** + ** (1) Initialize a context buffer mdContext using MD5_Init ** + ** (2) Call MD5_Update on mdContext and M ** + ** (3) Call MD5_Final on mdContext ** ** The message digest is now in mdContext->digest[0...15] ** *********************************************************************** */ /* forward declaration */ -static void Transform (u32_t *buf, u32_t *in); +static void Transform (UINT4 *buf, UINT4 *in); static unsigned char PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -81,76 +75,69 @@ static unsigned char PADDING[64] = { /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ /* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s, ac) \ - {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \ + {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) \ - {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \ + {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) \ - {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \ + {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) \ - {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \ + {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #ifdef __STDC__ -#define UL(x) x##UL +#define UL(x) x##U #else -#ifdef WIN32 -#define UL(x) x##UL -#else -#define UL(x) x -#endif +#define UL(x) x #endif -/* The routine MD5Init initializes the message-digest context +/* The routine MD5_Init initializes the message-digest context mdContext. All fields are set to zero. */ -void -MD5Init (MD5_CTX *mdContext) +void MD5_Init (mdContext) +MD5_CTX *mdContext; { - mdContext->i[0] = mdContext->i[1] = (u32_t)0; + mdContext->i[0] = mdContext->i[1] = (UINT4)0; - /* Load magic initialization constants. */ - mdContext->buf[0] = (u32_t)0x67452301UL; - mdContext->buf[1] = (u32_t)0xefcdab89UL; - mdContext->buf[2] = (u32_t)0x98badcfeUL; - mdContext->buf[3] = (u32_t)0x10325476UL; + /* Load magic initialization constants. + */ + mdContext->buf[0] = (UINT4)0x67452301; + mdContext->buf[1] = (UINT4)0xefcdab89; + mdContext->buf[2] = (UINT4)0x98badcfe; + mdContext->buf[3] = (UINT4)0x10325476; } /* The routine MD5Update updates the message-digest context to account for the presence of each of the characters inBuf[0..inLen-1] in the message whose digest is being computed. */ -void -MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) +void MD5_Update (mdContext, inBuf, inLen) +MD5_CTX *mdContext; +unsigned char *inBuf; +unsigned int inLen; { - u32_t in[16]; + UINT4 in[16]; int mdi; unsigned int i, ii; -#if 0 - PPPDEBUG(LOG_INFO, ("MD5Update: %u:%.*H\n", inLen, LWIP_MIN(inLen, 20) * 2, inBuf)); - PPPDEBUG(LOG_INFO, ("MD5Update: %u:%s\n", inLen, inBuf)); -#endif - /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* update number of bits */ - if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0]) { + if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) mdContext->i[1]++; - } - mdContext->i[0] += ((u32_t)inLen << 3); - mdContext->i[1] += ((u32_t)inLen >> 29); + mdContext->i[0] += ((UINT4)inLen << 3); + mdContext->i[1] += ((UINT4)inLen >> 29); while (inLen--) { /* add new character to buffer, increment mdi */ @@ -158,12 +145,11 @@ MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) /* transform if necessary */ if (mdi == 0x40) { - for (i = 0, ii = 0; i < 16; i++, ii += 4) { - in[i] = (((u32_t)mdContext->in[ii+3]) << 24) | - (((u32_t)mdContext->in[ii+2]) << 16) | - (((u32_t)mdContext->in[ii+1]) << 8) | - ((u32_t)mdContext->in[ii]); - } + for (i = 0, ii = 0; i < 16; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); Transform (mdContext->buf, in); mdi = 0; } @@ -173,10 +159,11 @@ MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) /* The routine MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[0...15]. */ -void -MD5Final (unsigned char hash[], MD5_CTX *mdContext) +void MD5_Final (hash, mdContext) +unsigned char hash[]; +MD5_CTX *mdContext; { - u32_t in[16]; + UINT4 in[16]; int mdi; unsigned int i, ii; unsigned int padLen; @@ -190,36 +177,36 @@ MD5Final (unsigned char hash[], MD5_CTX *mdContext) /* pad out to 56 mod 64 */ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); - MD5Update (mdContext, PADDING, padLen); + MD5_Update (mdContext, PADDING, padLen); /* append length in bits and transform */ - for (i = 0, ii = 0; i < 14; i++, ii += 4) { - in[i] = (((u32_t)mdContext->in[ii+3]) << 24) | - (((u32_t)mdContext->in[ii+2]) << 16) | - (((u32_t)mdContext->in[ii+1]) << 8) | - ((u32_t)mdContext->in[ii]); - } + for (i = 0, ii = 0; i < 14; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); Transform (mdContext->buf, in); /* store buffer in digest */ for (i = 0, ii = 0; i < 4; i++, ii += 4) { - mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); mdContext->digest[ii+1] = - (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); mdContext->digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); mdContext->digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); } - SMEMCPY(hash, mdContext->digest, 16); + memcpy(hash, mdContext->digest, 16); } /* Basic MD5 step. Transforms buf based on in. */ -static void -Transform (u32_t *buf, u32_t *in) +static void Transform (buf, in) +UINT4 *buf; +UINT4 *in; { - u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; /* Round 1 */ #define S11 7 @@ -315,6 +302,8 @@ Transform (u32_t *buf, u32_t *in) buf[3] += d; } -#endif /* CHAP_SUPPORT || MD5_SUPPORT */ - -#endif /* PPP_SUPPORT */ +/* + *********************************************************************** + ** End of md5.c ** + ******************************** (cut) ******************************** + */ diff --git a/src/netif/ppp/md5.h b/src/netif/ppp/md5.h index e129533f..71e8b00e 100644 --- a/src/netif/ppp/md5.h +++ b/src/netif/ppp/md5.h @@ -37,19 +37,29 @@ *********************************************************************** */ -#ifndef MD5_H -#define MD5_H +#ifndef __MD5_INCLUDE__ + +/* typedef a 32-bit type */ +#ifdef _LP64 +typedef unsigned int UINT4; +typedef int INT4; +#else +typedef unsigned long UINT4; +typedef long INT4; +#endif +#define _UINT4_T /* Data structure for MD5 (Message-Digest) computation */ typedef struct { - u32_t i[2]; /* number of _bits_ handled mod 2^64 */ - u32_t buf[4]; /* scratch buffer */ - unsigned char in[64]; /* input buffer */ - unsigned char digest[16]; /* actual digest after MD5Final call */ + UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ } MD5_CTX; -void MD5Init ( MD5_CTX *mdContext); -void MD5Update( MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); -void MD5Final ( unsigned char hash[], MD5_CTX *mdContext); +void MD5_Init (MD5_CTX *mdContext); +void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); +void MD5_Final (unsigned char hash[], MD5_CTX *mdContext); -#endif /* MD5_H */ +#define __MD5_INCLUDE__ +#endif /* __MD5_INCLUDE__ */ diff --git a/src/netif/ppp/mppe.h b/src/netif/ppp/mppe.h new file mode 100644 index 00000000..5eb3b37a --- /dev/null +++ b/src/netif/ppp/mppe.h @@ -0,0 +1,121 @@ +/* + * mppe.h - Definitions for MPPE + * + * Copyright (c) 2008 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define MPPE_PAD 4 /* MPPE growth per frame */ +#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ + +/* option bits for ccp_options.mppe */ +#define MPPE_OPT_40 0x01 /* 40 bit */ +#define MPPE_OPT_128 0x02 /* 128 bit */ +#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */ +/* unsupported opts */ +#define MPPE_OPT_56 0x08 /* 56 bit */ +#define MPPE_OPT_MPPC 0x10 /* MPPC compression */ +#define MPPE_OPT_D 0x20 /* Unknown */ +#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D) +#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */ + +/* + * This is not nice ... the alternative is a bitfield struct though. + * And unfortunately, we cannot share the same bits for the option + * names above since C and H are the same bit. We could do a u_int32 + * but then we have to do a htonl() all the time and/or we still need + * to know which octet is which. + */ +#define MPPE_C_BIT 0x01 /* MPPC */ +#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */ +#define MPPE_L_BIT 0x20 /* 40-bit */ +#define MPPE_S_BIT 0x40 /* 128-bit */ +#define MPPE_M_BIT 0x80 /* 56-bit, not supported */ +#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */ + +/* Does not include H bit; used for least significant octet only. */ +#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT) + +/* Build a CI from mppe opts (see RFC 3078) */ +#define MPPE_OPTS_TO_CI(opts, ci) \ + do { \ + u_char *ptr = ci; /* u_char[4] */ \ + \ + /* H bit */ \ + if (opts & MPPE_OPT_STATEFUL) \ + *ptr++ = 0x0; \ + else \ + *ptr++ = MPPE_H_BIT; \ + *ptr++ = 0; \ + *ptr++ = 0; \ + \ + /* S,L bits */ \ + *ptr = 0; \ + if (opts & MPPE_OPT_128) \ + *ptr |= MPPE_S_BIT; \ + if (opts & MPPE_OPT_40) \ + *ptr |= MPPE_L_BIT; \ + /* M,D,C bits not supported */ \ + } while (/* CONSTCOND */ 0) + +/* The reverse of the above */ +#define MPPE_CI_TO_OPTS(ci, opts) \ + do { \ + u_char *ptr = ci; /* u_char[4] */ \ + \ + opts = 0; \ + \ + /* H bit */ \ + if (!(ptr[0] & MPPE_H_BIT)) \ + opts |= MPPE_OPT_STATEFUL; \ + \ + /* S,L bits */ \ + if (ptr[3] & MPPE_S_BIT) \ + opts |= MPPE_OPT_128; \ + if (ptr[3] & MPPE_L_BIT) \ + opts |= MPPE_OPT_40; \ + \ + /* M,D,C bits */ \ + if (ptr[3] & MPPE_M_BIT) \ + opts |= MPPE_OPT_56; \ + if (ptr[3] & MPPE_D_BIT) \ + opts |= MPPE_OPT_D; \ + if (ptr[3] & MPPE_C_BIT) \ + opts |= MPPE_OPT_MPPC; \ + \ + /* Other bits */ \ + if (ptr[0] & ~MPPE_H_BIT) \ + opts |= MPPE_OPT_UNKNOWN; \ + if (ptr[1] || ptr[2]) \ + opts |= MPPE_OPT_UNKNOWN; \ + if (ptr[3] & ~MPPE_ALL_BITS) \ + opts |= MPPE_OPT_UNKNOWN; \ + } while (/* CONSTCOND */ 0) diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c new file mode 100644 index 00000000..0cd30076 --- /dev/null +++ b/src/netif/ppp/multilink.c @@ -0,0 +1,595 @@ +/* + * multilink.c - support routines for multilink. + * + * Copyright (c) 2000-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pppd.h" +#include "fsm.h" +#include "lcp.h" +#include "tdb.h" + +bool endpoint_specified; /* user gave explicit endpoint discriminator */ +char *bundle_id; /* identifier for our bundle */ +char *blinks_id; /* key for the list of links */ +bool doing_multilink; /* multilink was enabled and agreed to */ +bool multilink_master; /* we own the multilink bundle */ + +extern TDB_CONTEXT *pppdb; +extern char db_key[]; + +static void make_bundle_links __P((int append)); +static void remove_bundle_link __P((void)); +static void iterate_bundle_links __P((void (*func) __P((char *)))); + +static int get_default_epdisc __P((struct epdisc *)); +static int parse_num __P((char *str, const char *key, int *valp)); +static int owns_unit __P((TDB_DATA pid, int unit)); + +#define set_ip_epdisc(ep, addr) do { \ + ep->length = 4; \ + ep->value[0] = addr >> 24; \ + ep->value[1] = addr >> 16; \ + ep->value[2] = addr >> 8; \ + ep->value[3] = addr; \ +} while (0) + +#define LOCAL_IP_ADDR(addr) \ + (((addr) & 0xff000000) == 0x0a000000 /* 10.x.x.x */ \ + || ((addr) & 0xfff00000) == 0xac100000 /* 172.16.x.x */ \ + || ((addr) & 0xffff0000) == 0xc0a80000) /* 192.168.x.x */ + +#define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH) + +void +mp_check_options() +{ + lcp_options *wo = &lcp_wantoptions[0]; + lcp_options *ao = &lcp_allowoptions[0]; + + doing_multilink = 0; + if (!multilink) + return; + /* if we're doing multilink, we have to negotiate MRRU */ + if (!wo->neg_mrru) { + /* mrru not specified, default to mru */ + wo->mrru = wo->mru; + wo->neg_mrru = 1; + } + ao->mrru = ao->mru; + ao->neg_mrru = 1; + + if (!wo->neg_endpoint && !noendpoint) { + /* get a default endpoint value */ + wo->neg_endpoint = get_default_epdisc(&wo->endpoint); + } +} + +/* + * Make a new bundle or join us to an existing bundle + * if we are doing multilink. + */ +int +mp_join_bundle() +{ + lcp_options *go = &lcp_gotoptions[0]; + lcp_options *ho = &lcp_hisoptions[0]; + lcp_options *ao = &lcp_allowoptions[0]; + int unit, pppd_pid; + int l, mtu; + char *p; + TDB_DATA key, pid, rec; + + if (doing_multilink) { + /* have previously joined a bundle */ + if (!go->neg_mrru || !ho->neg_mrru) { + notice("oops, didn't get multilink on renegotiation"); + lcp_close(0, "multilink required"); + return 0; + } + /* XXX should check the peer_authname and ho->endpoint + are the same as previously */ + return 0; + } + + if (!go->neg_mrru || !ho->neg_mrru) { + /* not doing multilink */ + if (go->neg_mrru) + notice("oops, multilink negotiated only for receive"); + mtu = ho->neg_mru? ho->mru: PPP_MRU; + if (mtu > ao->mru) + mtu = ao->mru; + if (demand) { + /* already have a bundle */ + cfg_bundle(0, 0, 0, 0); + netif_set_mtu(0, mtu); + return 0; + } + make_new_bundle(0, 0, 0, 0); + set_ifunit(1); + netif_set_mtu(0, mtu); + return 0; + } + + doing_multilink = 1; + + /* + * Find the appropriate bundle or join a new one. + * First we make up a name for the bundle. + * The length estimate is worst-case assuming every + * character has to be quoted. + */ + l = 4 * strlen(peer_authname) + 10; + if (ho->neg_endpoint) + l += 3 * ho->endpoint.length + 8; + if (bundle_name) + l += 3 * strlen(bundle_name) + 2; + bundle_id = malloc(l); + if (bundle_id == 0) + novm("bundle identifier"); + + p = bundle_id; + p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname); + if (ho->neg_endpoint || bundle_name) + *p++ = '/'; + if (ho->neg_endpoint) + p += slprintf(p, bundle_id+l-p, "%s", + epdisc_to_str(&ho->endpoint)); + if (bundle_name) + p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); + + /* Make the key for the list of links belonging to the bundle */ + l = p - bundle_id; + blinks_id = malloc(l + 7); + if (blinks_id == NULL) + novm("bundle links key"); + slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7); + + /* + * For demand mode, we only need to configure the bundle + * and attach the link. + */ + mtu = MIN(ho->mrru, ao->mru); + if (demand) { + cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); + netif_set_mtu(0, mtu); + script_setenv("BUNDLE", bundle_id + 7, 1); + return 0; + } + + /* + * Check if the bundle ID is already in the database. + */ + unit = -1; + lock_db(); + key.dptr = bundle_id; + key.dsize = p - bundle_id; + pid = tdb_fetch(pppdb, key); + if (pid.dptr != NULL) { + /* bundle ID exists, see if the pppd record exists */ + rec = tdb_fetch(pppdb, pid); + if (rec.dptr != NULL && rec.dsize > 0) { + /* make sure the string is null-terminated */ + rec.dptr[rec.dsize-1] = 0; + /* parse the interface number */ + parse_num(rec.dptr, "IFNAME=ppp", &unit); + /* check the pid value */ + if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) + || !process_exists(pppd_pid) + || !owns_unit(pid, unit)) + unit = -1; + free(rec.dptr); + } + free(pid.dptr); + } + + if (unit >= 0) { + /* attach to existing unit */ + if (bundle_attach(unit)) { + set_ifunit(0); + script_setenv("BUNDLE", bundle_id + 7, 0); + make_bundle_links(1); + unlock_db(); + info("Link attached to %s", ifname); + return 1; + } + /* attach failed because bundle doesn't exist */ + } + + /* we have to make a new bundle */ + make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); + set_ifunit(1); + netif_set_mtu(0, mtu); + script_setenv("BUNDLE", bundle_id + 7, 1); + make_bundle_links(0); + unlock_db(); + info("New bundle %s created", ifname); + multilink_master = 1; + return 0; +} + +void mp_exit_bundle() +{ + lock_db(); + remove_bundle_link(); + unlock_db(); +} + +static void sendhup(char *str) +{ + int pid; + + if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid()) { + if (debug) + dbglog("sending SIGHUP to process %d", pid); + kill(pid, SIGHUP); + } +} + +void mp_bundle_terminated() +{ + TDB_DATA key; + + bundle_terminating = 1; + upper_layers_down(0); + notice("Connection terminated."); + print_link_stats(); + if (!demand) { + remove_pidfiles(); + script_unsetenv("IFNAME"); + } + + lock_db(); + destroy_bundle(); + iterate_bundle_links(sendhup); + key.dptr = blinks_id; + key.dsize = strlen(blinks_id); + tdb_delete(pppdb, key); + unlock_db(); + + new_phase(PHASE_DEAD); + + doing_multilink = 0; + multilink_master = 0; +} + +static void make_bundle_links(int append) +{ + TDB_DATA key, rec; + char *p; + char entry[32]; + int l; + + key.dptr = blinks_id; + key.dsize = strlen(blinks_id); + slprintf(entry, sizeof(entry), "%s;", db_key); + p = entry; + if (append) { + rec = tdb_fetch(pppdb, key); + if (rec.dptr != NULL && rec.dsize > 0) { + rec.dptr[rec.dsize-1] = 0; + if (strstr(rec.dptr, db_key) != NULL) { + /* already in there? strange */ + warn("link entry already exists in tdb"); + return; + } + l = rec.dsize + strlen(entry); + p = malloc(l); + if (p == NULL) + novm("bundle link list"); + slprintf(p, l, "%s%s", rec.dptr, entry); + } else { + warn("bundle link list not found"); + } + if (rec.dptr != NULL) + free(rec.dptr); + } + rec.dptr = p; + rec.dsize = strlen(p) + 1; + if (tdb_store(pppdb, key, rec, TDB_REPLACE)) + error("couldn't %s bundle link list", + append? "update": "create"); + if (p != entry) + free(p); +} + +static void remove_bundle_link() +{ + TDB_DATA key, rec; + char entry[32]; + char *p, *q; + int l; + + key.dptr = blinks_id; + key.dsize = strlen(blinks_id); + slprintf(entry, sizeof(entry), "%s;", db_key); + + rec = tdb_fetch(pppdb, key); + if (rec.dptr == NULL || rec.dsize <= 0) { + if (rec.dptr != NULL) + free(rec.dptr); + return; + } + rec.dptr[rec.dsize-1] = 0; + p = strstr(rec.dptr, entry); + if (p != NULL) { + q = p + strlen(entry); + l = strlen(q) + 1; + memmove(p, q, l); + rec.dsize = p - rec.dptr + l; + if (tdb_store(pppdb, key, rec, TDB_REPLACE)) + error("couldn't update bundle link list (removal)"); + } + free(rec.dptr); +} + +static void iterate_bundle_links(void (*func)(char *)) +{ + TDB_DATA key, rec, pp; + char *p, *q; + + key.dptr = blinks_id; + key.dsize = strlen(blinks_id); + rec = tdb_fetch(pppdb, key); + if (rec.dptr == NULL || rec.dsize <= 0) { + error("bundle link list not found (iterating list)"); + if (rec.dptr != NULL) + free(rec.dptr); + return; + } + p = rec.dptr; + p[rec.dsize-1] = 0; + while ((q = strchr(p, ';')) != NULL) { + *q = 0; + key.dptr = p; + key.dsize = q - p; + pp = tdb_fetch(pppdb, key); + if (pp.dptr != NULL && pp.dsize > 0) { + pp.dptr[pp.dsize-1] = 0; + func(pp.dptr); + } + if (pp.dptr != NULL) + free(pp.dptr); + p = q + 1; + } + free(rec.dptr); +} + +static int +parse_num(str, key, valp) + char *str; + const char *key; + int *valp; +{ + char *p, *endp; + int i; + + p = strstr(str, key); + if (p != 0) { + p += strlen(key); + i = strtol(p, &endp, 10); + if (endp != p && (*endp == 0 || *endp == ';')) { + *valp = i; + return 1; + } + } + return 0; +} + +/* + * Check whether the pppd identified by `key' still owns ppp unit `unit'. + */ +static int +owns_unit(key, unit) + TDB_DATA key; + int unit; +{ + char ifkey[32]; + TDB_DATA kd, vd; + int ret = 0; + + slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit); + kd.dptr = ifkey; + kd.dsize = strlen(ifkey); + vd = tdb_fetch(pppdb, kd); + if (vd.dptr != NULL) { + ret = vd.dsize == key.dsize + && memcmp(vd.dptr, key.dptr, vd.dsize) == 0; + free(vd.dptr); + } + return ret; +} + +static int +get_default_epdisc(ep) + struct epdisc *ep; +{ + char *p; + struct hostent *hp; + u_int32_t addr; + + /* First try for an ethernet MAC address */ + p = get_first_ethernet(); + if (p != 0 && get_if_hwaddr(ep->value, p) >= 0) { + ep->class = EPD_MAC; + ep->length = 6; + return 1; + } + + /* see if our hostname corresponds to a reasonable IP address */ + hp = gethostbyname(hostname); + if (hp != NULL) { + addr = *(u_int32_t *)hp->h_addr; + if (!bad_ip_adrs(addr)) { + addr = ntohl(addr); + if (!LOCAL_IP_ADDR(addr)) { + ep->class = EPD_IP; + set_ip_epdisc(ep, addr); + return 1; + } + } + } + + return 0; +} + +/* + * epdisc_to_str - make a printable string from an endpoint discriminator. + */ + +static char *endp_class_names[] = { + "null", "local", "IP", "MAC", "magic", "phone" +}; + +char * +epdisc_to_str(ep) + struct epdisc *ep; +{ + static char str[MAX_ENDP_LEN*3+8]; + u_char *p = ep->value; + int i, mask = 0; + char *q, c, c2; + + if (ep->class == EPD_NULL && ep->length == 0) + return "null"; + if (ep->class == EPD_IP && ep->length == 4) { + u_int32_t addr; + + GETLONG(addr, p); + slprintf(str, sizeof(str), "IP:%I", htonl(addr)); + return str; + } + + c = ':'; + c2 = '.'; + if (ep->class == EPD_MAC && ep->length == 6) + c2 = ':'; + else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0) + mask = 3; + q = str; + if (ep->class <= EPD_PHONENUM) + q += slprintf(q, sizeof(str)-1, "%s", + endp_class_names[ep->class]); + else + q += slprintf(q, sizeof(str)-1, "%d", ep->class); + c = ':'; + for (i = 0; i < ep->length && i < MAX_ENDP_LEN; ++i) { + if ((i & mask) == 0) { + *q++ = c; + c = c2; + } + q += slprintf(q, str + sizeof(str) - q, "%.2x", ep->value[i]); + } + return str; +} + +static int hexc_val(int c) +{ + if (c >= 'a') + return c - 'a' + 10; + if (c >= 'A') + return c - 'A' + 10; + return c - '0'; +} + +int +str_to_epdisc(ep, str) + struct epdisc *ep; + char *str; +{ + int i, l; + char *p, *endp; + + for (i = EPD_NULL; i <= EPD_PHONENUM; ++i) { + int sl = strlen(endp_class_names[i]); + if (strncasecmp(str, endp_class_names[i], sl) == 0) { + str += sl; + break; + } + } + if (i > EPD_PHONENUM) { + /* not a class name, try a decimal class number */ + i = strtol(str, &endp, 10); + if (endp == str) + return 0; /* can't parse class number */ + str = endp; + } + ep->class = i; + if (*str == 0) { + ep->length = 0; + return 1; + } + if (*str != ':' && *str != '.') + return 0; + ++str; + + if (i == EPD_IP) { + u_int32_t addr; + i = parse_dotted_ip(str, &addr); + if (i == 0 || str[i] != 0) + return 0; + set_ip_epdisc(ep, addr); + return 1; + } + if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) { + ep->length = 6; + return 1; + } + + p = str; + for (l = 0; l < MAX_ENDP_LEN; ++l) { + if (*str == 0) + break; + if (p <= str) + for (p = str; isxdigit(*p); ++p) + ; + i = p - str; + if (i == 0) + return 0; + ep->value[l] = hexc_val(*str++); + if ((i & 1) == 0) + ep->value[l] = (ep->value[l] << 4) + hexc_val(*str++); + if (*str == ':' || *str == '.') + ++str; + } + if (*str != 0 || (ep->class == EPD_MAC && l != 6)) + return 0; + ep->length = l; + return 1; +} + diff --git a/src/netif/ppp/net/if_ppp.h b/src/netif/ppp/net/if_ppp.h new file mode 100644 index 00000000..bfec6064 --- /dev/null +++ b/src/netif/ppp/net/if_ppp.h @@ -0,0 +1,156 @@ +/* $Id: if_ppp.h,v 1.19 2002/12/06 09:49:15 paulus Exp $ */ + +/* + * if_ppp.h - Point-to-Point Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _IF_PPP_H_ +#define _IF_PPP_H_ + +/* + * Bit definitions for flags. + */ +#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */ +#define SC_COMP_AC 0x00000002 /* header compression (output) */ +#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */ +#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */ +#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */ +#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */ +#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */ +#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */ +#define SC_DEBUG 0x00010000 /* enable debug messages */ +#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */ +#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ +#define SC_LOG_RAWIN 0x00080000 /* log all chars received */ +#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ +#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ +#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */ +#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ +#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ +#define SC_SYNC 0x00200000 /* use synchronous HDLC framing */ +#define SC_MASK 0x0fff00ff /* bits that user can change */ + +/* + * State bits in sc_flags, not changeable by user. + */ +#define SC_TIMEOUT 0x00000400 /* timeout is currently pending */ +#define SC_VJ_RESET 0x00000800 /* need to reset VJ decomp */ +#define SC_COMP_RUN 0x00001000 /* compressor has been inited */ +#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */ +#define SC_DC_ERROR 0x00004000 /* non-fatal decomp error detected */ +#define SC_DC_FERROR 0x00008000 /* fatal decomp error detected */ +#define SC_TBUSY 0x10000000 /* xmitter doesn't need a packet yet */ +#define SC_PKTLOST 0x20000000 /* have lost or dropped a packet */ +#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */ +#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */ + +/* + * Ioctl definitions. + */ + +struct npioctl { + int protocol; /* PPP procotol, e.g. PPP_IP */ + enum NPmode mode; +}; + +/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ +struct ppp_option_data { + u_char *ptr; + u_int length; + int transmit; +}; + +struct ifpppstatsreq { + char ifr_name[IFNAMSIZ]; + struct ppp_stats stats; +}; + +struct ifpppcstatsreq { + char ifr_name[IFNAMSIZ]; + struct ppp_comp_stats stats; +}; + +/* + * Ioctl definitions. + */ + +#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */ +#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */ +#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */ +#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */ +#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */ +#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */ +#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */ +#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */ +#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */ +#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */ +#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */ +#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */ +#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */ +#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data) +#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */ +#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */ +#define PPPIOCGIDLE _IOR('t', 74, struct ppp_idle) /* get idle time */ +#ifdef PPP_FILTER +#define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */ +#define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */ +#endif /* PPP_FILTER */ + +/* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */ +#define PPPIOCGMTU _IOR('t', 73, int) /* get interface MTU */ +#define PPPIOCSMTU _IOW('t', 72, int) /* set interface MTU */ + +/* + * These two are interface ioctls so that pppstats can do them on + * a socket without having to open the serial device. + */ +#define SIOCGPPPSTATS _IOWR('i', 123, struct ifpppstatsreq) +#define SIOCGPPPCSTATS _IOWR('i', 122, struct ifpppcstatsreq) + +#if !defined(ifr_mtu) +#define ifr_mtu ifr_ifru.ifru_metric +#endif + +#if (defined(_KERNEL) || defined(KERNEL)) && !defined(NeXT) +void pppattach __P((void)); +void pppintr __P((void)); +#endif +#endif /* _IF_PPP_H_ */ diff --git a/src/netif/ppp/net/ppp-comp.h b/src/netif/ppp/net/ppp-comp.h new file mode 100644 index 00000000..088c73e9 --- /dev/null +++ b/src/netif/ppp/net/ppp-comp.h @@ -0,0 +1,179 @@ +/* + * ppp-comp.h - Definitions for doing PPP packet compression. + * + * Copyright (c) 1984 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ppp-comp.h,v 1.13 2002/12/06 09:49:15 paulus Exp $ + */ + +#ifndef _NET_PPP_COMP_H +#define _NET_PPP_COMP_H + +/* + * The following symbols control whether we include code for + * various compression methods. + */ +#ifndef DO_BSD_COMPRESS +#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ +#endif +#ifndef DO_DEFLATE +#define DO_DEFLATE 1 /* by default, include Deflate */ +#endif +#define DO_PREDICTOR_1 0 +#define DO_PREDICTOR_2 0 + +/* + * Structure giving methods for compression/decompression. + */ +#ifdef PACKETPTR +struct compressor { + int compress_proto; /* CCP compression protocol number */ + + /* Allocate space for a compressor (transmit side) */ + void *(*comp_alloc) __P((u_char *options, int opt_len)); + /* Free space used by a compressor */ + void (*comp_free) __P((void *state)); + /* Initialize a compressor */ + int (*comp_init) __P((void *state, u_char *options, int opt_len, + int unit, int hdrlen, int debug)); + /* Reset a compressor */ + void (*comp_reset) __P((void *state)); + /* Compress a packet */ + int (*compress) __P((void *state, PACKETPTR *mret, + PACKETPTR mp, int orig_len, int max_len)); + /* Return compression statistics */ + void (*comp_stat) __P((void *state, struct compstat *stats)); + + /* Allocate space for a decompressor (receive side) */ + void *(*decomp_alloc) __P((u_char *options, int opt_len)); + /* Free space used by a decompressor */ + void (*decomp_free) __P((void *state)); + /* Initialize a decompressor */ + int (*decomp_init) __P((void *state, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug)); + /* Reset a decompressor */ + void (*decomp_reset) __P((void *state)); + /* Decompress a packet. */ + int (*decompress) __P((void *state, PACKETPTR mp, + PACKETPTR *dmpp)); + /* Update state for an incompressible packet received */ + void (*incomp) __P((void *state, PACKETPTR mp)); + /* Return decompression statistics */ + void (*decomp_stat) __P((void *state, struct compstat *stats)); +}; +#endif /* PACKETPTR */ + +/* + * Return values for decompress routine. + * We need to make these distinctions so that we can disable certain + * useful functionality, namely sending a CCP reset-request as a result + * of an error detected after decompression. This is to avoid infringing + * a patent held by Motorola. + * Don't you just lurve software patents. + */ +#define DECOMP_OK 0 /* everything went OK */ +#define DECOMP_ERROR 1 /* error detected before decomp. */ +#define DECOMP_FATALERROR 2 /* error detected after decomp. */ + +/* + * CCP codes. + */ +#define CCP_CONFREQ 1 +#define CCP_CONFACK 2 +#define CCP_TERMREQ 5 +#define CCP_TERMACK 6 +#define CCP_RESETREQ 14 +#define CCP_RESETACK 15 + +/* + * Max # bytes for a CCP option + */ +#define CCP_MAX_OPTION_LENGTH 32 + +/* + * Parts of a CCP packet. + */ +#define CCP_CODE(dp) ((dp)[0]) +#define CCP_ID(dp) ((dp)[1]) +#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) +#define CCP_HDRLEN 4 + +#define CCP_OPT_CODE(dp) ((dp)[0]) +#define CCP_OPT_LENGTH(dp) ((dp)[1]) +#define CCP_OPT_MINLEN 2 + +/* + * Definitions for BSD-Compress. + */ +#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ +#define CILEN_BSD_COMPRESS 3 /* length of config. option */ + +/* Macros for handling the 3rd byte of the BSD-Compress config option. */ +#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ +#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ +#define BSD_CURRENT_VERSION 1 /* current version number */ +#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) + +#define BSD_MIN_BITS 9 /* smallest code size supported */ +#define BSD_MAX_BITS 15 /* largest code size supported */ + +/* + * Definitions for Deflate. + */ +#define CI_DEFLATE 26 /* config option for Deflate */ +#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ +#define CILEN_DEFLATE 4 /* length of its config option */ + +#define DEFLATE_MIN_SIZE 8 +#define DEFLATE_MAX_SIZE 15 +#define DEFLATE_METHOD_VAL 8 +#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) +#define DEFLATE_METHOD(x) ((x) & 0x0F) +#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ + + DEFLATE_METHOD_VAL) +#define DEFLATE_CHK_SEQUENCE 0 + +/* + * Definitions for MPPE. + */ +#define CI_MPPE 18 /* config option for MPPE */ +#define CILEN_MPPE 6 /* length of config option */ + +/* + * Definitions for other, as yet unsupported, compression methods. + */ +#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ +#define CILEN_PREDICTOR_1 2 /* length of its config option */ +#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ +#define CILEN_PREDICTOR_2 2 /* length of its config option */ + +#endif /* _NET_PPP_COMP_H */ diff --git a/src/netif/ppp/net/ppp_defs.h b/src/netif/ppp/net/ppp_defs.h new file mode 100644 index 00000000..2baf70a6 --- /dev/null +++ b/src/netif/ppp/net/ppp_defs.h @@ -0,0 +1,197 @@ +/* $Id: ppp_defs.h,v 1.17 2002/12/06 09:49:15 paulus Exp $ */ + +/* + * ppp_defs.h - PPP definitions. + * + * Copyright (c) 1984 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PPP_DEFS_H_ +#define _PPP_DEFS_H_ + +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#if 0 /* defined in opt.h */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 65000 /* Largest MRU we allow */ +#define PPP_MINMRU 128 +#endif + +#define PPP_ADDRESS(p) (((u_char *)(p))[0]) +#define PPP_CONTROL(p) (((u_char *)(p))[1]) +#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) + + +/* + * Significant octet values. + */ +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_FLAG 0x7e /* Flag Sequence */ +#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ +#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* + * Protocol field values. + */ +#define PPP_IP 0x21 /* Internet Protocol */ +#define PPP_AT 0x29 /* AppleTalk Protocol */ +#define PPP_IPX 0x2b /* IPX protocol */ +#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ +#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ +#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ +#define PPP_COMP 0xfd /* compressed packet */ +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ +#define PPP_IPXCP 0x802b /* IPX Control Protocol */ +#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#define PPP_CCP 0x80fd /* Compression Control Protocol */ +#define PPP_ECP 0x8053 /* Encryption Control Protocol */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ +#define PPP_CBCP 0xc029 /* Callback Control Protocol */ +#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ + +/* + * Values for FCS calculations. + */ +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +/* + * A 32-bit unsigned integral type. + */ + +#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \ + && !defined(__FreeBSD__) && (NS_TARGET < 40) +#ifdef UINT32_T +typedef UINT32_T u_int32_t; +#else +typedef unsigned int u_int32_t; +typedef unsigned short u_int16_t; +#endif +#endif + +/* + * Extended asyncmap - allows any character to be escaped. + */ +typedef u_int32_t ext_accm[8]; + +/* + * What to do with network protocol (NP) packets. + */ +enum NPmode { + NPMODE_PASS, /* pass the packet through */ + NPMODE_DROP, /* silently drop the packet */ + NPMODE_ERROR, /* return an error */ + NPMODE_QUEUE /* save it up for later. */ +}; + +/* + * Statistics. + */ +struct pppstat { + unsigned int ppp_ibytes; /* bytes received */ + unsigned int ppp_ipackets; /* packets received */ + unsigned int ppp_ierrors; /* receive errors */ + unsigned int ppp_obytes; /* bytes sent */ + unsigned int ppp_opackets; /* packets sent */ + unsigned int ppp_oerrors; /* transmit errors */ +}; + +struct vjstat { + unsigned int vjs_packets; /* outbound packets */ + unsigned int vjs_compressed; /* outbound compressed packets */ + unsigned int vjs_searches; /* searches for connection state */ + unsigned int vjs_misses; /* times couldn't find conn. state */ + unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ + unsigned int vjs_compressedin; /* inbound compressed packets */ + unsigned int vjs_errorin; /* inbound unknown type packets */ + unsigned int vjs_tossed; /* inbound packets tossed because of error */ +}; + +struct ppp_stats { + struct pppstat p; /* basic PPP statistics */ + struct vjstat vj; /* VJ header compression statistics */ +}; + +struct compstat { + unsigned int unc_bytes; /* total uncompressed bytes */ + unsigned int unc_packets; /* total uncompressed packets */ + unsigned int comp_bytes; /* compressed bytes */ + unsigned int comp_packets; /* compressed packets */ + unsigned int inc_bytes; /* incompressible bytes */ + unsigned int inc_packets; /* incompressible packets */ + unsigned int ratio; /* recent compression ratio << 8 */ +}; + +struct ppp_comp_stats { + struct compstat c; /* packet compression statistics */ + struct compstat d; /* packet decompression statistics */ +}; + +/* + * The following structure records the time in seconds since + * the last NP packet was sent or received. + */ +struct ppp_idle { + time_t xmit_idle; /* time since last NP packet sent */ + time_t recv_idle; /* time since last NP packet received */ +}; + +#ifndef __P +#ifdef __STDC__ +#define __P(x) x +#else +#define __P(x) () +#endif +#endif + +#endif /* _PPP_DEFS_H_ */ diff --git a/src/netif/ppp/net/pppio.h b/src/netif/ppp/net/pppio.h new file mode 100644 index 00000000..54cfe445 --- /dev/null +++ b/src/netif/ppp/net/pppio.h @@ -0,0 +1,107 @@ +/* + * pppio.h - ioctl and other misc. definitions for STREAMS modules. + * + * Copyright (c) 1994 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: pppio.h,v 1.9 2002/12/06 09:49:15 paulus Exp $ + */ + +#define _PPPIO(n) (('p' << 8) + (n)) + +#define PPPIO_NEWPPA _PPPIO(130) /* allocate a new PPP unit */ +#define PPPIO_GETSTAT _PPPIO(131) /* get PPP statistics */ +#define PPPIO_GETCSTAT _PPPIO(132) /* get PPP compression stats */ +#define PPPIO_MTU _PPPIO(133) /* set max transmission unit */ +#define PPPIO_MRU _PPPIO(134) /* set max receive unit */ +#define PPPIO_CFLAGS _PPPIO(135) /* set/clear/get compression flags */ +#define PPPIO_XCOMP _PPPIO(136) /* alloc transmit compressor */ +#define PPPIO_RCOMP _PPPIO(137) /* alloc receive decompressor */ +#define PPPIO_XACCM _PPPIO(138) /* set transmit asyncmap */ +#define PPPIO_RACCM _PPPIO(139) /* set receive asyncmap */ +#define PPPIO_VJINIT _PPPIO(140) /* initialize VJ comp/decomp */ +#define PPPIO_ATTACH _PPPIO(141) /* attach to a ppa (without putmsg) */ +#define PPPIO_LASTMOD _PPPIO(142) /* mark last ppp module */ +#define PPPIO_GCLEAN _PPPIO(143) /* get 8-bit-clean flags */ +#define PPPIO_DEBUG _PPPIO(144) /* request debug information */ +#define PPPIO_BIND _PPPIO(145) /* bind to SAP */ +#define PPPIO_NPMODE _PPPIO(146) /* set mode for handling data pkts */ +#define PPPIO_GIDLE _PPPIO(147) /* get time since last data pkt */ +#define PPPIO_PASSFILT _PPPIO(148) /* set filter for packets to pass */ +#define PPPIO_ACTIVEFILT _PPPIO(149) /* set filter for "link active" pkts */ + +/* + * Values for PPPIO_CFLAGS + */ +#define COMP_AC 0x1 /* compress address/control */ +#define DECOMP_AC 0x2 /* decompress address/control */ +#define COMP_PROT 0x4 /* compress PPP protocol */ +#define DECOMP_PROT 0x8 /* decompress PPP protocol */ + +#define COMP_VJC 0x10 /* compress TCP/IP headers */ +#define COMP_VJCCID 0x20 /* compress connection ID as well */ +#define DECOMP_VJC 0x40 /* decompress TCP/IP headers */ +#define DECOMP_VJCCID 0x80 /* accept compressed connection ID */ + +#define CCP_ISOPEN 0x100 /* look at CCP packets */ +#define CCP_ISUP 0x200 /* do packet comp/decomp */ +#define CCP_ERROR 0x400 /* (status) error in packet decomp */ +#define CCP_FATALERROR 0x800 /* (status) fatal error ditto */ +#define CCP_COMP_RUN 0x1000 /* (status) seen CCP ack sent */ +#define CCP_DECOMP_RUN 0x2000 /* (status) seen CCP ack rcvd */ + +/* + * Values for 8-bit-clean flags. + */ +#define RCV_B7_0 1 /* have rcvd char with bit 7 = 0 */ +#define RCV_B7_1 2 /* have rcvd char with bit 7 = 1 */ +#define RCV_EVNP 4 /* have rcvd char with even parity */ +#define RCV_ODDP 8 /* have rcvd char with odd parity */ + +/* + * Values for the first byte of M_CTL messages passed between + * PPP modules. + */ +#define PPPCTL_OERROR 0xe0 /* output error [up] */ +#define PPPCTL_IERROR 0xe1 /* input error (e.g. FCS) [up] */ +#define PPPCTL_MTU 0xe2 /* set MTU [down] */ +#define PPPCTL_MRU 0xe3 /* set MRU [down] */ +#define PPPCTL_UNIT 0xe4 /* note PPP unit number [down] */ + +/* + * Values for the integer argument to PPPIO_DEBUG. + */ +#define PPPDBG_DUMP 0x10000 /* print out debug info now */ +#define PPPDBG_LOG 0x100 /* log various things */ +#define PPPDBG_DRIVER 0 /* identifies ppp driver as target */ +#define PPPDBG_IF 1 /* identifies ppp network i/f target */ +#define PPPDBG_COMP 2 /* identifies ppp compression target */ +#define PPPDBG_AHDLC 3 /* identifies ppp async hdlc target */ diff --git a/src/netif/ppp/net/slcompress.h b/src/netif/ppp/net/slcompress.h new file mode 100644 index 00000000..d887dfc2 --- /dev/null +++ b/src/netif/ppp/net/slcompress.h @@ -0,0 +1,148 @@ +/* + * Definitions for tcp compression routines. + * + * $Id: slcompress.h,v 1.4 1994/09/21 06:50:08 paulus Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * 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 University of California, Berkeley. 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. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + */ + +#ifndef _SLCOMPRESS_H_ +#define _SLCOMPRESS_H_ + +#define MAX_STATES 16 /* must be > 2 and < 256 */ +#define MAX_HDR MLEN /* XXX 4bsd-ism: should really be 128 */ + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowlegement, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + +/* packet types */ +#define TYPE_IP 0x40 +#define TYPE_UNCOMPRESSED_TCP 0x70 +#define TYPE_COMPRESSED_TCP 0x80 +#define TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + struct cstate *cs_next; /* next most recently used cstate (xmit only) */ + u_short cs_hlen; /* size of hdr (receive only) */ + u_char cs_id; /* connection # associated with this state */ + u_char cs_filler; + union { + char csu_hdr[MAX_HDR]; + struct ip csu_ip; /* ip/tcp hdr from most recent packet */ + } slcs_u; +}; +#define cs_ip slcs_u.csu_ip +#define cs_hdr slcs_u.csu_hdr + +/* + * all the state data for one serial line (we need one of these + * per line). + */ +struct slcompress { + struct cstate *last_cs; /* most recently used tstate */ + u_char last_recv; /* last rcvd conn. id */ + u_char last_xmit; /* last sent conn. id */ + u_short flags; +#ifndef SL_NO_STATS + int sls_packets; /* outbound packets */ + int sls_compressed; /* outbound compressed packets */ + int sls_searches; /* searches for connection state */ + int sls_misses; /* times couldn't find conn. state */ + int sls_uncompressedin; /* inbound uncompressed packets */ + int sls_compressedin; /* inbound compressed packets */ + int sls_errorin; /* inbound unknown type packets */ + int sls_tossed; /* inbound packets tossed because of error */ +#endif + struct cstate tstate[MAX_STATES]; /* xmit connection states */ + struct cstate rstate[MAX_STATES]; /* receive connection states */ +}; +/* flag values */ +#define SLF_TOSS 1 /* tossing rcvd frames because of input err */ + +void sl_compress_init __P((struct slcompress *)); +void sl_compress_setup __P((struct slcompress *, int)); +u_int sl_compress_tcp __P((struct mbuf *, + struct ip *, struct slcompress *, int)); +int sl_uncompress_tcp __P((u_char **, int, u_int, struct slcompress *)); +int sl_uncompress_tcp_core __P((u_char *, int, int, u_int, + struct slcompress *, u_char **, u_int *)); + +#endif /* _SLCOMPRESS_H_ */ diff --git a/src/netif/ppp/vj.h b/src/netif/ppp/net/vjcompress.h similarity index 59% rename from src/netif/ppp/vj.h rename to src/netif/ppp/net/vjcompress.h index fad12136..03a33bf7 100644 --- a/src/netif/ppp/vj.h +++ b/src/netif/ppp/net/vjcompress.h @@ -1,7 +1,7 @@ /* * Definitions for tcp compression routines. * - * $Id: vj.h,v 1.7 2010/02/22 17:52:09 goldsimon Exp $ + * $Id: vjcompress.h,v 1.3 1996/05/28 00:55:33 paulus Exp $ * * Copyright (c) 1989 Regents of the University of California. * All rights reserved. @@ -18,18 +18,15 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. */ -#ifndef VJ_H -#define VJ_H +#ifndef _VJCOMPRESS_H_ +#define _VJCOMPRESS_H_ -#include "lwip/ip.h" -#include "lwip/tcp_impl.h" - -#define MAX_SLOTS 16 /* must be > 2 and < 256 */ -#define MAX_HDR 128 +#define MAX_STATES 16 /* must be > 2 and < 256 */ +#define MAX_HDR 128 /* * Compressed packet format: @@ -75,22 +72,22 @@ */ /* packet types */ -#define TYPE_IP 0x40 +#define TYPE_IP 0x40 #define TYPE_UNCOMPRESSED_TCP 0x70 -#define TYPE_COMPRESSED_TCP 0x80 -#define TYPE_ERROR 0x00 +#define TYPE_COMPRESSED_TCP 0x80 +#define TYPE_ERROR 0x00 /* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 /* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ #define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) #define TCP_PUSH_BIT 0x10 @@ -103,54 +100,45 @@ * the transmit & receive ends of the line use to locate saved header. */ struct cstate { - struct cstate *cs_next; /* next most recently used state (xmit only) */ - u_short cs_hlen; /* size of hdr (receive only) */ - u_char cs_id; /* connection # associated with this state */ - u_char cs_filler; - union { - char csu_hdr[MAX_HDR]; - struct ip_hdr csu_ip; /* ip/tcp hdr from most recent packet */ - } vjcs_u; + struct cstate *cs_next; /* next most recently used state (xmit only) */ + u_short cs_hlen; /* size of hdr (receive only) */ + u_char cs_id; /* connection # associated with this state */ + u_char cs_filler; + union { + char csu_hdr[MAX_HDR]; + struct ip csu_ip; /* ip/tcp hdr from most recent packet */ + } vjcs_u; }; #define cs_ip vjcs_u.csu_ip #define cs_hdr vjcs_u.csu_hdr - -struct vjstat { - unsigned long vjs_packets; /* outbound packets */ - unsigned long vjs_compressed; /* outbound compressed packets */ - unsigned long vjs_searches; /* searches for connection state */ - unsigned long vjs_misses; /* times couldn't find conn. state */ - unsigned long vjs_uncompressedin; /* inbound uncompressed packets */ - unsigned long vjs_compressedin; /* inbound compressed packets */ - unsigned long vjs_errorin; /* inbound unknown type packets */ - unsigned long vjs_tossed; /* inbound packets tossed because of error */ -}; - /* * all the state data for one serial line (we need one of these per line). */ struct vjcompress { - struct cstate *last_cs; /* most recently used tstate */ - u_char last_recv; /* last rcvd conn. id */ - u_char last_xmit; /* last sent conn. id */ - u_short flags; - u_char maxSlotIndex; - u_char compressSlot; /* Flag indicating OK to compress slot ID. */ -#if LINK_STATS - struct vjstat stats; + struct cstate *last_cs; /* most recently used tstate */ + u_char last_recv; /* last rcvd conn. id */ + u_char last_xmit; /* last sent conn. id */ + u_short flags; +#ifndef VJ_NO_STATS + struct vjstat stats; #endif - struct cstate tstate[MAX_SLOTS]; /* xmit connection states */ - struct cstate rstate[MAX_SLOTS]; /* receive connection states */ + struct cstate tstate[MAX_STATES]; /* xmit connection states */ + struct cstate rstate[MAX_STATES]; /* receive connection states */ }; /* flag values */ -#define VJF_TOSS 1U /* tossing rcvd frames because of input err */ +#define VJF_TOSS 1 /* tossing rcvd frames because of input err */ -extern void vj_compress_init (struct vjcompress *comp); -extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb); -extern void vj_uncompress_err (struct vjcompress *comp); -extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp); -extern int vj_uncompress_tcp (struct pbuf **nb, struct vjcompress *comp); +extern void vj_compress_init __P((struct vjcompress *comp, int max_state)); +extern u_int vj_compress_tcp __P((struct ip *ip, u_int mlen, + struct vjcompress *comp, int compress_cid_flag, + u_char **vjhdrp)); +extern void vj_uncompress_err __P((struct vjcompress *comp)); +extern int vj_uncompress_uncomp __P((u_char *buf, int buflen, + struct vjcompress *comp)); +extern int vj_uncompress_tcp __P((u_char *buf, int buflen, int total_len, + struct vjcompress *comp, u_char **hdrp, + u_int *hlenp)); -#endif /* VJ_H */ +#endif /* _VJCOMPRESS_H_ */ diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c new file mode 100644 index 00000000..65da3e36 --- /dev/null +++ b/src/netif/ppp/options.c @@ -0,0 +1,1627 @@ +/* + * options.c - handles option processing for PPP. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: options.c,v 1.102 2008/06/15 06:53:06 paulus Exp $" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef PLUGIN +#include +#endif + +#ifdef PPP_FILTER +#include +/* + * There have been 3 or 4 different names for this in libpcap CVS, but + * this seems to be what they have settled on... + * For older versions of libpcap, use DLT_PPP - but that means + * we lose the inbound and outbound qualifiers. + */ +#ifndef DLT_PPP_PPPD +#ifdef DLT_PPP_WITHDIRECTION +#define DLT_PPP_PPPD DLT_PPP_WITHDIRECTION +#else +#define DLT_PPP_PPPD DLT_PPP +#endif +#endif +#endif /* PPP_FILTER */ + +#include "pppd.h" +#include "pathnames.h" + +#if defined(ultrix) || defined(NeXT) +char *strdup __P((char *)); +#endif + +static const char rcsid[] = RCSID; + +struct option_value { + struct option_value *next; + const char *source; + char value[1]; +}; + +/* + * Option variables and default values. + */ +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 */ +bool nodetach = 0; /* Don't detach from controlling tty */ +bool updetach = 0; /* Detach once link is up */ +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 */ +int log_to_fd = 1; /* send log messages to this fd too */ +bool log_default = 1; /* log_to_fd is default (stdout) */ +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 */ +int req_unit = -1; /* requested interface unit */ +bool multilink = 0; /* Enable multilink operation */ +char *bundle_name = NULL; /* bundle name for multilink */ +bool dump_options; /* print out option values */ +bool dryrun; /* print out option values and exit */ +char *domain; /* domain name set by domain option */ +int child_wait = 5; /* # seconds to wait for children at exit */ + +#ifdef MAXOCTETS +unsigned int maxoctets = 0; /* default - no limit */ +int maxoctets_dir = 0; /* default - sum of traffic */ +int maxoctets_timeout = 1; /* default 1 second */ +#endif + + +extern option_t auth_options[]; +extern struct stat devstat; + +#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 */ +#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 */ +int option_priority = OPRIO_CFGFILE; /* priority of the current options */ +bool devnam_fixed; /* can no longer change device name */ + +static int logfile_fd = -1; /* fd opened for log file */ +static char logfile_name[MAXPATHLEN]; /* name of log file */ + +/* + * Prototypes + */ +static int setdomain __P((char **)); +static int readfile __P((char **)); +static int callfile __P((char **)); +static int showversion __P((char **)); +static int showhelp __P((char **)); +static void usage __P((void)); +static int setlogfile __P((char **)); +#ifdef PLUGIN +static int loadplugin __P((char **)); +#endif + +#ifdef PPP_FILTER +static int setpassfilter __P((char **)); +static int setactivefilter __P((char **)); +#endif + +#ifdef MAXOCTETS +static int setmodir __P((char **)); +#endif + +static option_t *find_option __P((const char *name)); +static int process_option __P((option_t *, char *, char **)); +static int n_arguments __P((option_t *)); +static int number_option __P((char *, u_int32_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 }, + { "-d", o_int, &debug, + "Increase debugging level", + OPT_ALIAS | OPT_INC | OPT_NOARG | 1 }, + + { "kdebug", o_int, &kdebugflag, + "Set kernel driver debug level", OPT_PRIO }, + + { "nodetach", o_bool, &nodetach, + "Don't detach from controlling tty", OPT_PRIO | 1 }, + { "-detach", o_bool, &nodetach, + "Don't detach from controlling tty", OPT_ALIAS | OPT_PRIOSUB | 1 }, + { "updetach", o_bool, &updetach, + "Detach from controlling tty once link is up", + OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach }, + + { "holdoff", o_int, &holdoff, + "Set time in seconds before retrying connection", + OPT_PRIO, &holdoff_specified }, + + { "idle", o_int, &idle_time_limit, + "Set time in seconds before disconnecting idle link", OPT_PRIO }, + + { "maxconnect", o_int, &maxconnect, + "Set connection time limit", + OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, + + { "domain", o_special, (void *)setdomain, + "Add given domain name to hostname", + OPT_PRIO | OPT_PRIV | OPT_A2STRVAL, &domain }, + + { "file", o_special, (void *)readfile, + "Take options from a file", OPT_NOPRINT }, + { "call", o_special, (void *)callfile, + "Take options from a privileged file", OPT_NOPRINT }, + + { "persist", o_bool, &persist, + "Keep on reopening connection after close", OPT_PRIO | 1 }, + { "nopersist", o_bool, &persist, + "Turn off persist option", OPT_PRIOSUB }, + + { "demand", o_bool, &demand, + "Dial on demand", OPT_INITONLY | 1, &persist }, + + { "--version", o_special_noarg, (void *)showversion, + "Show version number" }, + { "--help", o_special_noarg, (void *)showhelp, + "Show brief listing of options" }, + { "-h", o_special_noarg, (void *)showhelp, + "Show brief listing of options", OPT_ALIAS }, + + { "logfile", o_special, (void *)setlogfile, + "Append log messages to this file", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, &logfile_name }, + { "logfd", o_int, &log_to_fd, + "Send log messages to this file descriptor", + OPT_PRIOSUB | OPT_A2CLR, &log_default }, + { "nolog", o_int, &log_to_fd, + "Don't send log messages to any file", + OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, + { "nologfd", o_int, &log_to_fd, + "Don't send log messages to any file descriptor", + OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, + + { "linkname", o_string, linkname, + "Set logical name for link", + OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXPATHLEN }, + + { "maxfail", o_int, &maxfail, + "Maximum number of unsuccessful connection attempts to allow", + OPT_PRIO }, + + { "ktune", o_bool, &tune_kernel, + "Alter kernel settings as necessary", OPT_PRIO | 1 }, + { "noktune", o_bool, &tune_kernel, + "Don't alter kernel settings", OPT_PRIOSUB }, + + { "connect-delay", o_int, &connect_delay, + "Maximum time (in ms) to wait after connect script finishes", + OPT_PRIO }, + + { "unit", o_int, &req_unit, + "PPP interface unit number to use if possible", + OPT_PRIO | OPT_LLIMIT, 0, 0 }, + + { "dump", o_bool, &dump_options, + "Print out option values after parsing all options", 1 }, + { "dryrun", o_bool, &dryrun, + "Stop after parsing, printing, and checking options", 1 }, + + { "child-timeout", o_int, &child_wait, + "Number of seconds to wait for child processes at exit", + OPT_PRIO }, + +#ifdef HAVE_MULTILINK + { "multilink", o_bool, &multilink, + "Enable multilink operation", OPT_PRIO | 1 }, + { "mp", o_bool, &multilink, + "Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 }, + { "nomultilink", o_bool, &multilink, + "Disable multilink operation", OPT_PRIOSUB | 0 }, + { "nomp", o_bool, &multilink, + "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 }, + + { "bundle", o_string, &bundle_name, + "Bundle name for multilink", OPT_PRIO }, +#endif /* HAVE_MULTILINK */ + +#ifdef PLUGIN + { "plugin", o_special, (void *)loadplugin, + "Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST }, +#endif + +#ifdef PPP_FILTER + { "pass-filter", o_special, setpassfilter, + "set filter for packets to pass", OPT_PRIO }, + + { "active-filter", o_special, setactivefilter, + "set filter for active pkts", OPT_PRIO }, +#endif + +#ifdef MAXOCTETS + { "maxoctets", o_int, &maxoctets, + "Set connection traffic limit", + OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, + { "mo", o_int, &maxoctets, + "Set connection traffic limit", + OPT_ALIAS | OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, + { "mo-direction", o_special, setmodir, + "Set direction for limit traffic (sum,in,out,max)" }, + { "mo-timeout", o_int, &maxoctets_timeout, + "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 }, +#endif + + { NULL } +}; + +#ifndef IMPLEMENTATION +#define IMPLEMENTATION "" +#endif + +static char *usage_string = "\ +pppd version %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. + */ +int +parse_args(argc, argv) + int argc; + char **argv; +{ + char *arg; + option_t *opt; + int n; + + privileged_option = privileged; + option_source = "command line"; + option_priority = OPRIO_CMDLINE; + while (argc > 0) { + arg = *argv++; + --argc; + opt = find_option(arg); + if (opt == NULL) { + option_error("unrecognized option '%s'", arg); + usage(); + return 0; + } + n = n_arguments(opt); + if (argc < n) { + option_error("too few parameters for option %s", arg); + return 0; + } + if (!process_option(opt, arg, argv)) + return 0; + argc -= n; + argv += n; + } + return 1; +} + +/* + * options_from_file - Read a string of options from a file, + * and interpret them. + */ +int +options_from_file(filename, must_exist, check_prot, priv) + char *filename; + int must_exist; + int check_prot; + int priv; +{ + FILE *f; + int i, newline, ret, err; + option_t *opt; + int oldpriv, n; + char *oldsource; + uid_t euid; + char *argv[MAXARGS]; + char args[MAXARGS][MAXWORDLEN]; + char cmd[MAXWORDLEN]; + + euid = geteuid(); + if (check_prot && seteuid(getuid()) == -1) { + option_error("unable to drop privileges to open %s: %m", filename); + return 0; + } + f = fopen(filename, "r"); + err = errno; + if (check_prot && seteuid(euid) == -1) + fatal("unable to regain privileges"); + if (f == NULL) { + errno = err; + if (!must_exist) { + if (err != ENOENT && err != ENOTDIR) + warn("Warning: can't open options file %s: %m", filename); + return 1; + } + 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)) { + opt = find_option(cmd); + if (opt == NULL) { + option_error("In file %s: unrecognized option '%s'", + filename, cmd); + goto err; + } + 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]; + } + if (!process_option(opt, cmd, argv)) + 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() +{ + char *user, *path, *file; + int ret; + struct passwd *pw; + size_t pl; + + pw = getpwuid(getuid()); + if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) + return 1; + file = _PATH_USEROPT; + pl = strlen(user) + strlen(file) + 2; + path = malloc(pl); + if (path == NULL) + novm("init file name"); + slprintf(path, pl, "%s/%s", user, file); + option_priority = OPRIO_CFGFILE; + ret = options_from_file(path, 0, 1, privileged); + free(path); + return ret; +} + +/* + * options_for_tty - See if an options file exists for the serial + * device, and if so, interpret options from it. + * We only allow the per-tty options file to override anything from + * the command line if it is something that the user can't override + * once it has been set by root; this is done by giving configuration + * files a lower priority than the command line. + */ +int +options_for_tty() +{ + char *dev, *path, *p; + int ret; + size_t pl; + + dev = devnam; + if ((p = strstr(dev, "/dev/")) != NULL) + dev = p + 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 = '.'; + option_priority = OPRIO_CFGFILE; + 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(w, priv) + struct wordlist *w; + int priv; +{ + char *argv[MAXARGS]; + option_t *opt; + int i, n, ret = 0; + struct wordlist *w0; + + privileged_option = priv; + option_source = "secrets file"; + option_priority = OPRIO_SECFILE; + + while (w != NULL) { + opt = find_option(w->word); + if (opt == NULL) { + option_error("In secrets file: unrecognized option '%s'", + w->word); + goto err; + } + n = n_arguments(opt); + 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; + } + if (!process_option(opt, w0->word, argv)) + goto err; + w = w->next; + } + ret = 1; + +err: + return ret; +} + +/* + * match_option - see if this option matches an option_t structure. + */ +static int +match_option(name, opt, dowild) + char *name; + option_t *opt; + int dowild; +{ + int (*match) __P((char *, char **, int)); + + if (dowild != (opt->type == o_wild)) + return 0; + if (!dowild) + return strcmp(name, opt->name) == 0; + match = (int (*) __P((char *, char **, int))) opt->addr; + return (*match)(name, NULL, 0); +} + +/* + * 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(name) + const char *name; +{ + option_t *opt; + struct option_list *list; + int i, dowild; + + for (dowild = 0; dowild <= 1; ++dowild) { + for (opt = general_options; opt->name != NULL; ++opt) + if (match_option(name, opt, dowild)) + return opt; + for (opt = auth_options; opt->name != NULL; ++opt) + if (match_option(name, opt, dowild)) + return opt; + for (list = extra_options; list != NULL; list = list->next) + for (opt = list->options; opt->name != NULL; ++opt) + if (match_option(name, opt, dowild)) + return opt; + for (opt = the_channel->options; opt->name != NULL; ++opt) + if (match_option(name, opt, dowild)) + return opt; + for (i = 0; protocols[i] != NULL; ++i) + if ((opt = protocols[i]->options) != NULL) + for (; opt->name != NULL; ++opt) + if (match_option(name, opt, dowild)) + return opt; + } + return NULL; +} + +/* + * process_option - process one new-style option. + */ +static int +process_option(opt, cmd, argv) + option_t *opt; + char *cmd; + char **argv; +{ + u_int32_t v; + int iv, a; + char *sv; + int (*parser) __P((char **)); + int (*wildp) __P((char *, char **, int)); + char *optopt = (opt->type == o_wild)? "": " option"; + int prio = option_priority; + option_t *mainopt = opt; + + current_option = opt->name; + if ((opt->flags & OPT_PRIVFIX) && privileged_option) + prio += OPRIO_ROOT; + while (mainopt->flags & OPT_PRIOSUB) + --mainopt; + if (mainopt->flags & OPT_PRIO) { + if (prio < mainopt->priority) { + /* new value doesn't override old */ + if (prio == OPRIO_CMDLINE && mainopt->priority > OPRIO_ROOT) { + option_error("%s%s set in %s cannot be overridden\n", + opt->name, optopt, mainopt->source); + return 0; + } + return 1; + } + if (prio > OPRIO_ROOT && mainopt->priority == OPRIO_CMDLINE) + warn("%s%s from %s overrides command line", + opt->name, optopt, option_source); + } + + if ((opt->flags & OPT_INITONLY) && phase != PHASE_INITIALIZE) { + option_error("%s%s cannot be changed after initialization", + opt->name, optopt); + return 0; + } + if ((opt->flags & OPT_PRIV) && !privileged_option) { + option_error("using the %s%s requires root privilege", + opt->name, optopt); + return 0; + } + if ((opt->flags & OPT_ENABLE) && *(bool *)(opt->addr2) == 0) { + option_error("%s%s is disabled", opt->name, optopt); + return 0; + } + if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) { + option_error("the %s%s may not be changed in %s", + opt->name, optopt, option_source); + 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; + else if (opt->addr2 && (opt->flags & OPT_A2CLR)) + *(bool *)(opt->addr2) = 0; + else if (opt->addr2 && (opt->flags & OPT_A2CLRB)) + *(u_char *)(opt->addr2) &= ~v; + else if (opt->addr2 && (opt->flags & OPT_A2OR)) + *(u_char *)(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, zok, 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; + if (v & 0x80) + v |= 0xffffff00U; + } else if (!number_option(*argv, &v, 16)) + return 0; + if (opt->flags & OPT_OR) + v |= *(u_int32_t *)(opt->addr); + *(u_int32_t *)(opt->addr) = v; + if (opt->addr2 && (opt->flags & OPT_A2COPY)) + *(u_int32_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"); + *(char **)(opt->addr) = sv; + } + break; + + case o_special_noarg: + case o_special: + parser = (int (*) __P((char **))) opt->addr; + if (!(*parser)(argv)) + return 0; + if (opt->flags & OPT_A2LIST) { + struct option_value *ovp, *pp; + + ovp = malloc(sizeof(*ovp) + strlen(*argv)); + if (ovp != 0) { + strcpy(ovp->value, *argv); + ovp->source = option_source; + ovp->next = NULL; + if (opt->addr2 == NULL) { + opt->addr2 = ovp; + } else { + for (pp = opt->addr2; pp->next != NULL; pp = pp->next) + ; + pp->next = ovp; + } + } + } + break; + + case o_wild: + wildp = (int (*) __P((char *, char **, int))) opt->addr; + if (!(*wildp)(cmd, argv, 1)) + return 0; + break; + } + + /* + * If addr2 wasn't used by any flag (OPT_A2COPY, etc.) but is set, + * treat it as a bool and set/clear it based on the OPT_A2CLR bit. + */ + if (opt->addr2 && (opt->flags & (OPT_A2COPY|OPT_ENABLE + |OPT_A2PRINTER|OPT_A2STRVAL|OPT_A2LIST|OPT_A2OR)) == 0) + *(bool *)(opt->addr2) = !(opt->flags & OPT_A2CLR); + + mainopt->source = option_source; + mainopt->priority = prio; + mainopt->winner = opt - mainopt; + + return 1; +} + +/* + * override_value - if the option priorities would permit us to + * override the value of option, return 1 and update the priority + * and source of the option value. Otherwise returns 0. + */ +int +override_value(option, priority, source) + const char *option; + int priority; + const char *source; +{ + option_t *opt; + + opt = find_option(option); + if (opt == NULL) + return 0; + while (opt->flags & OPT_PRIOSUB) + --opt; + if ((opt->flags & OPT_PRIO) && priority < opt->priority) + return 0; + opt->priority = priority; + opt->source = source; + opt->winner = -1; + return 1; +} + +/* + * n_arguments - tell how many arguments an option takes + */ +static int +n_arguments(opt) + 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(opt) + 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; +} + +/* + * check_options - check that options are valid and consistent. + */ +void +check_options() +{ + if (logfile_fd >= 0 && logfile_fd != log_to_fd) + close(logfile_fd); +} + +/* + * print_option - print out an option and its value + */ +static void +print_option(opt, mainopt, printer, arg) + option_t *opt, *mainopt; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + int i, v; + char *p; + + if (opt->flags & OPT_NOPRINT) + return; + switch (opt->type) { + case o_bool: + v = opt->flags & OPT_VALUE; + if (*(bool *)opt->addr != v) + /* this can happen legitimately, e.g. lock + option turned off for default device */ + break; + printer(arg, "%s", opt->name); + break; + case o_int: + v = opt->flags & OPT_VALUE; + if (v >= 128) + v -= 256; + i = *(int *)opt->addr; + if (opt->flags & OPT_NOARG) { + printer(arg, "%s", opt->name); + if (i != v) { + if (opt->flags & OPT_INC) { + for (; i > v; i -= v) + printer(arg, " %s", opt->name); + } else + printer(arg, " # oops: %d not %d\n", + i, v); + } + } else { + printer(arg, "%s %d", opt->name, i); + } + break; + case o_uint32: + printer(arg, "%s", opt->name); + if ((opt->flags & OPT_NOARG) == 0) + printer(arg, " %x", *(u_int32_t *)opt->addr); + break; + + case o_string: + if (opt->flags & OPT_HIDE) { + p = "??????"; + } else { + p = (char *) opt->addr; + if ((opt->flags & OPT_STATIC) == 0) + p = *(char **)p; + } + printer(arg, "%s %q", opt->name, p); + break; + + case o_special: + case o_special_noarg: + case o_wild: + if (opt->type != o_wild) { + printer(arg, "%s", opt->name); + if (n_arguments(opt) == 0) + break; + printer(arg, " "); + } + if (opt->flags & OPT_A2PRINTER) { + void (*oprt) __P((option_t *, + void ((*)__P((void *, char *, ...))), + void *)); + oprt = (void (*) __P((option_t *, + void ((*)__P((void *, char *, ...))), + void *)))opt->addr2; + (*oprt)(opt, printer, arg); + } else if (opt->flags & OPT_A2STRVAL) { + p = (char *) opt->addr2; + if ((opt->flags & OPT_STATIC) == 0) + p = *(char **)p; + printer("%q", p); + } else if (opt->flags & OPT_A2LIST) { + struct option_value *ovp; + + ovp = (struct option_value *) opt->addr2; + for (;;) { + printer(arg, "%q", ovp->value); + if ((ovp = ovp->next) == NULL) + break; + printer(arg, "\t\t# (from %s)\n%s ", + ovp->source, opt->name); + } + } else { + printer(arg, "xxx # [don't know how to print value]"); + } + break; + + default: + printer(arg, "# %s value (type %d\?\?)", opt->name, opt->type); + break; + } + printer(arg, "\t\t# (from %s)\n", mainopt->source); +} + +/* + * print_option_list - print out options in effect from an + * array of options. + */ +static void +print_option_list(opt, printer, arg) + option_t *opt; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + while (opt->name != NULL) { + if (opt->priority != OPRIO_DEFAULT + && opt->winner != (short int) -1) + print_option(opt + opt->winner, opt, printer, arg); + do { + ++opt; + } while (opt->flags & OPT_PRIOSUB); + } +} + +/* + * print_options - print out what options are in effect. + */ +void +print_options(printer, arg) + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + struct option_list *list; + int i; + + printer(arg, "pppd options in effect:\n"); + print_option_list(general_options, printer, arg); + print_option_list(auth_options, printer, arg); + for (list = extra_options; list != NULL; list = list->next) + print_option_list(list->options, printer, arg); + print_option_list(the_channel->options, printer, arg); + for (i = 0; protocols[i] != NULL; ++i) + print_option_list(protocols[i]->options, printer, arg); +} + +/* + * usage - print out a message telling how to use the program. + */ +static void +usage() +{ + if (phase == PHASE_INITIALIZE) + fprintf(stderr, usage_string, VERSION, progname); +} + +/* + * showhelp - print out usage message and exit. + */ +static int +showhelp(argv) + char **argv; +{ + if (phase == PHASE_INITIALIZE) { + usage(); + exit(0); + } + return 0; +} + +/* + * showversion - print out the version number and exit. + */ +static int +showversion(argv) + char **argv; +{ + if (phase == PHASE_INITIALIZE) { + fprintf(stderr, "pppd version %s\n", VERSION); + exit(0); + } + return 0; +} + +/* + * option_error - print a message about an error in an option. + * The message is logged, and also sent to + * stderr if phase == PHASE_INITIALIZE. + */ +void +option_error __V((char *fmt, ...)) +{ + va_list args; + char buf[1024]; + +#if defined(__STDC__) + va_start(args, fmt); +#else + char *fmt; + va_start(args); + fmt = va_arg(args, char *); +#endif + vslprintf(buf, sizeof(buf), fmt, args); + va_end(args); + if (phase == PHASE_INITIALIZE) + fprintf(stderr, "%s: %s\n", progname, buf); + syslog(LOG_ERR, "%s", buf); +} + +#if 0 +/* + * readable - check if a file is readable by the real user. + */ +int +readable(fd) + int fd; +{ + uid_t uid; + int i; + struct stat sbuf; + + uid = getuid(); + if (uid == 0) + return 1; + if (fstat(fd, &sbuf) != 0) + return 0; + if (sbuf.st_uid == uid) + return sbuf.st_mode & S_IRUSR; + if (sbuf.st_gid == getgid()) + return sbuf.st_mode & S_IRGRP; + for (i = 0; i < ngroups; ++i) + if (sbuf.st_gid == groups[i]) + return sbuf.st_mode & S_IRGRP; + return sbuf.st_mode & S_IROTH; +} +#endif + +/* + * 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(f, word, newlinep, filename) + 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(str, valp, base) + char *str; + u_int32_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(str, valp) + char *str; + int *valp; +{ + u_int32_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(argv) + 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(argv) + 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 +/* + * setpassfilter - Set the pass filter for packets + */ +static int +setpassfilter(argv) + char **argv; +{ + pcap_t *pc; + int ret = 1; + + pc = pcap_open_dead(DLT_PPP_PPPD, 65535); + if (pcap_compile(pc, &pass_filter, *argv, 1, netmask) == -1) { + option_error("error in pass-filter expression: %s\n", + pcap_geterr(pc)); + ret = 0; + } + pcap_close(pc); + + return ret; +} + +/* + * setactivefilter - Set the active filter for packets + */ +static int +setactivefilter(argv) + char **argv; +{ + pcap_t *pc; + int ret = 1; + + pc = pcap_open_dead(DLT_PPP_PPPD, 65535); + if (pcap_compile(pc, &active_filter, *argv, 1, netmask) == -1) { + option_error("error in active-filter expression: %s\n", + pcap_geterr(pc)); + ret = 0; + } + pcap_close(pc); + + return ret; +} +#endif + +/* + * setdomain - Set domain name to append to hostname + */ +static int +setdomain(argv) + char **argv; +{ + gethostname(hostname, MAXNAMELEN); + if (**argv != 0) { + if (**argv != '.') + strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); + domain = hostname + strlen(hostname); + strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); + } + hostname[MAXNAMELEN-1] = 0; + return (1); +} + +static int +setlogfile(argv) + char **argv; +{ + int fd, err; + uid_t euid; + + euid = geteuid(); + if (!privileged_option && seteuid(getuid()) == -1) { + option_error("unable to drop permissions to open %s: %m", *argv); + return 0; + } + 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 (!privileged_option && seteuid(euid) == -1) + fatal("unable to regain privileges: %m"); + if (fd < 0) { + errno = err; + option_error("Can't open log file %s: %m", *argv); + return 0; + } + strlcpy(logfile_name, *argv, sizeof(logfile_name)); + if (logfile_fd >= 0) + close(logfile_fd); + logfile_fd = fd; + log_to_fd = fd; + log_default = 0; + return 1; +} + +#ifdef MAXOCTETS +static int +setmodir(argv) + char **argv; +{ + if(*argv == NULL) + return 0; + if(!strcmp(*argv,"in")) { + maxoctets_dir = PPP_OCTETS_DIRECTION_IN; + } else if (!strcmp(*argv,"out")) { + maxoctets_dir = PPP_OCTETS_DIRECTION_OUT; + } else if (!strcmp(*argv,"max")) { + maxoctets_dir = PPP_OCTETS_DIRECTION_MAXOVERAL; + } else { + maxoctets_dir = PPP_OCTETS_DIRECTION_SUM; + } + return 1; +} +#endif + +#ifdef PLUGIN +static int +loadplugin(argv) + char **argv; +{ + char *arg = *argv; + void *handle; + const char *err; + void (*init) __P((void)); + char *path = arg; + const char *vers; + + if (strchr(arg, '/') == 0) { + const char *base = ""; + int l = strlen(base) + strlen(arg) + 2; + path = malloc(l); + if (path == 0) + novm("plugin file path"); + strlcpy(path, base, l); + strlcat(path, "/", l); + strlcat(path, arg, l); + } + handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); + if (handle == 0) { + err = dlerror(); + if (err != 0) + option_error("%s", err); + option_error("Couldn't load plugin %s", arg); + goto err; + } + init = (void (*)(void))dlsym(handle, "plugin_init"); + if (init == 0) { + option_error("%s has no initialization entry point", arg); + goto errclose; + } + vers = (const char *) dlsym(handle, "pppd_version"); + if (vers == 0) { + warn("Warning: plugin %s has no version information", arg); + } else if (strcmp(vers, VERSION) != 0) { + option_error("Plugin %s is for pppd version %s, this is %s", + arg, vers, VERSION); + goto errclose; + } + info("Plugin %s loaded.", arg); + (*init)(); + return 1; + + errclose: + dlclose(handle); + err: + if (path != arg) + free(path); + return 0; +} +#endif /* PLUGIN */ diff --git a/src/netif/ppp/pap.c b/src/netif/ppp/pap.c deleted file mode 100644 index 5fb9f886..00000000 --- a/src/netif/ppp/pap.c +++ /dev/null @@ -1,628 +0,0 @@ -/***************************************************************************** -* pap.c - Network Password Authentication Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-12 Guy Lancaster , Global Election Systems Inc. -* Original. -*****************************************************************************/ -/* - * 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. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "auth.h" -#include "pap.h" - -#include - -#if 0 /* UNUSED */ -static bool hide_password = 1; - -/* - * Command-line options. - */ -static option_t pap_option_list[] = { - { "hide-password", o_bool, &hide_password, - "Don't output passwords to log", 1 }, - { "show-password", o_bool, &hide_password, - "Show password string in debug log messages", 0 }, - { "pap-restart", o_int, &upap[0].us_timeouttime, - "Set retransmit timeout for PAP" }, - { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, - "Set max number of transmissions for auth-reqs" }, - { "pap-timeout", o_int, &upap[0].us_reqtimeout, - "Set time limit for peer PAP authentication" }, - { NULL } -}; -#endif - -/* - * 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); -#if PPP_ADDITIONAL_CALLBACKS -static int upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *); -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -struct protent pap_protent = { - PPP_PAP, - upap_init, - upap_input, - upap_protrej, - upap_lowerup, - upap_lowerdown, - NULL, - NULL, -#if PPP_ADDITIONAL_CALLBACKS - upap_printpkt, - NULL, -#endif /* PPP_ADDITIONAL_CALLBACKS */ - 1, - "PAP", -#if PPP_ADDITIONAL_CALLBACKS - NULL, - NULL, - NULL -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -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 *, u_char, 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]; - - UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", 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]; - - UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n", - unit, user, password, u->us_clientstate)); - - /* Save the username and password we're given */ - u->us_user = user; - u->us_userlen = (int)strlen(user); - u->us_passwd = password; - u->us_passwdlen = (int)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; - - UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n", - u->us_unit, u->us_timeouttime, u->us_clientstate)); - - if (u->us_clientstate != UPAPCS_AUTHREQ) { - UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n")); - return; - } - - if (u->us_transmits >= u->us_maxtransmits) { - /* give up in disgust */ - UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n")); - u->us_clientstate = UPAPCS_BADAUTH; - auth_withpeer_fail(u->us_unit, PPP_PAP); - return; - } - - upap_sauthreq(u); /* Send Authenticate-Request and set upap timeout*/ -} - - -/* - * 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]; - - UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate)); - - 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 */ - /* now client state is UPAPCS__AUTHREQ */ - } - - 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]; - - UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate)); - - 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) { - UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n")); - auth_withpeer_fail(unit, PPP_PAP); - } - if (u->us_serverstate == UPAPSS_LISTEN) { - UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n")); - 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 < (int)UPAP_HEADERLEN) { - UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < (int)UPAP_HEADERLEN) { - UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n")); - return; - } - if (len > l) { - UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n")); - 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 */ - UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len)); - break; - } -} - - -/* - * upap_rauth - Receive Authenticate. - */ -static void -upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len) -{ - u_char ruserlen, rpasswdlen; - char *ruser, *rpasswd; - u_char retcode; - char *msg; - int msglen; - - UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id)); - - 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 < (int)sizeof (u_char)) { - UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); - return; - } - GETCHAR(ruserlen, inp); - len -= sizeof (u_char) + ruserlen + sizeof (u_char); - if (len < 0) { - UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); - return; - } - ruser = (char *) inp; - INCPTR(ruserlen, inp); - GETCHAR(rpasswdlen, inp); - if (len < rpasswdlen) { - UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); - return; - } - rpasswd = (char *) inp; - - /* - * Check the username and password given. - */ - retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen); - /* lwip: currently retcode is always UPAP_AUTHACK */ - BZERO(rpasswd, rpasswdlen); - - 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; - - LWIP_UNUSED_ARG(id); - - UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate)); - - if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */ - UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n")); - return; - } - - /* - * Parse message. - */ - if (len < (int)sizeof (u_char)) { - UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ - u->us_clientstate = UPAPCS_OPEN; - - auth_withpeer_success(u->us_unit, PPP_PAP); -} - - -/* - * upap_rauthnak - Receive Authenticate-Nak. - */ -static void -upap_rauthnak(upap_state *u, u_char *inp, int id, int len) -{ - u_char msglen; - char *msg; - - LWIP_UNUSED_ARG(id); - - UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate)); - - if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */ - return; - } - - /* - * Parse message. - */ - if (len < sizeof (u_char)) { - UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n")); - } else { - GETCHAR(msglen, inp); - if(msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - u->us_clientstate = UPAPCS_BADAUTH; - - UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n")); - 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[u->us_unit]; - - 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); - - pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN); - - UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id)); - - 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[u->us_unit]; - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(msglen, outp); - BCOPY(msg, outp, msglen); - pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN); - - UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate)); -} - -#if PPP_ADDITIONAL_CALLBACKS -static char *upap_codenames[] = { - "AuthReq", "AuthAck", "AuthNak" -}; - -/* - * upap_printpkt - print the contents of a PAP packet. - */ -static int upap_printpkt( - u_char *p, - int plen, - void (*printer) (void *, char *, ...), - void *arg -) -{ - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(plen); - LWIP_UNUSED_ARG(printer); - LWIP_UNUSED_ARG(arg); - return 0; -} -#endif /* PPP_ADDITIONAL_CALLBACKS */ - -#endif /* PAP_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/pap.h b/src/netif/ppp/pap.h deleted file mode 100644 index c99a2040..00000000 --- a/src/netif/ppp/pap.h +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************************************** -* pap.h - PPP Password Authentication Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-12-04 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ -/* - * 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. - */ - -#ifndef PAP_H -#define PAP_H - -#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * Packet header = Code, id, length. - */ -#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) - - -/* - * 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 */ - const char *us_user; /* User */ - int us_userlen; /* User length */ - const 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 */ - - -extern upap_state upap[]; - -void upap_authwithpeer (int, char *, char *); -void upap_authpeer (int); - -extern struct protent pap_protent; - -#endif /* PAP_SUPPORT */ - -#endif /* PAP_H */ diff --git a/src/netif/ppp/patchlevel.h b/src/netif/ppp/patchlevel.h new file mode 100644 index 00000000..b7d6ce33 --- /dev/null +++ b/src/netif/ppp/patchlevel.h @@ -0,0 +1,2 @@ +#define VERSION "2.4.5" +#define DATE "17 November 2009" diff --git a/src/netif/ppp/pathnames.h b/src/netif/ppp/pathnames.h new file mode 100644 index 00000000..a33f0466 --- /dev/null +++ b/src/netif/ppp/pathnames.h @@ -0,0 +1,65 @@ +/* + * define path names + * + * $Id: pathnames.h,v 1.18 2005/08/25 23:59:34 paulus Exp $ + */ + +#ifdef HAVE_PATHS_H +#include + +#else /* HAVE_PATHS_H */ +#ifndef _PATH_VARRUN +#define _PATH_VARRUN "/etc/ppp/" +#endif +#define _PATH_DEVNULL "/dev/null" +#endif /* HAVE_PATHS_H */ + +#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_SRPFILE _ROOT_PATH "/etc/ppp/srp-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_IPPREUP _ROOT_PATH "/etc/ppp/ip-pre-up" +#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" +#define _PATH_PSEUDONYM ".ppp_pseudonym" + +#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 */ + +#ifdef __STDC__ +#define _PATH_PPPDB _ROOT_PATH _PATH_VARRUN "pppd2.tdb" +#else /* __STDC__ */ +#ifdef HAVE_PATHS_H +#define _PATH_PPPDB "/var/run/pppd2.tdb" +#else +#define _PATH_PPPDB "/etc/ppp/pppd2.tdb" +#endif +#endif /* __STDC__ */ + +#ifdef PLUGIN +#ifdef __STDC__ +#define _PATH_PLUGIN DESTDIR "/lib/pppd/" VERSION +#else /* __STDC__ */ +#define _PATH_PLUGIN "/usr/lib/pppd" +#endif /* __STDC__ */ + +#endif /* PLUGIN */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 2a346575..d03f83f0 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1,2052 +1,2154 @@ -/***************************************************************************** -* ppp.c - Network Point to Point Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original. -*****************************************************************************/ - /* - * ppp_defs.h - PPP definitions. + * main.c - Point-to-Point Protocol main module * - * if_pppvar.h - private structures and declarations for PPP. + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 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. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * - * 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. - */ - -/* - * if_ppp.h - Point-to-Point Protocol definitions. + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * - * 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Copyright (c) 1999-2004 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "lwip/opt.h" +#include "pppmy.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "lwip/ip.h" /* for ip_input() */ - -#include "pppdebug.h" - -#include "randm.h" -#include "fsm.h" -#if PAP_SUPPORT -#include "pap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "chap.h" -#endif /* CHAP_SUPPORT */ -#include "ipcp.h" -#include "lcp.h" -#include "magic.h" -#include "auth.h" -#if VJ_SUPPORT -#include "vj.h" -#endif /* VJ_SUPPORT */ -#if PPPOE_SUPPORT -#include "netif/ppp_oe.h" -#endif /* PPPOE_SUPPORT */ - -#include "lwip/tcpip.h" -#include "lwip/api.h" -#include "lwip/snmp.h" +#define RCSID "$Id: main.c,v 1.156 2008/06/23 11:47:18 paulus Exp $" +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -/*************************/ -/*** LOCAL DEFINITIONS ***/ -/*************************/ +#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-new.h" +#include "eap.h" +#include "ccp.h" +#include "ecp.h" +#include "pathnames.h" -/** PPP_INPROC_MULTITHREADED==1 call pppInput using tcpip_callback(). - * Set this to 0 if pppInProc is called inside tcpip_thread or with NO_SYS==1. - * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). - */ -#ifndef PPP_INPROC_MULTITHREADED -#define PPP_INPROC_MULTITHREADED (NO_SYS==0) +#ifdef USE_TDB +#include "tdb.h" #endif -/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session. - * Default is 0: call pppos_input() for received raw characters, charcater - * reception is up to the port */ -#ifndef PPP_INPROC_OWNTHREAD -#define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED +#if CBCP_SUPPORT +#include "cbcp.h" #endif -#if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED - #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1" +#ifdef IPX_CHANGE +#include "ipxcp.h" +#endif /* IPX_CHANGE */ +#ifdef AT_CHANGE +#include "atcp.h" #endif +static const char rcsid[] = RCSID; + +/* interface vars */ +char ifname[32]; /* Interface name */ +int ifunit; /* Interface unit number */ + +struct channel *the_channel; + +char *progname; /* Name of this program */ +char hostname[MAXNAMELEN]; /* Our hostname */ +static char pidfilename[MAXPATHLEN]; /* name of pid file */ +static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ +char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ +uid_t uid; /* Our real user-id */ +struct notifier *pidchange = NULL; +struct notifier *phasechange = NULL; +struct notifier *exitnotify = NULL; +struct notifier *sigreceived = NULL; +struct notifier *fork_notifier = NULL; + +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 */ +volatile int 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 */ +int ppp_session_number; /* Session number, for channels with such a + concept (eg PPPoE) */ +int childwait_done; /* have timed out waiting for children */ + +#ifdef USE_TDB +TDB_CONTEXT *pppdb; /* database for storing status etc. */ +#endif + +char db_key[32]; + +int (*holdoff_hook) __P((void)) = NULL; +int (*new_phase_hook) __P((int)) = NULL; +void (*snoop_recv_hook) __P((unsigned char *p, int len)) = NULL; +void (*snoop_send_hook) __P((unsigned char *p, int len)) = NULL; + +static int conn_running; /* we have a [dis]connector running */ +static int fd_loop; /* fd for getting demand-dial packets */ + +int fd_devnull; /* fd for /dev/null */ +int devfd = -1; /* fd of underlying device */ +int fd_ppp = -1; /* fd for talking PPP */ +int phase; /* where the link is at */ +int kill_link; +int asked_to_quit; +int open_ccp_flag; +int listen_time; +int got_sigusr2; +int got_sigterm; +int got_sighup; + +static sigset_t signals_handled; +static int waiting; +static sigjmp_buf sigjmp; + +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 */ + +static int n_children; /* # child processes still running */ +static int got_sigchld; /* set if we have received a SIGCHLD */ + +int privopen; /* don't lock, open device as root */ + +char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; + +GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ +int ngroups; /* How many groups valid in groups */ + +static struct timeval start_time; /* Time when link was started. */ + +static struct pppd_stats old_link_stats; +struct pppd_stats link_stats; +unsigned link_connect_time; +int link_stats_valid; + +int error_count; + +bool bundle_eof; +bool bundle_terminating; + /* - * The basic PPP frame. + * We maintain a list of child process pids and + * functions to call when they exit. */ -#define PPP_ADDRESS(p) (((u_char *)(p))[0]) -#define PPP_CONTROL(p) (((u_char *)(p))[1]) -#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) - -/* PPP packet parser states. Current state indicates operation yet to be - * completed. */ -typedef enum { - PDIDLE = 0, /* Idle state - waiting. */ - PDSTART, /* Process start flag. */ - PDADDRESS, /* Process address field. */ - PDCONTROL, /* Process control field. */ - PDPROTOCOL1, /* Process protocol field 1. */ - PDPROTOCOL2, /* Process protocol field 2. */ - PDDATA /* Process data byte. */ -} PPPDevStates; - -#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07]) - -/************************/ -/*** LOCAL DATA TYPES ***/ -/************************/ - -/** RX buffer size: this may be configured smaller! */ -#ifndef PPPOS_RX_BUFSIZE -#define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN) -#endif - -typedef struct PPPControlRx_s { - /** unit number / ppp descriptor */ - int pd; - /** the rx file descriptor */ - sio_fd_t fd; - /** receive buffer - encoded data is stored here */ -#if PPP_INPROC_OWNTHREAD - u_char rxbuf[PPPOS_RX_BUFSIZE]; -#endif /* PPP_INPROC_OWNTHREAD */ - - /* The input packet. */ - struct pbuf *inHead, *inTail; - -#if PPPOS_SUPPORT - u16_t inProtocol; /* The input protocol code. */ - u16_t inFCS; /* Input Frame Check Sequence value. */ -#endif /* PPPOS_SUPPORT */ - PPPDevStates inState; /* The input process state. */ - char inEscaped; /* Escape next character. */ - ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ -} PPPControlRx; - -/* - * PPP interface control block. - */ -typedef struct PPPControl_s { - PPPControlRx rx; - char openFlag; /* True when in use. */ -#if PPPOE_SUPPORT - struct netif *ethif; - struct pppoe_softc *pppoe_sc; -#endif /* PPPOE_SUPPORT */ - int if_up; /* True when the interface is up. */ - int errCode; /* Code indicating why interface is down. */ -#if PPPOS_SUPPORT - sio_fd_t fd; /* File device ID of port. */ -#endif /* PPPOS_SUPPORT */ - u16_t mtu; /* Peer's mru */ - int pcomp; /* Does peer accept protocol compression? */ - int accomp; /* Does peer accept addr/ctl compression? */ - u_long lastXMit; /* Time of last transmission. */ - ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ -#if PPPOS_SUPPORT && VJ_SUPPORT - int vjEnabled; /* Flag indicating VJ compression enabled. */ - struct vjcompress vjComp; /* Van Jacobson compression header. */ -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - - struct netif netif; - - struct ppp_addrs addrs; - - void (*linkStatusCB)(void *ctx, int errCode, void *arg); - void *linkStatusCtx; - -} PPPControl; - - -/* - * Ioctl definitions. - */ - -struct npioctl { - int protocol; /* PPP procotol, e.g. PPP_IP */ - enum NPmode mode; +struct subprocess { + pid_t pid; + char *prog; + void (*done) __P((void *)); + void *arg; + int killable; + struct subprocess *next; }; +static struct subprocess *children; +/* Prototypes for procedures local to this file. */ -/***********************************/ -/*** LOCAL FUNCTION DECLARATIONS ***/ -/***********************************/ -#if PPPOS_SUPPORT -#if PPP_INPROC_OWNTHREAD -static void pppInputThread(void *arg); -#endif /* PPP_INPROC_OWNTHREAD */ -static void pppDrop(PPPControlRx *pcrx); -static void pppInProc(PPPControlRx *pcrx, u_char *s, int l); -static void pppFreeCurrentInputPacket(PPPControlRx *pcrx); -#endif /* PPPOS_SUPPORT */ +static void setup_signals __P((void)); +static void create_pidfile __P((int pid)); +static void create_linkpidfile __P((int pid)); +static void cleanup __P((void)); +static void get_input __P((void)); +static void calltimeout __P((void)); +static struct timeval *timeleft __P((struct timeval *)); +static void kill_my_pg __P((int)); +static void hup __P((int)); +static void term __P((int)); +static void chld __P((int)); +static void toggle_debug __P((int)); +static void open_ccp __P((int)); +static void bad_signal __P((int)); +static void holdoff_end __P((void *)); +static void forget_child __P((int pid, int status)); +static int reap_kids __P((void)); +static void childwait_end __P((void *)); +#ifdef USE_TDB +static void update_db_entry __P((void)); +static void add_db_key __P((const char *)); +static void delete_db_key __P((const char *)); +static void cleanup_db __P((void)); +#endif -/******************************/ -/*** PUBLIC DATA STRUCTURES ***/ -/******************************/ -static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ +static void handle_events __P((void)); +void print_link_stats __P((void)); + +extern char *ttyname __P((int)); +extern char *getlogin __P((void)); +//int main __P((int, char *[])); + +#ifdef ultrix +#undef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif + +#ifdef ULTRIX +#define setlogmask(x) +#endif /* * PPP Data Link Layer "protocol" table. * One entry per supported protocol. * The last entry must be NULL. */ -struct protent *ppp_protocols[] = { - &lcp_protent, -#if PAP_SUPPORT - &pap_protent, -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - &chap_protent, -#endif /* CHAP_SUPPORT */ +struct protent *protocols[] = { + &lcp_protent, + &pap_protent, + &chap_protent, #if CBCP_SUPPORT - &cbcp_protent, -#endif /* CBCP_SUPPORT */ - &ipcp_protent, -#if CCP_SUPPORT - &ccp_protent, -#endif /* CCP_SUPPORT */ - NULL + &cbcp_protent, +#endif + &ipcp_protent, +#ifdef INET6 + &ipv6cp_protent, +#endif + &ccp_protent, + &ecp_protent, +#ifdef IPX_CHANGE + &ipxcp_protent, +#endif +#ifdef AT_CHANGE + &atcp_protent, +#endif + &eap_protent, + NULL }; - /* - * Buffers for outgoing packets. This must be accessed only from the appropriate - * PPP task so that it doesn't need to be protected to avoid collisions. + * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. */ -u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; +#if !defined(PPP_DRV_NAME) +#define PPP_DRV_NAME "ppp" +#endif /* !defined(PPP_DRV_NAME) */ +int ppp_oldmain() { + int argc = 0; + char *argv[0]; + int i, t; + char *p; + struct passwd *pw; + struct protent *protp; + char numbuf[16]; -/*****************************/ -/*** LOCAL DATA STRUCTURES ***/ -/*****************************/ + link_stats_valid = 0; + new_phase(PHASE_INITIALIZE); -#if PPPOS_SUPPORT -/* - * FCS lookup table as calculated by genfcstab. - * @todo: smaller, slower implementation for lower memory footprint? - */ -static const 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 -}; + script_env = NULL; -/* PPP's Asynchronous-Control-Character-Map. The mask array is used - * to select the specific bit for a character. */ -static u_char pppACCMMask[] = { - 0x01, - 0x02, - 0x04, - 0x08, - 0x10, - 0x20, - 0x40, - 0x80 -}; + /* Initialize syslog facilities */ + reopen_log(); -#if PPP_INPROC_OWNTHREAD -/** Wake up the task blocked in reading from serial line (if any) */ -static void -pppRecvWakeup(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd)); - if (pppControl[pd].openFlag != 0) { - sio_read_abort(pppControl[pd].fd); - } -} -#endif /* PPP_INPROC_OWNTHREAD */ -#endif /* PPPOS_SUPPORT */ - -void -pppLinkTerminated(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d\n", pd)); - -#if PPPOE_SUPPORT - if (pppControl[pd].ethif) { - pppoe_disconnect(pppControl[pd].pppoe_sc); - } else -#endif /* PPPOE_SUPPORT */ - { -#if PPPOS_SUPPORT - PPPControl* pc; -#if PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); -#endif /* PPP_INPROC_OWNTHREAD */ - pc = &pppControl[pd]; - - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + if (gethostname(hostname, MAXNAMELEN) < 0 ) { + option_error("Couldn't get hostname: %m"); + exit(1); } + hostname[MAXNAMELEN-1] = 0; - pc->openFlag = 0;/**/ -#endif /* PPPOS_SUPPORT */ - } - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: finished.\n")); -} + /* make sure we don't create world or group writable files. */ + umask(umask(0777) | 022); -void -pppLinkDown(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppLinkDown: unit %d\n", pd)); + uid = getuid(); + privileged = uid == 0; + slprintf(numbuf, sizeof(numbuf), "%d", uid); + script_setenv("ORIG_UID", numbuf, 0); -#if PPPOE_SUPPORT - if (pppControl[pd].ethif) { - pppoe_disconnect(pppControl[pd].pppoe_sc); - } else -#endif /* PPPOE_SUPPORT */ - { -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ - } -} - -/** Initiate LCP open request */ -static void -pppStart(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd)); - lcp_lowerup(pd); - lcp_open(pd); /* Start protocol */ - PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n")); -} - -/** LCP close request */ -static void -pppStop(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppStop: unit %d\n", pd)); - lcp_close(pd, "User request"); -} - -/** Called when carrier/link is lost */ -static void -pppHup(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppHupCB: unit %d\n", pd)); - lcp_lowerdown(pd); - link_terminated(pd); -} - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -/* Initialize the PPP subsystem. */ - -struct ppp_settings ppp_settings; - -void -pppInit(void) -{ - struct protent *protp; - int i, j; - - memset(&ppp_settings, 0, sizeof(ppp_settings)); - ppp_settings.usepeerdns = 1; - pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL); - - magicInit(); - - for (i = 0; i < NUM_PPP; i++) { - /* Initialize each protocol to the standard option set. */ - for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j) { - (*protp->init)(i); - } - } -} - -void -pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) -{ - switch(authType) { - case PPPAUTHTYPE_NONE: - default: -#ifdef LWIP_PPP_STRICT_PAP_REJECT - ppp_settings.refuse_pap = 1; -#else /* LWIP_PPP_STRICT_PAP_REJECT */ - /* some providers request pap and accept an empty login/pw */ - ppp_settings.refuse_pap = 0; -#endif /* LWIP_PPP_STRICT_PAP_REJECT */ - ppp_settings.refuse_chap = 1; - break; - - case PPPAUTHTYPE_ANY: - /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. - * RFC 1994 says: - * - * In practice, within or associated with each PPP server, there is a - * database which associates "user" names with authentication - * information ("secrets"). It is not anticipated that a particular - * named user would be authenticated by multiple methods. This would - * make the user vulnerable to attacks which negotiate the least secure - * method from among a set (such as PAP rather than CHAP). If the same - * secret was used, PAP would reveal the secret to be used later with - * CHAP. - * - * Instead, for each user name there should be an indication of exactly - * one method used to authenticate that user name. If a user needs to - * make use of different authentication methods under different - * circumstances, then distinct user names SHOULD be employed, each of - * which identifies exactly one authentication method. - * - */ - ppp_settings.refuse_pap = 0; - ppp_settings.refuse_chap = 0; - break; - - case PPPAUTHTYPE_PAP: - ppp_settings.refuse_pap = 0; - ppp_settings.refuse_chap = 1; - break; - - case PPPAUTHTYPE_CHAP: - ppp_settings.refuse_pap = 1; - ppp_settings.refuse_chap = 0; - break; - } - - if(user) { - strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); - ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0'; - } else { - ppp_settings.user[0] = '\0'; - } - - if(passwd) { - strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1); - ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0'; - } else { - ppp_settings.passwd[0] = '\0'; - } -} - -#if PPPOS_SUPPORT -/** Open a new PPP connection using the given I/O device. - * This initializes the PPP control block but does not - * attempt to negotiate the LCP session. If this port - * connects to a modem, the modem connection must be - * established before calling this. - * Return a new PPP connection descriptor on success or - * an error code (negative) on failure. - * - * pppOpen() is directly defined to this function. - */ -int -pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) -{ - PPPControl *pc; - int pd; - - if (linkStatusCB == NULL) { - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ - return PPPERR_PARAM; - } - - /* Find a free PPP session descriptor. */ - for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); - - if (pd >= NUM_PPP) { - pd = PPPERR_OPEN; - } else { - pc = &pppControl[pd]; - /* input pbuf left over from last session? */ - pppFreeCurrentInputPacket(&pc->rx); - /* @todo: is this correct or do I overwrite something? */ - memset(pc, 0, sizeof(PPPControl)); - pc->rx.pd = pd; - pc->rx.fd = fd; - - pc->openFlag = 1; - pc->fd = fd; - -#if VJ_SUPPORT - vj_compress_init(&pc->vjComp); -#endif /* VJ_SUPPORT */ - - /* - * Default the in and out accm so that escape and flag characters - * are always escaped. - */ - pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */ - pc->outACCM[15] = 0x60; - - pc->linkStatusCB = linkStatusCB; - pc->linkStatusCtx = linkStatusCtx; + ngroups = getgroups(NGROUPS_MAX, groups); /* - * Start the connection and handle incoming events (packet or timeout). + * Initialize magic number generator now so that protocols may + * use magic numbers in initialization. */ - PPPDEBUG(LOG_INFO, ("pppOverSerialOpen: unit %d: Connecting\n", pd)); - pppStart(pd); -#if PPP_INPROC_OWNTHREAD - sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); -#endif /* PPP_INPROC_OWNTHREAD */ - } + magic_init(); - return pd; -} -#endif /* PPPOS_SUPPORT */ + /* + * Initialize each protocol. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + (*protp->init)(0); -#if PPPOE_SUPPORT -static void pppOverEthernetLinkStatusCB(int pd, int up); + /* + * Initialize the default channel. + */ + tty_init(); -void -pppOverEthernetClose(int pd) -{ - PPPControl* pc = &pppControl[pd]; + progname = *argv; - /* *TJL* There's no lcp_deinit */ - lcp_close(pd, NULL); + /* + * Parse, in order, the system options file, the user's options file, + * and the command line arguments. + */ + if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) + || !options_from_user() + || !parse_args(argc-1, argv+1)) + exit(EXIT_OPTION_ERROR); + devnam_fixed = 1; /* can no longer change device name */ - pppoe_destroy(&pc->netif); -} + /* + * Work out the device name, if it hasn't already been specified, + * and parse the tty's options file. + */ + if (the_channel->process_extra_options) + (*the_channel->process_extra_options)(); -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, - pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) -{ - PPPControl *pc; - int pd; + if (debug) + setlogmask(LOG_UPTO(LOG_DEBUG)); - LWIP_UNUSED_ARG(service_name); - LWIP_UNUSED_ARG(concentrator_name); - - if (linkStatusCB == NULL) { - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ - return PPPERR_PARAM; - } - - /* Find a free PPP session descriptor. Critical region? */ - for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); - if (pd >= NUM_PPP) { - pd = PPPERR_OPEN; - } else { - pc = &pppControl[pd]; - memset(pc, 0, sizeof(PPPControl)); - pc->openFlag = 1; - pc->ethif = ethif; - - pc->linkStatusCB = linkStatusCB; - pc->linkStatusCtx = linkStatusCtx; - - lcp_wantoptions[pd].mru = PPPOE_MAXMTU; - lcp_wantoptions[pd].neg_asyncmap = 0; - lcp_wantoptions[pd].neg_pcompression = 0; - lcp_wantoptions[pd].neg_accompression = 0; - - lcp_allowoptions[pd].mru = PPPOE_MAXMTU; - lcp_allowoptions[pd].neg_asyncmap = 0; - lcp_allowoptions[pd].neg_pcompression = 0; - lcp_allowoptions[pd].neg_accompression = 0; - - if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) { - pc->openFlag = 0; - return PPPERR_OPEN; + /* + * Check that we are running as root. + */ + if (geteuid() != 0) { + option_error("must be root to run %s, since it is not setuid-root", + argv[0]); + exit(EXIT_NOT_ROOT); } - pppoe_connect(pc->pppoe_sc); - } + if (!ppp_available()) { + option_error("%s", no_ppp_msg); + exit(EXIT_NO_KERNEL_SUPPORT); + } - return pd; -} -#endif /* PPPOE_SUPPORT */ + /* + * Check that the options given are valid and consistent. + */ + check_options(); + if (!sys_check_options()) + exit(EXIT_OPTION_ERROR); + auth_check_options(); +#ifdef HAVE_MULTILINK + mp_check_options(); +#endif + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->check_options != NULL) + (*protp->check_options)(); + if (the_channel->check_options) + (*the_channel->check_options)(); -/* Close a PPP connection and release the descriptor. - * Any outstanding packets in the queues are dropped. - * Return 0 on success, an error code on failure. */ -int -pppClose(int pd) -{ - PPPControl *pc = &pppControl[pd]; - int st = 0; + if (dump_options || dryrun) { + init_pr_log(NULL, LOG_INFO); + print_options(pr_log, NULL); + end_pr_log(); + } - PPPDEBUG(LOG_DEBUG, ("pppClose() called\n")); + if (dryrun) + die(0); - /* Disconnect */ -#if PPPOE_SUPPORT - if(pc->ethif) { - PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); - pc->errCode = PPPERR_USER; - /* This will leave us at PHASE_DEAD. */ - pppStop(pd); - } else -#endif /* PPPOE_SUPPORT */ - { -#if PPPOS_SUPPORT - PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); - pc->errCode = PPPERR_USER; - /* This will leave us at PHASE_DEAD. */ - pppStop(pd); -#if PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); -#endif /* PPP_INPROC_OWNTHREAD */ -#endif /* PPPOS_SUPPORT */ - } + /* Make sure fds 0, 1, 2 are open to somewhere. */ + fd_devnull = open(_PATH_DEVNULL, O_RDWR); + if (fd_devnull < 0) + fatal("Couldn't open %s: %m", _PATH_DEVNULL); + while (fd_devnull <= 2) { + i = dup(fd_devnull); + if (i < 0) + fatal("Critical shortage of file descriptors: dup failed: %m"); + fd_devnull = i; + } - return st; + /* + * Initialize system-dependent stuff. + */ + linux_sys_init(); + +#ifdef USE_TDB + pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644); + if (pppdb != NULL) { + slprintf(db_key, sizeof(db_key), "pppd%d", getpid()); + update_db_entry(); + } else { + warn("Warning: couldn't open ppp database %s", _PATH_PPPDB); + if (multilink) { + warn("Warning: disabling multilink"); + multilink = 0; + } + } +#endif + + /* + * Detach ourselves from the terminal, if required, + * and identify who is running us. + */ + if (!nodetach && !updetach) + detach(); + p = getlogin(); + if (p == NULL) { + pw = getpwuid(uid); + if (pw != NULL && pw->pw_name != NULL) + p = pw->pw_name; + else + p = "(unknown)"; + } + syslog(LOG_NOTICE, "pppd %s started by %s, uid %d", VERSION, p, uid); + script_setenv("PPPLOGNAME", p, 0); + + if (devnam[0]) + script_setenv("DEVICE", devnam, 1); + slprintf(numbuf, sizeof(numbuf), "%d", getpid()); + script_setenv("PPPD_PID", numbuf, 1); + + setup_signals(); + + create_linkpidfile(getpid()); + + waiting = 0; + + /* + * If we're doing dial-on-demand, set up the interface now. + */ + if (demand) { + /* + * Open the loopback channel and set it up to be the ppp interface. + */ + fd_loop = open_ppp_loopback(); + set_ifunit(1); + /* + * Configure the interface and mark it up, etc. + */ + demand_conf(); + } + + do_callback = 0; + for (;;) { + + bundle_eof = 0; + bundle_terminating = 0; + listen_time = 0; + need_holdoff = 1; + devfd = -1; + status = EXIT_OK; + ++unsuccess; + doing_callback = do_callback; + do_callback = 0; + + if (demand && !doing_callback) { + /* + * Don't do anything until we see some activity. + */ + new_phase(PHASE_DORMANT); + demand_unblock(); + add_fd(fd_loop); + for (;;) { + handle_events(); + if (asked_to_quit) + break; + if (get_loop_output()) + break; + } + remove_fd(fd_loop); + if (asked_to_quit) + break; + + /* + * Now we want to bring up the link. + */ + demand_block(); + info("Starting link"); + } + + gettimeofday(&start_time, NULL); + script_unsetenv("CONNECT_TIME"); + script_unsetenv("BYTES_SENT"); + script_unsetenv("BYTES_RCVD"); + + lcp_open(0); /* Start protocol */ + //start_link(0); + while (phase != PHASE_DEAD) { + handle_events(); + get_input(); + if (kill_link) + lcp_close(0, "User request"); + if (asked_to_quit) { + bundle_terminating = 1; + if (phase == PHASE_MASTER) + mp_bundle_terminated(); + } + if (open_ccp_flag) { + if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { + ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ + (*ccp_protent.open)(0); + } + } + } + /* restore FSMs to original state */ + lcp_close(0, ""); + + if (!persist || asked_to_quit || (maxfail > 0 && unsuccess >= maxfail)) + break; + + 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 { + handle_events(); + if (kill_link) + new_phase(PHASE_DORMANT); /* allow signal to end holdoff */ + } while (phase == PHASE_HOLDOFF); + if (!persist) + break; + } + } + + /* Wait for scripts to finish */ + reap_kids(); + if (n_children > 0) { + if (child_wait > 0) + TIMEOUT(childwait_end, NULL, child_wait); + if (debug) { + struct subprocess *chp; + dbglog("Waiting for %d child processes...", n_children); + for (chp = children; chp != NULL; chp = chp->next) + dbglog(" script %s, pid %d", chp->prog, chp->pid); + } + while (n_children > 0 && !childwait_done) { + handle_events(); + if (kill_link && !childwait_done) + childwait_end(NULL); + } + } + + die(status); + return 0; } -/* This function is called when carrier is lost on the PPP channel. */ -void -pppSigHUP(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); - pppHup(pd); -} - -#if PPPOS_SUPPORT +/* + * handle_events - wait for something to happen and respond to it. + */ static void -nPut(PPPControl *pc, struct pbuf *nb) +handle_events() { - struct pbuf *b; - int c; + struct timeval timo; - for(b = nb; b != NULL; b = b->next) { - if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) { - PPPDEBUG(LOG_WARNING, - ("PPP nPut: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); - LINK_STATS_INC(link.err); - pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */ - snmp_inc_ifoutdiscards(&pc->netif); - pbuf_free(nb); - return; + kill_link = open_ccp_flag = 0; + if (sigsetjmp(sigjmp, 1) == 0) { + sigprocmask(SIG_BLOCK, &signals_handled, NULL); + if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) { + sigprocmask(SIG_UNBLOCK, &signals_handled, NULL); + } else { + waiting = 1; + sigprocmask(SIG_UNBLOCK, &signals_handled, NULL); + wait_input(timeleft(&timo)); + } } - } - - snmp_add_ifoutoctets(&pc->netif, nb->tot_len); - snmp_inc_ifoutucastpkts(&pc->netif); - pbuf_free(nb); - LINK_STATS_INC(link.xmit); -} - -/* - * pppAppend - append given character to end of given pbuf. If outACCM - * is not NULL and the character needs to be escaped, do so. - * If pbuf is full, append another. - * Return the current pbuf. - */ -static struct pbuf * -pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM) -{ - struct pbuf *tb = nb; - - /* Make sure there is room for the character and an escape code. - * Sure we don't quite fill the buffer if the character doesn't - * get escaped but is one character worth complicating this? */ - /* Note: We assume no packet header. */ - if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) { - tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (tb) { - nb->next = tb; - } else { - LINK_STATS_INC(link.memerr); + waiting = 0; + calltimeout(); + if (got_sighup) { + info("Hangup (SIGHUP)"); + kill_link = 1; + got_sighup = 0; + if (status != EXIT_HANGUP) + status = EXIT_USER_REQUEST; } - nb = tb; - } - - if (nb) { - if (outACCM && ESCAPE_P(*outACCM, c)) { - *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE; - *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS; - } else { - *((u_char*)nb->payload + nb->len++) = c; + if (got_sigterm) { + info("Terminating on signal %d", got_sigterm); + kill_link = 1; + asked_to_quit = 1; + persist = 0; + status = EXIT_USER_REQUEST; + got_sigterm = 0; } - } - - return tb; -} -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT -static err_t -pppifOutputOverEthernet(int pd, struct pbuf *p) -{ - PPPControl *pc = &pppControl[pd]; - struct pbuf *pb; - u_short protocol = PPP_IP; - int i=0; - u16_t tot_len; - - /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return ERR_MEM; - } - - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - - pc->lastXMit = sys_jiffies(); - - if (!pc->pcomp || protocol > 0xFF) { - *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; - } - *((u_char*)pb->payload + i) = protocol & 0xFF; - - pbuf_chain(pb, p); - tot_len = pb->tot_len; - - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { - LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_DEVICE; - } - - snmp_add_ifoutoctets(&pc->netif, tot_len); - snmp_inc_ifoutucastpkts(&pc->netif); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} -#endif /* PPPOE_SUPPORT */ - -/* Send a packet on the given connection. */ -static err_t -pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) -{ - int pd = (int)(size_t)netif->state; - PPPControl *pc = &pppControl[pd]; -#if PPPOS_SUPPORT - u_short protocol = PPP_IP; - u_int fcsOut = PPP_INITFCS; - struct pbuf *headMB = NULL, *tailMB = NULL, *p; - u_char c; -#endif /* PPPOS_SUPPORT */ - - LWIP_UNUSED_ARG(ipaddr); - - /* Validate parameters. */ - /* We let any protocol value go through - it can't hurt us - * and the peer will just drop it if it's not accepting it. */ - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", - pd, PPP_IP, pb)); - LINK_STATS_INC(link.opterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_ARG; - } - - /* Check that the link is up. */ - if (lcp_phase[pd] == PHASE_DEAD) { - PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd)); - LINK_STATS_INC(link.rterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_RTE; - } - -#if PPPOE_SUPPORT - if(pc->ethif) { - return pppifOutputOverEthernet(pd, pb); - } -#endif /* PPPOE_SUPPORT */ - -#if PPPOS_SUPPORT - /* Grab an output buffer. */ - headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (headMB == NULL) { - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd)); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_MEM; - } - -#if VJ_SUPPORT - /* - * Attempt Van Jacobson header compression if VJ is configured and - * this is an IP packet. - */ - if (protocol == PPP_IP && pc->vjEnabled) { - switch (vj_compress_tcp(&pc->vjComp, pb)) { - case TYPE_IP: - /* No change... - protocol = PPP_IP_PROTOCOL; */ - break; - case TYPE_COMPRESSED_TCP: - protocol = PPP_VJC_COMP; - break; - case TYPE_UNCOMPRESSED_TCP: - protocol = PPP_VJC_UNCOMP; - break; - default: - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd)); - LINK_STATS_INC(link.proterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - pbuf_free(headMB); - return ERR_VAL; + if (got_sigchld) { + got_sigchld = 0; + reap_kids(); /* Don't leave dead kids lying around */ } - } -#endif /* VJ_SUPPORT */ - - tailMB = headMB; - - /* Build the PPP header. */ - if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - } - - pc->lastXMit = sys_jiffies(); - if (!pc->accomp) { - fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS); - tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM); - fcsOut = PPP_FCS(fcsOut, PPP_UI); - tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM); - } - if (!pc->pcomp || protocol > 0xFF) { - c = (protocol >> 8) & 0xFF; - fcsOut = PPP_FCS(fcsOut, c); - tailMB = pppAppend(c, tailMB, &pc->outACCM); - } - c = protocol & 0xFF; - fcsOut = PPP_FCS(fcsOut, c); - tailMB = pppAppend(c, tailMB, &pc->outACCM); - - /* Load packet. */ - for(p = pb; p; p = p->next) { - int n; - u_char *sPtr; - - sPtr = (u_char*)p->payload; - n = p->len; - while (n-- > 0) { - c = *sPtr++; - - /* Update FCS before checking for special characters. */ - fcsOut = PPP_FCS(fcsOut, c); - - /* Copy to output buffer escaping special characters. */ - tailMB = pppAppend(c, tailMB, &pc->outACCM); + if (got_sigusr2) { + open_ccp_flag = 1; + got_sigusr2 = 0; } - } - - /* Add FCS and trailing flag. */ - c = ~fcsOut & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - c = (~fcsOut >> 8) & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - - /* If we failed to complete the packet, throw it away. */ - if (!tailMB) { - PPPDEBUG(LOG_WARNING, - ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", - pd, protocol)); - pbuf_free(headMB); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_MEM; - } - - /* Send it. */ - PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); - - nPut(pc, headMB); -#endif /* PPPOS_SUPPORT */ - - return ERR_OK; -} - -/* Get and set parameters for the given connection. - * Return 0 on success, an error code on failure. */ -int -pppIOCtl(int pd, int cmd, void *arg) -{ - PPPControl *pc = &pppControl[pd]; - int st = 0; - - if (pd < 0 || pd >= NUM_PPP) { - st = PPPERR_PARAM; - } else { - switch(cmd) { - case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ - if (arg) { - *(int *)arg = (int)(pc->if_up); - } else { - st = PPPERR_PARAM; - } - break; - case PPPCTLS_ERRCODE: /* Set the PPP error code. */ - if (arg) { - pc->errCode = *(int *)arg; - } else { - st = PPPERR_PARAM; - } - break; - case PPPCTLG_ERRCODE: /* Get the PPP error code. */ - if (arg) { - *(int *)arg = (int)(pc->errCode); - } else { - st = PPPERR_PARAM; - } - break; -#if PPPOS_SUPPORT - case PPPCTLG_FD: /* Get the fd associated with the ppp */ - if (arg) { - *(sio_fd_t *)arg = pc->fd; - } else { - st = PPPERR_PARAM; - } - break; -#endif /* PPPOS_SUPPORT */ - default: - st = PPPERR_PARAM; - break; - } - } - - return st; } /* - * Return the Maximum Transmission Unit for the given PPP connection. + * setup_signals - initialize signal handling. */ -u_short -pppMTU(int pd) +static void +setup_signals() { - PPPControl *pc = &pppControl[pd]; - u_short st; + struct sigaction sa; - /* Validate parameters. */ - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - } else { - st = pc->mtu; - } + /* + * Compute mask of all interesting signals and install signal handlers + * for each. Only one signal handler may be active at a time. Therefore, + * all other signals should be masked when any handler is executing. + */ + sigemptyset(&signals_handled); + sigaddset(&signals_handled, SIGHUP); + sigaddset(&signals_handled, SIGINT); + sigaddset(&signals_handled, SIGTERM); + sigaddset(&signals_handled, SIGCHLD); + sigaddset(&signals_handled, SIGUSR2); - return st; -} +#define SIGNAL(s, handler) do { \ + sa.sa_handler = handler; \ + if (sigaction(s, &sa, NULL) < 0) \ + fatal("Couldn't establish signal handler (%d): %m", s); \ + } while (0) -#if PPPOE_SUPPORT -int -pppWriteOverEthernet(int pd, const u_char *s, int n) -{ - PPPControl *pc = &pppControl[pd]; - struct pbuf *pb; + sa.sa_mask = signals_handled; + sa.sa_flags = 0; + SIGNAL(SIGHUP, hup); /* Hangup */ + SIGNAL(SIGINT, term); /* Interrupt */ + SIGNAL(SIGTERM, term); /* Terminate */ + SIGNAL(SIGCHLD, chld); - /* skip address & flags */ - s += 2; - n -= 2; + SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ + SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ - LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } + /* + * Install a handler for other signals which would otherwise + * cause pppd to exit without cleaning up. + */ + SIGNAL(SIGABRT, bad_signal); + SIGNAL(SIGALRM, bad_signal); + SIGNAL(SIGFPE, bad_signal); + SIGNAL(SIGILL, bad_signal); + SIGNAL(SIGPIPE, bad_signal); + SIGNAL(SIGQUIT, bad_signal); + SIGNAL(SIGSEGV, bad_signal); +#ifdef SIGBUS + SIGNAL(SIGBUS, bad_signal); +#endif +#ifdef SIGEMT + SIGNAL(SIGEMT, bad_signal); +#endif +#ifdef SIGPOLL + SIGNAL(SIGPOLL, bad_signal); +#endif +#ifdef SIGPROF + SIGNAL(SIGPROF, bad_signal); +#endif +#ifdef SIGSYS + SIGNAL(SIGSYS, bad_signal); +#endif +#ifdef SIGTRAP + SIGNAL(SIGTRAP, bad_signal); +#endif +#ifdef SIGVTALRM + SIGNAL(SIGVTALRM, bad_signal); +#endif +#ifdef SIGXCPU + SIGNAL(SIGXCPU, bad_signal); +#endif +#ifdef SIGXFSZ + SIGNAL(SIGXFSZ, bad_signal); +#endif - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - - pc->lastXMit = sys_jiffies(); - - MEMCPY(pb->payload, s, n); - - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { - LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_DEVICE; - } - - snmp_add_ifoutoctets(&pc->netif, (u16_t)n); - snmp_inc_ifoutucastpkts(&pc->netif); - LINK_STATS_INC(link.xmit); - return PPPERR_NONE; -} -#endif /* PPPOE_SUPPORT */ - -/* - * Write n characters to a ppp link. - * RETURN: >= 0 Number of characters written - * -1 Failed to write to device - */ -int -pppWrite(int pd, const u_char *s, int n) -{ - PPPControl *pc = &pppControl[pd]; -#if PPPOS_SUPPORT - u_char c; - u_int fcsOut; - struct pbuf *headMB, *tailMB; -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT - if(pc->ethif) { - return pppWriteOverEthernet(pd, s, n); - } -#endif /* PPPOE_SUPPORT */ - -#if PPPOS_SUPPORT - headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (headMB == NULL) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - tailMB = headMB; - - /* If the link has been idle, we'll send a fresh flag character to - * flush any noise. */ - if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - } - pc->lastXMit = sys_jiffies(); - - fcsOut = PPP_INITFCS; - /* Load output buffer. */ - while (n-- > 0) { - c = *s++; - - /* Update FCS before checking for special characters. */ - fcsOut = PPP_FCS(fcsOut, c); - - /* Copy to output buffer escaping special characters. */ - tailMB = pppAppend(c, tailMB, &pc->outACCM); - } - - /* Add FCS and trailing flag. */ - c = ~fcsOut & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - c = (~fcsOut >> 8) & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - - /* If we failed to complete the packet, throw it away. - * Otherwise send it. */ - if (!tailMB) { - PPPDEBUG(LOG_WARNING, - ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); - /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ - pbuf_free(headMB); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len)); - /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ - nPut(pc, headMB); -#endif /* PPPOS_SUPPORT */ - - return PPPERR_NONE; + /* + * Apparently we can get a SIGPIPE when we call syslog, if + * syslogd has died and been restarted. Ignoring it seems + * be sufficient. + */ + signal(SIGPIPE, SIG_IGN); } /* - * ppp_send_config - configure the transmit characteristics of - * the ppp interface. + * set_ifunit - do things we need to do once we know which ppp + * unit we are using. */ void -ppp_send_config( int unit, u16_t mtu, u32_t asyncmap, int pcomp, int accomp) +set_ifunit(iskey) + int iskey; { - PPPControl *pc = &pppControl[unit]; - int i; - - pc->mtu = mtu; - pc->pcomp = pcomp; - pc->accomp = accomp; - - /* Load the ACCM bits for the 32 control codes. */ - for (i = 0; i < 32/8; i++) { - pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF); - } - PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", - unit, - pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); + info("Using interface %s%d", PPP_DRV_NAME, ifunit); + slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); + script_setenv("IFNAME", ifname, iskey); + if (iskey) { + create_pidfile(getpid()); /* write pid to file */ + create_linkpidfile(getpid()); + } } - /* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. + * detach - detach us from the controlling terminal. */ void -ppp_set_xaccm(int unit, ext_accm *accm) +detach() { - SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm)); - PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n", - unit, - pppControl[unit].outACCM[0], - pppControl[unit].outACCM[1], - pppControl[unit].outACCM[2], - pppControl[unit].outACCM[3])); + int pid; + char numbuf[16]; + int pipefd[2]; + + if (detached) + return; + if (pipe(pipefd) == -1) + pipefd[0] = pipefd[1] = -1; + if ((pid = fork()) < 0) { + error("Couldn't detach (fork failed: %m)"); + die(1); /* or just return? */ + } + if (pid != 0) { + /* parent */ + notify(pidchange, pid); + /* update pid files if they have been written already */ + if (pidfilename[0]) + create_pidfile(pid); + if (linkpidfile[0]) + create_linkpidfile(pid); + exit(0); /* parent dies */ + } + setsid(); + chdir("/"); + dup2(fd_devnull, 0); + dup2(fd_devnull, 1); + dup2(fd_devnull, 2); + detached = 1; + if (log_default) + log_to_fd = -1; + slprintf(numbuf, sizeof(numbuf), "%d", getpid()); + script_setenv("PPPD_PID", numbuf, 1); + + /* wait for parent to finish updating pid & lock files and die */ + close(pipefd[1]); + complete_read(pipefd[0], numbuf, 1); + close(pipefd[0]); } +/* + * reopen_log - (re)open our connection to syslog. + */ +void +reopen_log() +{ + openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); + setlogmask(LOG_UPTO(LOG_INFO)); +} + +/* + * Create a file containing our process ID. + */ +static void +create_pidfile(pid) + int pid; +{ + FILE *pidfile; + + slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid", + _PATH_VARRUN, ifname); + if ((pidfile = fopen(pidfilename, "w")) != NULL) { + fprintf(pidfile, "%d\n", pid); + (void) fclose(pidfile); + } else { + error("Failed to create pid file %s: %m", pidfilename); + pidfilename[0] = 0; + } +} + +void +create_linkpidfile(pid) + int pid; +{ + FILE *pidfile; + + if (linkname[0] == 0) + return; + script_setenv("LINKNAME", linkname, 1); + slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid", + _PATH_VARRUN, linkname); + if ((pidfile = fopen(linkpidfile, "w")) != NULL) { + fprintf(pidfile, "%d\n", pid); + if (ifname[0]) + fprintf(pidfile, "%s\n", ifname); + (void) fclose(pidfile); + } else { + error("Failed to create pid file %s: %m", linkpidfile); + linkpidfile[0] = 0; + } +} + +/* + * remove_pidfile - remove our pid files + */ +void remove_pidfiles() +{ + if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) + warn("unable to delete pid file %s: %m", pidfilename); + pidfilename[0] = 0; + if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) + warn("unable to delete pid file %s: %m", linkpidfile); + linkpidfile[0] = 0; +} + +/* + * holdoff_end - called via a timeout when the holdoff period ends. + */ +static void +holdoff_end(arg) + 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" }, + { 0x51, "KNX Bridging Data" }, + { 0x53, "Encryption" }, + { 0x55, "Individual Link Encryption" }, + { 0x57, "IPv6" }, + { 0x59, "PPP Muxing" }, + { 0x5b, "Vendor-Specific Network Protocol" }, + { 0x61, "RTP IPHC Full Header" }, + { 0x63, "RTP IPHC Compressed TCP" }, + { 0x65, "RTP IPHC Compressed non-TCP" }, + { 0x67, "RTP IPHC Compressed UDP 8" }, + { 0x69, "RTP IPHC Compressed RTP 8" }, + { 0x6f, "Stampede Bridging" }, + { 0x73, "MP+" }, + { 0xc1, "NTCITS IPI" }, + { 0xfb, "single-link compression" }, + { 0xfd, "Compressed Datagram" }, + { 0x0201, "802.1d Hello Packets" }, + { 0x0203, "IBM Source Routing BPDU" }, + { 0x0205, "DEC LANBridge100 Spanning Tree" }, + { 0x0207, "Cisco Discovery Protocol" }, + { 0x0209, "Netcs Twin Routing" }, + { 0x020b, "STP - Scheduled Transfer Protocol" }, + { 0x020d, "EDP - Extreme Discovery Protocol" }, + { 0x0211, "Optical Supervisory Channel Protocol" }, + { 0x0213, "Optical Supervisory Channel Protocol" }, + { 0x0231, "Luxcom" }, + { 0x0233, "Sigma Network Systems" }, + { 0x0235, "Apple Client Server Protocol" }, + { 0x0281, "MPLS Unicast" }, + { 0x0283, "MPLS Multicast" }, + { 0x0285, "IEEE p1284.4 standard - data packets" }, + { 0x0287, "ETSI TETRA Network Protocol Type 1" }, + { 0x0289, "Multichannel Flow Treatment Protocol" }, + { 0x2063, "RTP IPHC Compressed TCP No Delta" }, + { 0x2065, "RTP IPHC Context State" }, + { 0x2067, "RTP IPHC Compressed UDP 16" }, + { 0x2069, "RTP IPHC Compressed RTP 16" }, + { 0x4001, "Cray Communications Control Protocol" }, + { 0x4003, "CDPD Mobile Network Registration Protocol" }, + { 0x4005, "Expand accelerator protocol" }, + { 0x4007, "ODSICP NCP" }, + { 0x4009, "DOCSIS DLL" }, + { 0x400B, "Cetacean Network Detection Protocol" }, + { 0x4021, "Stacker LZS" }, + { 0x4023, "RefTek Protocol" }, + { 0x4025, "Fibre Channel" }, + { 0x4027, "EMIT Protocols" }, + { 0x405b, "Vendor-Specific Protocol (VSP)" }, + { 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" }, + { 0x8051, "KNX Bridging Control Protocol" }, + { 0x8053, "Encryption Control Protocol" }, + { 0x8055, "Individual Link Encryption Control Protocol" }, + { 0x8057, "IPv6 Control Protocol" }, + { 0x8059, "PPP Muxing Control Protocol" }, + { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, + { 0x806f, "Stampede Bridging Control Protocol" }, + { 0x8073, "MP+ Control Protocol" }, + { 0x80c1, "NTCITS IPI Control Protocol" }, + { 0x80fb, "Single Link Compression Control Protocol" }, + { 0x80fd, "Compression Control Protocol" }, + { 0x8207, "Cisco Discovery Protocol Control" }, + { 0x8209, "Netcs Twin Routing" }, + { 0x820b, "STP - Control Protocol" }, + { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, + { 0x8235, "Apple Client Server Protocol Control" }, + { 0x8281, "MPLSCP" }, + { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, + { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, + { 0x8289, "Multichannel Flow Treatment Protocol" }, + { 0xc021, "Link Control Protocol" }, + { 0xc023, "Password Authentication Protocol" }, + { 0xc025, "Link Quality Report" }, + { 0xc027, "Shiva Password Authentication Protocol" }, + { 0xc029, "CallBack Control Protocol (CBCP)" }, + { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, + { 0xc02d, "BAP" }, + { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, + { 0xc081, "Container Control Protocol" }, + { 0xc223, "Challenge Handshake Authentication Protocol" }, + { 0xc225, "RSA Authentication Protocol" }, + { 0xc227, "Extensible Authentication Protocol" }, + { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, + { 0xc26f, "Stampede Bridging Authorization Protocol" }, + { 0xc281, "Proprietary Authentication Protocol" }, + { 0xc283, "Proprietary Authentication Protocol" }, + { 0xc481, "Proprietary Node ID Authentication Protocol" }, + { 0, NULL }, +}; + +/* + * protocol_name - find a name for a PPP protocol. + */ +const char * +protocol_name(proto) + 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() +{ + 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) { + if (bundle_eof && multilink_master) { + notice("Last channel has disconnected"); + mp_bundle_terminated(); + return; + } + notice("Modem hangup"); + hungup = 1; + status = EXIT_HANGUP; + lcp_lowerdown(0); /* serial link is no longer available */ + link_terminated(0); + return; + } + + if (len < PPP_HDRLEN) { + dbglog("received short packet:%.*B", len, p); + return; + } + + dump_packet("rcvd", p, len); + if (snoop_recv_hook) snoop_recv_hook(p, len); + + 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) { + dbglog("Discarded non-LCP packet when LCP not open"); + return; + } + + /* + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if (phase <= PHASE_AUTHENTICATE + && !(protocol == PPP_LCP || protocol == PPP_LQR + || protocol == PPP_PAP || protocol == PPP_CHAP || + protocol == PPP_EAP)) { + dbglog("discarding proto 0x%x in phase %d", + protocol, phase); + return; + } + + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + (*protp->input)(0, p, len); + return; + } + if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag + && protp->datainput != NULL) { + (*protp->datainput)(0, p, len); + return; + } + } + + if (debug) { + 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); +} + +/* + * ppp_send_config - configure the transmit-side characteristics of + * the ppp interface. Returns -1, indicating an error, if the channel + * send_config procedure called error() (or incremented error_count + * itself), otherwise 0. + */ +int +old_ppp_send_config(unit, mtu, accm, pcomp, accomp) + int unit, mtu; + u_int32_t accm; + int pcomp, accomp; +{ + int errs; + + if (the_channel->send_config == NULL) + return 0; + errs = error_count; + (*the_channel->send_config)(mtu, accm, pcomp, accomp); + return (error_count != errs)? -1: 0; +} /* * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. + * the ppp interface. Returns -1, indicating an error, if the channel + * recv_config procedure called error() (or incremented error_count + * itself), otherwise 0. + */ +int +old_ppp_recv_config(unit, mru, accm, pcomp, accomp) + int unit, mru; + u_int32_t accm; + int pcomp, accomp; +{ + int errs; + + if (the_channel->recv_config == NULL) + return 0; + errs = error_count; + (*the_channel->recv_config)(mru, accm, pcomp, accomp); + return (error_count != errs)? -1: 0; +} + +/* + * new_phase - signal the start of a new phase of pppd's operation. */ void -ppp_recv_config( int unit, int mru, u32_t asyncmap, int pcomp, int accomp) +new_phase(p) + int p; { - PPPControl *pc = &pppControl[unit]; - int i; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_UNUSED_ARG(accomp); - LWIP_UNUSED_ARG(pcomp); - LWIP_UNUSED_ARG(mru); - - /* Load the ACCM bits for the 32 control codes. */ - SYS_ARCH_PROTECT(lev); - for (i = 0; i < 32 / 8; i++) { - /* @todo: does this work? ext_accm has been modified from pppd! */ - pc->rx.inACCM[i] = (u_char)(asyncmap >> (i * 8)); - } - SYS_ARCH_UNPROTECT(lev); - PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", - unit, - pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); + phase = p; + if (new_phase_hook) + (*new_phase_hook)(p); + notify(phasechange, p); } +/* + * die - clean up state and exit with the specified status. + */ +void +die(status) + int status; +{ + if (!doing_multilink || multilink_master) + print_link_stats(); + cleanup(); + notify(exitnotify, status); + syslog(LOG_INFO, "Exit."); + exit(status); +} + +/* + * cleanup - restore anything which needs to be restored before we exit + */ +/* ARGSUSED */ +static void +cleanup() +{ + sys_cleanup(); + + if (fd_ppp >= 0) + the_channel->disestablish_ppp(devfd); + if (the_channel->cleanup) + (*the_channel->cleanup)(); + remove_pidfiles(); + +#ifdef USE_TDB + if (pppdb != NULL) + cleanup_db(); +#endif + +} + +void +print_link_stats() +{ + /* + * Print connect time and statistics. + */ + if (link_stats_valid) { + int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ + info("Connect time %d.%d minutes.", t/10, t%10); + info("Sent %u bytes, received %u bytes.", + link_stats.bytes_out, link_stats.bytes_in); + link_stats_valid = 0; + } +} + +/* + * reset_link_stats - "reset" stats when link goes up. + */ +void +reset_link_stats(u) + int u; +{ + if (!get_ppp_stats(u, &old_link_stats)) + return; + gettimeofday(&start_time, NULL); +} + +/* + * update_link_stats - get stats at link termination. + */ +void +update_link_stats(u) + 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; + + link_stats.bytes_in -= old_link_stats.bytes_in; + link_stats.bytes_out -= old_link_stats.bytes_out; + link_stats.pkts_in -= old_link_stats.pkts_in; + link_stats.pkts_out -= old_link_stats.pkts_out; + + slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time); + script_setenv("CONNECT_TIME", numbuf, 0); + slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out); + script_setenv("BYTES_SENT", numbuf, 0); + slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in); + script_setenv("BYTES_RCVD", numbuf, 0); +} + + +struct callout { + struct timeval c_time; /* time at which to call routine */ + void *c_arg; /* argument to routine */ + void (*c_func) __P((void *)); /* routine */ + struct callout *c_next; +}; + +static struct callout *callout = NULL; /* Callout list */ +static struct timeval timenow; /* Current time */ + #if 0 /* - * 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, int opt_len, int for_transmit, u_char *opt_ptr) -{ - return 0; /* XXX Currently no compression. */ -} - -/* - * ccp_flags_set - inform kernel about the current state of CCP. + * timeout - Schedule a timeout. */ void -ccp_flags_set(int unit, int isopen, int isup) +timeout(func, arg, secs, usecs) + void (*func) __P((void *)); + void *arg; + int secs, usecs; { - /* XXX */ + struct callout *newp, *p, **pp; + + /* + * 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 + secs; + newp->c_time.tv_usec = timenow.tv_usec + usecs; + if (newp->c_time.tv_usec >= 1000000) { + newp->c_time.tv_sec += newp->c_time.tv_usec / 1000000; + newp->c_time.tv_usec %= 1000000; + } + + /* + * 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; } + /* - * 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. + * untimeout - Unschedule a timeout. */ -int -ccp_fatal_error(int unit) +void +untimeout(func, arg) + void (*func) __P((void *)); + void *arg; { - /* XXX */ - return 0; + struct callout **copp, *freep; + + /* + * 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; + } } #endif /* - * get_idle_time - return how long the link has been idle. + * calltimeout - Call any timeout routines which are now due. */ -int -get_idle_time(int u, struct ppp_idle *ip) +static void +calltimeout() { - /* XXX */ - LWIP_UNUSED_ARG(u); - LWIP_UNUSED_ARG(ip); + struct callout *p; - return 0; + 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); + } } /* - * 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. + * timeleft - return the length of time until the next timeout is due. */ -u32_t -GetMask(u32_t addr) +static struct timeval * +timeleft(tvp) + struct timeval *tvp; { - u32_t mask, nmask; + if (callout == NULL) + return NULL; - addr = htonl(addr); - if (IP_CLASSA(addr)) { /* determine network mask for address class */ - nmask = IP_CLASSA_NET; - } else if (IP_CLASSB(addr)) { - nmask = IP_CLASSB_NET; - } else { - nmask = IP_CLASSC_NET; - } + 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; - /* class D nets are disallowed by bad_ip_adrs */ - mask = PP_HTONL(0xffffff00UL) | htonl(nmask); - - /* XXX - * Scan through the system's network interfaces. - * Get each netmask and OR them into our mask. - */ - - return mask; -} - -/* - * sifvjcomp - config tcp header compression - */ -int -sifvjcomp(int pd, int vjcomp, u8_t cidcomp, u8_t maxcid) -{ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPControl *pc = &pppControl[pd]; - - pc->vjEnabled = vjcomp; - pc->vjComp.compressSlot = cidcomp; - pc->vjComp.maxSlotIndex = maxcid; - PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", - vjcomp, cidcomp, maxcid)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - LWIP_UNUSED_ARG(pd); - LWIP_UNUSED_ARG(vjcomp); - LWIP_UNUSED_ARG(cidcomp); - LWIP_UNUSED_ARG(maxcid); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - - return 0; -} - -/* - * pppifNetifInit - netif init callback - */ -static err_t -pppifNetifInit(struct netif *netif) -{ - netif->name[0] = 'p'; - netif->name[1] = 'p'; - netif->output = pppifOutput; - netif->mtu = pppMTU((int)(size_t)netif->state); - netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; -#if LWIP_NETIF_HOSTNAME - /* @todo: Initialize interface hostname */ - /* netif_set_hostname(netif, "lwip"); */ -#endif /* LWIP_NETIF_HOSTNAME */ - return ERR_OK; + return tvp; } /* - * sifup - Config the interface up and enable IP packets to pass. + * kill_my_pg - send a signal to our process group, and ignore it ourselves. + * We assume that sig is currently blocked. */ -int -sifup(int pd) +static void +kill_my_pg(sig) + int sig; { - PPPControl *pc = &pppControl[pd]; - int st = 1; - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - netif_remove(&pc->netif); - if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, - &pc->addrs.his_ipaddr, (void *)(size_t)pd, pppifNetifInit, ip_input)) { - netif_set_up(&pc->netif); - pc->if_up = 1; - pc->errCode = PPPERR_NONE; + struct sigaction act, oldact; + struct subprocess *chp; - PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); - } + if (!detached) { + /* + * There might be other things in our process group that we + * didn't start that would get hit if we did a kill(0), so + * just send the signal individually to our children. + */ + for (chp = children; chp != NULL; chp = chp->next) + if (chp->killable) + kill(chp->pid, sig); + return; + } + + /* We've done a setsid(), so we can just use a kill(0) */ + sigemptyset(&act.sa_mask); /* unnecessary in fact */ + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + kill(0, sig); + /* + * The kill() above made the signal pending for us, as well as + * the rest of our process group, but we don't want it delivered + * to us. It is blocked at the moment. Setting it to be ignored + * will cause the pending signal to be discarded. If we did the + * kill() after setting the signal to be ignored, it is unspecified + * (by POSIX) whether the signal is immediately discarded or left + * pending, and in fact Linux would leave it pending, and so it + * would be delivered after the current signal handler exits, + * leading to an infinite loop. + */ + sigaction(sig, &act, &oldact); + sigaction(sig, &oldact, NULL); +} + + +/* + * hup - Catch SIGHUP signal. + * + * Indicates that the physical layer has been disconnected. + * We don't rely on this indication; if the user has sent this + * signal, we just take the link down. + */ +static void +hup(sig) + int sig; +{ + /* can't log a message here, it can deadlock */ + got_sighup = 1; + if (conn_running) + /* Send the signal to the [dis]connector process(es) also */ + kill_my_pg(sig); + notify(sigreceived, sig); + if (waiting) + siglongjmp(sigjmp, 1); +} + + +/* + * term - Catch SIGTERM signal and SIGINT signal (^C/del). + * + * Indicates that we should initiate a graceful disconnect and exit. + */ +/*ARGSUSED*/ +static void +term(sig) + int sig; +{ + /* can't log a message here, it can deadlock */ + got_sigterm = sig; + if (conn_running) + /* Send the signal to the [dis]connector process(es) also */ + kill_my_pg(sig); + notify(sigreceived, sig); + if (waiting) + siglongjmp(sigjmp, 1); +} + + +/* + * chld - Catch SIGCHLD signal. + * Sets a flag so we will call reap_kids in the mainline. + */ +static void +chld(sig) + int sig; +{ + got_sigchld = 1; + if (waiting) + siglongjmp(sigjmp, 1); +} + + +/* + * toggle_debug - Catch SIGUSR1 signal. + * + * Toggle debug flag. + */ +/*ARGSUSED*/ +static void +toggle_debug(sig) + int sig; +{ + debug = !debug; + if (debug) { + setlogmask(LOG_UPTO(LOG_DEBUG)); } else { - st = 0; - PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pd)); + setlogmask(LOG_UPTO(LOG_WARNING)); } - } - - return st; } + /* - * sifnpmode - Set the mode for handling packets for a given NP. + * open_ccp - Catch SIGUSR2 signal. + * + * Try to (re)negotiate compression. */ -int -sifnpmode(int u, int proto, enum NPmode mode) -{ - LWIP_UNUSED_ARG(u); - LWIP_UNUSED_ARG(proto); - LWIP_UNUSED_ARG(mode); - return 0; -} - -/* - * sifdown - Config the interface down and disable IP. - */ -int -sifdown(int pd) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", pd)); - } else { - pc->if_up = 0; - /* make sure the netif status callback is called */ - netif_set_down(&pc->netif); - netif_remove(&pc->netif); - PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL); - } - } - return st; -} - -/** - * sifaddr - Config the interface IP addresses and netmask. - * @param pd Interface unit ??? - * @param o Our IP address ??? - * @param h His IP address ??? - * @param m IP subnet mask ??? - * @param ns1 Primary DNS - * @param ns2 Secondary DNS - */ -int -sifaddr( int pd, u32_t o, u32_t h, u32_t m, u32_t ns1, u32_t ns2) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - SMEMCPY(&pc->addrs.our_ipaddr, &o, sizeof(o)); - SMEMCPY(&pc->addrs.his_ipaddr, &h, sizeof(h)); - SMEMCPY(&pc->addrs.netmask, &m, sizeof(m)); - SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); - SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); - } - return st; -} - -/** - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - * @param pd Interface unit ??? - * @param o Our IP address ??? - * @param h IP broadcast address ??? - */ -int -cifaddr( int pd, u32_t o, u32_t h) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - LWIP_UNUSED_ARG(o); - LWIP_UNUSED_ARG(h); - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); - IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); - IP4_ADDR(&pc->addrs.netmask, 255,255,255,0); - IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); - IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); - } - return st; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ -int -sifdefaultroute(int pd, u32_t l, u32_t g) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - LWIP_UNUSED_ARG(l); - LWIP_UNUSED_ARG(g); - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - netif_set_default(&pc->netif); - } - - /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */ - - return st; -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ -int -cifdefaultroute(int pd, u32_t l, u32_t g) -{ - PPPControl *pc = &pppControl[pd]; - int st = 1; - - LWIP_UNUSED_ARG(l); - LWIP_UNUSED_ARG(g); - - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); - } else { - netif_set_default(NULL); - } - - return st; -} - -/**********************************/ -/*** LOCAL FUNCTION DEFINITIONS ***/ -/**********************************/ - -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD -/* The main PPP process function. This implements the state machine according - * to section 4 of RFC 1661: The Point-To-Point Protocol. */ +/*ARGSUSED*/ static void -pppInputThread(void *arg) +open_ccp(sig) + int sig; { - int count; - PPPControlRx *pcrx = arg; + got_sigusr2 = 1; + if (waiting) + siglongjmp(sigjmp, 1); +} - while (lcp_phase[pcrx->pd] != PHASE_DEAD) { - count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); - if(count > 0) { - pppInProc(pcrx, pcrx->rxbuf, count); + +/* + * bad_signal - We've caught a fatal signal. Clean up state and exit. + */ +static void +bad_signal(sig) + int sig; +{ + static int crashed = 0; + + if (crashed) + _exit(127); + crashed = 1; + error("Fatal signal %d", sig); + if (conn_running) + kill_my_pg(SIGTERM); + notify(sigreceived, sig); + die(127); +} + +/* + * safe_fork - Create a child process. The child closes all the + * file descriptors that we don't want to leak to a script. + * The parent waits for the child to do this before returning. + * This also arranges for the specified fds to be dup'd to + * fds 0, 1, 2 in the child. + */ +pid_t +safe_fork(int infd, int outfd, int errfd) +{ + pid_t pid; + int fd, pipefd[2]; + char buf[1]; + + /* make sure fds 0, 1, 2 are occupied (probably not necessary) */ + while ((fd = dup(fd_devnull)) >= 0) { + if (fd > 2) { + close(fd); + break; + } + } + + if (pipe(pipefd) == -1) + pipefd[0] = pipefd[1] = -1; + pid = fork(); + if (pid < 0) { + error("fork failed: %m"); + return -1; + } + if (pid > 0) { + /* parent */ + close(pipefd[1]); + /* this read() blocks until the close(pipefd[1]) below */ + complete_read(pipefd[0], buf, 1); + close(pipefd[0]); + return pid; + } + + /* Executing in the child */ + sys_close(); +#ifdef USE_TDB + tdb_close(pppdb); +#endif + + /* make sure infd, outfd and errfd won't get tromped on below */ + if (infd == 1 || infd == 2) + infd = dup(infd); + if (outfd == 0 || outfd == 2) + outfd = dup(outfd); + if (errfd == 0 || errfd == 1) + errfd = dup(errfd); + + closelog(); + + /* dup the in, out, err fds to 0, 1, 2 */ + if (infd != 0) + dup2(infd, 0); + if (outfd != 1) + dup2(outfd, 1); + if (errfd != 2) + dup2(errfd, 2); + + if (log_to_fd > 2) + close(log_to_fd); + if (the_channel->close) + (*the_channel->close)(); + else + close(devfd); /* some plugins don't have a close function */ + close(fd_ppp); + close(fd_devnull); + if (infd != 0) + close(infd); + if (outfd != 1) + close(outfd); + if (errfd != 2) + close(errfd); + + notify(fork_notifier, 0); + close(pipefd[0]); + /* this close unblocks the read() call above in the parent */ + close(pipefd[1]); + + return 0; +} + +/* + * device_script - run a program to talk to the specified fds + * (e.g. to run the connector or disconnector script). + * stderr gets connected to the log fd or to the _PATH_CONNERRS file. + */ +int +device_script(program, in, out, dont_wait) + char *program; + int in, out; + int dont_wait; +{ + int pid; + int status = -1; + int errfd; + + if (log_to_fd >= 0) + errfd = log_to_fd; + else + errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); + + ++conn_running; + pid = safe_fork(in, out, errfd); + + if (pid != 0 && log_to_fd < 0) + close(errfd); + + if (pid < 0) { + --conn_running; + error("Failed to create child process: %m"); + return -1; + } + + if (pid != 0) { + record_child(pid, program, NULL, NULL, 1); + status = 0; + if (!dont_wait) { + while (waitpid(pid, &status, 0) < 0) { + if (errno == EINTR) + continue; + fatal("error waiting for (dis)connection process: %m"); + } + forget_child(pid, status); + --conn_running; + } + return (status == 0 ? 0 : -1); + } + + /* here we are executing in the child */ + + setgid(getgid()); + setuid(uid); + if (getuid() != uid) { + fprintf(stderr, "pppd: setuid failed\n"); + exit(1); + } + execl("/bin/sh", "sh", "-c", program, (char *)0); + perror("pppd: could not exec /bin/sh"); + exit(99); + /* NOTREACHED */ +} + + +/* + * run_program - execute a program with given arguments, + * but don't wait for it unless wait is non-zero. + * If the program can't be executed, logs an error unless + * must_exist is 0 and the program file doesn't exist. + * Returns -1 if it couldn't fork, 0 if the file doesn't exist + * or isn't an executable plain file, or the process ID of the child. + * If done != NULL, (*done)(arg) will be called later (within + * reap_kids) iff the return value is > 0. + */ +pid_t +run_program(prog, args, must_exist, done, arg, wait) + char *prog; + char **args; + int must_exist; + void (*done) __P((void *)); + void *arg; + int wait; +{ + int pid, status; + struct stat sbuf; + + printf("REMOVEME: run_program() called\n"); + return -1; + + /* + * First check if the file exists and is executable. + * We don't use access() because that would use the + * real user-id, which might not be root, and the script + * might be accessible only to root. + */ + errno = EINVAL; + if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode) + || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { + if (must_exist || errno != ENOENT) + warn("Can't execute %s: %m", prog); + return 0; + } + + pid = safe_fork(fd_devnull, fd_devnull, fd_devnull); + if (pid == -1) { + error("Failed to create child process for %s: %m", prog); + return -1; + } + if (pid != 0) { + if (debug) + dbglog("Script %s started (pid %d)", prog, pid); + record_child(pid, prog, done, arg, 0); + if (wait) { + while (waitpid(pid, &status, 0) < 0) { + if (errno == EINTR) + continue; + fatal("error waiting for script %s: %m", prog); + } + forget_child(pid, status); + } + return pid; + } + + /* Leave the current location */ + (void) setsid(); /* No controlling tty. */ + (void) umask (S_IRWXG|S_IRWXO); + (void) chdir ("/"); /* no current directory. */ + setuid(0); /* set real UID = root */ + setgid(getegid()); + +#ifdef BSD + /* Force the priority back to zero if pppd is running higher. */ + if (setpriority (PRIO_PROCESS, 0, 0) < 0) + warn("can't reset priority to 0: %m"); +#endif + + /* run the program */ + execve(prog, args, script_env); + if (must_exist || errno != ENOENT) { + /* have to reopen the log, there's nowhere else + for the message to go. */ + reopen_log(); + syslog(LOG_ERR, "Can't execute %s: %m", prog); + closelog(); + } + _exit(-1); +} + + +/* + * record_child - add a child process to the list for reap_kids + * to use. + */ +void +record_child(pid, prog, done, arg, killable) + int pid; + char *prog; + void (*done) __P((void *)); + void *arg; + int killable; +{ + struct subprocess *chp; + + ++n_children; + + chp = (struct subprocess *) malloc(sizeof(struct subprocess)); + if (chp == NULL) { + warn("losing track of %s process", prog); } else { - /* nothing received, give other tasks a chance to run */ - sys_msleep(1); + chp->pid = pid; + chp->prog = prog; + chp->done = done; + chp->arg = arg; + chp->next = children; + chp->killable = killable; + children = chp; } - } -} -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ - -#if PPPOE_SUPPORT - -void -pppOverEthernetInitFailed(int pd) -{ - PPPControl* pc; - - pppHup(pd); - pppStop(pd); - - pc = &pppControl[pd]; - pppoe_destroy(&pc->netif); - pc->openFlag = 0; - - if(pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); - } -} - -static void -pppOverEthernetLinkStatusCB(int pd, int up) -{ - if(up) { - PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); - pppStart(pd); - } else { - pppOverEthernetInitFailed(pd); - } -} -#endif /* PPPOE_SUPPORT */ - -struct pbuf * -pppSingleBuf(struct pbuf *p) -{ - struct pbuf *q, *b; - u_char *pl; - - if(p->tot_len == p->len) { - return p; - } - - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if(!q) { - PPPDEBUG(LOG_ERR, - ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); - return p; /* live dangerously */ - } - - for(b = p, pl = q->payload; b != NULL; b = b->next) { - MEMCPY(pl, b->payload, b->len); - pl += b->len; - } - - pbuf_free(p); - - return q; -} - -/** Input helper struct, must be packed since it is stored to pbuf->payload, - * which might be unaligned. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppInputHeader { - PACK_STRUCT_FIELD(int unit); - PACK_STRUCT_FIELD(u16_t proto); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* - * Pass the processed input packet to the appropriate handler. - * This function and all handlers run in the context of the tcpip_thread - */ -static void -pppInput(void *arg) -{ - struct pbuf *nb = (struct pbuf *)arg; - u16_t protocol; - int pd; - - pd = ((struct pppInputHeader *)nb->payload)->unit; - protocol = ((struct pppInputHeader *)nb->payload)->proto; - - if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } - - LINK_STATS_INC(link.recv); - snmp_inc_ifinucastpkts(&pppControl[pd].netif); - snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); - - /* - * Toss all non-LCP packets unless LCP is OPEN. - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { - if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || - (lcp_phase[pd] != PHASE_AUTHENTICATE)) { - PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); - goto drop; - } - } - - switch(protocol) { - case PPP_VJC_COMP: /* VJ compressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", - pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - break; - - default: { - struct protent *protp; - int i; - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); - nb = pppSingleBuf(nb); - (*protp->input)(pd, nb->payload, nb->len); - PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); - goto out; - } - } - - /* No handler for this protocol so reject the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); - if (pbuf_header(nb, sizeof(protocol))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } -#if BYTE_ORDER == LITTLE_ENDIAN - protocol = htons(protocol); -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - SMEMCPY(nb->payload, &protocol, sizeof(protocol)); - lcp_sprotrej(pd, nb->payload, nb->len); - } - break; - } - -drop: - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); - -out: - pbuf_free(nb); - return; -} - -#if PPPOS_SUPPORT -/* - * Drop the input packet. - */ -static void -pppFreeCurrentInputPacket(PPPControlRx *pcrx) -{ - if (pcrx->inHead != NULL) { - if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) { - pbuf_free(pcrx->inTail); - } - pbuf_free(pcrx->inHead); - pcrx->inHead = NULL; - } - pcrx->inTail = NULL; } /* - * Drop the input packet and increase error counters. + * childwait_end - we got fed up waiting for the child processes to + * exit, send them all a SIGTERM. */ static void -pppDrop(PPPControlRx *pcrx) +childwait_end(arg) + void *arg; { - if (pcrx->inHead != NULL) { -#if 0 - PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload)); -#endif - PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead)); - } - pppFreeCurrentInputPacket(pcrx); -#if VJ_SUPPORT - vj_uncompress_err(&pppControl[pcrx->pd].vjComp); -#endif /* VJ_SUPPORT */ + struct subprocess *chp; - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); + for (chp = children; chp != NULL; chp = chp->next) { + if (debug) + dbglog("sending SIGTERM to process %d", chp->pid); + kill(chp->pid, SIGTERM); + } + childwait_done = 1; } -#if !PPP_INPROC_OWNTHREAD -/** Pass received raw characters to PPPoS to be decoded. This function is - * thread-safe and can be called from a dedicated RX-thread or from a main-loop. - * - * @param pd PPP descriptor index, returned by pppOpen() - * @param data received data - * @param len length of received data +/* + * forget_child - clean up after a dead child + */ +static void +forget_child(pid, status) + int pid, status; +{ + struct subprocess *chp, **prevp; + + for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) { + if (chp->pid == pid) { + --n_children; + *prevp = chp->next; + break; + } + } + if (WIFSIGNALED(status)) { + warn("Child process %s (pid %d) terminated with signal %d", + (chp? chp->prog: "??"), pid, WTERMSIG(status)); + } else if (debug) + dbglog("Script %s finished (pid %d), status = 0x%x", + (chp? chp->prog: "??"), pid, + WIFEXITED(status) ? WEXITSTATUS(status) : status); + if (chp && chp->done) + (*chp->done)(chp->arg); + if (chp) + free(chp); +} + +/* + * reap_kids - get status from any dead child processes, + * and log a message for abnormal terminations. + */ +static int +reap_kids() +{ + int pid, status; + + if (n_children == 0) + return 0; + while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) { + forget_child(pid, status); + } + if (pid == -1) { + if (errno == ECHILD) + return -1; + if (errno != EINTR) + error("Error waiting for child process: %m"); + } + return 0; +} + +/* + * add_notifier - add a new function to be called when something happens. */ void -pppos_input(int pd, u_char* data, int len) +add_notifier(notif, func, arg) + struct notifier **notif; + notify_func func; + void *arg; { - pppInProc(&pppControl[pd].rx, data, len); + struct notifier *np; + + np = malloc(sizeof(struct notifier)); + if (np == 0) + novm("notifier struct"); + np->next = *notif; + np->func = func; + np->arg = arg; + *notif = np; } -#endif -/** - * Process a received octet string. +/* + * remove_notifier - remove a function from the list of things to + * be called when something happens. */ -static void -pppInProc(PPPControlRx *pcrx, u_char *s, int l) +void +remove_notifier(notif, func, arg) + struct notifier **notif; + notify_func func; + void *arg; { - struct pbuf *nextNBuf; - u_char curChar; - u_char escaped; - SYS_ARCH_DECL_PROTECT(lev); + struct notifier *np; - PPPDEBUG(LOG_DEBUG, ("pppInProc[%d]: got %d bytes\n", pcrx->pd, l)); - while (l-- > 0) { - curChar = *s++; + for (; (np = *notif) != 0; notif = &np->next) { + if (np->func == func && np->arg == arg) { + *notif = np->next; + free(np); + break; + } + } +} - SYS_ARCH_PROTECT(lev); - escaped = ESCAPE_P(pcrx->inACCM, curChar); - SYS_ARCH_UNPROTECT(lev); - /* Handle special characters. */ - if (escaped) { - /* Check for escape sequences. */ - /* XXX Note that this does not handle an escaped 0x5d character which - * would appear as an escape character. Since this is an ASCII ']' - * and there is no reason that I know of to escape it, I won't complicate - * the code to handle this case. GLL */ - if (curChar == PPP_ESCAPE) { - pcrx->inEscaped = 1; - /* Check for the flag character. */ - } else if (curChar == PPP_FLAG) { - /* If this is just an extra flag character, ignore it. */ - if (pcrx->inState <= PDADDRESS) { - /* ignore it */; - /* If we haven't received the packet header, drop what has come in. */ - } else if (pcrx->inState < PDDATA) { - PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Dropping incomplete packet %d\n", - pcrx->pd, pcrx->inState)); - LINK_STATS_INC(link.lenerr); - pppDrop(pcrx); - /* If the fcs is invalid, drop the packet. */ - } else if (pcrx->inFCS != PPP_GOODFCS) { - PPPDEBUG(LOG_INFO, - ("pppInProc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", - pcrx->pd, pcrx->inFCS, pcrx->inProtocol)); - /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ - LINK_STATS_INC(link.chkerr); - pppDrop(pcrx); - /* Otherwise it's a good packet so pass it on. */ - } else { - struct pbuf *inp; - /* Trim off the checksum. */ - if(pcrx->inTail->len > 2) { - pcrx->inTail->len -= 2; +/* + * notify - call a set of functions registered with add_notifier. + */ +void +notify(notif, val) + struct notifier *notif; + int val; +{ + struct notifier *np; - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); - } - } else { - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); - } + while ((np = notif) != 0) { + notif = np->next; + (*np->func)(np->arg, val); + } +} - pbuf_realloc(pcrx->inHead, pcrx->inHead->tot_len - 2); - } +/* + * novm - log an error message saying we ran out of memory, and die. + */ +void +novm(msg) + char *msg; +{ + fatal("Virtual memory exhausted allocating %s\n", msg); +} - /* Dispatch the packet thereby consuming it. */ - inp = pcrx->inHead; - /* Packet consumed, release our references. */ - pcrx->inHead = NULL; - pcrx->inTail = NULL; -#if PPP_INPROC_MULTITHREADED - if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); - pbuf_free(inp); - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); - } -#else /* PPP_INPROC_MULTITHREADED */ - pppInput(inp); -#endif /* PPP_INPROC_MULTITHREADED */ - } +/* + * script_setenv - set an environment variable value to be used + * for scripts that we run (e.g. ip-up, auth-up, etc.) + */ +void +script_setenv(var, value, iskey) + char *var, *value; + int iskey; +{ + size_t varl = strlen(var); + size_t vl = varl + strlen(value) + 2; + int i; + char *p, *newstring; - /* Prepare for a new packet. */ - pcrx->inFCS = PPP_INITFCS; - pcrx->inState = PDADDRESS; - pcrx->inEscaped = 0; - /* Other characters are usually control characters that may have - * been inserted by the physical layer so here we just drop them. */ - } else { - PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, curChar)); - } - /* Process other characters. */ + newstring = (char *) malloc(vl+1); + if (newstring == 0) + return; + *newstring++ = iskey; + slprintf(newstring, vl, "%s=%s", var, value); + + /* check if this variable is already set */ + if (script_env != 0) { + for (i = 0; (p = script_env[i]) != 0; ++i) { + if (strncmp(p, var, varl) == 0 && p[varl] == '=') { +#ifdef USE_TDB + if (p[-1] && pppdb != NULL) + delete_db_key(p); +#endif + free(p-1); + script_env[i] = newstring; +#ifdef USE_TDB + if (iskey && pppdb != NULL) + add_db_key(newstring); + update_db_entry(); +#endif + return; + } + } } else { - /* Unencode escaped characters. */ - if (pcrx->inEscaped) { - pcrx->inEscaped = 0; - curChar ^= PPP_TRANS; - } - - /* Process character relative to current state. */ - switch(pcrx->inState) { - case PDIDLE: /* Idle state - waiting. */ - /* Drop the character if it's not 0xff - * we would have processed a flag character above. */ - if (curChar != PPP_ALLSTATIONS) { - break; - } - - /* Fall through */ - case PDSTART: /* Process start flag. */ - /* Prepare for a new packet. */ - pcrx->inFCS = PPP_INITFCS; - - /* Fall through */ - case PDADDRESS: /* Process address field. */ - if (curChar == PPP_ALLSTATIONS) { - pcrx->inState = PDCONTROL; - break; - } - /* Else assume compressed address and control fields so - * fall through to get the protocol... */ - case PDCONTROL: /* Process control field. */ - /* If we don't get a valid control code, restart. */ - if (curChar == PPP_UI) { - pcrx->inState = PDPROTOCOL1; - break; - } -#if 0 - else { - PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar)); - pcrx->inState = PDSTART; - } -#endif - case PDPROTOCOL1: /* Process protocol field 1. */ - /* If the lower bit is set, this is the end of the protocol - * field. */ - if (curChar & 1) { - pcrx->inProtocol = curChar; - pcrx->inState = PDDATA; - } else { - pcrx->inProtocol = (u_int)curChar << 8; - pcrx->inState = PDPROTOCOL2; - } - break; - case PDPROTOCOL2: /* Process protocol field 2. */ - pcrx->inProtocol |= curChar; - pcrx->inState = PDDATA; - break; - case PDDATA: /* Process data byte. */ - /* Make space to receive processed data. */ - if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) { - if (pcrx->inTail != NULL) { - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); - /* give up the inTail reference now */ - pcrx->inTail = NULL; - } - } - /* If we haven't started a packet, we need a packet header. */ - nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (nextNBuf == NULL) { - /* No free buffers. Drop the input packet and let the - * higher layers deal with it. Continue processing - * the received pbuf chain in case a new packet starts. */ - PPPDEBUG(LOG_ERR, ("pppInProc[%d]: NO FREE MBUFS!\n", pcrx->pd)); - LINK_STATS_INC(link.memerr); - pppDrop(pcrx); - pcrx->inState = PDSTART; /* Wait for flag sequence. */ - break; - } - if (pcrx->inHead == NULL) { - struct pppInputHeader *pih = nextNBuf->payload; - - pih->unit = pcrx->pd; - pih->proto = pcrx->inProtocol; - - nextNBuf->len += sizeof(*pih); - - pcrx->inHead = nextNBuf; - } - pcrx->inTail = nextNBuf; - } - /* Load character into buffer. */ - ((u_char*)pcrx->inTail->payload)[pcrx->inTail->len++] = curChar; - break; - } - - /* update the frame check sequence number. */ - pcrx->inFCS = PPP_FCS(pcrx->inFCS, curChar); + /* no space allocated for script env. ptrs. yet */ + i = 0; + script_env = (char **) malloc(16 * sizeof(char *)); + if (script_env == 0) + return; + s_env_nalloc = 16; } - } /* while (l-- > 0), all bytes processed */ - avRandomize(); + /* reallocate script_env with more space if needed */ + if (i + 1 >= s_env_nalloc) { + int new_n = i + 17; + char **newenv = (char **) realloc((void *)script_env, + new_n * sizeof(char *)); + if (newenv == 0) + return; + script_env = newenv; + s_env_nalloc = new_n; + } + + script_env[i] = newstring; + script_env[i+1] = 0; + +#ifdef USE_TDB + if (pppdb != NULL) { + if (iskey) + add_db_key(newstring); + update_db_entry(); + } +#endif } -#endif /* PPPOS_SUPPORT */ -#if PPPOE_SUPPORT -void -pppInProcOverEthernet(int pd, struct pbuf *pb) -{ - struct pppInputHeader *pih; - u16_t inProtocol; - - if(pb->len < sizeof(inProtocol)) { - PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n")); - goto drop; - } - - inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - - /* make room for pppInputHeader - should not fail */ - if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { - PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n")); - goto drop; - } - - pih = pb->payload; - - pih->unit = pd; - pih->proto = inProtocol; - - /* Dispatch the packet thereby consuming it. */ - pppInput(pb); - return; - -drop: - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); - pbuf_free(pb); - return; -} -#endif /* PPPOE_SUPPORT */ - -#if LWIP_NETIF_STATUS_CALLBACK -/** Set the status callback of a PPP's netif - * - * @param pd The PPP descriptor returned by pppOpen() - * @param status_callback pointer to the status callback function - * - * @see netif_set_status_callback +/* + * script_unsetenv - remove a variable from the environment + * for scripts. */ void -ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback) +script_unsetenv(var) + char *var; { - netif_set_status_callback(&pppControl[pd].netif, status_callback); -} -#endif /* LWIP_NETIF_STATUS_CALLBACK */ + int vl = strlen(var); + int i; + char *p; -#if LWIP_NETIF_LINK_CALLBACK -/** Set the link callback of a PPP's netif - * - * @param pd The PPP descriptor returned by pppOpen() - * @param link_callback pointer to the link callback function - * - * @see netif_set_link_callback + if (script_env == 0) + return; + for (i = 0; (p = script_env[i]) != 0; ++i) { + if (strncmp(p, var, vl) == 0 && p[vl] == '=') { +#ifdef USE_TDB + if (p[-1] && pppdb != NULL) + delete_db_key(p); +#endif + free(p-1); + while ((script_env[i] = script_env[i+1]) != 0) + ++i; + break; + } + } +#ifdef USE_TDB + if (pppdb != NULL) + update_db_entry(); +#endif +} + +/* + * Any arbitrary string used as a key for locking the database. + * It doesn't matter what it is as long as all pppds use the same string. */ -void -ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback) -{ - netif_set_link_callback(&pppControl[pd].netif, link_callback); -} -#endif /* LWIP_NETIF_LINK_CALLBACK */ +#define PPPD_LOCK_KEY "pppd lock" -#endif /* PPP_SUPPORT */ +/* + * lock_db - get an exclusive lock on the TDB database. + * Used to ensure atomicity of various lookup/modify operations. + */ +void lock_db() +{ +#ifdef USE_TDB + TDB_DATA key; + + key.dptr = PPPD_LOCK_KEY; + key.dsize = strlen(key.dptr); + tdb_chainlock(pppdb, key); +#endif +} + +/* + * unlock_db - remove the exclusive lock obtained by lock_db. + */ +void unlock_db() +{ +#ifdef USE_TDB + TDB_DATA key; + + key.dptr = PPPD_LOCK_KEY; + key.dsize = strlen(key.dptr); + tdb_chainunlock(pppdb, key); +#endif +} + +#ifdef USE_TDB +/* + * update_db_entry - update our entry in the database. + */ +static void +update_db_entry() +{ + TDB_DATA key, dbuf; + int vlen, i; + char *p, *q, *vbuf; + + if (script_env == NULL) + return; + vlen = 0; + for (i = 0; (p = script_env[i]) != 0; ++i) + vlen += strlen(p) + 1; + vbuf = malloc(vlen + 1); + if (vbuf == 0) + novm("database entry"); + q = vbuf; + for (i = 0; (p = script_env[i]) != 0; ++i) + q += slprintf(q, vbuf + vlen - q, "%s;", p); + + key.dptr = db_key; + key.dsize = strlen(db_key); + dbuf.dptr = vbuf; + dbuf.dsize = vlen; + if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) + error("tdb_store failed: %s", tdb_errorstr(pppdb)); + + if (vbuf) + free(vbuf); + +} + +/* + * add_db_key - add a key that we can use to look up our database entry. + */ +static void +add_db_key(str) + const char *str; +{ + TDB_DATA key, dbuf; + + key.dptr = (char *) str; + key.dsize = strlen(str); + dbuf.dptr = db_key; + dbuf.dsize = strlen(db_key); + if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) + error("tdb_store key failed: %s", tdb_errorstr(pppdb)); +} + +/* + * delete_db_key - delete a key for looking up our database entry. + */ +static void +delete_db_key(str) + const char *str; +{ + TDB_DATA key; + + key.dptr = (char *) str; + key.dsize = strlen(str); + tdb_delete(pppdb, key); +} + +/* + * cleanup_db - delete all the entries we put in the database. + */ +static void +cleanup_db() +{ + TDB_DATA key; + int i; + char *p; + + key.dptr = db_key; + key.dsize = strlen(db_key); + tdb_delete(pppdb, key); + for (i = 0; (p = script_env[i]) != 0; ++i) + if (p[-1]) + delete_db_key(p); +} +#endif /* USE_TDB */ diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h deleted file mode 100644 index 08d6e62d..00000000 --- a/src/netif/ppp/ppp.h +++ /dev/null @@ -1,201 +0,0 @@ -/***************************************************************************** -* ppp.h - Network Point to Point Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ - -#ifndef PPP_H -#define PPP_H - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/sio.h" -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/sys.h" -#include "lwip/timers.h" - - -#ifndef __u_char_defined - -/* Type definitions for BSD code. */ -typedef unsigned long u_long; -typedef unsigned int u_int; -typedef unsigned short u_short; -typedef unsigned char u_char; - -#endif - - -/************************* -*** PUBLIC DEFINITIONS *** -*************************/ - -/* Error codes. */ -#define PPPERR_NONE 0 /* No error. */ -#define PPPERR_PARAM -1 /* Invalid parameter. */ -#define PPPERR_OPEN -2 /* Unable to open PPP session. */ -#define PPPERR_DEVICE -3 /* Invalid I/O device for PPP. */ -#define PPPERR_ALLOC -4 /* Unable to allocate resources. */ -#define PPPERR_USER -5 /* User interrupt. */ -#define PPPERR_CONNECT -6 /* Connection lost. */ -#define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */ -#define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */ - -/* - * PPP IOCTL commands. - */ -/* - * Get the up status - 0 for down, non-zero for up. The argument must - * point to an int. - */ -#define PPPCTLG_UPSTATUS 100 /* Get the up status - 0 down else up */ -#define PPPCTLS_ERRCODE 101 /* Set the error code */ -#define PPPCTLG_ERRCODE 102 /* Get the error code */ -#define PPPCTLG_FD 103 /* Get the fd associated with the ppp */ - -/************************ -*** PUBLIC DATA TYPES *** -************************/ - -struct ppp_addrs { - ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; -}; - - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ - -/* Initialize the PPP subsystem. */ -void pppInit(void); - -/* Warning: Using PPPAUTHTYPE_ANY might have security consequences. - * RFC 1994 says: - * - * In practice, within or associated with each PPP server, there is a - * database which associates "user" names with authentication - * information ("secrets"). It is not anticipated that a particular - * named user would be authenticated by multiple methods. This would - * make the user vulnerable to attacks which negotiate the least secure - * method from among a set (such as PAP rather than CHAP). If the same - * secret was used, PAP would reveal the secret to be used later with - * CHAP. - * - * Instead, for each user name there should be an indication of exactly - * one method used to authenticate that user name. If a user needs to - * make use of different authentication methods under different - * circumstances, then distinct user names SHOULD be employed, each of - * which identifies exactly one authentication method. - * - */ -enum pppAuthType { - PPPAUTHTYPE_NONE, - PPPAUTHTYPE_ANY, - PPPAUTHTYPE_PAP, - PPPAUTHTYPE_CHAP -}; - -void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); - -/* Link status callback function prototype */ -typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); - -#if PPPOS_SUPPORT -/* - * Open a new PPP connection using the given serial I/O device. - * This initializes the PPP control block but does not - * attempt to negotiate the LCP session. - * Return a new PPP connection descriptor on success or - * an error code (negative) on failure. - */ -int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT -/* - * Open a new PPP Over Ethernet (PPPOE) connection. - */ -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, - pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); -#endif /* PPPOE_SUPPORT */ - -/* for source code compatibility */ -#define pppOpen(fd,cb,ls) pppOverSerialOpen(fd,cb,ls) - -/* - * Close a PPP connection and release the descriptor. - * Any outstanding packets in the queues are dropped. - * Return 0 on success, an error code on failure. - */ -int pppClose(int pd); - -/* - * Indicate to the PPP process that the line has disconnected. - */ -void pppSigHUP(int pd); - -/* - * Get and set parameters for the given connection. - * Return 0 on success, an error code on failure. - */ -int pppIOCtl(int pd, int cmd, void *arg); - -/* - * Return the Maximum Transmission Unit for the given PPP connection. - */ -u_short pppMTU(int pd); - -#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD -/* - * PPP over Serial: this is the input function to be called for received data. - * If PPP_INPROC_OWNTHREAD==1, a seperate input thread using the blocking - * sio_read() is used, so this is deactivated. - */ -void pppos_input(int pd, u_char* data, int len); -#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ - - -#if LWIP_NETIF_STATUS_CALLBACK -/* Set an lwIP-style status-callback for the selected PPP device */ -void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback); -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK -/* Set an lwIP-style link-callback for the selected PPP device */ -void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback); -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#endif /* PPP_SUPPORT */ - -#endif /* PPP_H */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h deleted file mode 100644 index 89aea60b..00000000 --- a/src/netif/ppp/ppp_impl.h +++ /dev/null @@ -1,363 +0,0 @@ -/***************************************************************************** -* ppp.h - Network Point to Point Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ - -#ifndef PPP_IMPL_H -#define PPP_IMPL_H - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp.h" -#include "lwip/def.h" -#include "lwip/sio.h" -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/sys.h" -#include "lwip/timers.h" - -/** Some defines for code we skip compared to the original pppd. - * These are just here to minimise the use of the ugly "#if 0". */ -#define PPP_ADDITIONAL_CALLBACKS 0 - -/** Some error checks to test for unsupported code */ -#if CBCP_SUPPORT -#error "CBCP is not supported in lwIP PPP" -#endif -#if CCP_SUPPORT -#error "CCP is not supported in lwIP PPP" -#endif - -/* - * 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. - * - */ -/* - * ppp_defs.h - PPP definitions. - * - * 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. - */ - -#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) -#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) - - -/* - * Constants and structures defined by the internet system, - * Per RFC 790, September 1981, and numerous additions. - */ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#define PPP_COMP 0xfd /* compressed packet */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ - -/* - * Values for FCS calculations. - */ -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) - -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u_char ext_accm[32]; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * 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); (cp)++; (s) <<= 8; \ - (s) |= *(cp); (cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s & 0xff); \ -} - -#define GETLONG(l, cp) { \ - (l) = *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (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)) - -#define BCMP(s0, s1, l) memcmp((u_char *)(s0), (u_char *)(s1), (l)) -#define BCOPY(s, d, l) MEMCPY((d), (s), (l)) -#define BZERO(s, n) memset(s, 0, n) - -#if PPP_DEBUG -#define PRINTMSG(m, l) { m[l] = '\0'; LWIP_DEBUGF(LOG_INFO, ("Remote message: %s\n", m)); } -#else /* PPP_DEBUG */ -#define PRINTMSG(m, l) -#endif /* PPP_DEBUG */ - -/* - * MAKEHEADER - Add PPP Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } - -/************************ -*** PUBLIC DATA TYPES *** -************************/ - -/* - * 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); -#if PPP_ADDITIONAL_CALLBACKS - /* 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); -#endif /* PPP_ADDITIONAL_CALLBACKS */ - int enabled_flag; /* 0 if protocol is disabled */ - char *name; /* Text name of protocol */ -#if PPP_ADDITIONAL_CALLBACKS - /* Check requested options, assign defaults */ - void (*check_options) (u_long); - /* 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); -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - u_short xmit_idle; /* seconds since last NP packet sent */ - u_short recv_idle; /* seconds since last NP packet received */ -}; - -struct ppp_settings { - - u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ - u_int auth_required : 1; /* Peer is required to authenticate */ - u_int explicit_remote : 1; /* remote_name specified with remotename opt */ - u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ - u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ - u_int usehostname : 1; /* Use hostname for our_name */ - u_int usepeerdns : 1; /* Ask peer for DNS adds */ - - u_short idle_time_limit; /* Shut down link if idle for this long */ - int maxconnect; /* Maximum connect time (seconds) */ - - char user [MAXNAMELEN + 1]; /* Username for PAP */ - char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ - char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ -}; - -/***************************** -*** PUBLIC DATA STRUCTURES *** -*****************************/ - -/* Buffers for outgoing packets. */ -extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; - -extern struct ppp_settings ppp_settings; - -extern struct protent *ppp_protocols[]; /* Table of pointers to supported protocols */ - - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ - -/* - * Write n characters to a ppp link. - * RETURN: >= 0 Number of characters written, -1 Failed to write to device. - */ -int pppWrite(int pd, const u_char *s, int n); - -void pppInProcOverEthernet(int pd, struct pbuf *pb); - -struct pbuf *pppSingleBuf(struct pbuf *p); - -void pppLinkTerminated(int pd); - -void pppLinkDown(int pd); - -/* Configure i/f transmit parameters */ -void ppp_send_config (int, u16_t, u32_t, int, int); -/* Set extended transmit ACCM */ -void ppp_set_xaccm (int, ext_accm *); -/* Configure i/f receive parameters */ -void ppp_recv_config (int, int, u32_t, int, int); -/* Find out how long link has been idle */ -int get_idle_time (int, struct ppp_idle *); - -/* Configure VJ TCP header compression */ -int sifvjcomp (int, int, u8_t, u8_t); -/* Configure i/f down (for IP) */ -int sifup (int); -/* Set mode for handling packets for proto */ -int sifnpmode (int u, int proto, enum NPmode mode); -/* Configure i/f down (for IP) */ -int sifdown (int); -/* Configure IP addresses for i/f */ -int sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t); -/* Reset i/f IP addresses */ -int cifaddr (int, u32_t, u32_t); -/* Create default route through i/f */ -int sifdefaultroute (int, u32_t, u32_t); -/* Delete default route through i/f */ -int cifdefaultroute (int, u32_t, u32_t); - -/* Get appropriate netmask for address */ -u32_t GetMask (u32_t); - -#endif /* PPP_SUPPORT */ - -#endif /* PPP_IMPL_H */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index fdf52ae2..cdb448bc 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -74,11 +74,14 @@ #include "netif/ppp_oe.h" -#include "ppp_impl.h" +//#include "ppp_impl.h" #include "pppdebug.h" +#include "pppd.h" +#include "pppmy.h" #include "lwip/timers.h" #include "lwip/memp.h" +#include "lwip/stats.h" #include #include @@ -262,13 +265,13 @@ pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) /* should be safe to access *sc now */ if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { - printf("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state); + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state)); return NULL; } if (sc->sc_ethif != rcvif) { - printf("%c%c%"U16_F": wrong interface, not accepting host unique\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": wrong interface, not accepting host unique\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); return NULL; } return sc; @@ -297,14 +300,13 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) #endif struct pppoehdr *ph; struct pppoetag pt; - int off, err, errortag; + int off, err; struct eth_hdr *ethhdr; pb = pppSingleBuf(pb); strcpy(devname, "pppoe"); /* as long as we don't know which instance */ err_msg = NULL; - errortag = 0; if (pb->len < sizeof(*ethhdr)) { goto done; } @@ -319,13 +321,13 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) #endif session = 0; if (pb->len - off < PPPOE_HEADERLEN) { - printf("pppoe: packet too short: %d\n", pb->len); + PPPDEBUG(LOG_DEBUG, ("pppoe: packet too short: %d\n", pb->len)); goto done; } ph = (struct pppoehdr *) (ethhdr + 1); if (ph->vertype != PPPOE_VERTYPE) { - printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); + PPPDEBUG(LOG_DEBUG, ("pppoe: unknown version/type packet: 0x%x\n", ph->vertype)); goto done; } session = ntohs(ph->session); @@ -333,8 +335,8 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) off += sizeof(*ph); if (plen + off > pb->len) { - printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", - pb->len - off, plen); + PPPDEBUG(LOG_DEBUG, ("pppoe: packet content does not fit: data available = %d, packet size = %u\n", + pb->len - off, plen)); goto done; } if(pb->tot_len == pb->len) { @@ -348,7 +350,7 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) tag = ntohs(pt.tag); len = ntohs(pt.len); if (off + sizeof(pt) + len > pb->len) { - printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); + PPPDEBUG(LOG_DEBUG, ("pppoe: tag 0x%x len 0x%x is too long\n", tag, len)); goto done; } switch (tag) { @@ -368,7 +370,10 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) #endif sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif); if (sc != NULL) { - snprintf(devname, sizeof(devname), "%c%c%"U16_F, sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + devname[0] = sc->sc_ethif->name[0]; + devname[1] = sc->sc_ethif->name[1]; + devname[2] = sc->sc_ethif->num; + devname[3] = '\0'; } break; case PPPOE_TAG_ACCOOKIE: @@ -379,28 +384,22 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) break; case PPPOE_TAG_SNAME_ERR: err_msg = "SERVICE NAME ERROR"; - errortag = 1; break; case PPPOE_TAG_ACSYS_ERR: err_msg = "AC SYSTEM ERROR"; - errortag = 1; break; case PPPOE_TAG_GENERIC_ERR: err_msg = "GENERIC ERROR"; - errortag = 1; break; } - if (err_msg) { - if (errortag && len) { + if (NULL != err_msg) { + if (len) { u16_t error_len = LWIP_MIN(len, sizeof(pppoe_error_tmp)-1); strncpy(pppoe_error_tmp, (char*)pb->payload + off + sizeof(pt), error_len); - pppoe_error_tmp[error_len-1] = '\0'; - printf("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp); + pppoe_error_tmp[error_len] = '\0'; + PPPDEBUG(LOG_DEBUG, ("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp)); } else { - printf("%s: %s\n", devname, err_msg); - } - if (errortag) { - goto done; + PPPDEBUG(LOG_DEBUG, ("%s: %s\n", devname, err_msg)); } } off += sizeof(pt) + len; @@ -429,7 +428,7 @@ breakbreak:; } } if (sc == NULL) { - /* printf("pppoe: free passive interface is not found\n"); */ + /* PPPDEBUG(LOG_DEBUG, ("pppoe: free passive interface is not found\n")); */ goto done; } if (hunique) { @@ -455,19 +454,19 @@ breakbreak:; */ if (ac_cookie == NULL) { /* be quiet if there is not a single pppoe instance */ - printf("pppoe: received PADR but not includes ac_cookie\n"); + PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but not includes ac_cookie\n")); goto done; } sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif); if (sc == NULL) { /* be quiet if there is not a single pppoe instance */ if (!LIST_EMPTY(&pppoe_softc_list)) { - printf("pppoe: received PADR but could not find request for it\n"); + PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but could not find request for it\n")); } goto done; } if (sc->sc_state != PPPOE_STATE_PADO_SENT) { - printf("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); goto done; } if (hunique) { @@ -493,12 +492,12 @@ breakbreak:; if (sc == NULL) { /* be quiet if there is not a single pppoe instance */ if (pppoe_softc_list != NULL) { - printf("pppoe: received PADO but could not find request for it\n"); + PPPDEBUG(LOG_DEBUG, ("pppoe: received PADO but could not find request for it\n")); } goto done; } if (sc->sc_state != PPPOE_STATE_PADI_SENT) { - printf("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); goto done; } if (ac_cookie) { @@ -532,11 +531,11 @@ breakbreak:; break; default: if(sc) { - printf("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n", + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, - (u16_t)ph->code, session); + (u16_t)ph->code, session)); } else { - printf("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session); + PPPDEBUG(LOG_DEBUG, ("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session)); } break; } @@ -546,6 +545,7 @@ done: return; } +/* FIXME: is this shit really necessary, why we don't call pppoe_dispatch_disc_pkt() instead !? */ void pppoe_disc_input(struct netif *netif, struct pbuf *p) { @@ -580,18 +580,18 @@ pppoe_data_input(struct netif *netif, struct pbuf *pb) pb = pppSingleBuf (pb); if (pb->len <= PPPOE_HEADERLEN) { - printf("pppoe (data): dropping too short packet: %d bytes\n", pb->len); + PPPDEBUG(LOG_DEBUG, ("pppoe (data): dropping too short packet: %d bytes\n", pb->len)); goto drop; } if (pb->len < sizeof(*ph)) { - printf("pppoe_data_input: could not get PPPoE header\n"); + PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: could not get PPPoE header\n")); goto drop; } ph = (struct pppoehdr *)pb->payload; if (ph->vertype != PPPOE_VERTYPE) { - printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); + PPPDEBUG(LOG_DEBUG, ("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype)); goto drop; } if (ph->code != 0) { @@ -602,7 +602,7 @@ pppoe_data_input(struct netif *netif, struct pbuf *pb) sc = pppoe_find_softc_by_session(session, netif); if (sc == NULL) { #ifdef PPPOE_TERM_UNKNOWN_SESSIONS - printf("pppoe: input for unknown session 0x%x, sending PADT\n", session); + PPPDEBUG(LOG_DEBUG, ("pppoe: input for unknown session 0x%x, sending PADT\n", session)); pppoe_send_padt(netif, session, shost); #endif goto drop; @@ -818,8 +818,9 @@ pppoe_connect(struct pppoe_softc *sc) /* save state, in case we fail to send PADI */ sc->sc_state = PPPOE_STATE_PADI_SENT; sc->sc_padr_retried = 0; - err = pppoe_send_padi(sc); - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + if ((err = pppoe_send_padi(sc)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); return err; } @@ -874,7 +875,7 @@ pppoe_do_disconnect(struct pppoe_softc *sc) static void pppoe_abort_connect(struct pppoe_softc *sc) { - printf("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); sc->sc_state = PPPOE_STATE_CLOSING; sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ @@ -1096,8 +1097,8 @@ pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir) } if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); - printf("%c%c%"U16_F": ethernet interface detached, going down\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": ethernet interface detached, going down\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); } sc->sc_ethif = NULL; pppoe_clear_softc(sc, "ethernet interface detached"); diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c new file mode 100644 index 00000000..1a66f680 --- /dev/null +++ b/src/netif/ppp/pppcrypt.c @@ -0,0 +1,195 @@ +/* + * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 + * + * Extracted from chap_ms.c by James Carlson. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#include +#include "pppd.h" +#include "pppcrypt.h" + +static u_char +Get7Bits(input, startBit) +u_char *input; +int startBit; +{ + unsigned int word; + + word = (unsigned)input[startBit / 8] << 8; + word |= (unsigned)input[startBit / 8 + 1]; + + word >>= 15 - (startBit % 8 + 7); + + return word & 0xFE; +} + +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 +} + +#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; + } +} + +bool +DesSetkey(key) +u_char *key; +{ + u_char des_key[8]; + u_char crypt_key[66]; + + MakeKey(key, des_key); + Expand(des_key, crypt_key); + errno = 0; + setkey((const char *)crypt_key); + if (errno != 0) + return (0); + return (1); +} + +bool +DesEncrypt(clear, cipher) +u_char *clear; /* IN 8 octets */ +u_char *cipher; /* OUT 8 octets */ +{ + u_char des_input[66]; + + Expand(clear, des_input); + errno = 0; + encrypt((char *)des_input, 0); + if (errno != 0) + return (0); + Collapse(des_input, cipher); + return (1); +} + +bool +DesDecrypt(cipher, clear) +u_char *cipher; /* IN 8 octets */ +u_char *clear; /* OUT 8 octets */ +{ + u_char des_input[66]; + + Expand(cipher, des_input); + errno = 0; + encrypt((char *)des_input, 1); + if (errno != 0) + return (0); + Collapse(des_input, clear); + return (1); +} + +#else /* USE_CRYPT */ +static des_key_schedule key_schedule; + +bool +DesSetkey(key) +u_char *key; +{ + des_cblock des_key; + MakeKey(key, des_key); + des_set_key(&des_key, key_schedule); + return (1); +} + +bool +DesEncrypt(clear, key, cipher) +u_char *clear; /* IN 8 octets */ +u_char *cipher; /* OUT 8 octets */ +{ + des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, + key_schedule, 1); + return (1); +} + +bool +DesDecrypt(cipher, clear) +u_char *cipher; /* IN 8 octets */ +u_char *clear; /* OUT 8 octets */ +{ + des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, + key_schedule, 0); + return (1); +} + +#endif /* USE_CRYPT */ diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h new file mode 100644 index 00000000..adcdcbcb --- /dev/null +++ b/src/netif/ppp/pppcrypt.h @@ -0,0 +1,48 @@ +/* + * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 + * + * Extracted from chap_ms.c by James Carlson. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef PPPCRYPT_H +#define PPPCRYPT_H + +#ifdef HAVE_CRYPT_H +#include +#endif + +#ifndef USE_CRYPT +#include +#endif + +extern bool DesSetkey __P((u_char *)); +extern bool DesEncrypt __P((u_char *, u_char *)); +extern bool DesDecrypt __P((u_char *, u_char *)); + +#endif /* PPPCRYPT_H */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h new file mode 100644 index 00000000..e42d3318 --- /dev/null +++ b/src/netif/ppp/pppd.h @@ -0,0 +1,913 @@ +/* + * pppd.h - PPP daemon global declarations. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $ + */ + +/* + * TODO: + */ + +#ifndef __PPPD_H__ +#define __PPPD_H__ + +#include /* for FILE */ +#include /* for NGROUPS_MAX */ +#include /* for MAXPATHLEN and BSD4_4, if defined */ +#include /* for u_int32_t, if defined */ +#include /* for struct timeval */ +#include +#include "patchlevel.h" + +#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. + */ + +typedef unsigned char bool; + +enum opt_type { + o_special_noarg = 0, + o_special = 1, + o_bool, + o_int, + o_uint32, + o_string, + o_wild +}; + +typedef struct { + char *name; /* name of the option */ + enum opt_type type; + void *addr; + char *description; + unsigned int flags; + void *addr2; + int upper_limit; + int lower_limit; + const char *source; + short int priority; + short int winner; +} option_t; + +/* Values for flags */ +#define OPT_VALUE 0xff /* mask for presupplied value */ +#define OPT_HEX 0x100 /* int option is in hex */ +#define OPT_NOARG 0x200 /* option doesn't take argument */ +#define OPT_OR 0x400 /* for u32, OR in argument to value */ +#define OPT_INC 0x400 /* for o_int, increment value */ +#define OPT_A2OR 0x800 /* for o_bool, OR arg to *(u_char *)addr2 */ +#define OPT_PRIV 0x1000 /* privileged option */ +#define OPT_STATIC 0x2000 /* string option goes into static array */ +#define OPT_NOINCR 0x2000 /* for o_int, value mustn't be increased */ +#define OPT_LLIMIT 0x4000 /* check value against lower limit */ +#define OPT_ULIMIT 0x8000 /* check value against upper limit */ +#define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT) +#define OPT_ZEROOK 0x10000 /* 0 value is OK even if not within limits */ +#define OPT_HIDE 0x10000 /* for o_string, print value as ?????? */ +#define OPT_A2LIST 0x20000 /* for o_special, keep list of values */ +#define OPT_A2CLRB 0x20000 /* o_bool, clr val bits in *(u_char *)addr2 */ +#define OPT_ZEROINF 0x40000 /* with OPT_NOINCR, 0 == infinity */ +#define OPT_PRIO 0x80000 /* process option priorities for this option */ +#define OPT_PRIOSUB 0x100000 /* subsidiary member of priority group */ +#define OPT_ALIAS 0x200000 /* option is alias for previous option */ +#define OPT_A2COPY 0x400000 /* addr2 -> second location to rcv value */ +#define OPT_ENABLE 0x800000 /* use *addr2 as enable for option */ +#define OPT_A2CLR 0x1000000 /* clear *(bool *)addr2 */ +#define OPT_PRIVFIX 0x2000000 /* user can't override if set by root */ +#define OPT_INITONLY 0x4000000 /* option can only be set in init phase */ +#define OPT_DEVEQUIV 0x8000000 /* equiv to device name */ +#define OPT_DEVNAM (OPT_INITONLY | OPT_DEVEQUIV) +#define OPT_A2PRINTER 0x10000000 /* *addr2 is a fn for printing option */ +#define OPT_A2STRVAL 0x20000000 /* *addr2 points to current string value */ +#define OPT_NOPRINT 0x40000000 /* don't print this option at all */ + +#define OPT_VAL(x) ((x) & OPT_VALUE) + +/* Values for priority */ +#define OPRIO_DEFAULT 0 /* a default value */ +#define OPRIO_CFGFILE 1 /* value from a configuration file */ +#define OPRIO_CMDLINE 2 /* value from the command line */ +#define OPRIO_SECFILE 3 /* value from options in a secrets file */ +#define OPRIO_ROOT 100 /* added to priority if OPT_PRIVFIX && root */ + +#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 */ + u_int32_t base; /* match if (addr & mask) == base */ + u_int32_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; + unsigned int pkts_in; + unsigned int pkts_out; +}; + +/* Used for storing a sequence of words. Usually malloced. */ +struct wordlist { + struct wordlist *next; + char *word; +}; + +/* An endpoint discriminator, used with multilink. */ +#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ +struct epdisc { + unsigned char class; + unsigned char length; + unsigned char value[MAX_ENDP_LEN]; +}; + +/* values for epdisc.class */ +#define EPD_NULL 0 /* null discriminator, no data */ +#define EPD_LOCAL 1 +#define EPD_IP 2 +#define EPD_MAC 3 +#define EPD_MAGIC 4 +#define EPD_PHONENUM 5 + +typedef void (*notify_func) __P((void *, int)); + +struct notifier { + struct notifier *next; + notify_func func; + void *arg; +}; + +/* + * Global variables. + */ + +extern int hungup; /* Physical layer has disconnected */ +extern int ifunit; /* Interface unit number */ +extern char ifname[]; /* Interface name */ +extern char hostname[]; /* Our hostname */ +extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ +extern int devfd; /* fd of underlying device */ +extern int fd_ppp; /* fd for talking PPP */ +extern int phase; /* Current state of link - see values below */ +extern int baud_rate; /* Current link speed in bits/sec */ +extern char *progname; /* Name of this program */ +extern int redirect_stderr;/* Connector's stderr should go to file */ +extern char peer_authname[];/* Authenticated name of peer */ +extern int auth_done[NUM_PPP]; /* Methods actually used for auth */ +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 link_stats_valid; /* set if link_stats is valid */ +extern unsigned link_connect_time; /* time the link was up for */ +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 bool log_default; /* log_to_fd is default (stdout) */ +extern char *no_ppp_msg; /* message to print if ppp not in kernel */ +extern volatile int status; /* exit status for pppd */ +extern bool 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 int error_count; /* # of times error() has been called */ +extern char ppp_devnam[MAXPATHLEN]; +extern char remote_number[MAXNAMELEN]; /* Remote telephone number, if avail. */ +extern int ppp_session_number; /* Session number (eg PPPoE session) */ +extern int fd_devnull; /* fd open to /dev/null */ + +extern int listen_time; /* time to listen first (ms) */ +extern bool doing_multilink; +extern bool multilink_master; +extern bool bundle_eof; +extern bool bundle_terminating; + +extern struct notifier *pidchange; /* for notifications of pid changing */ +extern struct notifier *phasechange; /* for notifications of phase changes */ +extern struct notifier *exitnotify; /* for notification that we're exiting */ +extern struct notifier *sigreceived; /* notification of received signal */ +extern struct notifier *ip_up_notifier; /* IPCP has come up */ +extern struct notifier *ip_down_notifier; /* IPCP has gone down */ +extern struct notifier *auth_up_notifier; /* peer has authenticated */ +extern struct notifier *link_down_notifier; /* link has gone down */ +extern struct notifier *fork_notifier; /* we are a new child process */ + +/* 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 u_int32_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 bool session_mgmt; /* Do session management (login records) */ +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 *pty_socket; /* Socket to connect to pty */ +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 */ +extern int max_data_rate; /* max bytes/sec through charshunt */ +extern int req_unit; /* interface unit number to use */ +extern bool multilink; /* enable multilink operation */ +extern bool noendpoint; /* don't send or accept endpt. discrim. */ +extern char *bundle_name; /* bundle name for multilink */ +extern bool dump_options; /* print out option values */ +extern bool dryrun; /* check everything, print options, exit */ +extern int child_wait; /* # seconds to wait for children at end */ + +#ifdef MAXOCTETS +extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ +extern int maxoctets_dir; /* Direction : + 0 - in+out (default) + 1 - in + 2 - out + 3 - max(in,out) */ +extern int maxoctets_timeout; /* Timeout for check of octets limit */ +#define PPP_OCTETS_DIRECTION_SUM 0 +#define PPP_OCTETS_DIRECTION_IN 1 +#define PPP_OCTETS_DIRECTION_OUT 2 +#define PPP_OCTETS_DIRECTION_MAXOVERAL 3 +/* same as previos, but little different on RADIUS side */ +#define PPP_OCTETS_DIRECTION_MAXSESSION 4 +#endif + +#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 + +/* Values for auth_pending, auth_done */ +#define PAP_WITHPEER 0x1 +#define PAP_PEER 0x2 +#define CHAP_WITHPEER 0x4 +#define CHAP_PEER 0x8 +#define EAP_WITHPEER 0x10 +#define EAP_PEER 0x20 + +/* Values for auth_done only */ +#define CHAP_MD5_WITHPEER 0x40 +#define CHAP_MD5_PEER 0x80 +#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ +#define CHAP_MS_WITHPEER 0x100 +#define CHAP_MS_PEER 0x200 +#define CHAP_MS2_WITHPEER 0x400 +#define CHAP_MS2_PEER 0x800 + +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 */ +extern int option_priority; /* priority of current options */ + +/* + * 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 +#define PHASE_MASTER 12 + +/* + * 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) __P((int unit)); + /* Process a received packet */ + void (*input) __P((int unit, u_char *pkt, int len)); + /* Process a received protocol-reject */ + void (*protrej) __P((int unit)); + /* Lower layer has come up */ + void (*lowerup) __P((int unit)); + /* Lower layer has gone down */ + void (*lowerdown) __P((int unit)); + /* Open the protocol */ + void (*open) __P((int unit)); + /* Close the protocol */ + void (*close) __P((int unit, char *reason)); + /* Print a packet in readable form */ + int (*printpkt) __P((u_char *pkt, int len, + void (*printer) __P((void *, char *, ...)), + void *arg)); + /* Process a received data packet */ + void (*datainput) __P((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) __P((void)); + /* Configure interface for demand-dial */ + int (*demand_conf) __P((int unit)); + /* Say whether to bring up link for this pkt */ + int (*active_pkt) __P((u_char *pkt, int len)); +}; + +/* Table of pointers to supported protocols */ +extern struct protent *protocols[]; + +/* + * This struct contains pointers to a set of procedures for + * doing operations on a "channel". A channel provides a way + * to send and receive PPP packets - the canonical example is + * a serial port device in PPP line discipline (or equivalently + * with PPP STREAMS modules pushed onto it). + */ +struct channel { + /* set of options for this channel */ + option_t *options; + /* find and process a per-channel options file */ + void (*process_extra_options) __P((void)); + /* check all the options that have been given */ + void (*check_options) __P((void)); + /* get the channel ready to do PPP, return a file descriptor */ + int (*connect) __P((void)); + /* we're finished with the channel */ + void (*disconnect) __P((void)); + /* put the channel into PPP `mode' */ + int (*establish_ppp) __P((int)); + /* take the channel out of PPP `mode', restore loopback if demand */ + void (*disestablish_ppp) __P((int)); + /* set the transmit-side PPP parameters of the channel */ + void (*send_config) __P((int, u_int32_t, int, int)); + /* set the receive-side PPP parameters of the channel */ + void (*recv_config) __P((int, u_int32_t, int, int)); + /* cleanup on error or normal exit */ + void (*cleanup) __P((void)); + /* close the device, called in children after fork */ + void (*close) __P((void)); +}; + +extern struct channel *the_channel; + +/* + * Prototypes. + */ + +/* Procedures exported from main.c. */ +void set_ifunit __P((int)); /* set stuff that depends on ifunit */ +void detach __P((void)); /* Detach from controlling tty */ +void die __P((int)); /* Cleanup and exit */ +void quit __P((void)); /* like die(1) */ +void novm __P((char *)); /* Say we ran out of memory, and die */ +void timeout __P((void (*func)(void *), void *arg, int s, int us)); + /* Call func(arg) after s.us seconds */ +void untimeout __P((void (*func)(void *), void *arg)); + /* Cancel call to func(arg) */ +void record_child __P((int, char *, void (*) (void *), void *, int)); +pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ +int device_script __P((char *cmd, int in, int out, int dont_wait)); + /* Run `cmd' with given stdin and stdout */ +pid_t run_program __P((char *prog, char **args, int must_exist, + void (*done)(void *), void *arg, int wait)); + /* Run program prog with args in child */ +void reopen_log __P((void)); /* (re)open the connection to syslog */ +void print_link_stats __P((void)); /* Print stats, if available */ +void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */ +void update_link_stats __P((int)); /* Get stats at link termination */ +void script_setenv __P((char *, char *, int)); /* set script env var */ +void script_unsetenv __P((char *)); /* unset script env var */ +void new_phase __P((int)); /* signal start of new phase */ +void add_notifier __P((struct notifier **, notify_func, void *)); +void remove_notifier __P((struct notifier **, notify_func, void *)); +void notify __P((struct notifier *, int)); +int ppp_send_config __P((int, int, u_int32_t, int, int)); +int ppp_recv_config __P((int, int, u_int32_t, int, int)); +const char *protocol_name __P((int)); +void remove_pidfiles __P((void)); +void lock_db __P((void)); +void unlock_db __P((void)); + +/* Procedures exported from tty.c. */ +void tty_init __P((void)); + +/* Procedures exported from utils.c. */ +void log_packet __P((u_char *, int, char *, int)); + /* Format a packet and log it with syslog */ +void print_string __P((char *, int, void (*) (void *, char *, ...), + void *)); /* Format a string for output */ +int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ +int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ +size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ +size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ +void dbglog __P((char *, ...)); /* log a debug message */ +void info __P((char *, ...)); /* log an informational message */ +void notice __P((char *, ...)); /* log a notice-level message */ +void warn __P((char *, ...)); /* log a warning message */ +void error __P((char *, ...)); /* log an error message */ +void fatal __P((char *, ...)); /* log an error message and die(1) */ +void init_pr_log __P((const char *, int)); /* initialize for using pr_log */ +void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ +void end_pr_log __P((void)); /* finish up after using pr_log */ +void dump_packet __P((const char *, u_char *, int)); + /* dump packet to debug log if interesting */ +ssize_t complete_read __P((int, void *, size_t)); + /* read a complete buffer */ + +/* Procedures exported from auth.c */ +void link_required __P((int)); /* we are starting to use the link */ +void start_link __P((int)); /* bring the link up now */ +void link_terminated __P((int)); /* we are finished with the link */ +void link_down __P((int)); /* the LCP layer has left the Opened state */ +void upper_layers_down __P((int));/* take all NCPs down */ +void link_established __P((int)); /* the link is up; authenticate now */ +void start_networks __P((int)); /* start all the network control protos */ +void continue_networks __P((int)); /* start network [ip, etc] control protos */ +void np_up __P((int, int)); /* a network protocol has come up */ +void np_down __P((int, int)); /* a network protocol has gone down */ +void np_finished __P((int, int)); /* a network protocol no longer needs link */ +void auth_peer_fail __P((int, int)); + /* peer failed to authenticate itself */ +void auth_peer_success __P((int, int, int, char *, int)); + /* peer successfully authenticated itself */ +void auth_withpeer_fail __P((int, int)); + /* we failed to authenticate ourselves */ +void auth_withpeer_success __P((int, int, int)); + /* we successfully authenticated ourselves */ +void auth_check_options __P((void)); + /* check authentication options supplied */ +void auth_reset __P((int)); /* check what secrets we have */ +int check_passwd __P((int, char *, int, char *, int, char **)); + /* Check peer-supplied username/password */ +int get_secret __P((int, char *, char *, char *, int *, int)); + /* get "secret" for chap */ +int get_srp_secret __P((int unit, char *client, char *server, char *secret, + int am_server)); +int auth_ip_addr __P((int, u_int32_t)); + /* check if IP address is authorized */ +int auth_number __P((void)); /* check if remote number is authorized */ +int bad_ip_adrs __P((u_int32_t)); + /* check if IP address is unreasonable */ + +/* Procedures exported from demand.c */ +void demand_conf __P((void)); /* config interface(s) for demand-dial */ +void demand_block __P((void)); /* set all NPs to queue up packets */ +void demand_unblock __P((void)); /* set all NPs to pass packets */ +void demand_discard __P((void)); /* set all NPs to discard packets */ +void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ +int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ +int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ + +/* Procedures exported from multilink.c */ +#ifdef HAVE_MULTILINK +void mp_check_options __P((void)); /* Check multilink-related options */ +int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ +void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */ +void mp_bundle_terminated __P((void)); +char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ +int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ +#else +#define mp_bundle_terminated() /* nothing */ +#define mp_exit_bundle() /* nothing */ +#define doing_multilink 0 +#define multilink_master 0 +#endif + +/* Procedures exported from sys-*.c */ +void sys_init __P((void)); /* Do system-dependent initialization */ +void sys_cleanup __P((void)); /* Restore system state before exiting */ +int sys_check_options __P((void)); /* Check options specified */ +void sys_close __P((void)); /* Clean up in a child before execing */ +int ppp_available __P((void)); /* Test whether ppp kernel support exists */ +int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */ +int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */ +int tty_establish_ppp __P((int)); /* Turn serial port into a ppp interface */ +void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */ +void generic_disestablish_ppp __P((int dev_fd)); /* Restore device setting */ +int generic_establish_ppp __P((int dev_fd)); /* Make a ppp interface */ +void make_new_bundle __P((int, int, int, int)); /* Create new bundle */ +int bundle_attach __P((int)); /* Attach link to existing bundle */ +void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */ +void destroy_bundle __P((void)); /* Tell driver to destroy bundle */ +void clean_check __P((void)); /* Check if line was 8-bit clean */ +void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */ +void restore_tty __P((int)); /* Restore port's original parameters */ +void setdtr __P((int, int)); /* Raise or lower port's DTR line */ +void output __P((int, u_char *, int)); /* Output a PPP packet */ +void wait_input __P((struct timeval *)); + /* Wait for input, with timeout */ +void add_fd __P((int)); /* Add fd to set to wait for */ +void remove_fd __P((int)); /* Remove fd from set to wait for */ +int read_packet __P((u_char *)); /* Read PPP packet */ +int get_loop_output __P((void)); /* Read pkts from loopback */ +void tty_send_config __P((int, u_int32_t, int, int)); + /* Configure i/f transmit parameters */ +void tty_set_xaccm __P((ext_accm)); + /* Set extended transmit ACCM */ +void tty_recv_config __P((int, u_int32_t, int, int)); + /* Configure i/f receive parameters */ +int ccp_test __P((int, u_char *, int, int)); + /* Test support for compression scheme */ +void ccp_flags_set __P((int, int, int)); + /* Set kernel CCP state */ +int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */ +int get_idle_time __P((int, struct ppp_idle *)); + /* Find out how long link has been idle */ +int get_ppp_stats __P((int, struct pppd_stats *)); + /* Return link statistics */ +void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */ +int netif_get_mtu __P((int)); /* Get PPP interface MTU */ +int sifvjcomp __P((int, int, int, int)); + /* Configure VJ TCP header compression */ +int sifup __P((int)); /* Configure i/f up for one protocol */ +int sifnpmode __P((int u, int proto, enum NPmode mode)); + /* Set mode for handling packets for proto */ +int sifdown __P((int)); /* Configure i/f down for one protocol */ +int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t)); + /* Configure IPv4 addresses for i/f */ +int cifaddr __P((int, u_int32_t, u_int32_t)); + /* Reset i/f IP addresses */ +#ifdef INET6 +int sif6addr __P((int, eui64_t, eui64_t)); + /* Configure IPv6 addresses for i/f */ +int cif6addr __P((int, eui64_t, eui64_t)); + /* Remove an IPv6 address from i/f */ +#endif +int sifdefaultroute __P((int, u_int32_t, u_int32_t)); + /* Create default route through i/f */ +int cifdefaultroute __P((int, u_int32_t, u_int32_t)); + /* Delete default route through i/f */ +int sifproxyarp __P((int, u_int32_t)); + /* Add proxy ARP entry for peer */ +int cifproxyarp __P((int, u_int32_t)); + /* Delete proxy ARP entry for peer */ +u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ +int lock __P((char *)); /* Create lock file for device */ +int relock __P((int)); /* Rewrite lock file with new pid */ +void unlock __P((void)); /* Delete previously-created lock file */ +void logwtmp __P((const char *, const char *, const char *)); + /* Write entry to wtmp file */ +int get_host_seed __P((void)); /* Get host-dependent random number seed */ +int have_route_to __P((u_int32_t)); /* Check if route to addr exists */ +#ifdef PPP_FILTER +int set_filters __P((struct bpf_program *pass, struct bpf_program *active)); + /* Set filter programs in kernel */ +#endif +#ifdef IPX_CHANGE +int sipxfaddr __P((int, unsigned long, unsigned char *)); +int cipxfaddr __P((int)); +#endif +int get_if_hwaddr __P((u_char *addr, char *name)); +char *get_first_ethernet __P((void)); + +/* Procedures exported from options.c */ +int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */ +int parse_args __P((int argc, char **argv)); + /* Parse options from arguments given */ +int options_from_file __P((char *filename, int must_exist, int check_prot, + int privileged)); + /* Parse options from an options file */ +int options_from_user __P((void)); /* Parse options from user's .ppprc */ +int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */ +int options_from_list __P((struct wordlist *, int privileged)); + /* Parse options from a wordlist */ +int getword __P((FILE *f, char *word, int *newlinep, char *filename)); + /* Read a word from a file */ +void option_error __P((char *fmt, ...)); + /* Print an error message about an option */ +int int_option __P((char *, int *)); + /* Simplified number_option for decimal ints */ +void add_options __P((option_t *)); /* Add extra options */ +void check_options __P((void)); /* check values after all options parsed */ +int override_value __P((const char *, int, const char *)); + /* override value if permitted by priority */ +void print_options __P((void (*) __P((void *, char *, ...)), void *)); + /* print out values of all options */ + +int parse_dotted_ip __P((char *, u_int32_t *)); + +/* + * Hooks to enable plugins to change various things. + */ +extern int (*new_phase_hook) __P((int)); +extern int (*idle_time_hook) __P((struct ppp_idle *)); +extern int (*holdoff_hook) __P((void)); +extern int (*pap_check_hook) __P((void)); +extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, + struct wordlist **paddrs, + struct wordlist **popts)); +extern void (*pap_logout_hook) __P((void)); +extern int (*pap_passwd_hook) __P((char *user, char *passwd)); +extern int (*allowed_address_hook) __P((u_int32_t addr)); +extern void (*ip_up_hook) __P((void)); +extern void (*ip_down_hook) __P((void)); +extern void (*ip_choose_hook) __P((u_int32_t *)); + +extern int (*chap_check_hook) __P((void)); +extern int (*chap_passwd_hook) __P((char *user, char *passwd)); +extern void (*multilink_join_hook) __P((void)); + +/* Let a plugin snoop sent and received packets. Useful for L2TP */ +extern void (*snoop_recv_hook) __P((unsigned char *p, int len)); +extern void (*snoop_send_hook) __P((unsigned char *p, int len)); + +/* + * 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) timeout((r), (f), (t), 0) +#define UNTIMEOUT(r, f) untimeout((r), (f)) +*/ +#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) +#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) +#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) + +#define BCOPY(s, d, l) memcpy(d, s, l) +#define BZERO(s, n) memset(s, 0, n) +#define BCMP(s1, s2, l) memcmp(s1, s2, l) + +#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 +#ifdef MAXOCTETS +#define EXIT_TRAFFIC_LIMIT 20 +#endif +#define EXIT_CNID_AUTH_FAILED 21 + +/* + * 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 + +#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */ +#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \ + || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \ + || defined(DEBUGCHAP) || defined(DEBUG) || defined(DEBUGIPV6CP) +#define LOG_PPP LOG_LOCAL2 +#else +#define LOG_PPP LOG_DAEMON +#endif +#endif /* LOG_PPP */ + +#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 */ + +#ifndef MIN +#define MIN(a, b) ((a) < (b)? (a): (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((a) > (b)? (a): (b)) +#endif + +#ifndef offsetof +#define offsetof(type, member) ((size_t) &((type *)0)->member) +#endif + +#endif /* __PPP_H__ */ diff --git a/src/netif/ppp/pppdebug.h b/src/netif/ppp/pppdebug.h index 81349971..43f583ae 100644 --- a/src/netif/ppp/pppdebug.h +++ b/src/netif/ppp/pppdebug.h @@ -45,27 +45,26 @@ #define LOG_DETAIL (PPP_DEBUG) #define LOG_DEBUG (PPP_DEBUG) - #define TRACELCP PPP_DEBUG #if PPP_DEBUG -#define AUTHDEBUG(a, b) LWIP_DEBUGF(a, b) -#define IPCPDEBUG(a, b) LWIP_DEBUGF(a, b) -#define UPAPDEBUG(a, b) LWIP_DEBUGF(a, b) -#define LCPDEBUG(a, b) LWIP_DEBUGF(a, b) -#define FSMDEBUG(a, b) LWIP_DEBUGF(a, b) -#define CHAPDEBUG(a, b) LWIP_DEBUGF(a, b) +//#define AUTHDEBUG(a, b) LWIP_DEBUGF(a, b) +//#define IPCPDEBUG(a, b) LWIP_DEBUGF(a, b) +//#define UPAPDEBUG(a, b) LWIP_DEBUGF(a, b) +//#define LCPDEBUG(a, b) LWIP_DEBUGF(a, b) +//#define FSMDEBUG(a, b) LWIP_DEBUGF(a, b) +//#define CHAPDEBUG(a, b) LWIP_DEBUGF(a, b) #define PPPDEBUG(a, b) LWIP_DEBUGF(a, b) #else /* PPP_DEBUG */ -#define AUTHDEBUG(a, b) -#define IPCPDEBUG(a, b) -#define UPAPDEBUG(a, b) -#define LCPDEBUG(a, b) -#define FSMDEBUG(a, b) -#define CHAPDEBUG(a, b) +//#define AUTHDEBUG(a, b) +//#define IPCPDEBUG(a, b) +//#define UPAPDEBUG(a, b) +//#define LCPDEBUG(a, b) +//#define FSMDEBUG(a, b) +//#define CHAPDEBUG(a, b) #define PPPDEBUG(a, b) #endif /* PPP_DEBUG */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c new file mode 100644 index 00000000..8085741b --- /dev/null +++ b/src/netif/ppp/pppmy.c @@ -0,0 +1,1110 @@ +/* + * pppmy.c + * + * Created on: May 12, 2012 + * Author: gradator + */ + +#include "lwip/opt.h" + +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/sys.h" + +#include "pppd.h" +#include "fsm.h" +#include "lcp.h" +#include "ipcp.h" + +#include "pppdebug.h" +#include "pppmy.h" + +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ + +/* PPP packet parser states. Current state indicates operation yet to be + * completed. */ +typedef enum { + PDIDLE = 0, /* Idle state - waiting. */ + PDSTART, /* Process start flag. */ + PDADDRESS, /* Process address field. */ + PDCONTROL, /* Process control field. */ + PDPROTOCOL1, /* Process protocol field 1. */ + PDPROTOCOL2, /* Process protocol field 2. */ + PDDATA /* Process data byte. */ +} PPPDevStates; + +typedef struct PPPControlRx_s { + /** unit number / ppp descriptor */ + int pd; + /** the rx file descriptor */ +#if PPPOS_SUPPORT /* FIXME: enable sio_fd_t back */ + sio_fd_t fd; +#endif +#if PPPOE_SUPPORT + int fd; +#endif + /** receive buffer - encoded data is stored here */ +#if PPP_INPROC_OWNTHREAD + u_char rxbuf[PPPOS_RX_BUFSIZE]; +#endif /* PPP_INPROC_OWNTHREAD */ + + /* The input packet. */ + struct pbuf *inHead, *inTail; + +#if PPPOS_SUPPORT + u16_t inProtocol; /* The input protocol code. */ + u16_t inFCS; /* Input Frame Check Sequence value. */ +#endif /* PPPOS_SUPPORT */ + PPPDevStates inState; /* The input process state. */ + char inEscaped; /* Escape next character. */ + ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ +} PPPControlRx; + +/* + * PPP interface control block. + */ +typedef struct PPPControl_s { + PPPControlRx rx; + char openFlag; /* True when in use. */ +#if PPPOE_SUPPORT + struct netif *ethif; + struct pppoe_softc *pppoe_sc; +#endif /* PPPOE_SUPPORT */ + int if_up; /* True when the interface is up. */ + int errCode; /* Code indicating why interface is down. */ +#if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ +#endif /* PPPOS_SUPPORT */ + u16_t mtu; /* Peer's mru */ + int pcomp; /* Does peer accept protocol compression? */ + int accomp; /* Does peer accept addr/ctl compression? */ + u_long lastXMit; /* Time of last transmission. */ + ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ +#if PPPOS_SUPPORT && VJ_SUPPORT + int vjEnabled; /* Flag indicating VJ compression enabled. */ + struct vjcompress vjComp; /* Van Jacobson compression header. */ +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + struct netif netif; + + struct ppp_addrs addrs; + + void (*linkStatusCB)(void *ctx, int errCode, void *arg); + void *linkStatusCtx; + +} PPPControl; + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ +static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ + + +struct pbuf * pppSingleBuf(struct pbuf *p) { + struct pbuf *q, *b; + u_char *pl; + + if(p->tot_len == p->len) { + return p; + } + + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(!q) { + PPPDEBUG(LOG_ERR, + ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); + return p; /* live dangerously */ + } + + for(b = p, pl = q->payload; b != NULL; b = b->next) { + MEMCPY(pl, b->payload, b->len); + pl += b->len; + } + + pbuf_free(p); + + return q; +} + +/** Input helper struct, must be packed since it is stored to pbuf->payload, + * which might be unaligned. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppInputHeader { + PACK_STRUCT_FIELD(int unit); + PACK_STRUCT_FIELD(u16_t proto); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +/** Initiate LCP open request */ +static void pppStart(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd)); + lcp_open(pd); /* Start protocol */ + lcp_lowerup(pd); + PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n")); +} + + +/* + * Pass the processed input packet to the appropriate handler. + * This function and all handlers run in the context of the tcpip_thread + */ + +/* FIXME: maybe we should pass in two arguments pppInputHeader and payload + * this is totally stupid to make room for it and then modify the packet directly + * or it is used in output ? have to find out... + */ +static void ppp_input(void *arg) { + struct pbuf *nb = (struct pbuf *)arg; + u16_t protocol; + int pd; + + pd = ((struct pppInputHeader *)nb->payload)->unit; + protocol = ((struct pppInputHeader *)nb->payload)->proto; + printf("ppp_input() called, pd = %d, protocol = 0x%x\n", pd, protocol); + + if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + + LINK_STATS_INC(link.recv); + snmp_inc_ifinucastpkts(&pppControl[pd].netif); + snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); + + /* + * Toss all non-LCP packets unless LCP is OPEN. + */ + if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { + dbglog("Discarded non-LCP packet when LCP not open"); + return; + } + + /* FIXME: add a phase per connection */ + + /* + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if (phase <= PHASE_AUTHENTICATE + && !(protocol == PPP_LCP || protocol == PPP_LQR + || protocol == PPP_PAP || protocol == PPP_CHAP || + protocol == PPP_EAP)) { + dbglog("discarding proto 0x%x in phase %d", + protocol, phase); + return; + } + + /* FIXME: should we write protent to do that ? */ + + switch(protocol) { + case PPP_VJC_COMP: /* VJ compressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, + ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", + pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_IP: /* Internet Protocol */ + printf("IP packet received\n"); + PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + if (pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + break; + + default: { + + int i; + struct protent *protp; + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + (*protp->input)(pd, nb->payload, nb->len); + goto out; + } +#if 0 /* Unused ? */ + if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag + && protp->datainput != NULL) { + (*protp->datainput)(pd, nb->payload, nb->len); + goto out; + } +#endif /* Unused */ + } + + 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); + } + if (pbuf_header(nb, sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + lcp_sprotrej(pd, nb->payload, nb->len); + } + break; + } + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pd].netif); + +out: + pbuf_free(nb); + return; + + #if 0 + /* + * Toss all non-LCP packets unless LCP is OPEN. + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { + if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || + (lcp_phase[pd] != PHASE_AUTHENTICATE)) { + PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); + goto drop; + } + } + + switch(protocol) { + case PPP_VJC_COMP: /* VJ compressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, + ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", + pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_IP: /* Internet Protocol */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + if (pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + break; + + default: { + struct protent *protp; + int i; + + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); + nb = pppSingleBuf(nb); + (*protp->input)(pd, nb->payload, nb->len); + PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); + goto out; + } + } + + /* No handler for this protocol so reject the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); + if (pbuf_header(nb, sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } +#if BYTE_ORDER == LITTLE_ENDIAN + protocol = htons(protocol); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + SMEMCPY(nb->payload, &protocol, sizeof(protocol)); + lcp_sprotrej(pd, nb->payload, nb->len); + } + break; + } +#endif + + +} + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* Initialize the PPP subsystem. */ + +int ppp_init(void) { + int i; + struct protent *protp; + + debug = 1; + + openlog("LWIP-PPP", LOG_PID | LOG_NDELAY, LOG_PPP); + setlogmask(LOG_UPTO(LOG_DEBUG)); + syslog(LOG_DEBUG, "hello, this is gradator lwIP PPP!"); + + memset(&ppp_settings, 0, sizeof(ppp_settings)); + ppp_settings.usepeerdns = 1; + pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL); + + /* + * Initialize magic number generator now so that protocols may + * use magic numbers in initialization. + */ + magic_init(); + + /* + * Initialize each protocol. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + (*protp->init)(0); +} + +void +pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) +{ + switch(authType) { + case PPPAUTHTYPE_NONE: + default: +#ifdef LWIP_PPP_STRICT_PAP_REJECT + ppp_settings.refuse_pap = 1; +#else /* LWIP_PPP_STRICT_PAP_REJECT */ + /* some providers request pap and accept an empty login/pw */ + ppp_settings.refuse_pap = 0; +#endif /* LWIP_PPP_STRICT_PAP_REJECT */ + ppp_settings.refuse_chap = 1; + break; + + case PPPAUTHTYPE_ANY: + /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. + * RFC 1994 says: + * + * In practice, within or associated with each PPP server, there is a + * database which associates "user" names with authentication + * information ("secrets"). It is not anticipated that a particular + * named user would be authenticated by multiple methods. This would + * make the user vulnerable to attacks which negotiate the least secure + * method from among a set (such as PAP rather than CHAP). If the same + * secret was used, PAP would reveal the secret to be used later with + * CHAP. + * + * Instead, for each user name there should be an indication of exactly + * one method used to authenticate that user name. If a user needs to + * make use of different authentication methods under different + * circumstances, then distinct user names SHOULD be employed, each of + * which identifies exactly one authentication method. + * + */ + ppp_settings.refuse_pap = 0; + ppp_settings.refuse_chap = 0; + break; + + case PPPAUTHTYPE_PAP: + ppp_settings.refuse_pap = 0; + ppp_settings.refuse_chap = 1; + break; + + case PPPAUTHTYPE_CHAP: + ppp_settings.refuse_pap = 1; + ppp_settings.refuse_chap = 0; + break; + } + + if(user) { + strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); + ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0'; + } else { + ppp_settings.user[0] = '\0'; + } + + if(passwd) { + strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1); + ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0'; + } else { + ppp_settings.passwd[0] = '\0'; + } +} + +#if PPPOE_SUPPORT +static void pppOverEthernetLinkStatusCB(int pd, int up); + +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, + pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) +{ + PPPControl *pc; + int pd; + + LWIP_UNUSED_ARG(service_name); + LWIP_UNUSED_ARG(concentrator_name); + + if (linkStatusCB == NULL) { + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + return PPPERR_PARAM; + } + + /* Find a free PPP session descriptor. Critical region? */ + for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + if (pd >= NUM_PPP) { + pd = PPPERR_OPEN; + } else { + pc = &pppControl[pd]; + memset(pc, 0, sizeof(PPPControl)); + pc->openFlag = 1; + pc->ethif = ethif; + + pc->linkStatusCB = linkStatusCB; + pc->linkStatusCtx = linkStatusCtx; + + lcp_wantoptions[pd].mru = PPPOE_MAXMTU; + lcp_wantoptions[pd].neg_asyncmap = 0; + lcp_wantoptions[pd].neg_pcompression = 0; + lcp_wantoptions[pd].neg_accompression = 0; + + lcp_allowoptions[pd].mru = PPPOE_MAXMTU; + lcp_allowoptions[pd].neg_asyncmap = 0; + lcp_allowoptions[pd].neg_pcompression = 0; + lcp_allowoptions[pd].neg_accompression = 0; + + if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) { + pc->openFlag = 0; + return PPPERR_OPEN; + } + + pppoe_connect(pc->pppoe_sc); + } + + return pd; +} + +/* FIXME: maybe we should pass in two arguments pppInputHeader and payload + * this is totally stupid to make room for it and then modify the packet directly + * or it is used in output ? have to find out... + */ +void pppInProcOverEthernet(int pd, struct pbuf *pb) { + struct pppInputHeader *pih; + u16_t inProtocol; + + if(pb->len < sizeof(inProtocol)) { + PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n")); + goto drop; + } + + inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; + printf("pppInProcOverEthernet() called, pd = %d, inprotocol = 0x%x\n", pd, inProtocol); + + /* make room for pppInputHeader - should not fail */ + if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { + PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n")); + goto drop; + } + + pih = pb->payload; + + pih->unit = pd; + pih->proto = inProtocol; + + /* Dispatch the packet thereby consuming it. */ + ppp_input(pb); + return; + +drop: + LINK_STATS_INC(link.drop); +// snmp_inc_ifindiscards(&pppControl[pd].netif); + pbuf_free(pb); + return; +} + +void +pppOverEthernetInitFailed(int pd) +{ + PPPControl* pc; + + //pppHup(pd); + //pppStop(pd); + + pc = &pppControl[pd]; + pppoe_destroy(&pc->netif); + pc->openFlag = 0; + + if(pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + } +} + +static void +pppOverEthernetLinkStatusCB(int pd, int up) +{ + printf("pppOverEthernetLinkStatusCB: called, pd = %d, up = %d\n", pd, up); + if(up) { + PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); + pppStart(pd); + } else { + pppOverEthernetInitFailed(pd); + } +} +#endif + +#if PPPOE_SUPPORT +static err_t +pppifOutputOverEthernet(int pd, struct pbuf *p) +{ + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + u_short protocol = PPP_IP; + int i=0; + u16_t tot_len; + + /* @todo: try to use pbuf_header() here! */ + pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return ERR_MEM; + } + + pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + + pc->lastXMit = sys_jiffies(); + + if (!pc->pcomp || protocol > 0xFF) { + *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; + } + *((u_char*)pb->payload + i) = protocol & 0xFF; + + pbuf_chain(pb, p); + tot_len = pb->tot_len; + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pc->netif, tot_len); + snmp_inc_ifoutucastpkts(&pc->netif); + LINK_STATS_INC(link.xmit); + return ERR_OK; +} +#endif /* PPPOE_SUPPORT */ + +/* Send a packet on the given connection. */ +static err_t +pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) +{ + int pd = (int)(size_t)netif->state; + PPPControl *pc = &pppControl[pd]; +#if PPPOS_SUPPORT + u_short protocol = PPP_IP; + u_int fcsOut = PPP_INITFCS; + struct pbuf *headMB = NULL, *tailMB = NULL, *p; + u_char c; +#endif /* PPPOS_SUPPORT */ + + LWIP_UNUSED_ARG(ipaddr); + + /* Validate parameters. */ + /* We let any protocol value go through - it can't hurt us + * and the peer will just drop it if it's not accepting it. */ + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", + pd, PPP_IP, pb)); + LINK_STATS_INC(link.opterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_ARG; + } + + /* Check that the link is up. */ + if (phase == PHASE_DEAD) { + PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd)); + LINK_STATS_INC(link.rterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_RTE; + } + +#if PPPOE_SUPPORT + if(pc->ethif) { + return pppifOutputOverEthernet(pd, pb); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOS_SUPPORT + /* Grab an output buffer. */ + headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (headMB == NULL) { + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd)); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_MEM; + } + +#if VJ_SUPPORT + /* + * Attempt Van Jacobson header compression if VJ is configured and + * this is an IP packet. + */ + if (protocol == PPP_IP && pc->vjEnabled) { + switch (vj_compress_tcp(&pc->vjComp, pb)) { + case TYPE_IP: + /* No change... + protocol = PPP_IP_PROTOCOL; */ + break; + case TYPE_COMPRESSED_TCP: + protocol = PPP_VJC_COMP; + break; + case TYPE_UNCOMPRESSED_TCP: + protocol = PPP_VJC_UNCOMP; + break; + default: + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd)); + LINK_STATS_INC(link.proterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + pbuf_free(headMB); + return ERR_VAL; + } + } +#endif /* VJ_SUPPORT */ + + tailMB = headMB; + + /* Build the PPP header. */ + if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + } + + pc->lastXMit = sys_jiffies(); + if (!pc->accomp) { + fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS); + tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM); + fcsOut = PPP_FCS(fcsOut, PPP_UI); + tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM); + } + if (!pc->pcomp || protocol > 0xFF) { + c = (protocol >> 8) & 0xFF; + fcsOut = PPP_FCS(fcsOut, c); + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + c = protocol & 0xFF; + fcsOut = PPP_FCS(fcsOut, c); + tailMB = pppAppend(c, tailMB, &pc->outACCM); + + /* Load packet. */ + for(p = pb; p; p = p->next) { + int n; + u_char *sPtr; + + sPtr = (u_char*)p->payload; + n = p->len; + while (n-- > 0) { + c = *sPtr++; + + /* Update FCS before checking for special characters. */ + fcsOut = PPP_FCS(fcsOut, c); + + /* Copy to output buffer escaping special characters. */ + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + } + + /* Add FCS and trailing flag. */ + c = ~fcsOut & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + c = (~fcsOut >> 8) & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + + /* If we failed to complete the packet, throw it away. */ + if (!tailMB) { + PPPDEBUG(LOG_WARNING, + ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", + pd, protocol)); + pbuf_free(headMB); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_MEM; + } + + /* Send it. */ + PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); + + nPut(pc, headMB); +#endif /* PPPOS_SUPPORT */ + + return ERR_OK; +} + + +/* + * Return the Maximum Transmission Unit for the given PPP connection. + */ +u_short +pppMTU(int pd) +{ + PPPControl *pc = &pppControl[pd]; + u_short st; + + /* Validate parameters. */ + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + } else { + st = pc->mtu; + } + + return st; +} + +#if PPPOE_SUPPORT +int +pppWriteOverEthernet(int pd, const u_char *s, int n) +{ + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + + printf("pppWriteOverEthernet() called\n"); + + /* skip address & flags */ + s += 2; + n -= 2; + + LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + + pc->lastXMit = sys_jiffies(); + + MEMCPY(pb->payload, s, n); + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pc->netif, (u16_t)n); + snmp_inc_ifoutucastpkts(&pc->netif); + LINK_STATS_INC(link.xmit); + return PPPERR_NONE; +} +#endif /* PPPOE_SUPPORT */ + +/* + * Write n characters to a ppp link. + * RETURN: >= 0 Number of characters written + * -1 Failed to write to device + */ +int +pppWrite(int pd, const u_char *s, int n) +{ + PPPControl *pc = &pppControl[pd]; +#if PPPOS_SUPPORT + u_char c; + u_int fcsOut; + struct pbuf *headMB, *tailMB; +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT + if(pc->ethif) { + return pppWriteOverEthernet(pd, s, n); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOS_SUPPORT + headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (headMB == NULL) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + tailMB = headMB; + + /* If the link has been idle, we'll send a fresh flag character to + * flush any noise. */ + if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + } + pc->lastXMit = sys_jiffies(); + + fcsOut = PPP_INITFCS; + /* Load output buffer. */ + while (n-- > 0) { + c = *s++; + + /* Update FCS before checking for special characters. */ + fcsOut = PPP_FCS(fcsOut, c); + + /* Copy to output buffer escaping special characters. */ + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + + /* Add FCS and trailing flag. */ + c = ~fcsOut & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + c = (~fcsOut >> 8) & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + + /* If we failed to complete the packet, throw it away. + * Otherwise send it. */ + if (!tailMB) { + PPPDEBUG(LOG_WARNING, + ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); + /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + pbuf_free(headMB); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len)); + /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + nPut(pc, headMB); +#endif /* PPPOS_SUPPORT */ + + return PPPERR_NONE; +} + + +/* FIXME: rename all output() to pppWrite() */ +/******************************************************************** + * + * output - Output PPP packet. + */ + +void output (int unit, unsigned char *p, int len) +{ + pppWrite(unit, p, len); +} + + +/* + * ppp_send_config - configure the transmit-side characteristics of + * the ppp interface. + */ +int +ppp_send_config(unit, mtu, accm, pcomp, accomp) + int unit, mtu; + u_int32_t accm; + int pcomp, accomp; +{ + PPPControl *pc = &pppControl[unit]; + int i; + + pc->mtu = mtu; + pc->pcomp = pcomp; + pc->accomp = accomp; + + /* Load the ACCM bits for the 32 control codes. */ + for (i = 0; i < 32/8; i++) { + pc->outACCM[i] = (u_char)((accm >> (8 * i)) & 0xFF); + } + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", + unit, + pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); +} + +/* + * ppp_recv_config - configure the receive-side characteristics of + * the ppp interface. + */ +int +ppp_recv_config(unit, mru, accm, pcomp, accomp) + int unit, mru; + u_int32_t accm; + int pcomp, accomp; +{ + PPPControl *pc = &pppControl[unit]; + int i; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_UNUSED_ARG(accomp); + LWIP_UNUSED_ARG(pcomp); + LWIP_UNUSED_ARG(mru); + + /* Load the ACCM bits for the 32 control codes. */ + SYS_ARCH_PROTECT(lev); + for (i = 0; i < 32 / 8; i++) { + /* @todo: does this work? ext_accm has been modified from pppd! */ + pc->rx.inACCM[i] = (u_char)(accm >> (i * 8)); + } + SYS_ARCH_UNPROTECT(lev); + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", + unit, + pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); +} + + + + +/* + * sifaddr - Config the interface IP addresses and netmask. + */ +int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, + u_int32_t net_mask) +{ + PPPControl *pc = &pppControl[unit]; + int st = 1; + + if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); + } else { + SMEMCPY(&pc->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); + SMEMCPY(&pc->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); + SMEMCPY(&pc->addrs.netmask, &net_mask, sizeof(net_mask)); +// SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); +// SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); + } + return st; +} + +/* + * pppifNetifInit - netif init callback + */ +static err_t +pppifNetifInit(struct netif *netif) +{ + netif->name[0] = 'p'; + netif->name[1] = 'p'; + netif->output = pppifOutput; + netif->mtu = pppMTU((int)(size_t)netif->state); + netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; +#if LWIP_NETIF_HOSTNAME + /* @todo: Initialize interface hostname */ + /* netif_set_hostname(netif, "lwip"); */ +#endif /* LWIP_NETIF_HOSTNAME */ + return ERR_OK; +} + +/* + * sifup - Config the interface up and enable IP packets to pass. + */ +int sifup(int u) +{ + PPPControl *pc = &pppControl[u]; + int st = 1; + + if (u < 0 || u >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", u)); + } else { + netif_remove(&pc->netif); + if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, + &pc->addrs.his_ipaddr, (void *)(size_t)u, pppifNetifInit, ip_input)) { + netif_set_up(&pc->netif); + pc->if_up = 1; + pc->errCode = PPPERR_NONE; + + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", u, pc->linkStatusCB, pc->errCode)); + if (pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); + } + } else { + st = 0; + PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", u)); + } + } + + return st; +} + + +/* + * sifnpmode - Set the mode for handling packets for a given NP. + */ +int +sifnpmode(int u, int proto, enum NPmode mode) +{ + LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(proto); + LWIP_UNUSED_ARG(mode); + return 0; +} + diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h new file mode 100644 index 00000000..8246fbd0 --- /dev/null +++ b/src/netif/ppp/pppmy.h @@ -0,0 +1,121 @@ +/* + * pppmy.h + * + * Created on: May 12, 2012 + * Author: gradator + */ + +#ifndef PPPMY_H_ +#define PPPMY_H_ + +#include /* FIXME: temporary */ + +#include "lwip/netif.h" + +/************************* +*** PUBLIC DEFINITIONS *** +*************************/ + +/* Error codes. */ +#define PPPERR_NONE 0 /* No error. */ +#define PPPERR_PARAM -1 /* Invalid parameter. */ +#define PPPERR_OPEN -2 /* Unable to open PPP session. */ +#define PPPERR_DEVICE -3 /* Invalid I/O device for PPP. */ +#define PPPERR_ALLOC -4 /* Unable to allocate resources. */ +#define PPPERR_USER -5 /* User interrupt. */ +#define PPPERR_CONNECT -6 /* Connection lost. */ +#define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */ +#define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */ + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +struct ppp_addrs { + ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; +}; + + +/* FIXME: use PPP option instead ? */ + +struct ppp_settings { + + u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ + u_int auth_required : 1; /* Peer is required to authenticate */ + u_int explicit_remote : 1; /* remote_name specified with remotename opt */ + u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ + u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ + u_int usehostname : 1; /* Use hostname for our_name */ + u_int usepeerdns : 1; /* Ask peer for DNS adds */ + + u_short idle_time_limit; /* Shut down link if idle for this long */ + int maxconnect; /* Maximum connect time (seconds) */ + + char user [MAXNAMELEN + 1]; /* Username for PAP */ + char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ + char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ + char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ +}; + +struct ppp_settings ppp_settings; + +/* FIXME: move all private stuff into a new include */ + +/************************* + *** PRIVATE FUNCTIONS *** + *************************/ + +/** Initiate LCP open request */ +static void pppStart(int pd); + +struct pbuf *pppSingleBuf(struct pbuf *p); + + +/************************ + *** PUBLIC FUNCTIONS *** + ************************/ + +/* Initialize the PPP subsystem. */ +int ppp_init(void); + +/* Warning: Using PPPAUTHTYPE_ANY might have security consequences. + * RFC 1994 says: + * + * In practice, within or associated with each PPP server, there is a + * database which associates "user" names with authentication + * information ("secrets"). It is not anticipated that a particular + * named user would be authenticated by multiple methods. This would + * make the user vulnerable to attacks which negotiate the least secure + * method from among a set (such as PAP rather than CHAP). If the same + * secret was used, PAP would reveal the secret to be used later with + * CHAP. + * + * Instead, for each user name there should be an indication of exactly + * one method used to authenticate that user name. If a user needs to + * make use of different authentication methods under different + * circumstances, then distinct user names SHOULD be employed, each of + * which identifies exactly one authentication method. + * + */ +enum pppAuthType { + PPPAUTHTYPE_NONE, + PPPAUTHTYPE_ANY, + PPPAUTHTYPE_PAP, + PPPAUTHTYPE_CHAP +}; + +void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); + +/* Link status callback function prototype */ +typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); + +/* + * Open a new PPP Over Ethernet (PPPOE) connection. + */ +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, + pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); + +void pppInProcOverEthernet(int pd, struct pbuf *pb); + + +#endif /* PPPMY_H_ */ diff --git a/src/netif/ppp/randm.c b/src/netif/ppp/randm.c deleted file mode 100644 index b736091f..00000000 --- a/src/netif/ppp/randm.c +++ /dev/null @@ -1,249 +0,0 @@ -/***************************************************************************** -* randm.c - Random number generator program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1998 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-06-03 Guy Lancaster , Global Election Systems Inc. -* Extracted from avos. -*****************************************************************************/ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "md5.h" -#include "randm.h" - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include - -#if MD5_SUPPORT /* this module depends on MD5 */ -#define RANDPOOLSZ 16 /* Bytes stored in the pool of randomness. */ - -/*****************************/ -/*** LOCAL DATA STRUCTURES ***/ -/*****************************/ -static char randPool[RANDPOOLSZ]; /* Pool of randomness. */ -static long randCount = 0; /* Pseudo-random incrementer */ - - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -/* - * Initialize the random number generator. - * - * Since this is to be called on power up, we don't have much - * system randomess to work with. Here all we use is the - * real-time clock. We'll accumulate more randomness as soon - * as things start happening. - */ -void -avRandomInit() -{ - avChurnRand(NULL, 0); -} - -/* - * Churn the randomness pool on a random event. Call this early and often - * on random and semi-random system events to build randomness in time for - * usage. For randomly timed events, pass a null pointer and a zero length - * and this will use the system timer and other sources to add randomness. - * If new random data is available, pass a pointer to that and it will be - * included. - * - * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 - */ -void -avChurnRand(char *randData, u32_t randLen) -{ - MD5_CTX md5; - - /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", randLen, randData)); */ - MD5Init(&md5); - MD5Update(&md5, (u_char *)randPool, sizeof(randPool)); - if (randData) { - MD5Update(&md5, (u_char *)randData, randLen); - } else { - struct { - /* INCLUDE fields for any system sources of randomness */ - char foobar; - } sysData; - - /* Load sysData fields here. */ - MD5Update(&md5, (u_char *)&sysData, sizeof(sysData)); - } - MD5Final((u_char *)randPool, &md5); -/* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ -} - -/* - * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using churnRand(). - * Note: It's important that there be sufficient randomness in randPool - * before this is called for otherwise the range of the result may be - * narrow enough to make a search feasible. - * - * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 - * - * XXX Why does he not just call churnRand() for each block? Probably - * so that you don't ever publish the seed which could possibly help - * predict future values. - * XXX Why don't we preserve md5 between blocks and just update it with - * randCount each time? Probably there is a weakness but I wish that - * it was documented. - */ -void -avGenRand(char *buf, u32_t bufLen) -{ - MD5_CTX md5; - u_char tmp[16]; - u32_t n; - - while (bufLen > 0) { - n = LWIP_MIN(bufLen, RANDPOOLSZ); - MD5Init(&md5); - MD5Update(&md5, (u_char *)randPool, sizeof(randPool)); - MD5Update(&md5, (u_char *)&randCount, sizeof(randCount)); - MD5Final(tmp, &md5); - randCount++; - MEMCPY(buf, tmp, n); - buf += n; - bufLen -= n; - } -} - -/* - * Return a new random number. - */ -u32_t -avRandom() -{ - u32_t newRand; - - avGenRand((char *)&newRand, sizeof(newRand)); - - return newRand; -} - -#else /* MD5_SUPPORT */ - -/*****************************/ -/*** LOCAL DATA STRUCTURES ***/ -/*****************************/ -static int avRandomized = 0; /* Set when truely randomized. */ -static u32_t avRandomSeed = 0; /* Seed used for random number generation. */ - - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -/* - * Initialize the random number generator. - * - * Here we attempt to compute a random number seed but even if - * it isn't random, we'll randomize it later. - * - * The current method uses the fields from the real time clock, - * the idle process counter, the millisecond counter, and the - * hardware timer tick counter. When this is invoked - * in startup(), then the idle counter and timer values may - * repeat after each boot and the real time clock may not be - * operational. Thus we call it again on the first random - * event. - */ -void -avRandomInit() -{ -#if 0 - /* Get a pointer into the last 4 bytes of clockBuf. */ - u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]); - - /* - * Initialize our seed using the real-time clock, the idle - * counter, the millisecond timer, and the hardware timer - * tick counter. The real-time clock and the hardware - * tick counter are the best sources of randomness but - * since the tick counter is only 16 bit (and truncated - * at that), the idle counter and millisecond timer - * (which may be small values) are added to help - * randomize the lower 16 bits of the seed. - */ - readClk(); - avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr - + ppp_mtime() + ((u32_t)TM1 << 16) + TM1; -#else - avRandomSeed += sys_jiffies(); /* XXX */ -#endif - - /* Initialize the Borland random number generator. */ - srand((unsigned)avRandomSeed); -} - -/* - * Randomize our random seed value. Here we use the fact that - * this function is called at *truely random* times by the polling - * and network functions. Here we only get 16 bits of new random - * value but we use the previous value to randomize the other 16 - * bits. - */ -void -avRandomize(void) -{ - static u32_t last_jiffies; - - if (!avRandomized) { - avRandomized = !0; - avRandomInit(); - /* The initialization function also updates the seed. */ - } else { - /* avRandomSeed += (avRandomSeed << 16) + TM1; */ - avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */ - } - last_jiffies = sys_jiffies(); -} - -/* - * Return a new random number. - * Here we use the Borland rand() function to supply a pseudo random - * number which we make truely random by combining it with our own - * seed which is randomized by truely random events. - * Thus the numbers will be truely random unless there have been no - * operator or network events in which case it will be pseudo random - * seeded by the real time clock. - */ -u32_t -avRandom() -{ - return ((((u32_t)rand() << 16) + rand()) + avRandomSeed); -} - -#endif /* MD5_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/randm.h b/src/netif/ppp/randm.h deleted file mode 100644 index a0984b02..00000000 --- a/src/netif/ppp/randm.h +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************************** -* randm.h - Random number generator header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-05-29 Guy Lancaster , Global Election Systems Inc. -* Extracted from avos. -*****************************************************************************/ - -#ifndef RANDM_H -#define RANDM_H - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ -/* - * Initialize the random number generator. - */ -void avRandomInit(void); - -/* - * Churn the randomness pool on a random event. Call this early and often - * on random and semi-random system events to build randomness in time for - * usage. For randomly timed events, pass a null pointer and a zero length - * and this will use the system timer and other sources to add randomness. - * If new random data is available, pass a pointer to that and it will be - * included. - */ -void avChurnRand(char *randData, u32_t randLen); - -/* - * Randomize our random seed value. To be called for truely random events - * such as user operations and network traffic. - */ -#if MD5_SUPPORT -#define avRandomize() avChurnRand(NULL, 0) -#else /* MD5_SUPPORT */ -void avRandomize(void); -#endif /* MD5_SUPPORT */ - -/* - * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using churnRand(). - * Thus it's important to make sure that the results of this are not - * published directly because one could predict the next result to at - * least some degree. Also, it's important to get a good seed before - * the first use. - */ -void avGenRand(char *buf, u32_t bufLen); - -/* - * Return a new random number. - */ -u32_t avRandom(void); - - -#endif /* RANDM_H */ diff --git a/src/netif/ppp/readme.txt b/src/netif/ppp/readme.txt deleted file mode 100644 index 5be41b90..00000000 --- a/src/netif/ppp/readme.txt +++ /dev/null @@ -1,21 +0,0 @@ -About the PPP code: - -The PPP code is not our "own" code - we just copied it from pppd (http://ppp.samba.org/) and adapted it to lwIP. -Unfortunately, not many here know their way around it too well. Back in 2009, we took the effort to see which -version of pppd our code relates to and we're pretty much on 2.3.11 with some bugs from 2.4.x backported. - -Aside from simple code adaptions, there are some files that are different, however: -- chpms.c/.h are named chap_ms.c/.h in the original pppd 2.3.11 sources -- pap.c/.h are named upap.c/.h in the original pppd 2.3.11 sources -- randm.c is a random generator not included in the original pppd -- magic.c does not use the C library's random functions, but uses randm.c instead -- vj.c/.h is an implementation of the Van Jacobson header compression algorithm adapted to lwIP pbufs, - probably copied from one of the vjcompress.c files from pppd. -- ppp.c, ppp.h and ppp_impl.h contain the adaption from pppd to lwIP. This is the "OS"-dependent part like there - is an implementation for linux, xBSD etc. in the pppd sources. -- ppp_oe.c is Marc Boucher's implementation based on NetBSD's if_pppoe.c - -There is of course potential for bugs in it, but when analyzing of reporting bugs, it is strongly encouraged to -compare the code in question to pppd 2.3.11 (our basis) and newer versions (perhaps it's already fixed?) and to -share this knowledge with us when reporting a bug. - diff --git a/src/netif/ppp/session.c b/src/netif/ppp/session.c new file mode 100644 index 00000000..29c56f2e --- /dev/null +++ b/src/netif/ppp/session.c @@ -0,0 +1,423 @@ +/* + * session.c - PPP session control. + * + * Copyright (c) 2007 Diego Rivera. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Derived from auth.c, which is: + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#include +#include +#include +#include +#include +#ifdef HAS_SHADOW +#include +#endif +#include +#include +#include +#include +#include "pppd.h" +#include "session.h" + +#ifdef USE_PAM +#include +#endif /* #ifdef USE_PAM */ + +#define SET_MSG(var, msg) if (var != NULL) { var[0] = msg; } +#define COPY_STRING(s) ((s) ? strdup(s) : NULL) + +#define SUCCESS_MSG "Session started successfully" +#define ABORT_MSG "Session can't be started without a username" +#define SERVICE_NAME "ppp" + +#define SESSION_FAILED 0 +#define SESSION_OK 1 + +/* We have successfully started a session */ +static bool logged_in = 0; + +#ifdef USE_PAM +/* + * Static variables used to communicate between the conversation function + * and the server_login function + */ +static const char *PAM_username; +static const char *PAM_password; +static int PAM_session = 0; +static pam_handle_t *pamh = NULL; + +/* PAM conversation function + * Here we assume (for now, at least) that echo on means login name, and + * echo off means password. + */ + +static int conversation (int num_msg, +#ifndef SOL2 + const +#endif + struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + int replies = 0; + struct pam_response *reply = NULL; + + reply = malloc(sizeof(struct pam_response) * num_msg); + if (!reply) return PAM_CONV_ERR; + + for (replies = 0; replies < num_msg; replies++) { + switch (msg[replies]->msg_style) { + case PAM_PROMPT_ECHO_ON: + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = COPY_STRING(PAM_username); + /* PAM frees resp */ + break; + case PAM_PROMPT_ECHO_OFF: + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = COPY_STRING(PAM_password); + /* PAM frees resp */ + break; + case PAM_TEXT_INFO: + /* fall through */ + case PAM_ERROR_MSG: + /* ignore it, but pam still wants a NULL response... */ + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = NULL; + break; + default: + /* Must be an error of some sort... */ + free (reply); + return PAM_CONV_ERR; + } + } + *resp = reply; + return PAM_SUCCESS; +} + +static struct pam_conv pam_conv_data = { + &conversation, + NULL +}; +#endif /* #ifdef USE_PAM */ + +int +session_start(flags, user, passwd, ttyName, msg) + const int flags; + const char *user; + const char *passwd; + const char *ttyName; + char **msg; +{ +#ifdef USE_PAM + bool ok = 1; + const char *usr; + int pam_error; + bool try_session = 0; +#else /* #ifdef USE_PAM */ + struct passwd *pw; +#ifdef HAS_SHADOW + struct spwd *spwd; + struct spwd *getspnam(); + long now = 0; +#endif /* #ifdef HAS_SHADOW */ +#endif /* #ifdef USE_PAM */ + + SET_MSG(msg, SUCCESS_MSG); + + /* If no verification is requested, then simply return an OK */ + if (!(SESS_ALL & flags)) { + return SESSION_OK; + } + + if (user == NULL) { + SET_MSG(msg, ABORT_MSG); + return SESSION_FAILED; + } + +#ifdef USE_PAM + /* Find the '\\' in the username */ + /* This needs to be fixed to support different username schemes */ + if ((usr = strchr(user, '\\')) == NULL) + usr = user; + else + usr++; + + PAM_session = 0; + PAM_username = usr; + PAM_password = passwd; + + dbglog("Initializing PAM (%d) for user %s", flags, usr); + pam_error = pam_start (SERVICE_NAME, usr, &pam_conv_data, &pamh); + dbglog("---> PAM INIT Result = %d", pam_error); + ok = (pam_error == PAM_SUCCESS); + + if (ok) { + ok = (pam_set_item(pamh, PAM_TTY, ttyName) == PAM_SUCCESS) && + (pam_set_item(pamh, PAM_RHOST, ifname) == PAM_SUCCESS); + } + + if (ok && (SESS_AUTH & flags)) { + dbglog("Attempting PAM authentication"); + pam_error = pam_authenticate (pamh, PAM_SILENT); + if (pam_error == PAM_SUCCESS) { + /* PAM auth was OK */ + dbglog("PAM Authentication OK for %s", user); + } else { + /* No matter the reason, we fail because we're authenticating */ + ok = 0; + if (pam_error == PAM_USER_UNKNOWN) { + dbglog("User unknown, failing PAM authentication"); + SET_MSG(msg, "User unknown - cannot authenticate via PAM"); + } else { + /* Any other error means authentication was bad */ + dbglog("PAM Authentication failed: %d: %s", pam_error, + pam_strerror(pamh, pam_error)); + SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); + } + } + } + + if (ok && (SESS_ACCT & flags)) { + dbglog("Attempting PAM account checks"); + pam_error = pam_acct_mgmt (pamh, PAM_SILENT); + if (pam_error == PAM_SUCCESS) { + /* + * PAM account was OK, set the flag which indicates that we should + * try to perform the session checks. + */ + try_session = 1; + dbglog("PAM Account OK for %s", user); + } else { + /* + * If the account checks fail, then we should not try to perform + * the session check, because they don't make sense. + */ + try_session = 0; + if (pam_error == PAM_USER_UNKNOWN) { + /* + * We're checking the account, so it's ok to not have one + * because the user might come from the secrets files, or some + * other plugin. + */ + dbglog("User unknown, ignoring PAM restrictions"); + SET_MSG(msg, "User unknown - ignoring PAM restrictions"); + } else { + /* Any other error means session is rejected */ + ok = 0; + dbglog("PAM Account checks failed: %d: %s", pam_error, + pam_strerror(pamh, pam_error)); + SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); + } + } + } + + if (ok && try_session && (SESS_ACCT & flags)) { + /* Only open a session if the user's account was found */ + pam_error = pam_open_session (pamh, PAM_SILENT); + if (pam_error == PAM_SUCCESS) { + dbglog("PAM Session opened for user %s", user); + PAM_session = 1; + } else { + dbglog("PAM Session denied for user %s", user); + SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); + ok = 0; + } + } + + /* This is needed because apparently the PAM stuff closes the log */ + reopen_log(); + + /* If our PAM checks have already failed, then we must return a failure */ + if (!ok) return SESSION_FAILED; + +#else /* #ifdef USE_PAM */ + +/* + * Use the non-PAM methods directly. 'pw' will remain NULL if the user + * has not been authenticated using local UNIX system services. + */ + + pw = NULL; + if ((SESS_AUTH & flags)) { + pw = getpwnam(user); + + endpwent(); + /* + * Here, we bail if we have no user account, because there is nothing + * to verify against. + */ + if (pw == NULL) + return SESSION_FAILED; + +#ifdef HAS_SHADOW + + spwd = getspnam(user); + endspent(); + + /* + * If there is no shadow entry for the user, then we can't verify the + * account. + */ + if (spwd == NULL) + return SESSION_FAILED; + + /* + * We check validity all the time, because if the password has expired, + * then clearly we should not authenticate against it (if we're being + * called for authentication only). Thus, in this particular instance, + * there is no real difference between using the AUTH, SESS or ACCT + * flags, or combinations thereof. + */ + now = time(NULL) / 86400L; + if ((spwd->sp_expire > 0 && now >= spwd->sp_expire) + || ((spwd->sp_max >= 0 && spwd->sp_max < 10000) + && spwd->sp_lstchg >= 0 + && now >= spwd->sp_lstchg + spwd->sp_max)) { + warn("Password for %s has expired", user); + return SESSION_FAILED; + } + + /* We have a valid shadow entry, keep the password */ + pw->pw_passwd = spwd->sp_pwdp; + +#endif /* #ifdef HAS_SHADOW */ + + /* + * If no passwd, don't let them login if we're authenticating. + */ + if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2 + || strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0) + return SESSION_FAILED; + } + +#endif /* #ifdef USE_PAM */ + + /* + * Write a wtmp entry for this user. + */ + + if (SESS_ACCT & flags) { + if (strncmp(ttyName, "/dev/", 5) == 0) + ttyName += 5; + logwtmp(ttyName, user, ifname); /* Add wtmp login entry */ + logged_in = 1; + +#if defined(_PATH_LASTLOG) && !defined(USE_PAM) + /* + * Enter the user in lastlog only if he has been authenticated using + * local system services. If he has not, then we don't know what his + * UID might be, and lastlog is indexed by UID. + */ + if (pw != NULL) { + struct lastlog ll; + int fd; + time_t tnow; + + if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { + (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); + memset((void *)&ll, 0, sizeof(ll)); + (void)time(&tnow); + ll.ll_time = tnow; + (void)strncpy(ll.ll_line, ttyName, sizeof(ll.ll_line)); + (void)strncpy(ll.ll_host, ifname, sizeof(ll.ll_host)); + (void)write(fd, (char *)&ll, sizeof(ll)); + (void)close(fd); + } + } +#endif /* _PATH_LASTLOG and not USE_PAM */ + info("user %s logged in on tty %s intf %s", user, ttyName, ifname); + } + + return SESSION_OK; +} + +/* + * session_end - Logout the user. + */ +void +session_end(const char* ttyName) +{ +#ifdef USE_PAM + int pam_error = PAM_SUCCESS; + + if (pamh != NULL) { + if (PAM_session) pam_error = pam_close_session (pamh, PAM_SILENT); + PAM_session = 0; + pam_end (pamh, pam_error); + pamh = NULL; + /* Apparently the pam stuff does closelog(). */ + reopen_log(); + } +#endif + if (logged_in) { + if (strncmp(ttyName, "/dev/", 5) == 0) + ttyName += 5; + logwtmp(ttyName, "", ""); /* Wipe out utmp logout entry */ + logged_in = 0; + } +} diff --git a/src/netif/ppp/session.h b/src/netif/ppp/session.h new file mode 100644 index 00000000..bee8c412 --- /dev/null +++ b/src/netif/ppp/session.h @@ -0,0 +1,91 @@ +/* + * session.c - PPP session control. + * + * Copyright (c) 2007 Diego Rivera. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __SESSION_H +#define __SESSION_H + +#define SESS_AUTH 1 /* Check User Authentication */ +#define SESS_ACCT 2 /* Check Account Validity */ + +/* Convenience parameter to do the whole enchilada */ +#define SESS_ALL (SESS_AUTH | SESS_ACCT) + +/* + * int session_start(...) + * + * Start a session, performing any necessary validations. + * + * Parameters: + * const int flags : + * Any combination of the SESS_XXX flags, to indicate what the function + * should do as part of its checks + * + * const char* user : + * The username to validate. May safely be null. + * + * const char* passwd : + * The password to validate the user with. May safely be null. + * + * const char* tty : + * The TTY the user is connected on. May safely be null. + * + * char** msg : + * A char* to return an error or success message. This message will be returned + * regardless of the result. May safely be null. + * + * Return Value: + * Zero value for failure, non-zero value for successful session verification. + */ +int +session_start(const int flags, const char* user, const char* passwd, const char* tty, char** msg); + +/* Added these macros for convenience... */ +#define session_auth(user, pass, tty, msg) \ + session_start(SESS_AUTH, user, pass, tty, msg) + +#define session_check(user, pass, tty, msg) \ + session_start(SESS_ACCT, user, pass, tty, msg) + +#define session_full(user, pass, tty, msg) \ + session_start(SESS_ALL, user, pass, tty, msg) + +/* + * void session_end(...) + * + * End a previously-started session. + * + * Parameters: + * const char* tty : + * The TTY the user is connected on. May safely be null. + */ +void +session_end(const char* tty); + +#endif diff --git a/src/netif/ppp/sha1.c b/src/netif/ppp/sha1.c new file mode 100644 index 00000000..3b020b8f --- /dev/null +++ b/src/netif/ppp/sha1.c @@ -0,0 +1,172 @@ +/* + * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c + * + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + * + * Test Vectors (from FIPS PUB 180-1) + * "abc" + * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + * A million repetitions of "a" + * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F + */ + +#include "lwip/opt.h" + +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#include +#include /* htonl() */ +#include +#include "sha1.h" + +static void +SHA1_Transform(u_int32_t[5], const unsigned char[64]); + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#define blk0(i) (block->l[i] = htonl(block->l[i])) +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +static void +SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64]) +{ + u_int32_t a, b, c, d, e; + typedef union { + unsigned char c[64]; + u_int32_t l[16]; + } CHAR64LONG16; + CHAR64LONG16 *block; + +#ifdef SHA1HANDSOFF + static unsigned char workspace[64]; + block = (CHAR64LONG16 *) workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16 *) buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void +SHA1_Init(SHA1_CTX *context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void +SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) +{ + unsigned int i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + i = 64 - j; + while (len >= i) { + memcpy(&context->buffer[j], data, i); + SHA1_Transform(context->state, context->buffer); + data += i; + len -= i; + i = 64; + j = 0; + } + + memcpy(&context->buffer[j], data, len); +} + + +/* Add padding and return the message digest. */ + +void +SHA1_Final(unsigned char digest[20], SHA1_CTX *context) +{ + u_int32_t i, j; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1_Update(context, (unsigned char *) "\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1_Update(context, (unsigned char *) "\0", 1); + } + SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = j = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ + SHA1Transform(context->state, context->buffer); +#endif +} + diff --git a/src/netif/ppp/sha1.h b/src/netif/ppp/sha1.h new file mode 100644 index 00000000..83f64df2 --- /dev/null +++ b/src/netif/ppp/sha1.h @@ -0,0 +1,31 @@ +/* sha1.h */ + +/* If OpenSSL is in use, then use that version of SHA-1 */ +#ifdef OPENSSL +#include +#define __SHA1_INCLUDE_ +#endif + +#ifndef __SHA1_INCLUDE_ + +#ifndef SHA1_SIGNATURE_SIZE +#ifdef SHA_DIGESTSIZE +#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE +#else +#define SHA1_SIGNATURE_SIZE 20 +#endif +#endif + +typedef struct { + u_int32_t state[5]; + u_int32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +extern void SHA1_Init(SHA1_CTX *); +extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int); +extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *); + +#define __SHA1_INCLUDE_ +#endif /* __SHA1_INCLUDE_ */ + diff --git a/src/netif/ppp/spinlock.c b/src/netif/ppp/spinlock.c new file mode 100644 index 00000000..3e3e3cb1 --- /dev/null +++ b/src/netif/ppp/spinlock.c @@ -0,0 +1,476 @@ +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Anton Blanchard 2001 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "lwip/opt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" +#include "spinlock.h" + +#define DEBUG + +#ifdef USE_SPINLOCKS + +/* + * ARCH SPECIFIC + */ + +#if defined(SPARC_SPINLOCKS) + +static inline int __spin_trylock(spinlock_t *lock) +{ + unsigned int result; + + asm volatile("ldstub [%1], %0" + : "=r" (result) + : "r" (lock) + : "memory"); + + return (result == 0) ? 0 : EBUSY; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + asm volatile("":::"memory"); + *lock = 0; +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + *lock = 0; +} + +static inline int __spin_is_locked(spinlock_t *lock) +{ + return (*lock != 0); +} + +#elif defined(POWERPC_SPINLOCKS) + +static inline int __spin_trylock(spinlock_t *lock) +{ + unsigned int result; + + __asm__ __volatile__( +"1: lwarx %0,0,%1\n\ + cmpwi 0,%0,0\n\ + li %0,0\n\ + bne- 2f\n\ + li %0,1\n\ + stwcx. %0,0,%1\n\ + bne- 1b\n\ + isync\n\ +2:" : "=&r"(result) + : "r"(lock) + : "cr0", "memory"); + + return (result == 1) ? 0 : EBUSY; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + asm volatile("eieio":::"memory"); + *lock = 0; +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + *lock = 0; +} + +static inline int __spin_is_locked(spinlock_t *lock) +{ + return (*lock != 0); +} + +#elif defined(INTEL_SPINLOCKS) + +static inline int __spin_trylock(spinlock_t *lock) +{ + int oldval; + + asm volatile("xchgl %0,%1" + : "=r" (oldval), "=m" (*lock) + : "0" (0) + : "memory"); + + return oldval > 0 ? 0 : EBUSY; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + asm volatile("":::"memory"); + *lock = 1; +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + *lock = 1; +} + +static inline int __spin_is_locked(spinlock_t *lock) +{ + return (*lock != 1); +} + +#elif defined(MIPS_SPINLOCKS) && defined(sgi) && (_COMPILER_VERSION >= 730) + +/* Implement spinlocks on IRIX using the MIPSPro atomic fetch operations. See + * sync(3) for the details of the intrinsic operations. + * + * "sgi" and "_COMPILER_VERSION" are always defined by MIPSPro. + */ + +#ifdef STANDALONE + +/* MIPSPro 7.3 has "__inline" as an extension, but not "inline. */ +#define inline __inline + +#endif /* STANDALONE */ + +/* Returns 0 if the lock is acquired, EBUSY otherwise. */ +static inline int __spin_trylock(spinlock_t *lock) +{ + unsigned int val; + val = __lock_test_and_set(lock, 1); + return val == 0 ? 0 : EBUSY; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + __lock_release(lock); +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + __lock_release(lock); +} + +/* Returns 1 if the lock is held, 0 otherwise. */ +static inline int __spin_is_locked(spinlock_t *lock) +{ + unsigned int val; + val = __add_and_fetch(lock, 0); + return val; +} + +#elif defined(MIPS_SPINLOCKS) + +static inline unsigned int load_linked(unsigned long addr) +{ + unsigned int res; + + __asm__ __volatile__("ll\t%0,(%1)" + : "=r" (res) + : "r" (addr)); + + return res; +} + +static inline unsigned int store_conditional(unsigned long addr, unsigned int value) +{ + unsigned int res; + + __asm__ __volatile__("sc\t%0,(%2)" + : "=r" (res) + : "0" (value), "r" (addr)); + return res; +} + +static inline int __spin_trylock(spinlock_t *lock) +{ + unsigned int mw; + + do { + mw = load_linked(lock); + if (mw) + return EBUSY; + } while (!store_conditional(lock, 1)); + + asm volatile("":::"memory"); + + return 0; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + asm volatile("":::"memory"); + *lock = 0; +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + *lock = 0; +} + +static inline int __spin_is_locked(spinlock_t *lock) +{ + return (*lock != 0); +} + +#else +#error Need to implement spinlock code in spinlock.c +#endif + +/* + * OS SPECIFIC + */ + +static void yield_cpu(void) +{ + struct timespec tm; + +#ifdef USE_SCHED_YIELD + sched_yield(); +#else + /* Linux will busy loop for delays < 2ms on real time tasks */ + tm.tv_sec = 0; + tm.tv_nsec = 2000000L + 1; + nanosleep(&tm, NULL); +#endif +} + +static int this_is_smp(void) +{ +#if defined(HAVE_SYSCONF) && defined(SYSCONF_SC_NPROC_ONLN) + return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0; +#else + return 0; +#endif +} + +/* + * GENERIC + */ + +static int smp_machine = 0; + +static inline void __spin_lock(spinlock_t *lock) +{ + int ntries = 0; + + while(__spin_trylock(lock)) { + while(__spin_is_locked(lock)) { + if (smp_machine && ntries++ < MAX_BUSY_LOOPS) + continue; + yield_cpu(); + } + } +} + +static void __read_lock(tdb_rwlock_t *rwlock) +{ + int ntries = 0; + + while(1) { + __spin_lock(&rwlock->lock); + + if (!(rwlock->count & RWLOCK_BIAS)) { + rwlock->count++; + __spin_unlock(&rwlock->lock); + return; + } + + __spin_unlock(&rwlock->lock); + + while(rwlock->count & RWLOCK_BIAS) { + if (smp_machine && ntries++ < MAX_BUSY_LOOPS) + continue; + yield_cpu(); + } + } +} + +static void __write_lock(tdb_rwlock_t *rwlock) +{ + int ntries = 0; + + while(1) { + __spin_lock(&rwlock->lock); + + if (rwlock->count == 0) { + rwlock->count |= RWLOCK_BIAS; + __spin_unlock(&rwlock->lock); + return; + } + + __spin_unlock(&rwlock->lock); + + while(rwlock->count != 0) { + if (smp_machine && ntries++ < MAX_BUSY_LOOPS) + continue; + yield_cpu(); + } + } +} + +static void __write_unlock(tdb_rwlock_t *rwlock) +{ + __spin_lock(&rwlock->lock); + +#ifdef DEBUG + if (!(rwlock->count & RWLOCK_BIAS)) + fprintf(stderr, "bug: write_unlock\n"); +#endif + + rwlock->count &= ~RWLOCK_BIAS; + __spin_unlock(&rwlock->lock); +} + +static void __read_unlock(tdb_rwlock_t *rwlock) +{ + __spin_lock(&rwlock->lock); + +#ifdef DEBUG + if (!rwlock->count) + fprintf(stderr, "bug: read_unlock\n"); + + if (rwlock->count & RWLOCK_BIAS) + fprintf(stderr, "bug: read_unlock\n"); +#endif + + rwlock->count--; + __spin_unlock(&rwlock->lock); +} + +/* TDB SPECIFIC */ + +/* lock a list in the database. list -1 is the alloc list */ +int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) +{ + tdb_rwlock_t *rwlocks; + + if (!tdb->map_ptr) return -1; + rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); + + switch(rw_type) { + case F_RDLCK: + __read_lock(&rwlocks[list+1]); + break; + + case F_WRLCK: + __write_lock(&rwlocks[list+1]); + break; + + default: + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + return 0; +} + +/* unlock the database. */ +int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) +{ + tdb_rwlock_t *rwlocks; + + if (!tdb->map_ptr) return -1; + rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); + + switch(rw_type) { + case F_RDLCK: + __read_unlock(&rwlocks[list+1]); + break; + + case F_WRLCK: + __write_unlock(&rwlocks[list+1]); + break; + + default: + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + + return 0; +} + +int tdb_create_rwlocks(int fd, unsigned int hash_size) +{ + unsigned size, i; + tdb_rwlock_t *rwlocks; + + size = TDB_SPINLOCK_SIZE(hash_size); + rwlocks = malloc(size); + if (!rwlocks) + return -1; + + for(i = 0; i < hash_size+1; i++) { + __spin_lock_init(&rwlocks[i].lock); + rwlocks[i].count = 0; + } + + /* Write it out (appending to end) */ + if (write(fd, rwlocks, size) != size) { + free(rwlocks); + return -1; + } + smp_machine = this_is_smp(); + free(rwlocks); + return 0; +} + +int tdb_clear_spinlocks(TDB_CONTEXT *tdb) +{ + tdb_rwlock_t *rwlocks; + unsigned i; + + if (tdb->header.rwlocks == 0) return 0; + if (!tdb->map_ptr) return -1; + + /* We're mmapped here */ + rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); + for(i = 0; i < tdb->header.hash_size+1; i++) { + __spin_lock_init(&rwlocks[i].lock); + rwlocks[i].count = 0; + } + return 0; +} +#else +int tdb_create_rwlocks(int fd, unsigned int hash_size) { return 0; } +int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } +int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } + +/* Non-spinlock version: remove spinlock pointer */ +int tdb_clear_spinlocks(TDB_CONTEXT *tdb) +{ + tdb_off off = (tdb_off)((char *)&tdb->header.rwlocks + - (char *)&tdb->header); + + tdb->header.rwlocks = 0; + if (lseek(tdb->fd, off, SEEK_SET) != off + || write(tdb->fd, (void *)&tdb->header.rwlocks, + sizeof(tdb->header.rwlocks)) + != sizeof(tdb->header.rwlocks)) + return -1; + return 0; +} +#endif diff --git a/src/netif/ppp/spinlock.h b/src/netif/ppp/spinlock.h new file mode 100644 index 00000000..967fe374 --- /dev/null +++ b/src/netif/ppp/spinlock.h @@ -0,0 +1,59 @@ +#ifndef __SPINLOCK_H__ +#define __SPINLOCK_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "tdb.h" + +#ifdef USE_SPINLOCKS + +#define RWLOCK_BIAS 0x1000UL + +/* OS SPECIFIC */ +#define MAX_BUSY_LOOPS 1000 +#undef USE_SCHED_YIELD + +/* ARCH SPECIFIC */ +/* We should make sure these are padded to a cache line */ +#if defined(SPARC_SPINLOCKS) +typedef volatile char spinlock_t; +#elif defined(POWERPC_SPINLOCKS) +typedef volatile unsigned long spinlock_t; +#elif defined(INTEL_SPINLOCKS) +typedef volatile int spinlock_t; +#elif defined(MIPS_SPINLOCKS) +typedef volatile unsigned long spinlock_t; +#else +#error Need to implement spinlock code in spinlock.h +#endif + +typedef struct { + spinlock_t lock; + volatile int count; +} tdb_rwlock_t; + +int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); +int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); +int tdb_create_rwlocks(int fd, unsigned int hash_size); +int tdb_clear_spinlocks(TDB_CONTEXT *tdb); + +#define TDB_SPINLOCK_SIZE(hash_size) (((hash_size) + 1) * sizeof(tdb_rwlock_t)) + +#else /* !USE_SPINLOCKS */ +#if 0 +#define tdb_create_rwlocks(fd, hash_size) 0 +#define tdb_spinlock(tdb, list, rw_type) (-1) +#define tdb_spinunlock(tdb, list, rw_type) (-1) +#else +int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); +int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); +int tdb_create_rwlocks(int fd, unsigned int hash_size); +#endif +int tdb_clear_spinlocks(TDB_CONTEXT *tdb); +#define TDB_SPINLOCK_SIZE(hash_size) 0 + +#endif + +#endif diff --git a/src/netif/ppp/sys-linux.c b/src/netif/ppp/sys-linux.c new file mode 100644 index 00000000..48a46d60 --- /dev/null +++ b/src/netif/ppp/sys-linux.c @@ -0,0 +1,2922 @@ +/* + * sys-linux.c - System-dependent procedures for setting up + * PPP interfaces on Linux systems + * + * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Derived from main.c and pppd.h, which are: + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* This is in netdevice.h. However, this compile will fail miserably if + you attempt to include netdevice.h because it has so many references + to __memcpy functions which it should not attempt to do. So, since I + really don't use it, but it must be defined, define it now. */ + +#ifndef MAX_ADDR_LEN +#define MAX_ADDR_LEN 7 +#endif + +#if __GLIBC__ >= 2 +#include /* glibc 2 conflicts with linux/types.h */ +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif +#include +#include + +#include +#include + +#include "pppd.h" +#include "fsm.h" +#include "ipcp.h" + +#ifdef IPX_CHANGE +#include "ipxcp.h" +#if __GLIBC__ >= 2 && \ + !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0) +#include +#else +#include +#endif +#endif /* IPX_CHANGE */ + +#ifdef PPP_FILTER +#include +#include +#endif /* PPP_FILTER */ + +#ifdef LOCKLIB +#include +#endif + +#ifdef INET6 +#ifndef _LINUX_IN6_H +/* + * This is in linux/include/net/ipv6.h. + */ + +struct in6_ifreq { + struct in6_addr ifr6_addr; + __u32 ifr6_prefixlen; + unsigned int ifr6_ifindex; +}; +#endif + +#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \ + memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \ + sin6.s6_addr16[0] = htons(0xfe80); \ + eui64_copy(eui64, sin6.s6_addr32[2]); \ + } while (0) + +#endif /* INET6 */ + +/* We can get an EIO error on an ioctl if the modem has hung up */ +#define ok_error(num) ((num)==EIO) + +static int tty_disc = N_TTY; /* The TTY discipline */ +static int ppp_disc = N_PPP; /* The PPP discpline */ +static int initfdflags = -1; /* Initial file descriptor flags for fd */ +static int ppp_fd = -1; /* fd which is set to PPP discipline */ +static int sock_fd = -1; /* socket for doing interface ioctls */ +static int slave_fd = -1; /* pty for old-style demand mode, slave */ +static int master_fd = -1; /* pty for old-style demand mode, master */ +#ifdef INET6 +static int sock6_fd = -1; +#endif /* INET6 */ + +/* + * For the old-style kernel driver, this is the same as ppp_fd. + * For the new-style driver, it is the fd of an instance of /dev/ppp + * which is attached to the ppp unit and is used for controlling it. + */ +int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */ + +static int chindex; /* channel index (new style driver) */ + +static fd_set in_fds; /* set of fds that wait_input waits for */ +static int max_in_fd; /* highest fd set in in_fds */ + +static int has_proxy_arp = 0; +static int driver_version = 0; +static int driver_modification = 0; +static int driver_patch = 0; +static int driver_is_old = 0; +static int restore_term = 0; /* 1 => we've munged the terminal */ +static struct termios inittermios; /* Initial TTY termios */ + +int new_style_driver = 0; + +static char loop_name[20]; +static unsigned char inbuf[512]; /* buffer for chars read from loopback */ + +static int if_is_up; /* Interface has been marked up */ +static int have_default_route; /* Gateway for default route added */ +static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ +static char proxy_arp_dev[16]; /* Device for proxy arp entry */ +static u_int32_t our_old_addr; /* for detecting address changes */ +static int dynaddr_set; /* 1 if ip_dynaddr set */ +static int looped; /* 1 if using loop */ +static int link_mtu; /* mtu for the link (not bundle) */ + +static struct utsname utsname; /* for the kernel version */ +static int kernel_version; +#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p)) + +#define MAX_IFS 100 + +#define FLAGS_GOOD (IFF_UP | IFF_BROADCAST) +#define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \ + IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP) + +#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr) + +/* Prototypes for procedures local to this file. */ +static int modify_flags(int fd, int clear_bits, int set_bits); +static int translate_speed (int bps); +static int baud_rate_of (int speed); +static void close_route_table (void); +static int open_route_table (void); +static int read_route_table (struct rtentry *rt); +static int defaultroute_exists (struct rtentry *rt); +static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, + char *name, int namelen); +static void decode_version (char *buf, int *version, int *mod, int *patch); +static int set_kdebugflag(int level); +static int ppp_registered(void); +static int make_ppp_unit(void); + +extern u_char inpacket_buf[]; /* borrowed from main.c */ + +/* + * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, + * if it exists. + */ + +#define SET_SA_FAMILY(addr, family) \ + memset ((char *) &(addr), '\0', sizeof(addr)); \ + addr.sa_family = (family); + +/* + * Determine if the PPP connection should still be present. + */ + +extern int hungup; + +/* new_fd is the fd of a tty */ +static void set_ppp_fd (int new_fd) +{ + ppp_fd = new_fd; + if (!new_style_driver) + ppp_dev_fd = new_fd; +} + +static int still_ppp(void) +{ + if (new_style_driver) + return !hungup && ppp_fd >= 0; + if (!hungup || ppp_fd == slave_fd) + return 1; + if (slave_fd >= 0) { + set_ppp_fd(slave_fd); + return 1; + } + return 0; +} + +/* + * modify_flags - set and clear flag bits controlling the kernel + * PPP driver. + */ +static int modify_flags(int fd, int clear_bits, int set_bits) +{ + int flags; + + if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1) + goto err; + flags = (flags & ~clear_bits) | set_bits; + if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1) + goto err; + + return 0; + + err: + if (errno != EIO) + error("Failed to set PPP kernel option flags: %m"); + return -1; +} + +/******************************************************************** + * + * sys_init - System-dependent initialization. + */ + +void linux_sys_init(void) +{ + /* Get an internet socket for doing socket ioctls. */ + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + fatal("Couldn't create IP socket: %m(%d)", errno); + +#ifdef INET6 + sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (sock6_fd < 0) + sock6_fd = -errno; /* save errno for later */ +#endif + + FD_ZERO(&in_fds); + max_in_fd = 0; +} + +/******************************************************************** + * + * sys_cleanup - restore any system state we modified before exiting: + * mark the interface down, delete default route and/or proxy arp entry. + * This shouldn't call die() because it's called from die(). + */ + +void sys_cleanup(void) +{ +/* + * Take down the device + */ + if (if_is_up) { + if_is_up = 0; + sifdown(0); + } +/* + * Delete any routes through the device. + */ + if (have_default_route) + cifdefaultroute(0, 0, 0); + + if (has_proxy_arp) + cifproxyarp(0, proxy_arp_addr); +} + +/******************************************************************** + * + * sys_close - Clean up in a child process before execing. + */ +void +sys_close(void) +{ + if (new_style_driver && ppp_dev_fd >= 0) + close(ppp_dev_fd); + if (sock_fd >= 0) + close(sock_fd); +#ifdef INET6 + if (sock6_fd >= 0) + close(sock6_fd); +#endif + if (slave_fd >= 0) + close(slave_fd); + if (master_fd >= 0) + close(master_fd); +} + +/******************************************************************** + * + * set_kdebugflag - Define the debugging level for the kernel + */ + +static int set_kdebugflag (int requested_level) +{ + if (ppp_dev_fd < 0) + return 1; + if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) { + if ( ! ok_error (errno) ) + error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__); + return (0); + } + return (1); +} + +/******************************************************************** + * + * tty_establish_ppp - Turn the serial port into a ppp interface. + */ + +int tty_establish_ppp (int tty_fd) +{ + int ret_fd; + +/* + * Ensure that the tty device is in exclusive mode. + */ + if (ioctl(tty_fd, TIOCEXCL, 0) < 0) { + if ( ! ok_error ( errno )) + warn("Couldn't make tty exclusive: %m"); + } +/* + * Demand mode - prime the old ppp device to relinquish the unit. + */ + if (!new_style_driver && looped + && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) { + error("ioctl(transfer ppp unit): %m, line %d", __LINE__); + return -1; + } +/* + * Set the current tty to the PPP discpline + */ + +#ifndef N_SYNC_PPP +#define N_SYNC_PPP 14 +#endif + ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP; + if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) { + if ( ! ok_error (errno) ) { + error("Couldn't set tty to PPP discipline: %m"); + return -1; + } + } + + ret_fd = generic_establish_ppp(tty_fd); + +#define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP) +#define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \ + | SC_LOG_FLUSH) + + if (ret_fd >= 0) { + modify_flags(ppp_fd, SC_RCVB | SC_LOGB, + (kdebugflag * SC_DEBUG) & SC_LOGB); + } else { + if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno)) + warn("Couldn't reset tty to normal line discipline: %m"); + } + + return ret_fd; +} + +/******************************************************************** + * + * generic_establish_ppp - Turn the fd into a ppp interface. + */ +int generic_establish_ppp (int fd) +{ + int x; + + if (new_style_driver) { + int flags; + + /* Open an instance of /dev/ppp and connect the channel to it */ + if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) { + error("Couldn't get channel number: %m"); + goto err; + } + dbglog("using channel %d", chindex); + fd = open("/dev/ppp", O_RDWR); + if (fd < 0) { + error("Couldn't reopen /dev/ppp: %m"); + goto err; + } + (void) fcntl(fd, F_SETFD, FD_CLOEXEC); + if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) { + error("Couldn't attach to channel %d: %m", chindex); + goto err_close; + } + flags = fcntl(fd, F_GETFL); + if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) + warn("Couldn't set /dev/ppp (channel) to nonblock: %m"); + set_ppp_fd(fd); + + if (!looped) + ifunit = -1; + if (!looped && !multilink) { + /* + * Create a new PPP unit. + */ + if (make_ppp_unit() < 0) + goto err_close; + } + + if (looped) + modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0); + + if (!multilink) { + add_fd(ppp_dev_fd); + if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) { + error("Couldn't attach to PPP unit %d: %m", ifunit); + goto err_close; + } + } + + } else { + /* + * Old-style driver: find out which interface we were given. + */ + set_ppp_fd (fd); + if (ioctl(fd, PPPIOCGUNIT, &x) < 0) { + if (ok_error (errno)) + goto err; + fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__); + } + /* Check that we got the same unit again. */ + if (looped && x != ifunit) + fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x); + ifunit = x; + + /* + * Fetch the initial file flags and reset blocking mode on the file. + */ + initfdflags = fcntl(fd, F_GETFL); + if (initfdflags == -1 || + fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { + if ( ! ok_error (errno)) + warn("Couldn't set device to non-blocking mode: %m"); + } + } + + /* + * Enable debug in the driver if requested. + */ + if (!looped) + set_kdebugflag (kdebugflag); + + looped = 0; + + return ppp_fd; + + err_close: + close(fd); + err: + return -1; +} + +/******************************************************************** + * + * tty_disestablish_ppp - Restore the serial port to normal operation. + * This shouldn't call die() because it's called from die(). + */ + +void tty_disestablish_ppp(int tty_fd) +{ + if (!hungup) { +/* + * Flush the tty output buffer so that the TIOCSETD doesn't hang. + */ + if (tcflush(tty_fd, TCIOFLUSH) < 0) + { + warn("tcflush failed: %m"); + goto flushfailed; + } +/* + * Restore the previous line discipline + */ + if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) { + if ( ! ok_error (errno)) + error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__); + } + + if (ioctl(tty_fd, TIOCNXCL, 0) < 0) { + if ( ! ok_error (errno)) + warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__); + } + + /* Reset non-blocking mode on fd. */ + if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) { + if ( ! ok_error (errno)) + warn("Couldn't restore device fd flags: %m"); + } + } +flushfailed: + initfdflags = -1; + + generic_disestablish_ppp(tty_fd); +} + +/******************************************************************** + * + * generic_disestablish_ppp - Restore device components to normal + * operation, and reconnect the ppp unit to the loopback if in demand + * mode. This shouldn't call die() because it's called from die(). + */ +void generic_disestablish_ppp(int dev_fd) +{ + if (new_style_driver) { + close(ppp_fd); + ppp_fd = -1; + if (demand) { + modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC); + looped = 1; + } else if (!doing_multilink && ppp_dev_fd >= 0) { + close(ppp_dev_fd); + remove_fd(ppp_dev_fd); + ppp_dev_fd = -1; + } + } else { + /* old-style driver */ + if (demand) + set_ppp_fd(slave_fd); + else + ppp_dev_fd = -1; + } +} + +/* + * make_ppp_unit - make a new ppp unit for ppp_dev_fd. + * Assumes new_style_driver. + */ +static int make_ppp_unit() +{ + int x, flags; + + if (ppp_dev_fd >= 0) { + dbglog("in make_ppp_unit, already had /dev/ppp open?"); + close(ppp_dev_fd); + } + ppp_dev_fd = open("/dev/ppp", O_RDWR); + if (ppp_dev_fd < 0) + fatal("Couldn't open /dev/ppp: %m"); + flags = fcntl(ppp_dev_fd, F_GETFL); + if (flags == -1 + || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) + warn("Couldn't set /dev/ppp to nonblock: %m"); + + ifunit = req_unit; + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + if (x < 0 && req_unit >= 0 && errno == EEXIST) { + warn("Couldn't allocate PPP unit %d as it is already in use", req_unit); + ifunit = -1; + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + } + if (x < 0) + error("Couldn't create new ppp unit: %m"); + return x; +} + +/* + * cfg_bundle - configure the existing bundle. + * Used in demand mode. + */ +void cfg_bundle(int mrru, int mtru, int rssn, int tssn) +{ + if (!new_style_driver) + return; + + /* set the mrru, mtu and flags */ + if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0) + error("Couldn't set MRRU: %m"); + + modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK, + ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0) + | (mrru? SC_MULTILINK: 0))); + + /* connect up the channel */ + if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0) + fatal("Couldn't attach to PPP unit %d: %m", ifunit); + add_fd(ppp_dev_fd); +} + +/* + * make_new_bundle - create a new PPP unit (i.e. a bundle) + * and connect our channel to it. This should only get called + * if `multilink' was set at the time establish_ppp was called. + * In demand mode this uses our existing bundle instead of making + * a new one. + */ +void make_new_bundle(int mrru, int mtru, int rssn, int tssn) +{ + if (!new_style_driver) + return; + + /* make us a ppp unit */ + if (make_ppp_unit() < 0) + die(1); + + /* set the mrru and flags */ + cfg_bundle(mrru, mtru, rssn, tssn); +} + +/* + * bundle_attach - attach our link to a given PPP unit. + * We assume the unit is controlled by another pppd. + */ +int bundle_attach(int ifnum) +{ + int master_fd; + + if (!new_style_driver) + return -1; + + master_fd = open("/dev/ppp", O_RDWR); + if (master_fd < 0) + fatal("Couldn't open /dev/ppp: %m"); + if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) { + if (errno == ENXIO) { + close(master_fd); + return 0; /* doesn't still exist */ + } + fatal("Couldn't attach to interface unit %d: %m\n", ifnum); + } + if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0) + fatal("Couldn't connect to interface unit %d: %m", ifnum); + modify_flags(master_fd, 0, SC_MULTILINK); + close(master_fd); + + ifunit = ifnum; + return 1; +} + +/* + * destroy_bundle - tell the driver to destroy our bundle. + */ +void destroy_bundle(void) +{ + if (ppp_dev_fd >= 0) { + close(ppp_dev_fd); + remove_fd(ppp_dev_fd); + ppp_dev_fd = -1; + } +} + +/******************************************************************** + * + * clean_check - Fetch the flags for the device and generate + * appropriate error messages. + */ +void clean_check(void) +{ + int x; + char *s; + + if (still_ppp()) { + 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 = "all had bit 7 set to 1"; + break; + + case SC_RCV_B7_1: + s = "all had bit 7 set to 0"; + break; + + case SC_RCV_EVNP: + s = "all had odd parity"; + break; + + case SC_RCV_ODDP: + s = "all had even parity"; + break; + } + + if (s != NULL) { + warn("Receive serial link is not 8-bit clean:"); + warn("Problem: %s", s); + } + } + } +} + + +/* + * List of valid speeds. + */ + +struct speed { + int speed_int, speed_val; +} speeds[] = { +#ifdef B50 + { 50, B50 }, +#endif +#ifdef B75 + { 75, B75 }, +#endif +#ifdef B110 + { 110, B110 }, +#endif +#ifdef B134 + { 134, B134 }, +#endif +#ifdef B150 + { 150, B150 }, +#endif +#ifdef B200 + { 200, B200 }, +#endif +#ifdef B300 + { 300, B300 }, +#endif +#ifdef B600 + { 600, B600 }, +#endif +#ifdef B1200 + { 1200, B1200 }, +#endif +#ifdef B1800 + { 1800, B1800 }, +#endif +#ifdef B2000 + { 2000, B2000 }, +#endif +#ifdef B2400 + { 2400, B2400 }, +#endif +#ifdef B3600 + { 3600, B3600 }, +#endif +#ifdef B4800 + { 4800, B4800 }, +#endif +#ifdef B7200 + { 7200, B7200 }, +#endif +#ifdef B9600 + { 9600, B9600 }, +#endif +#ifdef B19200 + { 19200, B19200 }, +#endif +#ifdef B38400 + { 38400, B38400 }, +#endif +#ifdef B57600 + { 57600, B57600 }, +#endif +#ifdef B76800 + { 76800, B76800 }, +#endif +#ifdef B115200 + { 115200, B115200 }, +#endif +#ifdef EXTA + { 19200, EXTA }, +#endif +#ifdef EXTB + { 38400, EXTB }, +#endif +#ifdef B230400 + { 230400, B230400 }, +#endif +#ifdef B460800 + { 460800, B460800 }, +#endif +#ifdef B921600 + { 921600, B921600 }, +#endif +#ifdef B1000000 + { 1000000, B1000000 }, +#endif +#ifdef B1152000 + { 1152000, B1152000 }, +#endif +#ifdef B1500000 + { 1500000, B1500000 }, +#endif +#ifdef B2000000 + { 2000000, B2000000 }, +#endif +#ifdef B2500000 + { 2500000, B2500000 }, +#endif +#ifdef B3000000 + { 3000000, B3000000 }, +#endif +#ifdef B3500000 + { 3500000, B3500000 }, +#endif +#ifdef B4000000 + { 4000000, B4000000 }, +#endif + { 0, 0 } +}; + +/******************************************************************** + * + * Translate from bits/second to a speed_t. + */ + +static int translate_speed (int bps) +{ + struct speed *speedp; + + if (bps != 0) { + for (speedp = speeds; speedp->speed_int; speedp++) { + if (bps == speedp->speed_int) + return speedp->speed_val; + } + warn("speed %d not supported", bps); + } + return 0; +} + +/******************************************************************** + * + * Translate from a speed_t to bits/second. + */ + +static int baud_rate_of (int speed) +{ + struct speed *speedp; + + if (speed != 0) { + for (speedp = speeds; speedp->speed_int; speedp++) { + if (speed == speedp->speed_val) + return speedp->speed_int; + } + } + return 0; +} + +/******************************************************************** + * + * 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. + */ + +void set_up_tty(int tty_fd, int local) +{ + int speed; + struct termios tios; + + setdtr(tty_fd, 1); + if (tcgetattr(tty_fd, &tios) < 0) { + if (!ok_error(errno)) + fatal("tcgetattr: %m (line %d)", __LINE__); + return; + } + + if (!restore_term) + inittermios = tios; + + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); + tios.c_cflag |= CS8 | CREAD | HUPCL; + + tios.c_iflag = IGNBRK | IGNPAR; + tios.c_oflag = 0; + tios.c_lflag = 0; + tios.c_cc[VMIN] = 1; + tios.c_cc[VTIME] = 0; + + if (local || !modem) + tios.c_cflag ^= (CLOCAL | HUPCL); + + switch (crtscts) { + case 1: + tios.c_cflag |= CRTSCTS; + break; + + case -2: + tios.c_iflag |= IXON | IXOFF; + tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ + tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ + break; + + case -1: + tios.c_cflag &= ~CRTSCTS; + break; + + default: + break; + } + + speed = translate_speed(inspeed); + if (speed) { + cfsetospeed (&tios, speed); + cfsetispeed (&tios, speed); + } +/* + * We can't proceed if the serial port speed is B0, + * since that implies that the serial port is disabled. + */ + else { + speed = cfgetospeed(&tios); + if (speed == B0) + fatal("Baud rate for %s is 0; need explicit baud rate", devnam); + } + + while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno)) + if (errno != EINTR) + fatal("tcsetattr: %m (line %d)", __LINE__); + + baud_rate = baud_rate_of(speed); + restore_term = 1; +} + +/******************************************************************** + * + * setdtr - control the DTR line on the serial port. + * This is called from die(), so it shouldn't call die(). + */ + +void setdtr (int tty_fd, int on) +{ + int modembits = TIOCM_DTR; + + ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits); +} + +/******************************************************************** + * + * restore_tty - restore the terminal to the saved settings. + */ + +void restore_tty (int tty_fd) +{ + if (restore_term) { + restore_term = 0; +/* + * 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. + */ + if (!default_device) + inittermios.c_lflag &= ~(ECHO | ECHONL); + + if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) { + if (! ok_error (errno)) + warn("tcsetattr: %m (line %d)", __LINE__); + } + } +} + +/******************************************************************** + * + * output - Output PPP packet. + */ + +void old_output (int unit, unsigned char *p, int len) +{ + int fd = ppp_fd; + int proto; + + dump_packet("sent", p, len); + if (snoop_send_hook) snoop_send_hook(p, len); + + if (len < PPP_HDRLEN) + return; + if (new_style_driver) { + p += 2; + len -= 2; + proto = (p[0] << 8) + p[1]; + if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG)) + fd = ppp_dev_fd; + } + if (write(fd, p, len) < 0) { + if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS + || errno == ENXIO || errno == EIO || errno == EINTR) + warn("write: warning: %m (%d)", errno); + else + error("write: %m (%d)", errno); + } +} + +/******************************************************************** + * + * 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) +{ + fd_set ready, exc; + int n; + + ready = in_fds; + exc = in_fds; + n = select(max_in_fd + 1, &ready, NULL, &exc, timo); + if (n < 0 && errno != EINTR) + fatal("select: %m"); +} + +/* + * add_fd - add an fd to the set that wait_input waits for. + */ +void add_fd(int fd) +{ + if (fd >= FD_SETSIZE) + fatal("internal error: file descriptor too large (%d)", fd); + FD_SET(fd, &in_fds); + if (fd > max_in_fd) + max_in_fd = fd; +} + +/* + * remove_fd - remove an fd from the set that wait_input waits for. + */ +void remove_fd(int fd) +{ + FD_CLR(fd, &in_fds); +} + + +/******************************************************************** + * + * read_packet - get a PPP packet from the serial device. + */ + +int read_packet (unsigned char *buf) +{ + int len, nr; + + len = PPP_MRU + PPP_HDRLEN; + if (new_style_driver) { + *buf++ = PPP_ALLSTATIONS; + *buf++ = PPP_UI; + len -= 2; + } + nr = -1; + if (ppp_fd >= 0) { + nr = read(ppp_fd, buf, len); + if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN + && errno != EIO && errno != EINTR) + error("read: %m"); + if (nr < 0 && errno == ENXIO) + return 0; + } + if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) { + /* N.B. we read ppp_fd first since LCP packets come in there. */ + nr = read(ppp_dev_fd, buf, len); + if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN + && errno != EIO && errno != EINTR) + error("read /dev/ppp: %m"); + if (nr < 0 && errno == ENXIO) + nr = 0; + if (nr == 0 && doing_multilink) { + remove_fd(ppp_dev_fd); + bundle_eof = 1; + } + } + if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0) + nr = 0; + return (new_style_driver && nr > 0)? nr+2: nr; +} + +/******************************************************************** + * + * get_loop_output - get outgoing packets from the ppp device, + * 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; + + if (new_style_driver) { + while ((n = read_packet(inpacket_buf)) > 0) + if (loop_frame(inpacket_buf, n)) + rv = 1; + return rv; + } + + while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0) + if (loop_chars(inbuf, n)) + rv = 1; + + if (n == 0) + fatal("eof on loopback"); + + if (errno != EWOULDBLOCK && errno != EAGAIN) + fatal("read from loopback: %m(%d)", errno); + + return rv; +} + +/* + * netif_set_mtu - set the MTU on the PPP network interface. + */ +void +netif_set_mtu(int unit, int mtu) +{ + struct ifreq ifr; + + memset (&ifr, '\0', sizeof (ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + ifr.ifr_mtu = mtu; + + if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) + error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__); +} + +/* + * netif_get_mtu - get the MTU on the PPP network interface. + */ +int +netif_get_mtu(int unit) +{ + struct ifreq ifr; + + memset (&ifr, '\0', sizeof (ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + + if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) { + error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__); + return 0; + } + return ifr.ifr_mtu; +} + +/******************************************************************** + * + * tty_send_config - configure the transmit characteristics of + * the ppp interface. + */ + +void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp) +{ + int x; + + if (!still_ppp()) + return; + link_mtu = mtu; + if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { + if (errno != EIO && errno != ENOTTY) + error("Couldn't set transmit async character map: %m"); + ++error_count; + return; + } + + x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0) + | (sync_serial? SC_SYNC: 0); + modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x); +} + +/******************************************************************** + * + * tty_set_xaccm - set the extended transmit ACCM for the interface. + */ + +void tty_set_xaccm (ext_accm accm) +{ + if (!still_ppp()) + return; + if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) { + if ( ! ok_error (errno)) + warn("ioctl(set extended ACCM): %m (line %d)", __LINE__); + } +} + +/******************************************************************** + * + * tty_recv_config - configure the receive-side characteristics of + * the ppp interface. + */ + +void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp) +{ +/* + * If we were called because the link has gone down then there is nothing + * which may be done. Just return without incident. + */ + if (!still_ppp()) + return; +/* + * Set the receiver parameters + */ + if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { + if (errno != EIO && errno != ENOTTY) + error("Couldn't set channel receive MRU: %m"); + } + if (new_style_driver && ppp_dev_fd >= 0 + && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) + error("Couldn't set MRU in generic PPP layer: %m"); + + if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { + if (errno != EIO && errno != ENOTTY) + error("Couldn't set channel receive asyncmap: %m"); + } +} + +/******************************************************************** + * + * ccp_test - ask kernel whether a given compression method + * is acceptable for use. + */ + +int +ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit) +{ + struct ppp_option_data data; + + memset (&data, '\0', sizeof (data)); + data.ptr = opt_ptr; + data.length = opt_len; + data.transmit = for_transmit; + + if (ioctl(ppp_dev_fd, 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; + + x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0); + if (still_ppp() && ppp_dev_fd >= 0) + modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x); +} + +#ifdef PPP_FILTER +/* + * set_filters - set the active and pass filters in the kernel driver. + */ +int set_filters(struct bpf_program *pass, struct bpf_program *active) +{ + struct sock_fprog fp; + + fp.len = pass->bf_len; + fp.filter = (struct sock_filter *) pass->bf_insns; + if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) { + if (errno == ENOTTY) + warn("kernel does not support PPP filtering"); + else + error("Couldn't set pass-filter in kernel: %m"); + return 0; + } + fp.len = active->bf_len; + fp.filter = (struct sock_filter *) active->bf_insns; + if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) { + error("Couldn't set active-filter in kernel: %m"); + return 0; + } + return 1; +} +#endif /* PPP_FILTER */ + +/******************************************************************** + * + * get_idle_time - return how long the link has been idle. + */ +int +get_idle_time(u, ip) + int u; + struct ppp_idle *ip; +{ + return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0; +} + +/******************************************************************** + * + * get_ppp_stats - return statistics for the link. + */ +int +get_ppp_stats(u, stats) + int u; + struct pppd_stats *stats; +{ + printf("REPLACEORTOSSME: get_ppp_stats()\n"); +#if 0 + struct ifpppstatsreq req; + + memset (&req, 0, sizeof (req)); + + req.stats_ptr = (caddr_t) &req.stats; + strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name)); + if (ioctl(sock_fd, 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; + stats->pkts_in = req.stats.p.ppp_ipackets; + stats->pkts_out = req.stats.p.ppp_opackets; +#endif + stats->bytes_in = 0; + stats->bytes_out = 0; + stats->pkts_in = 0; + stats->pkts_out = 0; + return 1; +} + +/******************************************************************** + * + * 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 flags; + + if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) { + error("Couldn't read compression error flags: %m"); + flags = 0; + } + return flags & SC_DC_FERROR; +} + +/******************************************************************** + * + * path_to_procfs - find the path to the proc file system mount point + */ +static char proc_path[MAXPATHLEN]; +static int proc_path_len; + +static char *path_to_procfs(const char *tail) +{ + struct mntent *mntent; + FILE *fp; + + if (proc_path_len == 0) { + /* Default the mount location of /proc */ + strlcpy (proc_path, "/proc", sizeof(proc_path)); + proc_path_len = 5; + fp = fopen(MOUNTED, "r"); + if (fp != NULL) { + while ((mntent = getmntent(fp)) != NULL) { + if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) + continue; + if (strcmp(mntent->mnt_type, "proc") == 0) { + strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path)); + proc_path_len = strlen(proc_path); + break; + } + } + fclose (fp); + } + } + + strlcpy(proc_path + proc_path_len, tail, + sizeof(proc_path) - proc_path_len); + return proc_path; +} + +/* + * /proc/net/route parsing stuff. + */ +#define ROUTE_MAX_COLS 12 +FILE *route_fd = (FILE *) 0; +static char route_buffer[512]; +static int route_dev_col, route_dest_col, route_gw_col; +static int route_flags_col, route_mask_col; +static int route_num_cols; + +static int open_route_table (void); +static void close_route_table (void); +static int read_route_table (struct rtentry *rt); + +/******************************************************************** + * + * close_route_table - close the interface to the route table + */ + +static void close_route_table (void) +{ + if (route_fd != (FILE *) 0) { + fclose (route_fd); + route_fd = (FILE *) 0; + } +} + +/******************************************************************** + * + * open_route_table - open the interface to the route table + */ +static char route_delims[] = " \t\n"; + +static int open_route_table (void) +{ + char *path; + + close_route_table(); + + path = path_to_procfs("/net/route"); + route_fd = fopen (path, "r"); + if (route_fd == NULL) { + error("can't open routing table %s: %m", path); + return 0; + } + + route_dev_col = 0; /* default to usual columns */ + route_dest_col = 1; + route_gw_col = 2; + route_flags_col = 3; + route_mask_col = 7; + route_num_cols = 8; + + /* parse header line */ + if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) { + char *p = route_buffer, *q; + int col; + for (col = 0; col < ROUTE_MAX_COLS; ++col) { + int used = 1; + if ((q = strtok(p, route_delims)) == 0) + break; + if (strcasecmp(q, "iface") == 0) + route_dev_col = col; + else if (strcasecmp(q, "destination") == 0) + route_dest_col = col; + else if (strcasecmp(q, "gateway") == 0) + route_gw_col = col; + else if (strcasecmp(q, "flags") == 0) + route_flags_col = col; + else if (strcasecmp(q, "mask") == 0) + route_mask_col = col; + else + used = 0; + if (used && col >= route_num_cols) + route_num_cols = col + 1; + p = NULL; + } + } + + return 1; +} + +/******************************************************************** + * + * read_route_table - read the next entry from the route table + */ + +static int read_route_table(struct rtentry *rt) +{ + char *cols[ROUTE_MAX_COLS], *p; + int col; + + memset (rt, '\0', sizeof (struct rtentry)); + + if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) + return 0; + + p = route_buffer; + for (col = 0; col < route_num_cols; ++col) { + cols[col] = strtok(p, route_delims); + if (cols[col] == NULL) + return 0; /* didn't get enough columns */ + p = NULL; + } + + SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); + SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); + SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); + + rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); + rt->rt_dev = cols[route_dev_col]; + + return 1; +} + +/******************************************************************** + * + * defaultroute_exists - determine if there is a default route + */ + +static int defaultroute_exists (struct rtentry *rt) +{ + int result = 0; + + if (!open_route_table()) + return 0; + + while (read_route_table(rt) != 0) { + if ((rt->rt_flags & RTF_UP) == 0) + continue; + + if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) + continue; + if (SIN_ADDR(rt->rt_dst) == 0L) { + result = 1; + break; + } + } + + close_route_table(); + return result; +} + +/* + * have_route_to - determine if the system has any route to + * a given IP address. `addr' is in network byte order. + * Return value is 1 if yes, 0 if no, -1 if don't know. + * For demand mode to work properly, we have to ignore routes + * through our own interface. + */ +int have_route_to(u_int32_t addr) +{ + struct rtentry rt; + int result = 0; + + if (!open_route_table()) + return -1; /* don't know */ + + while (read_route_table(&rt)) { + if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0) + continue; + if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) { + result = 1; + break; + } + } + + close_route_table(); + return result; +} + +/******************************************************************** + * + * sifdefaultroute - assign a default route through the address given. + */ + +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) +{ + struct rtentry rt; + + if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { + if (rt.rt_flags & RTF_GATEWAY) + error("not replacing existing default route via %I", + SIN_ADDR(rt.rt_gateway)); + else + error("not replacing existing default route through %s", + rt.rt_dev); + return 0; + } + + memset (&rt, 0, sizeof (rt)); + SET_SA_FAMILY (rt.rt_dst, AF_INET); + + rt.rt_dev = ifname; + + if (kernel_version > KVERSION(2,1,0)) { + SET_SA_FAMILY (rt.rt_genmask, AF_INET); + SIN_ADDR(rt.rt_genmask) = 0L; + } + + rt.rt_flags = RTF_UP; + if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { + if ( ! ok_error ( errno )) + error("default route ioctl(SIOCADDRT): %m"); + return 0; + } + + have_default_route = 1; + return 1; +} + +/******************************************************************** + * + * cifdefaultroute - delete a default route through the address given. + */ + +int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) +{ + struct rtentry rt; + + have_default_route = 0; + + memset (&rt, '\0', sizeof (rt)); + SET_SA_FAMILY (rt.rt_dst, AF_INET); + SET_SA_FAMILY (rt.rt_gateway, AF_INET); + + rt.rt_dev = ifname; + + if (kernel_version > KVERSION(2,1,0)) { + SET_SA_FAMILY (rt.rt_genmask, AF_INET); + SIN_ADDR(rt.rt_genmask) = 0L; + } + + rt.rt_flags = RTF_UP; + if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { + if (still_ppp()) { + if ( ! ok_error ( errno )) + error("default route ioctl(SIOCDELRT): %m"); + return 0; + } + } + + return 1; +} + +/******************************************************************** + * + * sifproxyarp - Make a proxy ARP entry for the peer. + */ + +int sifproxyarp (int unit, u_int32_t his_adr) +{ + struct arpreq arpreq; + char *forw_path; + + if (has_proxy_arp == 0) { + memset (&arpreq, '\0', sizeof(arpreq)); + + SET_SA_FAMILY(arpreq.arp_pa, AF_INET); + SIN_ADDR(arpreq.arp_pa) = his_adr; + arpreq.arp_flags = ATF_PERM | ATF_PUBL; +/* + * Get the hardware address of an interface on the same subnet + * as our local address. + */ + if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev, + sizeof(proxy_arp_dev))) { + error("Cannot determine ethernet address for proxy ARP"); + return 0; + } + strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); + + if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) { + if ( ! ok_error ( errno )) + error("ioctl(SIOCSARP): %m"); + return 0; + } + proxy_arp_addr = his_adr; + has_proxy_arp = 1; + + if (tune_kernel) { + forw_path = path_to_procfs("/sys/net/ipv4/ip_forward"); + if (forw_path != 0) { + int fd = open(forw_path, O_WRONLY); + if (fd >= 0) { + if (write(fd, "1", 1) != 1) + error("Couldn't enable IP forwarding: %m"); + close(fd); + } + } + } + } + + return 1; +} + +/******************************************************************** + * + * cifproxyarp - Delete the proxy ARP entry for the peer. + */ + +int cifproxyarp (int unit, u_int32_t his_adr) +{ + struct arpreq arpreq; + + if (has_proxy_arp) { + has_proxy_arp = 0; + memset (&arpreq, '\0', sizeof(arpreq)); + SET_SA_FAMILY(arpreq.arp_pa, AF_INET); + SIN_ADDR(arpreq.arp_pa) = his_adr; + arpreq.arp_flags = ATF_PERM | ATF_PUBL; + strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); + + if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { + if ( ! ok_error ( errno )) + warn("ioctl(SIOCDARP): %m"); + return 0; + } + } + return 1; +} + +/******************************************************************** + * + * get_ether_addr - get the hardware address of an interface on the + * the same subnet as ipaddr. + */ + +static int get_ether_addr (u_int32_t ipaddr, + struct sockaddr *hwaddr, + char *name, int namelen) +{ + struct ifreq *ifr, *ifend; + u_int32_t ina, mask; + char *aliasp; + struct ifreq ifreq, bestifreq; + struct ifconf ifc; + struct ifreq ifs[MAX_IFS]; + + u_int32_t bestmask=0; + int found_interface = 0; + + ifc.ifc_len = sizeof(ifs); + ifc.ifc_req = ifs; + if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) { + if ( ! ok_error ( errno )) + error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__); + return 0; + } + +/* + * Scan through looking for an interface with an Internet + * address on the same subnet as `ipaddr'. + */ + ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); + for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { + if (ifr->ifr_addr.sa_family == AF_INET) { + ina = SIN_ADDR(ifr->ifr_addr); + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); +/* + * Check that the interface is up, and not point-to-point + * nor loopback. + */ + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) + continue; + + if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) + continue; +/* + * Get its netmask and check that it's on the right subnet. + */ + if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) + continue; + + mask = SIN_ADDR(ifreq.ifr_addr); + + if (((ipaddr ^ ina) & mask) != 0) + continue; /* no match */ + /* matched */ + if (mask >= bestmask) { + /* Compare using >= instead of > -- it is possible for + an interface to have a netmask of 0.0.0.0 */ + found_interface = 1; + bestifreq = ifreq; + bestmask = mask; + } + } + } + + if (!found_interface) return 0; + + strlcpy(name, bestifreq.ifr_name, namelen); + + /* trim off the :1 in eth0:1 */ + aliasp = strchr(name, ':'); + if (aliasp != 0) + *aliasp = 0; + + info("found interface %s for proxy arp", name); +/* + * Now get the hardware address. + */ + memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); + if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) { + error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name); + return 0; + } + + memcpy (hwaddr, + &bestifreq.ifr_hwaddr, + sizeof (struct sockaddr)); + + return 1; +} + +/* + * get_if_hwaddr - get the hardware address for the specified + * network interface device. + */ +int +get_if_hwaddr(u_char *addr, char *name) +{ + struct ifreq ifreq; + int ret, sock_fd; + + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + return 0; + memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); + strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name)); + ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); + close(sock_fd); + if (ret >= 0) + memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6); + return ret; +} + +/* + * get_first_ethernet - return the name of the first ethernet-style + * interface on this system. + */ +char * +get_first_ethernet() +{ + return "eth0"; +} + +/******************************************************************** + * + * 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. + */ + +u_int32_t GetMask (u_int32_t addr) +{ + u_int32_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(sock_fd, SIOCGIFCONF, &ifc) < 0) { + if ( ! ok_error ( errno )) + warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__); + return mask; + } + + ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); + for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { +/* + * Check the interface's internet address. + */ + if (ifr->ifr_addr.sa_family != AF_INET) + continue; + ina = SIN_ADDR(ifr->ifr_addr); + if (((ntohl(ina) ^ addr) & nmask) != 0) + continue; +/* + * Check that the interface is up, and not point-to-point nor loopback. + */ + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) + continue; + + if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) + continue; +/* + * Get its netmask and OR it into our mask. + */ + if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) + continue; + mask |= SIN_ADDR(ifreq.ifr_addr); + break; + } + return mask; +} + +/******************************************************************** + * + * Internal routine to decode the version.modification.patch level + */ + +static void decode_version (char *buf, int *version, + int *modification, int *patch) +{ + char *endp; + + *version = (int) strtoul (buf, &endp, 10); + *modification = 0; + *patch = 0; + + if (endp != buf && *endp == '.') { + buf = endp + 1; + *modification = (int) strtoul (buf, &endp, 10); + if (endp != buf && *endp == '.') { + buf = endp + 1; + *patch = (int) strtoul (buf, &buf, 10); + } + } +} + +/******************************************************************** + * + * Procedure to determine if the PPP line discipline is registered. + */ + +static int +ppp_registered(void) +{ + int local_fd; + int mfd = -1; + int ret = 0; + char slave[16]; + + /* + * We used to open the serial device and set it to the ppp line + * discipline here, in order to create a ppp unit. But that is + * not a good idea - the user might have specified a device that + * they can't open (permission, or maybe it doesn't really exist). + * So we grab a pty master/slave pair and use that. + */ + if (!get_pty(&mfd, &local_fd, slave, 0)) { + no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)"; + return 0; + } + + /* + * Try to put the device into the PPP discipline. + */ + if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) { + error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__); + } else + ret = 1; + + close(local_fd); + close(mfd); + return ret; +} + +/******************************************************************** + * + * 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, fd, err; + struct ifreq ifr; + int size; + int my_version, my_modification, my_patch; + int osmaj, osmin, ospatch; + + /* get the kernel version now, since we are called before sys_init */ + uname(&utsname); + osmaj = osmin = ospatch = 0; + sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch); + kernel_version = KVERSION(osmaj, osmin, ospatch); + + fd = open("/dev/ppp", O_RDWR); + if (fd >= 0) { + new_style_driver = 1; + + /* XXX should get from driver */ + driver_version = 2; + driver_modification = 4; + driver_patch = 0; + close(fd); + return 1; + } + err = errno; + + if (kernel_version >= KVERSION(2,3,13)) { + error("Couldn't open the /dev/ppp device: %m"); + if (errno == ENOENT) + no_ppp_msg = + "You need to create the /dev/ppp device node by\n" + "executing the following command as root:\n" + " mknod /dev/ppp c 108 0\n"; + else if (errno == ENODEV || errno == ENXIO) + no_ppp_msg = + "Please load the ppp_generic kernel module.\n"; + return 0; + } + + /* we are running on a really really old kernel */ + no_ppp_msg = + "This system lacks kernel support for PPP. This could be because\n" + "the PPP kernel module could not be loaded, or because PPP was not\n" + "included in the kernel configuration. If PPP was included as a\n" + "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n" + "ppp.o exists in /lib/modules/`uname -r`/net.\n" + "See README.linux file in the ppp distribution for more details.\n"; + +/* + * Open a socket for doing the ioctl operations. + */ + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + return 0; + + strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; +/* + * If the device did not exist then attempt to create one by putting the + * current tty into the PPP discipline. If this works then obtain the + * flags for the device again. + */ + if (!ok) { + if (ppp_registered()) { + strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; + } + } +/* + * Ensure that the hardware address is for PPP and not something else + */ + if (ok) + ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0; + + if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP)) + ok = 0; + +/* + * This is the PPP device. Validate the version of the driver at this + * point to ensure that this program will work with the driver. + */ + if (ok) { + char abBuffer [1024]; + + ifr.ifr_data = abBuffer; + size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr); + if (size < 0) { + error("Couldn't read driver version: %m"); + ok = 0; + no_ppp_msg = "Sorry, couldn't verify kernel driver version\n"; + + } else { + decode_version(abBuffer, + &driver_version, + &driver_modification, + &driver_patch); +/* + * Validate the version of the driver against the version that we used. + */ + decode_version(VERSION, + &my_version, + &my_modification, + &my_patch); + + /* The version numbers must match */ + if (driver_version != my_version) + ok = 0; + + /* The modification levels must be legal */ + if (driver_modification < 3) { + if (driver_modification >= 2) { + /* we can cope with 2.2.0 and above */ + driver_is_old = 1; + } else { + ok = 0; + } + } + + close (s); + if (!ok) { + slprintf(route_buffer, sizeof(route_buffer), + "Sorry - PPP driver version %d.%d.%d is out of date\n", + driver_version, driver_modification, driver_patch); + + no_ppp_msg = route_buffer; + } + } + } + return ok; +} + +/******************************************************************** + * + * Update the wtmp file with the appropriate user name and tty device. + */ + +void logwtmp (const char *line, const char *name, const char *host) +{ + struct utmp ut, *utp; + pid_t mypid = getpid(); +#if __GLIBC__ < 2 + int wtmp; +#endif + +/* + * Update the signon database for users. + * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996 + */ + utmpname(_PATH_UTMP); + setutent(); + while ((utp = getutent()) && (utp->ut_pid != mypid)) + /* nothing */; + + if (utp) + memcpy(&ut, utp, sizeof(ut)); + else + /* some gettys/telnetds don't initialize utmp... */ + memset(&ut, 0, sizeof(ut)); + + if (ut.ut_id[0] == 0) + strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); + + strncpy(ut.ut_user, name, sizeof(ut.ut_user)); + strncpy(ut.ut_line, line, sizeof(ut.ut_line)); + + time(&ut.ut_time); + + ut.ut_type = USER_PROCESS; + ut.ut_pid = mypid; + + /* Insert the host name if one is supplied */ + if (*host) + strncpy (ut.ut_host, host, sizeof(ut.ut_host)); + + /* Insert the IP address of the remote system if IP is enabled */ + if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr) + memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr, + sizeof(ut.ut_addr)); + + /* CL: Makes sure that the logout works */ + if (*host == 0 && *name==0) + ut.ut_host[0]=0; + + pututline(&ut); + endutent(); +/* + * Update the wtmp file. + */ +#if __GLIBC__ >= 2 + updwtmp(_PATH_WTMP, &ut); +#else + wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY); + if (wtmp >= 0) { + flock(wtmp, LOCK_EX); + + if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut)) + warn("error writing %s: %m", _PATH_WTMP); + + flock(wtmp, LOCK_UN); + + close (wtmp); + } +#endif +} + + +/******************************************************************** + * + * sifvjcomp - config tcp header compression + */ + +int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) +{ + u_int x; + + if (vjcomp) { + if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) + error("Couldn't set up TCP header compression: %m"); + vjcomp = 0; + } + + x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID); + modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x); + + return 1; +} + +#if 0 +/******************************************************************** + * + * sifup - Config the interface up and enable IP packets to pass. + */ + +int sifup(int u) +{ + printf("REPLACE ME: sifup() called\n"); + return 1; + + struct ifreq ifr; + + memset (&ifr, '\0', sizeof (ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { + if (! ok_error (errno)) + error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__); + return 0; + } + + ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT); + if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { + if (! ok_error (errno)) + error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__); + return 0; + } + if_is_up++; + + return 1; +} +#endif + +/******************************************************************** + * + * sifdown - Disable the indicated protocol and config the interface + * down if there are no remaining protocols. + */ + +int sifdown (int u) +{ + printf("REPLACE ME: sifdown() called\n"); + return 1; + + struct ifreq ifr; + + if (if_is_up && --if_is_up > 0) + return 1; + + memset (&ifr, '\0', sizeof (ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { + if (! ok_error (errno)) + error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__); + return 0; + } + + ifr.ifr_flags &= ~IFF_UP; + ifr.ifr_flags |= IFF_POINTOPOINT; + if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { + if (! ok_error (errno)) + error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__); + return 0; + } + return 1; +} + +#if 0 +/******************************************************************** + * + * sifaddr - Config the interface IP addresses and netmask. + */ + +int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, + u_int32_t net_mask) +{ + printf("REPLACE ME: sifaddr() called\n"); + return 1; + + struct ifreq ifr; + struct rtentry rt; + + memset (&ifr, '\0', sizeof (ifr)); + memset (&rt, '\0', sizeof (rt)); + + SET_SA_FAMILY (ifr.ifr_addr, AF_INET); + SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); + SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); + + strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); +/* + * Set our IP address + */ + SIN_ADDR(ifr.ifr_addr) = our_adr; + if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { + if (errno != EEXIST) { + if (! ok_error (errno)) + error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); + } + else { + warn("ioctl(SIOCSIFADDR): Address already exists"); + } + return (0); + } +/* + * Set the gateway address + */ + if (his_adr != 0) { + SIN_ADDR(ifr.ifr_dstaddr) = his_adr; + if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { + if (! ok_error (errno)) + error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__); + return (0); + } + } +/* + * Set the netmask. + * For recent kernels, force the netmask to 255.255.255.255. + */ + if (kernel_version >= KVERSION(2,1,16)) + net_mask = ~0L; + if (net_mask != 0) { + SIN_ADDR(ifr.ifr_netmask) = net_mask; + if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { + if (! ok_error (errno)) + error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__); + return (0); + } + } +/* + * Add the device route + */ + if (kernel_version < KVERSION(2,1,16)) { + SET_SA_FAMILY (rt.rt_dst, AF_INET); + SET_SA_FAMILY (rt.rt_gateway, AF_INET); + rt.rt_dev = ifname; + + SIN_ADDR(rt.rt_gateway) = 0L; + SIN_ADDR(rt.rt_dst) = his_adr; + rt.rt_flags = RTF_UP | RTF_HOST; + + if (kernel_version > KVERSION(2,1,0)) { + SET_SA_FAMILY (rt.rt_genmask, AF_INET); + SIN_ADDR(rt.rt_genmask) = -1L; + } + + if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { + if (! ok_error (errno)) + error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__); + return (0); + } + } + + /* set ip_dynaddr in demand mode if address changes */ + if (demand && tune_kernel && !dynaddr_set + && our_old_addr && our_old_addr != our_adr) { + /* set ip_dynaddr if possible */ + char *path; + int fd; + + path = path_to_procfs("/sys/net/ipv4/ip_dynaddr"); + if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) { + if (write(fd, "1", 1) != 1) + error("Couldn't enable dynamic IP addressing: %m"); + close(fd); + } + dynaddr_set = 1; /* only 1 attempt */ + } + our_old_addr = 0; + + return 1; +} +#endif + +/******************************************************************** + * + * cifaddr - Clear the interface IP addresses, and delete routes + * through the interface if possible. + */ + +int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) +{ + printf("REPLACE ME: cifaddr() called\n"); + return 1; + + struct ifreq ifr; + + if (kernel_version < KVERSION(2,1,16)) { +/* + * Delete the route through the device + */ + struct rtentry rt; + memset (&rt, '\0', sizeof (rt)); + + SET_SA_FAMILY (rt.rt_dst, AF_INET); + SET_SA_FAMILY (rt.rt_gateway, AF_INET); + rt.rt_dev = ifname; + + SIN_ADDR(rt.rt_gateway) = 0; + SIN_ADDR(rt.rt_dst) = his_adr; + rt.rt_flags = RTF_UP | RTF_HOST; + + if (kernel_version > KVERSION(2,1,0)) { + SET_SA_FAMILY (rt.rt_genmask, AF_INET); + SIN_ADDR(rt.rt_genmask) = -1L; + } + + if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { + if (still_ppp() && ! ok_error (errno)) + error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__); + return (0); + } + } + + /* This way it is possible to have an IPX-only or IPv6-only interface */ + memset(&ifr, 0, sizeof(ifr)); + SET_SA_FAMILY(ifr.ifr_addr, AF_INET); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { + if (! ok_error (errno)) { + error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); + return 0; + } + } + + our_old_addr = our_adr; + + return 1; +} + +#ifdef INET6 +/******************************************************************** + * + * sif6addr - Config the interface with an IPv6 link-local address + */ +int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) +{ + struct in6_ifreq ifr6; + struct ifreq ifr; + struct in6_rtmsg rt6; + + if (sock6_fd < 0) { + errno = -sock6_fd; + error("IPv6 socket creation failed: %m"); + return 0; + } + memset(&ifr, 0, sizeof (ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { + error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__); + return 0; + } + + /* Local interface */ + memset(&ifr6, 0, sizeof(ifr6)); + IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); + ifr6.ifr6_ifindex = ifr.ifr_ifindex; + ifr6.ifr6_prefixlen = 10; + + if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { + error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); + return 0; + } + + /* Route to remote host */ + memset(&rt6, 0, sizeof(rt6)); + IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); + rt6.rtmsg_flags = RTF_UP; + rt6.rtmsg_dst_len = 10; + rt6.rtmsg_ifindex = ifr.ifr_ifindex; + rt6.rtmsg_metric = 1; + + if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { + error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__); + return 0; + } + + return 1; +} + + +/******************************************************************** + * + * cif6addr - Remove IPv6 address from interface + */ +int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) +{ + struct ifreq ifr; + struct in6_ifreq ifr6; + + if (sock6_fd < 0) { + errno = -sock6_fd; + error("IPv6 socket creation failed: %m"); + return 0; + } + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { + error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__); + return 0; + } + + memset(&ifr6, 0, sizeof(ifr6)); + IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); + ifr6.ifr6_ifindex = ifr.ifr_ifindex; + ifr6.ifr6_prefixlen = 10; + + if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { + if (errno != EADDRNOTAVAIL) { + if (! ok_error (errno)) + error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__); + } + else { + warn("cif6addr: ioctl(SIOCDIFADDR): No such address"); + } + return (0); + } + return 1; +} +#endif /* INET6 */ + +/* + * get_pty - get a pty master/slave pair and chown the slave side + * to the uid given. Assumes slave_name points to >= 16 bytes of space. + */ +int +get_pty(master_fdp, slave_fdp, slave_name, uid) + int *master_fdp; + int *slave_fdp; + char *slave_name; + int uid; +{ + int i, mfd, sfd = -1; + char pty_name[16]; + struct termios tios; + +#ifdef TIOCGPTN + /* + * Try the unix98 way first. + */ + mfd = open("/dev/ptmx", O_RDWR); + if (mfd >= 0) { + int ptn; + if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { + slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn); + chmod(pty_name, S_IRUSR | S_IWUSR); +#ifdef TIOCSPTLCK + ptn = 0; + if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) + warn("Couldn't unlock pty slave %s: %m", pty_name); +#endif + if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) + warn("Couldn't open pty slave %s: %m", pty_name); + } + } +#endif /* TIOCGPTN */ + + if (sfd < 0) { + /* the old way - scan through the pty name space */ + for (i = 0; i < 64; ++i) { + slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", + 'p' + i / 16, i % 16); + mfd = open(pty_name, O_RDWR, 0); + if (mfd >= 0) { + pty_name[5] = 't'; + sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); + if (sfd >= 0) { + fchown(sfd, uid, -1); + fchmod(sfd, S_IRUSR | S_IWUSR); + break; + } + close(mfd); + } + } + } + + if (sfd < 0) + return 0; + + strlcpy(slave_name, pty_name, 16); + *master_fdp = mfd; + *slave_fdp = sfd; + if (tcgetattr(sfd, &tios) == 0) { + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); + tios.c_cflag |= CS8 | CREAD | CLOCAL; + tios.c_iflag = IGNPAR; + tios.c_oflag = 0; + tios.c_lflag = 0; + if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) + warn("couldn't set attributes on pty: %m"); + } else + warn("couldn't get attributes on pty: %m"); + + return 1; +} + +/******************************************************************** + * + * open_loopback - open the device we use for getting packets + * in demand mode. Under Linux, we use a pty master/slave pair. + */ +int +open_ppp_loopback(void) +{ + int flags; + + looped = 1; + if (new_style_driver) { + /* allocate ourselves a ppp unit */ + if (make_ppp_unit() < 0) + die(1); + modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC); + set_kdebugflag(kdebugflag); + ppp_fd = -1; + return ppp_dev_fd; + } + + if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) + fatal("No free pty for loopback"); + + set_ppp_fd(slave_fd); + + flags = fcntl(master_fd, F_GETFL); + if (flags == -1 || + fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1) + warn("couldn't set master loopback to nonblock: %m"); + + flags = fcntl(ppp_fd, F_GETFL); + if (flags == -1 || + fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1) + warn("couldn't set slave loopback to nonblock: %m"); + + if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) + fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__); +/* + * Find out which interface we were given. + */ + if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) + fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__); +/* + * Enable debug in the driver if requested. + */ + set_kdebugflag (kdebugflag); + + return master_fd; +} + +#if 0 +/******************************************************************** + * + * sifnpmode - Set the mode for handling packets for a given NP. + */ + +int +sifnpmode(u, proto, mode) + int u; + int proto; + enum NPmode mode; +{ + printf("REPLACE ME: sifnpmode() called\n"); + return 1; + + struct npioctl npi; + + npi.protocol = proto; + npi.mode = mode; + if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { + if (! ok_error (errno)) + error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode); + return 0; + } + return 1; +} +#endif + +/******************************************************************** + * + * sipxfaddr - Config the interface IPX networknumber + */ + +int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) +{ + int result = 1; + +#ifdef IPX_CHANGE + int skfd; + struct ifreq ifr; + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; + + skfd = socket (AF_IPX, SOCK_DGRAM, 0); + if (skfd < 0) { + if (! ok_error (errno)) + dbglog("socket(AF_IPX): %m (line %d)", __LINE__); + result = 0; + } + else { + memset (&ifr, '\0', sizeof (ifr)); + strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + memcpy (sipx->sipx_node, node, IPX_NODE_LEN); + sipx->sipx_family = AF_IPX; + sipx->sipx_port = 0; + sipx->sipx_network = htonl (network); + sipx->sipx_type = IPX_FRAME_ETHERII; + sipx->sipx_action = IPX_CRTITF; +/* + * Set the IPX device + */ + if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { + result = 0; + if (errno != EEXIST) { + if (! ok_error (errno)) + dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__); + } + else { + warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists"); + } + } + close (skfd); + } +#endif + return result; +} + +/******************************************************************** + * + * cipxfaddr - Clear the information for the IPX network. The IPX routes + * are removed and the device is no longer able to pass IPX + * frames. + */ + +int cipxfaddr (int unit) +{ + int result = 1; + +#ifdef IPX_CHANGE + int skfd; + struct ifreq ifr; + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; + + skfd = socket (AF_IPX, SOCK_DGRAM, 0); + if (skfd < 0) { + if (! ok_error (errno)) + dbglog("socket(AF_IPX): %m (line %d)", __LINE__); + result = 0; + } + else { + memset (&ifr, '\0', sizeof (ifr)); + strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + sipx->sipx_type = IPX_FRAME_ETHERII; + sipx->sipx_action = IPX_DLTITF; + sipx->sipx_family = AF_IPX; +/* + * Set the IPX device + */ + if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { + if (! ok_error (errno)) + info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__); + result = 0; + } + close (skfd); + } +#endif + return result; +} + +/* + * Use the hostname as part of the random number seed. + */ +int +get_host_seed() +{ + int h; + char *p = hostname; + + h = 407; + for (p = hostname; *p != 0; ++p) + h = h * 37 + *p; + return h; +} + +/******************************************************************** + * + * sys_check_options - check the options that the user specified + */ + +int +sys_check_options(void) +{ +#ifdef IPX_CHANGE +/* + * Disable the IPX protocol if the support is not present in the kernel. + */ + char *path; + + if (ipxcp_protent.enabled_flag) { + struct stat stat_buf; + if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL + && (path = path_to_procfs("/net/ipx_interface")) == NULL) + || lstat(path, &stat_buf) < 0) { + error("IPX support is not present in the kernel\n"); + ipxcp_protent.enabled_flag = 0; + } + } +#endif + if (demand && driver_is_old) { + option_error("demand dialling is not supported by kernel driver " + "version %d.%d.%d", driver_version, driver_modification, + driver_patch); + return 0; + } + if (multilink && !new_style_driver) { + warn("Warning: multilink is not supported by the kernel driver"); + multilink = 0; + } + return 1; +} + +#ifdef INET6 +/* + * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI + * + * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes + * that the system has a properly configured Ethernet interface for this + * function to return non-zero. + */ +int +ether_to_eui64(eui64_t *p_eui64) +{ + struct ifreq ifr; + int skfd; + const unsigned char *ptr; + + skfd = socket(PF_INET6, SOCK_DGRAM, 0); + if(skfd == -1) + { + warn("could not open IPv6 socket"); + return 0; + } + + strcpy(ifr.ifr_name, "eth0"); + if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) + { + close(skfd); + warn("could not obtain hardware address for eth0"); + return 0; + } + close(skfd); + + /* + * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] + */ + ptr = ifr.ifr_hwaddr.sa_data; + p_eui64->e8[0] = ptr[0] | 0x02; + p_eui64->e8[1] = ptr[1]; + p_eui64->e8[2] = ptr[2]; + p_eui64->e8[3] = 0xFF; + p_eui64->e8[4] = 0xFE; + p_eui64->e8[5] = ptr[3]; + p_eui64->e8[6] = ptr[4]; + p_eui64->e8[7] = ptr[5]; + + return 1; +} +#endif diff --git a/src/netif/ppp/tdb.c b/src/netif/ppp/tdb.c new file mode 100644 index 00000000..d2c446d4 --- /dev/null +++ b/src/netif/ppp/tdb.c @@ -0,0 +1,2011 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2004 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +/* NOTE: If you use tdbs under valgrind, and in particular if you run + * tdbtorture, you may get spurious "uninitialized value" warnings. I + * think this is because valgrind doesn't understand that the mmap'd + * area may be written to by other processes. Memory can, from the + * point of view of the grinded process, spontaneously become + * initialized. + * + * I can think of a few solutions. [mbp 20030311] + * + * 1 - Write suppressions for Valgrind so that it doesn't complain + * about this. Probably the most reasonable but people need to + * remember to use them. + * + * 2 - Use IO not mmap when running under valgrind. Not so nice. + * + * 3 - Use the special valgrind macros to mark memory as valid at the + * right time. Probably too hard -- the process just doesn't know. + */ + +#include "lwip/opt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" +#include "spinlock.h" + +#define TDB_MAGIC_FOOD "TDB file\n" +#define TDB_VERSION (0x26011967 + 6) +#define TDB_MAGIC (0x26011999U) +#define TDB_FREE_MAGIC (~TDB_MAGIC) +#define TDB_DEAD_MAGIC (0xFEE1DEAD) +#define TDB_ALIGNMENT 4 +#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT) +#define DEFAULT_HASH_SIZE 131 +#define TDB_PAGE_SIZE 0x2000 +#define FREELIST_TOP (sizeof(struct tdb_header)) +#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) +#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) +#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) +#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) +#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off)) +#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + TDB_SPINLOCK_SIZE(hash_size)) + + +/* NB assumes there is a local variable called "tdb" that is the + * current context, also takes doubly-parenthesized print-style + * argument. */ +#define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0) + +/* lock offsets */ +#define GLOBAL_LOCK 0 +#define ACTIVE_LOCK 4 + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +/* free memory if the pointer is valid and zero the pointer */ +#ifndef SAFE_FREE +#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0) +#endif + +#define BUCKET(hash) ((hash) % tdb->header.hash_size) +TDB_DATA tdb_null; + +/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ +static TDB_CONTEXT *tdbs = NULL; + +static int tdb_munmap(TDB_CONTEXT *tdb) +{ + if (tdb->flags & TDB_INTERNAL) + return 0; + +#ifdef HAVE_MMAP + if (tdb->map_ptr) { + int ret = munmap(tdb->map_ptr, tdb->map_size); + if (ret != 0) + return ret; + } +#endif + tdb->map_ptr = NULL; + return 0; +} + +static void tdb_mmap(TDB_CONTEXT *tdb) +{ + if (tdb->flags & TDB_INTERNAL) + return; + +#ifdef HAVE_MMAP + if (!(tdb->flags & TDB_NOMMAP)) { + tdb->map_ptr = mmap(NULL, tdb->map_size, + PROT_READ|(tdb->read_only? 0:PROT_WRITE), + MAP_SHARED|MAP_FILE, tdb->fd, 0); + + /* + * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! + */ + + if (tdb->map_ptr == MAP_FAILED) { + tdb->map_ptr = NULL; + TDB_LOG((tdb, 2, "tdb_mmap failed for size %d (%s)\n", + tdb->map_size, strerror(errno))); + } + } else { + tdb->map_ptr = NULL; + } +#else + tdb->map_ptr = NULL; +#endif +} + +/* Endian conversion: we only ever deal with 4 byte quantities */ +static void *convert(void *buf, u32 size) +{ + u32 i, *p = buf; + for (i = 0; i < size / 4; i++) + p[i] = TDB_BYTEREV(p[i]); + return buf; +} +#define DOCONV() (tdb->flags & TDB_CONVERT) +#define CONVERT(x) (DOCONV() ? convert(&x, sizeof(x)) : &x) + +/* the body of the database is made of one list_struct for the free space + plus a separate data list for each hash value */ +struct list_struct { + tdb_off next; /* offset of the next record in the list */ + tdb_len rec_len; /* total byte length of record */ + tdb_len key_len; /* byte length of key */ + tdb_len data_len; /* byte length of data */ + u32 full_hash; /* the full 32 bit hash of the key */ + u32 magic; /* try to catch errors */ + /* the following union is implied: + union { + char record[rec_len]; + struct { + char key[key_len]; + char data[data_len]; + } + u32 totalsize; (tailer) + } + */ +}; + +/*************************************************************** + Allow a caller to set a "alarm" flag that tdb can check to abort + a blocking lock on SIGALRM. +***************************************************************/ + +static sig_atomic_t *palarm_fired; + +void tdb_set_lock_alarm(sig_atomic_t *palarm) +{ + palarm_fired = palarm; +} + +/* a byte range locking function - return 0 on success + this functions locks/unlocks 1 byte at the specified offset. + + On error, errno is also set so that errors are passed back properly + through tdb_open(). */ +static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, + int rw_type, int lck_type, int probe) +{ + struct flock fl; + int ret; + + if (tdb->flags & TDB_NOLOCK) + return 0; + if ((rw_type == F_WRLCK) && (tdb->read_only)) { + errno = EACCES; + return -1; + } + + fl.l_type = rw_type; + fl.l_whence = SEEK_SET; + fl.l_start = offset; + fl.l_len = 1; + fl.l_pid = 0; + + do { + ret = fcntl(tdb->fd,lck_type,&fl); + if (ret == -1 && errno == EINTR && palarm_fired && *palarm_fired) + break; + } while (ret == -1 && errno == EINTR); + + if (ret == -1) { + if (!probe && lck_type != F_SETLK) { + /* Ensure error code is set for log fun to examine. */ + if (errno == EINTR && palarm_fired && *palarm_fired) + tdb->ecode = TDB_ERR_LOCK_TIMEOUT; + else + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n", + tdb->fd, offset, rw_type, lck_type)); + } + /* Was it an alarm timeout ? */ + if (errno == EINTR && palarm_fired && *palarm_fired) { + TDB_LOG((tdb, 5, "tdb_brlock timed out (fd=%d) at offset %d rw_type=%d lck_type=%d\n", + tdb->fd, offset, rw_type, lck_type)); + return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1); + } + /* Otherwise - generic lock error. errno set by fcntl. + * EAGAIN is an expected return from non-blocking + * locks. */ + if (errno != EAGAIN) { + TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", + tdb->fd, offset, rw_type, lck_type, + strerror(errno))); + } + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + return 0; +} + +/* lock a list in the database. list -1 is the alloc list */ +static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype) +{ + if (list < -1 || list >= (int)tdb->header.hash_size) { + TDB_LOG((tdb, 0,"tdb_lock: invalid list %d for ltype=%d\n", + list, ltype)); + return -1; + } + if (tdb->flags & TDB_NOLOCK) + return 0; + + /* Since fcntl locks don't nest, we do a lock for the first one, + and simply bump the count for future ones */ + if (tdb->locked[list+1].count == 0) { + if (!tdb->read_only && tdb->header.rwlocks) { + if (tdb_spinlock(tdb, list, ltype)) { + TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list %d ltype=%d\n", + list, ltype)); + return -1; + } + } else if (tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, 0)) { + TDB_LOG((tdb, 0,"tdb_lock failed on list %d ltype=%d (%s)\n", + list, ltype, strerror(errno))); + return -1; + } + tdb->locked[list+1].ltype = ltype; + } + tdb->locked[list+1].count++; + return 0; +} + +/* unlock the database: returns void because it's too late for errors. */ + /* changed to return int it may be interesting to know there + has been an error --simo */ +static int tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype) +{ + int ret = -1; + + if (tdb->flags & TDB_NOLOCK) + return 0; + + /* Sanity checks */ + if (list < -1 || list >= (int)tdb->header.hash_size) { + TDB_LOG((tdb, 0, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); + return ret; + } + + if (tdb->locked[list+1].count==0) { + TDB_LOG((tdb, 0, "tdb_unlock: count is 0\n")); + return ret; + } + + if (tdb->locked[list+1].count == 1) { + /* Down to last nested lock: unlock underneath */ + if (!tdb->read_only && tdb->header.rwlocks) { + ret = tdb_spinunlock(tdb, list, ltype); + } else { + ret = tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0); + } + } else { + ret = 0; + } + tdb->locked[list+1].count--; + + if (ret) + TDB_LOG((tdb, 0,"tdb_unlock: An error occurred unlocking!\n")); + return ret; +} + +/* check for an out of bounds access - if it is out of bounds then + see if the database has been expanded by someone else and expand + if necessary + note that "len" is the minimum length needed for the db +*/ +static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe) +{ + struct stat st; + if (len <= tdb->map_size) + return 0; + if (tdb->flags & TDB_INTERNAL) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, 0,"tdb_oob len %d beyond internal malloc size %d\n", + (int)len, (int)tdb->map_size)); + } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + + if (fstat(tdb->fd, &st) == -1) + return TDB_ERRCODE(TDB_ERR_IO, -1); + + if (st.st_size < (size_t)len) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n", + (int)len, (int)st.st_size)); + } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + + /* Unmap, update size, remap */ + if (tdb_munmap(tdb) == -1) + return TDB_ERRCODE(TDB_ERR_IO, -1); + tdb->map_size = st.st_size; + tdb_mmap(tdb); + return 0; +} + +/* write a lump of data at a specified offset */ +static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len) +{ + if (tdb_oob(tdb, off + len, 0) != 0) + return -1; + + if (tdb->map_ptr) + memcpy(off + (char *)tdb->map_ptr, buf, len); +#ifdef HAVE_PWRITE + else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) { +#else + else if (lseek(tdb->fd, off, SEEK_SET) != off + || write(tdb->fd, buf, len) != (ssize_t)len) { +#endif + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n", + off, len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + return 0; +} + +/* read a lump of data at a specified offset, maybe convert */ +static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv) +{ + if (tdb_oob(tdb, off + len, 0) != 0) + return -1; + + if (tdb->map_ptr) + memcpy(buf, off + (char *)tdb->map_ptr, len); +#ifdef HAVE_PREAD + else if (pread(tdb->fd, buf, len, off) != (ssize_t)len) { +#else + else if (lseek(tdb->fd, off, SEEK_SET) != off + || read(tdb->fd, buf, len) != (ssize_t)len) { +#endif + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n", + off, len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + if (cv) + convert(buf, len); + return 0; +} + +/* read a lump of data, allocating the space for it */ +static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len) +{ + char *buf; + + if (!(buf = malloc(len))) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, 0,"tdb_alloc_read malloc failed len=%d (%s)\n", + len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_OOM, buf); + } + if (tdb_read(tdb, offset, buf, len, 0) == -1) { + SAFE_FREE(buf); + return NULL; + } + return buf; +} + +/* read/write a tdb_off */ +static int ofs_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) +{ + return tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); +} +static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) +{ + tdb_off off = *d; + return tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); +} + +/* read/write a record */ +static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) +{ + if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) + return -1; + if (TDB_BAD_MAGIC(rec)) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } + return tdb_oob(tdb, rec->next+sizeof(*rec), 0); +} +static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) +{ + struct list_struct r = *rec; + return tdb_write(tdb, offset, CONVERT(r), sizeof(r)); +} + +/* read a freelist record and check for simple errors */ +static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) +{ + if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) + return -1; + + if (rec->magic == TDB_MAGIC) { + /* this happens when a app is showdown while deleting a record - we should + not completely fail when this happens */ + TDB_LOG((tdb, 0,"rec_free_read non-free magic 0x%x at offset=%d - fixing\n", + rec->magic, off)); + rec->magic = TDB_FREE_MAGIC; + if (tdb_write(tdb, off, rec, sizeof(*rec)) == -1) + return -1; + } + + if (rec->magic != TDB_FREE_MAGIC) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n", + rec->magic, off)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } + if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) + return -1; + return 0; +} + +/* update a record tailer (must hold allocation lock) */ +static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset, + const struct list_struct *rec) +{ + tdb_off totalsize; + + /* Offset of tailer from record header */ + totalsize = sizeof(*rec) + rec->rec_len; + return ofs_write(tdb, offset + totalsize - sizeof(tdb_off), + &totalsize); +} + +static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset) +{ + struct list_struct rec; + tdb_off tailer_ofs, tailer; + + if (tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { + printf("ERROR: failed to read record at %u\n", offset); + return 0; + } + + printf(" rec: offset=%u next=%d rec_len=%d key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", + offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic); + + tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off); + if (ofs_read(tdb, tailer_ofs, &tailer) == -1) { + printf("ERROR: failed to read tailer at %u\n", tailer_ofs); + return rec.next; + } + + if (tailer != rec.rec_len + sizeof(rec)) { + printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", + (unsigned)tailer, (unsigned)(rec.rec_len + sizeof(rec))); + } + return rec.next; +} + +static int tdb_dump_chain(TDB_CONTEXT *tdb, int i) +{ + tdb_off rec_ptr, top; + + top = TDB_HASH_TOP(i); + + if (tdb_lock(tdb, i, F_WRLCK) != 0) + return -1; + + if (ofs_read(tdb, top, &rec_ptr) == -1) + return tdb_unlock(tdb, i, F_WRLCK); + + if (rec_ptr) + printf("hash=%d\n", i); + + while (rec_ptr) { + rec_ptr = tdb_dump_record(tdb, rec_ptr); + } + + return tdb_unlock(tdb, i, F_WRLCK); +} + +void tdb_dump_all(TDB_CONTEXT *tdb) +{ + int i; + for (i=0;iheader.hash_size;i++) { + tdb_dump_chain(tdb, i); + } + printf("freelist:\n"); + tdb_dump_chain(tdb, -1); +} + +int tdb_printfreelist(TDB_CONTEXT *tdb) +{ + int ret; + long total_free = 0; + tdb_off offset, rec_ptr; + struct list_struct rec; + + if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) + return ret; + + offset = FREELIST_TOP; + + /* read in the freelist top */ + if (ofs_read(tdb, offset, &rec_ptr) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + } + + printf("freelist top=[0x%08x]\n", rec_ptr ); + while (rec_ptr) { + if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); + return -1; + } + + if (rec.magic != TDB_FREE_MAGIC) { + printf("bad magic 0x%08x in free list\n", rec.magic); + tdb_unlock(tdb, -1, F_WRLCK); + return -1; + } + + printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)]\n", rec.next, rec.rec_len, rec.rec_len ); + total_free += rec.rec_len; + + /* move to the next record */ + rec_ptr = rec.next; + } + printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, + (int)total_free); + + return tdb_unlock(tdb, -1, F_WRLCK); +} + +/* Remove an element from the freelist. Must have alloc lock. */ +static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next) +{ + tdb_off last_ptr, i; + + /* read in the freelist top */ + last_ptr = FREELIST_TOP; + while (ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { + if (i == off) { + /* We've found it! */ + return ofs_write(tdb, last_ptr, &next); + } + /* Follow chain (next offset is at start of record) */ + last_ptr = i; + } + TDB_LOG((tdb, 0,"remove_from_freelist: not on list at off=%d\n", off)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); +} + +/* Add an element into the freelist. Merge adjacent records if + neccessary. */ +static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) +{ + tdb_off right, left; + + /* Allocation and tailer lock */ + if (tdb_lock(tdb, -1, F_WRLCK) != 0) + return -1; + + /* set an initial tailer, so if we fail we don't leave a bogus record */ + if (update_tailer(tdb, offset, rec) != 0) { + TDB_LOG((tdb, 0, "tdb_free: upfate_tailer failed!\n")); + goto fail; + } + + /* Look right first (I'm an Australian, dammit) */ + right = offset + sizeof(*rec) + rec->rec_len; + if (right + sizeof(*rec) <= tdb->map_size) { + struct list_struct r; + + if (tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { + TDB_LOG((tdb, 0, "tdb_free: right read failed at %u\n", right)); + goto left; + } + + /* If it's free, expand to include it. */ + if (r.magic == TDB_FREE_MAGIC) { + if (remove_from_freelist(tdb, right, r.next) == -1) { + TDB_LOG((tdb, 0, "tdb_free: right free failed at %u\n", right)); + goto left; + } + rec->rec_len += sizeof(r) + r.rec_len; + } + } + +left: + /* Look left */ + left = offset - sizeof(tdb_off); + if (left > TDB_DATA_START(tdb->header.hash_size)) { + struct list_struct l; + tdb_off leftsize; + + /* Read in tailer and jump back to header */ + if (ofs_read(tdb, left, &leftsize) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left)); + goto update; + } + left = offset - leftsize; + + /* Now read in record */ + if (tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); + goto update; + } + + /* If it's free, expand to include it. */ + if (l.magic == TDB_FREE_MAGIC) { + if (remove_from_freelist(tdb, left, l.next) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left free failed at %u\n", left)); + goto update; + } else { + offset = left; + rec->rec_len += leftsize; + } + } + } + +update: + if (update_tailer(tdb, offset, rec) == -1) { + TDB_LOG((tdb, 0, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } + + /* Now, prepend to free list */ + rec->magic = TDB_FREE_MAGIC; + + if (ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || + rec_write(tdb, offset, rec) == -1 || + ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, 0, "tdb_free record write failed at offset=%d\n", offset)); + goto fail; + } + + /* And we're done. */ + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return -1; +} + + +/* expand a file. we prefer to use ftruncate, as that is what posix + says to use for mmap expansion */ +static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition) +{ + char buf[1024]; +#if HAVE_FTRUNCATE_EXTEND + if (ftruncate(tdb->fd, size+addition) != 0) { + TDB_LOG((tdb, 0, "expand_file ftruncate to %d failed (%s)\n", + size+addition, strerror(errno))); + return -1; + } +#else + char b = 0; + +#ifdef HAVE_PWRITE + if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) { +#else + if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 || + write(tdb->fd, &b, 1) != 1) { +#endif + TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n", + size+addition, strerror(errno))); + return -1; + } +#endif + + /* now fill the file with something. This ensures that the file isn't sparse, which would be + very bad if we ran out of disk. This must be done with write, not via mmap */ + memset(buf, 0x42, sizeof(buf)); + while (addition) { + int n = addition>sizeof(buf)?sizeof(buf):addition; +#ifdef HAVE_PWRITE + int ret = pwrite(tdb->fd, buf, n, size); +#else + int ret; + if (lseek(tdb->fd, size, SEEK_SET) != size) + return -1; + ret = write(tdb->fd, buf, n); +#endif + if (ret != n) { + TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n", + n, strerror(errno))); + return -1; + } + addition -= n; + size += n; + } + return 0; +} + + +/* expand the database at least size bytes by expanding the underlying + file and doing the mmap again if necessary */ +static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) +{ + struct list_struct rec; + tdb_off offset; + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + TDB_LOG((tdb, 0, "lock failed in tdb_expand\n")); + return -1; + } + + /* must know about any previous expansions by another process */ + tdb_oob(tdb, tdb->map_size + 1, 1); + + /* always make room for at least 10 more records, and round + the database up to a multiple of TDB_PAGE_SIZE */ + size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size; + + if (!(tdb->flags & TDB_INTERNAL)) + tdb_munmap(tdb); + + /* + * We must ensure the file is unmapped before doing this + * to ensure consistency with systems like OpenBSD where + * writes and mmaps are not consistent. + */ + + /* expand the file itself */ + if (!(tdb->flags & TDB_INTERNAL)) { + if (expand_file(tdb, tdb->map_size, size) != 0) + goto fail; + } + + tdb->map_size += size; + + if (tdb->flags & TDB_INTERNAL) + tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); + else { + /* + * We must ensure the file is remapped before adding the space + * to ensure consistency with systems like OpenBSD where + * writes and mmaps are not consistent. + */ + + /* We're ok if the mmap fails as we'll fallback to read/write */ + tdb_mmap(tdb); + } + + /* form a new freelist record */ + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = size - sizeof(rec); + + /* link it into the free list */ + offset = tdb->map_size - size; + if (tdb_free(tdb, offset, &rec) == -1) + goto fail; + + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return -1; +} + +/* allocate some space from the free list. The offset returned points + to a unconnected list_struct within the database with room for at + least length bytes of total data + + 0 is returned if the space could not be allocated + */ +static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, + struct list_struct *rec) +{ + tdb_off rec_ptr, last_ptr, newrec_ptr; + struct list_struct newrec; + + memset(&newrec, '\0', sizeof(newrec)); + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) + return 0; + + /* Extra bytes required for tailer */ + length += sizeof(tdb_off); + + again: + last_ptr = FREELIST_TOP; + + /* read in the freelist top */ + if (ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) + goto fail; + + /* keep looking until we find a freelist record big enough */ + while (rec_ptr) { + if (rec_free_read(tdb, rec_ptr, rec) == -1) + goto fail; + + if (rec->rec_len >= length) { + /* found it - now possibly split it up */ + if (rec->rec_len > length + MIN_REC_SIZE) { + /* Length of left piece */ + length = TDB_ALIGN(length, TDB_ALIGNMENT); + + /* Right piece to go on free list */ + newrec.rec_len = rec->rec_len + - (sizeof(*rec) + length); + newrec_ptr = rec_ptr + sizeof(*rec) + length; + + /* And left record is shortened */ + rec->rec_len = length; + } else + newrec_ptr = 0; + + /* Remove allocated record from the free list */ + if (ofs_write(tdb, last_ptr, &rec->next) == -1) + goto fail; + + /* Update header: do this before we drop alloc + lock, otherwise tdb_free() might try to + merge with us, thinking we're free. + (Thanks Jeremy Allison). */ + rec->magic = TDB_MAGIC; + if (rec_write(tdb, rec_ptr, rec) == -1) + goto fail; + + /* Did we create new block? */ + if (newrec_ptr) { + /* Update allocated record tailer (we + shortened it). */ + if (update_tailer(tdb, rec_ptr, rec) == -1) + goto fail; + + /* Free new record */ + if (tdb_free(tdb, newrec_ptr, &newrec) == -1) + goto fail; + } + + /* all done - return the new record offset */ + tdb_unlock(tdb, -1, F_WRLCK); + return rec_ptr; + } + /* move to the next record */ + last_ptr = rec_ptr; + rec_ptr = rec->next; + } + /* we didn't find enough space. See if we can expand the + database and if we can then try again */ + if (tdb_expand(tdb, length + sizeof(*rec)) == 0) + goto again; + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return 0; +} + +/* initialise a new database with a specified hash size */ +static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size) +{ + struct tdb_header *newdb; + int size, ret = -1; + + /* We make it up in memory, then write it out if not internal */ + size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off); + if (!(newdb = calloc(size, 1))) + return TDB_ERRCODE(TDB_ERR_OOM, -1); + + /* Fill in the header */ + newdb->version = TDB_VERSION; + newdb->hash_size = hash_size; + if (tdb->flags & TDB_INTERNAL) { + tdb->map_size = size; + tdb->map_ptr = (char *)newdb; + memcpy(&tdb->header, newdb, sizeof(tdb->header)); + /* Convert the `ondisk' version if asked. */ + CONVERT(*newdb); + return 0; + } + if (lseek(tdb->fd, 0, SEEK_SET) == -1) + goto fail; + + if (ftruncate(tdb->fd, 0) == -1) + goto fail; + + /* This creates an endian-converted header, as if read from disk */ + CONVERT(*newdb); + memcpy(&tdb->header, newdb, sizeof(tdb->header)); + /* Don't endian-convert the magic food! */ + memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); + if (write(tdb->fd, newdb, size) != size) + ret = -1; + else + ret = tdb_create_rwlocks(tdb->fd, hash_size); + + fail: + SAFE_FREE(newdb); + return ret; +} + +/* Returns 0 on fail. On success, return offset of record, and fills + in rec */ +static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, + struct list_struct *r) +{ + tdb_off rec_ptr; + + /* read in the hash top */ + if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) + return 0; + + /* keep looking until we find the right record */ + while (rec_ptr) { + if (rec_read(tdb, rec_ptr, r) == -1) + return 0; + + if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) { + char *k; + /* a very likely hit - read the key */ + k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r), + r->key_len); + if (!k) + return 0; + + if (memcmp(key.dptr, k, key.dsize) == 0) { + SAFE_FREE(k); + return rec_ptr; + } + SAFE_FREE(k); + } + rec_ptr = r->next; + } + return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); +} + +/* As tdb_find, but if you succeed, keep the lock */ +static tdb_off tdb_find_lock_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, int locktype, + struct list_struct *rec) +{ + u32 rec_ptr; + + if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) + return 0; + if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) + tdb_unlock(tdb, BUCKET(hash), locktype); + return rec_ptr; +} + +enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb) +{ + return tdb->ecode; +} + +static struct tdb_errname { + enum TDB_ERROR ecode; const char *estring; +} emap[] = { {TDB_SUCCESS, "Success"}, + {TDB_ERR_CORRUPT, "Corrupt database"}, + {TDB_ERR_IO, "IO Error"}, + {TDB_ERR_LOCK, "Locking error"}, + {TDB_ERR_OOM, "Out of memory"}, + {TDB_ERR_EXISTS, "Record exists"}, + {TDB_ERR_NOLOCK, "Lock exists on other keys"}, + {TDB_ERR_NOEXIST, "Record does not exist"} }; + +/* Error string for the last tdb error */ +const char *tdb_errorstr(TDB_CONTEXT *tdb) +{ + u32 i; + for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) + if (tdb->ecode == emap[i].ecode) + return emap[i].estring; + return "Invalid error code"; +} + +/* update an entry in place - this only works if the new data size + is <= the old data size and the key exists. + on failure return -1. +*/ + +static int tdb_update_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf) +{ + struct list_struct rec; + tdb_off rec_ptr; + + /* find entry */ + if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) + return -1; + + /* must be long enough key, data and tailer */ + if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off)) { + tdb->ecode = TDB_SUCCESS; /* Not really an error */ + return -1; + } + + if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, + dbuf.dptr, dbuf.dsize) == -1) + return -1; + + if (dbuf.dsize != rec.data_len) { + /* update size */ + rec.data_len = dbuf.dsize; + return rec_write(tdb, rec_ptr, &rec); + } + + return 0; +} + +/* find an entry in the database given a key */ +/* If an entry doesn't exist tdb_err will be set to + * TDB_ERR_NOEXIST. If a key has no data attached + * tdb_err will not be set. Both will return a + * zero pptr and zero dsize. + */ + +TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) +{ + tdb_off rec_ptr; + struct list_struct rec; + TDB_DATA ret; + u32 hash; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) + return tdb_null; + + if (rec.data_len) + ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, + rec.data_len); + else + ret.dptr = NULL; + ret.dsize = rec.data_len; + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + return ret; +} + +/* check if an entry in the database exists + + note that 1 is returned if the key is found and 0 is returned if not found + this doesn't match the conventions in the rest of this module, but is + compatible with gdbm +*/ +static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) +{ + struct list_struct rec; + + if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) + return 0; + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + return 1; +} + +int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) +{ + u32 hash = tdb->hash_fn(&key); + return tdb_exists_hash(tdb, key, hash); +} + +/* record lock stops delete underneath */ +static int lock_record(TDB_CONTEXT *tdb, tdb_off off) +{ + return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0; +} +/* + Write locks override our own fcntl readlocks, so check it here. + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ + +static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off) +{ + struct tdb_traverse_lock *i; + for (i = &tdb->travlocks; i; i = i->next) + if (i->off == off) + return -1; + return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1); +} + +/* + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ + +static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off) +{ + return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0); +} +/* fcntl locks don't stack: avoid unlocking someone else's */ +static int unlock_record(TDB_CONTEXT *tdb, tdb_off off) +{ + struct tdb_traverse_lock *i; + u32 count = 0; + + if (off == 0) + return 0; + for (i = &tdb->travlocks; i; i = i->next) + if (i->off == off) + count++; + return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0) : 0); +} + +/* actually delete an entry in the database given the offset */ +static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec) +{ + tdb_off last_ptr, i; + struct list_struct lastrec; + + if (tdb->read_only) return -1; + + if (write_lock_record(tdb, rec_ptr) == -1) { + /* Someone traversing here: mark it as dead */ + rec->magic = TDB_DEAD_MAGIC; + return rec_write(tdb, rec_ptr, rec); + } + if (write_unlock_record(tdb, rec_ptr) != 0) + return -1; + + /* find previous record in hash chain */ + if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) + return -1; + for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) + if (rec_read(tdb, i, &lastrec) == -1) + return -1; + + /* unlink it: next ptr is at start of record. */ + if (last_ptr == 0) + last_ptr = TDB_HASH_TOP(rec->full_hash); + if (ofs_write(tdb, last_ptr, &rec->next) == -1) + return -1; + + /* recover the space */ + if (tdb_free(tdb, rec_ptr, rec) == -1) + return -1; + return 0; +} + +/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */ +static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock, + struct list_struct *rec) +{ + int want_next = (tlock->off != 0); + + /* Lock each chain from the start one. */ + for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { + if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1) + return -1; + + /* No previous record? Start at top of chain. */ + if (!tlock->off) { + if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash), + &tlock->off) == -1) + goto fail; + } else { + /* Otherwise unlock the previous record. */ + if (unlock_record(tdb, tlock->off) != 0) + goto fail; + } + + if (want_next) { + /* We have offset of old record: grab next */ + if (rec_read(tdb, tlock->off, rec) == -1) + goto fail; + tlock->off = rec->next; + } + + /* Iterate through chain */ + while( tlock->off) { + tdb_off current; + if (rec_read(tdb, tlock->off, rec) == -1) + goto fail; + if (!TDB_DEAD(rec)) { + /* Woohoo: we found one! */ + if (lock_record(tdb, tlock->off) != 0) + goto fail; + return tlock->off; + } + /* Try to clean dead ones from old traverses */ + current = tlock->off; + tlock->off = rec->next; + if (!tdb->read_only && + do_delete(tdb, current, rec) != 0) + goto fail; + } + tdb_unlock(tdb, tlock->hash, F_WRLCK); + want_next = 0; + } + /* We finished iteration without finding anything */ + return TDB_ERRCODE(TDB_SUCCESS, 0); + + fail: + tlock->off = 0; + if (tdb_unlock(tdb, tlock->hash, F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_next_lock: On error unlock failed!\n")); + return -1; +} + +/* traverse the entire database - calling fn(tdb, key, data) on each element. + return -1 on error or the record count traversed + if fn is NULL then it is not called + a non-zero return value from fn() indicates that the traversal should stop + */ +int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *private) +{ + TDB_DATA key, dbuf; + struct list_struct rec; + struct tdb_traverse_lock tl = { NULL, 0, 0 }; + int ret, count = 0; + + /* This was in the initializaton, above, but the IRIX compiler + * did not like it. crh + */ + tl.next = tdb->travlocks.next; + + /* fcntl locks don't stack: beware traverse inside traverse */ + tdb->travlocks.next = &tl; + + /* tdb_next_lock places locks on the record returned, and its chain */ + while ((ret = tdb_next_lock(tdb, &tl, &rec)) > 0) { + count++; + /* now read the full record */ + key.dptr = tdb_alloc_read(tdb, tl.off + sizeof(rec), + rec.key_len + rec.data_len); + if (!key.dptr) { + ret = -1; + if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) + goto out; + if (unlock_record(tdb, tl.off) != 0) + TDB_LOG((tdb, 0, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); + goto out; + } + key.dsize = rec.key_len; + dbuf.dptr = key.dptr + rec.key_len; + dbuf.dsize = rec.data_len; + + /* Drop chain lock, call out */ + if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) { + ret = -1; + goto out; + } + if (fn && fn(tdb, key, dbuf, private)) { + /* They want us to terminate traversal */ + ret = count; + if (unlock_record(tdb, tl.off) != 0) { + TDB_LOG((tdb, 0, "tdb_traverse: unlock_record failed!\n"));; + ret = -1; + } + tdb->travlocks.next = tl.next; + SAFE_FREE(key.dptr); + return count; + } + SAFE_FREE(key.dptr); + } +out: + tdb->travlocks.next = tl.next; + if (ret < 0) + return -1; + else + return count; +} + +/* find the first entry in the database and return its key */ +TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb) +{ + TDB_DATA key; + struct list_struct rec; + + /* release any old lock */ + if (unlock_record(tdb, tdb->travlocks.off) != 0) + return tdb_null; + tdb->travlocks.off = tdb->travlocks.hash = 0; + + if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) + return tdb_null; + /* now read the key */ + key.dsize = rec.key_len; + key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); + if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_firstkey: error occurred while tdb_unlocking!\n")); + return key; +} + +/* find the next entry in the database, returning its key */ +TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey) +{ + u32 oldhash; + TDB_DATA key = tdb_null; + struct list_struct rec; + char *k = NULL; + + /* Is locked key the old key? If so, traverse will be reliable. */ + if (tdb->travlocks.off) { + if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK)) + return tdb_null; + if (rec_read(tdb, tdb->travlocks.off, &rec) == -1 + || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), + rec.key_len)) + || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { + /* No, it wasn't: unlock it and start from scratch */ + if (unlock_record(tdb, tdb->travlocks.off) != 0) + return tdb_null; + if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) + return tdb_null; + tdb->travlocks.off = 0; + } + + SAFE_FREE(k); + } + + if (!tdb->travlocks.off) { + /* No previous element: do normal find, and lock record */ + tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), F_WRLCK, &rec); + if (!tdb->travlocks.off) + return tdb_null; + tdb->travlocks.hash = BUCKET(rec.full_hash); + if (lock_record(tdb, tdb->travlocks.off) != 0) { + TDB_LOG((tdb, 0, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); + return tdb_null; + } + } + oldhash = tdb->travlocks.hash; + + /* Grab next record: locks chain and returned record, + unlocks old record */ + if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) { + key.dsize = rec.key_len; + key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), + key.dsize); + /* Unlock the chain of this new record */ + if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); + } + /* Unlock the chain of old record */ + if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); + return key; +} + +/* delete an entry in the database given a key */ +static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) +{ + tdb_off rec_ptr; + struct list_struct rec; + int ret; + + if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec))) + return -1; + ret = do_delete(tdb, rec_ptr, &rec); + if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_delete: WARNING tdb_unlock failed!\n")); + return ret; +} + +int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) +{ + u32 hash = tdb->hash_fn(&key); + return tdb_delete_hash(tdb, key, hash); +} + +/* store an element in the database, replacing any existing element + with the same key + + return 0 on success, -1 on failure +*/ +int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) +{ + struct list_struct rec; + u32 hash; + tdb_off rec_ptr; + char *p = NULL; + int ret = 0; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + /* check for it existing, on insert. */ + if (flag == TDB_INSERT) { + if (tdb_exists_hash(tdb, key, hash)) { + tdb->ecode = TDB_ERR_EXISTS; + goto fail; + } + } else { + /* first try in-place update, on modify or replace. */ + if (tdb_update_hash(tdb, key, hash, dbuf) == 0) + goto out; + if (tdb->ecode == TDB_ERR_NOEXIST && + flag == TDB_MODIFY) { + /* if the record doesn't exist and we are in TDB_MODIFY mode then + we should fail the store */ + goto fail; + } + } + /* reset the error code potentially set by the tdb_update() */ + tdb->ecode = TDB_SUCCESS; + + /* delete any existing record - if it doesn't exist we don't + care. Doing this first reduces fragmentation, and avoids + coalescing with `allocated' block before it's updated. */ + if (flag != TDB_INSERT) + tdb_delete_hash(tdb, key, hash); + + /* Copy key+value *before* allocating free space in case malloc + fails and we are left with a dead spot in the tdb. */ + + if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + + memcpy(p, key.dptr, key.dsize); + if (dbuf.dsize) + memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); + + /* we have to allocate some space */ + if (!(rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec))) + goto fail; + + /* Read hash top into next ptr */ + if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) + goto fail; + + rec.key_len = key.dsize; + rec.data_len = dbuf.dsize; + rec.full_hash = hash; + rec.magic = TDB_MAGIC; + + /* write out and point the top of the hash chain at it */ + if (rec_write(tdb, rec_ptr, &rec) == -1 + || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 + || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { + /* Need to tdb_unallocate() here */ + goto fail; + } + out: + SAFE_FREE(p); + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + return ret; +fail: + ret = -1; + goto out; +} + +/* Attempt to append data to an entry in place - this only works if the new data size + is <= the old data size and the key exists. + on failure return -1. Record must be locked before calling. +*/ +static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA new_dbuf) +{ + struct list_struct rec; + tdb_off rec_ptr; + + /* find entry */ + if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) + return -1; + + /* Append of 0 is always ok. */ + if (new_dbuf.dsize == 0) + return 0; + + /* must be long enough for key, old data + new data and tailer */ + if (rec.rec_len < key.dsize + rec.data_len + new_dbuf.dsize + sizeof(tdb_off)) { + /* No room. */ + tdb->ecode = TDB_SUCCESS; /* Not really an error */ + return -1; + } + + if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len + rec.data_len, + new_dbuf.dptr, new_dbuf.dsize) == -1) + return -1; + + /* update size */ + rec.data_len += new_dbuf.dsize; + return rec_write(tdb, rec_ptr, &rec); +} + +/* Append to an entry. Create if not exist. */ + +int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) +{ + struct list_struct rec; + u32 hash; + tdb_off rec_ptr; + char *p = NULL; + int ret = 0; + size_t new_data_size = 0; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + /* first try in-place. */ + if (tdb_append_inplace(tdb, key, hash, new_dbuf) == 0) + goto out; + + /* reset the error code potentially set by the tdb_append_inplace() */ + tdb->ecode = TDB_SUCCESS; + + /* find entry */ + if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { + if (tdb->ecode != TDB_ERR_NOEXIST) + goto fail; + + /* Not found - create. */ + + ret = tdb_store(tdb, key, new_dbuf, TDB_INSERT); + goto out; + } + + new_data_size = rec.data_len + new_dbuf.dsize; + + /* Copy key+old_value+value *before* allocating free space in case malloc + fails and we are left with a dead spot in the tdb. */ + + if (!(p = (char *)malloc(key.dsize + new_data_size))) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + + /* Copy the key in place. */ + memcpy(p, key.dptr, key.dsize); + + /* Now read the old data into place. */ + if (rec.data_len && + tdb_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, p + key.dsize, rec.data_len, 0) == -1) + goto fail; + + /* Finally append the new data. */ + if (new_dbuf.dsize) + memcpy(p+key.dsize+rec.data_len, new_dbuf.dptr, new_dbuf.dsize); + + /* delete any existing record - if it doesn't exist we don't + care. Doing this first reduces fragmentation, and avoids + coalescing with `allocated' block before it's updated. */ + + tdb_delete_hash(tdb, key, hash); + + if (!(rec_ptr = tdb_allocate(tdb, key.dsize + new_data_size, &rec))) + goto fail; + + /* Read hash top into next ptr */ + if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) + goto fail; + + rec.key_len = key.dsize; + rec.data_len = new_data_size; + rec.full_hash = hash; + rec.magic = TDB_MAGIC; + + /* write out and point the top of the hash chain at it */ + if (rec_write(tdb, rec_ptr, &rec) == -1 + || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+new_data_size)==-1 + || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { + /* Need to tdb_unallocate() here */ + goto fail; + } + + out: + SAFE_FREE(p); + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + return ret; + +fail: + ret = -1; + goto out; +} + +static int tdb_already_open(dev_t device, + ino_t ino) +{ + TDB_CONTEXT *i; + + for (i = tdbs; i; i = i->next) { + if (i->device == device && i->inode == ino) { + return 1; + } + } + + return 0; +} + +/* This is based on the hash algorithm from gdbm */ +static u32 default_tdb_hash(TDB_DATA *key) +{ + u32 value; /* Used to compute the hash value. */ + u32 i; /* Used to cycle through random values. */ + + /* Set the initial value from the key size. */ + for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) + value = (value + (key->dptr[i] << (i*5 % 24))); + + return (1103515243 * value + 12345); +} + +/* open the database, creating it if necessary + + The open_flags and mode are passed straight to the open call on the + database file. A flags value of O_WRONLY is invalid. The hash size + is advisory, use zero for a default value. + + Return is NULL on error, in which case errno is also set. Don't + try to call tdb_error or tdb_errname, just do strerror(errno). + + @param name may be NULL for internal databases. */ +TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); +} + + +TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + tdb_log_func log_fn, + tdb_hash_func hash_fn) +{ + TDB_CONTEXT *tdb; + struct stat st; + int rev = 0, locked = 0; + unsigned char *vp; + u32 vertest; + + if (!(tdb = calloc(1, sizeof *tdb))) { + /* Can't log this */ + errno = ENOMEM; + goto fail; + } + tdb->fd = -1; + tdb->name = NULL; + tdb->map_ptr = NULL; + tdb->flags = tdb_flags; + tdb->open_flags = open_flags; + tdb->log_fn = log_fn; + tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash; + + if ((open_flags & O_ACCMODE) == O_WRONLY) { + TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n", + name)); + errno = EINVAL; + goto fail; + } + + if (hash_size == 0) + hash_size = DEFAULT_HASH_SIZE; + if ((open_flags & O_ACCMODE) == O_RDONLY) { + tdb->read_only = 1; + /* read only databases don't do locking or clear if first */ + tdb->flags |= TDB_NOLOCK; + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + } + + /* internal databases don't mmap or lock, and start off cleared */ + if (tdb->flags & TDB_INTERNAL) { + tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + if (tdb_new_database(tdb, hash_size) != 0) { + TDB_LOG((tdb, 0, "tdb_open_ex: tdb_new_database failed!")); + goto fail; + } + goto internal; + } + + if ((tdb->fd = open(name, open_flags, mode)) == -1) { + TDB_LOG((tdb, 5, "tdb_open_ex: could not open file %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by open(2) */ + } + + /* ensure there is only one process initialising at once */ + if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) { + TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by tdb_brlock */ + } + + /* we need to zero database if we are the only one with it open */ + if ((tdb_flags & TDB_CLEAR_IF_FIRST) && + (locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))) { + open_flags |= O_CREAT; + if (ftruncate(tdb->fd, 0) == -1) { + TDB_LOG((tdb, 0, "tdb_open_ex: " + "failed to truncate %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by ftruncate */ + } + } + + if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) + || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0 + || (tdb->header.version != TDB_VERSION + && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) { + /* its not a valid database - possibly initialise it */ + if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { + errno = EIO; /* ie bad format or something */ + goto fail; + } + rev = (tdb->flags & TDB_CONVERT); + } + vp = (unsigned char *)&tdb->header.version; + vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) | + (((u32)vp[2]) << 8) | (u32)vp[3]; + tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; + if (!rev) + tdb->flags &= ~TDB_CONVERT; + else { + tdb->flags |= TDB_CONVERT; + convert(&tdb->header, sizeof(tdb->header)); + } + if (fstat(tdb->fd, &st) == -1) + goto fail; + + /* Is it already in the open list? If so, fail. */ + if (tdb_already_open(st.st_dev, st.st_ino)) { + TDB_LOG((tdb, 2, "tdb_open_ex: " + "%s (%d,%d) is already open in this process\n", + name, (int)st.st_dev, (int)st.st_ino)); + errno = EBUSY; + goto fail; + } + + if (!(tdb->name = (char *)strdup(name))) { + errno = ENOMEM; + goto fail; + } + + tdb->map_size = st.st_size; + tdb->device = st.st_dev; + tdb->inode = st.st_ino; + tdb->locked = calloc(tdb->header.hash_size+1, sizeof(tdb->locked[0])); + if (!tdb->locked) { + TDB_LOG((tdb, 2, "tdb_open_ex: " + "failed to allocate lock structure for %s\n", + name)); + errno = ENOMEM; + goto fail; + } + tdb_mmap(tdb); + if (locked) { + if (!tdb->read_only) + if (tdb_clear_spinlocks(tdb) != 0) { + TDB_LOG((tdb, 0, "tdb_open_ex: " + "failed to clear spinlock\n")); + goto fail; + } + if (tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) { + TDB_LOG((tdb, 0, "tdb_open_ex: " + "failed to take ACTIVE_LOCK on %s: %s\n", + name, strerror(errno))); + goto fail; + } + + } + + /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if + we didn't get the initial exclusive lock as we need to let all other + users know we're using it. */ + + if (tdb_flags & TDB_CLEAR_IF_FIRST) { + /* leave this lock in place to indicate it's in use */ + if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) + goto fail; + } + + + internal: + /* Internal (memory-only) databases skip all the code above to + * do with disk files, and resume here by releasing their + * global lock and hooking into the active list. */ + if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1) + goto fail; + tdb->next = tdbs; + tdbs = tdb; + return tdb; + + fail: + { int save_errno = errno; + + if (!tdb) + return NULL; + + if (tdb->map_ptr) { + if (tdb->flags & TDB_INTERNAL) + SAFE_FREE(tdb->map_ptr); + else + tdb_munmap(tdb); + } + SAFE_FREE(tdb->name); + if (tdb->fd != -1) + if (close(tdb->fd) != 0) + TDB_LOG((tdb, 5, "tdb_open_ex: failed to close tdb->fd on error!\n")); + SAFE_FREE(tdb->locked); + SAFE_FREE(tdb); + errno = save_errno; + return NULL; + } +} + +/** + * Close a database. + * + * @returns -1 for error; 0 for success. + **/ +int tdb_close(TDB_CONTEXT *tdb) +{ + TDB_CONTEXT **i; + int ret = 0; + + if (tdb->map_ptr) { + if (tdb->flags & TDB_INTERNAL) + SAFE_FREE(tdb->map_ptr); + else + tdb_munmap(tdb); + } + SAFE_FREE(tdb->name); + if (tdb->fd != -1) + ret = close(tdb->fd); + SAFE_FREE(tdb->locked); + + /* Remove from contexts list */ + for (i = &tdbs; *i; i = &(*i)->next) { + if (*i == tdb) { + *i = tdb->next; + break; + } + } + + memset(tdb, 0, sizeof(*tdb)); + SAFE_FREE(tdb); + + return ret; +} + +/* lock/unlock entire database */ +int tdb_lockall(TDB_CONTEXT *tdb) +{ + u32 i; + + /* There are no locks on read-only dbs */ + if (tdb->read_only) + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + for (i = 0; i < tdb->header.hash_size; i++) + if (tdb_lock(tdb, i, F_WRLCK)) + break; + + /* If error, release locks we have... */ + if (i < tdb->header.hash_size) { + u32 j; + + for ( j = 0; j < i; j++) + tdb_unlock(tdb, j, F_WRLCK); + return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); + } + + return 0; +} +void tdb_unlockall(TDB_CONTEXT *tdb) +{ + u32 i; + for (i=0; i < tdb->header.hash_size; i++) + tdb_unlock(tdb, i, F_WRLCK); +} + +/* lock/unlock one hash chain. This is meant to be used to reduce + contention - it cannot guarantee how many records will be locked */ +int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key) +{ + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); +} + +int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key) +{ + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); +} + +int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key) +{ + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); +} + +int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key) +{ + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); +} + + +/* register a loging function */ +void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)) +{ + tdb->log_fn = fn; +} + +/* reopen a tdb - this can be used after a fork to ensure that we have an independent + seek pointer from our parent and to re-establish locks */ +int tdb_reopen(TDB_CONTEXT *tdb) +{ + struct stat st; + + if (tdb->flags & TDB_INTERNAL) + return 0; /* Nothing to do. */ + if (tdb_munmap(tdb) != 0) { + TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); + goto fail; + } + if (close(tdb->fd) != 0) + TDB_LOG((tdb, 0, "tdb_reopen: WARNING closing tdb->fd failed!\n")); + tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); + if (tdb->fd == -1) { + TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno))); + goto fail; + } + if (fstat(tdb->fd, &st) != 0) { + TDB_LOG((tdb, 0, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); + goto fail; + } + if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { + TDB_LOG((tdb, 0, "tdb_reopen: file dev/inode has changed!\n")); + goto fail; + } + tdb_mmap(tdb); + if ((tdb->flags & TDB_CLEAR_IF_FIRST) && (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) { + TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n")); + goto fail; + } + + return 0; + +fail: + tdb_close(tdb); + return -1; +} + +/* reopen all tdb's */ +int tdb_reopen_all(void) +{ + TDB_CONTEXT *tdb; + + for (tdb=tdbs; tdb; tdb = tdb->next) { + /* Ensure no clear-if-first. */ + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + if (tdb_reopen(tdb) != 0) + return -1; + } + + return 0; +} diff --git a/src/netif/ppp/tdb.h b/src/netif/ppp/tdb.h new file mode 100644 index 00000000..153b6e99 --- /dev/null +++ b/src/netif/ppp/tdb.h @@ -0,0 +1,164 @@ +#ifndef __TDB_H__ +#define __TDB_H__ + +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2004 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PRINTF_ATTRIBUTE +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#if (__GNUC__ >= 3) +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +/* flags to tdb_store() */ +#define TDB_REPLACE 1 +#define TDB_INSERT 2 +#define TDB_MODIFY 3 + +/* flags for tdb_open() */ +#define TDB_DEFAULT 0 /* just a readability place holder */ +#define TDB_CLEAR_IF_FIRST 1 +#define TDB_INTERNAL 2 /* don't store on disk */ +#define TDB_NOLOCK 4 /* don't do any locking */ +#define TDB_NOMMAP 8 /* don't use mmap */ +#define TDB_CONVERT 16 /* convert endian (internal use) */ +#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ + +#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) + +/* error codes */ +enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, + TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, + TDB_ERR_NOEXIST}; + +#ifndef u32 +#define u32 unsigned +#endif + +typedef struct { + char *dptr; + size_t dsize; +} TDB_DATA; + +typedef u32 tdb_len; +typedef u32 tdb_off; + +/* this is stored at the front of every database */ +struct tdb_header { + char magic_food[32]; /* for /etc/magic */ + u32 version; /* version of the code */ + u32 hash_size; /* number of hash entries */ + tdb_off rwlocks; + tdb_off reserved[31]; +}; + +struct tdb_lock_type { + u32 count; + u32 ltype; +}; + +struct tdb_traverse_lock { + struct tdb_traverse_lock *next; + u32 off; + u32 hash; +}; + +/* this is the context structure that is returned from a db open */ +typedef struct tdb_context { + char *name; /* the name of the database */ + void *map_ptr; /* where it is currently mapped */ + int fd; /* open file descriptor for the database */ + tdb_len map_size; /* how much space has been mapped */ + int read_only; /* opened read-only */ + struct tdb_lock_type *locked; /* array of chain locks */ + enum TDB_ERROR ecode; /* error code for last tdb error */ + struct tdb_header header; /* a cached copy of the header */ + u32 flags; /* the flags passed to tdb_open */ + struct tdb_traverse_lock travlocks; /* current traversal locks */ + struct tdb_context *next; /* all tdbs to avoid multiple opens */ + dev_t device; /* uniquely identifies this tdb */ + ino_t inode; /* uniquely identifies this tdb */ + void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...) PRINTF_ATTRIBUTE(3,4); /* logging function */ + u32 (*hash_fn)(TDB_DATA *key); + int open_flags; /* flags used in the open - needed by reopen */ +} TDB_CONTEXT; + +typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *); +typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...); +typedef u32 (*tdb_hash_func)(TDB_DATA *key); + +TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode); +TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + tdb_log_func log_fn, + tdb_hash_func hash_fn); + +int tdb_reopen(TDB_CONTEXT *tdb); +int tdb_reopen_all(void); +void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func); +enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); +const char *tdb_errorstr(TDB_CONTEXT *tdb); +TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); +int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf); +int tdb_close(TDB_CONTEXT *tdb); +TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); +TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *); +int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]); +void tdb_unlockkeys(TDB_CONTEXT *tdb); +int tdb_lockall(TDB_CONTEXT *tdb); +void tdb_unlockall(TDB_CONTEXT *tdb); + +/* Low level locking functions: use with care */ +void tdb_set_lock_alarm(sig_atomic_t *palarm); +int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); + +/* Debug functions. Not used in production. */ +void tdb_dump_all(TDB_CONTEXT *tdb); +int tdb_printfreelist(TDB_CONTEXT *tdb); + +extern TDB_DATA tdb_null; + +#ifdef __cplusplus +} +#endif + +#endif /* tdb.h */ diff --git a/src/netif/ppp/tty.c b/src/netif/ppp/tty.c new file mode 100644 index 00000000..9a11777f --- /dev/null +++ b/src/netif/ppp/tty.c @@ -0,0 +1,1264 @@ +/* + * tty.c - code for handling serial ports in pppd. + * + * Copyright (C) 2000-2004 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Portions derived from main.c, which is: + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: tty.c,v 1.27 2008/07/01 12:27:56 paulus Exp $" + +#include +#include +#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 "fsm.h" +#include "lcp.h" + +void tty_process_extra_options __P((void)); +void tty_check_options __P((void)); +int connect_tty __P((void)); +void disconnect_tty __P((void)); +void tty_close_fds __P((void)); +void cleanup_tty __P((void)); +void tty_do_send_config __P((int, u_int32_t, int, int)); + +static int setdevname __P((char *, char **, int)); +static int setspeed __P((char *, char **, int)); +static int setxonxoff __P((char **)); +static int setescape __P((char **)); +static void printescape __P((option_t *, void (*)(void *, char *,...),void *)); +static void finish_tty __P((void)); +static int start_charshunt __P((int, int)); +static void stop_charshunt __P((void *, int)); +static void charshunt_done __P((void *)); +static void charshunt __P((int, int, char *)); +static int record_write __P((FILE *, int code, u_char *buf, int nb, + struct timeval *)); +static int open_socket __P((char *)); +static void maybe_relock __P((void *, int)); + +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) */ +static int ttyfd; /* Serial port file descriptor */ +static char speed_str[16]; /* Serial port speed as string */ + +mode_t tty_mode = (mode_t)-1; /* Original access permissions to tty */ +int baud_rate; /* Actual bits/second for serial device */ +char *callback_script; /* script for doing callback */ +int charshunt_pid; /* Process ID for charshunt */ +int locked; /* lock() has succeeded */ +struct stat devstat; /* result of stat() on devnam */ + +/* option variables */ +int crtscts = 0; /* Use hardware flow control */ +bool modem = 1; /* Use modem control lines */ +int inspeed = 0; /* Input/Output speed requested */ +bool lockflag = 0; /* Create lock file to lock the serial dev */ +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 */ +bool notty = 0; /* Stdin/out is not a tty */ +char *record_file = NULL; /* File to record chars sent/received */ +int max_data_rate; /* max bytes/sec through charshunt */ +bool sync_serial = 0; /* Device is synchronous serial device */ +char *pty_socket = NULL; /* Socket to connect to pty */ +int using_pty = 0; /* we're allocating a pty as the device */ + +extern uid_t uid; +extern int kill_link; +extern int asked_to_quit; +extern int got_sigterm; + +/* XXX */ +extern int privopen; /* don't lock, open device as root */ + +u_int32_t xmit_accm[8]; /* extended transmit ACCM */ + +/* option descriptors */ +option_t tty_options[] = { + /* device name must be first, or change connect_tty() below! */ + { "device name", o_wild, (void *) &setdevname, + "Serial port device name", + OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, + devnam}, + + { "tty speed", o_wild, (void *) &setspeed, + "Baud rate for serial port", + OPT_PRIO | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, speed_str }, + + { "lock", o_bool, &lockflag, + "Lock serial device with UUCP-style lock file", OPT_PRIO | 1 }, + { "nolock", o_bool, &lockflag, + "Don't lock serial device", OPT_PRIOSUB | OPT_PRIV }, + + { "init", o_string, &initializer, + "A program to initialize the device", OPT_PRIO | OPT_PRIVFIX }, + + { "connect", o_string, &connect_script, + "A program to set up a connection", OPT_PRIO | OPT_PRIVFIX }, + + { "disconnect", o_string, &disconnect_script, + "Program to disconnect serial device", OPT_PRIO | OPT_PRIVFIX }, + + { "welcome", o_string, &welcomer, + "Script to welcome client", OPT_PRIO | OPT_PRIVFIX }, + + { "pty", o_string, &ptycommand, + "Script to run on pseudo-tty master side", + OPT_PRIO | OPT_PRIVFIX | OPT_DEVNAM }, + + { "notty", o_bool, ¬ty, + "Input/output is not a tty", OPT_DEVNAM | 1 }, + + { "socket", o_string, &pty_socket, + "Send and receive over socket, arg is host:port", + OPT_PRIO | OPT_DEVNAM }, + + { "record", o_string, &record_file, + "Record characters sent/received to file", OPT_PRIO }, + + { "crtscts", o_int, &crtscts, + "Set hardware (RTS/CTS) flow control", + OPT_PRIO | OPT_NOARG | OPT_VAL(1) }, + { "cdtrcts", o_int, &crtscts, + "Set alternate hardware (DTR/CTS) flow control", + OPT_PRIOSUB | OPT_NOARG | OPT_VAL(2) }, + { "nocrtscts", o_int, &crtscts, + "Disable hardware flow control", + OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, + { "-crtscts", o_int, &crtscts, + "Disable hardware flow control", + OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, + { "nocdtrcts", o_int, &crtscts, + "Disable hardware flow control", + OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, + { "xonxoff", o_special_noarg, (void *)setxonxoff, + "Set software (XON/XOFF) flow control", OPT_PRIOSUB }, + + { "modem", o_bool, &modem, + "Use modem control lines", OPT_PRIO | 1 }, + { "local", o_bool, &modem, + "Don't use modem control lines", OPT_PRIOSUB | 0 }, + + { "sync", o_bool, &sync_serial, + "Use synchronous HDLC serial encoding", 1 }, + + { "datarate", o_int, &max_data_rate, + "Maximum data rate in bytes/sec (with pty, notty or record option)", + OPT_PRIO }, + + { "escape", o_special, (void *)setescape, + "List of character codes to escape on transmission", + OPT_A2PRINTER, (void *)printescape }, + + { NULL } +}; + + +struct channel tty_channel = { + tty_options, + &tty_process_extra_options, + &tty_check_options, + &connect_tty, + &disconnect_tty, + &tty_establish_ppp, + &tty_disestablish_ppp, + &tty_do_send_config, + &tty_recv_config, + &cleanup_tty, + &tty_close_fds +}; + +/* + * setspeed - Set the serial port baud rate. + * If doit is 0, the call is to check whether this option is + * potentially a speed value. + */ +static int +setspeed(arg, argv, doit) + char *arg; + char **argv; + int doit; +{ + char *ptr; + int spd; + + spd = strtol(arg, &ptr, 0); + if (ptr == arg || *ptr != 0 || spd == 0) + return 0; + if (doit) { + inspeed = spd; + slprintf(speed_str, sizeof(speed_str), "%d", spd); + } + return 1; +} + + +/* + * setdevname - Set the device name. + * If doit is 0, the call is to check whether this option is + * potentially a device name. + */ +static int +setdevname(cp, argv, doit) + char *cp; + char **argv; + int doit; +{ + struct stat statbuf; + char dev[MAXPATHLEN]; + + if (*cp == 0) + return 0; + + if (*cp != '/') { + 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 (!doit) + return errno != ENOENT; + option_error("Couldn't stat %s: %m", cp); + return 0; + } + if (!S_ISCHR(statbuf.st_mode)) { + if (doit) + option_error("%s is not a character device", cp); + return 0; + } + + if (doit) { + strlcpy(devnam, cp, sizeof(devnam)); + devstat = statbuf; + default_device = 0; + } + + return 1; +} + +static int +setxonxoff(argv) + char **argv; +{ + lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ + lcp_wantoptions[0].neg_asyncmap = 1; + + crtscts = -2; + return 1; +} + +/* + * setescape - add chars to the set we escape on transmission. + */ +static int +setescape(argv) + 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[n >> 5] |= 1 << (n & 0x1F); + while (*p == ',' || *p == ' ') + ++p; + } + lcp_allowoptions[0].asyncmap = xmit_accm[0]; + return ret; +} + +static void +printescape(opt, printer, arg) + option_t *opt; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + int n; + int first = 1; + + for (n = 0; n < 256; ++n) { + if (n == 0x7d) + n += 2; /* skip 7d, 7e */ + if (xmit_accm[n >> 5] & (1 << (n & 0x1f))) { + if (!first) + printer(arg, ","); + else + first = 0; + printer(arg, "%x", n); + } + } + if (first) + printer(arg, "oops # nothing escaped"); +} + +/* + * tty_init - do various tty-related initializations. + */ +void tty_init() +{ + add_notifier(&pidchange, maybe_relock, 0); + the_channel = &tty_channel; + xmit_accm[3] = 0x60000000; +} + +/* + * tty_process_extra_options - work out which tty device we are using + * and read its options file. + */ +void tty_process_extra_options() +{ + using_pty = notty || ptycommand != NULL || pty_socket != NULL; + if (using_pty) + return; + if (default_device) { + char *p; + if (!isatty(0) || (p = ttyname(0)) == NULL) { + option_error("no device specified and stdin is not a tty"); + exit(EXIT_OPTION_ERROR); + } + strlcpy(devnam, p, sizeof(devnam)); + if (stat(devnam, &devstat) < 0) + fatal("Couldn't stat default device %s: %m", devnam); + } + + + /* + * Parse the tty options file. + * The per-tty options file should not change + * ptycommand, pty_socket, notty or devnam. + * options_for_tty doesn't override options set on the command line, + * except for some privileged options. + */ + if (!options_for_tty()) + exit(EXIT_OPTION_ERROR); +} + +/* + * tty_check_options - do consistency checks on the options we were given. + */ +void +tty_check_options() +{ + struct stat statbuf; + int fdflags; + + if (demand && notty) { + option_error("demand-dialling is incompatible with notty"); + exit(EXIT_OPTION_ERROR); + } + if (demand && connect_script == 0 && ptycommand == NULL + && pty_socket == NULL) { + option_error("connect script is required for demand-dialling\n"); + exit(EXIT_OPTION_ERROR); + } + /* default holdoff to 0 if no connect script has been given */ + if (connect_script == 0 && !holdoff_specified) + holdoff = 0; + + if (using_pty) { + if (!default_device) { + option_error("%s option precludes specifying device name", + pty_socket? "socket": notty? "notty": "pty"); + exit(EXIT_OPTION_ERROR); + } + if (ptycommand != NULL && notty) { + option_error("pty option is incompatible with notty option"); + exit(EXIT_OPTION_ERROR); + } + if (pty_socket != NULL && (ptycommand != NULL || notty)) { + option_error("socket option is incompatible with pty and notty"); + exit(EXIT_OPTION_ERROR); + } + default_device = notty; + lockflag = 0; + modem = 0; + if (notty && log_to_fd <= 1) + log_to_fd = -1; + } else { + /* + * If the user has specified a device which is the same as + * the one on stdin, pretend they didn't specify any. + * If the device is already open read/write on stdin, + * we assume we don't need to lock it, and we can open it + * as root. + */ + if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode) + && statbuf.st_rdev == devstat.st_rdev) { + default_device = 1; + fdflags = fcntl(0, F_GETFL); + if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR) + privopen = 1; + } + } + if (default_device) + nodetach = 1; + + /* + * Don't send log messages to the serial port, it tends to + * confuse the peer. :-) + */ + if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0 + && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev) + log_to_fd = -1; +} + +/* + * connect_tty - get the serial port ready to start doing PPP. + * That is, open the serial port, set its speed and mode, and run + * the connector and/or welcomer. + */ +int connect_tty() +{ + char *connector; + int fdflags; +#ifndef __linux__ + struct stat statbuf; +#endif + char numbuf[16]; + + /* + * Get a pty master/slave pair if the pty, notty, socket, + * or record options were specified. + */ + strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); + pty_master = -1; + pty_slave = -1; + real_ttyfd = -1; + if (using_pty || record_file != NULL) { + if (!get_pty(&pty_master, &pty_slave, ppp_devnam, uid)) { + error("Couldn't allocate pseudo-tty"); + status = EXIT_FATAL_ERROR; + return -1; + } + set_up_tty(pty_slave, 1); + } + + /* + * Lock the device if we've been asked to. + */ + status = EXIT_LOCK_FAILED; + if (lockflag && !privopen) { + if (lock(devnam) < 0) + goto errret; + locked = 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. + */ + got_sigterm = 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, prio; + + prio = privopen? OPRIO_ROOT: tty_options[0].priority; + if (prio < OPRIO_ROOT && seteuid(uid) == -1) { + error("Unable to drop privileges before opening %s: %m\n", + devnam); + status = EXIT_OPEN_FAILED; + goto errret; + } + real_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0); + err = errno; + if (prio < OPRIO_ROOT && seteuid(0) == -1) + fatal("Unable to regain privileges"); + if (real_ttyfd >= 0) + break; + errno = err; + if (err != EINTR) { + error("Failed to open %s: %m", devnam); + status = EXIT_OPEN_FAILED; + } + if (!persist || err != EINTR) + goto errret; + } + ttyfd = real_ttyfd; + if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 + || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) + warn("Couldn't reset non-blocking mode on device: %m"); + +#ifndef __linux__ + /* + * Linux 2.4 and above blocks normal writes to the tty + * when it is in PPP line discipline, so this isn't needed. + */ + /* + * Do the equivalent of `mesg n' to stop broadcast messages. + */ + if (fstat(ttyfd, &statbuf) < 0 + || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { + warn("Couldn't restrict write permissions to %s: %m", devnam); + } else + tty_mode = statbuf.st_mode; +#endif /* __linux__ */ + + /* + * 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(ttyfd, ((connector != NULL && connector[0] != 0) + || initializer != NULL)); + } + + /* + * If the pty, socket, notty and/or record option was specified, + * start up the character shunt now. + */ + status = EXIT_PTYCMD_FAILED; + if (ptycommand != NULL) { + if (record_file != NULL) { + int ipipe[2], opipe[2], ok; + + if (pipe(ipipe) < 0 || pipe(opipe) < 0) + fatal("Couldn't create pipes for record option: %m"); + + /* don't leak these to the ptycommand */ + (void) fcntl(ipipe[0], F_SETFD, FD_CLOEXEC); + (void) fcntl(opipe[1], F_SETFD, FD_CLOEXEC); + + ok = device_script(ptycommand, opipe[0], ipipe[1], 1) == 0 + && start_charshunt(ipipe[0], opipe[1]); + close(ipipe[0]); + close(ipipe[1]); + close(opipe[0]); + close(opipe[1]); + if (!ok) + goto errret; + } else { + if (device_script(ptycommand, pty_master, pty_master, 1) < 0) + goto errret; + } + } else if (pty_socket != NULL) { + int fd = open_socket(pty_socket); + if (fd < 0) + goto errret; + if (!start_charshunt(fd, fd)) + goto errret; + close(fd); + } else if (notty) { + if (!start_charshunt(0, 1)) + goto errret; + dup2(fd_devnull, 0); + dup2(fd_devnull, 1); + if (log_to_fd == 1) + log_to_fd = -1; + if (log_to_fd != 2) + dup2(fd_devnull, 2); + } else if (record_file != NULL) { + int fd = dup(ttyfd); + if (!start_charshunt(fd, fd)) + goto errret; + } + + if (using_pty || record_file != NULL) { + ttyfd = pty_slave; + close(pty_master); + pty_master = -1; + } + + /* 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(initializer, ttyfd, ttyfd, 0) < 0) { + error("Initializer script failed"); + status = EXIT_INIT_FAILED; + goto errretf; + } + if (got_sigterm) { + disconnect_tty(); + goto errretf; + } + info("Serial port initialized."); + } + + if (connector && connector[0]) { + if (device_script(connector, ttyfd, ttyfd, 0) < 0) { + error("Connect script failed"); + status = EXIT_CONNECT_FAILED; + goto errretf; + } + if (got_sigterm) { + disconnect_tty(); + goto errretf; + } + 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) { + int i; + for (;;) { + if ((i = open(devnam, O_RDWR)) >= 0) + break; + if (errno != EINTR) { + error("Failed to reopen %s: %m", devnam); + status = EXIT_OPEN_FAILED; + } + if (!persist || errno != EINTR || hungup || got_sigterm) + goto errret; + } + close(i); + } + + slprintf(numbuf, sizeof(numbuf), "%d", baud_rate); + script_setenv("SPEED", numbuf, 0); + + /* run welcome script, if any */ + if (welcomer && welcomer[0]) { + if (device_script(welcomer, ttyfd, ttyfd, 0) < 0) + warn("Welcome script failed"); + } + + /* + * If we are initiating this connection, wait for a short + * time for something from the peer. This can avoid bouncing + * our packets off his tty before he has it set up. + */ + if (connector != NULL || ptycommand != NULL || pty_socket != NULL) + listen_time = connect_delay; + + return ttyfd; + + errretf: + if (real_ttyfd >= 0) + tcflush(real_ttyfd, TCIOFLUSH); + errret: + if (pty_master >= 0) { + close(pty_master); + pty_master = -1; + } + ttyfd = -1; + if (got_sigterm) + asked_to_quit = 1; + return -1; +} + + +void disconnect_tty() +{ + if (disconnect_script == NULL || hungup) + return; + if (real_ttyfd >= 0) + set_up_tty(real_ttyfd, 1); + if (device_script(disconnect_script, ttyfd, ttyfd, 0) < 0) { + warn("disconnect script failed"); + } else { + info("Serial link disconnected."); + } + stop_charshunt(NULL, 0); +} + +void tty_close_fds() +{ + if (pty_slave >= 0) + close(pty_slave); + if (real_ttyfd >= 0) { + close(real_ttyfd); + real_ttyfd = -1; + } + /* N.B. ttyfd will == either pty_slave or real_ttyfd */ +} + +void cleanup_tty() +{ + if (real_ttyfd >= 0) + finish_tty(); + tty_close_fds(); + if (locked) { + unlock(); + locked = 0; + } +} + +/* + * tty_do_send_config - set transmit-side PPP configuration. + * We set the extended transmit ACCM here as well. + */ +void +tty_do_send_config(mtu, accm, pcomp, accomp) + int mtu; + u_int32_t accm; + int pcomp, accomp; +{ + tty_set_xaccm(xmit_accm); + tty_send_config(mtu, accm, pcomp, accomp); +} + +/* + * finish_tty - restore the terminal device to its original settings + */ +static void +finish_tty() +{ + /* 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); + +#ifndef __linux__ + if (tty_mode != (mode_t) -1) { + if (fchmod(real_ttyfd, tty_mode) != 0) + error("Couldn't restore tty permissions"); + } +#endif /* __linux__ */ + + close(real_ttyfd); + real_ttyfd = -1; +} + +/* + * maybe_relock - our PID has changed, maybe update the lock file. + */ +static void +maybe_relock(arg, pid) + void *arg; + int pid; +{ + if (locked) + relock(pid); +} + +/* + * open_socket - establish a stream socket connection to the nominated + * host and port. + */ +static int +open_socket(dest) + char *dest; +{ + char *sep, *endp = NULL; + int sock, port = -1; + u_int32_t host; + struct hostent *hent; + struct sockaddr_in sad; + + /* parse host:port and resolve host to an IP address */ + sep = strchr(dest, ':'); + if (sep != NULL) + port = strtol(sep+1, &endp, 10); + if (port < 0 || endp == sep+1 || sep == dest) { + error("Can't parse host:port for socket destination"); + return -1; + } + *sep = 0; + host = inet_addr(dest); + if (host == (u_int32_t) -1) { + hent = gethostbyname(dest); + if (hent == NULL) { + error("%s: unknown host in socket option", dest); + *sep = ':'; + return -1; + } + host = *(u_int32_t *)(hent->h_addr_list[0]); + } + *sep = ':'; + + /* get a socket and connect it to the other end */ + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + error("Can't create socket: %m"); + return -1; + } + memset(&sad, 0, sizeof(sad)); + sad.sin_family = AF_INET; + sad.sin_port = htons(port); + sad.sin_addr.s_addr = host; + if (connect(sock, (struct sockaddr *)&sad, sizeof(sad)) < 0) { + error("Can't connect to %s: %m", dest); + close(sock); + return -1; + } + + return sock; +} + + +/* + * start_charshunt - create a child process to run the character shunt. + */ +static int +start_charshunt(ifd, ofd) + int ifd, ofd; +{ + int cpid; + + cpid = safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2)); + if (cpid == -1) { + error("Can't fork process for character shunt: %m"); + return 0; + } + if (cpid == 0) { + /* child */ + reopen_log(); + if (!nodetach) + log_to_fd = -1; + else if (log_to_fd >= 0) + log_to_fd = 2; + setgid(getgid()); + setuid(uid); + if (getuid() != uid) + fatal("setuid failed"); + charshunt(0, 1, record_file); + exit(0); + } + charshunt_pid = cpid; + record_child(cpid, "pppd (charshunt)", charshunt_done, NULL, 1); + return 1; +} + +static void +charshunt_done(arg) + void *arg; +{ + charshunt_pid = 0; +} + +static void +stop_charshunt(arg, sig) + void *arg; + int sig; +{ + if (charshunt_pid) + kill(charshunt_pid, (sig == SIGINT? sig: SIGTERM)); +} + +/* + * charshunt - the character shunt, which passes characters between + * the pty master side and the serial port (or stdin/stdout). + * This runs as the user (not as root). + * (We assume ofd >= ifd which is true the way this gets called. :-). + */ +static void +charshunt(ifd, ofd, record_file) + int ifd, ofd; + char *record_file; +{ + int n, nfds; + fd_set ready, writey; + u_char *ibufp, *obufp; + int nibuf, nobuf; + int flags; + int pty_readable, stdin_readable; + struct timeval lasttime; + FILE *recordf = NULL; + int ilevel, olevel, max_level; + struct timeval levelt, tout, *top; + extern u_char inpacket_buf[]; + + /* + * Reset signal handlers. + */ + signal(SIGHUP, SIG_IGN); /* Hangup */ + signal(SIGINT, SIG_DFL); /* Interrupt */ + signal(SIGTERM, SIG_DFL); /* Terminate */ + signal(SIGCHLD, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + signal(SIGUSR2, SIG_DFL); + signal(SIGABRT, SIG_DFL); + signal(SIGALRM, SIG_DFL); + signal(SIGFPE, SIG_DFL); + signal(SIGILL, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGSEGV, SIG_DFL); +#ifdef SIGBUS + signal(SIGBUS, SIG_DFL); +#endif +#ifdef SIGEMT + signal(SIGEMT, SIG_DFL); +#endif +#ifdef SIGPOLL + signal(SIGPOLL, SIG_DFL); +#endif +#ifdef SIGPROF + signal(SIGPROF, SIG_DFL); +#endif +#ifdef SIGSYS + signal(SIGSYS, SIG_DFL); +#endif +#ifdef SIGTRAP + signal(SIGTRAP, SIG_DFL); +#endif +#ifdef SIGVTALRM + signal(SIGVTALRM, SIG_DFL); +#endif +#ifdef SIGXCPU + signal(SIGXCPU, SIG_DFL); +#endif +#ifdef SIGXFSZ + signal(SIGXFSZ, SIG_DFL); +#endif + + /* + * Check that the fds won't overrun the fd_sets + */ + if (ifd >= FD_SETSIZE || ofd >= FD_SETSIZE || pty_master >= FD_SETSIZE) + fatal("internal error: file descriptor too large (%d, %d, %d)", + ifd, ofd, pty_master); + + /* + * Open the record file if required. + */ + if (record_file != NULL) { + recordf = fopen(record_file, "a"); + if (recordf == NULL) + error("Couldn't create record file %s: %m", record_file); + } + + /* set all the fds to non-blocking mode */ + flags = fcntl(pty_master, F_GETFL); + if (flags == -1 + || fcntl(pty_master, F_SETFL, flags | O_NONBLOCK) == -1) + warn("couldn't set pty master to nonblock: %m"); + flags = fcntl(ifd, F_GETFL); + if (flags == -1 + || fcntl(ifd, F_SETFL, flags | O_NONBLOCK) == -1) + warn("couldn't set %s to nonblock: %m", (ifd==0? "stdin": "tty")); + if (ofd != ifd) { + flags = fcntl(ofd, F_GETFL); + if (flags == -1 + || fcntl(ofd, F_SETFL, flags | O_NONBLOCK) == -1) + warn("couldn't set stdout to nonblock: %m"); + } + + nibuf = nobuf = 0; + ibufp = obufp = NULL; + pty_readable = stdin_readable = 1; + + ilevel = olevel = 0; + gettimeofday(&levelt, NULL); + if (max_data_rate) { + max_level = max_data_rate / 10; + if (max_level < 100) + max_level = 100; + } else + max_level = PPP_MRU + PPP_HDRLEN + 1; + + nfds = (ofd > pty_master? ofd: pty_master) + 1; + if (recordf != NULL) { + gettimeofday(&lasttime, NULL); + putc(7, recordf); /* put start marker */ + putc(lasttime.tv_sec >> 24, recordf); + putc(lasttime.tv_sec >> 16, recordf); + putc(lasttime.tv_sec >> 8, recordf); + putc(lasttime.tv_sec, recordf); + lasttime.tv_usec = 0; + } + + while (nibuf != 0 || nobuf != 0 || pty_readable || stdin_readable) { + top = 0; + tout.tv_sec = 0; + tout.tv_usec = 10000; + FD_ZERO(&ready); + FD_ZERO(&writey); + if (nibuf != 0) { + if (ilevel >= max_level) + top = &tout; + else + FD_SET(pty_master, &writey); + } else if (stdin_readable) + FD_SET(ifd, &ready); + if (nobuf != 0) { + if (olevel >= max_level) + top = &tout; + else + FD_SET(ofd, &writey); + } else if (pty_readable) + FD_SET(pty_master, &ready); + if (select(nfds, &ready, &writey, NULL, top) < 0) { + if (errno != EINTR) + fatal("select"); + continue; + } + if (max_data_rate) { + double dt; + int nbt; + struct timeval now; + + gettimeofday(&now, NULL); + dt = (now.tv_sec - levelt.tv_sec + + (now.tv_usec - levelt.tv_usec) / 1e6); + nbt = (int)(dt * max_data_rate); + ilevel = (nbt < 0 || nbt > ilevel)? 0: ilevel - nbt; + olevel = (nbt < 0 || nbt > olevel)? 0: olevel - nbt; + levelt = now; + } else + ilevel = olevel = 0; + if (FD_ISSET(ifd, &ready)) { + ibufp = inpacket_buf; + nibuf = read(ifd, ibufp, PPP_MRU + PPP_HDRLEN); + if (nibuf < 0 && errno == EIO) + nibuf = 0; + if (nibuf < 0) { + if (!(errno == EINTR || errno == EAGAIN)) { + error("Error reading standard input: %m"); + break; + } + nibuf = 0; + } else if (nibuf == 0) { + /* end of file from stdin */ + stdin_readable = 0; + if (recordf) + if (!record_write(recordf, 4, NULL, 0, &lasttime)) + recordf = NULL; + } else { + FD_SET(pty_master, &writey); + if (recordf) + if (!record_write(recordf, 2, ibufp, nibuf, &lasttime)) + recordf = NULL; + } + } + if (FD_ISSET(pty_master, &ready)) { + obufp = outpacket_buf; + nobuf = read(pty_master, obufp, PPP_MRU + PPP_HDRLEN); + if (nobuf < 0 && errno == EIO) + nobuf = 0; + if (nobuf < 0) { + if (!(errno == EINTR || errno == EAGAIN)) { + error("Error reading pseudo-tty master: %m"); + break; + } + nobuf = 0; + } else if (nobuf == 0) { + /* end of file from the pty - slave side has closed */ + pty_readable = 0; + stdin_readable = 0; /* pty is not writable now */ + nibuf = 0; + close(ofd); + if (recordf) + if (!record_write(recordf, 3, NULL, 0, &lasttime)) + recordf = NULL; + } else { + FD_SET(ofd, &writey); + if (recordf) + if (!record_write(recordf, 1, obufp, nobuf, &lasttime)) + recordf = NULL; + } + } else if (!stdin_readable) + pty_readable = 0; + if (FD_ISSET(ofd, &writey)) { + n = nobuf; + if (olevel + n > max_level) + n = max_level - olevel; + n = write(ofd, obufp, n); + if (n < 0) { + if (errno == EIO) { + pty_readable = 0; + nobuf = 0; + } else if (errno != EAGAIN && errno != EINTR) { + error("Error writing standard output: %m"); + break; + } + } else { + obufp += n; + nobuf -= n; + olevel += n; + } + } + if (FD_ISSET(pty_master, &writey)) { + n = nibuf; + if (ilevel + n > max_level) + n = max_level - ilevel; + n = write(pty_master, ibufp, n); + if (n < 0) { + if (errno == EIO) { + stdin_readable = 0; + nibuf = 0; + } else if (errno != EAGAIN && errno != EINTR) { + error("Error writing pseudo-tty master: %m"); + break; + } + } else { + ibufp += n; + nibuf -= n; + ilevel += n; + } + } + } + exit(0); +} + +static int +record_write(f, code, buf, nb, tp) + FILE *f; + int code; + u_char *buf; + int nb; + struct timeval *tp; +{ + struct timeval now; + int diff; + + gettimeofday(&now, NULL); + now.tv_usec /= 100000; /* actually 1/10 s, not usec now */ + diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec); + if (diff > 0) { + if (diff > 255) { + putc(5, f); + putc(diff >> 24, f); + putc(diff >> 16, f); + putc(diff >> 8, f); + putc(diff, f); + } else { + putc(6, f); + putc(diff, f); + } + *tp = now; + } + putc(code, f); + if (buf != NULL) { + putc(nb >> 8, f); + putc(nb, f); + fwrite(buf, nb, 1, f); + } + fflush(f); + if (ferror(f)) { + error("Error writing record file: %m"); + return 0; + } + return 1; +} diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c new file mode 100644 index 00000000..1321c6d4 --- /dev/null +++ b/src/netif/ppp/upap.c @@ -0,0 +1,684 @@ +/* + * upap.c - User/Password Authentication Protocol. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: upap.c,v 1.30 2005/07/13 10:41:58 paulus Exp $" + +/* + * TODO: + */ + +#include +#include + +#include "pppd.h" +#include "upap.h" + +static const char rcsid[] = RCSID; + +static bool hide_password = 1; + +/* + * Command-line options. + */ +static option_t pap_option_list[] = { + { "hide-password", o_bool, &hide_password, + "Don't output passwords to log", OPT_PRIO | 1 }, + { "show-password", o_bool, &hide_password, + "Show password string in debug log messages", OPT_PRIOSUB | 0 }, + + { "pap-restart", o_int, &upap[0].us_timeouttime, + "Set retransmit timeout for PAP", OPT_PRIO }, + { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, + "Set max number of transmissions for auth-reqs", OPT_PRIO }, + { "pap-timeout", o_int, &upap[0].us_reqtimeout, + "Set time limit for peer PAP authentication", OPT_PRIO }, + + { NULL } +}; + +/* + * Protocol entry points. + */ +static void upap_init __P((int)); +static void upap_lowerup __P((int)); +static void upap_lowerdown __P((int)); +static void upap_input __P((int, u_char *, int)); +static void upap_protrej __P((int)); +static int upap_printpkt __P((u_char *, int, + void (*) __P((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 __P((void *)); +static void upap_reqtimeout __P((void *)); +static void upap_rauthreq __P((upap_state *, u_char *, int, int)); +static void upap_rauthack __P((upap_state *, u_char *, int, int)); +static void upap_rauthnak __P((upap_state *, u_char *, int, int)); +static void upap_sauthreq __P((upap_state *)); +static void upap_sresp __P((upap_state *, int, int, char *, int)); + + +/* + * upap_init - Initialize a UPAP unit. + */ +static void +upap_init(unit) + 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(unit, user, password) + int unit; + char *user, *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(unit) + 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(arg) + 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(arg) + 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(unit) + 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(unit) + 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(unit) + 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(unit, inpacket, l) + 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(u, inp, id, len) + upap_state *u; + u_char *inp; + int id; + int len; +{ + u_char ruserlen, rpasswdlen; + char *ruser, *rpasswd; + char rhostname[256]; + 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); + + /* + * Check remote number authorization. A plugin may have filled in + * the remote number or added an allowed number, and rather than + * return an authenticate failure, is leaving it for us to verify. + */ + if (retcode == UPAP_AUTHACK) { + if (!auth_number()) { + /* We do not want to leak info about the pap result. */ + retcode = UPAP_AUTHNAK; /* XXX exit value will be "wrong" */ + warn("calling number %q is not authorized", remote_number); + } + } + + msglen = strlen(msg); + if (msglen > 255) + msglen = 255; + upap_sresp(u, retcode, id, msg, msglen); + + /* Null terminate and clean remote name. */ + slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); + + if (retcode == UPAP_AUTHACK) { + u->us_serverstate = UPAPSS_OPEN; + notice("PAP peer authentication succeeded for %q", rhostname); + auth_peer_success(u->us_unit, PPP_PAP, 0, ruser, ruserlen); + } else { + u->us_serverstate = UPAPSS_BADAUTH; + warn("PAP peer authentication failed for %q", rhostname); + 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(u, inp, id, len) + 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, 0); +} + + +/* + * upap_rauthnak - Receive Authenticate-Nak. + */ +static void +upap_rauthnak(u, inp, id, len) + 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(u) + 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(u, code, id, msg, msglen) + upap_state *u; + u_char code, 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(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((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/src/netif/ppp/upap.h b/src/netif/ppp/upap.h new file mode 100644 index 00000000..5cb59e98 --- /dev/null +++ b/src/netif/ppp/upap.h @@ -0,0 +1,110 @@ +/* + * upap.h - User/Password Authentication Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: upap.h,v 1.8 2002/12/04 23:03:33 paulus Exp $ + */ + +/* + * 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 3 /* Timeout (seconds) for retransmitting req */ +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ + +extern upap_state upap[]; + +void upap_authwithpeer __P((int, char *, char *)); +void upap_authpeer __P((int)); + +extern struct protent pap_protent; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c new file mode 100644 index 00000000..9df19db1 --- /dev/null +++ b/src/netif/ppp/utils.c @@ -0,0 +1,1056 @@ +/* + * utils.c - various utility functions used in pppd. + * + * Copyright (c) 1999-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: utils.c,v 1.25 2008/06/03 12:06:37 paulus Exp $" + +#include +#include +#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" +#include "fsm.h" +#include "lcp.h" + +static const char rcsid[] = RCSID; + +#if defined(SUNOS4) +extern char *strerror(); +#endif + +static void logit __P((int, char *, va_list)); +static void log_write __P((int, char *)); +static void vslp_printer __P((void *, char *, ...)); +static void format_packet __P((u_char *, int, void (*) (void *, char *, ...), + void *)); + +struct buffer_info { + char *ptr; + int len; +}; + +/* + * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, + * always leaves destination null-terminated (for len > 0). + */ +size_t +strlcpy(dest, src, len) + char *dest; + const char *src; + size_t len; +{ + size_t ret = strlen(src); + + if (len != 0) { + if (ret < len) + strcpy(dest, src); + else { + strncpy(dest, src, len - 1); + dest[len-1] = 0; + } + } + return ret; +} + +/* + * strlcat - like strcat/strncat, doesn't overflow destination buffer, + * always leaves destination null-terminated (for len > 0). + */ +size_t +strlcat(dest, src, len) + char *dest; + const char *src; + size_t len; +{ + size_t dlen = strlen(dest); + + return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); +} + + +/* + * slprintf - format a message into a buffer. Like sprintf except we + * also specify the length of the output buffer, and we handle + * %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(buf, buflen, fmt, args) + char *buf; + int buflen; + char *fmt; + va_list args; +{ + int c, i, n; + int width, prec, fillch; + int base, len, neg, quoted; + unsigned long val = 0; + char *str, *f, *buf0; + unsigned char *p; + char num[32]; + time_t t; + u_int32_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 'l': + c = *fmt++; + switch (c) { + case 'd': + val = va_arg(args, long); + if (val < 0) { + neg = 1; + val = -val; + } + base = 10; + break; + case 'u': + val = va_arg(args, unsigned long); + base = 10; + break; + default: + OUTCHAR('%'); + OUTCHAR('l'); + --fmt; /* so %lz outputs %lz etc. */ + continue; + } + break; + case 'd': + i = va_arg(args, int); + if (i < 0) { + neg = 1; + val = -i; + } else + val = i; + base = 10; + break; + case 'u': + val = va_arg(args, unsigned int); + 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 = (unsigned long) 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, u_int32_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; +#if 0 /* not used, and breaks on S/390, apparently */ + case 'r': + f = va_arg(args, char *); +#ifndef __powerpc__ + n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list)); +#else + /* 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; +#endif + 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; +} + +#ifdef unused +/* + * log_packet - format a packet and log it. + */ + +void +log_packet(p, len, prefix, level) + u_char *p; + int len; + char *prefix; + int level; +{ + init_pr_log(prefix, level); + format_packet(p, len, pr_log, &level); + end_pr_log(); +} +#endif /* unused */ + +/* + * format_packet - make a readable representation of a packet, + * calling `printer(arg, format, ...)' to output it. + */ +static void +format_packet(p, len, printer, arg) + u_char *p; + int len; + void (*printer) __P((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); +} + +/* + * init_pr_log, end_pr_log - initialize and finish use of pr_log. + */ + +static char line[256]; /* line to be logged accumulated here */ +static char *linep; /* current pointer within line */ +static int llevel; /* level for logging */ + +void +init_pr_log(prefix, level) + const char *prefix; + int level; +{ + linep = line; + if (prefix != NULL) { + strlcpy(line, prefix, sizeof(line)); + linep = line + strlen(line); + } + llevel = level; +} + +void +end_pr_log() +{ + if (linep != line) { + *linep = 0; + log_write(llevel, line); + } +} + +/* + * pr_log - printer routine for outputting to syslog + */ +void +pr_log __V((void *arg, char *fmt, ...)) +{ + int l, n; + va_list pvar; + char *p, *eol; + 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); + + p = buf; + eol = strchr(buf, '\n'); + if (linep != line) { + l = (eol == NULL)? n: eol - buf; + if (linep + l < line + sizeof(line)) { + if (l > 0) { + memcpy(linep, buf, l); + linep += l; + } + if (eol == NULL) + return; + p = eol + 1; + eol = strchr(p, '\n'); + } + *linep = 0; + log_write(llevel, line); + linep = line; + } + + while (eol != NULL) { + *eol = 0; + log_write(llevel, p); + p = eol + 1; + eol = strchr(p, '\n'); + } + + /* assumes sizeof(buf) <= sizeof(line) */ + l = buf + n - p; + if (l > 0) { + memcpy(line, p, n); + linep = line + l; + } +} + +/* + * print_string - print a readable representation of a string using + * printer. + */ +void +print_string(p, len, printer, arg) + char *p; + int len; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + int c; + + 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(level, fmt, args) + int level; + char *fmt; + va_list args; +{ + int n; + char buf[1024]; + + n = vslprintf(buf, sizeof(buf), fmt, args); + log_write(level, buf); +} + +static void +log_write(level, buf) + int level; + char *buf; +{ + syslog(level, "%s", buf); + if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { + int n = strlen(buf); + + if (n > 0 && buf[n-1] == '\n') + --n; + if (write(log_to_fd, buf, n) != n + || write(log_to_fd, "\n", 1) != 1) + log_to_fd = -1; + } +} + +/* + * fatal - log an error message and die horribly. + */ +void +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 +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); + ++error_count; +} + +/* + * warn - log a warning message. + */ +void +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 +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 +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 +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); +} + +/* + * dump_packet - print out a packet in readable form if it is interesting. + * Assumes len >= PPP_HDRLEN. + */ +void +dump_packet(const char *tag, unsigned char *p, int len) +{ + int proto; + + if (!debug) + return; + + /* + * don't print LCP echo request/reply packets if debug <= 1 + * and the link is up. + */ + proto = (p[2] << 8) + p[3]; + if (debug <= 1 && unsuccess == 0 && proto == PPP_LCP + && len >= PPP_HDRLEN + HEADERLEN) { + unsigned char *lcp = p + PPP_HDRLEN; + int l = (lcp[2] << 8) + lcp[3]; + + if ((lcp[0] == ECHOREQ || lcp[0] == ECHOREP) + && l >= HEADERLEN && l <= len - PPP_HDRLEN) + return; + } + + dbglog("%s %P", tag, p, len); +} + +/* + * complete_read - read a full `count' bytes from fd, + * unless end-of-file or an error other than EINTR is encountered. + */ +ssize_t +complete_read(int fd, void *buf, size_t count) +{ + size_t done; + ssize_t nb; + char *ptr = buf; + + for (done = 0; done < count; ) { + nb = read(fd, ptr, count - done); + if (nb < 0) { + if (errno == EINTR) + continue; + return -1; + } + if (nb == 0) + break; + done += nb; + ptr += nb; + } + return done; +} + +/* 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(dev) + char *dev; +{ +#ifdef LOCKLIB + int result; + + result = mklock (dev, (void *) 0); + if (result == 0) { + strlcpy(lock_file, dev, sizeof(lock_file)); + 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; + char lockdev[MAXPATHLEN]; + + if ((p = strstr(dev, "dev/")) != NULL) { + dev = p + 4; + strncpy(lockdev, dev, MAXPATHLEN-1); + lockdev[MAXPATHLEN-1] = 0; + while ((p = strrchr(lockdev, '/')) != NULL) { + *p = '_'; + } + dev = lockdev; + } else + 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(pid) + 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() +{ + if (lock_file[0]) { +#ifdef LOCKLIB + (void) rmlock(lock_file, (void *) 0); +#else + unlink(lock_file); +#endif + lock_file[0] = 0; + } +} + diff --git a/src/netif/ppp/vj.c b/src/netif/ppp/vj.c deleted file mode 100644 index 40fdad13..00000000 --- a/src/netif/ppp/vj.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Routines to compress and uncompess tcp packets (for transmission - * over low speed serial lines. - * - * Copyright (c) 1989 Regents of the University of California. - * 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 University of California, Berkeley. 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. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * Initial distribution. - * - * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, - * so that the entire packet being decompressed doesn't have - * to be in contiguous memory (just the compressed header). - * - * Modified March 1998 by Guy Lancaster, glanca@gesn.com, - * for a 16 bit processor. - */ - -#include "lwip/opt.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "ppp_impl.h" -#include "pppdebug.h" - -#include "vj.h" - -#include - -#if VJ_SUPPORT - -#if LINK_STATS -#define INCR(counter) ++comp->stats.counter -#else -#define INCR(counter) -#endif - -void -vj_compress_init(struct vjcompress *comp) -{ - register u_char i; - register struct cstate *tstate = comp->tstate; - -#if MAX_SLOTS == 0 - memset((char *)comp, 0, sizeof(*comp)); -#endif - comp->maxSlotIndex = MAX_SLOTS - 1; - comp->compressSlot = 0; /* Disable slot ID compression by default. */ - for (i = MAX_SLOTS - 1; i > 0; --i) { - tstate[i].cs_id = i; - tstate[i].cs_next = &tstate[i - 1]; - } - tstate[0].cs_next = &tstate[MAX_SLOTS - 1]; - tstate[0].cs_id = 0; - comp->last_cs = &tstate[0]; - comp->last_recv = 255; - comp->last_xmit = 255; - comp->flags = VJF_TOSS; -} - - -/* ENCODE encodes a number that is known to be non-zero. ENCODEZ - * checks for zero (since zero has to be encoded in the long, 3 byte - * form). - */ -#define ENCODE(n) { \ - if ((u_short)(n) >= 256) { \ - *cp++ = 0; \ - cp[1] = (u_char)(n); \ - cp[0] = (u_char)((n) >> 8); \ - cp += 2; \ - } else { \ - *cp++ = (u_char)(n); \ - } \ -} -#define ENCODEZ(n) { \ - if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ - *cp++ = 0; \ - cp[1] = (u_char)(n); \ - cp[0] = (u_char)((n) >> 8); \ - cp += 2; \ - } else { \ - *cp++ = (u_char)(n); \ - } \ -} - -#define DECODEL(f) { \ - if (*cp == 0) {\ - u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \ - (f) = htonl(tmp); \ - cp += 3; \ - } else { \ - u32_t tmp = ntohl(f) + (u32_t)*cp++; \ - (f) = htonl(tmp); \ - } \ -} - -#define DECODES(f) { \ - if (*cp == 0) {\ - u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \ - (f) = htons(tmp); \ - cp += 3; \ - } else { \ - u_short tmp = ntohs(f) + (u_short)*cp++; \ - (f) = htons(tmp); \ - } \ -} - -#define DECODEU(f) { \ - if (*cp == 0) {\ - (f) = htons(((u_short)cp[1] << 8) | cp[2]); \ - cp += 3; \ - } else { \ - (f) = htons((u_short)*cp++); \ - } \ -} - -/* - * vj_compress_tcp - Attempt to do Van Jacobson header compression on a - * packet. This assumes that nb and comp are not null and that the first - * buffer of the chain contains a valid IP header. - * Return the VJ type code indicating whether or not the packet was - * compressed. - */ -u_int -vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) -{ - register struct ip_hdr *ip = (struct ip_hdr *)pb->payload; - register struct cstate *cs = comp->last_cs->cs_next; - register u_short hlen = IPH_HL(ip); - register struct tcp_hdr *oth; - register struct tcp_hdr *th; - register u_short deltaS, deltaA; - register u_long deltaL; - register u_int changes = 0; - u_char new_seq[16]; - register u_char *cp = new_seq; - - /* - * Check that the packet is IP proto TCP. - */ - if (IPH_PROTO(ip) != IP_PROTO_TCP) { - return (TYPE_IP); - } - - /* - * Bail if this is an IP fragment or if the TCP packet isn't - * `compressible' (i.e., ACK isn't set or some other control bit is - * set). - */ - if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) { - return (TYPE_IP); - } - th = (struct tcp_hdr *)&((long *)ip)[hlen]; - if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) { - return (TYPE_IP); - } - /* - * Packet is compressible -- we're going to send either a - * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need - * to locate (or create) the connection state. Special case the - * most recently used connection since it's most likely to be used - * again & we don't have to do any reordering if it's used. - */ - INCR(vjs_packets); - if (!ip_addr_cmp(&ip->src, &cs->cs_ip.src) - || !ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) - || *(long *)th != ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { - /* - * Wasn't the first -- search for it. - * - * States are kept in a circularly linked list with - * last_cs pointing to the end of the list. The - * list is kept in lru order by moving a state to the - * head of the list whenever it is referenced. Since - * the list is short and, empirically, the connection - * we want is almost always near the front, we locate - * states via linear search. If we don't find a state - * for the datagram, the oldest state is (re-)used. - */ - register struct cstate *lcs; - register struct cstate *lastcs = comp->last_cs; - - do { - lcs = cs; cs = cs->cs_next; - INCR(vjs_searches); - if (ip_addr_cmp(&ip->src, &cs->cs_ip.src) - && ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) - && *(long *)th == ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { - goto found; - } - } while (cs != lastcs); - - /* - * Didn't find it -- re-use oldest cstate. Send an - * uncompressed packet that tells the other side what - * connection number we're using for this conversation. - * Note that since the state list is circular, the oldest - * state points to the newest and we only need to set - * last_cs to update the lru linkage. - */ - INCR(vjs_misses); - comp->last_cs = lcs; - hlen += TCPH_HDRLEN(th); - hlen <<= 2; - /* Check that the IP/TCP headers are contained in the first buffer. */ - if (hlen > pb->len) { - return (TYPE_IP); - } - goto uncompressed; - - found: - /* - * Found it -- move to the front on the connection list. - */ - if (cs == lastcs) { - comp->last_cs = lcs; - } else { - lcs->cs_next = cs->cs_next; - cs->cs_next = lastcs->cs_next; - lastcs->cs_next = cs; - } - } - - oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen]; - deltaS = hlen; - hlen += TCPH_HDRLEN(th); - hlen <<= 2; - /* Check that the IP/TCP headers are contained in the first buffer. */ - if (hlen > pb->len) { - PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen)); - return (TYPE_IP); - } - - /* - * Make sure that only what we expect to change changed. The first - * line of the `if' checks the IP protocol version, header length & - * type of service. The 2nd line checks the "Don't fragment" bit. - * The 3rd line checks the time-to-live and protocol (the protocol - * check is unnecessary but costless). The 4th line checks the TCP - * header length. The 5th line checks IP options, if any. The 6th - * line checks TCP options, if any. If any of these things are - * different between the previous & current datagram, we send the - * current datagram `uncompressed'. - */ - if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] - || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] - || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] - || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) - || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) - || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) { - goto uncompressed; - } - - /* - * Figure out which of the changing fields changed. The - * receiver expects changes in the order: urgent, window, - * ack, seq (the order minimizes the number of temporaries - * needed in this section of code). - */ - if (TCPH_FLAGS(th) & TCP_URG) { - deltaS = ntohs(th->urgp); - ENCODEZ(deltaS); - changes |= NEW_U; - } else if (th->urgp != oth->urgp) { - /* argh! URG not set but urp changed -- a sensible - * implementation should never do this but RFC793 - * doesn't prohibit the change so we have to deal - * with it. */ - goto uncompressed; - } - - if ((deltaS = (u_short)(ntohs(th->wnd) - ntohs(oth->wnd))) != 0) { - ENCODE(deltaS); - changes |= NEW_W; - } - - if ((deltaL = ntohl(th->ackno) - ntohl(oth->ackno)) != 0) { - if (deltaL > 0xffff) { - goto uncompressed; - } - deltaA = (u_short)deltaL; - ENCODE(deltaA); - changes |= NEW_A; - } - - if ((deltaL = ntohl(th->seqno) - ntohl(oth->seqno)) != 0) { - if (deltaL > 0xffff) { - goto uncompressed; - } - deltaS = (u_short)deltaL; - ENCODE(deltaS); - changes |= NEW_S; - } - - switch(changes) { - case 0: - /* - * Nothing changed. If this packet contains data and the - * last one didn't, this is probably a data packet following - * an ack (normal on an interactive connection) and we send - * it compressed. Otherwise it's probably a retransmit, - * retransmitted ack or window probe. Send it uncompressed - * in case the other side missed the compressed version. - */ - if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) && - ntohs(IPH_LEN(&cs->cs_ip)) == hlen) { - break; - } - - /* (fall through) */ - - case SPECIAL_I: - case SPECIAL_D: - /* - * actual changes match one of our special case encodings -- - * send packet uncompressed. - */ - goto uncompressed; - - case NEW_S|NEW_A: - if (deltaS == deltaA && deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { - /* special case for echoed terminal traffic */ - changes = SPECIAL_I; - cp = new_seq; - } - break; - - case NEW_S: - if (deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { - /* special case for data xfer */ - changes = SPECIAL_D; - cp = new_seq; - } - break; - } - - deltaS = (u_short)(ntohs(IPH_ID(ip)) - ntohs(IPH_ID(&cs->cs_ip))); - if (deltaS != 1) { - ENCODEZ(deltaS); - changes |= NEW_I; - } - if (TCPH_FLAGS(th) & TCP_PSH) { - changes |= TCP_PUSH_BIT; - } - /* - * Grab the cksum before we overwrite it below. Then update our - * state with this packet's header. - */ - deltaA = ntohs(th->chksum); - BCOPY(ip, &cs->cs_ip, hlen); - - /* - * We want to use the original packet as our compressed packet. - * (cp - new_seq) is the number of bytes we need for compressed - * sequence numbers. In addition we need one byte for the change - * mask, one for the connection id and two for the tcp checksum. - * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how - * many bytes of the original packet to toss so subtract the two to - * get the new packet size. - */ - deltaS = (u_short)(cp - new_seq); - if (!comp->compressSlot || comp->last_xmit != cs->cs_id) { - comp->last_xmit = cs->cs_id; - hlen -= deltaS + 4; - if(pbuf_header(pb, -hlen)){ - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - } - cp = (u_char *)pb->payload; - *cp++ = (u_char)(changes | NEW_C); - *cp++ = cs->cs_id; - } else { - hlen -= deltaS + 3; - if(pbuf_header(pb, -hlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - } - cp = (u_char *)pb->payload; - *cp++ = (u_char)changes; - } - *cp++ = (u_char)(deltaA >> 8); - *cp++ = (u_char)deltaA; - BCOPY(new_seq, cp, deltaS); - INCR(vjs_compressed); - return (TYPE_COMPRESSED_TCP); - - /* - * Update connection state cs & send uncompressed packet (that is, - * a regular ip/tcp packet but with the 'conversation id' we hope - * to use on future compressed packets in the protocol field). - */ -uncompressed: - BCOPY(ip, &cs->cs_ip, hlen); - IPH_PROTO_SET(ip, cs->cs_id); - comp->last_xmit = cs->cs_id; - return (TYPE_UNCOMPRESSED_TCP); -} - -/* - * Called when we may have missed a packet. - */ -void -vj_uncompress_err(struct vjcompress *comp) -{ - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); -} - -/* - * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. - * Return 0 on success, -1 on failure. - */ -int -vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) -{ - register u_int hlen; - register struct cstate *cs; - register struct ip_hdr *ip; - - ip = (struct ip_hdr *)nb->payload; - hlen = IPH_HL(ip) << 2; - if (IPH_PROTO(ip) >= MAX_SLOTS - || hlen + sizeof(struct tcp_hdr) > nb->len - || (hlen += TCPH_HDRLEN(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2) - > nb->len - || hlen > MAX_HDR) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", - IPH_PROTO(ip), hlen, nb->len)); - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); - return -1; - } - cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)]; - comp->flags &=~ VJF_TOSS; - IPH_PROTO_SET(ip, IP_PROTO_TCP); - BCOPY(ip, &cs->cs_ip, hlen); - cs->cs_hlen = (u_short)hlen; - INCR(vjs_uncompressedin); - return 0; -} - -/* - * Uncompress a packet of type TYPE_COMPRESSED_TCP. - * The packet is composed of a buffer chain and the first buffer - * must contain an accurate chain length. - * The first buffer must include the entire compressed TCP/IP header. - * This procedure replaces the compressed header with the uncompressed - * header and returns the length of the VJ header. - */ -int -vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) -{ - u_char *cp; - struct tcp_hdr *th; - struct cstate *cs; - u_short *bp; - struct pbuf *n0 = *nb; - u32_t tmp; - u_int vjlen, hlen, changes; - - INCR(vjs_compressedin); - cp = (u_char *)n0->payload; - changes = *cp++; - if (changes & NEW_C) { - /* - * Make sure the state index is in range, then grab the state. - * If we have a good state index, clear the 'discard' flag. - */ - if (*cp >= MAX_SLOTS) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp)); - goto bad; - } - - comp->flags &=~ VJF_TOSS; - comp->last_recv = *cp++; - } else { - /* - * this packet has an implicit state index. If we've - * had a line error since the last time we got an - * explicit state index, we have to toss the packet. - */ - if (comp->flags & VJF_TOSS) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n")); - INCR(vjs_tossed); - return (-1); - } - } - cs = &comp->rstate[comp->last_recv]; - hlen = IPH_HL(&cs->cs_ip) << 2; - th = (struct tcp_hdr *)&((u_char *)&cs->cs_ip)[hlen]; - th->chksum = htons((*cp << 8) | cp[1]); - cp += 2; - if (changes & TCP_PUSH_BIT) { - TCPH_SET_FLAG(th, TCP_PSH); - } else { - TCPH_UNSET_FLAG(th, TCP_PSH); - } - - switch (changes & SPECIALS_MASK) { - case SPECIAL_I: - { - register u32_t i = ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; - /* some compilers can't nest inline assembler.. */ - tmp = ntohl(th->ackno) + i; - th->ackno = htonl(tmp); - tmp = ntohl(th->seqno) + i; - th->seqno = htonl(tmp); - } - break; - - case SPECIAL_D: - /* some compilers can't nest inline assembler.. */ - tmp = ntohl(th->seqno) + ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; - th->seqno = htonl(tmp); - break; - - default: - if (changes & NEW_U) { - TCPH_SET_FLAG(th, TCP_URG); - DECODEU(th->urgp); - } else { - TCPH_UNSET_FLAG(th, TCP_URG); - } - if (changes & NEW_W) { - DECODES(th->wnd); - } - if (changes & NEW_A) { - DECODEL(th->ackno); - } - if (changes & NEW_S) { - DECODEL(th->seqno); - } - break; - } - if (changes & NEW_I) { - DECODES(cs->cs_ip._id); - } else { - IPH_ID_SET(&cs->cs_ip, ntohs(IPH_ID(&cs->cs_ip)) + 1); - IPH_ID_SET(&cs->cs_ip, htons(IPH_ID(&cs->cs_ip))); - } - - /* - * At this point, cp points to the first byte of data in the - * packet. Fill in the IP total length and update the IP - * header checksum. - */ - vjlen = (u_short)(cp - (u_char*)n0->payload); - if (n0->len < vjlen) { - /* - * We must have dropped some characters (crc should detect - * this but the old slip framing won't) - */ - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n", - n0->len, vjlen)); - goto bad; - } - -#if BYTE_ORDER == LITTLE_ENDIAN - tmp = n0->tot_len - vjlen + cs->cs_hlen; - IPH_LEN_SET(&cs->cs_ip, htons((u_short)tmp)); -#else - IPH_LEN_SET(&cs->cs_ip, htons(n0->tot_len - vjlen + cs->cs_hlen)); -#endif - - /* recompute the ip header checksum */ - bp = (u_short *) &cs->cs_ip; - IPH_CHKSUM_SET(&cs->cs_ip, 0); - for (tmp = 0; hlen > 0; hlen -= 2) { - tmp += *bp++; - } - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - IPH_CHKSUM_SET(&cs->cs_ip, (u_short)(~tmp)); - - /* Remove the compressed header and prepend the uncompressed header. */ - if(pbuf_header(n0, -((s16_t)(vjlen)))) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - goto bad; - } - - if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) { - struct pbuf *np, *q; - u8_t *bufptr; - - np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); - if(!np) { - PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n")); - goto bad; - } - - if(pbuf_header(np, -cs->cs_hlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - goto bad; - } - - bufptr = n0->payload; - for(q = np; q != NULL; q = q->next) { - MEMCPY(q->payload, bufptr, q->len); - bufptr += q->len; - } - - if(n0->next) { - pbuf_chain(np, n0->next); - pbuf_dechain(n0); - } - pbuf_free(n0); - n0 = np; - } - - if(pbuf_header(n0, cs->cs_hlen)) { - struct pbuf *np; - - LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE); - np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL); - if(!np) { - PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n")); - goto bad; - } - pbuf_cat(np, n0); - n0 = np; - } - LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); - MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen); - - *nb = n0; - - return vjlen; - -bad: - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); - return (-1); -} - -#endif /* VJ_SUPPORT */ - -#endif /* PPP_SUPPORT */ From 54d5ee5562d1a5df5e989606ace6f9ba338cc396 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 15:50:15 +0200 Subject: [PATCH 002/320] added LCP adaptive echo from Debian patches, I like the idea --- src/netif/ppp/lcp.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 2a68b669..645fc030 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -75,6 +75,9 @@ static void lcp_delayed_up __P((void *)); */ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +#if PPP_LCP_ADAPTIVE +bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ +#endif bool lax_recv = 0; /* accept control chars in asyncmap */ bool noendpoint = 0; /* don't send/accept endpoint discriminator */ @@ -153,6 +156,10 @@ static option_t lcp_option_list[] = { OPT_PRIO }, { "lcp-echo-interval", o_int, &lcp_echo_interval, "Set time in seconds between LCP echo requests", OPT_PRIO }, +#if PPP_LCP_ADAPTIVE + { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive, + "Suppress LCP echo requests if traffic was received", 1 }, +#endif { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, "Set time in seconds between LCP retransmissions", OPT_PRIO }, { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, @@ -2325,6 +2332,24 @@ LcpSendEchoRequest (f) } } +#if PPP_LCP_ADAPTIVE + /* + * If adaptive echos have been enabled, only send the echo request if + * no traffic was received since the last one. + */ + if (lcp_echo_adaptive) { + static unsigned int last_pkts_in = 0; + + update_link_stats(f->unit); + link_stats_valid = 0; + + if (link_stats.pkts_in != last_pkts_in) { + last_pkts_in = link_stats.pkts_in; + return; + } + } +#endif + /* * Make and send the echo request frame. */ From ef59e952d856fbf8b9131c2d25d8f1d55499ea65 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 15:55:27 +0200 Subject: [PATCH 003/320] added IPCP no/replace default route option from Debian patches, I like the idea --- src/netif/ppp/ipcp.c | 37 +++++++++++++++----- src/netif/ppp/ipcp.h | 1 + src/netif/ppp/pppd.h | 2 +- src/netif/ppp/sys-linux.c | 74 +++++++++++++++++++++++++++++++++------ 4 files changed, 94 insertions(+), 20 deletions(-) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index f2bafe70..f8547846 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -200,6 +200,14 @@ static option_t ipcp_option_list[] = { "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, &ipcp_wantoptions[0].default_route }, + { "replacedefaultroute", o_bool, + &ipcp_wantoptions[0].replace_default_route, + "Replace default route", 1 + }, + { "noreplacedefaultroute", o_bool, + &ipcp_allowoptions[0].replace_default_route, + "Never replace default route", OPT_A2COPY, + &ipcp_wantoptions[0].replace_default_route }, { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, @@ -273,7 +281,7 @@ struct protent ipcp_protent = { ip_active_pkt }; -static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t)); +static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool)); static void ipcp_script __P((char *, int)); /* Run an up/down script */ static void ipcp_script_done __P((void *)); @@ -1744,7 +1752,8 @@ ip_demand_conf(u) if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) return 0; if (wo->default_route) - if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) + if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr, + wo->replace_default_route)) default_route_set[u] = 1; if (wo->proxy_arp) if (sifproxyarp(u, wo->hisaddr)) @@ -1835,7 +1844,8 @@ ipcp_up(f) */ if (demand) { if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { - ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); + ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr, + wo->replace_default_route); if (go->ouraddr != wo->ouraddr) { warn("Local IP address changed to %I", go->ouraddr); script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); @@ -1860,7 +1870,8 @@ ipcp_up(f) /* assign a default route through the interface if required */ if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, + wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ @@ -1910,7 +1921,8 @@ ipcp_up(f) /* assign a default route through the interface if required */ if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, + wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ @@ -1988,7 +2000,7 @@ ipcp_down(f) 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_hisoptions[f->unit].hisaddr, 0); } /* Execute the ip-down script */ @@ -2004,16 +2016,25 @@ ipcp_down(f) * proxy arp entries, etc. */ static void -ipcp_clear_addrs(unit, ouraddr, hisaddr) +ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute) int unit; u_int32_t ouraddr; /* local address */ u_int32_t hisaddr; /* remote address */ + bool replacedefaultroute; { if (proxy_arp_set[unit]) { cifproxyarp(unit, hisaddr); proxy_arp_set[unit] = 0; } - if (default_route_set[unit]) { + /* If replacedefaultroute, sifdefaultroute will be called soon + * with replacedefaultroute set and that will overwrite the current + * default route. This is the case only when doing demand, otherwise + * during demand, this cifdefaultroute would restore the old default + * route which is not what we want in this case. In the non-demand + * case, we'll delete the default route and restore the old if there + * is one saved by an sifdefaultroute with replacedefaultroute. + */ + if (!replacedefaultroute && default_route_set[unit]) { cifdefaultroute(unit, ouraddr, hisaddr); default_route_set[unit] = 0; } diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index 6cf14c99..7ecfa79d 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -70,6 +70,7 @@ typedef struct ipcp_options { 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 replace_default_route; /* Replace 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? */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index e42d3318..0119f106 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -643,7 +643,7 @@ int sif6addr __P((int, eui64_t, eui64_t)); int cif6addr __P((int, eui64_t, eui64_t)); /* Remove an IPv6 address from i/f */ #endif -int sifdefaultroute __P((int, u_int32_t, u_int32_t)); +int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt)); /* Create default route through i/f */ int cifdefaultroute __P((int, u_int32_t, u_int32_t)); /* Delete default route through i/f */ diff --git a/src/netif/ppp/sys-linux.c b/src/netif/ppp/sys-linux.c index 48a46d60..9c735ab9 100644 --- a/src/netif/ppp/sys-linux.c +++ b/src/netif/ppp/sys-linux.c @@ -208,6 +208,8 @@ static unsigned char inbuf[512]; /* buffer for chars read from loopback */ static int if_is_up; /* Interface has been marked up */ static int have_default_route; /* Gateway for default route added */ +static struct rtentry old_def_rt; /* Old default route */ +static int default_rt_repl_rest; /* replace and restore old default rt */ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ static char proxy_arp_dev[16]; /* Device for proxy arp entry */ static u_int32_t our_old_addr; /* for detecting address changes */ @@ -1546,6 +1548,9 @@ static int read_route_table(struct rtentry *rt) p = NULL; } + SET_SA_FAMILY (rt->rt_dst, AF_INET); + SET_SA_FAMILY (rt->rt_gateway, AF_INET); + SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); @@ -1615,20 +1620,51 @@ int have_route_to(u_int32_t addr) /******************************************************************** * * sifdefaultroute - assign a default route through the address given. + * + * If the global default_rt_repl_rest flag is set, then this function + * already replaced the original system defaultroute with some other + * route and it should just replace the current defaultroute with + * another one, without saving the current route. Use: demand mode, + * when pppd sets first a defaultroute it it's temporary ppp0 addresses + * and then changes the temporary addresses to the addresses for the real + * ppp connection when it has come up. */ -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { - struct rtentry rt; + struct rtentry rt, tmp_rt; + struct rtentry *del_rt = NULL; - if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { - if (rt.rt_flags & RTF_GATEWAY) - error("not replacing existing default route via %I", - SIN_ADDR(rt.rt_gateway)); - else + if (default_rt_repl_rest) { + /* We have already reclaced the original defaultroute, if we + are called again, we will delete the current default route + and set the new default route in this function. + - this is normally only the case the doing demand: */ + if (defaultroute_exists(&tmp_rt)) + del_rt = &tmp_rt; + } else if (defaultroute_exists(&old_def_rt) && + strcmp(old_def_rt.rt_dev, ifname) != 0) { + /* We did not yet replace an existing default route, let's + check if we should save and replace a default route: */ + if (old_def_rt.rt_flags & RTF_GATEWAY) { + if (!replace) { + error("not replacing existing default route via %I", + SIN_ADDR(old_def_rt.rt_gateway)); + return 0; + } else { + /* we need to copy rt_dev because we need it permanent too: */ + char *tmp_dev = malloc(strlen(old_def_rt.rt_dev) + 1); + strcpy(tmp_dev, old_def_rt.rt_dev); + old_def_rt.rt_dev = tmp_dev; + + notice("replacing old default route to %s [%I]", + old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway)); + default_rt_repl_rest = 1; + del_rt = &old_def_rt; + } + } else error("not replacing existing default route through %s", - rt.rt_dev); - return 0; + old_def_rt.rt_dev); } memset (&rt, 0, sizeof (rt)); @@ -1643,10 +1679,16 @@ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) rt.rt_flags = RTF_UP; if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { - if ( ! ok_error ( errno )) + if (!ok_error(errno)) error("default route ioctl(SIOCADDRT): %m"); return 0; } + if (default_rt_repl_rest && del_rt) + if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) { + if (!ok_error(errno)) + error("del old default route ioctl(SIOCDELRT): %m"); + return 0; + } have_default_route = 1; return 1; @@ -1677,11 +1719,21 @@ int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) rt.rt_flags = RTF_UP; if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp()) { - if ( ! ok_error ( errno )) + if (!ok_error(errno)) error("default route ioctl(SIOCDELRT): %m"); return 0; } } + if (default_rt_repl_rest) { + notice("restoring old default route to %s [%I]", + old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway)); + if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) { + if (!ok_error(errno)) + error("restore default route ioctl(SIOCADDRT): %m"); + return 0; + } + default_rt_repl_rest = 0; + } return 1; } From d4978210f0cf54109c4d1030be1eb289e4c75b39 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 15:56:35 +0200 Subject: [PATCH 004/320] using rp-pppoe pppd exits with EXIT_OK after receiving a timeout waiting for PADO due to no modem attached, from Debian patches http://ppp.samba.org/cgi-bin/ppp-bugs/incoming?id=2211 Using rp-pppoe pppd exits with exitcode 0, whenever there is no modem connected and pppd get's a timeout while waiting for a PADO. This happens because status is set to EXIT_OK in main.c at the beginning of the procedures. Within start_link(), connect() will be called as one of the first calls. If that call fails (no pppoe discovery for example), jumps to "fail", which returns without setting the status variable to failure. So at the end pppd exits with EXIT_OK. I moved the status = EXIT_NEGOTIATION_FAILED which will be set later within start_link, at the top of it. That seems to work out, patch is attached: --- src/netif/ppp/auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 9e105c0a..f54e4925 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -559,6 +559,7 @@ void start_link(unit) { char *msg; + status = EXIT_NEGOTIATION_FAILED; new_phase(PHASE_SERIALCONN); hungup = 0; @@ -595,7 +596,6 @@ void start_link(unit) notice("Starting negotiation on %s", ppp_devnam); add_fd(fd_ppp); - status = EXIT_NEGOTIATION_FAILED; new_phase(PHASE_ESTABLISH); lcp_lowerup(0); From bea796ebc0bb87b5a3cfcf61b48d8069a26f4342 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 16:14:30 +0200 Subject: [PATCH 005/320] pppd: Terminate correctly if lcp_lowerup delayed calling fsm_lowerup --- src/netif/ppp/lcp.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 645fc030..0656ea48 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -406,21 +406,29 @@ lcp_close(unit, reason) char *reason; { fsm *f = &lcp_fsm[unit]; + int oldstate; if (phase != PHASE_DEAD && phase != PHASE_MASTER) new_phase(PHASE_TERMINATE); - if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { + + if (f->flags & DELAYED_UP) { + untimeout(lcp_delayed_up, f); + f->state = STOPPED; + } + oldstate = f->state; + + fsm_close(f, reason); + if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) { /* * 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. + * lcp_close() when a connection hasn't been established + * because we are in passive/silent mode or because we have + * delayed the fsm_lowerup() call and it hasn't happened yet. */ - f->state = CLOSED; + f->flags &= ~DELAYED_UP; lcp_finished(f); - - } else - fsm_close(f, reason); + } } @@ -462,9 +470,10 @@ lcp_lowerdown(unit) { fsm *f = &lcp_fsm[unit]; - if (f->flags & DELAYED_UP) + if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; - else + untimeout(lcp_delayed_up, f); + } else fsm_lowerdown(&lcp_fsm[unit]); } @@ -498,6 +507,7 @@ lcp_input(unit, p, len) if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; + untimeout(lcp_delayed_up, f); fsm_lowerup(f); } fsm_input(f, p, len); From a1d80c29deebda8ee158129f4445d27cc7a1a5d0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 16:23:32 +0200 Subject: [PATCH 006/320] fixed demand_rexmit() with new IP addr, maybe we will never support demand or drop it, but it is already patched just in case --- src/netif/ppp/demand.c | 99 +++++++++++++++++++++++++++++++++++++++++- src/netif/ppp/ipcp.c | 2 +- src/netif/ppp/pppd.h | 2 +- 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index fd24b8bb..c654d34d 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include #include @@ -45,6 +47,8 @@ #include #include #include +#include +#include #ifdef PPP_FILTER #include #endif @@ -223,6 +227,14 @@ loop_chars(p, n) int c, rv; rv = 0; + +/* check for synchronous connection... */ + + if ( (p[0] == 0xFF) && (p[1] == 0x03) ) { + rv = loop_frame(p,n); + return rv; + } + for (; n > 0; --n) { c = *p++; if (c == PPP_FLAG) { @@ -301,17 +313,102 @@ loop_frame(frame, len) * loopback, now that the real serial link is up. */ void -demand_rexmit(proto) +demand_rexmit(proto, newip) int proto; + u_int32_t newip; { struct packet *pkt, *prev, *nextpkt; + unsigned short checksum; + unsigned short pkt_checksum = 0; + unsigned iphdr; + struct timeval tv; + char cv = 0; + char ipstr[16]; prev = NULL; pkt = pend_q; pend_q = NULL; + tv.tv_sec = 1; + tv.tv_usec = 0; + select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */ for (; pkt != NULL; pkt = nextpkt) { nextpkt = pkt->next; if (PPP_PROTOCOL(pkt->data) == proto) { + if ( (proto == PPP_IP) && newip ) { + /* Get old checksum */ + + iphdr = (pkt->data[4] & 15) << 2; + checksum = *((unsigned short *) (pkt->data+14)); + if (checksum == 0xFFFF) { + checksum = 0; + } + + + if (pkt->data[13] == 17) { + pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr)); + if (pkt_checksum) { + cv = 1; + if (pkt_checksum == 0xFFFF) { + pkt_checksum = 0; + } + } + else { + cv = 0; + } + } + + if (pkt->data[13] == 6) { + pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr)); + cv = 1; + if (pkt_checksum == 0xFFFF) { + pkt_checksum = 0; + } + } + + /* Delete old Source-IP-Address */ + checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + /* Change Source-IP-Address */ + * ((u_int32_t *) (pkt->data + 16)) = newip; + + /* Add new Source-IP-Address */ + checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + /* Write new checksum */ + if (!checksum) { + checksum = 0xFFFF; + } + *((unsigned short *) (pkt->data+14)) = checksum; + if (pkt->data[13] == 6) { + *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum; + } + if (cv && (pkt->data[13] == 17) ) { + *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum; + } + + /* Log Packet */ + strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16)))); + if (pkt->data[13] == 1) { + syslog(LOG_INFO,"Open ICMP %s -> %s\n", + ipstr, + inet_ntoa(*( (struct in_addr *) (pkt->data+20)))); + } else { + syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n", + pkt->data[13] == 6 ? "TCP" : "UDP", + ipstr, + ntohs(*( (short *) (pkt->data+iphdr+4))), + inet_ntoa(*( (struct in_addr *) (pkt->data+20))), + ntohs(*( (short *) (pkt->data+iphdr+6)))); + } + } output(0, pkt->data, pkt->length); free(pkt); } else { diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index f8547846..c29d5253 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1880,7 +1880,7 @@ ipcp_up(f) proxy_arp_set[f->unit] = 1; } - demand_rexmit(PPP_IP); + demand_rexmit(PPP_IP,go->ouraddr); sifnpmode(f->unit, PPP_IP, NPMODE_PASS); } else { diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 0119f106..7238da36 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -564,7 +564,7 @@ void demand_conf __P((void)); /* config interface(s) for demand-dial */ void demand_block __P((void)); /* set all NPs to queue up packets */ void demand_unblock __P((void)); /* set all NPs to pass packets */ void demand_discard __P((void)); /* set all NPs to discard packets */ -void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ +void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ From db794c2d325bdc22ffc4cd6bcfa16abcd6149abb Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 16:29:00 +0200 Subject: [PATCH 007/320] PPPoL2TP patch from Debian, not used yet, but already fixed --- src/netif/ppp/linux/if_pppol2tp.h | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/linux/if_pppol2tp.h b/src/netif/ppp/linux/if_pppol2tp.h index 4113d6ad..7ee86b24 100644 --- a/src/netif/ppp/linux/if_pppol2tp.h +++ b/src/netif/ppp/linux/if_pppol2tp.h @@ -2,7 +2,7 @@ * Linux PPP over L2TP (PPPoL2TP) Socket Implementation (RFC 2661) * * This file supplies definitions required by the PPP over L2TP driver - * (pppol2tp.c). All version information wrt this file is located in pppol2tp.c + * (l2tp_ppp.c). All version information wrt this file is located in l2tp_ppp.c * * License: * This program is free software; you can redistribute it and/or @@ -15,14 +15,14 @@ #ifndef __LINUX_IF_PPPOL2TP_H #define __LINUX_IF_PPPOL2TP_H -#include +#include + /* Structure used to connect() the socket to a particular tunnel UDP * socket. */ -struct pppol2tp_addr -{ - pid_t pid; /* pid that owns the fd. +struct pppol2tp_addr { + __kernel_pid_t pid; /* pid that owns the fd. * 0 => current */ int fd; /* FD of UDP socket to use */ @@ -32,6 +32,20 @@ struct pppol2tp_addr __u16 d_tunnel, d_session; /* For sending outgoing packets */ }; +/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32 + * bits. So we need a different sockaddr structure. + */ +struct pppol2tpv3_addr { + pid_t pid; /* pid that owns the fd. + * 0 => current */ + int fd; /* FD of UDP or IP socket to use */ + + struct sockaddr_in addr; /* IP address and port to send to */ + + __u32 s_tunnel, s_session; /* For matching incoming packets */ + __u32 d_tunnel, d_session; /* For sending outgoing packets */ +}; + /* Socket options: * DEBUG - bitmask of debug message categories * SENDSEQ - 0 => don't send packets with sequence numbers From 8834a8b2164f481ec89e53e176872d37d84ff9c9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 16:36:59 +0200 Subject: [PATCH 008/320] using UNTIMEOUT macro instead of timeout() --- src/netif/ppp/lcp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 0656ea48..8ee2db74 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -412,7 +412,7 @@ lcp_close(unit, reason) new_phase(PHASE_TERMINATE); if (f->flags & DELAYED_UP) { - untimeout(lcp_delayed_up, f); + UNTIMEOUT(lcp_delayed_up, f); f->state = STOPPED; } oldstate = f->state; @@ -472,7 +472,7 @@ lcp_lowerdown(unit) if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; - untimeout(lcp_delayed_up, f); + UNTIMEOUT(lcp_delayed_up, f); } else fsm_lowerdown(&lcp_fsm[unit]); } @@ -507,7 +507,7 @@ lcp_input(unit, p, len) if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; - untimeout(lcp_delayed_up, f); + UNTIMEOUT(lcp_delayed_up, f); fsm_lowerup(f); } fsm_input(f, p, len); From 33e8472473fa063eb88911d0f1918b131f0892fe Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 19:05:47 +0200 Subject: [PATCH 009/320] CHAP auth is now working --- src/netif/ppp/auth.c | 99 ++++++++++++++++++++++++++++++---------- src/netif/ppp/chap-new.c | 11 ++++- 2 files changed, 83 insertions(+), 27 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index f54e4925..34495f43 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -224,8 +224,8 @@ static pid_t auth_script_pid = 0; bool uselogin = 0; /* Use /etc/passwd for checking PAP */ bool session_mgmt = 0; /* Do session management (login records) */ 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 refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ +//bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ #ifdef CHAPMS bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ @@ -252,7 +252,7 @@ static void network_phase __P((int)); static void check_idle __P((void *)); static void connect_time_expired __P((void *)); static int null_login __P((int)); -static int get_pap_passwd __P((char *)); +/* static int get_pap_passwd __P((char *)); */ static int have_pap_secret __P((int *)); static int have_chap_secret __P((char *, char *, int, int *)); static int have_srp_secret __P((char *client, char *server, int need_ip, @@ -318,7 +318,7 @@ option_t auth_options[] = { OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, &lcp_wantoptions[0].chap_mdtype }, #endif - +#if 0 { "refuse-pap", o_bool, &refuse_pap, "Don't agree to auth to peer with PAP", 1 }, { "-pap", o_bool, &refuse_pap, @@ -331,6 +331,7 @@ option_t auth_options[] = { "Don't allow CHAP authentication with peer", OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5, &lcp_allowoptions[0].chap_mdtype }, +#endif #ifdef CHAPMS { "refuse-mschap", o_bool, &refuse_mschap, "Don't agree to auth to peer with MS-CHAP", @@ -459,11 +460,11 @@ setupapfile(argv) p[l-1] = 0; if (override_value("user", option_priority, fname)) { - strlcpy(user, u, sizeof(user)); + strlcpy(ppp_settings.user, u, sizeof(ppp_settings.user)); explicit_user = 1; } if (override_value("passwd", option_priority, fname)) { - strlcpy(passwd, p, sizeof(passwd)); + strlcpy(ppp_settings.passwd, p, sizeof(ppp_settings.passwd)); explicit_passwd = 1; } @@ -789,10 +790,10 @@ link_established(unit) auth |= PAP_PEER; } if (ho->neg_eap) { - eap_authwithpeer(unit, user); + eap_authwithpeer(unit, ppp_settings.user); auth |= EAP_WITHPEER; } else if (ho->neg_chap) { - chap_auth_with_peer(unit, user, CHAP_DIGEST(ho->chap_mdtype)); + chap_auth_with_peer(unit, ppp_settings.user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else if (ho->neg_upap) { #if 0 @@ -1007,7 +1008,7 @@ auth_withpeer_fail(unit, protocol) int unit, protocol; { if (passwd_from_file) - BZERO(passwd, MAXSECRETLEN); + BZERO(ppp_settings.passwd, MAXSECRETLEN); /* * We've failed to authenticate ourselves to our peer. * Some servers keep sending CHAP challenges, but there @@ -1244,8 +1245,8 @@ auth_check_options() strlcpy(our_name, hostname, sizeof(our_name)); /* If a blank username was explicitly given as an option, trust the user and don't use our_name */ - if (user[0] == 0 && !explicit_user) - strlcpy(user, our_name, sizeof(user)); + if (ppp_settings.user[0] == 0 && !explicit_user) + strlcpy(ppp_settings.user, our_name, sizeof(ppp_settings.user)); /* * If we have a default route, require the peer to authenticate @@ -1337,16 +1338,23 @@ auth_reset(unit) int hadchap; hadchap = -1; - ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); - ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2) + //ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); + ao->neg_upap = !ppp_settings.refuse_pap && ppp_settings.passwd[0] != 0; + + ao->neg_chap = (!ppp_settings.refuse_chap || !refuse_mschap || !refuse_mschap_v2) && ppp_settings.passwd[0]; + + return; + + /* + ao->neg_chap = (!ppp_settings.refuse_chap || !refuse_mschap || !refuse_mschap_v2) && (passwd[0] != 0 || (hadchap = have_chap_secret(user, (explicit_remote? remote_name: - NULL), 0, NULL))); + NULL), 0, NULL))); */ ao->neg_eap = !refuse_eap && ( passwd[0] != 0 || - (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, + (hadchap == 1 || (hadchap == -1 && have_chap_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL))) || - have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); + have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); hadchap = -1; if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) @@ -1365,7 +1373,6 @@ auth_reset(unit) go->neg_eap = 0; } - /* * check_passwd - Check the user name and passwd against the PAP secrets * file. If requested, also check against the system password database, @@ -1398,15 +1405,15 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) * If there are unprintable characters in the password, make * them visible. */ - slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd); - slprintf(user, sizeof(user), "%.*v", userlen, auser); + slprintf(ppp_settings.passwd, sizeof(ppp_settings.passwd), "%.*v", passwdlen, apasswd); + slprintf(ppp_settings.user, sizeof(ppp_settings.user), "%.*v", userlen, auser); *msg = ""; /* * Check if a plugin wants to handle this. */ if (pap_auth_hook) { - ret = (*pap_auth_hook)(user, passwd, msg, &addrs, &opts); + ret = (*pap_auth_hook)(ppp_settings.user, ppp_settings.passwd, msg, &addrs, &opts); if (ret >= 0) { /* note: set_allowed_addrs() saves opts (but not addrs): don't free it! */ @@ -1434,7 +1441,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) } else { check_access(f, filename); - if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename, 0) < 0) { + if (scan_authfile(f, ppp_settings.user, our_name, secret, &addrs, &opts, filename, 0) < 0) { warn("no PAP secret found for %s", user); } else { /* @@ -1449,7 +1456,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) ret = UPAP_AUTHNAK; } } else if (session_mgmt) { - if (session_check(user, NULL, devnam, NULL) == 0) { + if (session_check(ppp_settings.user, NULL, devnam, NULL) == 0) { warn("Peer %q failed PAP Session verification", user); ret = UPAP_AUTHNAK; } @@ -1546,7 +1553,7 @@ null_login(unit) return ret; } - +#if 0 /* * get_pap_passwd - get a password for authenticating ourselves with * our peer using PAP. Returns 1 on success, 0 if no suitable password @@ -1566,7 +1573,7 @@ get_pap_passwd(passwd) * Check whether a plugin wants to supply this. */ if (pap_passwd_hook) { - ret = (*pap_passwd_hook)(user, passwd); + ret = (*pap_passwd_hook)(ppp_settings,user, ppp_settings.passwd); if (ret >= 0) return ret; } @@ -1587,7 +1594,7 @@ get_pap_passwd(passwd) BZERO(secret, sizeof(secret)); return 1; } - +#endif /* * have_pap_secret - check whether we have a PAP file with any @@ -1734,6 +1741,43 @@ get_secret(unit, client, server, secret, secret_len, am_server) int *secret_len; int am_server; { + int len; + struct wordlist *addrs; + + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(server); + LWIP_UNUSED_ARG(am_server); + + addrs = NULL; + + if(!client || !client[0] || strcmp(client, ppp_settings.user)) { + return 0; + } + + len = (int)strlen(ppp_settings.passwd); + if (len > MAXSECRETLEN) { + error("Secret for %s on %s is too long", client, server); + len = MAXSECRETLEN; + } + + BCOPY(ppp_settings.passwd, secret, len); + *secret_len = len; + + return 1; +#if 0 + // strlcpy(rname, ppp_settings.user, sizeof(rname)); + + +/* + strlcpy(rname, ppp_settings.user, sizeof(rname)); + strlcpy(secret, ppp_settings.passwd, sizeof(secret)); + secret_len = strlen(secret); + + printf("CHAP USER = %s\n", ppp_settings.user); + printf("CHAP PASS = %s\n", ppp_settings.passwd); + printf("CHAP PASS LEN = %s\n", strlen(secret)); +*/ + FILE *f; int ret, len; char *filename; @@ -1783,6 +1827,7 @@ get_secret(unit, client, server, secret, secret_len, am_server) *secret_len = len; return 1; +#endif } @@ -1799,6 +1844,9 @@ get_srp_secret(unit, client, server, secret, am_server) char *secret; int am_server; { + /* FIXME: clean that */ + return 0; +#if 0 FILE *fp; int ret; char *filename; @@ -1833,6 +1881,7 @@ get_srp_secret(unit, client, server, secret, am_server) } return 1; +#endif } /* diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index e2fb031b..5fe183f8 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -29,6 +29,7 @@ */ #include "lwip/opt.h" +#include "pppmy.h" #define RCSID "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $" @@ -455,8 +456,14 @@ chap_respond(struct chap_client_state *cs, int id, slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); /* Microsoft doesn't send their name back in the PPP packet */ - if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) - strlcpy(rname, remote_name, sizeof(rname)); + if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rname[0] == 0)) { + strncpy(rname, ppp_settings.remote_name, sizeof(rname)); + rname[sizeof(rname) - 1] = 0; + } + +// /* Microsoft doesn't send their name back in the PPP packet */ +// if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) +// strlcpy(rname, remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { From 2a44bad2e7d7da5e897751175099462eda025b88 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 19:29:54 +0200 Subject: [PATCH 010/320] removed passwd_from_file usage, removed some of unused PAP file fetch code --- src/netif/ppp/auth.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 34495f43..c52f353c 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -157,9 +157,6 @@ 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; @@ -796,16 +793,6 @@ link_established(unit) chap_auth_with_peer(unit, ppp_settings.user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else if (ho->neg_upap) { -#if 0 - /* If a blank password was explicitly given as an option, trust - the user and don't try to look up one. */ - if (passwd[0] == 0 && !explicit_passwd) { - passwd_from_file = 1; - if (!get_pap_passwd(passwd)) - error("No secret found for PAP login"); - } - upap_authwithpeer(unit, user, passwd); -#endif upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); auth |= PAP_WITHPEER; } @@ -1007,8 +994,6 @@ void auth_withpeer_fail(unit, protocol) int unit, protocol; { - if (passwd_from_file) - BZERO(ppp_settings.passwd, MAXSECRETLEN); /* * We've failed to authenticate ourselves to our peer. * Some servers keep sending CHAP challenges, but there @@ -1048,8 +1033,6 @@ auth_withpeer_success(unit, protocol, prot_flavor) } break; case PPP_PAP: - if (passwd_from_file) - BZERO(passwd, MAXSECRETLEN); bit = PAP_WITHPEER; prot = "PAP"; break; From 372a0f9eeaf216d88e6f2b21e36b009e5ef303dd Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 19:41:34 +0200 Subject: [PATCH 011/320] moved refuse_mschap, refuse_mschap_v2, refuse_eap from globals to ppp_settings --- src/netif/ppp/auth.c | 26 +++++++++++++++++--------- src/netif/ppp/pppmy.h | 3 +++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index c52f353c..82ee1550 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -223,13 +223,13 @@ bool session_mgmt = 0; /* Do session management (login records) */ 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 refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ +//bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ #ifdef CHAPMS -bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ -bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +//bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ +//bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #else -bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ -bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +//bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ +//bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #endif bool usehostname = 0; /* Use hostname for our_name */ bool auth_required = 0; /* Always require authentication from peer */ @@ -330,6 +330,7 @@ option_t auth_options[] = { &lcp_allowoptions[0].chap_mdtype }, #endif #ifdef CHAPMS +#if 0 { "refuse-mschap", o_bool, &refuse_mschap, "Don't agree to auth to peer with MS-CHAP", OPT_A2CLRB | MDTYPE_MICROSOFT, @@ -346,14 +347,16 @@ option_t auth_options[] = { "Don't allow MS-CHAPv2 authentication with peer", OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, &lcp_allowoptions[0].chap_mdtype }, +#endif #endif { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, "Require EAP authentication from peer", OPT_PRIOSUB | 1, &auth_required }, +#if 0 { "refuse-eap", o_bool, &refuse_eap, "Don't agree to authenticate to peer with EAP", 1 }, - +#endif { "name", o_string, our_name, "Set local name for authentication", OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, @@ -1319,12 +1322,15 @@ auth_reset(unit) lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; int hadchap; - hadchap = -1; + //ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); + ao->neg_upap = !ppp_settings.refuse_pap && ppp_settings.passwd[0] != 0; - ao->neg_chap = (!ppp_settings.refuse_chap || !refuse_mschap || !refuse_mschap_v2) && ppp_settings.passwd[0]; + ao->neg_chap = (!ppp_settings.refuse_chap || !ppp_settings.refuse_mschap || !ppp_settings.refuse_mschap_v2) && ppp_settings.passwd[0]; + + ao->neg_eap = !ppp_settings.refuse_eap && ppp_settings.passwd[0] != 0; return; @@ -1333,12 +1339,14 @@ auth_reset(unit) && (passwd[0] != 0 || (hadchap = have_chap_secret(user, (explicit_remote? remote_name: NULL), 0, NULL))); */ + /* ao->neg_eap = !refuse_eap && ( passwd[0] != 0 || (hadchap == 1 || (hadchap == -1 && have_chap_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL))) || - have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); + have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); */ + /* FIXME: find what the below stuff do */ hadchap = -1; if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) go->neg_upap = 0; diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 8246fbd0..632521f4 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -45,6 +45,9 @@ struct ppp_settings { u_int explicit_remote : 1; /* remote_name specified with remotename opt */ u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ + u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ + u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ + u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ u_int usehostname : 1; /* Use hostname for our_name */ u_int usepeerdns : 1; /* Ask peer for DNS adds */ From 0f3e70b679b5303a164355c5d740e22708f5e257 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 20:05:37 +0200 Subject: [PATCH 012/320] removed user and passwd globals --- src/netif/ppp/auth.c | 20 +++++++++++--------- src/netif/ppp/options.c | 4 ++-- src/netif/ppp/pppd.h | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 82ee1550..79295c22 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -365,6 +365,7 @@ option_t auth_options[] = { "Get PAP user and password from file", OPT_PRIO | OPT_A2STRVAL, &uafname }, +#if 0 { "user", o_string, user, "Set name for auth with peer", OPT_PRIO | OPT_STATIC, &explicit_user, MAXNAMELEN }, @@ -373,6 +374,7 @@ option_t auth_options[] = { "Password for authenticating us to the peer", OPT_PRIO | OPT_STATIC | OPT_HIDE, &explicit_passwd, MAXSECRETLEN }, +#endif { "usehostname", o_bool, &usehostname, "Must use hostname for authentication", 1 }, @@ -1414,7 +1416,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) free_wordlist(opts); if (addrs != 0) free_wordlist(addrs); - BZERO(passwd, sizeof(passwd)); + BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); return ret? UPAP_AUTHACK: UPAP_AUTHNAK; } } @@ -1443,7 +1445,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) ret = UPAP_AUTHACK; if (uselogin || login_secret) { /* login option or secret is @login */ - if (session_full(user, passwd, devnam, msg) == 0) { + if (session_full(ppp_settings.user, ppp_settings.passwd, devnam, msg) == 0) { ret = UPAP_AUTHNAK; } } else if (session_mgmt) { @@ -1454,8 +1456,8 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) } if (secret[0] != 0 && !login_secret) { /* password given in pap-secrets - must match */ - if ((cryptpap || strcmp(passwd, secret) != 0) - && strcmp(crypt(passwd, secret), secret) != 0) + if ((cryptpap || strcmp(ppp_settings.passwd, secret) != 0) + && strcmp(crypt(ppp_settings.passwd, secret), secret) != 0) ret = UPAP_AUTHNAK; } } @@ -1489,7 +1491,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) if (addrs != NULL) free_wordlist(addrs); - BZERO(passwd, sizeof(passwd)); + BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); BZERO(secret, sizeof(secret)); return ret; @@ -1775,8 +1777,8 @@ get_secret(unit, client, server, secret, secret_len, am_server) struct wordlist *addrs, *opts; char secbuf[MAXWORDLEN]; - if (!am_server && passwd[0] != 0) { - strlcpy(secbuf, passwd, sizeof(secbuf)); + if (!am_server && ppp_settings.passwd[0] != 0) { + strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf)); } else if (!am_server && chap_passwd_hook) { if ( (*chap_passwd_hook)(client, secbuf) < 0) { error("Unable to obtain CHAP password for %s on %s from plugin", @@ -1843,8 +1845,8 @@ get_srp_secret(unit, client, server, secret, am_server) char *filename; struct wordlist *addrs, *opts; - if (!am_server && passwd[0] != '\0') { - strlcpy(secret, passwd, MAXWORDLEN); + if (!am_server && ppp_settings.passwd[0] != '\0') { + strlcpy(secret, ppp_settings.passwd, MAXWORDLEN); } else { filename = _PATH_SRPFILE; addrs = NULL; diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 65da3e36..f4c913d5 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -99,8 +99,8 @@ char devnam[MAXPATHLEN]; /* Device name */ bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ int maxconnect = 0; /* Maximum connect time */ -char user[MAXNAMELEN]; /* Username for PAP */ -char passwd[MAXSECRETLEN]; /* Password for PAP */ +//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 */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 7238da36..eaf954f6 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -288,8 +288,8 @@ 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 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 */ From 4885b39121156c07c95125bc24b0de835668af61 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 20:17:31 +0200 Subject: [PATCH 013/320] removed run_program() support --- src/netif/ppp/auth.c | 87 ------------------------------- src/netif/ppp/ipcp.c | 107 +------------------------------------- src/netif/ppp/pathnames.h | 2 - src/netif/ppp/ppp.c | 85 ------------------------------ src/netif/ppp/pppd.h | 3 -- 5 files changed, 1 insertion(+), 283 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 79295c22..45801642 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -202,19 +202,6 @@ struct notifier *auth_up_notifier = NULL; /* A notifier for when the link goes down. */ struct notifier *link_down_notifier = 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; -static pid_t auth_script_pid = 0; - /* * Option variables. */ @@ -259,8 +246,6 @@ static int scan_authfile __P((FILE *, char *, char *, char *, struct wordlist **, struct wordlist **, char *, int)); static void free_wordlist __P((struct wordlist *)); -static void auth_script __P((char *)); -static void auth_script_done __P((void *)); static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *)); static int some_ip_ok __P((struct wordlist *)); static int setupapfile __P((char **)); @@ -696,15 +681,6 @@ void link_down(unit) int unit; { - if (auth_state != s_down) { - notify(link_down_notifier, 0); - auth_state = s_down; - if (auth_script_state == s_up && auth_script_pid == 0) { - update_link_stats(unit); - auth_script_state = s_down; - auth_script(_PATH_AUTHDOWN); - } - } if (!doing_multilink) { upper_layers_down(unit); if (phase != PHASE_DEAD && phase != PHASE_MASTER) @@ -826,11 +802,6 @@ network_phase(unit) */ if (go->neg_chap || go->neg_upap || go->neg_eap) { notify(auth_up_notifier, 0); - auth_state = s_up; - if (auth_script_state == s_down && auth_script_pid == 0) { - auth_script_state = s_up; - auth_script(_PATH_AUTHUP); - } } #if CBCP_SUPPORT @@ -2356,61 +2327,3 @@ free_wordlist(wp) wp = next; } } - -/* - * auth_script_done - called when the auth-up or auth-down script - * has finished. - */ -static void -auth_script_done(arg) - void *arg; -{ - auth_script_pid = 0; - switch (auth_script_state) { - case s_up: - if (auth_state == s_down) { - auth_script_state = s_down; - auth_script(_PATH_AUTHDOWN); - } - break; - case s_down: - if (auth_state == s_up) { - auth_script_state = s_up; - auth_script(_PATH_AUTHUP); - } - break; - } -} - -/* - * auth_script - execute a script with arguments - * interface-name peer-name real-user tty speed - */ -static void -auth_script(script) - char *script; -{ - char strspeed[32]; - struct passwd *pw; - char struid[32]; - char *user_name; - char *argv[8]; - - if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) - user_name = pw->pw_name; - else { - slprintf(struid, sizeof(struid), "%d", getuid()); - user_name = struid; - } - slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); - - argv[0] = script; - argv[1] = ifname; - argv[2] = peer_authname; - argv[3] = user_name; - argv[4] = devnam; - argv[5] = strspeed; - argv[6] = NULL; - - auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0); -} diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index c29d5253..085c870c 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -282,8 +282,6 @@ struct protent ipcp_protent = { }; static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool)); -static void ipcp_script __P((char *, int)); /* Run an up/down script */ -static void ipcp_script_done __P((void *)); /* * Lengths of configuration options. @@ -298,16 +296,6 @@ static void ipcp_script_done __P((void *)); #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") -/* - * This state variable is used to ensure that we don't - * run an ipcp-up/down script while one is already running. - */ -static enum script_state { - s_down, - s_up, -} ipcp_script_state; -static pid_t ipcp_script_pid; - /* * Make a string representation of a network IP address. */ @@ -1746,7 +1734,6 @@ ip_demand_conf(u) } if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) return 0; - ipcp_script(_PATH_IPPREUP, 1); if (!sifup(u)) return 0; if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) @@ -1898,9 +1885,6 @@ ipcp_up(f) } #endif - /* run the pre-up script, if any, and wait for it to finish */ - ipcp_script(_PATH_IPPREUP, 1); - /* bring the interface up for IP */ if (!sifup(f->unit)) { if (debug) @@ -1949,15 +1933,6 @@ ipcp_up(f) notify(ip_up_notifier, 0); if (ip_up_hook) ip_up_hook(); - - /* - * Execute the ip-up script, like this: - * /etc/ppp/ip-up interface tty speed local-IP remote-IP - */ - if (ipcp_script_state == s_down && ipcp_script_pid == 0) { - ipcp_script_state = s_up; - ipcp_script(_PATH_IPUP, 0); - } } @@ -2002,12 +1977,6 @@ ipcp_down(f) ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, ipcp_hisoptions[f->unit].hisaddr, 0); } - - /* Execute the ip-down script */ - if (ipcp_script_state == s_up && ipcp_script_pid == 0) { - ipcp_script_state = s_down; - ipcp_script(_PATH_IPDOWN, 0); - } } @@ -2056,63 +2025,6 @@ ipcp_finished(f) } -/* - * ipcp_script_done - called when the ip-up or ip-down script - * has finished. - */ -static void -ipcp_script_done(arg) - void *arg; -{ - ipcp_script_pid = 0; - switch (ipcp_script_state) { - case s_up: - if (ipcp_fsm[0].state != OPENED) { - ipcp_script_state = s_down; - ipcp_script(_PATH_IPDOWN, 0); - } - break; - case s_down: - if (ipcp_fsm[0].state == OPENED) { - ipcp_script_state = s_up; - ipcp_script(_PATH_IPUP, 0); - } - break; - } -} - - -/* - * ipcp_script - Execute a script with arguments - * interface-name tty-name speed local-IP remote-IP. - */ -static void -ipcp_script(script, wait) - char *script; - int wait; -{ - char strspeed[32], strlocal[32], strremote[32]; - char *argv[8]; - - slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); - slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr); - slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr); - - argv[0] = script; - argv[1] = ifname; - argv[2] = devnam; - argv[3] = strspeed; - argv[4] = strlocal; - argv[5] = strremote; - argv[6] = ipparam; - argv[7] = NULL; - if (wait) - run_program(script, argv, 0, NULL, NULL, 1); - else - ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done, - NULL, 0); -} - /* * create_resolv - create the replacement resolv.conf file */ @@ -2120,24 +2032,7 @@ static void create_resolv(peerdns1, peerdns2) u_int32_t peerdns1, peerdns2; { - FILE *f; - - f = fopen(_PATH_RESOLV, "w"); - if (f == NULL) { - error("Failed to create %s: %m", _PATH_RESOLV); - return; - } - - if (peerdns1) - fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1)); - - if (peerdns2) - fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2)); - - if (ferror(f)) - error("Write failed to %s: %m", _PATH_RESOLV); - - fclose(f); + /* FIXME: do we need to set here the DNS servers ? */ } /* diff --git a/src/netif/ppp/pathnames.h b/src/netif/ppp/pathnames.h index a33f0466..bc81a8ce 100644 --- a/src/netif/ppp/pathnames.h +++ b/src/netif/ppp/pathnames.h @@ -25,8 +25,6 @@ #define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up" #define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down" #define _PATH_IPPREUP _ROOT_PATH "/etc/ppp/ip-pre-up" -#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/" diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index d03f83f0..b78cdc85 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1679,91 +1679,6 @@ device_script(program, in, out, dont_wait) } -/* - * run_program - execute a program with given arguments, - * but don't wait for it unless wait is non-zero. - * If the program can't be executed, logs an error unless - * must_exist is 0 and the program file doesn't exist. - * Returns -1 if it couldn't fork, 0 if the file doesn't exist - * or isn't an executable plain file, or the process ID of the child. - * If done != NULL, (*done)(arg) will be called later (within - * reap_kids) iff the return value is > 0. - */ -pid_t -run_program(prog, args, must_exist, done, arg, wait) - char *prog; - char **args; - int must_exist; - void (*done) __P((void *)); - void *arg; - int wait; -{ - int pid, status; - struct stat sbuf; - - printf("REMOVEME: run_program() called\n"); - return -1; - - /* - * First check if the file exists and is executable. - * We don't use access() because that would use the - * real user-id, which might not be root, and the script - * might be accessible only to root. - */ - errno = EINVAL; - if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode) - || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { - if (must_exist || errno != ENOENT) - warn("Can't execute %s: %m", prog); - return 0; - } - - pid = safe_fork(fd_devnull, fd_devnull, fd_devnull); - if (pid == -1) { - error("Failed to create child process for %s: %m", prog); - return -1; - } - if (pid != 0) { - if (debug) - dbglog("Script %s started (pid %d)", prog, pid); - record_child(pid, prog, done, arg, 0); - if (wait) { - while (waitpid(pid, &status, 0) < 0) { - if (errno == EINTR) - continue; - fatal("error waiting for script %s: %m", prog); - } - forget_child(pid, status); - } - return pid; - } - - /* Leave the current location */ - (void) setsid(); /* No controlling tty. */ - (void) umask (S_IRWXG|S_IRWXO); - (void) chdir ("/"); /* no current directory. */ - setuid(0); /* set real UID = root */ - setgid(getegid()); - -#ifdef BSD - /* Force the priority back to zero if pppd is running higher. */ - if (setpriority (PRIO_PROCESS, 0, 0) < 0) - warn("can't reset priority to 0: %m"); -#endif - - /* run the program */ - execve(prog, args, script_env); - if (must_exist || errno != ENOENT) { - /* have to reopen the log, there's nowhere else - for the message to go. */ - reopen_log(); - syslog(LOG_ERR, "Can't execute %s: %m", prog); - closelog(); - } - _exit(-1); -} - - /* * record_child - add a child process to the list for reap_kids * to use. diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index eaf954f6..da228b35 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -478,9 +478,6 @@ void record_child __P((int, char *, void (*) (void *), void *, int)); pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ int device_script __P((char *cmd, int in, int out, int dont_wait)); /* Run `cmd' with given stdin and stdout */ -pid_t run_program __P((char *prog, char **args, int must_exist, - void (*done)(void *), void *arg, int wait)); - /* Run program prog with args in child */ void reopen_log __P((void)); /* (re)open the connection to syslog */ void print_link_stats __P((void)); /* Print stats, if available */ void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */ From 00648c27eb5e7f3006e6801e539140310954b4e8 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 20:22:17 +0200 Subject: [PATCH 014/320] world changed, removed IPX support --- src/netif/ppp/ipxcp.c | 1600 ------------------------------------- src/netif/ppp/ipxcp.h | 94 --- src/netif/ppp/ppp.c | 6 - src/netif/ppp/sys-linux.c | 118 --- 4 files changed, 1818 deletions(-) delete mode 100644 src/netif/ppp/ipxcp.c delete mode 100644 src/netif/ppp/ipxcp.h diff --git a/src/netif/ppp/ipxcp.c b/src/netif/ppp/ipxcp.c deleted file mode 100644 index 8c8ba69a..00000000 --- a/src/netif/ppp/ipxcp.c +++ /dev/null @@ -1,1600 +0,0 @@ -/* - * ipxcp.c - PPP IPX Control Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "lwip/opt.h" - -#ifdef IPX_CHANGE - -#define RCSID "$Id: ipxcp.c,v 1.24 2005/08/25 23:59:34 paulus Exp $" - -/* - * TODO: - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "fsm.h" -#include "ipxcp.h" -#include "pathnames.h" -#include "magic.h" - -static const char rcsid[] = RCSID; - -/* global vars */ -ipxcp_options ipxcp_wantoptions[NUM_PPP]; /* Options that we want to request */ -ipxcp_options ipxcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -ipxcp_options ipxcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -ipxcp_options ipxcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ - -#define wo (&ipxcp_wantoptions[0]) -#define ao (&ipxcp_allowoptions[0]) -#define go (&ipxcp_gotoptions[0]) -#define ho (&ipxcp_hisoptions[0]) - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipxcp_resetci __P((fsm *)); /* Reset our CI */ -static int ipxcp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipxcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipxcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ -static int ipxcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipxcp_up __P((fsm *)); /* We're UP */ -static void ipxcp_down __P((fsm *)); /* We're DOWN */ -static void ipxcp_finished __P((fsm *)); /* Don't need lower layer */ -static void ipxcp_script __P((fsm *, char *)); /* Run an up/down script */ - -fsm ipxcp_fsm[NUM_PPP]; /* IPXCP fsm structure */ - -static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */ - ipxcp_resetci, /* Reset our Configuration Information */ - ipxcp_cilen, /* Length of our Configuration Information */ - ipxcp_addci, /* Add our Configuration Information */ - ipxcp_ackci, /* ACK our Configuration Information */ - ipxcp_nakci, /* NAK our Configuration Information */ - ipxcp_rejci, /* Reject our Configuration Information */ - ipxcp_reqci, /* Request peer's Configuration Information */ - ipxcp_up, /* Called when fsm reaches OPENED state */ - ipxcp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipxcp_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 */ - "IPXCP" /* String name of protocol */ -}; - -/* - * Command-line options. - */ -static int setipxnode __P((char **)); -static void printipxnode __P((option_t *, - void (*)(void *, char *, ...), void *)); -static int setipxname __P((char **)); - -static option_t ipxcp_option_list[] = { - { "ipx", o_bool, &ipxcp_protent.enabled_flag, - "Enable IPXCP (and IPX)", OPT_PRIO | 1 }, - { "+ipx", o_bool, &ipxcp_protent.enabled_flag, - "Enable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS | 1 }, - { "noipx", o_bool, &ipxcp_protent.enabled_flag, - "Disable IPXCP (and IPX)", OPT_PRIOSUB }, - { "-ipx", o_bool, &ipxcp_protent.enabled_flag, - "Disable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS }, - - { "ipx-network", o_uint32, &ipxcp_wantoptions[0].our_network, - "Set our IPX network number", OPT_PRIO, &ipxcp_wantoptions[0].neg_nn }, - - { "ipxcp-accept-network", o_bool, &ipxcp_wantoptions[0].accept_network, - "Accept peer IPX network number", 1, - &ipxcp_allowoptions[0].accept_network }, - - { "ipx-node", o_special, (void *)setipxnode, - "Set IPX node number", OPT_A2PRINTER, (void *)printipxnode }, - - { "ipxcp-accept-local", o_bool, &ipxcp_wantoptions[0].accept_local, - "Accept our IPX address", 1, - &ipxcp_allowoptions[0].accept_local }, - - { "ipxcp-accept-remote", o_bool, &ipxcp_wantoptions[0].accept_remote, - "Accept peer's IPX address", 1, - &ipxcp_allowoptions[0].accept_remote }, - - { "ipx-routing", o_int, &ipxcp_wantoptions[0].router, - "Set IPX routing proto number", OPT_PRIO, - &ipxcp_wantoptions[0].neg_router }, - - { "ipx-router-name", o_special, setipxname, - "Set IPX router name", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, - &ipxcp_wantoptions[0].name }, - - { "ipxcp-restart", o_int, &ipxcp_fsm[0].timeouttime, - "Set timeout for IPXCP", OPT_PRIO }, - { "ipxcp-max-terminate", o_int, &ipxcp_fsm[0].maxtermtransmits, - "Set max #xmits for IPXCP term-reqs", OPT_PRIO }, - { "ipxcp-max-configure", o_int, &ipxcp_fsm[0].maxconfreqtransmits, - "Set max #xmits for IPXCP conf-reqs", OPT_PRIO }, - { "ipxcp-max-failure", o_int, &ipxcp_fsm[0].maxnakloops, - "Set max #conf-naks for IPXCP", OPT_PRIO }, - - { NULL } -}; - -/* - * Protocol entry points. - */ - -static void ipxcp_init __P((int)); -static void ipxcp_open __P((int)); -static void ipxcp_close __P((int, char *)); -static void ipxcp_lowerup __P((int)); -static void ipxcp_lowerdown __P((int)); -static void ipxcp_input __P((int, u_char *, int)); -static void ipxcp_protrej __P((int)); -static int ipxcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); - -struct protent ipxcp_protent = { - PPP_IPXCP, - ipxcp_init, - ipxcp_input, - ipxcp_protrej, - ipxcp_lowerup, - ipxcp_lowerdown, - ipxcp_open, - ipxcp_close, - ipxcp_printpkt, - NULL, - 0, - "IPXCP", - "IPX", - ipxcp_option_list, - NULL, - NULL, - NULL -}; - -/* - * Lengths of configuration options. - */ - -#define CILEN_VOID 2 -#define CILEN_COMPLETE 2 /* length of complete option */ -#define CILEN_NETN 6 /* network number length option */ -#define CILEN_NODEN 8 /* node number length option */ -#define CILEN_PROTOCOL 4 /* Minimum length of routing protocol */ -#define CILEN_NAME 3 /* Minimum length of router name */ -#define CILEN_COMPRESS 4 /* Minimum length of compression protocol */ - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -static int ipxcp_is_up; - -static char *ipx_ntoa __P((u_int32_t)); - -/* Used in printing the node number */ -#define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5] - -/* Used to generate the proper bit mask */ -#define BIT(num) (1 << (num)) - -/* - * Convert from internal to external notation - */ - -static short int -to_external(internal) -short int internal; -{ - short int external; - - if (internal & BIT(IPX_NONE) ) - external = IPX_NONE; - else - external = RIP_SAP; - - return external; -} - -/* - * Make a string representation of a network IP address. - */ - -static char * -ipx_ntoa(ipxaddr) -u_int32_t ipxaddr; -{ - static char b[64]; - slprintf(b, sizeof(b), "%x", ipxaddr); - return b; -} - - -static u_char * -setipxnodevalue(src,dst) -u_char *src, *dst; -{ - int indx; - int item; - - for (;;) { - if (!isxdigit (*src)) - break; - - for (indx = 0; indx < 5; ++indx) { - dst[indx] <<= 4; - dst[indx] |= (dst[indx + 1] >> 4) & 0x0F; - } - - item = toupper (*src) - '0'; - if (item > 9) - item -= 7; - - dst[5] = (dst[5] << 4) | item; - ++src; - } - return src; -} - -static int ipx_prio_our, ipx_prio_his; - -static int -setipxnode(argv) - char **argv; -{ - u_char *end; - int have_his = 0; - u_char our_node[6]; - u_char his_node[6]; - - memset (our_node, 0, 6); - memset (his_node, 0, 6); - - end = setipxnodevalue (*argv, our_node); - if (*end == ':') { - have_his = 1; - end = setipxnodevalue (++end, his_node); - } - - if (*end == '\0') { - ipxcp_wantoptions[0].neg_node = 1; - if (option_priority >= ipx_prio_our) { - memcpy(&ipxcp_wantoptions[0].our_node[0], our_node, 6); - ipx_prio_our = option_priority; - } - if (have_his && option_priority >= ipx_prio_his) { - memcpy(&ipxcp_wantoptions[0].his_node[0], his_node, 6); - ipx_prio_his = option_priority; - } - return 1; - } - - option_error("invalid parameter '%s' for ipx-node option", *argv); - return 0; -} - -static void -printipxnode(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - unsigned char *p; - - p = ipxcp_wantoptions[0].our_node; - if (ipx_prio_our) - printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x", - p[0], p[1], p[2], p[3], p[4], p[5]); - printer(arg, ":"); - p = ipxcp_wantoptions[0].his_node; - if (ipx_prio_his) - printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x", - p[0], p[1], p[2], p[3], p[4], p[5]); -} - -static int -setipxname (argv) - char **argv; -{ - u_char *dest = ipxcp_wantoptions[0].name; - char *src = *argv; - int count; - char ch; - - ipxcp_wantoptions[0].neg_name = 1; - ipxcp_allowoptions[0].neg_name = 1; - memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name)); - - count = 0; - while (*src) { - ch = *src++; - if (! isalnum (ch) && ch != '_') { - option_error("IPX router name must be alphanumeric or _"); - return 0; - } - - if (count >= sizeof (ipxcp_wantoptions[0].name) - 1) { - option_error("IPX router name is limited to %d characters", - sizeof (ipxcp_wantoptions[0].name) - 1); - return 0; - } - - dest[count++] = toupper (ch); - } - dest[count] = 0; - - return 1; -} - -/* - * ipxcp_init - Initialize IPXCP. - */ -static void -ipxcp_init(unit) - int unit; -{ - fsm *f = &ipxcp_fsm[unit]; - - f->unit = unit; - f->protocol = PPP_IPXCP; - f->callbacks = &ipxcp_callbacks; - fsm_init(&ipxcp_fsm[unit]); - - memset (wo->name, 0, sizeof (wo->name)); - memset (wo->our_node, 0, sizeof (wo->our_node)); - memset (wo->his_node, 0, sizeof (wo->his_node)); - - wo->neg_nn = 1; - wo->neg_complete = 1; - wo->network = 0; - - ao->neg_node = 1; - ao->neg_nn = 1; - ao->neg_name = 1; - ao->neg_complete = 1; - ao->neg_router = 1; - - ao->accept_local = 0; - ao->accept_remote = 0; - ao->accept_network = 0; - - wo->tried_rip = 0; - wo->tried_nlsp = 0; -} - -/* - * Copy the node number - */ - -static void -copy_node (src, dst) -u_char *src, *dst; -{ - memcpy (dst, src, sizeof (ipxcp_wantoptions[0].our_node)); -} - -/* - * Compare node numbers - */ - -static int -compare_node (src, dst) -u_char *src, *dst; -{ - return memcmp (dst, src, sizeof (ipxcp_wantoptions[0].our_node)) == 0; -} - -/* - * Is the node number zero? - */ - -static int -zero_node (node) -u_char *node; -{ - int indx; - for (indx = 0; indx < sizeof (ipxcp_wantoptions[0].our_node); ++indx) - if (node [indx] != 0) - return 0; - return 1; -} - -/* - * Increment the node number - */ - -static void -inc_node (node) -u_char *node; -{ - u_char *outp; - u_int32_t magic_num; - - outp = node; - magic_num = magic(); - *outp++ = '\0'; - *outp++ = '\0'; - PUTLONG (magic_num, outp); -} - -/* - * ipxcp_open - IPXCP is allowed to come up. - */ -static void -ipxcp_open(unit) - int unit; -{ - fsm_open(&ipxcp_fsm[unit]); -} - -/* - * ipxcp_close - Take IPXCP down. - */ -static void -ipxcp_close(unit, reason) - int unit; - char *reason; -{ - fsm_close(&ipxcp_fsm[unit], reason); -} - - -/* - * ipxcp_lowerup - The lower layer is up. - */ -static void -ipxcp_lowerup(unit) - int unit; -{ - fsm_lowerup(&ipxcp_fsm[unit]); -} - - -/* - * ipxcp_lowerdown - The lower layer is down. - */ -static void -ipxcp_lowerdown(unit) - int unit; -{ - fsm_lowerdown(&ipxcp_fsm[unit]); -} - - -/* - * ipxcp_input - Input IPXCP packet. - */ -static void -ipxcp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm_input(&ipxcp_fsm[unit], p, len); -} - - -/* - * ipxcp_protrej - A Protocol-Reject was received for IPXCP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void -ipxcp_protrej(unit) - int unit; -{ - fsm_lowerdown(&ipxcp_fsm[unit]); -} - - -/* - * ipxcp_resetci - Reset our CI. - */ -static void -ipxcp_resetci(f) - fsm *f; -{ - wo->req_node = wo->neg_node && ao->neg_node; - wo->req_nn = wo->neg_nn && ao->neg_nn; - - if (wo->our_network == 0) { - wo->neg_node = 1; - ao->accept_network = 1; - } -/* - * If our node number is zero then change it. - */ - if (zero_node (wo->our_node)) { - inc_node (wo->our_node); - ao->accept_local = 1; - wo->neg_node = 1; - } -/* - * If his node number is zero then change it. - */ - if (zero_node (wo->his_node)) { - inc_node (wo->his_node); - ao->accept_remote = 1; - } -/* - * If no routing agent was specified then we do RIP/SAP according to the - * RFC documents. If you have specified something then OK. Otherwise, we - * do RIP/SAP. - */ - if (ao->router == 0) { - ao->router |= BIT(RIP_SAP); - wo->router |= BIT(RIP_SAP); - } - - /* Always specify a routing protocol unless it was REJected. */ - wo->neg_router = 1; -/* - * Start with these default values - */ - *go = *wo; -} - -/* - * ipxcp_cilen - Return length of our CI. - */ - -static int -ipxcp_cilen(f) - fsm *f; -{ - int len; - - len = go->neg_nn ? CILEN_NETN : 0; - len += go->neg_node ? CILEN_NODEN : 0; - len += go->neg_name ? CILEN_NAME + strlen ((char *)go->name) - 1 : 0; - - /* RFC says that defaults should not be included. */ - if (go->neg_router && to_external(go->router) != RIP_SAP) - len += CILEN_PROTOCOL; - - return (len); -} - - -/* - * ipxcp_addci - Add our desired CIs to a packet. - */ -static void -ipxcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; -{ -/* - * Add the options to the record. - */ - if (go->neg_nn) { - PUTCHAR (IPX_NETWORK_NUMBER, ucp); - PUTCHAR (CILEN_NETN, ucp); - PUTLONG (go->our_network, ucp); - } - - if (go->neg_node) { - int indx; - PUTCHAR (IPX_NODE_NUMBER, ucp); - PUTCHAR (CILEN_NODEN, ucp); - for (indx = 0; indx < sizeof (go->our_node); ++indx) - PUTCHAR (go->our_node[indx], ucp); - } - - if (go->neg_name) { - int cilen = strlen ((char *)go->name); - int indx; - PUTCHAR (IPX_ROUTER_NAME, ucp); - PUTCHAR (CILEN_NAME + cilen - 1, ucp); - for (indx = 0; indx < cilen; ++indx) - PUTCHAR (go->name [indx], ucp); - } - - if (go->neg_router) { - short external = to_external (go->router); - if (external != RIP_SAP) { - PUTCHAR (IPX_ROUTER_PROTOCOL, ucp); - PUTCHAR (CILEN_PROTOCOL, ucp); - PUTSHORT (external, ucp); - } - } -} - -/* - * ipxcp_ackci - Ack our CIs. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -ipxcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - u_short cilen, citype, cishort; - u_char cichar; - u_int32_t cilong; - -#define ACKCIVOID(opt, neg) \ - if (neg) { \ - if ((len -= CILEN_VOID) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || \ - citype != opt) \ - break; \ - } - -#define ACKCICOMPLETE(opt,neg) ACKCIVOID(opt, neg) - -#define ACKCICHARS(opt, neg, val, cnt) \ - if (neg) { \ - int indx, count = cnt; \ - len -= (count + 2); \ - if (len < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != (count + 2) || \ - citype != opt) \ - break; \ - for (indx = 0; indx < count; ++indx) {\ - GETCHAR(cichar, p); \ - if (cichar != ((u_char *) &val)[indx]) \ - break; \ - }\ - if (indx != count) \ - break; \ - } - -#define ACKCINODE(opt,neg,val) ACKCICHARS(opt,neg,val,sizeof(val)) -#define ACKCINAME(opt,neg,val) ACKCICHARS(opt,neg,val,strlen((char *)val)) - -#define ACKCINETWORK(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_NETN) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_NETN || \ - citype != opt) \ - break; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - break; \ - } - -#define ACKCIPROTO(opt, neg, val) \ - if (neg) { \ - if (len < 2) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_PROTOCOL || citype != opt) \ - break; \ - len -= cilen; \ - if (len < 0) \ - break; \ - GETSHORT(cishort, p); \ - if (cishort != to_external (val) || cishort == RIP_SAP) \ - break; \ - } -/* - * Process the ACK frame in the order in which the frame was assembled - */ - do { - ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network); - ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node); - ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name); - if (len > 0) - ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); -/* - * This is the end of the record. - */ - if (len == 0) - return (1); - } while (0); -/* - * The frame is invalid - */ - IPXCPDEBUG(("ipxcp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipxcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPXCP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ - -static int -ipxcp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; -{ - u_char citype, cilen, *next; - u_short s; - u_int32_t l; - ipxcp_options no; /* options we've seen Naks for */ - ipxcp_options try; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try = *go; - - while (len >= CILEN_VOID) { - GETCHAR (citype, p); - GETCHAR (cilen, p); - len -= cilen; - if (cilen < CILEN_VOID || len < 0) - goto bad; - next = &p [cilen - CILEN_VOID]; - - switch (citype) { - case IPX_NETWORK_NUMBER: - if (!go->neg_nn || no.neg_nn || (cilen != CILEN_NETN)) - goto bad; - no.neg_nn = 1; - - GETLONG(l, p); - if (treat_as_reject) - try.neg_nn = 0; - else if (l && ao->accept_network) - try.our_network = l; - break; - - case IPX_NODE_NUMBER: - if (!go->neg_node || no.neg_node || (cilen != CILEN_NODEN)) - goto bad; - no.neg_node = 1; - - if (treat_as_reject) - try.neg_node = 0; - else if (!zero_node (p) && ao->accept_local && - ! compare_node (p, ho->his_node)) - copy_node (p, try.our_node); - break; - - /* This has never been sent. Ignore the NAK frame */ - case IPX_COMPRESSION_PROTOCOL: - goto bad; - - case IPX_ROUTER_PROTOCOL: - if (!go->neg_router || (cilen < CILEN_PROTOCOL)) - goto bad; - - GETSHORT (s, p); - if (s > 15) /* This is just bad, but ignore for now. */ - break; - - s = BIT(s); - if (no.router & s) /* duplicate NAKs are always bad */ - goto bad; - - if (no.router == 0) /* Reset on first NAK only */ - try.router = 0; - - no.router |= s; - try.router |= s; - try.neg_router = 1; - break; - - /* These, according to the RFC, must never be NAKed. */ - case IPX_ROUTER_NAME: - case IPX_COMPLETE: - goto bad; - - /* These are for options which we have not seen. */ - default: - break; - } - p = next; - } - - /* - * Do not permit the peer to force a router protocol which we do not - * support. However, default to the condition that will accept "NONE". - */ - try.router &= (ao->router | BIT(IPX_NONE)); - if (try.router == 0 && ao->router != 0) - try.router = BIT(IPX_NONE); - - if (try.router != 0) - try.neg_router = 1; - - /* - * OK, the Nak is good. Now we can update state. - * If there are any options left, we ignore them. - */ - if (f->state != OPENED) - *go = try; - - return 1; - -bad: - IPXCPDEBUG(("ipxcp_nakci: received bad Nak!")); - return 0; -} - -/* - * ipxcp_rejci - Reject some of our CIs. - */ -static int -ipxcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - u_short cilen, citype, cishort; - u_char cichar; - u_int32_t cilong; - ipxcp_options try; /* options to request next time */ - -#define REJCINETWORK(opt, neg, val) \ - if (neg && p[0] == opt) { \ - if ((len -= CILEN_NETN) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_NETN || \ - citype != opt) \ - break; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - break; \ - neg = 0; \ - } - -#define REJCICHARS(opt, neg, val, cnt) \ - if (neg && p[0] == opt) { \ - int indx, count = cnt; \ - len -= (count + 2); \ - if (len < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != (count + 2) || \ - citype != opt) \ - break; \ - for (indx = 0; indx < count; ++indx) {\ - GETCHAR(cichar, p); \ - if (cichar != ((u_char *) &val)[indx]) \ - break; \ - }\ - if (indx != count) \ - break; \ - neg = 0; \ - } - -#define REJCINODE(opt,neg,val) REJCICHARS(opt,neg,val,sizeof(val)) -#define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen((char *)val)) - -#define REJCIVOID(opt, neg) \ - if (neg && p[0] == opt) { \ - if ((len -= CILEN_VOID) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || citype != opt) \ - break; \ - neg = 0; \ - } - -/* a reject for RIP/SAP is invalid since we don't send it and you can't - reject something which is not sent. (You can NAK, but you can't REJ.) */ -#define REJCIPROTO(opt, neg, val, bit) \ - if (neg && p[0] == opt) { \ - if ((len -= CILEN_PROTOCOL) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_PROTOCOL) \ - break; \ - GETSHORT(cishort, p); \ - if (cishort != to_external (val) || cishort == RIP_SAP) \ - break; \ - neg = 0; \ - } -/* - * 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. - */ - try = *go; - - do { - REJCINETWORK (IPX_NETWORK_NUMBER, try.neg_nn, try.our_network); - REJCINODE (IPX_NODE_NUMBER, try.neg_node, try.our_node); - REJCINAME (IPX_ROUTER_NAME, try.neg_name, try.name); - REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 0); -/* - * This is the end of the record. - */ - if (len == 0) { - if (f->state != OPENED) - *go = try; - return (1); - } - } while (0); -/* - * The frame is invalid at this point. - */ - IPXCPDEBUG(("ipxcp_rejci: received bad Reject!")); - return 0; -} - -/* - * ipxcp_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 -ipxcp_reqci(f, inp, len, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *len; /* Length of requested CIs */ - int reject_if_disagree; -{ - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ - u_short cishort; /* Parsed short value */ - u_int32_t cinetwork; /* 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 */ - - /* - * 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? */ - IPXCPDEBUG(("ipxcp_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 */ -/* - * The network number must match. Choose the larger of the two. - */ - case IPX_NETWORK_NUMBER: - /* if we wont negotiate the network number or the length is wrong - then reject the option */ - if ( !ao->neg_nn || cilen != CILEN_NETN ) { - orc = CONFREJ; - break; - } - GETLONG(cinetwork, p); - - /* If the network numbers match then acknowledge them. */ - if (cinetwork != 0) { - ho->his_network = cinetwork; - ho->neg_nn = 1; - if (wo->our_network == cinetwork) - break; -/* - * If the network number is not given or we don't accept their change or - * the network number is too small then NAK it. - */ - if (! ao->accept_network || cinetwork < wo->our_network) { - DECPTR (sizeof (u_int32_t), p); - PUTLONG (wo->our_network, p); - orc = CONFNAK; - } - break; - } -/* - * The peer sent '0' for the network. Give it ours if we have one. - */ - if (go->our_network != 0) { - DECPTR (sizeof (u_int32_t), p); - PUTLONG (wo->our_network, p); - orc = CONFNAK; -/* - * We don't have one. Reject the value. - */ - } else - orc = CONFREJ; - - break; -/* - * The node number is required - */ - case IPX_NODE_NUMBER: - /* if we wont negotiate the node number or the length is wrong - then reject the option */ - if ( cilen != CILEN_NODEN ) { - orc = CONFREJ; - break; - } - - copy_node (p, ho->his_node); - ho->neg_node = 1; -/* - * If the remote does not have a number and we do then NAK it with the value - * which we have for it. (We never have a default value of zero.) - */ - if (zero_node (ho->his_node)) { - orc = CONFNAK; - copy_node (wo->his_node, p); - INCPTR (sizeof (wo->his_node), p); - break; - } -/* - * If you have given me the expected network node number then I'll accept - * it now. - */ - if (compare_node (wo->his_node, ho->his_node)) { - orc = CONFACK; - ho->neg_node = 1; - INCPTR (sizeof (wo->his_node), p); - break; - } -/* - * If his node number is the same as ours then ask him to try the next - * value. - */ - if (compare_node (ho->his_node, go->our_node)) { - inc_node (ho->his_node); - orc = CONFNAK; - copy_node (ho->his_node, p); - INCPTR (sizeof (wo->his_node), p); - break; - } -/* - * If we don't accept a new value then NAK it. - */ - if (! ao->accept_remote) { - copy_node (wo->his_node, p); - INCPTR (sizeof (wo->his_node), p); - orc = CONFNAK; - break; - } - orc = CONFACK; - ho->neg_node = 1; - INCPTR (sizeof (wo->his_node), p); - break; -/* - * Compression is not desired at this time. It is always rejected. - */ - case IPX_COMPRESSION_PROTOCOL: - orc = CONFREJ; - break; -/* - * The routing protocol is a bitmask of various types. Any combination - * of the values RIP_SAP and NLSP are permissible. 'IPX_NONE' for no - * routing protocol must be specified only once. - */ - case IPX_ROUTER_PROTOCOL: - if ( !ao->neg_router || cilen < CILEN_PROTOCOL ) { - orc = CONFREJ; - break; - } - - GETSHORT (cishort, p); - - if (wo->neg_router == 0) { - wo->neg_router = 1; - wo->router = BIT(IPX_NONE); - } - - if ((cishort == IPX_NONE && ho->router != 0) || - (ho->router & BIT(IPX_NONE))) { - orc = CONFREJ; - break; - } - - cishort = BIT(cishort); - if (ho->router & cishort) { - orc = CONFREJ; - break; - } - - ho->router |= cishort; - ho->neg_router = 1; - - /* Finally do not allow a router protocol which we do not - support. */ - - if ((cishort & (ao->router | BIT(IPX_NONE))) == 0) { - int protocol; - - if (cishort == BIT(NLSP) && - (ao->router & BIT(RIP_SAP)) && - !wo->tried_rip) { - protocol = RIP_SAP; - wo->tried_rip = 1; - } else - protocol = IPX_NONE; - - DECPTR (sizeof (u_int16_t), p); - PUTSHORT (protocol, p); - orc = CONFNAK; - } - break; -/* - * The router name is advisorary. Just accept it if it is not too large. - */ - case IPX_ROUTER_NAME: - if (cilen >= CILEN_NAME) { - int name_size = cilen - CILEN_NAME; - if (name_size > sizeof (ho->name)) - name_size = sizeof (ho->name) - 1; - memset (ho->name, 0, sizeof (ho->name)); - memcpy (ho->name, p, name_size); - ho->name [name_size] = '\0'; - ho->neg_name = 1; - orc = CONFACK; - break; - } - orc = CONFREJ; - break; -/* - * This is advisorary. - */ - case IPX_COMPLETE: - if (cilen != CILEN_COMPLETE) - orc = CONFREJ; - else { - ho->neg_complete = 1; - orc = CONFACK; - } - break; -/* - * All other entries are not known at this time. - */ - 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 */ - 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 IPX_NODE_NUMBER option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - - if (rc != CONFREJ && !ho->neg_node && - wo->req_nn && !reject_if_disagree) { - if (rc == CONFACK) { - rc = CONFNAK; - wo->req_nn = 0; /* don't ask again */ - ucp = inp; /* reset pointer */ - } - - if (zero_node (wo->his_node)) - inc_node (wo->his_node); - - PUTCHAR (IPX_NODE_NUMBER, ucp); - PUTCHAR (CILEN_NODEN, ucp); - copy_node (wo->his_node, ucp); - INCPTR (sizeof (wo->his_node), ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPXCPDEBUG(("ipxcp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - -/* - * ipxcp_up - IPXCP has come UP. - * - * Configure the IP network interface appropriately and bring it up. - */ - -static void -ipxcp_up(f) - fsm *f; -{ - int unit = f->unit; - - IPXCPDEBUG(("ipxcp: up")); - - /* The default router protocol is RIP/SAP. */ - if (ho->router == 0) - ho->router = BIT(RIP_SAP); - - if (go->router == 0) - go->router = BIT(RIP_SAP); - - /* Fetch the network number */ - if (!ho->neg_nn) - ho->his_network = wo->his_network; - - if (!ho->neg_node) - copy_node (wo->his_node, ho->his_node); - - if (!wo->neg_node && !go->neg_node) - copy_node (wo->our_node, go->our_node); - - if (zero_node (go->our_node)) { - static char errmsg[] = "Could not determine local IPX node address"; - if (debug) - error(errmsg); - ipxcp_close(f->unit, errmsg); - return; - } - - go->network = go->our_network; - if (ho->his_network != 0 && ho->his_network > go->network) - go->network = ho->his_network; - - if (go->network == 0) { - static char errmsg[] = "Can not determine network number"; - if (debug) - error(errmsg); - ipxcp_close (unit, errmsg); - return; - } - - /* bring the interface up */ - if (!sifup(unit)) { - if (debug) - warn("sifup failed (IPX)"); - ipxcp_close(unit, "Interface configuration failed"); - return; - } - ipxcp_is_up = 1; - - /* set the network number for IPX */ - if (!sipxfaddr(unit, go->network, go->our_node)) { - if (debug) - warn("sipxfaddr failed"); - ipxcp_close(unit, "Interface configuration failed"); - return; - } - - np_up(f->unit, PPP_IPX); - - /* - * Execute the ipx-up script, like this: - * /etc/ppp/ipx-up interface tty speed local-IPX remote-IPX - */ - - ipxcp_script (f, _PATH_IPXUP); -} - -/* - * ipxcp_down - IPXCP has gone DOWN. - * - * Take the IP network interface down, clear its addresses - * and delete routes through it. - */ - -static void -ipxcp_down(f) - fsm *f; -{ - IPXCPDEBUG(("ipxcp: down")); - - if (!ipxcp_is_up) - return; - ipxcp_is_up = 0; - np_down(f->unit, PPP_IPX); - cipxfaddr(f->unit); - sifnpmode(f->unit, PPP_IPX, NPMODE_DROP); - sifdown(f->unit); - ipxcp_script (f, _PATH_IPXDOWN); -} - - -/* - * ipxcp_finished - possibly shut down the lower layers. - */ -static void -ipxcp_finished(f) - fsm *f; -{ - np_finished(f->unit, PPP_IPX); -} - - -/* - * ipxcp_script - Execute a script with arguments - * interface-name tty-name speed local-IPX remote-IPX networks. - */ -static void -ipxcp_script(f, script) - fsm *f; - char *script; -{ - char strspeed[32], strlocal[32], strremote[32]; - char strnetwork[32], strpid[32]; - char *argv[14], strproto_lcl[32], strproto_rmt[32]; - - slprintf(strpid, sizeof(strpid), "%d", getpid()); - slprintf(strspeed, sizeof(strspeed),"%d", baud_rate); - - strproto_lcl[0] = '\0'; - if (go->neg_router && ((go->router & BIT(IPX_NONE)) == 0)) { - if (go->router & BIT(RIP_SAP)) - strlcpy (strproto_lcl, "RIP ", sizeof(strproto_lcl)); - if (go->router & BIT(NLSP)) - strlcat (strproto_lcl, "NLSP ", sizeof(strproto_lcl)); - } - - if (strproto_lcl[0] == '\0') - strlcpy (strproto_lcl, "NONE ", sizeof(strproto_lcl)); - - strproto_lcl[strlen (strproto_lcl)-1] = '\0'; - - strproto_rmt[0] = '\0'; - if (ho->neg_router && ((ho->router & BIT(IPX_NONE)) == 0)) { - if (ho->router & BIT(RIP_SAP)) - strlcpy (strproto_rmt, "RIP ", sizeof(strproto_rmt)); - if (ho->router & BIT(NLSP)) - strlcat (strproto_rmt, "NLSP ", sizeof(strproto_rmt)); - } - - if (strproto_rmt[0] == '\0') - strlcpy (strproto_rmt, "NONE ", sizeof(strproto_rmt)); - - strproto_rmt[strlen (strproto_rmt)-1] = '\0'; - - strlcpy (strnetwork, ipx_ntoa (go->network), sizeof(strnetwork)); - - slprintf (strlocal, sizeof(strlocal), "%0.6B", go->our_node); - - slprintf (strremote, sizeof(strremote), "%0.6B", ho->his_node); - - argv[0] = script; - argv[1] = ifname; - argv[2] = devnam; - argv[3] = strspeed; - argv[4] = strnetwork; - argv[5] = strlocal; - argv[6] = strremote; - argv[7] = strproto_lcl; - argv[8] = strproto_rmt; - argv[9] = (char *)go->name; - argv[10] = (char *)ho->name; - argv[11] = ipparam; - argv[12] = strpid; - argv[13] = NULL; - run_program(script, argv, 0, NULL, NULL, 0); -} - -/* - * ipxcp_printpkt - print the contents of an IPXCP packet. - */ -static char *ipxcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int -ipxcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int code, id, len, olen; - u_char *pstart, *optend; - u_short cishort; - u_int32_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(ipxcp_codenames) / sizeof(char *)) - printer(arg, " %s", ipxcp_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 < CILEN_VOID || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case IPX_NETWORK_NUMBER: - if (olen == CILEN_NETN) { - p += 2; - GETLONG(cilong, p); - printer (arg, "network %s", ipx_ntoa (cilong)); - } - break; - case IPX_NODE_NUMBER: - if (olen == CILEN_NODEN) { - p += 2; - printer (arg, "node "); - while (p < optend) { - GETCHAR(code, p); - printer(arg, "%.2x", (int) (unsigned int) (unsigned char) code); - } - } - break; - case IPX_COMPRESSION_PROTOCOL: - if (olen == CILEN_COMPRESS) { - p += 2; - GETSHORT (cishort, p); - printer (arg, "compression %d", (int) cishort); - } - break; - case IPX_ROUTER_PROTOCOL: - if (olen == CILEN_PROTOCOL) { - p += 2; - GETSHORT (cishort, p); - printer (arg, "router proto %d", (int) cishort); - } - break; - case IPX_ROUTER_NAME: - if (olen >= CILEN_NAME) { - p += 2; - printer (arg, "router name \""); - while (p < optend) { - GETCHAR(code, p); - if (code >= 0x20 && code <= 0x7E) - printer (arg, "%c", (int) (unsigned int) (unsigned char) code); - else - printer (arg, " \\%.2x", (int) (unsigned int) (unsigned char) code); - } - printer (arg, "\""); - } - break; - case IPX_COMPLETE: - if (olen == CILEN_COMPLETE) { - p += 2; - printer (arg, "complete"); - } - break; - default: - break; - } - - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", (int) (unsigned int) (unsigned char) code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - print_string((char *)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", (int) (unsigned int) (unsigned char) code); - } - - return p - pstart; -} -#endif /* ifdef IPX_CHANGE */ diff --git a/src/netif/ppp/ipxcp.h b/src/netif/ppp/ipxcp.h deleted file mode 100644 index 396b6bba..00000000 --- a/src/netif/ppp/ipxcp.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * ipxcp.h - IPX Control Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ipxcp.h,v 1.5 2002/12/04 23:03:32 paulus Exp $ - */ - -/* - * Options. - */ -#define IPX_NETWORK_NUMBER 1 /* IPX Network Number */ -#define IPX_NODE_NUMBER 2 -#define IPX_COMPRESSION_PROTOCOL 3 -#define IPX_ROUTER_PROTOCOL 4 -#define IPX_ROUTER_NAME 5 -#define IPX_COMPLETE 6 - -/* Values for the router protocol */ -#define IPX_NONE 0 -#define RIP_SAP 2 -#define NLSP 4 - -typedef struct ipxcp_options { - bool neg_node; /* Negotiate IPX node number? */ - bool req_node; /* Ask peer to send IPX node number? */ - - bool neg_nn; /* Negotiate IPX network number? */ - bool req_nn; /* Ask peer to send IPX network number */ - - bool neg_name; /* Negotiate IPX router name */ - bool neg_complete; /* Negotiate completion */ - bool neg_router; /* Negotiate IPX router number */ - - bool accept_local; /* accept peer's value for ournode */ - bool accept_remote; /* accept peer's value for hisnode */ - bool accept_network; /* accept network number */ - - bool tried_nlsp; /* I have suggested NLSP already */ - bool tried_rip; /* I have suggested RIP/SAP already */ - - u_int32_t his_network; /* base network number */ - u_int32_t our_network; /* our value for network number */ - u_int32_t network; /* the final network number */ - - u_char his_node[6]; /* peer's node number */ - u_char our_node[6]; /* our node number */ - u_char name [48]; /* name of the router */ - int router; /* routing protocol */ -} ipxcp_options; - -extern fsm ipxcp_fsm[]; -extern ipxcp_options ipxcp_wantoptions[]; -extern ipxcp_options ipxcp_gotoptions[]; -extern ipxcp_options ipxcp_allowoptions[]; -extern ipxcp_options ipxcp_hisoptions[]; - -extern struct protent ipxcp_protent; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index b78cdc85..e8ccc7aa 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -117,9 +117,6 @@ #include "cbcp.h" #endif -#ifdef IPX_CHANGE -#include "ipxcp.h" -#endif /* IPX_CHANGE */ #ifdef AT_CHANGE #include "atcp.h" #endif @@ -291,9 +288,6 @@ struct protent *protocols[] = { #endif &ccp_protent, &ecp_protent, -#ifdef IPX_CHANGE - &ipxcp_protent, -#endif #ifdef AT_CHANGE &atcp_protent, #endif diff --git a/src/netif/ppp/sys-linux.c b/src/netif/ppp/sys-linux.c index 9c735ab9..9fdf6c73 100644 --- a/src/netif/ppp/sys-linux.c +++ b/src/netif/ppp/sys-linux.c @@ -127,16 +127,6 @@ #include "fsm.h" #include "ipcp.h" -#ifdef IPX_CHANGE -#include "ipxcp.h" -#if __GLIBC__ >= 2 && \ - !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0) -#include -#else -#include -#endif -#endif /* IPX_CHANGE */ - #ifdef PPP_FILTER #include #include @@ -2781,98 +2771,6 @@ sifnpmode(u, proto, mode) } #endif -/******************************************************************** - * - * sipxfaddr - Config the interface IPX networknumber - */ - -int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) -{ - int result = 1; - -#ifdef IPX_CHANGE - int skfd; - struct ifreq ifr; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; - - skfd = socket (AF_IPX, SOCK_DGRAM, 0); - if (skfd < 0) { - if (! ok_error (errno)) - dbglog("socket(AF_IPX): %m (line %d)", __LINE__); - result = 0; - } - else { - memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - memcpy (sipx->sipx_node, node, IPX_NODE_LEN); - sipx->sipx_family = AF_IPX; - sipx->sipx_port = 0; - sipx->sipx_network = htonl (network); - sipx->sipx_type = IPX_FRAME_ETHERII; - sipx->sipx_action = IPX_CRTITF; -/* - * Set the IPX device - */ - if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - result = 0; - if (errno != EEXIST) { - if (! ok_error (errno)) - dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__); - } - else { - warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists"); - } - } - close (skfd); - } -#endif - return result; -} - -/******************************************************************** - * - * cipxfaddr - Clear the information for the IPX network. The IPX routes - * are removed and the device is no longer able to pass IPX - * frames. - */ - -int cipxfaddr (int unit) -{ - int result = 1; - -#ifdef IPX_CHANGE - int skfd; - struct ifreq ifr; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; - - skfd = socket (AF_IPX, SOCK_DGRAM, 0); - if (skfd < 0) { - if (! ok_error (errno)) - dbglog("socket(AF_IPX): %m (line %d)", __LINE__); - result = 0; - } - else { - memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - sipx->sipx_type = IPX_FRAME_ETHERII; - sipx->sipx_action = IPX_DLTITF; - sipx->sipx_family = AF_IPX; -/* - * Set the IPX device - */ - if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__); - result = 0; - } - close (skfd); - } -#endif - return result; -} - /* * Use the hostname as part of the random number seed. */ @@ -2896,22 +2794,6 @@ get_host_seed() int sys_check_options(void) { -#ifdef IPX_CHANGE -/* - * Disable the IPX protocol if the support is not present in the kernel. - */ - char *path; - - if (ipxcp_protent.enabled_flag) { - struct stat stat_buf; - if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL - && (path = path_to_procfs("/net/ipx_interface")) == NULL) - || lstat(path, &stat_buf) < 0) { - error("IPX support is not present in the kernel\n"); - ipxcp_protent.enabled_flag = 0; - } - } -#endif if (demand && driver_is_old) { option_error("demand dialling is not supported by kernel driver " "version %d.%d.%d", driver_version, driver_modification, From bcba806ef002b918203982a7da8c369a97db7da3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 21:45:02 +0200 Subject: [PATCH 015/320] ported randm module from previous PPP port --- src/netif/ppp/magic.c | 288 +++++++++++++++++++++++++++++++++++------- src/netif/ppp/magic.h | 81 ++++++++++++ src/netif/ppp/pppmy.h | 1 + 3 files changed, 321 insertions(+), 49 deletions(-) diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 7e0a8ce0..38b80696 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -39,24 +39,48 @@ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/***************************************************************************** +* randm.c - Random number generator program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1998 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-06-03 Guy Lancaster , Global Election Systems Inc. +* Extracted from avos. +*****************************************************************************/ #include "lwip/opt.h" -#define RCSID "$Id: magic.c,v 1.11 2003/06/11 23:56:26 paulus Exp $" +#define PPP_SUPPORT 1 +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include -#include -#include -#include -#include - -#include "pppd.h" +#include "md5.h" #include "magic.h" - -static const char rcsid[] = RCSID; - -extern long mrand48 __P((void)); -extern void srand48 __P((long)); +#include "pppd.h" +#include "pppmy.h" /* * magic_init - Initialize the magic number generator. @@ -65,24 +89,124 @@ extern void srand48 __P((long)); * The current method uses the current hostid, current process ID * and current time, currently. */ -void -magic_init() -{ - long seed; - struct timeval t; - - gettimeofday(&t, NULL); - seed = get_host_seed() ^ t.tv_sec ^ t.tv_usec ^ getpid(); - srand48(seed); +void magic_init() { + avRandomInit(); } /* * magic - Returns the next magic number. */ -u_int32_t -magic() +u_int32_t magic() { + return (u_int32_t)avRandom(); +} + +#if MD5_SUPPORT /* this module depends on MD5 */ +#define RANDPOOLSZ 16 /* Bytes stored in the pool of randomness. */ + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static char randPool[RANDPOOLSZ]; /* Pool of randomness. */ +static long randCount = 0; /* Pseudo-random incrementer */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * Initialize the random number generator. + * + * Since this is to be called on power up, we don't have much + * system randomess to work with. Here all we use is the + * real-time clock. We'll accumulate more randomness as soon + * as things start happening. + */ +void +avRandomInit() { - return (u_int32_t) mrand48(); + avChurnRand(NULL, 0); +} + +/* + * Churn the randomness pool on a random event. Call this early and often + * on random and semi-random system events to build randomness in time for + * usage. For randomly timed events, pass a null pointer and a zero length + * and this will use the system timer and other sources to add randomness. + * If new random data is available, pass a pointer to that and it will be + * included. + * + * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 + */ +void +avChurnRand(char *randData, u32_t randLen) +{ + MD5_CTX md5; + + /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", randLen, randData)); */ + MD5_Init(&md5); + MD5_Update(&md5, (u_char *)randPool, sizeof(randPool)); + if (randData) { + MD5_Update(&md5, (u_char *)randData, randLen); + } else { + struct { + /* INCLUDE fields for any system sources of randomness */ + char foobar; + } sysData; + + /* Load sysData fields here. */ + MD5_Update(&md5, (u_char *)&sysData, sizeof(sysData)); + } + MD5_Final((u_char *)randPool, &md5); +/* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ +} + +/* + * Use the random pool to generate random data. This degrades to pseudo + * random when used faster than randomness is supplied using churnRand(). + * Note: It's important that there be sufficient randomness in randPool + * before this is called for otherwise the range of the result may be + * narrow enough to make a search feasible. + * + * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 + * + * XXX Why does he not just call churnRand() for each block? Probably + * so that you don't ever publish the seed which could possibly help + * predict future values. + * XXX Why don't we preserve md5 between blocks and just update it with + * randCount each time? Probably there is a weakness but I wish that + * it was documented. + */ +void +avGenRand(char *buf, u32_t bufLen) +{ + MD5_CTX md5; + u_char tmp[16]; + u32_t n; + + while (bufLen > 0) { + n = LWIP_MIN(bufLen, RANDPOOLSZ); + MD5_Init(&md5); + MD5_Update(&md5, (u_char *)randPool, sizeof(randPool)); + MD5_Update(&md5, (u_char *)&randCount, sizeof(randCount)); + MD5_Final(tmp, &md5); + randCount++; + MEMCPY(buf, tmp, n); + buf += n; + bufLen -= n; + } +} + +/* + * Return a new random number. + */ +u32_t +avRandom() +{ + u32_t newRand; + + avGenRand((char *)&newRand, sizeof(newRand)); + + return newRand; } /* @@ -91,35 +215,101 @@ magic() void random_bytes(unsigned char *buf, int len) { - int i; - - for (i = 0; i < len; ++i) - buf[i] = mrand48() >> 24; + avGenRand(buf, len); } -#ifdef NO_DRAND48 +#else /* MD5_SUPPORT */ + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static int avRandomized = 0; /* Set when truely randomized. */ +static u32_t avRandomSeed = 0; /* Seed used for random number generation. */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ /* - * Substitute procedures for those systems which don't have - * drand48 et al. + * Initialize the random number generator. + * + * Here we attempt to compute a random number seed but even if + * it isn't random, we'll randomize it later. + * + * The current method uses the fields from the real time clock, + * the idle process counter, the millisecond counter, and the + * hardware timer tick counter. When this is invoked + * in startup(), then the idle counter and timer values may + * repeat after each boot and the real time clock may not be + * operational. Thus we call it again on the first random + * event. */ - -double -drand48() -{ - return (double)random() / (double)0x7fffffffL; /* 2**31-1 */ -} - -long -mrand48() -{ - return random(); -} - void -srand48(seedval) -long seedval; +avRandomInit() { - srandom((int)seedval); +#if 0 + /* Get a pointer into the last 4 bytes of clockBuf. */ + u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]); + + /* + * Initialize our seed using the real-time clock, the idle + * counter, the millisecond timer, and the hardware timer + * tick counter. The real-time clock and the hardware + * tick counter are the best sources of randomness but + * since the tick counter is only 16 bit (and truncated + * at that), the idle counter and millisecond timer + * (which may be small values) are added to help + * randomize the lower 16 bits of the seed. + */ + readClk(); + avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr + + ppp_mtime() + ((u32_t)TM1 << 16) + TM1; +#else + avRandomSeed += sys_jiffies(); /* XXX */ +#endif + + /* Initialize the Borland random number generator. */ + srand((unsigned)avRandomSeed); } -#endif +/* + * Randomize our random seed value. Here we use the fact that + * this function is called at *truely random* times by the polling + * and network functions. Here we only get 16 bits of new random + * value but we use the previous value to randomize the other 16 + * bits. + */ +void +avRandomize(void) +{ + static u32_t last_jiffies; + + if (!avRandomized) { + avRandomized = !0; + avRandomInit(); + /* The initialization function also updates the seed. */ + } else { + /* avRandomSeed += (avRandomSeed << 16) + TM1; */ + avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */ + } + last_jiffies = sys_jiffies(); +} + +/* + * Return a new random number. + * Here we use the Borland rand() function to supply a pseudo random + * number which we make truely random by combining it with our own + * seed which is randomized by truely random events. + * Thus the numbers will be truely random unless there have been no + * operator or network events in which case it will be pseudo random + * seeded by the real time clock. + */ +u32_t +avRandom() +{ + return ((((u32_t)rand() << 16) + rand()) + avRandomSeed); +} + +#endif /* MD5_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/magic.h b/src/netif/ppp/magic.h index c81213b4..9aaf1b1f 100644 --- a/src/netif/ppp/magic.h +++ b/src/netif/ppp/magic.h @@ -41,6 +41,87 @@ * * $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $ */ +/***************************************************************************** +* randm.h - Random number generator header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-05-29 Guy Lancaster , Global Election Systems Inc. +* Extracted from avos. +*****************************************************************************/ + +#ifndef RANDM_H +#define RANDM_H + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ +/* + * Initialize the random number generator. + */ +void avRandomInit(void); + +/* + * Churn the randomness pool on a random event. Call this early and often + * on random and semi-random system events to build randomness in time for + * usage. For randomly timed events, pass a null pointer and a zero length + * and this will use the system timer and other sources to add randomness. + * If new random data is available, pass a pointer to that and it will be + * included. + */ +void avChurnRand(char *randData, u32_t randLen); + +/* + * Randomize our random seed value. To be called for truely random events + * such as user operations and network traffic. + */ +#if MD5_SUPPORT +#define avRandomize() avChurnRand(NULL, 0) +#else /* MD5_SUPPORT */ +void avRandomize(void); +#endif /* MD5_SUPPORT */ + +/* + * Use the random pool to generate random data. This degrades to pseudo + * random when used faster than randomness is supplied using churnRand(). + * Thus it's important to make sure that the results of this are not + * published directly because one could predict the next result to at + * least some degree. Also, it's important to get a good seed before + * the first use. + */ +void avGenRand(char *buf, u32_t bufLen); + +/* + * Return a new random number. + */ +u32_t avRandom(void); + + +#endif /* RANDM_H */ void magic_init __P((void)); /* Initialize the magic number generator */ u_int32_t magic __P((void)); /* Returns the next magic number */ diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 632521f4..e79f43fa 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -11,6 +11,7 @@ #include /* FIXME: temporary */ #include "lwip/netif.h" +#include "lwip/def.h" /************************* *** PUBLIC DEFINITIONS *** From 1a1deb5d5856002ebaf86ebaf55f77708fc44c52 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 22:42:07 +0200 Subject: [PATCH 016/320] reworked magic/randm --- src/netif/ppp/magic.c | 168 +++++++++++++++--------------------------- src/netif/ppp/magic.h | 53 ++++++------- 2 files changed, 80 insertions(+), 141 deletions(-) diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 38b80696..2360ecc8 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -74,7 +74,6 @@ #include "lwip/opt.h" -#define PPP_SUPPORT 1 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include "md5.h" @@ -82,50 +81,21 @@ #include "pppd.h" #include "pppmy.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() { - avRandomInit(); -} -/* - * magic - Returns the next magic number. - */ -u_int32_t magic() { - return (u_int32_t)avRandom(); -} +#if MD5_SUPPORT /* Using MD5 for better randomness if MD5 support is enabled */ -#if MD5_SUPPORT /* this module depends on MD5 */ -#define RANDPOOLSZ 16 /* Bytes stored in the pool of randomness. */ +#define MAGIC_RANDPOOLSIZE 16 /* Bytes stored in the pool of randomness. */ /*****************************/ /*** LOCAL DATA STRUCTURES ***/ /*****************************/ -static char randPool[RANDPOOLSZ]; /* Pool of randomness. */ -static long randCount = 0; /* Pseudo-random incrementer */ +static char magic_randpool[MAGIC_RANDPOOLSIZE]; /* Pool of randomness. */ +static long magic_randcount = 0; /* Pseudo-random incrementer */ /***********************************/ /*** PUBLIC FUNCTION DEFINITIONS ***/ /***********************************/ -/* - * Initialize the random number generator. - * - * Since this is to be called on power up, we don't have much - * system randomess to work with. Here all we use is the - * real-time clock. We'll accumulate more randomness as soon - * as things start happening. - */ -void -avRandomInit() -{ - avChurnRand(NULL, 0); -} /* * Churn the randomness pool on a random event. Call this early and often @@ -137,33 +107,47 @@ avRandomInit() * * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 */ -void -avChurnRand(char *randData, u32_t randLen) -{ +void magic_churnrand(char *rand_data, u32_t rand_len) { MD5_CTX md5; - /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", randLen, randData)); */ + /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", rand_len, rand_data)); */ MD5_Init(&md5); - MD5_Update(&md5, (u_char *)randPool, sizeof(randPool)); - if (randData) { - MD5_Update(&md5, (u_char *)randData, randLen); + MD5_Update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + if (rand_data) { + MD5_Update(&md5, (u_char *)rand_data, rand_len); } else { struct { /* INCLUDE fields for any system sources of randomness */ char foobar; - } sysData; + } sys_data; - /* Load sysData fields here. */ - MD5_Update(&md5, (u_char *)&sysData, sizeof(sysData)); + /* Load sys_data fields here. */ + MD5_Update(&md5, (u_char *)&sys_data, sizeof(sys_data)); } - MD5_Final((u_char *)randPool, &md5); + MD5_Final((u_char *)magic_randpool, &md5); /* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ } /* + * Initialize the random number generator. + */ +void magic_init() { + magic_churnrand(NULL, 0); +} + +/* + * Randomize our random seed value. + */ +void magic_randomize(void) { + magic_churnrand(NULL, 0); +} + +/* + * random_bytes - Fill a buffer with random bytes. + * * Use the random pool to generate random data. This degrades to pseudo * random when used faster than randomness is supplied using churnRand(). - * Note: It's important that there be sufficient randomness in randPool + * Note: It's important that there be sufficient randomness in magic_randpool * before this is called for otherwise the range of the result may be * narrow enough to make a search feasible. * @@ -173,49 +157,36 @@ avChurnRand(char *randData, u32_t randLen) * so that you don't ever publish the seed which could possibly help * predict future values. * XXX Why don't we preserve md5 between blocks and just update it with - * randCount each time? Probably there is a weakness but I wish that + * magic_randcount each time? Probably there is a weakness but I wish that * it was documented. */ -void -avGenRand(char *buf, u32_t bufLen) -{ +void random_bytes(unsigned char *buf, u32_t buf_len) { MD5_CTX md5; u_char tmp[16]; u32_t n; - while (bufLen > 0) { - n = LWIP_MIN(bufLen, RANDPOOLSZ); + while (buf_len > 0) { + n = LWIP_MIN(buf_len, MAGIC_RANDPOOLSIZE); MD5_Init(&md5); - MD5_Update(&md5, (u_char *)randPool, sizeof(randPool)); - MD5_Update(&md5, (u_char *)&randCount, sizeof(randCount)); + MD5_Update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + MD5_Update(&md5, (u_char *)&magic_randcount, sizeof(magic_randcount)); MD5_Final(tmp, &md5); - randCount++; + magic_randcount++; MEMCPY(buf, tmp, n); buf += n; - bufLen -= n; + buf_len -= n; } } /* * Return a new random number. */ -u32_t -avRandom() -{ - u32_t newRand; +u32_t magic() { + u32_t new_rand; - avGenRand((char *)&newRand, sizeof(newRand)); + random_bytes((char *)&new_rand, sizeof(new_rand)); - return newRand; -} - -/* - * random_bytes - Fill a buffer with random bytes. - */ -void -random_bytes(unsigned char *buf, int len) -{ - avGenRand(buf, len); + return new_rand; } #else /* MD5_SUPPORT */ @@ -223,13 +194,14 @@ random_bytes(unsigned char *buf, int len) /*****************************/ /*** LOCAL DATA STRUCTURES ***/ /*****************************/ -static int avRandomized = 0; /* Set when truely randomized. */ -static u32_t avRandomSeed = 0; /* Seed used for random number generation. */ +static int magic_randomized = 0; /* Set when truely randomized. */ +static u32_t magic_randomseed = 0; /* Seed used for random number generation. */ /***********************************/ /*** PUBLIC FUNCTION DEFINITIONS ***/ /***********************************/ + /* * Initialize the random number generator. * @@ -244,59 +216,39 @@ static u32_t avRandomSeed = 0; /* Seed used for random number generation. * * operational. Thus we call it again on the first random * event. */ -void -avRandomInit() -{ -#if 0 - /* Get a pointer into the last 4 bytes of clockBuf. */ - u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]); - - /* - * Initialize our seed using the real-time clock, the idle - * counter, the millisecond timer, and the hardware timer - * tick counter. The real-time clock and the hardware - * tick counter are the best sources of randomness but - * since the tick counter is only 16 bit (and truncated - * at that), the idle counter and millisecond timer - * (which may be small values) are added to help - * randomize the lower 16 bits of the seed. - */ - readClk(); - avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr - + ppp_mtime() + ((u32_t)TM1 << 16) + TM1; -#else - avRandomSeed += sys_jiffies(); /* XXX */ -#endif +void magic_init() { + magic_randomseed += sys_jiffies(); /* Initialize the Borland random number generator. */ - srand((unsigned)avRandomSeed); + srand((unsigned)magic_randomseed); } /* + * magic_init - Initialize the magic number generator. + * * Randomize our random seed value. Here we use the fact that * this function is called at *truely random* times by the polling * and network functions. Here we only get 16 bits of new random * value but we use the previous value to randomize the other 16 * bits. */ -void -avRandomize(void) -{ +void magic_randomize(void) { static u32_t last_jiffies; - if (!avRandomized) { - avRandomized = !0; - avRandomInit(); + if (!magic_randomized) { + magic_randomized = !0; + magic_randominit(); /* The initialization function also updates the seed. */ } else { - /* avRandomSeed += (avRandomSeed << 16) + TM1; */ - avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */ + /* magic_randomseed += (magic_randomseed << 16) + TM1; */ + magic_randomseed += (sys_jiffies() - last_jiffies); /* XXX */ } last_jiffies = sys_jiffies(); } /* * Return a new random number. + * * Here we use the Borland rand() function to supply a pseudo random * number which we make truely random by combining it with our own * seed which is randomized by truely random events. @@ -304,10 +256,8 @@ avRandomize(void) * operator or network events in which case it will be pseudo random * seeded by the real time clock. */ -u32_t -avRandom() -{ - return ((((u32_t)rand() << 16) + rand()) + avRandomSeed); +u32_t magic() { + return ((((u32_t)rand() << 16) + rand()) + magic_randomseed); } #endif /* MD5_SUPPORT */ diff --git a/src/netif/ppp/magic.h b/src/netif/ppp/magic.h index 9aaf1b1f..2c714140 100644 --- a/src/netif/ppp/magic.h +++ b/src/netif/ppp/magic.h @@ -74,38 +74,37 @@ * Extracted from avos. *****************************************************************************/ -#ifndef RANDM_H -#define RANDM_H +#ifndef MAGIC_H +#define MAGIC_H + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ /*********************** *** PUBLIC FUNCTIONS *** ***********************/ + /* * Initialize the random number generator. */ -void avRandomInit(void); - -/* - * Churn the randomness pool on a random event. Call this early and often - * on random and semi-random system events to build randomness in time for - * usage. For randomly timed events, pass a null pointer and a zero length - * and this will use the system timer and other sources to add randomness. - * If new random data is available, pass a pointer to that and it will be - * included. - */ -void avChurnRand(char *randData, u32_t randLen); +void magic_init(void); /* * Randomize our random seed value. To be called for truely random events * such as user operations and network traffic. */ -#if MD5_SUPPORT -#define avRandomize() avChurnRand(NULL, 0) -#else /* MD5_SUPPORT */ -void avRandomize(void); -#endif /* MD5_SUPPORT */ +void magic_randomize(void); /* + * Return a new random number. + */ +u32_t magic(void); /* Returns the next magic number */ + +#if MD5_SUPPORT +/* + * Fill buffer with random bytes + * * Use the random pool to generate random data. This degrades to pseudo * random when used faster than randomness is supplied using churnRand(). * Thus it's important to make sure that the results of this are not @@ -113,18 +112,8 @@ void avRandomize(void); * least some degree. Also, it's important to get a good seed before * the first use. */ -void avGenRand(char *buf, u32_t bufLen); +void random_bytes(unsigned char *buf, u32_t len); +#endif /* MD5_SUPPORT */ -/* - * Return a new random number. - */ -u32_t avRandom(void); - - -#endif /* RANDM_H */ - -void magic_init __P((void)); /* Initialize the magic number generator */ -u_int32_t magic __P((void)); /* Returns the next magic number */ - -/* Fill buffer with random bytes */ -void random_bytes __P((unsigned char *buf, int len)); +#endif /* PPP_SUPPORT */ +#endif /* MAGIC_H */ From 1d7efce0dc8ba68ac6cc02a545a17f0e9e443d81 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 23:21:09 +0200 Subject: [PATCH 017/320] Removed TDB code, which we cannot port, because it needs a filesystem. About multilink support. Multilink uses Samba TDB (Trivial Database Library), which we cannot port, for the above reason. We have to choose between doing a memory-shared TDB-clone, or dropping multilink support at all. --- src/netif/ppp/multilink.c | 12 + src/netif/ppp/ppp.c | 183 ---- src/netif/ppp/spinlock.c | 476 --------- src/netif/ppp/spinlock.h | 59 -- src/netif/ppp/tdb.c | 2011 ------------------------------------- src/netif/ppp/tdb.h | 164 --- 6 files changed, 12 insertions(+), 2893 deletions(-) delete mode 100644 src/netif/ppp/spinlock.c delete mode 100644 src/netif/ppp/spinlock.h delete mode 100644 src/netif/ppp/tdb.c delete mode 100644 src/netif/ppp/tdb.h diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 0cd30076..a8687b43 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -30,6 +30,17 @@ #include "lwip/opt.h" +/* Multilink support + * + * Multilink uses Samba TDB (Trivial Database Library), which + * we cannot port, because it needs a filesystem. + * + * We have to choose between doing a memory-shared TDB-clone, + * or dropping multilink support at all. + */ + +#ifdef HAVE_MULTILINK + #include #include #include @@ -593,3 +604,4 @@ str_to_epdisc(ep, str) return 1; } +#endif /* HAVE_MULTILINK */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index e8ccc7aa..eb212a36 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -109,10 +109,6 @@ #include "ecp.h" #include "pathnames.h" -#ifdef USE_TDB -#include "tdb.h" -#endif - #if CBCP_SUPPORT #include "cbcp.h" #endif @@ -153,10 +149,6 @@ int ppp_session_number; /* Session number, for channels with such a concept (eg PPPoE) */ int childwait_done; /* have timed out waiting for children */ -#ifdef USE_TDB -TDB_CONTEXT *pppdb; /* database for storing status etc. */ -#endif - char db_key[32]; int (*holdoff_hook) __P((void)) = NULL; @@ -247,13 +239,6 @@ static void forget_child __P((int pid, int status)); static int reap_kids __P((void)); static void childwait_end __P((void *)); -#ifdef USE_TDB -static void update_db_entry __P((void)); -static void add_db_key __P((const char *)); -static void delete_db_key __P((const char *)); -static void cleanup_db __P((void)); -#endif - static void handle_events __P((void)); void print_link_stats __P((void)); @@ -430,20 +415,6 @@ int ppp_oldmain() { */ linux_sys_init(); -#ifdef USE_TDB - pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644); - if (pppdb != NULL) { - slprintf(db_key, sizeof(db_key), "pppd%d", getpid()); - update_db_entry(); - } else { - warn("Warning: couldn't open ppp database %s", _PATH_PPPDB); - if (multilink) { - warn("Warning: disabling multilink"); - multilink = 0; - } - } -#endif - /* * Detach ourselves from the terminal, if required, * and identify who is running us. @@ -1184,12 +1155,6 @@ cleanup() if (the_channel->cleanup) (*the_channel->cleanup)(); remove_pidfiles(); - -#ifdef USE_TDB - if (pppdb != NULL) - cleanup_db(); -#endif - } void @@ -1566,9 +1531,6 @@ safe_fork(int infd, int outfd, int errfd) /* Executing in the child */ sys_close(); -#ifdef USE_TDB - tdb_close(pppdb); -#endif /* make sure infd, outfd and errfd won't get tromped on below */ if (infd == 1 || infd == 2) @@ -1864,17 +1826,8 @@ script_setenv(var, value, iskey) if (script_env != 0) { for (i = 0; (p = script_env[i]) != 0; ++i) { if (strncmp(p, var, varl) == 0 && p[varl] == '=') { -#ifdef USE_TDB - if (p[-1] && pppdb != NULL) - delete_db_key(p); -#endif free(p-1); script_env[i] = newstring; -#ifdef USE_TDB - if (iskey && pppdb != NULL) - add_db_key(newstring); - update_db_entry(); -#endif return; } } @@ -1900,14 +1853,6 @@ script_setenv(var, value, iskey) script_env[i] = newstring; script_env[i+1] = 0; - -#ifdef USE_TDB - if (pppdb != NULL) { - if (iskey) - add_db_key(newstring); - update_db_entry(); - } -#endif } /* @@ -1926,138 +1871,10 @@ script_unsetenv(var) return; for (i = 0; (p = script_env[i]) != 0; ++i) { if (strncmp(p, var, vl) == 0 && p[vl] == '=') { -#ifdef USE_TDB - if (p[-1] && pppdb != NULL) - delete_db_key(p); -#endif free(p-1); while ((script_env[i] = script_env[i+1]) != 0) ++i; break; } } -#ifdef USE_TDB - if (pppdb != NULL) - update_db_entry(); -#endif } - -/* - * Any arbitrary string used as a key for locking the database. - * It doesn't matter what it is as long as all pppds use the same string. - */ -#define PPPD_LOCK_KEY "pppd lock" - -/* - * lock_db - get an exclusive lock on the TDB database. - * Used to ensure atomicity of various lookup/modify operations. - */ -void lock_db() -{ -#ifdef USE_TDB - TDB_DATA key; - - key.dptr = PPPD_LOCK_KEY; - key.dsize = strlen(key.dptr); - tdb_chainlock(pppdb, key); -#endif -} - -/* - * unlock_db - remove the exclusive lock obtained by lock_db. - */ -void unlock_db() -{ -#ifdef USE_TDB - TDB_DATA key; - - key.dptr = PPPD_LOCK_KEY; - key.dsize = strlen(key.dptr); - tdb_chainunlock(pppdb, key); -#endif -} - -#ifdef USE_TDB -/* - * update_db_entry - update our entry in the database. - */ -static void -update_db_entry() -{ - TDB_DATA key, dbuf; - int vlen, i; - char *p, *q, *vbuf; - - if (script_env == NULL) - return; - vlen = 0; - for (i = 0; (p = script_env[i]) != 0; ++i) - vlen += strlen(p) + 1; - vbuf = malloc(vlen + 1); - if (vbuf == 0) - novm("database entry"); - q = vbuf; - for (i = 0; (p = script_env[i]) != 0; ++i) - q += slprintf(q, vbuf + vlen - q, "%s;", p); - - key.dptr = db_key; - key.dsize = strlen(db_key); - dbuf.dptr = vbuf; - dbuf.dsize = vlen; - if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) - error("tdb_store failed: %s", tdb_errorstr(pppdb)); - - if (vbuf) - free(vbuf); - -} - -/* - * add_db_key - add a key that we can use to look up our database entry. - */ -static void -add_db_key(str) - const char *str; -{ - TDB_DATA key, dbuf; - - key.dptr = (char *) str; - key.dsize = strlen(str); - dbuf.dptr = db_key; - dbuf.dsize = strlen(db_key); - if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) - error("tdb_store key failed: %s", tdb_errorstr(pppdb)); -} - -/* - * delete_db_key - delete a key for looking up our database entry. - */ -static void -delete_db_key(str) - const char *str; -{ - TDB_DATA key; - - key.dptr = (char *) str; - key.dsize = strlen(str); - tdb_delete(pppdb, key); -} - -/* - * cleanup_db - delete all the entries we put in the database. - */ -static void -cleanup_db() -{ - TDB_DATA key; - int i; - char *p; - - key.dptr = db_key; - key.dsize = strlen(db_key); - tdb_delete(pppdb, key); - for (i = 0; (p = script_env[i]) != 0; ++i) - if (p[-1]) - delete_db_key(p); -} -#endif /* USE_TDB */ diff --git a/src/netif/ppp/spinlock.c b/src/netif/ppp/spinlock.c deleted file mode 100644 index 3e3e3cb1..00000000 --- a/src/netif/ppp/spinlock.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Anton Blanchard 2001 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "lwip/opt.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" -#include "spinlock.h" - -#define DEBUG - -#ifdef USE_SPINLOCKS - -/* - * ARCH SPECIFIC - */ - -#if defined(SPARC_SPINLOCKS) - -static inline int __spin_trylock(spinlock_t *lock) -{ - unsigned int result; - - asm volatile("ldstub [%1], %0" - : "=r" (result) - : "r" (lock) - : "memory"); - - return (result == 0) ? 0 : EBUSY; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - asm volatile("":::"memory"); - *lock = 0; -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - *lock = 0; -} - -static inline int __spin_is_locked(spinlock_t *lock) -{ - return (*lock != 0); -} - -#elif defined(POWERPC_SPINLOCKS) - -static inline int __spin_trylock(spinlock_t *lock) -{ - unsigned int result; - - __asm__ __volatile__( -"1: lwarx %0,0,%1\n\ - cmpwi 0,%0,0\n\ - li %0,0\n\ - bne- 2f\n\ - li %0,1\n\ - stwcx. %0,0,%1\n\ - bne- 1b\n\ - isync\n\ -2:" : "=&r"(result) - : "r"(lock) - : "cr0", "memory"); - - return (result == 1) ? 0 : EBUSY; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - asm volatile("eieio":::"memory"); - *lock = 0; -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - *lock = 0; -} - -static inline int __spin_is_locked(spinlock_t *lock) -{ - return (*lock != 0); -} - -#elif defined(INTEL_SPINLOCKS) - -static inline int __spin_trylock(spinlock_t *lock) -{ - int oldval; - - asm volatile("xchgl %0,%1" - : "=r" (oldval), "=m" (*lock) - : "0" (0) - : "memory"); - - return oldval > 0 ? 0 : EBUSY; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - asm volatile("":::"memory"); - *lock = 1; -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - *lock = 1; -} - -static inline int __spin_is_locked(spinlock_t *lock) -{ - return (*lock != 1); -} - -#elif defined(MIPS_SPINLOCKS) && defined(sgi) && (_COMPILER_VERSION >= 730) - -/* Implement spinlocks on IRIX using the MIPSPro atomic fetch operations. See - * sync(3) for the details of the intrinsic operations. - * - * "sgi" and "_COMPILER_VERSION" are always defined by MIPSPro. - */ - -#ifdef STANDALONE - -/* MIPSPro 7.3 has "__inline" as an extension, but not "inline. */ -#define inline __inline - -#endif /* STANDALONE */ - -/* Returns 0 if the lock is acquired, EBUSY otherwise. */ -static inline int __spin_trylock(spinlock_t *lock) -{ - unsigned int val; - val = __lock_test_and_set(lock, 1); - return val == 0 ? 0 : EBUSY; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - __lock_release(lock); -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - __lock_release(lock); -} - -/* Returns 1 if the lock is held, 0 otherwise. */ -static inline int __spin_is_locked(spinlock_t *lock) -{ - unsigned int val; - val = __add_and_fetch(lock, 0); - return val; -} - -#elif defined(MIPS_SPINLOCKS) - -static inline unsigned int load_linked(unsigned long addr) -{ - unsigned int res; - - __asm__ __volatile__("ll\t%0,(%1)" - : "=r" (res) - : "r" (addr)); - - return res; -} - -static inline unsigned int store_conditional(unsigned long addr, unsigned int value) -{ - unsigned int res; - - __asm__ __volatile__("sc\t%0,(%2)" - : "=r" (res) - : "0" (value), "r" (addr)); - return res; -} - -static inline int __spin_trylock(spinlock_t *lock) -{ - unsigned int mw; - - do { - mw = load_linked(lock); - if (mw) - return EBUSY; - } while (!store_conditional(lock, 1)); - - asm volatile("":::"memory"); - - return 0; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - asm volatile("":::"memory"); - *lock = 0; -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - *lock = 0; -} - -static inline int __spin_is_locked(spinlock_t *lock) -{ - return (*lock != 0); -} - -#else -#error Need to implement spinlock code in spinlock.c -#endif - -/* - * OS SPECIFIC - */ - -static void yield_cpu(void) -{ - struct timespec tm; - -#ifdef USE_SCHED_YIELD - sched_yield(); -#else - /* Linux will busy loop for delays < 2ms on real time tasks */ - tm.tv_sec = 0; - tm.tv_nsec = 2000000L + 1; - nanosleep(&tm, NULL); -#endif -} - -static int this_is_smp(void) -{ -#if defined(HAVE_SYSCONF) && defined(SYSCONF_SC_NPROC_ONLN) - return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0; -#else - return 0; -#endif -} - -/* - * GENERIC - */ - -static int smp_machine = 0; - -static inline void __spin_lock(spinlock_t *lock) -{ - int ntries = 0; - - while(__spin_trylock(lock)) { - while(__spin_is_locked(lock)) { - if (smp_machine && ntries++ < MAX_BUSY_LOOPS) - continue; - yield_cpu(); - } - } -} - -static void __read_lock(tdb_rwlock_t *rwlock) -{ - int ntries = 0; - - while(1) { - __spin_lock(&rwlock->lock); - - if (!(rwlock->count & RWLOCK_BIAS)) { - rwlock->count++; - __spin_unlock(&rwlock->lock); - return; - } - - __spin_unlock(&rwlock->lock); - - while(rwlock->count & RWLOCK_BIAS) { - if (smp_machine && ntries++ < MAX_BUSY_LOOPS) - continue; - yield_cpu(); - } - } -} - -static void __write_lock(tdb_rwlock_t *rwlock) -{ - int ntries = 0; - - while(1) { - __spin_lock(&rwlock->lock); - - if (rwlock->count == 0) { - rwlock->count |= RWLOCK_BIAS; - __spin_unlock(&rwlock->lock); - return; - } - - __spin_unlock(&rwlock->lock); - - while(rwlock->count != 0) { - if (smp_machine && ntries++ < MAX_BUSY_LOOPS) - continue; - yield_cpu(); - } - } -} - -static void __write_unlock(tdb_rwlock_t *rwlock) -{ - __spin_lock(&rwlock->lock); - -#ifdef DEBUG - if (!(rwlock->count & RWLOCK_BIAS)) - fprintf(stderr, "bug: write_unlock\n"); -#endif - - rwlock->count &= ~RWLOCK_BIAS; - __spin_unlock(&rwlock->lock); -} - -static void __read_unlock(tdb_rwlock_t *rwlock) -{ - __spin_lock(&rwlock->lock); - -#ifdef DEBUG - if (!rwlock->count) - fprintf(stderr, "bug: read_unlock\n"); - - if (rwlock->count & RWLOCK_BIAS) - fprintf(stderr, "bug: read_unlock\n"); -#endif - - rwlock->count--; - __spin_unlock(&rwlock->lock); -} - -/* TDB SPECIFIC */ - -/* lock a list in the database. list -1 is the alloc list */ -int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) -{ - tdb_rwlock_t *rwlocks; - - if (!tdb->map_ptr) return -1; - rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); - - switch(rw_type) { - case F_RDLCK: - __read_lock(&rwlocks[list+1]); - break; - - case F_WRLCK: - __write_lock(&rwlocks[list+1]); - break; - - default: - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - return 0; -} - -/* unlock the database. */ -int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) -{ - tdb_rwlock_t *rwlocks; - - if (!tdb->map_ptr) return -1; - rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); - - switch(rw_type) { - case F_RDLCK: - __read_unlock(&rwlocks[list+1]); - break; - - case F_WRLCK: - __write_unlock(&rwlocks[list+1]); - break; - - default: - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - return 0; -} - -int tdb_create_rwlocks(int fd, unsigned int hash_size) -{ - unsigned size, i; - tdb_rwlock_t *rwlocks; - - size = TDB_SPINLOCK_SIZE(hash_size); - rwlocks = malloc(size); - if (!rwlocks) - return -1; - - for(i = 0; i < hash_size+1; i++) { - __spin_lock_init(&rwlocks[i].lock); - rwlocks[i].count = 0; - } - - /* Write it out (appending to end) */ - if (write(fd, rwlocks, size) != size) { - free(rwlocks); - return -1; - } - smp_machine = this_is_smp(); - free(rwlocks); - return 0; -} - -int tdb_clear_spinlocks(TDB_CONTEXT *tdb) -{ - tdb_rwlock_t *rwlocks; - unsigned i; - - if (tdb->header.rwlocks == 0) return 0; - if (!tdb->map_ptr) return -1; - - /* We're mmapped here */ - rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); - for(i = 0; i < tdb->header.hash_size+1; i++) { - __spin_lock_init(&rwlocks[i].lock); - rwlocks[i].count = 0; - } - return 0; -} -#else -int tdb_create_rwlocks(int fd, unsigned int hash_size) { return 0; } -int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } -int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } - -/* Non-spinlock version: remove spinlock pointer */ -int tdb_clear_spinlocks(TDB_CONTEXT *tdb) -{ - tdb_off off = (tdb_off)((char *)&tdb->header.rwlocks - - (char *)&tdb->header); - - tdb->header.rwlocks = 0; - if (lseek(tdb->fd, off, SEEK_SET) != off - || write(tdb->fd, (void *)&tdb->header.rwlocks, - sizeof(tdb->header.rwlocks)) - != sizeof(tdb->header.rwlocks)) - return -1; - return 0; -} -#endif diff --git a/src/netif/ppp/spinlock.h b/src/netif/ppp/spinlock.h deleted file mode 100644 index 967fe374..00000000 --- a/src/netif/ppp/spinlock.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __SPINLOCK_H__ -#define __SPINLOCK_H__ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "tdb.h" - -#ifdef USE_SPINLOCKS - -#define RWLOCK_BIAS 0x1000UL - -/* OS SPECIFIC */ -#define MAX_BUSY_LOOPS 1000 -#undef USE_SCHED_YIELD - -/* ARCH SPECIFIC */ -/* We should make sure these are padded to a cache line */ -#if defined(SPARC_SPINLOCKS) -typedef volatile char spinlock_t; -#elif defined(POWERPC_SPINLOCKS) -typedef volatile unsigned long spinlock_t; -#elif defined(INTEL_SPINLOCKS) -typedef volatile int spinlock_t; -#elif defined(MIPS_SPINLOCKS) -typedef volatile unsigned long spinlock_t; -#else -#error Need to implement spinlock code in spinlock.h -#endif - -typedef struct { - spinlock_t lock; - volatile int count; -} tdb_rwlock_t; - -int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); -int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); -int tdb_create_rwlocks(int fd, unsigned int hash_size); -int tdb_clear_spinlocks(TDB_CONTEXT *tdb); - -#define TDB_SPINLOCK_SIZE(hash_size) (((hash_size) + 1) * sizeof(tdb_rwlock_t)) - -#else /* !USE_SPINLOCKS */ -#if 0 -#define tdb_create_rwlocks(fd, hash_size) 0 -#define tdb_spinlock(tdb, list, rw_type) (-1) -#define tdb_spinunlock(tdb, list, rw_type) (-1) -#else -int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); -int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); -int tdb_create_rwlocks(int fd, unsigned int hash_size); -#endif -int tdb_clear_spinlocks(TDB_CONTEXT *tdb); -#define TDB_SPINLOCK_SIZE(hash_size) 0 - -#endif - -#endif diff --git a/src/netif/ppp/tdb.c b/src/netif/ppp/tdb.c deleted file mode 100644 index d2c446d4..00000000 --- a/src/netif/ppp/tdb.c +++ /dev/null @@ -1,2011 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2004 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - -/* NOTE: If you use tdbs under valgrind, and in particular if you run - * tdbtorture, you may get spurious "uninitialized value" warnings. I - * think this is because valgrind doesn't understand that the mmap'd - * area may be written to by other processes. Memory can, from the - * point of view of the grinded process, spontaneously become - * initialized. - * - * I can think of a few solutions. [mbp 20030311] - * - * 1 - Write suppressions for Valgrind so that it doesn't complain - * about this. Probably the most reasonable but people need to - * remember to use them. - * - * 2 - Use IO not mmap when running under valgrind. Not so nice. - * - * 3 - Use the special valgrind macros to mark memory as valid at the - * right time. Probably too hard -- the process just doesn't know. - */ - -#include "lwip/opt.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" -#include "spinlock.h" - -#define TDB_MAGIC_FOOD "TDB file\n" -#define TDB_VERSION (0x26011967 + 6) -#define TDB_MAGIC (0x26011999U) -#define TDB_FREE_MAGIC (~TDB_MAGIC) -#define TDB_DEAD_MAGIC (0xFEE1DEAD) -#define TDB_ALIGNMENT 4 -#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT) -#define DEFAULT_HASH_SIZE 131 -#define TDB_PAGE_SIZE 0x2000 -#define FREELIST_TOP (sizeof(struct tdb_header)) -#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) -#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) -#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) -#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) -#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off)) -#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + TDB_SPINLOCK_SIZE(hash_size)) - - -/* NB assumes there is a local variable called "tdb" that is the - * current context, also takes doubly-parenthesized print-style - * argument. */ -#define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0) - -/* lock offsets */ -#define GLOBAL_LOCK 0 -#define ACTIVE_LOCK 4 - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -#ifndef MAP_FAILED -#define MAP_FAILED ((void *)-1) -#endif - -/* free memory if the pointer is valid and zero the pointer */ -#ifndef SAFE_FREE -#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0) -#endif - -#define BUCKET(hash) ((hash) % tdb->header.hash_size) -TDB_DATA tdb_null; - -/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ -static TDB_CONTEXT *tdbs = NULL; - -static int tdb_munmap(TDB_CONTEXT *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return 0; - -#ifdef HAVE_MMAP - if (tdb->map_ptr) { - int ret = munmap(tdb->map_ptr, tdb->map_size); - if (ret != 0) - return ret; - } -#endif - tdb->map_ptr = NULL; - return 0; -} - -static void tdb_mmap(TDB_CONTEXT *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return; - -#ifdef HAVE_MMAP - if (!(tdb->flags & TDB_NOMMAP)) { - tdb->map_ptr = mmap(NULL, tdb->map_size, - PROT_READ|(tdb->read_only? 0:PROT_WRITE), - MAP_SHARED|MAP_FILE, tdb->fd, 0); - - /* - * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! - */ - - if (tdb->map_ptr == MAP_FAILED) { - tdb->map_ptr = NULL; - TDB_LOG((tdb, 2, "tdb_mmap failed for size %d (%s)\n", - tdb->map_size, strerror(errno))); - } - } else { - tdb->map_ptr = NULL; - } -#else - tdb->map_ptr = NULL; -#endif -} - -/* Endian conversion: we only ever deal with 4 byte quantities */ -static void *convert(void *buf, u32 size) -{ - u32 i, *p = buf; - for (i = 0; i < size / 4; i++) - p[i] = TDB_BYTEREV(p[i]); - return buf; -} -#define DOCONV() (tdb->flags & TDB_CONVERT) -#define CONVERT(x) (DOCONV() ? convert(&x, sizeof(x)) : &x) - -/* the body of the database is made of one list_struct for the free space - plus a separate data list for each hash value */ -struct list_struct { - tdb_off next; /* offset of the next record in the list */ - tdb_len rec_len; /* total byte length of record */ - tdb_len key_len; /* byte length of key */ - tdb_len data_len; /* byte length of data */ - u32 full_hash; /* the full 32 bit hash of the key */ - u32 magic; /* try to catch errors */ - /* the following union is implied: - union { - char record[rec_len]; - struct { - char key[key_len]; - char data[data_len]; - } - u32 totalsize; (tailer) - } - */ -}; - -/*************************************************************** - Allow a caller to set a "alarm" flag that tdb can check to abort - a blocking lock on SIGALRM. -***************************************************************/ - -static sig_atomic_t *palarm_fired; - -void tdb_set_lock_alarm(sig_atomic_t *palarm) -{ - palarm_fired = palarm; -} - -/* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset. - - On error, errno is also set so that errors are passed back properly - through tdb_open(). */ -static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, - int rw_type, int lck_type, int probe) -{ - struct flock fl; - int ret; - - if (tdb->flags & TDB_NOLOCK) - return 0; - if ((rw_type == F_WRLCK) && (tdb->read_only)) { - errno = EACCES; - return -1; - } - - fl.l_type = rw_type; - fl.l_whence = SEEK_SET; - fl.l_start = offset; - fl.l_len = 1; - fl.l_pid = 0; - - do { - ret = fcntl(tdb->fd,lck_type,&fl); - if (ret == -1 && errno == EINTR && palarm_fired && *palarm_fired) - break; - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { - if (!probe && lck_type != F_SETLK) { - /* Ensure error code is set for log fun to examine. */ - if (errno == EINTR && palarm_fired && *palarm_fired) - tdb->ecode = TDB_ERR_LOCK_TIMEOUT; - else - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n", - tdb->fd, offset, rw_type, lck_type)); - } - /* Was it an alarm timeout ? */ - if (errno == EINTR && palarm_fired && *palarm_fired) { - TDB_LOG((tdb, 5, "tdb_brlock timed out (fd=%d) at offset %d rw_type=%d lck_type=%d\n", - tdb->fd, offset, rw_type, lck_type)); - return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1); - } - /* Otherwise - generic lock error. errno set by fcntl. - * EAGAIN is an expected return from non-blocking - * locks. */ - if (errno != EAGAIN) { - TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", - tdb->fd, offset, rw_type, lck_type, - strerror(errno))); - } - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - return 0; -} - -/* lock a list in the database. list -1 is the alloc list */ -static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype) -{ - if (list < -1 || list >= (int)tdb->header.hash_size) { - TDB_LOG((tdb, 0,"tdb_lock: invalid list %d for ltype=%d\n", - list, ltype)); - return -1; - } - if (tdb->flags & TDB_NOLOCK) - return 0; - - /* Since fcntl locks don't nest, we do a lock for the first one, - and simply bump the count for future ones */ - if (tdb->locked[list+1].count == 0) { - if (!tdb->read_only && tdb->header.rwlocks) { - if (tdb_spinlock(tdb, list, ltype)) { - TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list %d ltype=%d\n", - list, ltype)); - return -1; - } - } else if (tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, 0)) { - TDB_LOG((tdb, 0,"tdb_lock failed on list %d ltype=%d (%s)\n", - list, ltype, strerror(errno))); - return -1; - } - tdb->locked[list+1].ltype = ltype; - } - tdb->locked[list+1].count++; - return 0; -} - -/* unlock the database: returns void because it's too late for errors. */ - /* changed to return int it may be interesting to know there - has been an error --simo */ -static int tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype) -{ - int ret = -1; - - if (tdb->flags & TDB_NOLOCK) - return 0; - - /* Sanity checks */ - if (list < -1 || list >= (int)tdb->header.hash_size) { - TDB_LOG((tdb, 0, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); - return ret; - } - - if (tdb->locked[list+1].count==0) { - TDB_LOG((tdb, 0, "tdb_unlock: count is 0\n")); - return ret; - } - - if (tdb->locked[list+1].count == 1) { - /* Down to last nested lock: unlock underneath */ - if (!tdb->read_only && tdb->header.rwlocks) { - ret = tdb_spinunlock(tdb, list, ltype); - } else { - ret = tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0); - } - } else { - ret = 0; - } - tdb->locked[list+1].count--; - - if (ret) - TDB_LOG((tdb, 0,"tdb_unlock: An error occurred unlocking!\n")); - return ret; -} - -/* check for an out of bounds access - if it is out of bounds then - see if the database has been expanded by someone else and expand - if necessary - note that "len" is the minimum length needed for the db -*/ -static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe) -{ - struct stat st; - if (len <= tdb->map_size) - return 0; - if (tdb->flags & TDB_INTERNAL) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, 0,"tdb_oob len %d beyond internal malloc size %d\n", - (int)len, (int)tdb->map_size)); - } - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - if (fstat(tdb->fd, &st) == -1) - return TDB_ERRCODE(TDB_ERR_IO, -1); - - if (st.st_size < (size_t)len) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n", - (int)len, (int)st.st_size)); - } - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - /* Unmap, update size, remap */ - if (tdb_munmap(tdb) == -1) - return TDB_ERRCODE(TDB_ERR_IO, -1); - tdb->map_size = st.st_size; - tdb_mmap(tdb); - return 0; -} - -/* write a lump of data at a specified offset */ -static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len) -{ - if (tdb_oob(tdb, off + len, 0) != 0) - return -1; - - if (tdb->map_ptr) - memcpy(off + (char *)tdb->map_ptr, buf, len); -#ifdef HAVE_PWRITE - else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) { -#else - else if (lseek(tdb->fd, off, SEEK_SET) != off - || write(tdb->fd, buf, len) != (ssize_t)len) { -#endif - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n", - off, len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - return 0; -} - -/* read a lump of data at a specified offset, maybe convert */ -static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv) -{ - if (tdb_oob(tdb, off + len, 0) != 0) - return -1; - - if (tdb->map_ptr) - memcpy(buf, off + (char *)tdb->map_ptr, len); -#ifdef HAVE_PREAD - else if (pread(tdb->fd, buf, len, off) != (ssize_t)len) { -#else - else if (lseek(tdb->fd, off, SEEK_SET) != off - || read(tdb->fd, buf, len) != (ssize_t)len) { -#endif - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n", - off, len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - if (cv) - convert(buf, len); - return 0; -} - -/* read a lump of data, allocating the space for it */ -static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len) -{ - char *buf; - - if (!(buf = malloc(len))) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, 0,"tdb_alloc_read malloc failed len=%d (%s)\n", - len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_OOM, buf); - } - if (tdb_read(tdb, offset, buf, len, 0) == -1) { - SAFE_FREE(buf); - return NULL; - } - return buf; -} - -/* read/write a tdb_off */ -static int ofs_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) -{ - return tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); -} -static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) -{ - tdb_off off = *d; - return tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); -} - -/* read/write a record */ -static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) -{ - if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - if (TDB_BAD_MAGIC(rec)) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - return tdb_oob(tdb, rec->next+sizeof(*rec), 0); -} -static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) -{ - struct list_struct r = *rec; - return tdb_write(tdb, offset, CONVERT(r), sizeof(r)); -} - -/* read a freelist record and check for simple errors */ -static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) -{ - if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - - if (rec->magic == TDB_MAGIC) { - /* this happens when a app is showdown while deleting a record - we should - not completely fail when this happens */ - TDB_LOG((tdb, 0,"rec_free_read non-free magic 0x%x at offset=%d - fixing\n", - rec->magic, off)); - rec->magic = TDB_FREE_MAGIC; - if (tdb_write(tdb, off, rec, sizeof(*rec)) == -1) - return -1; - } - - if (rec->magic != TDB_FREE_MAGIC) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n", - rec->magic, off)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) - return -1; - return 0; -} - -/* update a record tailer (must hold allocation lock) */ -static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset, - const struct list_struct *rec) -{ - tdb_off totalsize; - - /* Offset of tailer from record header */ - totalsize = sizeof(*rec) + rec->rec_len; - return ofs_write(tdb, offset + totalsize - sizeof(tdb_off), - &totalsize); -} - -static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset) -{ - struct list_struct rec; - tdb_off tailer_ofs, tailer; - - if (tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { - printf("ERROR: failed to read record at %u\n", offset); - return 0; - } - - printf(" rec: offset=%u next=%d rec_len=%d key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", - offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic); - - tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off); - if (ofs_read(tdb, tailer_ofs, &tailer) == -1) { - printf("ERROR: failed to read tailer at %u\n", tailer_ofs); - return rec.next; - } - - if (tailer != rec.rec_len + sizeof(rec)) { - printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", - (unsigned)tailer, (unsigned)(rec.rec_len + sizeof(rec))); - } - return rec.next; -} - -static int tdb_dump_chain(TDB_CONTEXT *tdb, int i) -{ - tdb_off rec_ptr, top; - - top = TDB_HASH_TOP(i); - - if (tdb_lock(tdb, i, F_WRLCK) != 0) - return -1; - - if (ofs_read(tdb, top, &rec_ptr) == -1) - return tdb_unlock(tdb, i, F_WRLCK); - - if (rec_ptr) - printf("hash=%d\n", i); - - while (rec_ptr) { - rec_ptr = tdb_dump_record(tdb, rec_ptr); - } - - return tdb_unlock(tdb, i, F_WRLCK); -} - -void tdb_dump_all(TDB_CONTEXT *tdb) -{ - int i; - for (i=0;iheader.hash_size;i++) { - tdb_dump_chain(tdb, i); - } - printf("freelist:\n"); - tdb_dump_chain(tdb, -1); -} - -int tdb_printfreelist(TDB_CONTEXT *tdb) -{ - int ret; - long total_free = 0; - tdb_off offset, rec_ptr; - struct list_struct rec; - - if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) - return ret; - - offset = FREELIST_TOP; - - /* read in the freelist top */ - if (ofs_read(tdb, offset, &rec_ptr) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - } - - printf("freelist top=[0x%08x]\n", rec_ptr ); - while (rec_ptr) { - if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - if (rec.magic != TDB_FREE_MAGIC) { - printf("bad magic 0x%08x in free list\n", rec.magic); - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)]\n", rec.next, rec.rec_len, rec.rec_len ); - total_free += rec.rec_len; - - /* move to the next record */ - rec_ptr = rec.next; - } - printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, - (int)total_free); - - return tdb_unlock(tdb, -1, F_WRLCK); -} - -/* Remove an element from the freelist. Must have alloc lock. */ -static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next) -{ - tdb_off last_ptr, i; - - /* read in the freelist top */ - last_ptr = FREELIST_TOP; - while (ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { - if (i == off) { - /* We've found it! */ - return ofs_write(tdb, last_ptr, &next); - } - /* Follow chain (next offset is at start of record) */ - last_ptr = i; - } - TDB_LOG((tdb, 0,"remove_from_freelist: not on list at off=%d\n", off)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); -} - -/* Add an element into the freelist. Merge adjacent records if - neccessary. */ -static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) -{ - tdb_off right, left; - - /* Allocation and tailer lock */ - if (tdb_lock(tdb, -1, F_WRLCK) != 0) - return -1; - - /* set an initial tailer, so if we fail we don't leave a bogus record */ - if (update_tailer(tdb, offset, rec) != 0) { - TDB_LOG((tdb, 0, "tdb_free: upfate_tailer failed!\n")); - goto fail; - } - - /* Look right first (I'm an Australian, dammit) */ - right = offset + sizeof(*rec) + rec->rec_len; - if (right + sizeof(*rec) <= tdb->map_size) { - struct list_struct r; - - if (tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { - TDB_LOG((tdb, 0, "tdb_free: right read failed at %u\n", right)); - goto left; - } - - /* If it's free, expand to include it. */ - if (r.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, right, r.next) == -1) { - TDB_LOG((tdb, 0, "tdb_free: right free failed at %u\n", right)); - goto left; - } - rec->rec_len += sizeof(r) + r.rec_len; - } - } - -left: - /* Look left */ - left = offset - sizeof(tdb_off); - if (left > TDB_DATA_START(tdb->header.hash_size)) { - struct list_struct l; - tdb_off leftsize; - - /* Read in tailer and jump back to header */ - if (ofs_read(tdb, left, &leftsize) == -1) { - TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left)); - goto update; - } - left = offset - leftsize; - - /* Now read in record */ - if (tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { - TDB_LOG((tdb, 0, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); - goto update; - } - - /* If it's free, expand to include it. */ - if (l.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, left, l.next) == -1) { - TDB_LOG((tdb, 0, "tdb_free: left free failed at %u\n", left)); - goto update; - } else { - offset = left; - rec->rec_len += leftsize; - } - } - } - -update: - if (update_tailer(tdb, offset, rec) == -1) { - TDB_LOG((tdb, 0, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } - - /* Now, prepend to free list */ - rec->magic = TDB_FREE_MAGIC; - - if (ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || - rec_write(tdb, offset, rec) == -1 || - ofs_write(tdb, FREELIST_TOP, &offset) == -1) { - TDB_LOG((tdb, 0, "tdb_free record write failed at offset=%d\n", offset)); - goto fail; - } - - /* And we're done. */ - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - - -/* expand a file. we prefer to use ftruncate, as that is what posix - says to use for mmap expansion */ -static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition) -{ - char buf[1024]; -#if HAVE_FTRUNCATE_EXTEND - if (ftruncate(tdb->fd, size+addition) != 0) { - TDB_LOG((tdb, 0, "expand_file ftruncate to %d failed (%s)\n", - size+addition, strerror(errno))); - return -1; - } -#else - char b = 0; - -#ifdef HAVE_PWRITE - if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) { -#else - if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 || - write(tdb->fd, &b, 1) != 1) { -#endif - TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n", - size+addition, strerror(errno))); - return -1; - } -#endif - - /* now fill the file with something. This ensures that the file isn't sparse, which would be - very bad if we ran out of disk. This must be done with write, not via mmap */ - memset(buf, 0x42, sizeof(buf)); - while (addition) { - int n = addition>sizeof(buf)?sizeof(buf):addition; -#ifdef HAVE_PWRITE - int ret = pwrite(tdb->fd, buf, n, size); -#else - int ret; - if (lseek(tdb->fd, size, SEEK_SET) != size) - return -1; - ret = write(tdb->fd, buf, n); -#endif - if (ret != n) { - TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n", - n, strerror(errno))); - return -1; - } - addition -= n; - size += n; - } - return 0; -} - - -/* expand the database at least size bytes by expanding the underlying - file and doing the mmap again if necessary */ -static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) -{ - struct list_struct rec; - tdb_off offset; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - TDB_LOG((tdb, 0, "lock failed in tdb_expand\n")); - return -1; - } - - /* must know about any previous expansions by another process */ - tdb_oob(tdb, tdb->map_size + 1, 1); - - /* always make room for at least 10 more records, and round - the database up to a multiple of TDB_PAGE_SIZE */ - size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size; - - if (!(tdb->flags & TDB_INTERNAL)) - tdb_munmap(tdb); - - /* - * We must ensure the file is unmapped before doing this - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* expand the file itself */ - if (!(tdb->flags & TDB_INTERNAL)) { - if (expand_file(tdb, tdb->map_size, size) != 0) - goto fail; - } - - tdb->map_size += size; - - if (tdb->flags & TDB_INTERNAL) - tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); - else { - /* - * We must ensure the file is remapped before adding the space - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* We're ok if the mmap fails as we'll fallback to read/write */ - tdb_mmap(tdb); - } - - /* form a new freelist record */ - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = size - sizeof(rec); - - /* link it into the free list */ - offset = tdb->map_size - size; - if (tdb_free(tdb, offset, &rec) == -1) - goto fail; - - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - -/* allocate some space from the free list. The offset returned points - to a unconnected list_struct within the database with room for at - least length bytes of total data - - 0 is returned if the space could not be allocated - */ -static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, - struct list_struct *rec) -{ - tdb_off rec_ptr, last_ptr, newrec_ptr; - struct list_struct newrec; - - memset(&newrec, '\0', sizeof(newrec)); - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) - return 0; - - /* Extra bytes required for tailer */ - length += sizeof(tdb_off); - - again: - last_ptr = FREELIST_TOP; - - /* read in the freelist top */ - if (ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) - goto fail; - - /* keep looking until we find a freelist record big enough */ - while (rec_ptr) { - if (rec_free_read(tdb, rec_ptr, rec) == -1) - goto fail; - - if (rec->rec_len >= length) { - /* found it - now possibly split it up */ - if (rec->rec_len > length + MIN_REC_SIZE) { - /* Length of left piece */ - length = TDB_ALIGN(length, TDB_ALIGNMENT); - - /* Right piece to go on free list */ - newrec.rec_len = rec->rec_len - - (sizeof(*rec) + length); - newrec_ptr = rec_ptr + sizeof(*rec) + length; - - /* And left record is shortened */ - rec->rec_len = length; - } else - newrec_ptr = 0; - - /* Remove allocated record from the free list */ - if (ofs_write(tdb, last_ptr, &rec->next) == -1) - goto fail; - - /* Update header: do this before we drop alloc - lock, otherwise tdb_free() might try to - merge with us, thinking we're free. - (Thanks Jeremy Allison). */ - rec->magic = TDB_MAGIC; - if (rec_write(tdb, rec_ptr, rec) == -1) - goto fail; - - /* Did we create new block? */ - if (newrec_ptr) { - /* Update allocated record tailer (we - shortened it). */ - if (update_tailer(tdb, rec_ptr, rec) == -1) - goto fail; - - /* Free new record */ - if (tdb_free(tdb, newrec_ptr, &newrec) == -1) - goto fail; - } - - /* all done - return the new record offset */ - tdb_unlock(tdb, -1, F_WRLCK); - return rec_ptr; - } - /* move to the next record */ - last_ptr = rec_ptr; - rec_ptr = rec->next; - } - /* we didn't find enough space. See if we can expand the - database and if we can then try again */ - if (tdb_expand(tdb, length + sizeof(*rec)) == 0) - goto again; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return 0; -} - -/* initialise a new database with a specified hash size */ -static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size) -{ - struct tdb_header *newdb; - int size, ret = -1; - - /* We make it up in memory, then write it out if not internal */ - size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off); - if (!(newdb = calloc(size, 1))) - return TDB_ERRCODE(TDB_ERR_OOM, -1); - - /* Fill in the header */ - newdb->version = TDB_VERSION; - newdb->hash_size = hash_size; - if (tdb->flags & TDB_INTERNAL) { - tdb->map_size = size; - tdb->map_ptr = (char *)newdb; - memcpy(&tdb->header, newdb, sizeof(tdb->header)); - /* Convert the `ondisk' version if asked. */ - CONVERT(*newdb); - return 0; - } - if (lseek(tdb->fd, 0, SEEK_SET) == -1) - goto fail; - - if (ftruncate(tdb->fd, 0) == -1) - goto fail; - - /* This creates an endian-converted header, as if read from disk */ - CONVERT(*newdb); - memcpy(&tdb->header, newdb, sizeof(tdb->header)); - /* Don't endian-convert the magic food! */ - memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - if (write(tdb->fd, newdb, size) != size) - ret = -1; - else - ret = tdb_create_rwlocks(tdb->fd, hash_size); - - fail: - SAFE_FREE(newdb); - return ret; -} - -/* Returns 0 on fail. On success, return offset of record, and fills - in rec */ -static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, - struct list_struct *r) -{ - tdb_off rec_ptr; - - /* read in the hash top */ - if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) { - char *k; - /* a very likely hit - read the key */ - k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r), - r->key_len); - if (!k) - return 0; - - if (memcmp(key.dptr, k, key.dsize) == 0) { - SAFE_FREE(k); - return rec_ptr; - } - SAFE_FREE(k); - } - rec_ptr = r->next; - } - return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); -} - -/* As tdb_find, but if you succeed, keep the lock */ -static tdb_off tdb_find_lock_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, int locktype, - struct list_struct *rec) -{ - u32 rec_ptr; - - if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) - return 0; - if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) - tdb_unlock(tdb, BUCKET(hash), locktype); - return rec_ptr; -} - -enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb) -{ - return tdb->ecode; -} - -static struct tdb_errname { - enum TDB_ERROR ecode; const char *estring; -} emap[] = { {TDB_SUCCESS, "Success"}, - {TDB_ERR_CORRUPT, "Corrupt database"}, - {TDB_ERR_IO, "IO Error"}, - {TDB_ERR_LOCK, "Locking error"}, - {TDB_ERR_OOM, "Out of memory"}, - {TDB_ERR_EXISTS, "Record exists"}, - {TDB_ERR_NOLOCK, "Lock exists on other keys"}, - {TDB_ERR_NOEXIST, "Record does not exist"} }; - -/* Error string for the last tdb error */ -const char *tdb_errorstr(TDB_CONTEXT *tdb) -{ - u32 i; - for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) - if (tdb->ecode == emap[i].ecode) - return emap[i].estring; - return "Invalid error code"; -} - -/* update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1. -*/ - -static int tdb_update_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf) -{ - struct list_struct rec; - tdb_off rec_ptr; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) - return -1; - - /* must be long enough key, data and tailer */ - if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off)) { - tdb->ecode = TDB_SUCCESS; /* Not really an error */ - return -1; - } - - if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, - dbuf.dptr, dbuf.dsize) == -1) - return -1; - - if (dbuf.dsize != rec.data_len) { - /* update size */ - rec.data_len = dbuf.dsize; - return rec_write(tdb, rec_ptr, &rec); - } - - return 0; -} - -/* find an entry in the database given a key */ -/* If an entry doesn't exist tdb_err will be set to - * TDB_ERR_NOEXIST. If a key has no data attached - * tdb_err will not be set. Both will return a - * zero pptr and zero dsize. - */ - -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) -{ - tdb_off rec_ptr; - struct list_struct rec; - TDB_DATA ret; - u32 hash; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) - return tdb_null; - - if (rec.data_len) - ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len); - else - ret.dptr = NULL; - ret.dsize = rec.data_len; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return ret; -} - -/* check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm -*/ -static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) -{ - struct list_struct rec; - - if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) - return 0; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return 1; -} - -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) -{ - u32 hash = tdb->hash_fn(&key); - return tdb_exists_hash(tdb, key, hash); -} - -/* record lock stops delete underneath */ -static int lock_record(TDB_CONTEXT *tdb, tdb_off off) -{ - return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0; -} -/* - Write locks override our own fcntl readlocks, so check it here. - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ - -static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off) -{ - struct tdb_traverse_lock *i; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - return -1; - return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1); -} - -/* - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ - -static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off) -{ - return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0); -} -/* fcntl locks don't stack: avoid unlocking someone else's */ -static int unlock_record(TDB_CONTEXT *tdb, tdb_off off) -{ - struct tdb_traverse_lock *i; - u32 count = 0; - - if (off == 0) - return 0; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - count++; - return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0) : 0); -} - -/* actually delete an entry in the database given the offset */ -static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec) -{ - tdb_off last_ptr, i; - struct list_struct lastrec; - - if (tdb->read_only) return -1; - - if (write_lock_record(tdb, rec_ptr) == -1) { - /* Someone traversing here: mark it as dead */ - rec->magic = TDB_DEAD_MAGIC; - return rec_write(tdb, rec_ptr, rec); - } - if (write_unlock_record(tdb, rec_ptr) != 0) - return -1; - - /* find previous record in hash chain */ - if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) - return -1; - for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) - if (rec_read(tdb, i, &lastrec) == -1) - return -1; - - /* unlink it: next ptr is at start of record. */ - if (last_ptr == 0) - last_ptr = TDB_HASH_TOP(rec->full_hash); - if (ofs_write(tdb, last_ptr, &rec->next) == -1) - return -1; - - /* recover the space */ - if (tdb_free(tdb, rec_ptr, rec) == -1) - return -1; - return 0; -} - -/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */ -static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock, - struct list_struct *rec) -{ - int want_next = (tlock->off != 0); - - /* Lock each chain from the start one. */ - for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { - if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1) - return -1; - - /* No previous record? Start at top of chain. */ - if (!tlock->off) { - if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash), - &tlock->off) == -1) - goto fail; - } else { - /* Otherwise unlock the previous record. */ - if (unlock_record(tdb, tlock->off) != 0) - goto fail; - } - - if (want_next) { - /* We have offset of old record: grab next */ - if (rec_read(tdb, tlock->off, rec) == -1) - goto fail; - tlock->off = rec->next; - } - - /* Iterate through chain */ - while( tlock->off) { - tdb_off current; - if (rec_read(tdb, tlock->off, rec) == -1) - goto fail; - if (!TDB_DEAD(rec)) { - /* Woohoo: we found one! */ - if (lock_record(tdb, tlock->off) != 0) - goto fail; - return tlock->off; - } - /* Try to clean dead ones from old traverses */ - current = tlock->off; - tlock->off = rec->next; - if (!tdb->read_only && - do_delete(tdb, current, rec) != 0) - goto fail; - } - tdb_unlock(tdb, tlock->hash, F_WRLCK); - want_next = 0; - } - /* We finished iteration without finding anything */ - return TDB_ERRCODE(TDB_SUCCESS, 0); - - fail: - tlock->off = 0; - if (tdb_unlock(tdb, tlock->hash, F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_next_lock: On error unlock failed!\n")); - return -1; -} - -/* traverse the entire database - calling fn(tdb, key, data) on each element. - return -1 on error or the record count traversed - if fn is NULL then it is not called - a non-zero return value from fn() indicates that the traversal should stop - */ -int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *private) -{ - TDB_DATA key, dbuf; - struct list_struct rec; - struct tdb_traverse_lock tl = { NULL, 0, 0 }; - int ret, count = 0; - - /* This was in the initializaton, above, but the IRIX compiler - * did not like it. crh - */ - tl.next = tdb->travlocks.next; - - /* fcntl locks don't stack: beware traverse inside traverse */ - tdb->travlocks.next = &tl; - - /* tdb_next_lock places locks on the record returned, and its chain */ - while ((ret = tdb_next_lock(tdb, &tl, &rec)) > 0) { - count++; - /* now read the full record */ - key.dptr = tdb_alloc_read(tdb, tl.off + sizeof(rec), - rec.key_len + rec.data_len); - if (!key.dptr) { - ret = -1; - if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) - goto out; - if (unlock_record(tdb, tl.off) != 0) - TDB_LOG((tdb, 0, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); - goto out; - } - key.dsize = rec.key_len; - dbuf.dptr = key.dptr + rec.key_len; - dbuf.dsize = rec.data_len; - - /* Drop chain lock, call out */ - if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) { - ret = -1; - goto out; - } - if (fn && fn(tdb, key, dbuf, private)) { - /* They want us to terminate traversal */ - ret = count; - if (unlock_record(tdb, tl.off) != 0) { - TDB_LOG((tdb, 0, "tdb_traverse: unlock_record failed!\n"));; - ret = -1; - } - tdb->travlocks.next = tl.next; - SAFE_FREE(key.dptr); - return count; - } - SAFE_FREE(key.dptr); - } -out: - tdb->travlocks.next = tl.next; - if (ret < 0) - return -1; - else - return count; -} - -/* find the first entry in the database and return its key */ -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb) -{ - TDB_DATA key; - struct list_struct rec; - - /* release any old lock */ - if (unlock_record(tdb, tdb->travlocks.off) != 0) - return tdb_null; - tdb->travlocks.off = tdb->travlocks.hash = 0; - - if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) - return tdb_null; - /* now read the key */ - key.dsize = rec.key_len; - key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); - if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_firstkey: error occurred while tdb_unlocking!\n")); - return key; -} - -/* find the next entry in the database, returning its key */ -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey) -{ - u32 oldhash; - TDB_DATA key = tdb_null; - struct list_struct rec; - char *k = NULL; - - /* Is locked key the old key? If so, traverse will be reliable. */ - if (tdb->travlocks.off) { - if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK)) - return tdb_null; - if (rec_read(tdb, tdb->travlocks.off, &rec) == -1 - || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), - rec.key_len)) - || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { - /* No, it wasn't: unlock it and start from scratch */ - if (unlock_record(tdb, tdb->travlocks.off) != 0) - return tdb_null; - if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) - return tdb_null; - tdb->travlocks.off = 0; - } - - SAFE_FREE(k); - } - - if (!tdb->travlocks.off) { - /* No previous element: do normal find, and lock record */ - tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), F_WRLCK, &rec); - if (!tdb->travlocks.off) - return tdb_null; - tdb->travlocks.hash = BUCKET(rec.full_hash); - if (lock_record(tdb, tdb->travlocks.off) != 0) { - TDB_LOG((tdb, 0, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); - return tdb_null; - } - } - oldhash = tdb->travlocks.hash; - - /* Grab next record: locks chain and returned record, - unlocks old record */ - if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) { - key.dsize = rec.key_len; - key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), - key.dsize); - /* Unlock the chain of this new record */ - if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - } - /* Unlock the chain of old record */ - if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - return key; -} - -/* delete an entry in the database given a key */ -static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) -{ - tdb_off rec_ptr; - struct list_struct rec; - int ret; - - if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec))) - return -1; - ret = do_delete(tdb, rec_ptr, &rec); - if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_delete: WARNING tdb_unlock failed!\n")); - return ret; -} - -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) -{ - u32 hash = tdb->hash_fn(&key); - return tdb_delete_hash(tdb, key, hash); -} - -/* store an element in the database, replacing any existing element - with the same key - - return 0 on success, -1 on failure -*/ -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) -{ - struct list_struct rec; - u32 hash; - tdb_off rec_ptr; - char *p = NULL; - int ret = 0; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - /* check for it existing, on insert. */ - if (flag == TDB_INSERT) { - if (tdb_exists_hash(tdb, key, hash)) { - tdb->ecode = TDB_ERR_EXISTS; - goto fail; - } - } else { - /* first try in-place update, on modify or replace. */ - if (tdb_update_hash(tdb, key, hash, dbuf) == 0) - goto out; - if (tdb->ecode == TDB_ERR_NOEXIST && - flag == TDB_MODIFY) { - /* if the record doesn't exist and we are in TDB_MODIFY mode then - we should fail the store */ - goto fail; - } - } - /* reset the error code potentially set by the tdb_update() */ - tdb->ecode = TDB_SUCCESS; - - /* delete any existing record - if it doesn't exist we don't - care. Doing this first reduces fragmentation, and avoids - coalescing with `allocated' block before it's updated. */ - if (flag != TDB_INSERT) - tdb_delete_hash(tdb, key, hash); - - /* Copy key+value *before* allocating free space in case malloc - fails and we are left with a dead spot in the tdb. */ - - if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - memcpy(p, key.dptr, key.dsize); - if (dbuf.dsize) - memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); - - /* we have to allocate some space */ - if (!(rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec))) - goto fail; - - /* Read hash top into next ptr */ - if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) - goto fail; - - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - - /* write out and point the top of the hash chain at it */ - if (rec_write(tdb, rec_ptr, &rec) == -1 - || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 - || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { - /* Need to tdb_unallocate() here */ - goto fail; - } - out: - SAFE_FREE(p); - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return ret; -fail: - ret = -1; - goto out; -} - -/* Attempt to append data to an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1. Record must be locked before calling. -*/ -static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA new_dbuf) -{ - struct list_struct rec; - tdb_off rec_ptr; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) - return -1; - - /* Append of 0 is always ok. */ - if (new_dbuf.dsize == 0) - return 0; - - /* must be long enough for key, old data + new data and tailer */ - if (rec.rec_len < key.dsize + rec.data_len + new_dbuf.dsize + sizeof(tdb_off)) { - /* No room. */ - tdb->ecode = TDB_SUCCESS; /* Not really an error */ - return -1; - } - - if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len + rec.data_len, - new_dbuf.dptr, new_dbuf.dsize) == -1) - return -1; - - /* update size */ - rec.data_len += new_dbuf.dsize; - return rec_write(tdb, rec_ptr, &rec); -} - -/* Append to an entry. Create if not exist. */ - -int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) -{ - struct list_struct rec; - u32 hash; - tdb_off rec_ptr; - char *p = NULL; - int ret = 0; - size_t new_data_size = 0; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - /* first try in-place. */ - if (tdb_append_inplace(tdb, key, hash, new_dbuf) == 0) - goto out; - - /* reset the error code potentially set by the tdb_append_inplace() */ - tdb->ecode = TDB_SUCCESS; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { - if (tdb->ecode != TDB_ERR_NOEXIST) - goto fail; - - /* Not found - create. */ - - ret = tdb_store(tdb, key, new_dbuf, TDB_INSERT); - goto out; - } - - new_data_size = rec.data_len + new_dbuf.dsize; - - /* Copy key+old_value+value *before* allocating free space in case malloc - fails and we are left with a dead spot in the tdb. */ - - if (!(p = (char *)malloc(key.dsize + new_data_size))) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - /* Copy the key in place. */ - memcpy(p, key.dptr, key.dsize); - - /* Now read the old data into place. */ - if (rec.data_len && - tdb_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, p + key.dsize, rec.data_len, 0) == -1) - goto fail; - - /* Finally append the new data. */ - if (new_dbuf.dsize) - memcpy(p+key.dsize+rec.data_len, new_dbuf.dptr, new_dbuf.dsize); - - /* delete any existing record - if it doesn't exist we don't - care. Doing this first reduces fragmentation, and avoids - coalescing with `allocated' block before it's updated. */ - - tdb_delete_hash(tdb, key, hash); - - if (!(rec_ptr = tdb_allocate(tdb, key.dsize + new_data_size, &rec))) - goto fail; - - /* Read hash top into next ptr */ - if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) - goto fail; - - rec.key_len = key.dsize; - rec.data_len = new_data_size; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - - /* write out and point the top of the hash chain at it */ - if (rec_write(tdb, rec_ptr, &rec) == -1 - || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+new_data_size)==-1 - || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { - /* Need to tdb_unallocate() here */ - goto fail; - } - - out: - SAFE_FREE(p); - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return ret; - -fail: - ret = -1; - goto out; -} - -static int tdb_already_open(dev_t device, - ino_t ino) -{ - TDB_CONTEXT *i; - - for (i = tdbs; i; i = i->next) { - if (i->device == device && i->inode == ino) { - return 1; - } - } - - return 0; -} - -/* This is based on the hash algorithm from gdbm */ -static u32 default_tdb_hash(TDB_DATA *key) -{ - u32 value; /* Used to compute the hash value. */ - u32 i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) - value = (value + (key->dptr[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - -/* open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the - database file. A flags value of O_WRONLY is invalid. The hash size - is advisory, use zero for a default value. - - Return is NULL on error, in which case errno is also set. Don't - try to call tdb_error or tdb_errname, just do strerror(errno). - - @param name may be NULL for internal databases. */ -TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); -} - - -TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_fn, - tdb_hash_func hash_fn) -{ - TDB_CONTEXT *tdb; - struct stat st; - int rev = 0, locked = 0; - unsigned char *vp; - u32 vertest; - - if (!(tdb = calloc(1, sizeof *tdb))) { - /* Can't log this */ - errno = ENOMEM; - goto fail; - } - tdb->fd = -1; - tdb->name = NULL; - tdb->map_ptr = NULL; - tdb->flags = tdb_flags; - tdb->open_flags = open_flags; - tdb->log_fn = log_fn; - tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash; - - if ((open_flags & O_ACCMODE) == O_WRONLY) { - TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n", - name)); - errno = EINVAL; - goto fail; - } - - if (hash_size == 0) - hash_size = DEFAULT_HASH_SIZE; - if ((open_flags & O_ACCMODE) == O_RDONLY) { - tdb->read_only = 1; - /* read only databases don't do locking or clear if first */ - tdb->flags |= TDB_NOLOCK; - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - } - - /* internal databases don't mmap or lock, and start off cleared */ - if (tdb->flags & TDB_INTERNAL) { - tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - if (tdb_new_database(tdb, hash_size) != 0) { - TDB_LOG((tdb, 0, "tdb_open_ex: tdb_new_database failed!")); - goto fail; - } - goto internal; - } - - if ((tdb->fd = open(name, open_flags, mode)) == -1) { - TDB_LOG((tdb, 5, "tdb_open_ex: could not open file %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by open(2) */ - } - - /* ensure there is only one process initialising at once */ - if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) { - TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by tdb_brlock */ - } - - /* we need to zero database if we are the only one with it open */ - if ((tdb_flags & TDB_CLEAR_IF_FIRST) && - (locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))) { - open_flags |= O_CREAT; - if (ftruncate(tdb->fd, 0) == -1) { - TDB_LOG((tdb, 0, "tdb_open_ex: " - "failed to truncate %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by ftruncate */ - } - } - - if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) - || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0 - || (tdb->header.version != TDB_VERSION - && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) { - /* its not a valid database - possibly initialise it */ - if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { - errno = EIO; /* ie bad format or something */ - goto fail; - } - rev = (tdb->flags & TDB_CONVERT); - } - vp = (unsigned char *)&tdb->header.version; - vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) | - (((u32)vp[2]) << 8) | (u32)vp[3]; - tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; - if (!rev) - tdb->flags &= ~TDB_CONVERT; - else { - tdb->flags |= TDB_CONVERT; - convert(&tdb->header, sizeof(tdb->header)); - } - if (fstat(tdb->fd, &st) == -1) - goto fail; - - /* Is it already in the open list? If so, fail. */ - if (tdb_already_open(st.st_dev, st.st_ino)) { - TDB_LOG((tdb, 2, "tdb_open_ex: " - "%s (%d,%d) is already open in this process\n", - name, (int)st.st_dev, (int)st.st_ino)); - errno = EBUSY; - goto fail; - } - - if (!(tdb->name = (char *)strdup(name))) { - errno = ENOMEM; - goto fail; - } - - tdb->map_size = st.st_size; - tdb->device = st.st_dev; - tdb->inode = st.st_ino; - tdb->locked = calloc(tdb->header.hash_size+1, sizeof(tdb->locked[0])); - if (!tdb->locked) { - TDB_LOG((tdb, 2, "tdb_open_ex: " - "failed to allocate lock structure for %s\n", - name)); - errno = ENOMEM; - goto fail; - } - tdb_mmap(tdb); - if (locked) { - if (!tdb->read_only) - if (tdb_clear_spinlocks(tdb) != 0) { - TDB_LOG((tdb, 0, "tdb_open_ex: " - "failed to clear spinlock\n")); - goto fail; - } - if (tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) { - TDB_LOG((tdb, 0, "tdb_open_ex: " - "failed to take ACTIVE_LOCK on %s: %s\n", - name, strerror(errno))); - goto fail; - } - - } - - /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if - we didn't get the initial exclusive lock as we need to let all other - users know we're using it. */ - - if (tdb_flags & TDB_CLEAR_IF_FIRST) { - /* leave this lock in place to indicate it's in use */ - if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) - goto fail; - } - - - internal: - /* Internal (memory-only) databases skip all the code above to - * do with disk files, and resume here by releasing their - * global lock and hooking into the active list. */ - if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1) - goto fail; - tdb->next = tdbs; - tdbs = tdb; - return tdb; - - fail: - { int save_errno = errno; - - if (!tdb) - return NULL; - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - SAFE_FREE(tdb->name); - if (tdb->fd != -1) - if (close(tdb->fd) != 0) - TDB_LOG((tdb, 5, "tdb_open_ex: failed to close tdb->fd on error!\n")); - SAFE_FREE(tdb->locked); - SAFE_FREE(tdb); - errno = save_errno; - return NULL; - } -} - -/** - * Close a database. - * - * @returns -1 for error; 0 for success. - **/ -int tdb_close(TDB_CONTEXT *tdb) -{ - TDB_CONTEXT **i; - int ret = 0; - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - SAFE_FREE(tdb->name); - if (tdb->fd != -1) - ret = close(tdb->fd); - SAFE_FREE(tdb->locked); - - /* Remove from contexts list */ - for (i = &tdbs; *i; i = &(*i)->next) { - if (*i == tdb) { - *i = tdb->next; - break; - } - } - - memset(tdb, 0, sizeof(*tdb)); - SAFE_FREE(tdb); - - return ret; -} - -/* lock/unlock entire database */ -int tdb_lockall(TDB_CONTEXT *tdb) -{ - u32 i; - - /* There are no locks on read-only dbs */ - if (tdb->read_only) - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - for (i = 0; i < tdb->header.hash_size; i++) - if (tdb_lock(tdb, i, F_WRLCK)) - break; - - /* If error, release locks we have... */ - if (i < tdb->header.hash_size) { - u32 j; - - for ( j = 0; j < i; j++) - tdb_unlock(tdb, j, F_WRLCK); - return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); - } - - return 0; -} -void tdb_unlockall(TDB_CONTEXT *tdb) -{ - u32 i; - for (i=0; i < tdb->header.hash_size; i++) - tdb_unlock(tdb, i, F_WRLCK); -} - -/* lock/unlock one hash chain. This is meant to be used to reduce - contention - it cannot guarantee how many records will be locked */ -int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); -} - -int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); -} - -int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); -} - -int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); -} - - -/* register a loging function */ -void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)) -{ - tdb->log_fn = fn; -} - -/* reopen a tdb - this can be used after a fork to ensure that we have an independent - seek pointer from our parent and to re-establish locks */ -int tdb_reopen(TDB_CONTEXT *tdb) -{ - struct stat st; - - if (tdb->flags & TDB_INTERNAL) - return 0; /* Nothing to do. */ - if (tdb_munmap(tdb) != 0) { - TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); - goto fail; - } - if (close(tdb->fd) != 0) - TDB_LOG((tdb, 0, "tdb_reopen: WARNING closing tdb->fd failed!\n")); - tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); - if (tdb->fd == -1) { - TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno))); - goto fail; - } - if (fstat(tdb->fd, &st) != 0) { - TDB_LOG((tdb, 0, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); - goto fail; - } - if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { - TDB_LOG((tdb, 0, "tdb_reopen: file dev/inode has changed!\n")); - goto fail; - } - tdb_mmap(tdb); - if ((tdb->flags & TDB_CLEAR_IF_FIRST) && (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) { - TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n")); - goto fail; - } - - return 0; - -fail: - tdb_close(tdb); - return -1; -} - -/* reopen all tdb's */ -int tdb_reopen_all(void) -{ - TDB_CONTEXT *tdb; - - for (tdb=tdbs; tdb; tdb = tdb->next) { - /* Ensure no clear-if-first. */ - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - if (tdb_reopen(tdb) != 0) - return -1; - } - - return 0; -} diff --git a/src/netif/ppp/tdb.h b/src/netif/ppp/tdb.h deleted file mode 100644 index 153b6e99..00000000 --- a/src/netif/ppp/tdb.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef __TDB_H__ -#define __TDB_H__ - -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2004 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef PRINTF_ATTRIBUTE -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#if (__GNUC__ >= 3) -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -/* flags to tdb_store() */ -#define TDB_REPLACE 1 -#define TDB_INSERT 2 -#define TDB_MODIFY 3 - -/* flags for tdb_open() */ -#define TDB_DEFAULT 0 /* just a readability place holder */ -#define TDB_CLEAR_IF_FIRST 1 -#define TDB_INTERNAL 2 /* don't store on disk */ -#define TDB_NOLOCK 4 /* don't do any locking */ -#define TDB_NOMMAP 8 /* don't use mmap */ -#define TDB_CONVERT 16 /* convert endian (internal use) */ -#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ - -#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) - -/* error codes */ -enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, - TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, - TDB_ERR_NOEXIST}; - -#ifndef u32 -#define u32 unsigned -#endif - -typedef struct { - char *dptr; - size_t dsize; -} TDB_DATA; - -typedef u32 tdb_len; -typedef u32 tdb_off; - -/* this is stored at the front of every database */ -struct tdb_header { - char magic_food[32]; /* for /etc/magic */ - u32 version; /* version of the code */ - u32 hash_size; /* number of hash entries */ - tdb_off rwlocks; - tdb_off reserved[31]; -}; - -struct tdb_lock_type { - u32 count; - u32 ltype; -}; - -struct tdb_traverse_lock { - struct tdb_traverse_lock *next; - u32 off; - u32 hash; -}; - -/* this is the context structure that is returned from a db open */ -typedef struct tdb_context { - char *name; /* the name of the database */ - void *map_ptr; /* where it is currently mapped */ - int fd; /* open file descriptor for the database */ - tdb_len map_size; /* how much space has been mapped */ - int read_only; /* opened read-only */ - struct tdb_lock_type *locked; /* array of chain locks */ - enum TDB_ERROR ecode; /* error code for last tdb error */ - struct tdb_header header; /* a cached copy of the header */ - u32 flags; /* the flags passed to tdb_open */ - struct tdb_traverse_lock travlocks; /* current traversal locks */ - struct tdb_context *next; /* all tdbs to avoid multiple opens */ - dev_t device; /* uniquely identifies this tdb */ - ino_t inode; /* uniquely identifies this tdb */ - void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...) PRINTF_ATTRIBUTE(3,4); /* logging function */ - u32 (*hash_fn)(TDB_DATA *key); - int open_flags; /* flags used in the open - needed by reopen */ -} TDB_CONTEXT; - -typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *); -typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...); -typedef u32 (*tdb_hash_func)(TDB_DATA *key); - -TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode); -TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_fn, - tdb_hash_func hash_fn); - -int tdb_reopen(TDB_CONTEXT *tdb); -int tdb_reopen_all(void); -void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func); -enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); -const char *tdb_errorstr(TDB_CONTEXT *tdb); -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); -int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf); -int tdb_close(TDB_CONTEXT *tdb); -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *); -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]); -void tdb_unlockkeys(TDB_CONTEXT *tdb); -int tdb_lockall(TDB_CONTEXT *tdb); -void tdb_unlockall(TDB_CONTEXT *tdb); - -/* Low level locking functions: use with care */ -void tdb_set_lock_alarm(sig_atomic_t *palarm); -int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); - -/* Debug functions. Not used in production. */ -void tdb_dump_all(TDB_CONTEXT *tdb); -int tdb_printfreelist(TDB_CONTEXT *tdb); - -extern TDB_DATA tdb_null; - -#ifdef __cplusplus -} -#endif - -#endif /* tdb.h */ From 6773326d9678c0ee6087c561135aba9b26e3fce5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 17 May 2012 23:41:39 +0200 Subject: [PATCH 018/320] replaced MIN to LWIP_MIN --- src/netif/ppp/auth.c | 2 +- src/netif/ppp/demand.c | 3 ++- src/netif/ppp/lcp.c | 3 ++- src/netif/ppp/multilink.c | 2 +- src/netif/ppp/pppd.h | 7 ------- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 45801642..39950350 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1163,7 +1163,7 @@ check_idle(arg) if (idle_time_hook != 0) { tlim = idle_time_hook(&idle); } else { - itime = MIN(idle.xmit_idle, idle.recv_idle); + itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); tlim = idle_time_limit - itime; } if (tlim <= 0) { diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index c654d34d..7016c5a6 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -54,6 +54,7 @@ #endif #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "ipcp.h" #include "lcp.h" @@ -100,7 +101,7 @@ demand_conf() flush_flag = 0; fcs = PPP_INITFCS; - netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU)); + netif_set_mtu(0, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU)); if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0 || ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0) fatal("Couldn't set up demand-dialled PPP interface: %m"); diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 8ee2db74..89250e01 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -53,6 +53,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "lcp.h" #include "chap-new.h" @@ -1930,7 +1931,7 @@ lcp_up(f) #ifdef HAVE_MULTILINK if (!(multilink && go->neg_mrru && ho->neg_mrru)) #endif /* HAVE_MULTILINK */ - netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru)); + netif_set_mtu(f->unit, LWIP_MIN(LWIP_MIN(mtu, mru), ao->mru)); ppp_send_config(f->unit, mtu, (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), ho->neg_pcompression, ho->neg_accompression); diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index a8687b43..47a34688 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -195,7 +195,7 @@ mp_join_bundle() * For demand mode, we only need to configure the bundle * and attach the link. */ - mtu = MIN(ho->mrru, ao->mru); + mtu = LWIP_MIN(ho->mrru, ao->mru); if (demand) { cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); netif_set_mtu(0, mtu); diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index da228b35..add22efe 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -896,13 +896,6 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */ #endif /* SIGTYPE */ -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a): (b)) -#endif -#ifndef MAX -#define MAX(a, b) ((a) > (b)? (a): (b)) -#endif - #ifndef offsetof #define offsetof(type, member) ((size_t) &((type *)0)->member) #endif From adf2b2bf033d61f860fc599f40de528145a260c2 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 19 May 2012 22:59:08 +0200 Subject: [PATCH 019/320] don't compile wkmodulus[] if SRP is not used --- src/netif/ppp/eap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 76404281..b082284a 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -141,6 +141,7 @@ struct protent eap_protent = { NULL /* say whether to bring up link for this pkt */ }; +#ifdef USE_SRP /* * A well-known 2048 bit modulus. */ @@ -178,6 +179,7 @@ static const u_char wkmodulus[] = { 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 }; +#endif /* Local forward declarations. */ static void eap_server_timeout __P((void *arg)); From aa2656cb9e8f6cdd7921fc36d5e00060065058a4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 01:44:22 +0200 Subject: [PATCH 020/320] Replaced md4/md5/sha1 implementations to PolarSSL ones Using cleaned PolarSSL md4/md5/sha1 implementations, without changing the API, so that lwIP users already doing SSL or using PolarSSL don't need to compile md4/md5/sha1 twice. Added to that, we need a DES library for MSCHAP, and PolarSSL provided a DES support. And finally, PolarSSL is outstanding :-) --- src/netif/ppp/chap-md5.c | 26 +-- src/netif/ppp/chap_ms.c | 97 +++++----- src/netif/ppp/eap.c | 26 +-- src/netif/ppp/magic.c | 24 +-- src/netif/ppp/md4.c | 301 ------------------------------- src/netif/ppp/md4.h | 64 ------- src/netif/ppp/md5.c | 309 -------------------------------- src/netif/ppp/md5.h | 65 ------- src/netif/ppp/polarssl/md4.c | 271 ++++++++++++++++++++++++++++ src/netif/ppp/polarssl/md4.h | 82 +++++++++ src/netif/ppp/polarssl/md5.c | 290 ++++++++++++++++++++++++++++++ src/netif/ppp/polarssl/md5.h | 82 +++++++++ src/netif/ppp/polarssl/sha1.c | 325 ++++++++++++++++++++++++++++++++++ src/netif/ppp/polarssl/sha1.h | 82 +++++++++ src/netif/ppp/sha1.c | 172 ------------------ src/netif/ppp/sha1.h | 31 ---- 16 files changed, 1219 insertions(+), 1028 deletions(-) delete mode 100644 src/netif/ppp/md4.c delete mode 100644 src/netif/ppp/md4.h delete mode 100644 src/netif/ppp/md5.c delete mode 100644 src/netif/ppp/md5.h create mode 100644 src/netif/ppp/polarssl/md4.c create mode 100644 src/netif/ppp/polarssl/md4.h create mode 100644 src/netif/ppp/polarssl/md5.c create mode 100644 src/netif/ppp/polarssl/md5.h create mode 100644 src/netif/ppp/polarssl/sha1.c create mode 100644 src/netif/ppp/polarssl/sha1.h delete mode 100644 src/netif/ppp/sha1.c delete mode 100644 src/netif/ppp/sha1.h diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 513fe430..dec34cfd 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -38,7 +38,7 @@ #include "chap-new.h" #include "chap-md5.h" #include "magic.h" -#include "md5.h" +#include "polarssl/md5.h" #define MD5_HASH_SIZE 16 #define MD5_MIN_CHALLENGE 16 @@ -61,7 +61,7 @@ chap_md5_verify_response(int id, char *name, unsigned char *challenge, unsigned char *response, char *message, int message_space) { - MD5_CTX ctx; + md5_context ctx; unsigned char idbyte = id; unsigned char hash[MD5_HASH_SIZE]; int challenge_len, response_len; @@ -70,11 +70,11 @@ chap_md5_verify_response(int id, char *name, response_len = *response++; if (response_len == MD5_HASH_SIZE) { /* Generate hash of ID, secret, challenge */ - MD5_Init(&ctx); - MD5_Update(&ctx, &idbyte, 1); - MD5_Update(&ctx, secret, secret_len); - MD5_Update(&ctx, challenge, challenge_len); - MD5_Final(hash, &ctx); + md5_starts(&ctx); + md5_update(&ctx, &idbyte, 1); + md5_update(&ctx, secret, secret_len); + md5_update(&ctx, challenge, challenge_len); + md5_finish(&ctx, hash); /* Test if our hash matches the peer's response */ if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { @@ -91,15 +91,15 @@ chap_md5_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { - MD5_CTX ctx; + md5_context ctx; unsigned char idbyte = id; int challenge_len = *challenge++; - MD5_Init(&ctx); - MD5_Update(&ctx, &idbyte, 1); - MD5_Update(&ctx, (u_char *)secret, secret_len); - MD5_Update(&ctx, challenge, challenge_len); - MD5_Final(&response[1], &ctx); + md5_starts(&ctx); + md5_update(&ctx, &idbyte, 1); + md5_update(&ctx, (u_char *)secret, secret_len); + md5_update(&ctx, challenge, challenge_len); + md5_finish(&ctx, &response[1]); response[0] = MD5_HASH_SIZE; } diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 0d3b5347..9efa2066 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -91,13 +91,14 @@ #include "pppd.h" #include "chap-new.h" #include "chap_ms.h" -#include "md4.h" -#include "sha1.h" +#include "polarssl/md4.h" +#include "polarssl/sha1.h" #include "pppcrypt.h" #include "magic.h" static const char rcsid[] = RCSID; +#define SHA1_SIGNATURE_SIZE 20 static void ascii2unicode __P((char[], int, u_char[])); static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); @@ -472,7 +473,7 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, char *username, u_char Challenge[8]) { - SHA1_CTX sha1Context; + sha1_context sha1Context; u_char sha1Hash[SHA1_SIGNATURE_SIZE]; char *user; @@ -482,11 +483,11 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, else user = username; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PeerChallenge, 16); - SHA1_Update(&sha1Context, rchallenge, 16); - SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user)); - SHA1_Final(sha1Hash, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PeerChallenge, 16); + sha1_update(&sha1Context, rchallenge, 16); + sha1_update(&sha1Context, (unsigned char *)user, strlen(user)); + sha1_finish(&sha1Context, sha1Hash); BCOPY(sha1Hash, Challenge, 8); } @@ -517,17 +518,17 @@ NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) #else int mdlen = secret_len * 8; #endif - MD4_CTX md4Context; + md4_context md4Context; - MD4Init(&md4Context); + md4_starts(&md4Context); /* MD4Update can take at most 64 bytes at a time */ while (mdlen > 512) { - MD4Update(&md4Context, secret, 512); + md4_update(&md4Context, secret, 512); secret += 64; mdlen -= 512; } - MD4Update(&md4Context, secret, mdlen); - MD4Final(hash, &md4Context); + md4_update(&md4Context, secret, mdlen); + md4_finish(&md4Context, hash); } @@ -608,23 +609,23 @@ GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], 0x6E }; int i; - SHA1_CTX sha1Context; + sha1_context sha1Context; u_char Digest[SHA1_SIGNATURE_SIZE]; u_char Challenge[8]; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, NTResponse, 24); - SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, NTResponse, 24); + sha1_update(&sha1Context, Magic1, sizeof(Magic1)); + sha1_finish(&sha1Context, Digest); ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, Digest, sizeof(Digest)); - SHA1_Update(&sha1Context, Challenge, sizeof(Challenge)); - SHA1_Update(&sha1Context, Magic2, sizeof(Magic2)); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, Digest, sizeof(Digest)); + sha1_update(&sha1Context, Challenge, sizeof(Challenge)); + sha1_update(&sha1Context, Magic2, sizeof(Magic2)); + sha1_finish(&sha1Context, Digest); /* Convert to ASCII hex string. */ for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) @@ -662,14 +663,14 @@ GenerateAuthenticatorResponsePlain void mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) { - SHA1_CTX sha1Context; + sha1_context sha1Context; u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, rchallenge, 8); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, rchallenge, 8); + sha1_finish(&sha1Context, Digest); /* Same key in both directions. */ BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); @@ -706,7 +707,7 @@ void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], int IsServer) { - SHA1_CTX sha1Context; + sha1_context sha1Context; u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ @@ -752,11 +753,11 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], 0x6b, 0x65, 0x79, 0x2e }; u_char *s; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, NTResponse, 24); - SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); - SHA1_Final(MasterKey, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, NTResponse, 24); + sha1_update(&sha1Context, Magic1, sizeof(Magic1)); + sha1_finish(&sha1Context, MasterKey); /* * generate send key @@ -765,12 +766,12 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], s = Magic3; else s = Magic2; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, MasterKey, 16); - SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); - SHA1_Update(&sha1Context, s, 84); - SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, MasterKey, 16); + sha1_update(&sha1Context, SHApad1, sizeof(SHApad1)); + sha1_update(&sha1Context, s, 84); + sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); + sha1_finish(&sha1Context, Digest); BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); @@ -781,12 +782,12 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], s = Magic2; else s = Magic3; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, MasterKey, 16); - SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); - SHA1_Update(&sha1Context, s, 84); - SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, MasterKey, 16); + sha1_update(&sha1Context, SHApad1, sizeof(SHApad1)); + sha1_update(&sha1Context, s, 84); + sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); + sha1_finish(&sha1Context, Digest); BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index b082284a..b545cbd0 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -64,7 +64,7 @@ #include "pppd.h" #include "pathnames.h" -#include "md5.h" +#include "polarssl/md5.h" #include "eap.h" #ifdef USE_SRP @@ -1322,7 +1322,7 @@ int len; int secret_len; char secret[MAXWORDLEN]; char rhostname[256]; - MD5_CTX mdContext; + md5_context mdContext; u_char hash[MD5_SIGNATURE_SIZE]; #ifdef USE_SRP struct t_client *tc; @@ -1449,13 +1449,13 @@ int len; eap_send_nak(esp, id, EAPT_SRP); break; } - MD5_Init(&mdContext); + md5_starts(&mdContext); typenum = id; - MD5_Update(&mdContext, &typenum, 1); - MD5_Update(&mdContext, (u_char *)secret, secret_len); + md5_update(&mdContext, &typenum, 1); + md5_update(&mdContext, (u_char *)secret, secret_len); BZERO(secret, sizeof (secret)); - MD5_Update(&mdContext, inp, vallen); - MD5_Final(hash, &mdContext); + md5_update(&mdContext, inp, vallen); + md5_finish(&mdContext, hash); eap_chap_response(esp, id, hash, esp->es_client.ea_name, esp->es_client.ea_namelen); break; @@ -1732,7 +1732,7 @@ int len; int secret_len; char secret[MAXSECRETLEN]; char rhostname[256]; - MD5_CTX mdContext; + md5_context mdContext; u_char hash[MD5_SIGNATURE_SIZE]; #ifdef USE_SRP struct t_server *ts; @@ -1875,12 +1875,12 @@ int len; eap_send_failure(esp); break; } - MD5_Init(&mdContext); - MD5_Update(&mdContext, &esp->es_server.ea_id, 1); - MD5_Update(&mdContext, (u_char *)secret, secret_len); + md5_starts(&mdContext); + md5_update(&mdContext, &esp->es_server.ea_id, 1); + md5_update(&mdContext, (u_char *)secret, secret_len); BZERO(secret, sizeof (secret)); - MD5_Update(&mdContext, esp->es_challenge, esp->es_challen); - MD5_Final(hash, &mdContext); + md5_update(&mdContext, esp->es_challenge, esp->es_challen); + md5_finish(&mdContext, hash); if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { eap_send_failure(esp); break; diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 2360ecc8..de65a96e 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -76,7 +76,7 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "md5.h" +#include "polarssl/md5.h" #include "magic.h" #include "pppd.h" #include "pppmy.h" @@ -108,13 +108,13 @@ static long magic_randcount = 0; /* Pseudo-random incrementer */ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 */ void magic_churnrand(char *rand_data, u32_t rand_len) { - MD5_CTX md5; + md5_context md5; /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", rand_len, rand_data)); */ - MD5_Init(&md5); - MD5_Update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + md5_starts(&md5); + md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); if (rand_data) { - MD5_Update(&md5, (u_char *)rand_data, rand_len); + md5_update(&md5, (u_char *)rand_data, rand_len); } else { struct { /* INCLUDE fields for any system sources of randomness */ @@ -122,9 +122,9 @@ void magic_churnrand(char *rand_data, u32_t rand_len) { } sys_data; /* Load sys_data fields here. */ - MD5_Update(&md5, (u_char *)&sys_data, sizeof(sys_data)); + md5_update(&md5, (u_char *)&sys_data, sizeof(sys_data)); } - MD5_Final((u_char *)magic_randpool, &md5); + md5_finish(&md5, (u_char *)magic_randpool); /* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ } @@ -161,16 +161,16 @@ void magic_randomize(void) { * it was documented. */ void random_bytes(unsigned char *buf, u32_t buf_len) { - MD5_CTX md5; + md5_context md5; u_char tmp[16]; u32_t n; while (buf_len > 0) { n = LWIP_MIN(buf_len, MAGIC_RANDPOOLSIZE); - MD5_Init(&md5); - MD5_Update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); - MD5_Update(&md5, (u_char *)&magic_randcount, sizeof(magic_randcount)); - MD5_Final(tmp, &md5); + md5_starts(&md5); + md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + md5_update(&md5, (u_char *)&magic_randcount, sizeof(magic_randcount)); + md5_finish(&md5, tmp); magic_randcount++; MEMCPY(buf, tmp, n); buf += n; diff --git a/src/netif/ppp/md4.c b/src/netif/ppp/md4.c deleted file mode 100644 index f0831a92..00000000 --- a/src/netif/ppp/md4.c +++ /dev/null @@ -1,301 +0,0 @@ -/* -** ******************************************************************** -** md4.c -- Implementation of MD4 Message Digest Algorithm ** -** Updated: 2/16/90 by Ronald L. Rivest ** -** (C) 1990 RSA Data Security, Inc. ** -** ******************************************************************** -*/ - -#include "lwip/opt.h" - -/* -** To use MD4: -** -- Include md4.h in your program -** -- Declare an MDstruct MD to hold the state of the digest -** computation. -** -- Initialize MD using MDbegin(&MD) -** -- For each full block (64 bytes) X you wish to process, call -** MD4Update(&MD,X,512) -** (512 is the number of bits in a full block.) -** -- For the last block (less than 64 bytes) you wish to process, -** MD4Update(&MD,X,n) -** where n is the number of bits in the partial block. A partial -** block terminates the computation, so every MD computation -** should terminate by processing a partial block, even if it -** has n = 0. -** -- The message digest is available in MD.buffer[0] ... -** MD.buffer[3]. (Least-significant byte of each word -** should be output first.) -** -- You can print out the digest using MDprint(&MD) -*/ - -/* Implementation notes: -** This implementation assumes that ints are 32-bit quantities. -*/ - -#define TRUE 1 -#define FALSE 0 - -/* Compile-time includes -*/ -#include -#include "md4.h" -#include "pppd.h" - -/* Compile-time declarations of MD4 "magic constants". -*/ -#define I0 0x67452301 /* Initial values for MD buffer */ -#define I1 0xefcdab89 -#define I2 0x98badcfe -#define I3 0x10325476 -#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ -#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ -/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 -** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. -** Table 2, page 660. -*/ - -#define fs1 3 /* round 1 shift amounts */ -#define fs2 7 -#define fs3 11 -#define fs4 19 -#define gs1 3 /* round 2 shift amounts */ -#define gs2 5 -#define gs3 9 -#define gs4 13 -#define hs1 3 /* round 3 shift amounts */ -#define hs2 9 -#define hs3 11 -#define hs4 15 - -/* Compile-time macro declarations for MD4. -** Note: The "rot" operator uses the variable "tmp". -** It assumes tmp is declared as unsigned int, so that the >> -** operator will shift in zeros rather than extending the sign bit. -*/ -#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) -#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) -#define h(X,Y,Z) (X^Y^Z) -#define rot(X,S) (tmp=X,(tmp<>(32-S))) -#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) -#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) -#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) - -/* MD4print(MDp) -** Print message digest buffer MDp as 32 hexadecimal digits. -** Order is from low-order byte of buffer[0] to high-order byte of -** buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -** This is a user-callable routine. -*/ -void -MD4Print(MDp) -MD4_CTX *MDp; -{ - int i,j; - for (i=0;i<4;i++) - for (j=0;j<32;j=j+8) - printf("%02x",(MDp->buffer[i]>>j) & 0xFF); -} - -/* MD4Init(MDp) -** Initialize message digest buffer MDp. -** This is a user-callable routine. -*/ -void -MD4Init(MDp) -MD4_CTX *MDp; -{ - int i; - MDp->buffer[0] = I0; - MDp->buffer[1] = I1; - MDp->buffer[2] = I2; - MDp->buffer[3] = I3; - for (i=0;i<8;i++) MDp->count[i] = 0; - MDp->done = 0; -} - -/* MDblock(MDp,X) -** Update message digest buffer MDp->buffer using 16-word data block X. -** Assumes all 16 words of X are full of data. -** Does not update MDp->count. -** This routine is not user-callable. -*/ -static void -MDblock(MDp,Xb) -MD4_CTX *MDp; -unsigned char *Xb; -{ - register unsigned int tmp, A, B, C, D; - unsigned int X[16]; - int i; - - for (i = 0; i < 16; ++i) { - X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); - Xb += 4; - } - - A = MDp->buffer[0]; - B = MDp->buffer[1]; - C = MDp->buffer[2]; - D = MDp->buffer[3]; - /* Update the message digest buffer */ - ff(A , B , C , D , 0 , fs1); /* Round 1 */ - ff(D , A , B , C , 1 , fs2); - ff(C , D , A , B , 2 , fs3); - ff(B , C , D , A , 3 , fs4); - ff(A , B , C , D , 4 , fs1); - ff(D , A , B , C , 5 , fs2); - ff(C , D , A , B , 6 , fs3); - ff(B , C , D , A , 7 , fs4); - ff(A , B , C , D , 8 , fs1); - ff(D , A , B , C , 9 , fs2); - ff(C , D , A , B , 10 , fs3); - ff(B , C , D , A , 11 , fs4); - ff(A , B , C , D , 12 , fs1); - ff(D , A , B , C , 13 , fs2); - ff(C , D , A , B , 14 , fs3); - ff(B , C , D , A , 15 , fs4); - gg(A , B , C , D , 0 , gs1); /* Round 2 */ - gg(D , A , B , C , 4 , gs2); - gg(C , D , A , B , 8 , gs3); - gg(B , C , D , A , 12 , gs4); - gg(A , B , C , D , 1 , gs1); - gg(D , A , B , C , 5 , gs2); - gg(C , D , A , B , 9 , gs3); - gg(B , C , D , A , 13 , gs4); - gg(A , B , C , D , 2 , gs1); - gg(D , A , B , C , 6 , gs2); - gg(C , D , A , B , 10 , gs3); - gg(B , C , D , A , 14 , gs4); - gg(A , B , C , D , 3 , gs1); - gg(D , A , B , C , 7 , gs2); - gg(C , D , A , B , 11 , gs3); - gg(B , C , D , A , 15 , gs4); - hh(A , B , C , D , 0 , hs1); /* Round 3 */ - hh(D , A , B , C , 8 , hs2); - hh(C , D , A , B , 4 , hs3); - hh(B , C , D , A , 12 , hs4); - hh(A , B , C , D , 2 , hs1); - hh(D , A , B , C , 10 , hs2); - hh(C , D , A , B , 6 , hs3); - hh(B , C , D , A , 14 , hs4); - hh(A , B , C , D , 1 , hs1); - hh(D , A , B , C , 9 , hs2); - hh(C , D , A , B , 5 , hs3); - hh(B , C , D , A , 13 , hs4); - hh(A , B , C , D , 3 , hs1); - hh(D , A , B , C , 11 , hs2); - hh(C , D , A , B , 7 , hs3); - hh(B , C , D , A , 15 , hs4); - MDp->buffer[0] += A; - MDp->buffer[1] += B; - MDp->buffer[2] += C; - MDp->buffer[3] += D; -} - -/* MD4Update(MDp,X,count) -** Input: X -- a pointer to an array of unsigned characters. -** count -- the number of bits of X to use. -** (if not a multiple of 8, uses high bits of last byte.) -** Update MDp using the number of bits of X given by count. -** This is the basic input routine for an MD4 user. -** The routine completes the MD computation when count < 512, so -** every MD computation should end with one call to MD4Update with a -** count less than 512. A call with count 0 will be ignored if the -** MD has already been terminated (done != 0), so an extra call with -** count 0 can be given as a "courtesy close" to force termination -** if desired. -*/ -void -MD4Update(MDp,X,count) -MD4_CTX *MDp; -unsigned char *X; -unsigned int count; -{ - unsigned int i, tmp, bit, byte, mask; - unsigned char XX[64]; - unsigned char *p; - - /* return with no error if this is a courtesy close with count - ** zero and MDp->done is true. - */ - if (count == 0 && MDp->done) return; - /* check to see if MD is already done and report error */ - if (MDp->done) - { printf("\nError: MD4Update MD already done."); return; } - - /* Add count to MDp->count */ - tmp = count; - p = MDp->count; - while (tmp) - { tmp += *p; - *p++ = tmp; - tmp = tmp >> 8; - } - - /* Process data */ - if (count == 512) - { /* Full block of data to handle */ - MDblock(MDp,X); - } - else if (count > 512) /* Check for count too large */ - { - printf("\nError: MD4Update called with illegal count value %d.", - count); - return; - } - else /* partial block -- must be last block so finish up */ - { - /* Find out how many bytes and residual bits there are */ - byte = count >> 3; - bit = count & 7; - /* Copy X into XX since we need to modify it */ - if (count) - for (i=0;i<=byte;i++) XX[i] = X[i]; - for (i=byte+1;i<64;i++) XX[i] = 0; - /* Add padding '1' bit and low-order zeros in last byte */ - mask = 1 << (7 - bit); - XX[byte] = (XX[byte] | mask) & ~( mask - 1); - /* If room for bit count, finish up with this block */ - if (byte <= 55) - { - for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; - MDblock(MDp,XX); - } - else /* need to do two blocks to finish up */ - { - MDblock(MDp,XX); - for (i=0;i<56;i++) XX[i] = 0; - for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; - MDblock(MDp,XX); - } - /* Set flag saying we're done with MD computation */ - MDp->done = 1; - } -} - -/* -** Finish up MD4 computation and return message digest. -*/ -void -MD4Final(buf, MD) -unsigned char *buf; -MD4_CTX *MD; -{ - int i, j; - unsigned int w; - - MD4Update(MD, NULL, 0); - for (i = 0; i < 4; ++i) { - w = MD->buffer[i]; - for (j = 0; j < 4; ++j) { - *buf++ = w; - w >>= 8; - } - } -} - -/* -** End of md4.c -****************************(cut)***********************************/ diff --git a/src/netif/ppp/md4.h b/src/netif/ppp/md4.h deleted file mode 100644 index 80e8f9a2..00000000 --- a/src/netif/ppp/md4.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* -** ******************************************************************** -** md4.h -- Header file for implementation of ** -** MD4 Message Digest Algorithm ** -** Updated: 2/13/90 by Ronald L. Rivest ** -** (C) 1990 RSA Data Security, Inc. ** -** ******************************************************************** -*/ - -#ifndef __P -# if defined(__STDC__) || defined(__GNUC__) -# define __P(x) x -# else -# define __P(x) () -# endif -#endif - - -/* MDstruct is the data structure for a message digest computation. -*/ -typedef struct { - unsigned int buffer[4]; /* Holds 4-word result of MD computation */ - unsigned char count[8]; /* Number of bits processed so far */ - unsigned int done; /* Nonzero means MD computation finished */ -} MD4_CTX; - -/* MD4Init(MD4_CTX *) -** Initialize the MD4_CTX prepatory to doing a message digest -** computation. -*/ -extern void MD4Init __P((MD4_CTX *MD)); - -/* MD4Update(MD,X,count) -** Input: X -- a pointer to an array of unsigned characters. -** count -- the number of bits of X to use (an unsigned int). -** Updates MD using the first "count" bits of X. -** The array pointed to by X is not modified. -** If count is not a multiple of 8, MD4Update uses high bits of -** last byte. -** This is the basic input routine for a user. -** The routine terminates the MD computation when count < 512, so -** every MD computation should end with one call to MD4Update with a -** count less than 512. Zero is OK for a count. -*/ -extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); - -/* MD4Print(MD) -** Prints message digest buffer MD as 32 hexadecimal digits. -** Order is from low-order byte of buffer[0] to high-order byte -** of buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -*/ -extern void MD4Print __P((MD4_CTX *)); - -/* MD4Final(buf, MD) -** Returns message digest from MD and terminates the message -** digest computation. -*/ -extern void MD4Final __P((unsigned char *, MD4_CTX *)); - -/* -** End of md4.h -****************************(cut)***********************************/ diff --git a/src/netif/ppp/md5.c b/src/netif/ppp/md5.c deleted file mode 100644 index 11de7b6d..00000000 --- a/src/netif/ppp/md5.c +++ /dev/null @@ -1,309 +0,0 @@ - - -/* - *********************************************************************** - ** md5.c -- the source code for MD5 routines ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** - *********************************************************************** - */ - -#include "lwip/opt.h" - -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ - -#include -#include "md5.h" - -/* - *********************************************************************** - ** Message-digest routines: ** - ** To form the message digest for a message M ** - ** (1) Initialize a context buffer mdContext using MD5_Init ** - ** (2) Call MD5_Update on mdContext and M ** - ** (3) Call MD5_Final on mdContext ** - ** The message digest is now in mdContext->digest[0...15] ** - *********************************************************************** - */ - -/* forward declaration */ -static void Transform (UINT4 *buf, UINT4 *in); - -static unsigned char PADDING[64] = { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* F, G, H and I are basic MD5 functions */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ -/* Rotation is separate from addition to prevent recomputation */ -#define FF(a, b, c, d, x, s, ac) \ - {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) \ - {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) \ - {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) \ - {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -#ifdef __STDC__ -#define UL(x) x##U -#else -#define UL(x) x -#endif - -/* The routine MD5_Init initializes the message-digest context - mdContext. All fields are set to zero. - */ -void MD5_Init (mdContext) -MD5_CTX *mdContext; -{ - mdContext->i[0] = mdContext->i[1] = (UINT4)0; - - /* Load magic initialization constants. - */ - mdContext->buf[0] = (UINT4)0x67452301; - mdContext->buf[1] = (UINT4)0xefcdab89; - mdContext->buf[2] = (UINT4)0x98badcfe; - mdContext->buf[3] = (UINT4)0x10325476; -} - -/* The routine MD5Update updates the message-digest context to - account for the presence of each of the characters inBuf[0..inLen-1] - in the message whose digest is being computed. - */ -void MD5_Update (mdContext, inBuf, inLen) -MD5_CTX *mdContext; -unsigned char *inBuf; -unsigned int inLen; -{ - UINT4 in[16]; - int mdi; - unsigned int i, ii; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* update number of bits */ - if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) - mdContext->i[1]++; - mdContext->i[0] += ((UINT4)inLen << 3); - mdContext->i[1] += ((UINT4)inLen >> 29); - - while (inLen--) { - /* add new character to buffer, increment mdi */ - mdContext->in[mdi++] = *inBuf++; - - /* transform if necessary */ - if (mdi == 0x40) { - for (i = 0, ii = 0; i < 16; i++, ii += 4) - in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | - (((UINT4)mdContext->in[ii+2]) << 16) | - (((UINT4)mdContext->in[ii+1]) << 8) | - ((UINT4)mdContext->in[ii]); - Transform (mdContext->buf, in); - mdi = 0; - } - } -} - -/* The routine MD5Final terminates the message-digest computation and - ends with the desired message digest in mdContext->digest[0...15]. - */ -void MD5_Final (hash, mdContext) -unsigned char hash[]; -MD5_CTX *mdContext; -{ - UINT4 in[16]; - int mdi; - unsigned int i, ii; - unsigned int padLen; - - /* save number of bits */ - in[14] = mdContext->i[0]; - in[15] = mdContext->i[1]; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* pad out to 56 mod 64 */ - padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); - MD5_Update (mdContext, PADDING, padLen); - - /* append length in bits and transform */ - for (i = 0, ii = 0; i < 14; i++, ii += 4) - in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | - (((UINT4)mdContext->in[ii+2]) << 16) | - (((UINT4)mdContext->in[ii+1]) << 8) | - ((UINT4)mdContext->in[ii]); - Transform (mdContext->buf, in); - - /* store buffer in digest */ - for (i = 0, ii = 0; i < 4; i++, ii += 4) { - mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); - mdContext->digest[ii+1] = - (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); - mdContext->digest[ii+2] = - (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); - mdContext->digest[ii+3] = - (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); - } - memcpy(hash, mdContext->digest, 16); -} - -/* Basic MD5 step. Transforms buf based on in. - */ -static void Transform (buf, in) -UINT4 *buf; -UINT4 *in; -{ - UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - - /* Round 1 */ -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 - FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ - FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ - FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ - FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ - FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ - FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ - FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ - FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ - FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ - FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ - FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ - FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ - FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ - FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ - FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ - FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ - - /* Round 2 */ -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 - GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ - GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ - GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ - GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ - GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ - GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ - GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ - GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ - GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ - GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ - GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ - GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ - GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ - GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ - GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ - GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ - - /* Round 3 */ -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 - HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ - HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ - HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ - HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ - HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ - HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ - HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ - HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ - HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ - HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ - HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ - HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ - HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ - HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ - HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ - HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ - - /* Round 4 */ -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ - II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ - II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ - II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ - II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ - II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ - II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ - II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ - II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ - II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ - II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ - II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ - II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ - II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ - II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ - II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -/* - *********************************************************************** - ** End of md5.c ** - ******************************** (cut) ******************************** - */ diff --git a/src/netif/ppp/md5.h b/src/netif/ppp/md5.h deleted file mode 100644 index 71e8b00e..00000000 --- a/src/netif/ppp/md5.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - *********************************************************************** - ** md5.h -- header file for implementation of MD5 ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** - ** Revised (for MD5): RLR 4/27/91 ** - ** -- G modified to have y&~z instead of y&z ** - ** -- FF, GG, HH modified to add in last register done ** - ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** - ** -- distinct additive constant for each step ** - ** -- round 4 added, working mod 7 ** - *********************************************************************** - */ - -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ - -#ifndef __MD5_INCLUDE__ - -/* typedef a 32-bit type */ -#ifdef _LP64 -typedef unsigned int UINT4; -typedef int INT4; -#else -typedef unsigned long UINT4; -typedef long INT4; -#endif -#define _UINT4_T - -/* Data structure for MD5 (Message-Digest) computation */ -typedef struct { - UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ - UINT4 buf[4]; /* scratch buffer */ - unsigned char in[64]; /* input buffer */ - unsigned char digest[16]; /* actual digest after MD5Final call */ -} MD5_CTX; - -void MD5_Init (MD5_CTX *mdContext); -void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); -void MD5_Final (unsigned char hash[], MD5_CTX *mdContext); - -#define __MD5_INCLUDE__ -#endif /* __MD5_INCLUDE__ */ diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/md4.c new file mode 100644 index 00000000..e5f715bc --- /dev/null +++ b/src/netif/ppp/polarssl/md4.c @@ -0,0 +1,271 @@ +/* + * RFC 1186/1320 compliant MD4 implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD4 algorithm was designed by Ron Rivest in 1990. + * + * http://www.ietf.org/rfc/rfc1186.txt + * http://www.ietf.org/rfc/rfc1320.txt + */ + +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_MD4_C) + +#include "polarssl/md4.h" + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_ULONG_LE +#define GET_ULONG_LE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] ) \ + | ( (unsigned long) (b)[(i) + 1] << 8 ) \ + | ( (unsigned long) (b)[(i) + 2] << 16 ) \ + | ( (unsigned long) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_ULONG_LE +#define PUT_ULONG_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* + * MD4 context setup + */ +void md4_starts( md4_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md4_process( md4_context *ctx, const unsigned char data[64] ) +{ + unsigned long X[16], A, B, C, D; + + GET_ULONG_LE( X[ 0], data, 0 ); + GET_ULONG_LE( X[ 1], data, 4 ); + GET_ULONG_LE( X[ 2], data, 8 ); + GET_ULONG_LE( X[ 3], data, 12 ); + GET_ULONG_LE( X[ 4], data, 16 ); + GET_ULONG_LE( X[ 5], data, 20 ); + GET_ULONG_LE( X[ 6], data, 24 ); + GET_ULONG_LE( X[ 7], data, 28 ); + GET_ULONG_LE( X[ 8], data, 32 ); + GET_ULONG_LE( X[ 9], data, 36 ); + GET_ULONG_LE( X[10], data, 40 ); + GET_ULONG_LE( X[11], data, 44 ); + GET_ULONG_LE( X[12], data, 48 ); + GET_ULONG_LE( X[13], data, 52 ); + GET_ULONG_LE( X[14], data, 56 ); + GET_ULONG_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) ((x & y) | ((~x) & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 1], 7 ); + P( C, D, A, B, X[ 2], 11 ); + P( B, C, D, A, X[ 3], 19 ); + P( A, B, C, D, X[ 4], 3 ); + P( D, A, B, C, X[ 5], 7 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[ 7], 19 ); + P( A, B, C, D, X[ 8], 3 ); + P( D, A, B, C, X[ 9], 7 ); + P( C, D, A, B, X[10], 11 ); + P( B, C, D, A, X[11], 19 ); + P( A, B, C, D, X[12], 3 ); + P( D, A, B, C, X[13], 7 ); + P( C, D, A, B, X[14], 11 ); + P( B, C, D, A, X[15], 19 ); + +#undef P +#undef F + +#define F(x,y,z) ((x & y) | (x & z) | (y & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 4], 5 ); + P( C, D, A, B, X[ 8], 9 ); + P( B, C, D, A, X[12], 13 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 5], 5 ); + P( C, D, A, B, X[ 9], 9 ); + P( B, C, D, A, X[13], 13 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[ 6], 5 ); + P( C, D, A, B, X[10], 9 ); + P( B, C, D, A, X[14], 13 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[ 7], 5 ); + P( C, D, A, B, X[11], 9 ); + P( B, C, D, A, X[15], 13 ); + +#undef P +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 8], 9 ); + P( C, D, A, B, X[ 4], 11 ); + P( B, C, D, A, X[12], 15 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[10], 9 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[14], 15 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 9], 9 ); + P( C, D, A, B, X[ 5], 11 ); + P( B, C, D, A, X[13], 15 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[11], 9 ); + P( C, D, A, B, X[ 7], 11 ); + P( B, C, D, A, X[15], 15 ); + +#undef F +#undef P + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD4 process buffer + */ +void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (unsigned long) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + md4_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md4_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md4_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD4 final digest + */ +void md4_finish( md4_context *ctx, unsigned char output[16] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_LE( low, msglen, 0 ); + PUT_ULONG_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md4_update( ctx, (unsigned char *) md4_padding, padn ); + md4_update( ctx, msglen, 8 ); + + PUT_ULONG_LE( ctx->state[0], output, 0 ); + PUT_ULONG_LE( ctx->state[1], output, 4 ); + PUT_ULONG_LE( ctx->state[2], output, 8 ); + PUT_ULONG_LE( ctx->state[3], output, 12 ); +} + +/* + * output = MD4( input buffer ) + */ +void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + md4_context ctx; + + md4_starts( &ctx ); + md4_update( &ctx, input, ilen ); + md4_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md4_context ) ); +} + +#endif /* LWIP_INCLUDED_POLARSSL_MD4_C */ diff --git a/src/netif/ppp/polarssl/md4.h b/src/netif/ppp/polarssl/md4.h new file mode 100644 index 00000000..1ad8250f --- /dev/null +++ b/src/netif/ppp/polarssl/md4.h @@ -0,0 +1,82 @@ +/** + * \file md4.h + * + * \brief MD4 message digest algorithm (hash function) + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef LWIP_INCLUDED_POLARSSL_MD4_H +#define LWIP_INCLUDED_POLARSSL_MD4_H + +/** + * \brief MD4 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +md4_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD4 context setup + * + * \param ctx context to be initialized + */ +void md4_starts( md4_context *ctx ); + +/** + * \brief MD4 process buffer + * + * \param ctx MD4 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief MD4 final digest + * + * \param ctx MD4 context + * \param output MD4 checksum result + */ +void md4_finish( md4_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = MD4( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD4 checksum result + */ +void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/md5.c new file mode 100644 index 00000000..621a5372 --- /dev/null +++ b/src/netif/ppp/polarssl/md5.c @@ -0,0 +1,290 @@ +/* + * RFC 1321 compliant MD5 implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD5 algorithm was designed by Ron Rivest in 1991. + * + * http://www.ietf.org/rfc/rfc1321.txt + */ + +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_MD5_C) + +#include "polarssl/md5.h" + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_ULONG_LE +#define GET_ULONG_LE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] ) \ + | ( (unsigned long) (b)[(i) + 1] << 8 ) \ + | ( (unsigned long) (b)[(i) + 2] << 16 ) \ + | ( (unsigned long) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_ULONG_LE +#define PUT_ULONG_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* + * MD5 context setup + */ +void md5_starts( md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md5_process( md5_context *ctx, const unsigned char data[64] ) +{ + unsigned long X[16], A, B, C, D; + + GET_ULONG_LE( X[ 0], data, 0 ); + GET_ULONG_LE( X[ 1], data, 4 ); + GET_ULONG_LE( X[ 2], data, 8 ); + GET_ULONG_LE( X[ 3], data, 12 ); + GET_ULONG_LE( X[ 4], data, 16 ); + GET_ULONG_LE( X[ 5], data, 20 ); + GET_ULONG_LE( X[ 6], data, 24 ); + GET_ULONG_LE( X[ 7], data, 28 ); + GET_ULONG_LE( X[ 8], data, 32 ); + GET_ULONG_LE( X[ 9], data, 36 ); + GET_ULONG_LE( X[10], data, 40 ); + GET_ULONG_LE( X[11], data, 44 ); + GET_ULONG_LE( X[12], data, 48 ); + GET_ULONG_LE( X[13], data, 52 ); + GET_ULONG_LE( X[14], data, 56 ); + GET_ULONG_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD5 process buffer + */ +void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (unsigned long) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + md5_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md5_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD5 final digest + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_LE( low, msglen, 0 ); + PUT_ULONG_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md5_update( ctx, (unsigned char *) md5_padding, padn ); + md5_update( ctx, msglen, 8 ); + + PUT_ULONG_LE( ctx->state[0], output, 0 ); + PUT_ULONG_LE( ctx->state[1], output, 4 ); + PUT_ULONG_LE( ctx->state[2], output, 8 ); + PUT_ULONG_LE( ctx->state[3], output, 12 ); +} + +/* + * output = MD5( input buffer ) + */ +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + md5_context ctx; + + md5_starts( &ctx ); + md5_update( &ctx, input, ilen ); + md5_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md5_context ) ); +} + +#endif /* LWIP_INCLUDED_POLARSSL_MD5_C */ diff --git a/src/netif/ppp/polarssl/md5.h b/src/netif/ppp/polarssl/md5.h new file mode 100644 index 00000000..389b4154 --- /dev/null +++ b/src/netif/ppp/polarssl/md5.h @@ -0,0 +1,82 @@ +/** + * \file md5.h + * + * \brief MD5 message digest algorithm (hash function) + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef LWIP_INCLUDED_POLARSSL_MD5_H +#define LWIP_INCLUDED_POLARSSL_MD5_H + +/** + * \brief MD5 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +md5_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD5 context setup + * + * \param ctx context to be initialized + */ +void md5_starts( md5_context *ctx ); + +/** + * \brief MD5 process buffer + * + * \param ctx MD5 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief MD5 final digest + * + * \param ctx MD5 context + * \param output MD5 checksum result + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = MD5( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD5 checksum result + */ +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/sha1.c new file mode 100644 index 00000000..5e9a661f --- /dev/null +++ b/src/netif/ppp/polarssl/sha1.c @@ -0,0 +1,325 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-1 standard was published by NIST in 1993. + * + * http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ + +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_SHA1_C) + +#include "polarssl/sha1.h" + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * SHA-1 context setup + */ +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) +{ + unsigned long temp, W[16], A, B, C, D, E; + + GET_ULONG_BE( W[ 0], data, 0 ); + GET_ULONG_BE( W[ 1], data, 4 ); + GET_ULONG_BE( W[ 2], data, 8 ); + GET_ULONG_BE( W[ 3], data, 12 ); + GET_ULONG_BE( W[ 4], data, 16 ); + GET_ULONG_BE( W[ 5], data, 20 ); + GET_ULONG_BE( W[ 6], data, 24 ); + GET_ULONG_BE( W[ 7], data, 28 ); + GET_ULONG_BE( W[ 8], data, 32 ); + GET_ULONG_BE( W[ 9], data, 36 ); + GET_ULONG_BE( W[10], data, 40 ); + GET_ULONG_BE( W[11], data, 44 ); + GET_ULONG_BE( W[12], data, 48 ); + GET_ULONG_BE( W[13], data, 52 ); + GET_ULONG_BE( W[14], data, 56 ); + GET_ULONG_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ + W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* + * SHA-1 process buffer + */ +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (unsigned long) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-1 final digest + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_BE( high, msglen, 0 ); + PUT_ULONG_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, (unsigned char *) sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_ULONG_BE( ctx->state[0], output, 0 ); + PUT_ULONG_BE( ctx->state[1], output, 4 ); + PUT_ULONG_BE( ctx->state[2], output, 8 ); + PUT_ULONG_BE( ctx->state[3], output, 12 ); + PUT_ULONG_BE( ctx->state[4], output, 16 ); +} + +/* + * output = SHA-1( input buffer ) + */ +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_starts( &ctx ); + sha1_update( &ctx, input, ilen ); + sha1_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha1_context ) ); +} + +#endif /* LWIP_INCLUDED_POLARSSL_SHA1_C */ diff --git a/src/netif/ppp/polarssl/sha1.h b/src/netif/ppp/polarssl/sha1.h new file mode 100644 index 00000000..b01e93f4 --- /dev/null +++ b/src/netif/ppp/polarssl/sha1.h @@ -0,0 +1,82 @@ +/** + * \file sha1.h + * + * \brief SHA-1 cryptographic hash function + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H +#define LWIP_INCLUDED_POLARSSL_SHA1_H + +/** + * \brief SHA-1 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +sha1_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + */ +void sha1_starts( sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ); + +/** + * \brief Output = SHA-1( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-1 checksum result + */ +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ diff --git a/src/netif/ppp/sha1.c b/src/netif/ppp/sha1.c deleted file mode 100644 index 3b020b8f..00000000 --- a/src/netif/ppp/sha1.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c - * - * SHA-1 in C - * By Steve Reid - * 100% Public Domain - * - * Test Vectors (from FIPS PUB 180-1) - * "abc" - * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D - * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 - * A million repetitions of "a" - * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F - */ - -#include "lwip/opt.h" - -/* #define SHA1HANDSOFF * Copies data before messing with it. */ - -#include -#include /* htonl() */ -#include -#include "sha1.h" - -static void -SHA1_Transform(u_int32_t[5], const unsigned char[64]); - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -/* I got the idea of expanding during the round function from SSLeay */ -#define blk0(i) (block->l[i] = htonl(block->l[i])) -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -static void -SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64]) -{ - u_int32_t a, b, c, d, e; - typedef union { - unsigned char c[64]; - u_int32_t l[16]; - } CHAR64LONG16; - CHAR64LONG16 *block; - -#ifdef SHA1HANDSOFF - static unsigned char workspace[64]; - block = (CHAR64LONG16 *) workspace; - memcpy(block, buffer, 64); -#else - block = (CHAR64LONG16 *) buffer; -#endif - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Wipe variables */ - a = b = c = d = e = 0; -} - - -/* SHA1Init - Initialize new context */ - -void -SHA1_Init(SHA1_CTX *context) -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - - -/* Run your data through this. */ - -void -SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) -{ - unsigned int i, j; - - j = (context->count[0] >> 3) & 63; - if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; - context->count[1] += (len >> 29); - i = 64 - j; - while (len >= i) { - memcpy(&context->buffer[j], data, i); - SHA1_Transform(context->state, context->buffer); - data += i; - len -= i; - i = 64; - j = 0; - } - - memcpy(&context->buffer[j], data, len); -} - - -/* Add padding and return the message digest. */ - -void -SHA1_Final(unsigned char digest[20], SHA1_CTX *context) -{ - u_int32_t i, j; - unsigned char finalcount[8]; - - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ - } - SHA1_Update(context, (unsigned char *) "\200", 1); - while ((context->count[0] & 504) != 448) { - SHA1_Update(context, (unsigned char *) "\0", 1); - } - SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - /* Wipe variables */ - i = j = 0; - memset(context->buffer, 0, 64); - memset(context->state, 0, 20); - memset(context->count, 0, 8); - memset(&finalcount, 0, 8); -#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ - SHA1Transform(context->state, context->buffer); -#endif -} - diff --git a/src/netif/ppp/sha1.h b/src/netif/ppp/sha1.h deleted file mode 100644 index 83f64df2..00000000 --- a/src/netif/ppp/sha1.h +++ /dev/null @@ -1,31 +0,0 @@ -/* sha1.h */ - -/* If OpenSSL is in use, then use that version of SHA-1 */ -#ifdef OPENSSL -#include -#define __SHA1_INCLUDE_ -#endif - -#ifndef __SHA1_INCLUDE_ - -#ifndef SHA1_SIGNATURE_SIZE -#ifdef SHA_DIGESTSIZE -#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE -#else -#define SHA1_SIGNATURE_SIZE 20 -#endif -#endif - -typedef struct { - u_int32_t state[5]; - u_int32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -extern void SHA1_Init(SHA1_CTX *); -extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int); -extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *); - -#define __SHA1_INCLUDE_ -#endif /* __SHA1_INCLUDE_ */ - From bf10a27db89eb64a50df40a173b2d012b47586e3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 15:27:52 +0200 Subject: [PATCH 021/320] modified auth_reset() so that we can choose which auth we want also fixed MS-CHAP and MS-CHAP-V2, MD4 polarssl uses bytes as input length, not bits --- src/netif/ppp/auth.c | 58 +++++++++++++++++++++++++++++++--------- src/netif/ppp/chap-new.c | 10 ++----- src/netif/ppp/chap_ms.c | 15 +---------- src/netif/ppp/pppmy.c | 9 +++++++ src/netif/ppp/pppmy.h | 3 ++- 5 files changed, 60 insertions(+), 35 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 39950350..5ec3f75d 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1292,21 +1292,42 @@ void auth_reset(unit) int unit; { - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - int hadchap; - hadchap = -1; + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *ao = &lcp_allowoptions[unit]; + + if( ppp_settings.passwd[0] ) { + + ao->neg_upap = !ppp_settings.refuse_pap; + + ao->neg_eap = !ppp_settings.refuse_eap; + + ao->chap_mdtype = MDTYPE_NONE; + if(!ppp_settings.refuse_chap) + ao->chap_mdtype |= MDTYPE_MD5; + if(!ppp_settings.refuse_mschap) + ao->chap_mdtype |= MDTYPE_MICROSOFT; + if(!ppp_settings.refuse_mschap_v2) + ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; + + ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); + + } else { + ao->neg_upap = 0; + ao->neg_chap = 0; + ao->neg_eap = 0; + ao->chap_mdtype = MDTYPE_NONE; + } + + + printf("neg_upap: %d\n", ao->neg_upap); + printf("neg_chap: %d\n", ao->neg_chap); + printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); + printf("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT) ); + printf("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2) ); + printf("neg_eap: %d\n", ao->neg_eap); //ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); - ao->neg_upap = !ppp_settings.refuse_pap && ppp_settings.passwd[0] != 0; - - ao->neg_chap = (!ppp_settings.refuse_chap || !ppp_settings.refuse_mschap || !ppp_settings.refuse_mschap_v2) && ppp_settings.passwd[0]; - - ao->neg_eap = !ppp_settings.refuse_eap && ppp_settings.passwd[0] != 0; - - return; - /* ao->neg_chap = (!ppp_settings.refuse_chap || !refuse_mschap || !refuse_mschap_v2) && (passwd[0] != 0 || @@ -1319,15 +1340,26 @@ auth_reset(unit) (explicit_remote? remote_name: NULL), 0, NULL))) || have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); */ + go->neg_upap = 0; + go->neg_chap = 0; + go->neg_eap = 0; + go->chap_mdtype = MDTYPE_NONE; + return; + /* FIXME: find what the below stuff do */ + int hadchap; + hadchap = -1; + hadchap = -1; if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) go->neg_upap = 0; + if (go->neg_chap) { if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL))) go->neg_chap = 0; } + if (go->neg_eap && (hadchap == 0 || (hadchap == -1 && !have_chap_secret((explicit_remote? remote_name: NULL), our_name, @@ -1728,6 +1760,8 @@ get_secret(unit, client, server, secret, secret_len, am_server) *secret_len = len; return 1; + +/* FIXME: clean that */ #if 0 // strlcpy(rname, ppp_settings.user, sizeof(rname)); diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 5fe183f8..7d773537 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -456,14 +456,8 @@ chap_respond(struct chap_client_state *cs, int id, slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); /* Microsoft doesn't send their name back in the PPP packet */ - if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rname[0] == 0)) { - strncpy(rname, ppp_settings.remote_name, sizeof(rname)); - rname[sizeof(rname) - 1] = 0; - } - -// /* Microsoft doesn't send their name back in the PPP packet */ -// if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) -// strlcpy(rname, remote_name, sizeof(rname)); + if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) + strlcpy(rname, remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 9efa2066..188e721b 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -512,24 +512,11 @@ ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) { -#ifdef __NetBSD__ - /* NetBSD uses the libc md4 routines which take bytes instead of bits */ - int mdlen = secret_len; -#else - int mdlen = secret_len * 8; -#endif md4_context md4Context; md4_starts(&md4Context); - /* MD4Update can take at most 64 bytes at a time */ - while (mdlen > 512) { - md4_update(&md4Context, secret, 512); - secret += 64; - mdlen -= 512; - } - md4_update(&md4Context, secret, mdlen); + md4_update(&md4Context, secret, secret_len); md4_finish(&md4Context, hash); - } static void diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 8085741b..3352b2ba 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -435,6 +435,14 @@ int ppp_init(void) { void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { + ppp_settings.refuse_pap = 1; + ppp_settings.refuse_chap = 1; + ppp_settings.refuse_mschap = 1; + ppp_settings.refuse_mschap_v2 = 0; + ppp_settings.refuse_eap = 1; + +/* FIXME: re-enable that */ +#if 0 switch(authType) { case PPPAUTHTYPE_NONE: default: @@ -481,6 +489,7 @@ pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) ppp_settings.refuse_chap = 0; break; } +#endif if(user) { strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index e79f43fa..07099ecd 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -58,7 +58,8 @@ struct ppp_settings { char user [MAXNAMELEN + 1]; /* Username for PAP */ char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ + // FIXME: re-enable that + // char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ }; struct ppp_settings ppp_settings; From de70b710af43942130690e9225b32b02cea279aa Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 19:57:37 +0200 Subject: [PATCH 022/320] Added PolarSSL DES library, which is necessary for MSCHAP. Added a README about our PolarSSL included files, clarifying what we did. Removed crypt(), -lcrypt ( setkey() / encrypt() ) dependencies. --- src/netif/ppp/chap_ms.c | 35 ++- src/netif/ppp/eap.c | 6 + src/netif/ppp/polarssl/README | 33 +++ src/netif/ppp/polarssl/des.c | 418 ++++++++++++++++++++++++++++++++++ src/netif/ppp/polarssl/des.h | 88 +++++++ src/netif/ppp/pppcrypt.c | 161 ++----------- src/netif/ppp/pppcrypt.h | 12 +- 7 files changed, 586 insertions(+), 167 deletions(-) create mode 100644 src/netif/ppp/polarssl/README create mode 100644 src/netif/ppp/polarssl/des.c create mode 100644 src/netif/ppp/polarssl/des.h diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 188e721b..2c46bbec 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -93,6 +93,7 @@ #include "chap_ms.h" #include "polarssl/md4.h" #include "polarssl/sha1.h" +#include "polarssl/des.h" #include "pppcrypt.h" #include "magic.h" @@ -447,6 +448,8 @@ ChallengeResponse(u_char *challenge, u_char response[24]) { u_char ZPasswordHash[21]; + des_context des; + u_char des_key[8]; BZERO(ZPasswordHash, sizeof(ZPasswordHash)); BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE); @@ -456,12 +459,17 @@ ChallengeResponse(u_char *challenge, sizeof(ZPasswordHash), ZPasswordHash); #endif - (void) DesSetkey(ZPasswordHash + 0); - DesEncrypt(challenge, response + 0); - (void) DesSetkey(ZPasswordHash + 7); - DesEncrypt(challenge, response + 8); - (void) DesSetkey(ZPasswordHash + 14); - DesEncrypt(challenge, response + 16); + pppcrypt_56_to_64_bit_key(ZPasswordHash + 0, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +0); + + pppcrypt_56_to_64_bit_key(ZPasswordHash + 7, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +8); + + pppcrypt_56_to_64_bit_key(ZPasswordHash + 14, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +16); #if 0 dbglog("ChallengeResponse - response %.24B", response); @@ -560,15 +568,22 @@ ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, int i; u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ u_char PasswordHash[MD4_SIGNATURE_SIZE]; + des_context des; + u_char des_key[8]; /* LANMan password is case insensitive */ BZERO(UcasePassword, sizeof(UcasePassword)); for (i = 0; i < secret_len; i++) UcasePassword[i] = (u_char)toupper(secret[i]); - (void) DesSetkey(UcasePassword + 0); - DesEncrypt( StdText, PasswordHash + 0 ); - (void) DesSetkey(UcasePassword + 7); - DesEncrypt( StdText, PasswordHash + 8 ); + + pppcrypt_56_to_64_bit_key(UcasePassword +0, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, StdText, PasswordHash +0); + + pppcrypt_56_to_64_bit_key(UcasePassword +7, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, StdText, PasswordHash +8); + ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); } #endif diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index b545cbd0..1585bcc7 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -334,6 +334,7 @@ pncrypt_setkey(int timeoffs) strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); SHA1Update(&ctxt, tbuf, strlen(tbuf)); SHA1Final(dig, &ctxt); + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ return (DesSetkey(dig)); } @@ -476,6 +477,7 @@ int status; for (i = 0; i < 5; i++) { pncrypt_setkey(toffs); toffs -= 86400; + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ if (!DesDecrypt(secbuf, clear)) { dbglog("no DES here; cannot decode " "pseudonym"); @@ -500,6 +502,7 @@ int status; dp += i; sp = secbuf + 8; while (plen > 0) { + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesDecrypt(sp, dp); sp += 8; dp += 8; @@ -781,6 +784,7 @@ eap_state *esp; BCOPY(cp, clear + 1, j); i -= j; cp += j; + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ if (!DesEncrypt(clear, cipher)) { dbglog("no DES here; not generating pseudonym"); break; @@ -789,6 +793,7 @@ eap_state *esp; outp++; /* space for pseudonym length */ outp += b64enc(&b64, cipher, 8, outp); while (i >= 8) { + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesEncrypt(cp, cipher); outp += b64enc(&b64, cipher, 8, outp); cp += 8; @@ -801,6 +806,7 @@ eap_state *esp; *cp++ = drand48() * 0x100; i++; } + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesEncrypt(clear, cipher); outp += b64enc(&b64, cipher, 8, outp); } diff --git a/src/netif/ppp/polarssl/README b/src/netif/ppp/polarssl/README new file mode 100644 index 00000000..8efc8ec1 --- /dev/null +++ b/src/netif/ppp/polarssl/README @@ -0,0 +1,33 @@ +About PolarSSL files into lwIP PPP support +------------------------------------------ + +This folder contains some files fetched from the PolarSSL project for +ciphers and encryption methods we need for lwIP PPP support. + +The PolarSSL files were cleaned to contain only the necessary struct +fields and functions needed for lwIP. + + +The PolarSSL API was not changed at all, so if you are already using +PolarSSL you can choose to skip the compilation of the included PolarSSL +library into lwIP: + +The following define are available for flexibility: + +LWIP_INCLUDED_POLARSSL_MD4_C ; Use lwIP internal PolarSSL for MD4 +LWIP_INCLUDED_POLARSSL_MD5_C ; Use lwIP internal PolarSSL for MD5 +LWIP_INCLUDED_POLARSSL_SHA1_C ; Use lwIP internal PolarSSL for SHA1 +LWIP_INCLUDED_POLARSSL_DES_C ; Use lwIP internal PolarSSL for DES + +If set (=1), the default if required by another enabled PPP feature unless +explicitely set to 0, using included lwIP PolarSSL. + +If clear (=0), using external PolarSSL. + +Undefined if not needed. + +Beware of the stack requirements which can be a lot larger if you are not +using our cleaned PolarSSL library. + + +PolarSSL project website: http://polarssl.org/ diff --git a/src/netif/ppp/polarssl/des.c b/src/netif/ppp/polarssl/des.c new file mode 100644 index 00000000..b3d98286 --- /dev/null +++ b/src/netif/ppp/polarssl/des.c @@ -0,0 +1,418 @@ +/* + * FIPS-46-3 compliant Triple-DES implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * DES, on which TDES is based, was originally designed by Horst Feistel + * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). + * + * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + */ + +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_DES_C) + +#include "polarssl/des.h" + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * Expanded DES S-boxes + */ +static const unsigned long SB1[64] = +{ + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static const unsigned long SB2[64] = +{ + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static const unsigned long SB3[64] = +{ + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const unsigned long SB4[64] = +{ + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const unsigned long SB5[64] = +{ + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const unsigned long SB6[64] = +{ + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const unsigned long SB7[64] = +{ + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const unsigned long SB8[64] = +{ + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * PC1: left and right halves bit-swap + */ +static const unsigned long LHs[16] = +{ + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +static const unsigned long RHs[16] = +{ + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Initial Permutation macro + */ +#define DES_IP(X,Y) \ +{ \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ + X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ +} + +/* + * Final Permutation macro + */ +#define DES_FP(X,Y) \ +{ \ + X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ + Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ +} + +/* + * DES round macro + */ +#define DES_ROUND(X,Y) \ +{ \ + T = *SK++ ^ X; \ + Y ^= SB8[ (T ) & 0x3F ] ^ \ + SB6[ (T >> 8) & 0x3F ] ^ \ + SB4[ (T >> 16) & 0x3F ] ^ \ + SB2[ (T >> 24) & 0x3F ]; \ + \ + T = *SK++ ^ ((X << 28) | (X >> 4)); \ + Y ^= SB7[ (T ) & 0x3F ] ^ \ + SB5[ (T >> 8) & 0x3F ] ^ \ + SB3[ (T >> 16) & 0x3F ] ^ \ + SB1[ (T >> 24) & 0x3F ]; \ +} + +#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } + +static void des_setkey( unsigned long SK[32], const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + unsigned long X, Y, T; + + GET_ULONG_BE( X, key, 0 ); + GET_ULONG_BE( Y, key, 4 ); + + /* + * Permuted Choice 1 + */ + T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); + T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); + + X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) + | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) + | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) + | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); + + Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) + | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) + | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) + | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); + + X &= 0x0FFFFFFF; + Y &= 0x0FFFFFFF; + + /* + * calculate subkeys + */ + for( i = 0; i < 16; i++ ) + { + if( i < 2 || i == 8 || i == 15 ) + { + X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; + Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; + } + else + { + X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; + Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; + } + + *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) + | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) + | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) + | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) + | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) + | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) + | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) + | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) + | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) + | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) + | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); + + *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) + | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) + | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) + | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) + | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) + | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) + | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) + | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) + | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) + | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) + | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); + } +} + +/* + * DES key schedule (56-bit, encryption) + */ +int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +{ + des_setkey( ctx->sk, key ); + + return( 0 ); +} + +/* + * DES key schedule (56-bit, decryption) + */ +int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + + des_setkey( ctx->sk, key ); + + for( i = 0; i < 16; i += 2 ) + { + SWAP( ctx->sk[i ], ctx->sk[30 - i] ); + SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); + } + + return( 0 ); +} + +/* + * DES-ECB block encryption/decryption + */ +int des_crypt_ecb( des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + unsigned long X, Y, T, *SK; + + SK = ctx->sk; + + GET_ULONG_BE( X, input, 0 ); + GET_ULONG_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_ULONG_BE( Y, output, 0 ); + PUT_ULONG_BE( X, output, 4 ); + + return( 0 ); +} + +#endif /* LWIP_INCLUDED_POLARSSL_DES_C */ diff --git a/src/netif/ppp/polarssl/des.h b/src/netif/ppp/polarssl/des.h new file mode 100644 index 00000000..21d84601 --- /dev/null +++ b/src/netif/ppp/polarssl/des.h @@ -0,0 +1,88 @@ +/** + * \file des.h + * + * \brief DES block cipher + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef LWIP_INCLUDED_POLARSSL_DES_H +#define LWIP_INCLUDED_POLARSSL_DES_H + +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ + +#define DES_KEY_SIZE 8 + +/** + * \brief DES context structure + */ +typedef struct +{ + int mode; /*!< encrypt/decrypt */ + unsigned long sk[32]; /*!< DES subkeys */ +} +des_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief DES key schedule (56-bit, encryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + */ +int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief DES key schedule (56-bit, decryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + */ +int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief DES-ECB block encryption/decryption + * + * \param ctx DES context + * \param input 64-bit input block + * \param output 64-bit output block + * + * \return 0 if successful + */ +int des_crypt_ecb( des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_DES_H */ diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index 1a66f680..9bde8953 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -32,15 +32,13 @@ #include "lwip/opt.h" -#include +/* FIXME: dont include if not needed */ + #include "pppd.h" #include "pppcrypt.h" -static u_char -Get7Bits(input, startBit) -u_char *input; -int startBit; -{ + +static u_char pppcrypt_get_7bits(u_char *input, int startBit) { unsigned int word; word = (unsigned)input[startBit / 8] << 8; @@ -51,145 +49,16 @@ int startBit; return word & 0xFE; } -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 -} - -#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() +/* IN 56 bit DES key missing parity bits + * OUT 64 bit DES key with parity bits added */ -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; - } +void pppcrypt_56_to_64_bit_key(u_char *key, u_char * des_key) { + des_key[0] = pppcrypt_get_7bits(key, 0); + des_key[1] = pppcrypt_get_7bits(key, 7); + des_key[2] = pppcrypt_get_7bits(key, 14); + des_key[3] = pppcrypt_get_7bits(key, 21); + des_key[4] = pppcrypt_get_7bits(key, 28); + des_key[5] = pppcrypt_get_7bits(key, 35); + des_key[6] = pppcrypt_get_7bits(key, 42); + des_key[7] = pppcrypt_get_7bits(key, 49); } - -/* 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; - } -} - -bool -DesSetkey(key) -u_char *key; -{ - u_char des_key[8]; - u_char crypt_key[66]; - - MakeKey(key, des_key); - Expand(des_key, crypt_key); - errno = 0; - setkey((const char *)crypt_key); - if (errno != 0) - return (0); - return (1); -} - -bool -DesEncrypt(clear, cipher) -u_char *clear; /* IN 8 octets */ -u_char *cipher; /* OUT 8 octets */ -{ - u_char des_input[66]; - - Expand(clear, des_input); - errno = 0; - encrypt((char *)des_input, 0); - if (errno != 0) - return (0); - Collapse(des_input, cipher); - return (1); -} - -bool -DesDecrypt(cipher, clear) -u_char *cipher; /* IN 8 octets */ -u_char *clear; /* OUT 8 octets */ -{ - u_char des_input[66]; - - Expand(cipher, des_input); - errno = 0; - encrypt((char *)des_input, 1); - if (errno != 0) - return (0); - Collapse(des_input, clear); - return (1); -} - -#else /* USE_CRYPT */ -static des_key_schedule key_schedule; - -bool -DesSetkey(key) -u_char *key; -{ - des_cblock des_key; - MakeKey(key, des_key); - des_set_key(&des_key, key_schedule); - return (1); -} - -bool -DesEncrypt(clear, key, cipher) -u_char *clear; /* IN 8 octets */ -u_char *cipher; /* OUT 8 octets */ -{ - des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, - key_schedule, 1); - return (1); -} - -bool -DesDecrypt(cipher, clear) -u_char *cipher; /* IN 8 octets */ -u_char *clear; /* OUT 8 octets */ -{ - des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, - key_schedule, 0); - return (1); -} - -#endif /* USE_CRYPT */ diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h index adcdcbcb..6b5eaf8b 100644 --- a/src/netif/ppp/pppcrypt.h +++ b/src/netif/ppp/pppcrypt.h @@ -33,16 +33,6 @@ #ifndef PPPCRYPT_H #define PPPCRYPT_H -#ifdef HAVE_CRYPT_H -#include -#endif - -#ifndef USE_CRYPT -#include -#endif - -extern bool DesSetkey __P((u_char *)); -extern bool DesEncrypt __P((u_char *, u_char *)); -extern bool DesDecrypt __P((u_char *, u_char *)); +void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key); #endif /* PPPCRYPT_H */ From f5dc6e80c061fafff993b377071bb0a50dcac641 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 20:04:05 +0200 Subject: [PATCH 023/320] Removed uneeded crypt() from auth.c and session.c --- src/netif/ppp/auth.c | 3 +++ src/netif/ppp/session.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 5ec3f75d..08410fd0 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1388,6 +1388,8 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) int passwdlen; char **msg; { + return UPAP_AUTHNAK; +#if 0 int ret; char *filename; FILE *f; @@ -1498,6 +1500,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) BZERO(secret, sizeof(secret)); return ret; +#endif } /* diff --git a/src/netif/ppp/session.c b/src/netif/ppp/session.c index 29c56f2e..aa4d746a 100644 --- a/src/netif/ppp/session.c +++ b/src/netif/ppp/session.c @@ -347,12 +347,14 @@ session_start(flags, user, passwd, ttyName, msg) #endif /* #ifdef HAS_SHADOW */ +#if 0 /* * If no passwd, don't let them login if we're authenticating. */ if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2 || strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0) return SESSION_FAILED; +#endif } #endif /* #ifdef USE_PAM */ From a820f32ec936a1a699ef76adb3fa8ea0915fc152 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 20:39:15 +0200 Subject: [PATCH 024/320] Revert "Added PolarSSL DES library, which is necessary for MSCHAP." This reverts commit de70b710af43942130690e9225b32b02cea279aa. Licence issue, we cannot include GPLed source code. --- src/netif/ppp/chap_ms.c | 35 +-- src/netif/ppp/eap.c | 6 - src/netif/ppp/polarssl/README | 33 --- src/netif/ppp/polarssl/des.c | 418 ---------------------------------- src/netif/ppp/polarssl/des.h | 88 ------- src/netif/ppp/pppcrypt.c | 163 +++++++++++-- src/netif/ppp/pppcrypt.h | 12 +- 7 files changed, 168 insertions(+), 587 deletions(-) delete mode 100644 src/netif/ppp/polarssl/README delete mode 100644 src/netif/ppp/polarssl/des.c delete mode 100644 src/netif/ppp/polarssl/des.h diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 2c46bbec..188e721b 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -93,7 +93,6 @@ #include "chap_ms.h" #include "polarssl/md4.h" #include "polarssl/sha1.h" -#include "polarssl/des.h" #include "pppcrypt.h" #include "magic.h" @@ -448,8 +447,6 @@ ChallengeResponse(u_char *challenge, u_char response[24]) { u_char ZPasswordHash[21]; - des_context des; - u_char des_key[8]; BZERO(ZPasswordHash, sizeof(ZPasswordHash)); BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE); @@ -459,17 +456,12 @@ ChallengeResponse(u_char *challenge, sizeof(ZPasswordHash), ZPasswordHash); #endif - pppcrypt_56_to_64_bit_key(ZPasswordHash + 0, des_key); - des_setkey_enc(&des, des_key); - des_crypt_ecb(&des, challenge, response +0); - - pppcrypt_56_to_64_bit_key(ZPasswordHash + 7, des_key); - des_setkey_enc(&des, des_key); - des_crypt_ecb(&des, challenge, response +8); - - pppcrypt_56_to_64_bit_key(ZPasswordHash + 14, des_key); - des_setkey_enc(&des, des_key); - des_crypt_ecb(&des, challenge, response +16); + (void) DesSetkey(ZPasswordHash + 0); + DesEncrypt(challenge, response + 0); + (void) DesSetkey(ZPasswordHash + 7); + DesEncrypt(challenge, response + 8); + (void) DesSetkey(ZPasswordHash + 14); + DesEncrypt(challenge, response + 16); #if 0 dbglog("ChallengeResponse - response %.24B", response); @@ -568,22 +560,15 @@ ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, int i; u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ u_char PasswordHash[MD4_SIGNATURE_SIZE]; - des_context des; - u_char des_key[8]; /* LANMan password is case insensitive */ BZERO(UcasePassword, sizeof(UcasePassword)); for (i = 0; i < secret_len; i++) UcasePassword[i] = (u_char)toupper(secret[i]); - - pppcrypt_56_to_64_bit_key(UcasePassword +0, des_key); - des_setkey_enc(&des, des_key); - des_crypt_ecb(&des, StdText, PasswordHash +0); - - pppcrypt_56_to_64_bit_key(UcasePassword +7, des_key); - des_setkey_enc(&des, des_key); - des_crypt_ecb(&des, StdText, PasswordHash +8); - + (void) DesSetkey(UcasePassword + 0); + DesEncrypt( StdText, PasswordHash + 0 ); + (void) DesSetkey(UcasePassword + 7); + DesEncrypt( StdText, PasswordHash + 8 ); ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); } #endif diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 1585bcc7..b545cbd0 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -334,7 +334,6 @@ pncrypt_setkey(int timeoffs) strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); SHA1Update(&ctxt, tbuf, strlen(tbuf)); SHA1Final(dig, &ctxt); - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ return (DesSetkey(dig)); } @@ -477,7 +476,6 @@ int status; for (i = 0; i < 5; i++) { pncrypt_setkey(toffs); toffs -= 86400; - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ if (!DesDecrypt(secbuf, clear)) { dbglog("no DES here; cannot decode " "pseudonym"); @@ -502,7 +500,6 @@ int status; dp += i; sp = secbuf + 8; while (plen > 0) { - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesDecrypt(sp, dp); sp += 8; dp += 8; @@ -784,7 +781,6 @@ eap_state *esp; BCOPY(cp, clear + 1, j); i -= j; cp += j; - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ if (!DesEncrypt(clear, cipher)) { dbglog("no DES here; not generating pseudonym"); break; @@ -793,7 +789,6 @@ eap_state *esp; outp++; /* space for pseudonym length */ outp += b64enc(&b64, cipher, 8, outp); while (i >= 8) { - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesEncrypt(cp, cipher); outp += b64enc(&b64, cipher, 8, outp); cp += 8; @@ -806,7 +801,6 @@ eap_state *esp; *cp++ = drand48() * 0x100; i++; } - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesEncrypt(clear, cipher); outp += b64enc(&b64, cipher, 8, outp); } diff --git a/src/netif/ppp/polarssl/README b/src/netif/ppp/polarssl/README deleted file mode 100644 index 8efc8ec1..00000000 --- a/src/netif/ppp/polarssl/README +++ /dev/null @@ -1,33 +0,0 @@ -About PolarSSL files into lwIP PPP support ------------------------------------------- - -This folder contains some files fetched from the PolarSSL project for -ciphers and encryption methods we need for lwIP PPP support. - -The PolarSSL files were cleaned to contain only the necessary struct -fields and functions needed for lwIP. - - -The PolarSSL API was not changed at all, so if you are already using -PolarSSL you can choose to skip the compilation of the included PolarSSL -library into lwIP: - -The following define are available for flexibility: - -LWIP_INCLUDED_POLARSSL_MD4_C ; Use lwIP internal PolarSSL for MD4 -LWIP_INCLUDED_POLARSSL_MD5_C ; Use lwIP internal PolarSSL for MD5 -LWIP_INCLUDED_POLARSSL_SHA1_C ; Use lwIP internal PolarSSL for SHA1 -LWIP_INCLUDED_POLARSSL_DES_C ; Use lwIP internal PolarSSL for DES - -If set (=1), the default if required by another enabled PPP feature unless -explicitely set to 0, using included lwIP PolarSSL. - -If clear (=0), using external PolarSSL. - -Undefined if not needed. - -Beware of the stack requirements which can be a lot larger if you are not -using our cleaned PolarSSL library. - - -PolarSSL project website: http://polarssl.org/ diff --git a/src/netif/ppp/polarssl/des.c b/src/netif/ppp/polarssl/des.c deleted file mode 100644 index b3d98286..00000000 --- a/src/netif/ppp/polarssl/des.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * FIPS-46-3 compliant Triple-DES implementation - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * DES, on which TDES is based, was originally designed by Horst Feistel - * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). - * - * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf - */ - -#include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_DES_C) - -#include "polarssl/des.h" - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_ULONG_BE -#define GET_ULONG_BE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ - | ( (unsigned long) (b)[(i) + 1] << 16 ) \ - | ( (unsigned long) (b)[(i) + 2] << 8 ) \ - | ( (unsigned long) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_ULONG_BE -#define PUT_ULONG_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * Expanded DES S-boxes - */ -static const unsigned long SB1[64] = -{ - 0x01010400, 0x00000000, 0x00010000, 0x01010404, - 0x01010004, 0x00010404, 0x00000004, 0x00010000, - 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, - 0x00000404, 0x01000400, 0x01000400, 0x00010400, - 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, - 0x00000000, 0x00000404, 0x00010404, 0x01000000, - 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, - 0x01010004, 0x00010000, 0x00010400, 0x01000004, - 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, - 0x01000004, 0x00000404, 0x00010404, 0x01010400, - 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 -}; - -static const unsigned long SB2[64] = -{ - 0x80108020, 0x80008000, 0x00008000, 0x00108020, - 0x00100000, 0x00000020, 0x80100020, 0x80008020, - 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, - 0x00108000, 0x00100020, 0x80008020, 0x00000000, - 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, - 0x00008020, 0x80108000, 0x80100000, 0x00008020, - 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, - 0x80100000, 0x80008000, 0x00000020, 0x80108020, - 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, - 0x00100020, 0x80008020, 0x80000020, 0x00100020, - 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 -}; - -static const unsigned long SB3[64] = -{ - 0x00000208, 0x08020200, 0x00000000, 0x08020008, - 0x08000200, 0x00000000, 0x00020208, 0x08000200, - 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, - 0x08000000, 0x00000008, 0x08020200, 0x00000200, - 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, - 0x00000008, 0x08020208, 0x00000200, 0x08000000, - 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, - 0x00000200, 0x00020008, 0x08020208, 0x08000200, - 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, - 0x00000008, 0x00020208, 0x00020200, 0x08000008, - 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 -}; - -static const unsigned long SB4[64] = -{ - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802080, 0x00800081, 0x00800001, 0x00002001, - 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, - 0x00000001, 0x00002000, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, - 0x00002000, 0x00802080, 0x00802081, 0x00000081, - 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, - 0x00002080, 0x00800080, 0x00800081, 0x00000001, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, - 0x00800001, 0x00002001, 0x00802080, 0x00800081, - 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 -}; - -static const unsigned long SB5[64] = -{ - 0x00000100, 0x02080100, 0x02080000, 0x42000100, - 0x00080000, 0x00000100, 0x40000000, 0x02080000, - 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, - 0x02000000, 0x40080000, 0x40080000, 0x00000000, - 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, - 0x02080100, 0x02000000, 0x42000000, 0x00080100, - 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, - 0x02000100, 0x40000000, 0x42080000, 0x02080100, - 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, - 0x02080000, 0x00000000, 0x40080000, 0x42000000, - 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 -}; - -static const unsigned long SB6[64] = -{ - 0x20000010, 0x20400000, 0x00004000, 0x20404010, - 0x20400000, 0x00000010, 0x20404010, 0x00400000, - 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, - 0x00000000, 0x00400010, 0x20004010, 0x00004000, - 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, - 0x00004010, 0x00404000, 0x20404000, 0x20000000, - 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, - 0x00400000, 0x20004000, 0x20000000, 0x00004010, - 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, - 0x00000010, 0x00004000, 0x20400000, 0x00404010, - 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 -}; - -static const unsigned long SB7[64] = -{ - 0x00200000, 0x04200002, 0x04000802, 0x00000000, - 0x00000800, 0x04000802, 0x00200802, 0x04200800, - 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, - 0x04000800, 0x00200802, 0x00200002, 0x04000800, - 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, - 0x00200800, 0x00000002, 0x04000000, 0x00200800, - 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, - 0x00200002, 0x04000000, 0x04000800, 0x00200000, - 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, - 0x00200800, 0x00000000, 0x00000002, 0x04200802, - 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 -}; - -static const unsigned long SB8[64] = -{ - 0x10001040, 0x00001000, 0x00040000, 0x10041040, - 0x10000000, 0x10001040, 0x00000040, 0x10000000, - 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, - 0x10040000, 0x10000040, 0x10001000, 0x00001040, - 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, - 0x10000040, 0x10001000, 0x00041040, 0x00040000, - 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, - 0x10001000, 0x00000040, 0x10000040, 0x10040000, - 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, - 0x10040000, 0x10001000, 0x10001040, 0x00000000, - 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 -}; - -/* - * PC1: left and right halves bit-swap - */ -static const unsigned long LHs[16] = -{ - 0x00000000, 0x00000001, 0x00000100, 0x00000101, - 0x00010000, 0x00010001, 0x00010100, 0x00010101, - 0x01000000, 0x01000001, 0x01000100, 0x01000101, - 0x01010000, 0x01010001, 0x01010100, 0x01010101 -}; - -static const unsigned long RHs[16] = -{ - 0x00000000, 0x01000000, 0x00010000, 0x01010000, - 0x00000100, 0x01000100, 0x00010100, 0x01010100, - 0x00000001, 0x01000001, 0x00010001, 0x01010001, - 0x00000101, 0x01000101, 0x00010101, 0x01010101, -}; - -/* - * Initial Permutation macro - */ -#define DES_IP(X,Y) \ -{ \ - T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ - T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ - T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ - T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ - Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ - T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ - X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ -} - -/* - * Final Permutation macro - */ -#define DES_FP(X,Y) \ -{ \ - X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ - T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ - Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ - T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ - T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ - T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ - T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ -} - -/* - * DES round macro - */ -#define DES_ROUND(X,Y) \ -{ \ - T = *SK++ ^ X; \ - Y ^= SB8[ (T ) & 0x3F ] ^ \ - SB6[ (T >> 8) & 0x3F ] ^ \ - SB4[ (T >> 16) & 0x3F ] ^ \ - SB2[ (T >> 24) & 0x3F ]; \ - \ - T = *SK++ ^ ((X << 28) | (X >> 4)); \ - Y ^= SB7[ (T ) & 0x3F ] ^ \ - SB5[ (T >> 8) & 0x3F ] ^ \ - SB3[ (T >> 16) & 0x3F ] ^ \ - SB1[ (T >> 24) & 0x3F ]; \ -} - -#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } - -static void des_setkey( unsigned long SK[32], const unsigned char key[DES_KEY_SIZE] ) -{ - int i; - unsigned long X, Y, T; - - GET_ULONG_BE( X, key, 0 ); - GET_ULONG_BE( Y, key, 4 ); - - /* - * Permuted Choice 1 - */ - T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); - T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); - - X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) - | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) - | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) - | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); - - Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) - | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) - | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) - | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); - - X &= 0x0FFFFFFF; - Y &= 0x0FFFFFFF; - - /* - * calculate subkeys - */ - for( i = 0; i < 16; i++ ) - { - if( i < 2 || i == 8 || i == 15 ) - { - X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; - Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; - } - else - { - X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; - Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; - } - - *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) - | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) - | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) - | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) - | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) - | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) - | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) - | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) - | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) - | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) - | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); - - *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) - | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) - | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) - | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) - | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) - | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) - | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) - | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) - | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) - | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) - | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); - } -} - -/* - * DES key schedule (56-bit, encryption) - */ -int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) -{ - des_setkey( ctx->sk, key ); - - return( 0 ); -} - -/* - * DES key schedule (56-bit, decryption) - */ -int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) -{ - int i; - - des_setkey( ctx->sk, key ); - - for( i = 0; i < 16; i += 2 ) - { - SWAP( ctx->sk[i ], ctx->sk[30 - i] ); - SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); - } - - return( 0 ); -} - -/* - * DES-ECB block encryption/decryption - */ -int des_crypt_ecb( des_context *ctx, - const unsigned char input[8], - unsigned char output[8] ) -{ - int i; - unsigned long X, Y, T, *SK; - - SK = ctx->sk; - - GET_ULONG_BE( X, input, 0 ); - GET_ULONG_BE( Y, input, 4 ); - - DES_IP( X, Y ); - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( Y, X ); - DES_ROUND( X, Y ); - } - - DES_FP( Y, X ); - - PUT_ULONG_BE( Y, output, 0 ); - PUT_ULONG_BE( X, output, 4 ); - - return( 0 ); -} - -#endif /* LWIP_INCLUDED_POLARSSL_DES_C */ diff --git a/src/netif/ppp/polarssl/des.h b/src/netif/ppp/polarssl/des.h deleted file mode 100644 index 21d84601..00000000 --- a/src/netif/ppp/polarssl/des.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * \file des.h - * - * \brief DES block cipher - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef LWIP_INCLUDED_POLARSSL_DES_H -#define LWIP_INCLUDED_POLARSSL_DES_H - -#define DES_ENCRYPT 1 -#define DES_DECRYPT 0 - -#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ - -#define DES_KEY_SIZE 8 - -/** - * \brief DES context structure - */ -typedef struct -{ - int mode; /*!< encrypt/decrypt */ - unsigned long sk[32]; /*!< DES subkeys */ -} -des_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief DES key schedule (56-bit, encryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - * - * \return 0 - */ -int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); - -/** - * \brief DES key schedule (56-bit, decryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - * - * \return 0 - */ -int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); - -/** - * \brief DES-ECB block encryption/decryption - * - * \param ctx DES context - * \param input 64-bit input block - * \param output 64-bit output block - * - * \return 0 if successful - */ -int des_crypt_ecb( des_context *ctx, - const unsigned char input[8], - unsigned char output[8] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_DES_H */ diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index 9bde8953..1a66f680 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -32,13 +32,15 @@ #include "lwip/opt.h" -/* FIXME: dont include if not needed */ - +#include #include "pppd.h" #include "pppcrypt.h" - -static u_char pppcrypt_get_7bits(u_char *input, int startBit) { +static u_char +Get7Bits(input, startBit) +u_char *input; +int startBit; +{ unsigned int word; word = (unsigned)input[startBit / 8] << 8; @@ -49,16 +51,145 @@ static u_char pppcrypt_get_7bits(u_char *input, int startBit) { return word & 0xFE; } -/* IN 56 bit DES key missing parity bits - * OUT 64 bit DES key with parity bits added - */ -void pppcrypt_56_to_64_bit_key(u_char *key, u_char * des_key) { - des_key[0] = pppcrypt_get_7bits(key, 0); - des_key[1] = pppcrypt_get_7bits(key, 7); - des_key[2] = pppcrypt_get_7bits(key, 14); - des_key[3] = pppcrypt_get_7bits(key, 21); - des_key[4] = pppcrypt_get_7bits(key, 28); - des_key[5] = pppcrypt_get_7bits(key, 35); - des_key[6] = pppcrypt_get_7bits(key, 42); - des_key[7] = pppcrypt_get_7bits(key, 49); +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 } + +#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; + } +} + +bool +DesSetkey(key) +u_char *key; +{ + u_char des_key[8]; + u_char crypt_key[66]; + + MakeKey(key, des_key); + Expand(des_key, crypt_key); + errno = 0; + setkey((const char *)crypt_key); + if (errno != 0) + return (0); + return (1); +} + +bool +DesEncrypt(clear, cipher) +u_char *clear; /* IN 8 octets */ +u_char *cipher; /* OUT 8 octets */ +{ + u_char des_input[66]; + + Expand(clear, des_input); + errno = 0; + encrypt((char *)des_input, 0); + if (errno != 0) + return (0); + Collapse(des_input, cipher); + return (1); +} + +bool +DesDecrypt(cipher, clear) +u_char *cipher; /* IN 8 octets */ +u_char *clear; /* OUT 8 octets */ +{ + u_char des_input[66]; + + Expand(cipher, des_input); + errno = 0; + encrypt((char *)des_input, 1); + if (errno != 0) + return (0); + Collapse(des_input, clear); + return (1); +} + +#else /* USE_CRYPT */ +static des_key_schedule key_schedule; + +bool +DesSetkey(key) +u_char *key; +{ + des_cblock des_key; + MakeKey(key, des_key); + des_set_key(&des_key, key_schedule); + return (1); +} + +bool +DesEncrypt(clear, key, cipher) +u_char *clear; /* IN 8 octets */ +u_char *cipher; /* OUT 8 octets */ +{ + des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, + key_schedule, 1); + return (1); +} + +bool +DesDecrypt(cipher, clear) +u_char *cipher; /* IN 8 octets */ +u_char *clear; /* OUT 8 octets */ +{ + des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, + key_schedule, 0); + return (1); +} + +#endif /* USE_CRYPT */ diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h index 6b5eaf8b..adcdcbcb 100644 --- a/src/netif/ppp/pppcrypt.h +++ b/src/netif/ppp/pppcrypt.h @@ -33,6 +33,16 @@ #ifndef PPPCRYPT_H #define PPPCRYPT_H -void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key); +#ifdef HAVE_CRYPT_H +#include +#endif + +#ifndef USE_CRYPT +#include +#endif + +extern bool DesSetkey __P((u_char *)); +extern bool DesEncrypt __P((u_char *, u_char *)); +extern bool DesDecrypt __P((u_char *, u_char *)); #endif /* PPPCRYPT_H */ From 624da03badb91e9a81d7ed9659cf0de88ae3e0df Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 20:40:08 +0200 Subject: [PATCH 025/320] Revert "modified auth_reset() so that we can choose which auth we want" This reverts commit bf10a27db89eb64a50df40a173b2d012b47586e3. Licence issue, we cannot include GPLed source code. --- src/netif/ppp/auth.c | 58 +++++++++------------------------------- src/netif/ppp/chap-new.c | 10 +++++-- src/netif/ppp/chap_ms.c | 15 ++++++++++- src/netif/ppp/pppmy.c | 9 ------- src/netif/ppp/pppmy.h | 3 +-- 5 files changed, 35 insertions(+), 60 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 08410fd0..3036721d 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1292,42 +1292,21 @@ void auth_reset(unit) int unit; { - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - - if( ppp_settings.passwd[0] ) { - - ao->neg_upap = !ppp_settings.refuse_pap; - - ao->neg_eap = !ppp_settings.refuse_eap; - - ao->chap_mdtype = MDTYPE_NONE; - if(!ppp_settings.refuse_chap) - ao->chap_mdtype |= MDTYPE_MD5; - if(!ppp_settings.refuse_mschap) - ao->chap_mdtype |= MDTYPE_MICROSOFT; - if(!ppp_settings.refuse_mschap_v2) - ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; - - ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); - - } else { - ao->neg_upap = 0; - ao->neg_chap = 0; - ao->neg_eap = 0; - ao->chap_mdtype = MDTYPE_NONE; - } - - - printf("neg_upap: %d\n", ao->neg_upap); - printf("neg_chap: %d\n", ao->neg_chap); - printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); - printf("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT) ); - printf("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2) ); - printf("neg_eap: %d\n", ao->neg_eap); + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *ao = &lcp_allowoptions[unit]; + int hadchap; + hadchap = -1; //ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); + ao->neg_upap = !ppp_settings.refuse_pap && ppp_settings.passwd[0] != 0; + + ao->neg_chap = (!ppp_settings.refuse_chap || !ppp_settings.refuse_mschap || !ppp_settings.refuse_mschap_v2) && ppp_settings.passwd[0]; + + ao->neg_eap = !ppp_settings.refuse_eap && ppp_settings.passwd[0] != 0; + + return; + /* ao->neg_chap = (!ppp_settings.refuse_chap || !refuse_mschap || !refuse_mschap_v2) && (passwd[0] != 0 || @@ -1340,26 +1319,15 @@ auth_reset(unit) (explicit_remote? remote_name: NULL), 0, NULL))) || have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); */ - go->neg_upap = 0; - go->neg_chap = 0; - go->neg_eap = 0; - go->chap_mdtype = MDTYPE_NONE; - return; - /* FIXME: find what the below stuff do */ - int hadchap; - hadchap = -1; - hadchap = -1; if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) go->neg_upap = 0; - if (go->neg_chap) { if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL))) go->neg_chap = 0; } - if (go->neg_eap && (hadchap == 0 || (hadchap == -1 && !have_chap_secret((explicit_remote? remote_name: NULL), our_name, @@ -1763,8 +1731,6 @@ get_secret(unit, client, server, secret, secret_len, am_server) *secret_len = len; return 1; - -/* FIXME: clean that */ #if 0 // strlcpy(rname, ppp_settings.user, sizeof(rname)); diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 7d773537..5fe183f8 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -456,8 +456,14 @@ chap_respond(struct chap_client_state *cs, int id, slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); /* Microsoft doesn't send their name back in the PPP packet */ - if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) - strlcpy(rname, remote_name, sizeof(rname)); + if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rname[0] == 0)) { + strncpy(rname, ppp_settings.remote_name, sizeof(rname)); + rname[sizeof(rname) - 1] = 0; + } + +// /* Microsoft doesn't send their name back in the PPP packet */ +// if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) +// strlcpy(rname, remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 188e721b..9efa2066 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -512,11 +512,24 @@ ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) { +#ifdef __NetBSD__ + /* NetBSD uses the libc md4 routines which take bytes instead of bits */ + int mdlen = secret_len; +#else + int mdlen = secret_len * 8; +#endif md4_context md4Context; md4_starts(&md4Context); - md4_update(&md4Context, secret, secret_len); + /* MD4Update can take at most 64 bytes at a time */ + while (mdlen > 512) { + md4_update(&md4Context, secret, 512); + secret += 64; + mdlen -= 512; + } + md4_update(&md4Context, secret, mdlen); md4_finish(&md4Context, hash); + } static void diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 3352b2ba..8085741b 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -435,14 +435,6 @@ int ppp_init(void) { void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { - ppp_settings.refuse_pap = 1; - ppp_settings.refuse_chap = 1; - ppp_settings.refuse_mschap = 1; - ppp_settings.refuse_mschap_v2 = 0; - ppp_settings.refuse_eap = 1; - -/* FIXME: re-enable that */ -#if 0 switch(authType) { case PPPAUTHTYPE_NONE: default: @@ -489,7 +481,6 @@ pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) ppp_settings.refuse_chap = 0; break; } -#endif if(user) { strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 07099ecd..e79f43fa 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -58,8 +58,7 @@ struct ppp_settings { char user [MAXNAMELEN + 1]; /* Username for PAP */ char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ - // FIXME: re-enable that - // char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ + char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ }; struct ppp_settings ppp_settings; From ca2fd867b8e6b92ab4338c504e5b9567ab76e414 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 20:40:27 +0200 Subject: [PATCH 026/320] Revert "Replaced md4/md5/sha1 implementations to PolarSSL ones" This reverts commit aa2656cb9e8f6cdd7921fc36d5e00060065058a4. Licence issue, we cannot include GPLed source code. --- src/netif/ppp/chap-md5.c | 26 +-- src/netif/ppp/chap_ms.c | 97 +++++----- src/netif/ppp/eap.c | 26 +-- src/netif/ppp/magic.c | 24 +-- src/netif/ppp/md4.c | 301 +++++++++++++++++++++++++++++++ src/netif/ppp/md4.h | 64 +++++++ src/netif/ppp/md5.c | 309 ++++++++++++++++++++++++++++++++ src/netif/ppp/md5.h | 65 +++++++ src/netif/ppp/polarssl/md4.c | 271 ---------------------------- src/netif/ppp/polarssl/md4.h | 82 --------- src/netif/ppp/polarssl/md5.c | 290 ------------------------------ src/netif/ppp/polarssl/md5.h | 82 --------- src/netif/ppp/polarssl/sha1.c | 325 ---------------------------------- src/netif/ppp/polarssl/sha1.h | 82 --------- src/netif/ppp/sha1.c | 172 ++++++++++++++++++ src/netif/ppp/sha1.h | 31 ++++ 16 files changed, 1028 insertions(+), 1219 deletions(-) create mode 100644 src/netif/ppp/md4.c create mode 100644 src/netif/ppp/md4.h create mode 100644 src/netif/ppp/md5.c create mode 100644 src/netif/ppp/md5.h delete mode 100644 src/netif/ppp/polarssl/md4.c delete mode 100644 src/netif/ppp/polarssl/md4.h delete mode 100644 src/netif/ppp/polarssl/md5.c delete mode 100644 src/netif/ppp/polarssl/md5.h delete mode 100644 src/netif/ppp/polarssl/sha1.c delete mode 100644 src/netif/ppp/polarssl/sha1.h create mode 100644 src/netif/ppp/sha1.c create mode 100644 src/netif/ppp/sha1.h diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index dec34cfd..513fe430 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -38,7 +38,7 @@ #include "chap-new.h" #include "chap-md5.h" #include "magic.h" -#include "polarssl/md5.h" +#include "md5.h" #define MD5_HASH_SIZE 16 #define MD5_MIN_CHALLENGE 16 @@ -61,7 +61,7 @@ chap_md5_verify_response(int id, char *name, unsigned char *challenge, unsigned char *response, char *message, int message_space) { - md5_context ctx; + MD5_CTX ctx; unsigned char idbyte = id; unsigned char hash[MD5_HASH_SIZE]; int challenge_len, response_len; @@ -70,11 +70,11 @@ chap_md5_verify_response(int id, char *name, response_len = *response++; if (response_len == MD5_HASH_SIZE) { /* Generate hash of ID, secret, challenge */ - md5_starts(&ctx); - md5_update(&ctx, &idbyte, 1); - md5_update(&ctx, secret, secret_len); - md5_update(&ctx, challenge, challenge_len); - md5_finish(&ctx, hash); + MD5_Init(&ctx); + MD5_Update(&ctx, &idbyte, 1); + MD5_Update(&ctx, secret, secret_len); + MD5_Update(&ctx, challenge, challenge_len); + MD5_Final(hash, &ctx); /* Test if our hash matches the peer's response */ if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { @@ -91,15 +91,15 @@ chap_md5_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { - md5_context ctx; + MD5_CTX ctx; unsigned char idbyte = id; int challenge_len = *challenge++; - md5_starts(&ctx); - md5_update(&ctx, &idbyte, 1); - md5_update(&ctx, (u_char *)secret, secret_len); - md5_update(&ctx, challenge, challenge_len); - md5_finish(&ctx, &response[1]); + MD5_Init(&ctx); + MD5_Update(&ctx, &idbyte, 1); + MD5_Update(&ctx, (u_char *)secret, secret_len); + MD5_Update(&ctx, challenge, challenge_len); + MD5_Final(&response[1], &ctx); response[0] = MD5_HASH_SIZE; } diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 9efa2066..0d3b5347 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -91,14 +91,13 @@ #include "pppd.h" #include "chap-new.h" #include "chap_ms.h" -#include "polarssl/md4.h" -#include "polarssl/sha1.h" +#include "md4.h" +#include "sha1.h" #include "pppcrypt.h" #include "magic.h" static const char rcsid[] = RCSID; -#define SHA1_SIGNATURE_SIZE 20 static void ascii2unicode __P((char[], int, u_char[])); static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); @@ -473,7 +472,7 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, char *username, u_char Challenge[8]) { - sha1_context sha1Context; + SHA1_CTX sha1Context; u_char sha1Hash[SHA1_SIGNATURE_SIZE]; char *user; @@ -483,11 +482,11 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, else user = username; - sha1_starts(&sha1Context); - sha1_update(&sha1Context, PeerChallenge, 16); - sha1_update(&sha1Context, rchallenge, 16); - sha1_update(&sha1Context, (unsigned char *)user, strlen(user)); - sha1_finish(&sha1Context, sha1Hash); + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PeerChallenge, 16); + SHA1_Update(&sha1Context, rchallenge, 16); + SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user)); + SHA1_Final(sha1Hash, &sha1Context); BCOPY(sha1Hash, Challenge, 8); } @@ -518,17 +517,17 @@ NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) #else int mdlen = secret_len * 8; #endif - md4_context md4Context; + MD4_CTX md4Context; - md4_starts(&md4Context); + MD4Init(&md4Context); /* MD4Update can take at most 64 bytes at a time */ while (mdlen > 512) { - md4_update(&md4Context, secret, 512); + MD4Update(&md4Context, secret, 512); secret += 64; mdlen -= 512; } - md4_update(&md4Context, secret, mdlen); - md4_finish(&md4Context, hash); + MD4Update(&md4Context, secret, mdlen); + MD4Final(hash, &md4Context); } @@ -609,23 +608,23 @@ GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], 0x6E }; int i; - sha1_context sha1Context; + SHA1_CTX sha1Context; u_char Digest[SHA1_SIGNATURE_SIZE]; u_char Challenge[8]; - sha1_starts(&sha1Context); - sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - sha1_update(&sha1Context, NTResponse, 24); - sha1_update(&sha1Context, Magic1, sizeof(Magic1)); - sha1_finish(&sha1Context, Digest); + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, NTResponse, 24); + SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); + SHA1_Final(Digest, &sha1Context); ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - sha1_starts(&sha1Context); - sha1_update(&sha1Context, Digest, sizeof(Digest)); - sha1_update(&sha1Context, Challenge, sizeof(Challenge)); - sha1_update(&sha1Context, Magic2, sizeof(Magic2)); - sha1_finish(&sha1Context, Digest); + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, Digest, sizeof(Digest)); + SHA1_Update(&sha1Context, Challenge, sizeof(Challenge)); + SHA1_Update(&sha1Context, Magic2, sizeof(Magic2)); + SHA1_Final(Digest, &sha1Context); /* Convert to ASCII hex string. */ for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) @@ -663,14 +662,14 @@ GenerateAuthenticatorResponsePlain void mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) { - sha1_context sha1Context; + SHA1_CTX sha1Context; u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - sha1_starts(&sha1Context); - sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - sha1_update(&sha1Context, rchallenge, 8); - sha1_finish(&sha1Context, Digest); + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, rchallenge, 8); + SHA1_Final(Digest, &sha1Context); /* Same key in both directions. */ BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); @@ -707,7 +706,7 @@ void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], int IsServer) { - sha1_context sha1Context; + SHA1_CTX sha1Context; u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ @@ -753,11 +752,11 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], 0x6b, 0x65, 0x79, 0x2e }; u_char *s; - sha1_starts(&sha1Context); - sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - sha1_update(&sha1Context, NTResponse, 24); - sha1_update(&sha1Context, Magic1, sizeof(Magic1)); - sha1_finish(&sha1Context, MasterKey); + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, NTResponse, 24); + SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); + SHA1_Final(MasterKey, &sha1Context); /* * generate send key @@ -766,12 +765,12 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], s = Magic3; else s = Magic2; - sha1_starts(&sha1Context); - sha1_update(&sha1Context, MasterKey, 16); - sha1_update(&sha1Context, SHApad1, sizeof(SHApad1)); - sha1_update(&sha1Context, s, 84); - sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); - sha1_finish(&sha1Context, Digest); + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, MasterKey, 16); + SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); + SHA1_Update(&sha1Context, s, 84); + SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); + SHA1_Final(Digest, &sha1Context); BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); @@ -782,12 +781,12 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], s = Magic2; else s = Magic3; - sha1_starts(&sha1Context); - sha1_update(&sha1Context, MasterKey, 16); - sha1_update(&sha1Context, SHApad1, sizeof(SHApad1)); - sha1_update(&sha1Context, s, 84); - sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); - sha1_finish(&sha1Context, Digest); + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, MasterKey, 16); + SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); + SHA1_Update(&sha1Context, s, 84); + SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); + SHA1_Final(Digest, &sha1Context); BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index b545cbd0..b082284a 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -64,7 +64,7 @@ #include "pppd.h" #include "pathnames.h" -#include "polarssl/md5.h" +#include "md5.h" #include "eap.h" #ifdef USE_SRP @@ -1322,7 +1322,7 @@ int len; int secret_len; char secret[MAXWORDLEN]; char rhostname[256]; - md5_context mdContext; + MD5_CTX mdContext; u_char hash[MD5_SIGNATURE_SIZE]; #ifdef USE_SRP struct t_client *tc; @@ -1449,13 +1449,13 @@ int len; eap_send_nak(esp, id, EAPT_SRP); break; } - md5_starts(&mdContext); + MD5_Init(&mdContext); typenum = id; - md5_update(&mdContext, &typenum, 1); - md5_update(&mdContext, (u_char *)secret, secret_len); + MD5_Update(&mdContext, &typenum, 1); + MD5_Update(&mdContext, (u_char *)secret, secret_len); BZERO(secret, sizeof (secret)); - md5_update(&mdContext, inp, vallen); - md5_finish(&mdContext, hash); + MD5_Update(&mdContext, inp, vallen); + MD5_Final(hash, &mdContext); eap_chap_response(esp, id, hash, esp->es_client.ea_name, esp->es_client.ea_namelen); break; @@ -1732,7 +1732,7 @@ int len; int secret_len; char secret[MAXSECRETLEN]; char rhostname[256]; - md5_context mdContext; + MD5_CTX mdContext; u_char hash[MD5_SIGNATURE_SIZE]; #ifdef USE_SRP struct t_server *ts; @@ -1875,12 +1875,12 @@ int len; eap_send_failure(esp); break; } - md5_starts(&mdContext); - md5_update(&mdContext, &esp->es_server.ea_id, 1); - md5_update(&mdContext, (u_char *)secret, secret_len); + MD5_Init(&mdContext); + MD5_Update(&mdContext, &esp->es_server.ea_id, 1); + MD5_Update(&mdContext, (u_char *)secret, secret_len); BZERO(secret, sizeof (secret)); - md5_update(&mdContext, esp->es_challenge, esp->es_challen); - md5_finish(&mdContext, hash); + MD5_Update(&mdContext, esp->es_challenge, esp->es_challen); + MD5_Final(hash, &mdContext); if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { eap_send_failure(esp); break; diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index de65a96e..2360ecc8 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -76,7 +76,7 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "polarssl/md5.h" +#include "md5.h" #include "magic.h" #include "pppd.h" #include "pppmy.h" @@ -108,13 +108,13 @@ static long magic_randcount = 0; /* Pseudo-random incrementer */ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 */ void magic_churnrand(char *rand_data, u32_t rand_len) { - md5_context md5; + MD5_CTX md5; /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", rand_len, rand_data)); */ - md5_starts(&md5); - md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + MD5_Init(&md5); + MD5_Update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); if (rand_data) { - md5_update(&md5, (u_char *)rand_data, rand_len); + MD5_Update(&md5, (u_char *)rand_data, rand_len); } else { struct { /* INCLUDE fields for any system sources of randomness */ @@ -122,9 +122,9 @@ void magic_churnrand(char *rand_data, u32_t rand_len) { } sys_data; /* Load sys_data fields here. */ - md5_update(&md5, (u_char *)&sys_data, sizeof(sys_data)); + MD5_Update(&md5, (u_char *)&sys_data, sizeof(sys_data)); } - md5_finish(&md5, (u_char *)magic_randpool); + MD5_Final((u_char *)magic_randpool, &md5); /* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ } @@ -161,16 +161,16 @@ void magic_randomize(void) { * it was documented. */ void random_bytes(unsigned char *buf, u32_t buf_len) { - md5_context md5; + MD5_CTX md5; u_char tmp[16]; u32_t n; while (buf_len > 0) { n = LWIP_MIN(buf_len, MAGIC_RANDPOOLSIZE); - md5_starts(&md5); - md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); - md5_update(&md5, (u_char *)&magic_randcount, sizeof(magic_randcount)); - md5_finish(&md5, tmp); + MD5_Init(&md5); + MD5_Update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + MD5_Update(&md5, (u_char *)&magic_randcount, sizeof(magic_randcount)); + MD5_Final(tmp, &md5); magic_randcount++; MEMCPY(buf, tmp, n); buf += n; diff --git a/src/netif/ppp/md4.c b/src/netif/ppp/md4.c new file mode 100644 index 00000000..f0831a92 --- /dev/null +++ b/src/netif/ppp/md4.c @@ -0,0 +1,301 @@ +/* +** ******************************************************************** +** md4.c -- Implementation of MD4 Message Digest Algorithm ** +** Updated: 2/16/90 by Ronald L. Rivest ** +** (C) 1990 RSA Data Security, Inc. ** +** ******************************************************************** +*/ + +#include "lwip/opt.h" + +/* +** To use MD4: +** -- Include md4.h in your program +** -- Declare an MDstruct MD to hold the state of the digest +** computation. +** -- Initialize MD using MDbegin(&MD) +** -- For each full block (64 bytes) X you wish to process, call +** MD4Update(&MD,X,512) +** (512 is the number of bits in a full block.) +** -- For the last block (less than 64 bytes) you wish to process, +** MD4Update(&MD,X,n) +** where n is the number of bits in the partial block. A partial +** block terminates the computation, so every MD computation +** should terminate by processing a partial block, even if it +** has n = 0. +** -- The message digest is available in MD.buffer[0] ... +** MD.buffer[3]. (Least-significant byte of each word +** should be output first.) +** -- You can print out the digest using MDprint(&MD) +*/ + +/* Implementation notes: +** This implementation assumes that ints are 32-bit quantities. +*/ + +#define TRUE 1 +#define FALSE 0 + +/* Compile-time includes +*/ +#include +#include "md4.h" +#include "pppd.h" + +/* Compile-time declarations of MD4 "magic constants". +*/ +#define I0 0x67452301 /* Initial values for MD buffer */ +#define I1 0xefcdab89 +#define I2 0x98badcfe +#define I3 0x10325476 +#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ +#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ +/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 +** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. +** Table 2, page 660. +*/ + +#define fs1 3 /* round 1 shift amounts */ +#define fs2 7 +#define fs3 11 +#define fs4 19 +#define gs1 3 /* round 2 shift amounts */ +#define gs2 5 +#define gs3 9 +#define gs4 13 +#define hs1 3 /* round 3 shift amounts */ +#define hs2 9 +#define hs3 11 +#define hs4 15 + +/* Compile-time macro declarations for MD4. +** Note: The "rot" operator uses the variable "tmp". +** It assumes tmp is declared as unsigned int, so that the >> +** operator will shift in zeros rather than extending the sign bit. +*/ +#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) +#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) +#define h(X,Y,Z) (X^Y^Z) +#define rot(X,S) (tmp=X,(tmp<>(32-S))) +#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) +#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) +#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) + +/* MD4print(MDp) +** Print message digest buffer MDp as 32 hexadecimal digits. +** Order is from low-order byte of buffer[0] to high-order byte of +** buffer[3]. +** Each byte is printed with high-order hexadecimal digit first. +** This is a user-callable routine. +*/ +void +MD4Print(MDp) +MD4_CTX *MDp; +{ + int i,j; + for (i=0;i<4;i++) + for (j=0;j<32;j=j+8) + printf("%02x",(MDp->buffer[i]>>j) & 0xFF); +} + +/* MD4Init(MDp) +** Initialize message digest buffer MDp. +** This is a user-callable routine. +*/ +void +MD4Init(MDp) +MD4_CTX *MDp; +{ + int i; + MDp->buffer[0] = I0; + MDp->buffer[1] = I1; + MDp->buffer[2] = I2; + MDp->buffer[3] = I3; + for (i=0;i<8;i++) MDp->count[i] = 0; + MDp->done = 0; +} + +/* MDblock(MDp,X) +** Update message digest buffer MDp->buffer using 16-word data block X. +** Assumes all 16 words of X are full of data. +** Does not update MDp->count. +** This routine is not user-callable. +*/ +static void +MDblock(MDp,Xb) +MD4_CTX *MDp; +unsigned char *Xb; +{ + register unsigned int tmp, A, B, C, D; + unsigned int X[16]; + int i; + + for (i = 0; i < 16; ++i) { + X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); + Xb += 4; + } + + A = MDp->buffer[0]; + B = MDp->buffer[1]; + C = MDp->buffer[2]; + D = MDp->buffer[3]; + /* Update the message digest buffer */ + ff(A , B , C , D , 0 , fs1); /* Round 1 */ + ff(D , A , B , C , 1 , fs2); + ff(C , D , A , B , 2 , fs3); + ff(B , C , D , A , 3 , fs4); + ff(A , B , C , D , 4 , fs1); + ff(D , A , B , C , 5 , fs2); + ff(C , D , A , B , 6 , fs3); + ff(B , C , D , A , 7 , fs4); + ff(A , B , C , D , 8 , fs1); + ff(D , A , B , C , 9 , fs2); + ff(C , D , A , B , 10 , fs3); + ff(B , C , D , A , 11 , fs4); + ff(A , B , C , D , 12 , fs1); + ff(D , A , B , C , 13 , fs2); + ff(C , D , A , B , 14 , fs3); + ff(B , C , D , A , 15 , fs4); + gg(A , B , C , D , 0 , gs1); /* Round 2 */ + gg(D , A , B , C , 4 , gs2); + gg(C , D , A , B , 8 , gs3); + gg(B , C , D , A , 12 , gs4); + gg(A , B , C , D , 1 , gs1); + gg(D , A , B , C , 5 , gs2); + gg(C , D , A , B , 9 , gs3); + gg(B , C , D , A , 13 , gs4); + gg(A , B , C , D , 2 , gs1); + gg(D , A , B , C , 6 , gs2); + gg(C , D , A , B , 10 , gs3); + gg(B , C , D , A , 14 , gs4); + gg(A , B , C , D , 3 , gs1); + gg(D , A , B , C , 7 , gs2); + gg(C , D , A , B , 11 , gs3); + gg(B , C , D , A , 15 , gs4); + hh(A , B , C , D , 0 , hs1); /* Round 3 */ + hh(D , A , B , C , 8 , hs2); + hh(C , D , A , B , 4 , hs3); + hh(B , C , D , A , 12 , hs4); + hh(A , B , C , D , 2 , hs1); + hh(D , A , B , C , 10 , hs2); + hh(C , D , A , B , 6 , hs3); + hh(B , C , D , A , 14 , hs4); + hh(A , B , C , D , 1 , hs1); + hh(D , A , B , C , 9 , hs2); + hh(C , D , A , B , 5 , hs3); + hh(B , C , D , A , 13 , hs4); + hh(A , B , C , D , 3 , hs1); + hh(D , A , B , C , 11 , hs2); + hh(C , D , A , B , 7 , hs3); + hh(B , C , D , A , 15 , hs4); + MDp->buffer[0] += A; + MDp->buffer[1] += B; + MDp->buffer[2] += C; + MDp->buffer[3] += D; +} + +/* MD4Update(MDp,X,count) +** Input: X -- a pointer to an array of unsigned characters. +** count -- the number of bits of X to use. +** (if not a multiple of 8, uses high bits of last byte.) +** Update MDp using the number of bits of X given by count. +** This is the basic input routine for an MD4 user. +** The routine completes the MD computation when count < 512, so +** every MD computation should end with one call to MD4Update with a +** count less than 512. A call with count 0 will be ignored if the +** MD has already been terminated (done != 0), so an extra call with +** count 0 can be given as a "courtesy close" to force termination +** if desired. +*/ +void +MD4Update(MDp,X,count) +MD4_CTX *MDp; +unsigned char *X; +unsigned int count; +{ + unsigned int i, tmp, bit, byte, mask; + unsigned char XX[64]; + unsigned char *p; + + /* return with no error if this is a courtesy close with count + ** zero and MDp->done is true. + */ + if (count == 0 && MDp->done) return; + /* check to see if MD is already done and report error */ + if (MDp->done) + { printf("\nError: MD4Update MD already done."); return; } + + /* Add count to MDp->count */ + tmp = count; + p = MDp->count; + while (tmp) + { tmp += *p; + *p++ = tmp; + tmp = tmp >> 8; + } + + /* Process data */ + if (count == 512) + { /* Full block of data to handle */ + MDblock(MDp,X); + } + else if (count > 512) /* Check for count too large */ + { + printf("\nError: MD4Update called with illegal count value %d.", + count); + return; + } + else /* partial block -- must be last block so finish up */ + { + /* Find out how many bytes and residual bits there are */ + byte = count >> 3; + bit = count & 7; + /* Copy X into XX since we need to modify it */ + if (count) + for (i=0;i<=byte;i++) XX[i] = X[i]; + for (i=byte+1;i<64;i++) XX[i] = 0; + /* Add padding '1' bit and low-order zeros in last byte */ + mask = 1 << (7 - bit); + XX[byte] = (XX[byte] | mask) & ~( mask - 1); + /* If room for bit count, finish up with this block */ + if (byte <= 55) + { + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,XX); + } + else /* need to do two blocks to finish up */ + { + MDblock(MDp,XX); + for (i=0;i<56;i++) XX[i] = 0; + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,XX); + } + /* Set flag saying we're done with MD computation */ + MDp->done = 1; + } +} + +/* +** Finish up MD4 computation and return message digest. +*/ +void +MD4Final(buf, MD) +unsigned char *buf; +MD4_CTX *MD; +{ + int i, j; + unsigned int w; + + MD4Update(MD, NULL, 0); + for (i = 0; i < 4; ++i) { + w = MD->buffer[i]; + for (j = 0; j < 4; ++j) { + *buf++ = w; + w >>= 8; + } + } +} + +/* +** End of md4.c +****************************(cut)***********************************/ diff --git a/src/netif/ppp/md4.h b/src/netif/ppp/md4.h new file mode 100644 index 00000000..80e8f9a2 --- /dev/null +++ b/src/netif/ppp/md4.h @@ -0,0 +1,64 @@ + +/* +** ******************************************************************** +** md4.h -- Header file for implementation of ** +** MD4 Message Digest Algorithm ** +** Updated: 2/13/90 by Ronald L. Rivest ** +** (C) 1990 RSA Data Security, Inc. ** +** ******************************************************************** +*/ + +#ifndef __P +# if defined(__STDC__) || defined(__GNUC__) +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + + +/* MDstruct is the data structure for a message digest computation. +*/ +typedef struct { + unsigned int buffer[4]; /* Holds 4-word result of MD computation */ + unsigned char count[8]; /* Number of bits processed so far */ + unsigned int done; /* Nonzero means MD computation finished */ +} MD4_CTX; + +/* MD4Init(MD4_CTX *) +** Initialize the MD4_CTX prepatory to doing a message digest +** computation. +*/ +extern void MD4Init __P((MD4_CTX *MD)); + +/* MD4Update(MD,X,count) +** Input: X -- a pointer to an array of unsigned characters. +** count -- the number of bits of X to use (an unsigned int). +** Updates MD using the first "count" bits of X. +** The array pointed to by X is not modified. +** If count is not a multiple of 8, MD4Update uses high bits of +** last byte. +** This is the basic input routine for a user. +** The routine terminates the MD computation when count < 512, so +** every MD computation should end with one call to MD4Update with a +** count less than 512. Zero is OK for a count. +*/ +extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); + +/* MD4Print(MD) +** Prints message digest buffer MD as 32 hexadecimal digits. +** Order is from low-order byte of buffer[0] to high-order byte +** of buffer[3]. +** Each byte is printed with high-order hexadecimal digit first. +*/ +extern void MD4Print __P((MD4_CTX *)); + +/* MD4Final(buf, MD) +** Returns message digest from MD and terminates the message +** digest computation. +*/ +extern void MD4Final __P((unsigned char *, MD4_CTX *)); + +/* +** End of md4.h +****************************(cut)***********************************/ diff --git a/src/netif/ppp/md5.c b/src/netif/ppp/md5.c new file mode 100644 index 00000000..11de7b6d --- /dev/null +++ b/src/netif/ppp/md5.c @@ -0,0 +1,309 @@ + + +/* + *********************************************************************** + ** md5.c -- the source code for MD5 routines ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** + *********************************************************************** + */ + +#include "lwip/opt.h" + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#include +#include "md5.h" + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5_Init ** + ** (2) Call MD5_Update on mdContext and M ** + ** (3) Call MD5_Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** + */ + +/* forward declaration */ +static void Transform (UINT4 *buf, UINT4 *in); + +static unsigned char PADDING[64] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s, ac) \ + {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) \ + {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) \ + {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) \ + {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +#ifdef __STDC__ +#define UL(x) x##U +#else +#define UL(x) x +#endif + +/* The routine MD5_Init initializes the message-digest context + mdContext. All fields are set to zero. + */ +void MD5_Init (mdContext) +MD5_CTX *mdContext; +{ + mdContext->i[0] = mdContext->i[1] = (UINT4)0; + + /* Load magic initialization constants. + */ + mdContext->buf[0] = (UINT4)0x67452301; + mdContext->buf[1] = (UINT4)0xefcdab89; + mdContext->buf[2] = (UINT4)0x98badcfe; + mdContext->buf[3] = (UINT4)0x10325476; +} + +/* The routine MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. + */ +void MD5_Update (mdContext, inBuf, inLen) +MD5_CTX *mdContext; +unsigned char *inBuf; +unsigned int inLen; +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* update number of bits */ + if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) + mdContext->i[1]++; + mdContext->i[0] += ((UINT4)inLen << 3); + mdContext->i[1] += ((UINT4)inLen >> 29); + + while (inLen--) { + /* add new character to buffer, increment mdi */ + mdContext->in[mdi++] = *inBuf++; + + /* transform if necessary */ + if (mdi == 0x40) { + for (i = 0, ii = 0; i < 16; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + Transform (mdContext->buf, in); + mdi = 0; + } + } +} + +/* The routine MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. + */ +void MD5_Final (hash, mdContext) +unsigned char hash[]; +MD5_CTX *mdContext; +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + /* save number of bits */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + MD5_Update (mdContext, PADDING, padLen); + + /* append length in bits and transform */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + Transform (mdContext->buf, in); + + /* store buffer in digest */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii+1] = + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii+2] = + (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii+3] = + (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } + memcpy(hash, mdContext->digest, 16); +} + +/* Basic MD5 step. Transforms buf based on in. + */ +static void Transform (buf, in) +UINT4 *buf; +UINT4 *in; +{ + UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ + FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ + FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ + FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ + FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ + FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ + FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ + FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ + FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ + FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ + FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ + FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ + FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ + FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ + FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ + FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ + + /* Round 2 */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ + GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ + GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ + GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ + GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ + GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ + GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ + GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ + GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ + GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ + GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ + GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ + GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ + GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ + GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ + GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ + + /* Round 3 */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ + HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ + HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ + HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ + HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ + HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ + HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ + HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ + HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ + HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ + HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ + HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ + HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ + HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ + HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ + HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ + + /* Round 4 */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ + II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ + II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ + II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ + II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ + II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ + II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ + II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ + II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ + II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ + II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ + II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ + II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ + II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ + II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ + II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + *********************************************************************** + ** End of md5.c ** + ******************************** (cut) ******************************** + */ diff --git a/src/netif/ppp/md5.h b/src/netif/ppp/md5.h new file mode 100644 index 00000000..71e8b00e --- /dev/null +++ b/src/netif/ppp/md5.h @@ -0,0 +1,65 @@ +/* + *********************************************************************** + ** md5.h -- header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#ifndef __MD5_INCLUDE__ + +/* typedef a 32-bit type */ +#ifdef _LP64 +typedef unsigned int UINT4; +typedef int INT4; +#else +typedef unsigned long UINT4; +typedef long INT4; +#endif +#define _UINT4_T + +/* Data structure for MD5 (Message-Digest) computation */ +typedef struct { + UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} MD5_CTX; + +void MD5_Init (MD5_CTX *mdContext); +void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); +void MD5_Final (unsigned char hash[], MD5_CTX *mdContext); + +#define __MD5_INCLUDE__ +#endif /* __MD5_INCLUDE__ */ diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/md4.c deleted file mode 100644 index e5f715bc..00000000 --- a/src/netif/ppp/polarssl/md4.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * RFC 1186/1320 compliant MD4 implementation - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * The MD4 algorithm was designed by Ron Rivest in 1990. - * - * http://www.ietf.org/rfc/rfc1186.txt - * http://www.ietf.org/rfc/rfc1320.txt - */ - -#include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_MD4_C) - -#include "polarssl/md4.h" - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] ) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} -#endif - -/* - * MD4 context setup - */ -void md4_starts( md4_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md4_process( md4_context *ctx, const unsigned char data[64] ) -{ - unsigned long X[16], A, B, C, D; - - GET_ULONG_LE( X[ 0], data, 0 ); - GET_ULONG_LE( X[ 1], data, 4 ); - GET_ULONG_LE( X[ 2], data, 8 ); - GET_ULONG_LE( X[ 3], data, 12 ); - GET_ULONG_LE( X[ 4], data, 16 ); - GET_ULONG_LE( X[ 5], data, 20 ); - GET_ULONG_LE( X[ 6], data, 24 ); - GET_ULONG_LE( X[ 7], data, 28 ); - GET_ULONG_LE( X[ 8], data, 32 ); - GET_ULONG_LE( X[ 9], data, 36 ); - GET_ULONG_LE( X[10], data, 40 ); - GET_ULONG_LE( X[11], data, 44 ); - GET_ULONG_LE( X[12], data, 48 ); - GET_ULONG_LE( X[13], data, 52 ); - GET_ULONG_LE( X[14], data, 56 ); - GET_ULONG_LE( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x, y, z) ((x & y) | ((~x) & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 1], 7 ); - P( C, D, A, B, X[ 2], 11 ); - P( B, C, D, A, X[ 3], 19 ); - P( A, B, C, D, X[ 4], 3 ); - P( D, A, B, C, X[ 5], 7 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[ 7], 19 ); - P( A, B, C, D, X[ 8], 3 ); - P( D, A, B, C, X[ 9], 7 ); - P( C, D, A, B, X[10], 11 ); - P( B, C, D, A, X[11], 19 ); - P( A, B, C, D, X[12], 3 ); - P( D, A, B, C, X[13], 7 ); - P( C, D, A, B, X[14], 11 ); - P( B, C, D, A, X[15], 19 ); - -#undef P -#undef F - -#define F(x,y,z) ((x & y) | (x & z) | (y & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 4], 5 ); - P( C, D, A, B, X[ 8], 9 ); - P( B, C, D, A, X[12], 13 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 5], 5 ); - P( C, D, A, B, X[ 9], 9 ); - P( B, C, D, A, X[13], 13 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[ 6], 5 ); - P( C, D, A, B, X[10], 9 ); - P( B, C, D, A, X[14], 13 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[ 7], 5 ); - P( C, D, A, B, X[11], 9 ); - P( B, C, D, A, X[15], 13 ); - -#undef P -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 8], 9 ); - P( C, D, A, B, X[ 4], 11 ); - P( B, C, D, A, X[12], 15 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[10], 9 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[14], 15 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 9], 9 ); - P( C, D, A, B, X[ 5], 11 ); - P( B, C, D, A, X[13], 15 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[11], 9 ); - P( C, D, A, B, X[ 7], 11 ); - P( B, C, D, A, X[15], 15 ); - -#undef F -#undef P - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -/* - * MD4 process buffer - */ -void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ) -{ - size_t fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (unsigned long) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - md4_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - md4_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, ilen ); - } -} - -static const unsigned char md4_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD4 final digest - */ -void md4_finish( md4_context *ctx, unsigned char output[16] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_LE( low, msglen, 0 ); - PUT_ULONG_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md4_update( ctx, (unsigned char *) md4_padding, padn ); - md4_update( ctx, msglen, 8 ); - - PUT_ULONG_LE( ctx->state[0], output, 0 ); - PUT_ULONG_LE( ctx->state[1], output, 4 ); - PUT_ULONG_LE( ctx->state[2], output, 8 ); - PUT_ULONG_LE( ctx->state[3], output, 12 ); -} - -/* - * output = MD4( input buffer ) - */ -void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) -{ - md4_context ctx; - - md4_starts( &ctx ); - md4_update( &ctx, input, ilen ); - md4_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md4_context ) ); -} - -#endif /* LWIP_INCLUDED_POLARSSL_MD4_C */ diff --git a/src/netif/ppp/polarssl/md4.h b/src/netif/ppp/polarssl/md4.h deleted file mode 100644 index 1ad8250f..00000000 --- a/src/netif/ppp/polarssl/md4.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * \file md4.h - * - * \brief MD4 message digest algorithm (hash function) - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef LWIP_INCLUDED_POLARSSL_MD4_H -#define LWIP_INCLUDED_POLARSSL_MD4_H - -/** - * \brief MD4 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -md4_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD4 context setup - * - * \param ctx context to be initialized - */ -void md4_starts( md4_context *ctx ); - -/** - * \brief MD4 process buffer - * - * \param ctx MD4 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ); - -/** - * \brief MD4 final digest - * - * \param ctx MD4 context - * \param output MD4 checksum result - */ -void md4_finish( md4_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = MD4( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD4 checksum result - */ -void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/md5.c deleted file mode 100644 index 621a5372..00000000 --- a/src/netif/ppp/polarssl/md5.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * RFC 1321 compliant MD5 implementation - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * The MD5 algorithm was designed by Ron Rivest in 1991. - * - * http://www.ietf.org/rfc/rfc1321.txt - */ - -#include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_MD5_C) - -#include "polarssl/md5.h" - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] ) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} -#endif - -/* - * MD5 context setup - */ -void md5_starts( md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md5_process( md5_context *ctx, const unsigned char data[64] ) -{ - unsigned long X[16], A, B, C, D; - - GET_ULONG_LE( X[ 0], data, 0 ); - GET_ULONG_LE( X[ 1], data, 4 ); - GET_ULONG_LE( X[ 2], data, 8 ); - GET_ULONG_LE( X[ 3], data, 12 ); - GET_ULONG_LE( X[ 4], data, 16 ); - GET_ULONG_LE( X[ 5], data, 20 ); - GET_ULONG_LE( X[ 6], data, 24 ); - GET_ULONG_LE( X[ 7], data, 28 ); - GET_ULONG_LE( X[ 8], data, 32 ); - GET_ULONG_LE( X[ 9], data, 36 ); - GET_ULONG_LE( X[10], data, 40 ); - GET_ULONG_LE( X[11], data, 44 ); - GET_ULONG_LE( X[12], data, 48 ); - GET_ULONG_LE( X[13], data, 52 ); - GET_ULONG_LE( X[14], data, 56 ); - GET_ULONG_LE( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define P(a,b,c,d,k,s,t) \ -{ \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) - - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) (y ^ (z & (x ^ y))) - - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) (x ^ y ^ z) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) (y ^ (x | ~z)) - - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); - -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -/* - * MD5 process buffer - */ -void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) -{ - size_t fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (unsigned long) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - md5_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - md5_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, ilen ); - } -} - -static const unsigned char md5_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD5 final digest - */ -void md5_finish( md5_context *ctx, unsigned char output[16] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_LE( low, msglen, 0 ); - PUT_ULONG_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md5_update( ctx, (unsigned char *) md5_padding, padn ); - md5_update( ctx, msglen, 8 ); - - PUT_ULONG_LE( ctx->state[0], output, 0 ); - PUT_ULONG_LE( ctx->state[1], output, 4 ); - PUT_ULONG_LE( ctx->state[2], output, 8 ); - PUT_ULONG_LE( ctx->state[3], output, 12 ); -} - -/* - * output = MD5( input buffer ) - */ -void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) -{ - md5_context ctx; - - md5_starts( &ctx ); - md5_update( &ctx, input, ilen ); - md5_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); -} - -#endif /* LWIP_INCLUDED_POLARSSL_MD5_C */ diff --git a/src/netif/ppp/polarssl/md5.h b/src/netif/ppp/polarssl/md5.h deleted file mode 100644 index 389b4154..00000000 --- a/src/netif/ppp/polarssl/md5.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * \file md5.h - * - * \brief MD5 message digest algorithm (hash function) - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef LWIP_INCLUDED_POLARSSL_MD5_H -#define LWIP_INCLUDED_POLARSSL_MD5_H - -/** - * \brief MD5 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -md5_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD5 context setup - * - * \param ctx context to be initialized - */ -void md5_starts( md5_context *ctx ); - -/** - * \brief MD5 process buffer - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ); - -/** - * \brief MD5 final digest - * - * \param ctx MD5 context - * \param output MD5 checksum result - */ -void md5_finish( md5_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = MD5( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - */ -void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/sha1.c deleted file mode 100644 index 5e9a661f..00000000 --- a/src/netif/ppp/polarssl/sha1.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_SHA1_C) - -#include "polarssl/sha1.h" - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_ULONG_BE -#define GET_ULONG_BE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ - | ( (unsigned long) (b)[(i) + 1] << 16 ) \ - | ( (unsigned long) (b)[(i) + 2] << 8 ) \ - | ( (unsigned long) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_ULONG_BE -#define PUT_ULONG_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * SHA-1 context setup - */ -void sha1_starts( sha1_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) -{ - unsigned long temp, W[16], A, B, C, D, E; - - GET_ULONG_BE( W[ 0], data, 0 ); - GET_ULONG_BE( W[ 1], data, 4 ); - GET_ULONG_BE( W[ 2], data, 8 ); - GET_ULONG_BE( W[ 3], data, 12 ); - GET_ULONG_BE( W[ 4], data, 16 ); - GET_ULONG_BE( W[ 5], data, 20 ); - GET_ULONG_BE( W[ 6], data, 24 ); - GET_ULONG_BE( W[ 7], data, 28 ); - GET_ULONG_BE( W[ 8], data, 32 ); - GET_ULONG_BE( W[ 9], data, 36 ); - GET_ULONG_BE( W[10], data, 40 ); - GET_ULONG_BE( W[11], data, 44 ); - GET_ULONG_BE( W[12], data, 48 ); - GET_ULONG_BE( W[13], data, 52 ); - GET_ULONG_BE( W[14], data, 56 ); - GET_ULONG_BE( W[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ - W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -/* - * SHA-1 process buffer - */ -void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) -{ - size_t fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (unsigned long) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - sha1_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - sha1_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, ilen ); - } -} - -static const unsigned char sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * SHA-1 final digest - */ -void sha1_finish( sha1_context *ctx, unsigned char output[20] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_BE( high, msglen, 0 ); - PUT_ULONG_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - sha1_update( ctx, (unsigned char *) sha1_padding, padn ); - sha1_update( ctx, msglen, 8 ); - - PUT_ULONG_BE( ctx->state[0], output, 0 ); - PUT_ULONG_BE( ctx->state[1], output, 4 ); - PUT_ULONG_BE( ctx->state[2], output, 8 ); - PUT_ULONG_BE( ctx->state[3], output, 12 ); - PUT_ULONG_BE( ctx->state[4], output, 16 ); -} - -/* - * output = SHA-1( input buffer ) - */ -void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) -{ - sha1_context ctx; - - sha1_starts( &ctx ); - sha1_update( &ctx, input, ilen ); - sha1_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); -} - -#endif /* LWIP_INCLUDED_POLARSSL_SHA1_C */ diff --git a/src/netif/ppp/polarssl/sha1.h b/src/netif/ppp/polarssl/sha1.h deleted file mode 100644 index b01e93f4..00000000 --- a/src/netif/ppp/polarssl/sha1.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * \file sha1.h - * - * \brief SHA-1 cryptographic hash function - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H -#define LWIP_INCLUDED_POLARSSL_SHA1_H - -/** - * \brief SHA-1 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[5]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -sha1_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief SHA-1 context setup - * - * \param ctx context to be initialized - */ -void sha1_starts( sha1_context *ctx ); - -/** - * \brief SHA-1 process buffer - * - * \param ctx SHA-1 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ); - -/** - * \brief SHA-1 final digest - * - * \param ctx SHA-1 context - * \param output SHA-1 checksum result - */ -void sha1_finish( sha1_context *ctx, unsigned char output[20] ); - -/** - * \brief Output = SHA-1( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-1 checksum result - */ -void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ diff --git a/src/netif/ppp/sha1.c b/src/netif/ppp/sha1.c new file mode 100644 index 00000000..3b020b8f --- /dev/null +++ b/src/netif/ppp/sha1.c @@ -0,0 +1,172 @@ +/* + * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c + * + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + * + * Test Vectors (from FIPS PUB 180-1) + * "abc" + * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + * A million repetitions of "a" + * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F + */ + +#include "lwip/opt.h" + +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#include +#include /* htonl() */ +#include +#include "sha1.h" + +static void +SHA1_Transform(u_int32_t[5], const unsigned char[64]); + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#define blk0(i) (block->l[i] = htonl(block->l[i])) +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +static void +SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64]) +{ + u_int32_t a, b, c, d, e; + typedef union { + unsigned char c[64]; + u_int32_t l[16]; + } CHAR64LONG16; + CHAR64LONG16 *block; + +#ifdef SHA1HANDSOFF + static unsigned char workspace[64]; + block = (CHAR64LONG16 *) workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16 *) buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void +SHA1_Init(SHA1_CTX *context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void +SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) +{ + unsigned int i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + i = 64 - j; + while (len >= i) { + memcpy(&context->buffer[j], data, i); + SHA1_Transform(context->state, context->buffer); + data += i; + len -= i; + i = 64; + j = 0; + } + + memcpy(&context->buffer[j], data, len); +} + + +/* Add padding and return the message digest. */ + +void +SHA1_Final(unsigned char digest[20], SHA1_CTX *context) +{ + u_int32_t i, j; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1_Update(context, (unsigned char *) "\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1_Update(context, (unsigned char *) "\0", 1); + } + SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = j = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ + SHA1Transform(context->state, context->buffer); +#endif +} + diff --git a/src/netif/ppp/sha1.h b/src/netif/ppp/sha1.h new file mode 100644 index 00000000..83f64df2 --- /dev/null +++ b/src/netif/ppp/sha1.h @@ -0,0 +1,31 @@ +/* sha1.h */ + +/* If OpenSSL is in use, then use that version of SHA-1 */ +#ifdef OPENSSL +#include +#define __SHA1_INCLUDE_ +#endif + +#ifndef __SHA1_INCLUDE_ + +#ifndef SHA1_SIGNATURE_SIZE +#ifdef SHA_DIGESTSIZE +#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE +#else +#define SHA1_SIGNATURE_SIZE 20 +#endif +#endif + +typedef struct { + u_int32_t state[5]; + u_int32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +extern void SHA1_Init(SHA1_CTX *); +extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int); +extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *); + +#define __SHA1_INCLUDE_ +#endif /* __SHA1_INCLUDE_ */ + From 4570f71f21914749fa13291317096d85299470fc Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 20:46:45 +0200 Subject: [PATCH 027/320] modified auth_reset() so that we can choose which auth we want --- src/netif/ppp/auth.c | 58 +++++++++++++++++++++++++++++++--------- src/netif/ppp/chap-new.c | 10 ++----- src/netif/ppp/pppmy.c | 9 +++++++ src/netif/ppp/pppmy.h | 3 ++- 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 3036721d..08410fd0 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1292,21 +1292,42 @@ void auth_reset(unit) int unit; { - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - int hadchap; - hadchap = -1; + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *ao = &lcp_allowoptions[unit]; + + if( ppp_settings.passwd[0] ) { + + ao->neg_upap = !ppp_settings.refuse_pap; + + ao->neg_eap = !ppp_settings.refuse_eap; + + ao->chap_mdtype = MDTYPE_NONE; + if(!ppp_settings.refuse_chap) + ao->chap_mdtype |= MDTYPE_MD5; + if(!ppp_settings.refuse_mschap) + ao->chap_mdtype |= MDTYPE_MICROSOFT; + if(!ppp_settings.refuse_mschap_v2) + ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; + + ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); + + } else { + ao->neg_upap = 0; + ao->neg_chap = 0; + ao->neg_eap = 0; + ao->chap_mdtype = MDTYPE_NONE; + } + + + printf("neg_upap: %d\n", ao->neg_upap); + printf("neg_chap: %d\n", ao->neg_chap); + printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); + printf("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT) ); + printf("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2) ); + printf("neg_eap: %d\n", ao->neg_eap); //ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); - ao->neg_upap = !ppp_settings.refuse_pap && ppp_settings.passwd[0] != 0; - - ao->neg_chap = (!ppp_settings.refuse_chap || !ppp_settings.refuse_mschap || !ppp_settings.refuse_mschap_v2) && ppp_settings.passwd[0]; - - ao->neg_eap = !ppp_settings.refuse_eap && ppp_settings.passwd[0] != 0; - - return; - /* ao->neg_chap = (!ppp_settings.refuse_chap || !refuse_mschap || !refuse_mschap_v2) && (passwd[0] != 0 || @@ -1319,15 +1340,26 @@ auth_reset(unit) (explicit_remote? remote_name: NULL), 0, NULL))) || have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); */ + go->neg_upap = 0; + go->neg_chap = 0; + go->neg_eap = 0; + go->chap_mdtype = MDTYPE_NONE; + return; + /* FIXME: find what the below stuff do */ + int hadchap; + hadchap = -1; + hadchap = -1; if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) go->neg_upap = 0; + if (go->neg_chap) { if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL))) go->neg_chap = 0; } + if (go->neg_eap && (hadchap == 0 || (hadchap == -1 && !have_chap_secret((explicit_remote? remote_name: NULL), our_name, @@ -1731,6 +1763,8 @@ get_secret(unit, client, server, secret, secret_len, am_server) *secret_len = len; return 1; + +/* FIXME: clean that */ #if 0 // strlcpy(rname, ppp_settings.user, sizeof(rname)); diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 5fe183f8..7d773537 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -456,14 +456,8 @@ chap_respond(struct chap_client_state *cs, int id, slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); /* Microsoft doesn't send their name back in the PPP packet */ - if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rname[0] == 0)) { - strncpy(rname, ppp_settings.remote_name, sizeof(rname)); - rname[sizeof(rname) - 1] = 0; - } - -// /* Microsoft doesn't send their name back in the PPP packet */ -// if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) -// strlcpy(rname, remote_name, sizeof(rname)); + if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) + strlcpy(rname, remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 8085741b..3352b2ba 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -435,6 +435,14 @@ int ppp_init(void) { void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { + ppp_settings.refuse_pap = 1; + ppp_settings.refuse_chap = 1; + ppp_settings.refuse_mschap = 1; + ppp_settings.refuse_mschap_v2 = 0; + ppp_settings.refuse_eap = 1; + +/* FIXME: re-enable that */ +#if 0 switch(authType) { case PPPAUTHTYPE_NONE: default: @@ -481,6 +489,7 @@ pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) ppp_settings.refuse_chap = 0; break; } +#endif if(user) { strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index e79f43fa..07099ecd 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -58,7 +58,8 @@ struct ppp_settings { char user [MAXNAMELEN + 1]; /* Username for PAP */ char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ + // FIXME: re-enable that + // char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ }; struct ppp_settings ppp_settings; From a9672e1a21882a144f12f01d182d3e469074b54c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 22:32:24 +0200 Subject: [PATCH 028/320] now using OpenBSD DES implementation --- src/netif/ppp/des.c | 546 +++++++++++++++++++++++++++++++++++++++ src/netif/ppp/des.h | 40 +++ src/netif/ppp/pppcrypt.c | 51 +--- src/netif/ppp/pppcrypt.h | 8 - 4 files changed, 587 insertions(+), 58 deletions(-) create mode 100644 src/netif/ppp/des.c create mode 100644 src/netif/ppp/des.h diff --git a/src/netif/ppp/des.c b/src/netif/ppp/des.c new file mode 100644 index 00000000..56b4f3e7 --- /dev/null +++ b/src/netif/ppp/des.c @@ -0,0 +1,546 @@ +/* $OpenBSD: crypt.c,v 1.20 2005/08/08 08:05:33 espie Exp $ */ + +/* + * FreeSec: libcrypt + * + * Copyright (c) 1994 David Burren + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * This is an original implementation of the DES and the crypt(3) interfaces + * by David Burren . + * + * An excellent reference on the underlying algorithm (and related + * algorithms) is: + * + * B. Schneier, Applied Cryptography: protocols, algorithms, + * and source code in C, John Wiley & Sons, 1994. + * + * Note that in that book's description of DES the lookups for the initial, + * pbox, and final permutations are inverted (this has been brought to the + * attention of the author). A list of errata for this book has been + * posted to the sci.crypt newsgroup by the author and is available for FTP. + */ + +#include "lwip/opt.h" + +#include "lwip/def.h" + +#include +#include +#include +#include +#include + +#ifdef DEBUG +# include +#endif + +static const u_char IP[64] = { + 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 +}; + +static u_char inv_key_perm[64]; +static u_char u_key_perm[56]; +static u_char const key_perm[56] = { + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 +}; + +static const u_char key_shifts[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +static u_char inv_comp_perm[56]; +static const u_char comp_perm[48] = { + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 +}; + +/* + * No E box is used, as it's replaced by some ANDs, shifts, and ORs. + */ + +static u_char u_sbox[8][64]; +static const u_char sbox[8][64] = { + { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 + }, + { + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 + }, + { + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 + }, + { + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 + }, + { + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 + }, + { + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 + }, + { + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 + }, + { + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 + } +}; + +static u_char un_pbox[32]; +static const u_char pbox[32] = { + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 +}; + +const u_int32_t _des_bits32[32] = +{ + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 +}; + +const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + +static u_int32_t saltbits; +static int32_t old_salt; +static const u_int32_t *bits28, *bits24; +static u_char init_perm[64], final_perm[64]; +static u_int32_t en_keysl[16], en_keysr[16]; +static u_int32_t de_keysl[16], de_keysr[16]; +int _des_initialised = 0; +static u_char m_sbox[4][4096]; +static u_int32_t psbox[4][256]; +static u_int32_t ip_maskl[8][256], ip_maskr[8][256]; +static u_int32_t fp_maskl[8][256], fp_maskr[8][256]; +static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; +static u_int32_t comp_maskl[8][128], comp_maskr[8][128]; +static u_int32_t old_rawkey0, old_rawkey1; + +void +_des_init(void) +{ + int i, j, b, k, inbit, obit; + u_int32_t *p, *il, *ir, *fl, *fr; + + old_rawkey0 = old_rawkey1 = 0; + saltbits = 0; + old_salt = 0; + bits24 = (bits28 = _des_bits32 + 4) + 4; + + /* + * Invert the S-boxes, reordering the input bits. + */ + for (i = 0; i < 8; i++) + for (j = 0; j < 64; j++) { + b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); + u_sbox[i][j] = sbox[i][b]; + } + + /* + * Convert the inverted S-boxes into 4 arrays of 8 bits. + * Each will handle 12 bits of the S-box input. + */ + for (b = 0; b < 4; b++) + for (i = 0; i < 64; i++) + for (j = 0; j < 64; j++) + m_sbox[b][(i << 6) | j] = + (u_sbox[(b << 1)][i] << 4) | + u_sbox[(b << 1) + 1][j]; + + /* + * Set up the initial & final permutations into a useful form, and + * initialise the inverted key permutation. + */ + for (i = 0; i < 64; i++) { + init_perm[final_perm[i] = IP[i] - 1] = i; + inv_key_perm[i] = 255; + } + + /* + * Invert the key permutation and initialise the inverted key + * compression permutation. + */ + for (i = 0; i < 56; i++) { + u_key_perm[i] = key_perm[i] - 1; + inv_key_perm[key_perm[i] - 1] = i; + inv_comp_perm[i] = 255; + } + + /* + * Invert the key compression permutation. + */ + for (i = 0; i < 48; i++) { + inv_comp_perm[comp_perm[i] - 1] = i; + } + + /* + * Set up the OR-mask arrays for the initial and final permutations, + * and for the key initial and compression permutations. + */ + for (k = 0; k < 8; k++) { + for (i = 0; i < 256; i++) { + *(il = &ip_maskl[k][i]) = 0; + *(ir = &ip_maskr[k][i]) = 0; + *(fl = &fp_maskl[k][i]) = 0; + *(fr = &fp_maskr[k][i]) = 0; + for (j = 0; j < 8; j++) { + inbit = 8 * k + j; + if (i & _des_bits8[j]) { + if ((obit = init_perm[inbit]) < 32) + *il |= _des_bits32[obit]; + else + *ir |= _des_bits32[obit-32]; + if ((obit = final_perm[inbit]) < 32) + *fl |= _des_bits32[obit]; + else + *fr |= _des_bits32[obit - 32]; + } + } + } + for (i = 0; i < 128; i++) { + *(il = &key_perm_maskl[k][i]) = 0; + *(ir = &key_perm_maskr[k][i]) = 0; + for (j = 0; j < 7; j++) { + inbit = 8 * k + j; + if (i & _des_bits8[j + 1]) { + if ((obit = inv_key_perm[inbit]) == 255) + continue; + if (obit < 28) + *il |= bits28[obit]; + else + *ir |= bits28[obit - 28]; + } + } + *(il = &comp_maskl[k][i]) = 0; + *(ir = &comp_maskr[k][i]) = 0; + for (j = 0; j < 7; j++) { + inbit = 7 * k + j; + if (i & _des_bits8[j + 1]) { + if ((obit=inv_comp_perm[inbit]) == 255) + continue; + if (obit < 24) + *il |= bits24[obit]; + else + *ir |= bits24[obit - 24]; + } + } + } + } + + /* + * Invert the P-box permutation, and convert into OR-masks for + * handling the output of the S-box arrays setup above. + */ + for (i = 0; i < 32; i++) + un_pbox[pbox[i] - 1] = i; + + for (b = 0; b < 4; b++) + for (i = 0; i < 256; i++) { + *(p = &psbox[b][i]) = 0; + for (j = 0; j < 8; j++) { + if (i & _des_bits8[j]) + *p |= _des_bits32[un_pbox[8 * b + j]]; + } + } + + _des_initialised = 1; +} + +int +des_setkey(const char *key) +{ + u_int32_t k0, k1, rawkey0, rawkey1; + int shifts, round; + + if (!_des_initialised) + _des_init(); + + rawkey0 = ntohl(*(u_int32_t *) key); + rawkey1 = ntohl(*(u_int32_t *) (key + 4)); + + if ((rawkey0 | rawkey1) + && rawkey0 == old_rawkey0 + && rawkey1 == old_rawkey1) { + /* + * Already setup for this key. + * This optimisation fails on a zero key (which is weak and + * has bad parity anyway) in order to simplify the starting + * conditions. + */ + return(0); + } + old_rawkey0 = rawkey0; + old_rawkey1 = rawkey1; + + /* + * Do key permutation and split into two 28-bit subkeys. + */ + k0 = key_perm_maskl[0][rawkey0 >> 25] + | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskl[4][rawkey1 >> 25] + | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; + k1 = key_perm_maskr[0][rawkey0 >> 25] + | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskr[4][rawkey1 >> 25] + | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; + /* + * Rotate subkeys and do compression permutation. + */ + shifts = 0; + for (round = 0; round < 16; round++) { + u_int32_t t0, t1; + + shifts += key_shifts[round]; + + t0 = (k0 << shifts) | (k0 >> (28 - shifts)); + t1 = (k1 << shifts) | (k1 >> (28 - shifts)); + + de_keysl[15 - round] = + en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] + | comp_maskl[1][(t0 >> 14) & 0x7f] + | comp_maskl[2][(t0 >> 7) & 0x7f] + | comp_maskl[3][t0 & 0x7f] + | comp_maskl[4][(t1 >> 21) & 0x7f] + | comp_maskl[5][(t1 >> 14) & 0x7f] + | comp_maskl[6][(t1 >> 7) & 0x7f] + | comp_maskl[7][t1 & 0x7f]; + + de_keysr[15 - round] = + en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f] + | comp_maskr[1][(t0 >> 14) & 0x7f] + | comp_maskr[2][(t0 >> 7) & 0x7f] + | comp_maskr[3][t0 & 0x7f] + | comp_maskr[4][(t1 >> 21) & 0x7f] + | comp_maskr[5][(t1 >> 14) & 0x7f] + | comp_maskr[6][(t1 >> 7) & 0x7f] + | comp_maskr[7][t1 & 0x7f]; + } + return(0); +} + +int +_des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, + int count) +{ + /* + * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. + */ + u_int32_t l, r, *kl, *kr, *kl1, *kr1; + u_int32_t f, r48l, r48r; + int round; + + if (count == 0) { + return(1); + } else if (count > 0) { + /* + * Encrypting + */ + kl1 = en_keysl; + kr1 = en_keysr; + } else { + /* + * Decrypting + */ + count = -count; + kl1 = de_keysl; + kr1 = de_keysr; + } + + /* + * Do initial permutation (IP). + */ + l = ip_maskl[0][l_in >> 24] + | ip_maskl[1][(l_in >> 16) & 0xff] + | ip_maskl[2][(l_in >> 8) & 0xff] + | ip_maskl[3][l_in & 0xff] + | ip_maskl[4][r_in >> 24] + | ip_maskl[5][(r_in >> 16) & 0xff] + | ip_maskl[6][(r_in >> 8) & 0xff] + | ip_maskl[7][r_in & 0xff]; + r = ip_maskr[0][l_in >> 24] + | ip_maskr[1][(l_in >> 16) & 0xff] + | ip_maskr[2][(l_in >> 8) & 0xff] + | ip_maskr[3][l_in & 0xff] + | ip_maskr[4][r_in >> 24] + | ip_maskr[5][(r_in >> 16) & 0xff] + | ip_maskr[6][(r_in >> 8) & 0xff] + | ip_maskr[7][r_in & 0xff]; + + while (count--) { + /* + * Do each round. + */ + kl = kl1; + kr = kr1; + round = 16; + while (round--) { + /* + * Expand R to 48 bits (simulate the E-box). + */ + r48l = ((r & 0x00000001) << 23) + | ((r & 0xf8000000) >> 9) + | ((r & 0x1f800000) >> 11) + | ((r & 0x01f80000) >> 13) + | ((r & 0x001f8000) >> 15); + + r48r = ((r & 0x0001f800) << 7) + | ((r & 0x00001f80) << 5) + | ((r & 0x000001f8) << 3) + | ((r & 0x0000001f) << 1) + | ((r & 0x80000000) >> 31); + /* + * Do salting for crypt() and friends, and + * XOR with the permuted key. + */ + f = (r48l ^ r48r) & saltbits; + r48l ^= f ^ *kl++; + r48r ^= f ^ *kr++; + /* + * Do sbox lookups (which shrink it back to 32 bits) + * and do the pbox permutation at the same time. + */ + f = psbox[0][m_sbox[0][r48l >> 12]] + | psbox[1][m_sbox[1][r48l & 0xfff]] + | psbox[2][m_sbox[2][r48r >> 12]] + | psbox[3][m_sbox[3][r48r & 0xfff]]; + /* + * Now that we've permuted things, complete f(). + */ + f ^= l; + l = r; + r = f; + } + r = l; + l = f; + } + /* + * Do final permutation (inverse of IP). + */ + *l_out = fp_maskl[0][l >> 24] + | fp_maskl[1][(l >> 16) & 0xff] + | fp_maskl[2][(l >> 8) & 0xff] + | fp_maskl[3][l & 0xff] + | fp_maskl[4][r >> 24] + | fp_maskl[5][(r >> 16) & 0xff] + | fp_maskl[6][(r >> 8) & 0xff] + | fp_maskl[7][r & 0xff]; + *r_out = fp_maskr[0][l >> 24] + | fp_maskr[1][(l >> 16) & 0xff] + | fp_maskr[2][(l >> 8) & 0xff] + | fp_maskr[3][l & 0xff] + | fp_maskr[4][r >> 24] + | fp_maskr[5][(r >> 16) & 0xff] + | fp_maskr[6][(r >> 8) & 0xff] + | fp_maskr[7][r & 0xff]; + return(0); +} + +int setkey(const char *key) { + int i, j; + u_int32_t packed_keys[2]; + u_char *p; + + p = (u_char *) packed_keys; + + for (i = 0; i < 8; i++) { + p[i] = 0; + for (j = 0; j < 8; j++) + if (*key++ & 1) + p[i] |= _des_bits8[j]; + } + return(des_setkey((char *)p)); +} + +int encrypt(char *block, int flag) { + u_int32_t io[2]; + u_char *p; + int i, j, retval; + + if (!_des_initialised) + _des_init(); + + //_des_setup_salt(0); + p = (u_char *)block; + for (i = 0; i < 2; i++) { + io[i] = 0L; + for (j = 0; j < 32; j++) + if (*p++ & 1) + io[i] |= _des_bits32[j]; + } + retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1); + for (i = 0; i < 2; i++) + for (j = 0; j < 32; j++) + block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0; + return(retval); +} diff --git a/src/netif/ppp/des.h b/src/netif/ppp/des.h new file mode 100644 index 00000000..9ae70f6a --- /dev/null +++ b/src/netif/ppp/des.h @@ -0,0 +1,40 @@ +/** + * @file + * + * DES header + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef DES_H_ +#define DES_H_ + +int setkey(const char *key); +int encrypt(char *block, int flag); + +#endif /* DES_H_ */ diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index 1a66f680..d4c48429 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -32,9 +32,9 @@ #include "lwip/opt.h" -#include #include "pppd.h" #include "pppcrypt.h" +#include "des.h" static u_char Get7Bits(input, startBit) @@ -64,13 +64,8 @@ u_char *des_key; /* OUT 64 bit DES key with parity bits added */ 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 } -#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 @@ -120,10 +115,7 @@ u_char *key; MakeKey(key, des_key); Expand(des_key, crypt_key); - errno = 0; setkey((const char *)crypt_key); - if (errno != 0) - return (0); return (1); } @@ -135,10 +127,7 @@ u_char *cipher; /* OUT 8 octets */ u_char des_input[66]; Expand(clear, des_input); - errno = 0; encrypt((char *)des_input, 0); - if (errno != 0) - return (0); Collapse(des_input, cipher); return (1); } @@ -151,45 +140,7 @@ u_char *clear; /* OUT 8 octets */ u_char des_input[66]; Expand(cipher, des_input); - errno = 0; encrypt((char *)des_input, 1); - if (errno != 0) - return (0); Collapse(des_input, clear); return (1); } - -#else /* USE_CRYPT */ -static des_key_schedule key_schedule; - -bool -DesSetkey(key) -u_char *key; -{ - des_cblock des_key; - MakeKey(key, des_key); - des_set_key(&des_key, key_schedule); - return (1); -} - -bool -DesEncrypt(clear, key, cipher) -u_char *clear; /* IN 8 octets */ -u_char *cipher; /* OUT 8 octets */ -{ - des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, - key_schedule, 1); - return (1); -} - -bool -DesDecrypt(cipher, clear) -u_char *cipher; /* IN 8 octets */ -u_char *clear; /* OUT 8 octets */ -{ - des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, - key_schedule, 0); - return (1); -} - -#endif /* USE_CRYPT */ diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h index adcdcbcb..d5deccd0 100644 --- a/src/netif/ppp/pppcrypt.h +++ b/src/netif/ppp/pppcrypt.h @@ -33,14 +33,6 @@ #ifndef PPPCRYPT_H #define PPPCRYPT_H -#ifdef HAVE_CRYPT_H -#include -#endif - -#ifndef USE_CRYPT -#include -#endif - extern bool DesSetkey __P((u_char *)); extern bool DesEncrypt __P((u_char *, u_char *)); extern bool DesDecrypt __P((u_char *, u_char *)); From 517659640e90ad95338518bac876e53b905f8e5b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 22:47:12 +0200 Subject: [PATCH 029/320] removed salted DES ( known as crypt() function ), we don't need it --- src/netif/ppp/des.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/netif/ppp/des.c b/src/netif/ppp/des.c index 56b4f3e7..123c1978 100644 --- a/src/netif/ppp/des.c +++ b/src/netif/ppp/des.c @@ -47,19 +47,10 @@ */ #include "lwip/opt.h" +/* FIXME: don't build if not necessary */ #include "lwip/def.h" -#include -#include -#include -#include -#include - -#ifdef DEBUG -# include -#endif - static const u_char IP[64] = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, @@ -164,8 +155,6 @@ const u_int32_t _des_bits32[32] = const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; -static u_int32_t saltbits; -static int32_t old_salt; static const u_int32_t *bits28, *bits24; static u_char init_perm[64], final_perm[64]; static u_int32_t en_keysl[16], en_keysr[16]; @@ -186,8 +175,6 @@ _des_init(void) u_int32_t *p, *il, *ir, *fl, *fr; old_rawkey0 = old_rawkey1 = 0; - saltbits = 0; - old_salt = 0; bits24 = (bits28 = _des_bits32 + 4) + 4; /* @@ -460,12 +447,10 @@ _des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, | ((r & 0x0000001f) << 1) | ((r & 0x80000000) >> 31); /* - * Do salting for crypt() and friends, and - * XOR with the permuted key. + * Do XOR with the permuted key. */ - f = (r48l ^ r48r) & saltbits; - r48l ^= f ^ *kl++; - r48r ^= f ^ *kr++; + r48l ^= *kl++; + r48r ^= *kr++; /* * Do sbox lookups (which shrink it back to 32 bits) * and do the pbox permutation at the same time. @@ -530,7 +515,6 @@ int encrypt(char *block, int flag) { if (!_des_initialised) _des_init(); - //_des_setup_salt(0); p = (u_char *)block; for (i = 0; i < 2; i++) { io[i] = 0L; From c268c5e07c046eb2cb8e5798a1f3eba7e0ad13c1 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 20 May 2012 23:23:14 +0200 Subject: [PATCH 030/320] Removed all stuff requiring encryption. OpenBSD DES require more than 70 kB of static memory. The GNU libcrypt DES, for information, require more than 131 kB, so this is probably the case with all non memory optimised DES. PolarSSL only required 132 bytes of stack with some kB of .rodata precomputed tables :-) I personally don't need MS CHAP v1 or MS CHAP v2, and that was not supported in the previous PPP port, so there is no regression, I feel comfortable about removing those hard to port stuff. If someone want to do the MS CHAP port, he first have to find or do a small memory footprint DES implementation. --- src/netif/ppp/auth.c | 58 +- src/netif/ppp/cbcp.h | 26 - src/netif/ppp/ccp.c | 1680 -------------------------------------- src/netif/ppp/ccp.h | 52 -- src/netif/ppp/chap_ms.c | 943 --------------------- src/netif/ppp/chap_ms.h | 109 --- src/netif/ppp/des.c | 530 ------------ src/netif/ppp/des.h | 40 - src/netif/ppp/ecp.c | 175 ---- src/netif/ppp/ecp.h | 45 - src/netif/ppp/md4.c | 301 ------- src/netif/ppp/md4.h | 64 -- src/netif/ppp/ppp.c | 40 +- src/netif/ppp/pppcrypt.c | 146 ---- src/netif/ppp/pppcrypt.h | 40 - src/netif/ppp/pppd.h | 1 - src/netif/ppp/pppmy.c | 4 +- src/netif/ppp/pppmy.h | 2 - src/netif/ppp/sha1.c | 172 ---- src/netif/ppp/sha1.h | 31 - 20 files changed, 6 insertions(+), 4453 deletions(-) delete mode 100644 src/netif/ppp/cbcp.h delete mode 100644 src/netif/ppp/ccp.c delete mode 100644 src/netif/ppp/ccp.h delete mode 100644 src/netif/ppp/chap_ms.c delete mode 100644 src/netif/ppp/chap_ms.h delete mode 100644 src/netif/ppp/des.c delete mode 100644 src/netif/ppp/des.h delete mode 100644 src/netif/ppp/ecp.c delete mode 100644 src/netif/ppp/ecp.h delete mode 100644 src/netif/ppp/md4.c delete mode 100644 src/netif/ppp/md4.h delete mode 100644 src/netif/ppp/pppcrypt.c delete mode 100644 src/netif/ppp/pppcrypt.h delete mode 100644 src/netif/ppp/sha1.c delete mode 100644 src/netif/ppp/sha1.h diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 08410fd0..020d53ce 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -106,15 +106,10 @@ #include "pppd.h" #include "fsm.h" #include "lcp.h" -#include "ccp.h" -#include "ecp.h" #include "ipcp.h" #include "upap.h" #include "chap-new.h" #include "eap.h" -#if CBCP_SUPPORT -#include "cbcp.h" -#endif #include "pathnames.h" #include "session.h" @@ -832,48 +827,9 @@ start_networks(unit) { int i; struct protent *protp; - int ecp_required, mppe_required; new_phase(PHASE_NETWORK); -#ifdef HAVE_MULTILINK - if (multilink) { - if (mp_join_bundle()) { - if (multilink_join_hook) - (*multilink_join_hook)(); - if (updetach && !nodetach) - detach(); - return; - } - } -#endif /* HAVE_MULTILINK */ - -#ifdef PPP_FILTER - if (!demand) - set_filters(&pass_filter, &active_filter); -#endif - /* Start CCP and ECP */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP) - && protp->enabled_flag && protp->open != NULL) - (*protp->open)(0); - - /* - * Bring up other network protocols iff encryption is not required. - */ - ecp_required = ecp_gotoptions[unit].required; - mppe_required = ccp_gotoptions[unit].mppe; - if (!ecp_required && !mppe_required) - continue_networks(unit); -} - -void -continue_networks(unit) - int unit; -{ - int i; - struct protent *protp; - /* * Start the "real" network protocols. */ @@ -1301,15 +1257,10 @@ auth_reset(unit) ao->neg_eap = !ppp_settings.refuse_eap; - ao->chap_mdtype = MDTYPE_NONE; - if(!ppp_settings.refuse_chap) - ao->chap_mdtype |= MDTYPE_MD5; - if(!ppp_settings.refuse_mschap) - ao->chap_mdtype |= MDTYPE_MICROSOFT; - if(!ppp_settings.refuse_mschap_v2) - ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; - - ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); + if(!ppp_settings.refuse_chap) { + ao->chap_mdtype = MDTYPE_MD5; + ao->neg_chap = 1; + } } else { ao->neg_upap = 0; @@ -1318,7 +1269,6 @@ auth_reset(unit) ao->chap_mdtype = MDTYPE_NONE; } - printf("neg_upap: %d\n", ao->neg_upap); printf("neg_chap: %d\n", ao->neg_chap); printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); diff --git a/src/netif/ppp/cbcp.h b/src/netif/ppp/cbcp.h deleted file mode 100644 index c2ab3f68..00000000 --- a/src/netif/ppp/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/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c deleted file mode 100644 index df07a387..00000000 --- a/src/netif/ppp/ccp.c +++ /dev/null @@ -1,1680 +0,0 @@ -/* - * ccp.c - PPP Compression Control Protocol. - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "lwip/opt.h" - -#define RCSID "$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $" - -#include -#include - -#include "pppd.h" -#include "fsm.h" -#include "ccp.h" -#include - -#ifdef MPPE -#include "chap_ms.h" /* mppe_xxxx_key, mppe_keys_set */ -#include "lcp.h" /* lcp_close(), lcp_fsm */ -#endif - -static const char rcsid[] = RCSID; - -/* - * Unfortunately there is a bug in zlib which means that using a - * size of 8 (window size = 256) for Deflate compression will cause - * buffer overruns and kernel crashes in the deflate module. - * Until this is fixed we only accept sizes in the range 9 .. 15. - * Thanks to James Carlson for pointing this out. - */ -#define DEFLATE_MIN_WORKS 9 - -/* - * Command-line options. - */ -static int setbsdcomp __P((char **)); -static int setdeflate __P((char **)); -static char bsd_value[8]; -static char deflate_value[8]; - -/* - * Option variables. - */ -#ifdef MPPE -bool refuse_mppe_stateful = 1; /* Allow stateful mode? */ -#endif - -static option_t ccp_option_list[] = { - { "noccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation" }, - { "-ccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation", OPT_ALIAS }, - - { "bsdcomp", o_special, (void *)setbsdcomp, - "Request BSD-Compress packet compression", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, - { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].bsd_compress }, - { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].bsd_compress }, - - { "deflate", o_special, (void *)setdeflate, - "request Deflate compression", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, - { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].deflate }, - { "-deflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].deflate }, - - { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, - "don't use draft deflate #", OPT_A2COPY, - &ccp_allowoptions[0].deflate_draft }, - - { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "request Predictor-1", OPT_PRIO | 1 }, - { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].predictor_1 }, - { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].predictor_1 }, - -#ifdef MPPE - /* MPPE options are symmetrical ... we only set wantoptions here */ - { "require-mppe", o_bool, &ccp_wantoptions[0].mppe, - "require MPPE encryption", - OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, - { "+mppe", o_bool, &ccp_wantoptions[0].mppe, - "require MPPE encryption", - OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, - { "nomppe", o_bool, &ccp_wantoptions[0].mppe, - "don't allow MPPE encryption", OPT_PRIO }, - { "-mppe", o_bool, &ccp_wantoptions[0].mppe, - "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO }, - - /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */ - { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 40-bit encryption", - OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, - { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 40-bit encryption", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - - { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 128-bit encryption", - OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 128-bit encryption", - OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, - { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 128-bit encryption", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - - /* strange one; we always request stateless, but will we allow stateful? */ - { "mppe-stateful", o_bool, &refuse_mppe_stateful, - "allow MPPE stateful mode", OPT_PRIO }, - { "nomppe-stateful", o_bool, &refuse_mppe_stateful, - "disallow MPPE stateful mode", OPT_PRIO | 1 }, -#endif /* MPPE */ - - { NULL } -}; - -/* - * Protocol entry points from main code. - */ -static void ccp_init __P((int unit)); -static void ccp_open __P((int unit)); -static void ccp_close __P((int unit, char *)); -static void ccp_lowerup __P((int unit)); -static void ccp_lowerdown __P((int)); -static void ccp_input __P((int unit, u_char *pkt, int len)); -static void ccp_protrej __P((int unit)); -static int ccp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); -static void ccp_datainput __P((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 __P((fsm *)); -static int ccp_cilen __P((fsm *)); -static void ccp_addci __P((fsm *, u_char *, int *)); -static int ccp_ackci __P((fsm *, u_char *, int)); -static int ccp_nakci __P((fsm *, u_char *, int, int)); -static int ccp_rejci __P((fsm *, u_char *, int)); -static int ccp_reqci __P((fsm *, u_char *, int *, int)); -static void ccp_up __P((fsm *)); -static void ccp_down __P((fsm *)); -static int ccp_extcode __P((fsm *, int, int, u_char *, int)); -static void ccp_rack_timeout __P((void *)); -static char *method_name __P((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 \ - || (opt).mppe) - -/* - * 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(argv) - 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; - slprintf(bsd_value, sizeof(bsd_value), - rbits == abits? "%d": "%d,%d", rbits, abits); - - return 1; -} - -static int -setdeflate(argv) - 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 == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { - if (rbits == DEFLATE_MIN_SIZE) - rbits = DEFLATE_MIN_WORKS; - if (abits == DEFLATE_MIN_SIZE) - abits = DEFLATE_MIN_WORKS; - warn("deflate option value of %d changed to %d to avoid zlib bug", - DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); - } - 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; - slprintf(deflate_value, sizeof(deflate_value), - rbits == abits? "%d": "%d,%d", rbits, abits); - - return 1; -} - -/* - * ccp_init - initialize CCP. - */ -static void -ccp_init(unit) - 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(unit) - 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(unit, reason) - 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(unit) - int unit; -{ - fsm_lowerup(&ccp_fsm[unit]); -} - -/* - * ccp_lowerdown - we may not transmit CCP packets. - */ -static void -ccp_lowerdown(unit) - int unit; -{ - fsm_lowerdown(&ccp_fsm[unit]); -} - -/* - * ccp_input - process a received CCP packet. - */ -static void -ccp_input(unit, p, len) - 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."); -#ifdef MPPE - if (ccp_gotoptions[unit].mppe) { - error("MPPE disabled, closing LCP"); - lcp_close(unit, "MPPE disabled by peer"); - } -#endif - } - - /* - * 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(f, code, id, p, len) - fsm *f; - int code, 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(unit) - int unit; -{ - ccp_flags_set(unit, 0, 0); - fsm_lowerdown(&ccp_fsm[unit]); - -#ifdef MPPE - if (ccp_gotoptions[unit].mppe) { - error("MPPE required but peer negotiation failed"); - lcp_close(unit, "MPPE required but peer negotiation failed"); - } -#endif - -} - -/* - * ccp_resetci - initialize at start of negotiation. - */ -static void -ccp_resetci(f) - fsm *f; -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char opt_buf[CCP_MAX_OPTION_LENGTH]; - - *go = ccp_wantoptions[f->unit]; - all_rejected[f->unit] = 0; - -#ifdef MPPE - if (go->mppe) { - ccp_options *ao = &ccp_allowoptions[f->unit]; - int auth_mschap_bits = auth_done[f->unit]; - int numbits; - - /* - * Start with a basic sanity check: mschap[v2] auth must be in - * exactly one direction. RFC 3079 says that the keys are - * 'derived from the credentials of the peer that initiated the call', - * however the PPP protocol doesn't have such a concept, and pppd - * cannot get this info externally. Instead we do the best we can. - * NB: If MPPE is required, all other compression opts are invalid. - * So, we return right away if we can't do it. - */ - - /* Leave only the mschap auth bits set */ - auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER | - CHAP_MS2_WITHPEER | CHAP_MS2_PEER); - /* Count the mschap auths */ - auth_mschap_bits >>= CHAP_MS_SHIFT; - numbits = 0; - do { - numbits += auth_mschap_bits & 1; - auth_mschap_bits >>= 1; - } while (auth_mschap_bits); - if (numbits > 1) { - error("MPPE required, but auth done in both directions."); - lcp_close(f->unit, "MPPE required but not available"); - return; - } - if (!numbits) { - error("MPPE required, but MS-CHAP[v2] auth not performed."); - lcp_close(f->unit, "MPPE required but not available"); - return; - } - - /* A plugin (eg radius) may not have obtained key material. */ - if (!mppe_keys_set) { - error("MPPE required, but keys are not available. " - "Possible plugin problem?"); - lcp_close(f->unit, "MPPE required but not available"); - return; - } - - /* LM auth not supported for MPPE */ - if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) { - /* This might be noise */ - if (go->mppe & MPPE_OPT_40) { - notice("Disabling 40-bit MPPE; MS-CHAP LM not supported"); - go->mppe &= ~MPPE_OPT_40; - ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40; - } - } - - /* Last check: can we actually negotiate something? */ - if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) { - /* Could be misconfig, could be 40-bit disabled above. */ - error("MPPE required, but both 40-bit and 128-bit disabled."); - lcp_close(f->unit, "MPPE required but not available"); - return; - } - - /* sync options */ - ao->mppe = go->mppe; - /* MPPE is not compatible with other compression types */ - ao->bsd_compress = go->bsd_compress = 0; - ao->predictor_1 = go->predictor_1 = 0; - ao->predictor_2 = go->predictor_2 = 0; - ao->deflate = go->deflate = 0; - } -#endif /* MPPE */ - - /* - * Check whether the kernel knows about the various - * compression methods we might request. - */ -#ifdef MPPE - if (go->mppe) { - opt_buf[0] = CI_MPPE; - opt_buf[1] = CILEN_MPPE; - MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); - /* Key material unimportant here. */ - if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) { - error("MPPE required, but kernel has no support."); - lcp_close(f->unit, "MPPE required but not available"); - } - } -#endif - 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_WORKS); - 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_WORKS); - 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(f) - 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) - + (go->mppe? CILEN_MPPE: 0); -} - -/* - * ccp_addci - put our requests in a packet. - */ -static void -ccp_addci(f, p, lenp) - 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. - */ -#ifdef MPPE - if (go->mppe) { - u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; - - p[0] = opt_buf[0] = CI_MPPE; - p[1] = opt_buf[1] = CILEN_MPPE; - MPPE_OPTS_TO_CI(go->mppe, &p[2]); - MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); - BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN); - res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0); - if (res > 0) - p += CILEN_MPPE; - else - /* This shouldn't happen, we've already tested it! */ - lcp_close(f->unit, "MPPE required but not available in kernel"); - } -#endif - 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; - if (p != p0) { - p += CILEN_DEFLATE; - } else { - for (;;) { - if (go->deflate_size < DEFLATE_MIN_WORKS) { - go->deflate = 0; - break; - } - res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); - if (res > 0) { - p += CILEN_DEFLATE; - break; - } else if (res < 0) { - 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 (;;) { - if (go->bsd_bits < BSD_MIN_BITS) { - go->bsd_compress = 0; - break; - } - res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); - if (res > 0) { - p += CILEN_BSD_COMPRESS; - break; - } else if (res < 0) { - 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(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char *p0 = p; - -#ifdef MPPE - if (go->mppe) { - u_char opt_buf[CILEN_MPPE]; - - opt_buf[0] = CI_MPPE; - opt_buf[1] = CILEN_MPPE; - MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); - if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE)) - return 0; - p += CILEN_MPPE; - len -= CILEN_MPPE; - /* XXX Cope with first/fast ack */ - if (len == 0) - return 1; - } -#endif - 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(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; -{ - 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; - -#ifdef MPPE - if (go->mppe && len >= CILEN_MPPE - && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { - no.mppe = 1; - /* - * Peer wants us to use a different strength or other setting. - * Fail if we aren't willing to use his suggestion. - */ - MPPE_CI_TO_OPTS(&p[2], try.mppe); - if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) { - error("Refusing MPPE stateful mode offered by peer"); - try.mppe = 0; - } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) { - /* Peer must have set options we didn't request (suggest) */ - try.mppe = 0; - } - - if (!try.mppe) { - error("MPPE required but peer negotiation failed"); - lcp_close(f->unit, "MPPE required but peer negotiation failed"); - } - } -#endif /* MPPE */ - 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_WORKS - || 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(f, p, len) - 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; - -#ifdef MPPE - if (go->mppe && len >= CILEN_MPPE - && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { - error("MPPE required but peer refused"); - lcp_close(f->unit, "MPPE required but peer refused"); - p += CILEN_MPPE; - len -= CILEN_MPPE; - } -#endif - if (go->deflate_correct && len >= CILEN_DEFLATE - && p[0] == CI_DEFLATE && 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_correct = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - if (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(f, p, lenp, dont_nak) - 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]; -#ifdef MPPE - bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */ - /* CI_MPPE, or due to other options? */ -#endif - - 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) { -#ifdef MPPE - case CI_MPPE: - if (!ao->mppe || clen != CILEN_MPPE) { - newret = CONFREJ; - break; - } - MPPE_CI_TO_OPTS(&p[2], ho->mppe); - - /* Nak if anything unsupported or unknown are set. */ - if (ho->mppe & MPPE_OPT_UNSUPPORTED) { - newret = CONFNAK; - ho->mppe &= ~MPPE_OPT_UNSUPPORTED; - } - if (ho->mppe & MPPE_OPT_UNKNOWN) { - newret = CONFNAK; - ho->mppe &= ~MPPE_OPT_UNKNOWN; - } - - /* Check state opt */ - if (ho->mppe & MPPE_OPT_STATEFUL) { - /* - * We can Nak and request stateless, but it's a - * lot easier to just assume the peer will request - * it if he can do it; stateful mode is bad over - * the Internet -- which is where we expect MPPE. - */ - if (refuse_mppe_stateful) { - error("Refusing MPPE stateful mode offered by peer"); - newret = CONFREJ; - break; - } - } - - /* Find out which of {S,L} are set. */ - if ((ho->mppe & MPPE_OPT_128) - && (ho->mppe & MPPE_OPT_40)) { - /* Both are set, negotiate the strongest. */ - newret = CONFNAK; - if (ao->mppe & MPPE_OPT_128) - ho->mppe &= ~MPPE_OPT_40; - else if (ao->mppe & MPPE_OPT_40) - ho->mppe &= ~MPPE_OPT_128; - else { - newret = CONFREJ; - break; - } - } else if (ho->mppe & MPPE_OPT_128) { - if (!(ao->mppe & MPPE_OPT_128)) { - newret = CONFREJ; - break; - } - } else if (ho->mppe & MPPE_OPT_40) { - if (!(ao->mppe & MPPE_OPT_40)) { - newret = CONFREJ; - break; - } - } else { - /* Neither are set. */ - /* We cannot accept this. */ - newret = CONFNAK; - /* Give the peer our idea of what can be used, - so it can choose and confirm */ - ho->mppe = ao->mppe; - } - - /* rebuild the opts */ - MPPE_OPTS_TO_CI(ho->mppe, &p[2]); - if (newret == CONFACK) { - u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; - int mtu; - - BCOPY(p, opt_buf, CILEN_MPPE); - BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE], - MPPE_MAX_KEY_LEN); - if (ccp_test(f->unit, opt_buf, - CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) { - /* This shouldn't happen, we've already tested it! */ - error("MPPE required, but kernel has no support."); - lcp_close(f->unit, "MPPE required but not available"); - newret = CONFREJ; - break; - } - /* - * We need to decrease the interface MTU by MPPE_PAD - * because MPPE frames **grow**. The kernel [must] - * allocate MPPE_PAD extra bytes in xmit buffers. - */ - mtu = netif_get_mtu(f->unit); - if (mtu) - netif_set_mtu(f->unit, mtu - MPPE_PAD); - else - newret = CONFREJ; - } - - /* - * We have accepted MPPE or are willing to negotiate - * MPPE parameters. A CONFREJ is due to subsequent - * (non-MPPE) processing. - */ - rej_for_ci_mppe = 0; - break; -#endif /* MPPE */ - 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_WORKS) { - 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_WORKS || 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; - } -#ifdef MPPE - if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) { - error("MPPE required but peer negotiation failed"); - lcp_close(f->unit, "MPPE required but peer negotiation failed"); - } -#endif - return ret; -} - -/* - * Make a string name for a compression method (or 2). - */ -static char * -method_name(opt, opt2) - ccp_options *opt, *opt2; -{ - static char result[64]; - - if (!ANY_COMPRESS(*opt)) - return "(none)"; - switch (opt->method) { -#ifdef MPPE - case CI_MPPE: - { - char *p = result; - char *q = result + sizeof(result); /* 1 past result */ - - slprintf(p, q - p, "MPPE "); - p += 5; - if (opt->mppe & MPPE_OPT_128) { - slprintf(p, q - p, "128-bit "); - p += 8; - } - if (opt->mppe & MPPE_OPT_40) { - slprintf(p, q - p, "40-bit "); - p += 7; - } - if (opt->mppe & MPPE_OPT_STATEFUL) - slprintf(p, q - p, "stateful"); - else - slprintf(p, q - p, "stateless"); - - break; - } -#endif - 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(f) - 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)); -#ifdef MPPE - if (go->mppe) { - BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN); - BZERO(mppe_send_key, MPPE_MAX_KEY_LEN); - continue_networks(f->unit); /* Bring up IP et al */ - } -#endif -} - -/* - * CCP has gone down - inform the kernel driver. - */ -static void -ccp_down(f) - 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); -#ifdef MPPE - if (ccp_gotoptions[f->unit].mppe) { - ccp_gotoptions[f->unit].mppe = 0; - if (lcp_fsm[f->unit].state == OPENED) { - /* If LCP is not already going down, make sure it does. */ - error("MPPE disabled"); - lcp_close(f->unit, "MPPE disabled"); - } - } -#endif -} - -/* - * 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(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((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) { -#ifdef MPPE - case CI_MPPE: - if (optlen >= CILEN_MPPE) { - u_char mppe_opts; - - MPPE_CI_TO_OPTS(&p[2], mppe_opts); - printer(arg, "mppe %s %s %s %s %s %s%s", - (p[2] & MPPE_H_BIT)? "+H": "-H", - (p[5] & MPPE_M_BIT)? "+M": "-M", - (p[5] & MPPE_S_BIT)? "+S": "-S", - (p[5] & MPPE_L_BIT)? "+L": "-L", - (p[5] & MPPE_D_BIT)? "+D": "-D", - (p[5] & MPPE_C_BIT)? "+C": "-C", - (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": ""); - if (mppe_opts & MPPE_OPT_UNKNOWN) - printer(arg, " (%.2x %.2x %.2x %.2x)", - p[2], p[3], p[4], p[5]); - p += CILEN_MPPE; - } - break; -#endif - 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((char *)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(unit, pkt, len) - 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"); -#ifdef MPPE - /* - * If we were doing MPPE, we must also take the link down. - */ - if (ccp_gotoptions[unit].mppe) { - error("Too many MPPE errors, closing LCP"); - lcp_close(unit, "Too many MPPE errors"); - } -#endif - } 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(arg) - 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/src/netif/ppp/ccp.h b/src/netif/ppp/ccp.h deleted file mode 100644 index 6f4a2fee..00000000 --- a/src/netif/ppp/ccp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ccp.h - Definitions for PPP Compression Control Protocol. - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $ - */ - -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? */ - bool mppe; /* do MPPE? */ - 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/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c deleted file mode 100644 index 0d3b5347..00000000 --- a/src/netif/ppp/chap_ms.c +++ /dev/null @@ -1,943 +0,0 @@ -/* - * chap_ms.c - Microsoft MS-CHAP compatible implementation. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * 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 - */ - -/* - * Modifications by Frank Cusack, frank@google.com, March 2002. - * - * Implemented MS-CHAPv2 functionality, heavily based on sample - * implementation in RFC 2759. Implemented MPPE functionality, - * heavily based on sample implementation in RFC 3079. - * - * Copyright (c) 2002 Google, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "lwip/opt.h" - -#define RCSID "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $" - -#ifdef CHAPMS - -#include -#include -#include -#include -#include -#include -#include - -#include "pppd.h" -#include "chap-new.h" -#include "chap_ms.h" -#include "md4.h" -#include "sha1.h" -#include "pppcrypt.h" -#include "magic.h" - -static const char rcsid[] = RCSID; - - -static void ascii2unicode __P((char[], int, u_char[])); -static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); -static void ChallengeResponse __P((u_char *, u_char *, u_char[24])); -static void ChapMS_NT __P((u_char *, char *, int, u_char[24])); -static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int, - u_char[24])); -static void GenerateAuthenticatorResponsePlain - __P((char*, int, u_char[24], u_char[16], u_char *, - char *, u_char[41])); -#ifdef MSLANMAN -static void ChapMS_LANMan __P((u_char *, char *, int, u_char *)); -#endif - -#ifdef MPPE -static void Set_Start_Key __P((u_char *, char *, int)); -static void SetMasterKeys __P((char *, int, u_char[24], int)); -#endif - -#ifdef MSLANMAN -bool ms_lanman = 0; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -#ifdef MPPE -u_char mppe_send_key[MPPE_MAX_KEY_LEN]; -u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; -int mppe_keys_set = 0; /* Have the MPPE keys been set? */ - -#ifdef DEBUGMPPEKEY -/* For MPPE debug */ -/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */ -static char *mschap_challenge = NULL; -/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */ -static char *mschap2_peer_challenge = NULL; -#endif - -#include "fsm.h" /* Need to poke MPPE options */ -#include "ccp.h" -#include -#endif - -/* - * Command-line options. - */ -static option_t chapms_option_list[] = { -#ifdef MSLANMAN - { "ms-lanman", o_bool, &ms_lanman, - "Use LanMan passwd when using MS-CHAP", 1 }, -#endif -#ifdef DEBUGMPPEKEY - { "mschap-challenge", o_string, &mschap_challenge, - "specify CHAP challenge" }, - { "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, - "specify CHAP peer challenge" }, -#endif - { NULL } -}; - -/* - * chapms_generate_challenge - generate a challenge for MS-CHAP. - * For MS-CHAP the challenge length is fixed at 8 bytes. - * The length goes in challenge[0] and the actual challenge starts - * at challenge[1]. - */ -static void -chapms_generate_challenge(unsigned char *challenge) -{ - *challenge++ = 8; -#ifdef DEBUGMPPEKEY - if (mschap_challenge && strlen(mschap_challenge) == 8) - memcpy(challenge, mschap_challenge, 8); - else -#endif - random_bytes(challenge, 8); -} - -static void -chapms2_generate_challenge(unsigned char *challenge) -{ - *challenge++ = 16; -#ifdef DEBUGMPPEKEY - if (mschap_challenge && strlen(mschap_challenge) == 16) - memcpy(challenge, mschap_challenge, 16); - else -#endif - random_bytes(challenge, 16); -} - -static int -chapms_verify_response(int id, char *name, - unsigned char *secret, int secret_len, - unsigned char *challenge, unsigned char *response, - char *message, int message_space) -{ - unsigned char md[MS_CHAP_RESPONSE_LEN]; - int diff; - int challenge_len, response_len; - - challenge_len = *challenge++; /* skip length, is 8 */ - response_len = *response++; - if (response_len != MS_CHAP_RESPONSE_LEN) - goto bad; - -#ifndef MSLANMAN - if (!response[MS_CHAP_USENT]) { - /* Should really propagate this into the error packet. */ - notice("Peer request for LANMAN auth not supported"); - goto bad; - } -#endif - - /* Generate the expected response. */ - ChapMS(challenge, (char *)secret, secret_len, md); - -#ifdef MSLANMAN - /* Determine which part of response to verify against */ - if (!response[MS_CHAP_USENT]) - diff = memcmp(&response[MS_CHAP_LANMANRESP], - &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN); - else -#endif - diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP], - MS_CHAP_NTRESP_LEN); - - if (diff == 0) { - slprintf(message, message_space, "Access granted"); - return 1; - } - - bad: - /* See comments below for MS-CHAP V2 */ - slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", - challenge_len, challenge); - return 0; -} - -static int -chapms2_verify_response(int id, char *name, - unsigned char *secret, int secret_len, - unsigned char *challenge, unsigned char *response, - char *message, int message_space) -{ - unsigned char md[MS_CHAP2_RESPONSE_LEN]; - char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; - int challenge_len, response_len; - - challenge_len = *challenge++; /* skip length, is 16 */ - response_len = *response++; - if (response_len != MS_CHAP2_RESPONSE_LEN) - goto bad; /* not even the right length */ - - /* Generate the expected response and our mutual auth. */ - ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name, - (char *)secret, secret_len, md, - (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); - - /* compare MDs and send the appropriate status */ - /* - * Per RFC 2759, success message must be formatted as - * "S= M=" - * where - * is the Authenticator Response (mutual auth) - * is a text message - * - * However, some versions of Windows (win98 tested) do not know - * about the M= part (required per RFC 2759) and flag - * it as an error (reported incorrectly as an encryption error - * to the user). Since the RFC requires it, and it can be - * useful information, we supply it if the peer is a conforming - * system. Luckily (?), win98 sets the Flags field to 0x04 - * (contrary to RFC requirements) so we can use that to - * distinguish between conforming and non-conforming systems. - * - * Special thanks to Alex Swiridov for - * help debugging this. - */ - if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], - MS_CHAP2_NTRESP_LEN) == 0) { - if (response[MS_CHAP2_FLAGS]) - slprintf(message, message_space, "S=%s", saresponse); - else - slprintf(message, message_space, "S=%s M=%s", - saresponse, "Access granted"); - return 1; - } - - bad: - /* - * Failure message must be formatted as - * "E=e R=r C=c V=v M=m" - * where - * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE) - * r = retry (we use 1, ok to retry) - * c = challenge to use for next response, we reuse previous - * v = Change Password version supported, we use 0 - * m = text message - * - * The M=m part is only for MS-CHAPv2. Neither win2k nor - * win98 (others untested) display the message to the user anyway. - * They also both ignore the E=e code. - * - * Note that it's safe to reuse the same challenge as we don't - * actually accept another response based on the error message - * (and no clients try to resend a response anyway). - * - * Basically, this whole bit is useless code, even the small - * implementation here is only because of overspecification. - */ - slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", - challenge_len, challenge, "Access denied"); - return 0; -} - -static void -chapms_make_response(unsigned char *response, int id, char *our_name, - unsigned char *challenge, char *secret, int secret_len, - unsigned char *private) -{ - challenge++; /* skip length, should be 8 */ - *response++ = MS_CHAP_RESPONSE_LEN; - ChapMS(challenge, secret, secret_len, response); -} - -static void -chapms2_make_response(unsigned char *response, int id, char *our_name, - unsigned char *challenge, char *secret, int secret_len, - unsigned char *private) -{ - challenge++; /* skip length, should be 16 */ - *response++ = MS_CHAP2_RESPONSE_LEN; - ChapMS2(challenge, -#ifdef DEBUGMPPEKEY - mschap2_peer_challenge, -#else - NULL, -#endif - our_name, secret, secret_len, response, private, - MS_CHAP2_AUTHENTICATEE); -} - -static int -chapms2_check_success(unsigned char *msg, int len, unsigned char *private) -{ - if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || - strncmp((char *)msg, "S=", 2) != 0) { - /* Packet does not start with "S=" */ - error("MS-CHAPv2 Success packet is badly formed."); - return 0; - } - msg += 2; - len -= 2; - if (len < MS_AUTH_RESPONSE_LENGTH - || memcmp(msg, private, MS_AUTH_RESPONSE_LENGTH)) { - /* Authenticator Response did not match expected. */ - error("MS-CHAPv2 mutual authentication failed."); - return 0; - } - /* Authenticator Response matches. */ - msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */ - len -= MS_AUTH_RESPONSE_LENGTH; - if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) { - msg += 3; /* Eat the delimiter */ - } else if (len) { - /* Packet has extra text which does not begin " M=" */ - error("MS-CHAPv2 Success packet is badly formed."); - return 0; - } - return 1; -} - -static void -chapms_handle_failure(unsigned char *inp, int len) -{ - int err; - char *p, *msg; - - /* We want a null-terminated string for strxxx(). */ - msg = malloc(len + 1); - if (!msg) { - notice("Out of memory in chapms_handle_failure"); - return; - } - BCOPY(inp, msg, len); - msg[len] = 0; - p = msg; - - /* - * Deal with MS-CHAP formatted failure messages; just print the - * M= part (if any). For MS-CHAP we're not really supposed - * to use M=, but it shouldn't hurt. See - * chapms[2]_verify_response. - */ - if (!strncmp(p, "E=", 2)) - err = strtol(p+2, NULL, 10); /* Remember the error code. */ - else - goto print_msg; /* Message is badly formatted. */ - - if (len && ((p = strstr(p, " M=")) != NULL)) { - /* M= field found. */ - p += 3; - } else { - /* No M=; use the error code. */ - switch (err) { - case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS: - p = "E=646 Restricted logon hours"; - break; - - case MS_CHAP_ERROR_ACCT_DISABLED: - p = "E=647 Account disabled"; - break; - - case MS_CHAP_ERROR_PASSWD_EXPIRED: - p = "E=648 Password expired"; - break; - - case MS_CHAP_ERROR_NO_DIALIN_PERMISSION: - p = "E=649 No dialin permission"; - break; - - case MS_CHAP_ERROR_AUTHENTICATION_FAILURE: - p = "E=691 Authentication failure"; - break; - - case MS_CHAP_ERROR_CHANGING_PASSWORD: - /* Should never see this, we don't support Change Password. */ - p = "E=709 Error changing password"; - break; - - default: - free(msg); - error("Unknown MS-CHAP authentication failure: %.*v", - len, inp); - return; - } - } -print_msg: - if (p != NULL) - error("MS-CHAP authentication failed: %v", p); - free(msg); -} - -static void -ChallengeResponse(u_char *challenge, - u_char PasswordHash[MD4_SIGNATURE_SIZE], - u_char response[24]) -{ - u_char ZPasswordHash[21]; - - BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE); - -#if 0 - dbglog("ChallengeResponse - ZPasswordHash %.*B", - sizeof(ZPasswordHash), ZPasswordHash); -#endif - - (void) DesSetkey(ZPasswordHash + 0); - DesEncrypt(challenge, response + 0); - (void) DesSetkey(ZPasswordHash + 7); - DesEncrypt(challenge, response + 8); - (void) DesSetkey(ZPasswordHash + 14); - DesEncrypt(challenge, response + 16); - -#if 0 - dbglog("ChallengeResponse - response %.24B", response); -#endif -} - -void -ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, - char *username, u_char Challenge[8]) - -{ - SHA1_CTX sha1Context; - u_char sha1Hash[SHA1_SIGNATURE_SIZE]; - char *user; - - /* remove domain from "domain\username" */ - if ((user = strrchr(username, '\\')) != NULL) - ++user; - else - user = username; - - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PeerChallenge, 16); - SHA1_Update(&sha1Context, rchallenge, 16); - SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user)); - SHA1_Final(sha1Hash, &sha1Context); - - BCOPY(sha1Hash, Challenge, 8); -} - -/* - * Convert the ASCII version of the password to Unicode. - * This implicitly supports 8-bit ISO8859/1 characters. - * This gives us the little-endian representation, which - * is assumed by all M$ CHAP RFCs. (Unicode byte ordering - * is machine-dependent.) - */ -static void -ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) -{ - int i; - - BZERO(unicode, ascii_len * 2); - for (i = 0; i < ascii_len; i++) - unicode[i * 2] = (u_char) ascii[i]; -} - -static void -NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) -{ -#ifdef __NetBSD__ - /* NetBSD uses the libc md4 routines which take bytes instead of bits */ - int mdlen = secret_len; -#else - int mdlen = secret_len * 8; -#endif - MD4_CTX md4Context; - - MD4Init(&md4Context); - /* MD4Update can take at most 64 bytes at a time */ - while (mdlen > 512) { - MD4Update(&md4Context, secret, 512); - secret += 64; - mdlen -= 512; - } - MD4Update(&md4Context, secret, mdlen); - MD4Final(hash, &md4Context); - -} - -static void -ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, - u_char NTResponse[24]) -{ - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - - /* Hash the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - - ChallengeResponse(rchallenge, PasswordHash, NTResponse); -} - -static void -ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, - char *secret, int secret_len, u_char NTResponse[24]) -{ - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char Challenge[8]; - - ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - - /* Hash the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - - ChallengeResponse(Challenge, PasswordHash, NTResponse); -} - -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void -ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, - unsigned char *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]); - (void) DesSetkey(UcasePassword + 0); - DesEncrypt( StdText, PasswordHash + 0 ); - (void) DesSetkey(UcasePassword + 7); - DesEncrypt( StdText, PasswordHash + 8 ); - ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); -} -#endif - - -void -GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], u_char PeerChallenge[16], - u_char *rchallenge, char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) -{ - /* - * "Magic" constants used in response generation, from RFC 2759. - */ - u_char Magic1[39] = /* "Magic server to client signing constant" */ - { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, - 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, - 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; - u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ - { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, - 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, - 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, - 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, - 0x6E }; - - int i; - SHA1_CTX sha1Context; - u_char Digest[SHA1_SIGNATURE_SIZE]; - u_char Challenge[8]; - - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, NTResponse, 24); - SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); - SHA1_Final(Digest, &sha1Context); - - ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, Digest, sizeof(Digest)); - SHA1_Update(&sha1Context, Challenge, sizeof(Challenge)); - SHA1_Update(&sha1Context, Magic2, sizeof(Magic2)); - SHA1_Final(Digest, &sha1Context); - - /* Convert to ASCII hex string. */ - for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) - sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); -} - - -static void -GenerateAuthenticatorResponsePlain - (char *secret, int secret_len, - u_char NTResponse[24], u_char PeerChallenge[16], - u_char *rchallenge, char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) -{ - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), - PasswordHashHash); - - GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge, - rchallenge, username, authResponse); -} - - -#ifdef MPPE -/* - * Set mppe_xxxx_key from the NTPasswordHashHash. - * RFC 2548 (RADIUS support) requires us to export this function (ugh). - */ -void -mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) -{ - SHA1_CTX sha1Context; - u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, rchallenge, 8); - SHA1_Final(Digest, &sha1Context); - - /* Same key in both directions. */ - BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); - BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); - - mppe_keys_set = 1; -} - -/* - * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) - */ -static void -Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) -{ - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); - - mppe_set_keys(rchallenge, PasswordHashHash); -} - -/* - * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) - * - * This helper function used in the Winbind module, which gets the - * NTHashHash from the server. - */ -void -mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], int IsServer) -{ - SHA1_CTX sha1Context; - u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - - u_char SHApad1[40] = - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - u_char SHApad2[40] = - { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 }; - - /* "This is the MPPE Master Key" */ - u_char Magic1[27] = - { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; - /* "On the client side, this is the send key; " - "on the server side, it is the receive key." */ - u_char Magic2[84] = - { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, - 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, - 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, - 0x6b, 0x65, 0x79, 0x2e }; - /* "On the client side, this is the receive key; " - "on the server side, it is the send key." */ - u_char Magic3[84] = - { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, - 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, - 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, - 0x6b, 0x65, 0x79, 0x2e }; - u_char *s; - - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, NTResponse, 24); - SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); - SHA1_Final(MasterKey, &sha1Context); - - /* - * generate send key - */ - if (IsServer) - s = Magic3; - else - s = Magic2; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, MasterKey, 16); - SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); - SHA1_Update(&sha1Context, s, 84); - SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); - SHA1_Final(Digest, &sha1Context); - - BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); - - /* - * generate recv key - */ - if (IsServer) - s = Magic2; - else - s = Magic3; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, MasterKey, 16); - SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); - SHA1_Update(&sha1Context, s, 84); - SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); - SHA1_Final(Digest, &sha1Context); - - BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); - - mppe_keys_set = 1; -} - -/* - * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) - */ -static void -SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) -{ - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); - mppe_set_keys2(PasswordHashHash, NTResponse, IsServer); -} - -#endif /* MPPE */ - - -void -ChapMS(u_char *rchallenge, char *secret, int secret_len, - unsigned char *response) -{ - BZERO(response, MS_CHAP_RESPONSE_LEN); - - ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); - -#ifdef MSLANMAN - ChapMS_LANMan(rchallenge, secret, secret_len, - &response[MS_CHAP_LANMANRESP]); - - /* preferred method is set by option */ - response[MS_CHAP_USENT] = !ms_lanman; -#else - response[MS_CHAP_USENT] = 1; -#endif - -#ifdef MPPE - Set_Start_Key(rchallenge, secret, secret_len); -#endif -} - - -/* - * If PeerChallenge is NULL, one is generated and the PeerChallenge - * field of response is filled in. Call this way when generating a response. - * If PeerChallenge is supplied, it is copied into the PeerChallenge field. - * Call this way when verifying a response (or debugging). - * Do not call with PeerChallenge = response. - * - * The PeerChallenge field of response is then used for calculation of the - * Authenticator Response. - */ -void -ChapMS2(u_char *rchallenge, u_char *PeerChallenge, - char *user, char *secret, int secret_len, unsigned char *response, - u_char authResponse[], int authenticator) -{ - /* ARGSUSED */ - u_char *p = &response[MS_CHAP2_PEER_CHALLENGE]; - int i; - - BZERO(response, MS_CHAP2_RESPONSE_LEN); - - /* Generate the Peer-Challenge if requested, or copy it if supplied. */ - if (!PeerChallenge) - for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++) - *p++ = (u_char) (drand48() * 0xff); - else - BCOPY(PeerChallenge, &response[MS_CHAP2_PEER_CHALLENGE], - MS_CHAP2_PEER_CHAL_LEN); - - /* Generate the NT-Response */ - ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, - secret, secret_len, &response[MS_CHAP2_NTRESP]); - - /* Generate the Authenticator Response. */ - GenerateAuthenticatorResponsePlain(secret, secret_len, - &response[MS_CHAP2_NTRESP], - &response[MS_CHAP2_PEER_CHALLENGE], - rchallenge, user, authResponse); - -#ifdef MPPE - SetMasterKeys(secret, secret_len, - &response[MS_CHAP2_NTRESP], authenticator); -#endif -} - -#ifdef MPPE -/* - * Set MPPE options from plugins. - */ -void -set_mppe_enc_types(int policy, int types) -{ - /* Early exit for unknown policies. */ - if (policy != MPPE_ENC_POL_ENC_ALLOWED || - policy != MPPE_ENC_POL_ENC_REQUIRED) - return; - - /* Don't modify MPPE if it's optional and wasn't already configured. */ - if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe) - return; - - /* - * Disable undesirable encryption types. Note that we don't ENABLE - * any encryption types, to avoid overriding manual configuration. - */ - switch(types) { - case MPPE_ENC_TYPES_RC4_40: - ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */ - break; - case MPPE_ENC_TYPES_RC4_128: - ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */ - break; - default: - break; - } -} -#endif /* MPPE */ - -static struct chap_digest_type chapms_digest = { - CHAP_MICROSOFT, /* code */ - chapms_generate_challenge, - chapms_verify_response, - chapms_make_response, - NULL, /* check_success */ - chapms_handle_failure, -}; - -static struct chap_digest_type chapms2_digest = { - CHAP_MICROSOFT_V2, /* code */ - chapms2_generate_challenge, - chapms2_verify_response, - chapms2_make_response, - chapms2_check_success, - chapms_handle_failure, -}; - -void -chapms_init(void) -{ - chap_register_digest(&chapms_digest); - chap_register_digest(&chapms2_digest); - add_options(chapms_option_list); -} - -#endif /* CHAPMS */ diff --git a/src/netif/ppp/chap_ms.h b/src/netif/ppp/chap_ms.h deleted file mode 100644 index 040d80ad..00000000 --- a/src/netif/ppp/chap_ms.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * chap_ms.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ - */ - -#ifndef __CHAPMS_INCLUDE__ - -#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ -#define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */ - -#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ -#define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */ -#define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */ - /* as ASCII */ - -/* E=eeeeeeeeee error codes for MS-CHAP failure messages. */ -#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646 -#define MS_CHAP_ERROR_ACCT_DISABLED 647 -#define MS_CHAP_ERROR_PASSWD_EXPIRED 648 -#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649 -#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691 -#define MS_CHAP_ERROR_CHANGING_PASSWORD 709 - -/* - * Offsets within the response field for MS-CHAP - */ -#define MS_CHAP_LANMANRESP 0 -#define MS_CHAP_LANMANRESP_LEN 24 -#define MS_CHAP_NTRESP 24 -#define MS_CHAP_NTRESP_LEN 24 -#define MS_CHAP_USENT 48 - -/* - * Offsets within the response field for MS-CHAP2 - */ -#define MS_CHAP2_PEER_CHALLENGE 0 -#define MS_CHAP2_PEER_CHAL_LEN 16 -#define MS_CHAP2_RESERVED_LEN 8 -#define MS_CHAP2_NTRESP 24 -#define MS_CHAP2_NTRESP_LEN 24 -#define MS_CHAP2_FLAGS 48 - -#ifdef MPPE -#include "mppe.h" /* MPPE_MAX_KEY_LEN */ -extern u_char mppe_send_key[MPPE_MAX_KEY_LEN]; -extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; -extern int mppe_keys_set; - -/* These values are the RADIUS attribute values--see RFC 2548. */ -#define MPPE_ENC_POL_ENC_ALLOWED 1 -#define MPPE_ENC_POL_ENC_REQUIRED 2 -#define MPPE_ENC_TYPES_RC4_40 2 -#define MPPE_ENC_TYPES_RC4_128 4 - -/* used by plugins (using above values) */ -extern void set_mppe_enc_types(int, int); -#endif - -/* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */ -#define MS_CHAP2_AUTHENTICATEE 0 -#define MS_CHAP2_AUTHENTICATOR 1 - -void ChapMS __P((u_char *, char *, int, u_char *)); -void ChapMS2 __P((u_char *, u_char *, char *, char *, int, - u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int)); -#ifdef MPPE -void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE])); -void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], int IsServer); -#endif - -void ChallengeHash __P((u_char[16], u_char *, char *, u_char[8])); - -void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], u_char PeerChallenge[16], - u_char *rchallenge, char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]); - -void chapms_init(void); - -#define __CHAPMS_INCLUDE__ -#endif /* __CHAPMS_INCLUDE__ */ diff --git a/src/netif/ppp/des.c b/src/netif/ppp/des.c deleted file mode 100644 index 123c1978..00000000 --- a/src/netif/ppp/des.c +++ /dev/null @@ -1,530 +0,0 @@ -/* $OpenBSD: crypt.c,v 1.20 2005/08/08 08:05:33 espie Exp $ */ - -/* - * FreeSec: libcrypt - * - * Copyright (c) 1994 David Burren - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the author nor the names of other contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - * This is an original implementation of the DES and the crypt(3) interfaces - * by David Burren . - * - * An excellent reference on the underlying algorithm (and related - * algorithms) is: - * - * B. Schneier, Applied Cryptography: protocols, algorithms, - * and source code in C, John Wiley & Sons, 1994. - * - * Note that in that book's description of DES the lookups for the initial, - * pbox, and final permutations are inverted (this has been brought to the - * attention of the author). A list of errata for this book has been - * posted to the sci.crypt newsgroup by the author and is available for FTP. - */ - -#include "lwip/opt.h" -/* FIXME: don't build if not necessary */ - -#include "lwip/def.h" - -static const u_char IP[64] = { - 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 -}; - -static u_char inv_key_perm[64]; -static u_char u_key_perm[56]; -static u_char const key_perm[56] = { - 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 -}; - -static const u_char key_shifts[16] = { - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 -}; - -static u_char inv_comp_perm[56]; -static const u_char comp_perm[48] = { - 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 -}; - -/* - * No E box is used, as it's replaced by some ANDs, shifts, and ORs. - */ - -static u_char u_sbox[8][64]; -static const u_char sbox[8][64] = { - { - 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 - }, - { - 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 - }, - { - 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 - }, - { - 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 - }, - { - 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 - }, - { - 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 - }, - { - 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 - }, - { - 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 - } -}; - -static u_char un_pbox[32]; -static const u_char pbox[32] = { - 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, - 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 -}; - -const u_int32_t _des_bits32[32] = -{ - 0x80000000, 0x40000000, 0x20000000, 0x10000000, - 0x08000000, 0x04000000, 0x02000000, 0x01000000, - 0x00800000, 0x00400000, 0x00200000, 0x00100000, - 0x00080000, 0x00040000, 0x00020000, 0x00010000, - 0x00008000, 0x00004000, 0x00002000, 0x00001000, - 0x00000800, 0x00000400, 0x00000200, 0x00000100, - 0x00000080, 0x00000040, 0x00000020, 0x00000010, - 0x00000008, 0x00000004, 0x00000002, 0x00000001 -}; - -const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; - -static const u_int32_t *bits28, *bits24; -static u_char init_perm[64], final_perm[64]; -static u_int32_t en_keysl[16], en_keysr[16]; -static u_int32_t de_keysl[16], de_keysr[16]; -int _des_initialised = 0; -static u_char m_sbox[4][4096]; -static u_int32_t psbox[4][256]; -static u_int32_t ip_maskl[8][256], ip_maskr[8][256]; -static u_int32_t fp_maskl[8][256], fp_maskr[8][256]; -static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; -static u_int32_t comp_maskl[8][128], comp_maskr[8][128]; -static u_int32_t old_rawkey0, old_rawkey1; - -void -_des_init(void) -{ - int i, j, b, k, inbit, obit; - u_int32_t *p, *il, *ir, *fl, *fr; - - old_rawkey0 = old_rawkey1 = 0; - bits24 = (bits28 = _des_bits32 + 4) + 4; - - /* - * Invert the S-boxes, reordering the input bits. - */ - for (i = 0; i < 8; i++) - for (j = 0; j < 64; j++) { - b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); - u_sbox[i][j] = sbox[i][b]; - } - - /* - * Convert the inverted S-boxes into 4 arrays of 8 bits. - * Each will handle 12 bits of the S-box input. - */ - for (b = 0; b < 4; b++) - for (i = 0; i < 64; i++) - for (j = 0; j < 64; j++) - m_sbox[b][(i << 6) | j] = - (u_sbox[(b << 1)][i] << 4) | - u_sbox[(b << 1) + 1][j]; - - /* - * Set up the initial & final permutations into a useful form, and - * initialise the inverted key permutation. - */ - for (i = 0; i < 64; i++) { - init_perm[final_perm[i] = IP[i] - 1] = i; - inv_key_perm[i] = 255; - } - - /* - * Invert the key permutation and initialise the inverted key - * compression permutation. - */ - for (i = 0; i < 56; i++) { - u_key_perm[i] = key_perm[i] - 1; - inv_key_perm[key_perm[i] - 1] = i; - inv_comp_perm[i] = 255; - } - - /* - * Invert the key compression permutation. - */ - for (i = 0; i < 48; i++) { - inv_comp_perm[comp_perm[i] - 1] = i; - } - - /* - * Set up the OR-mask arrays for the initial and final permutations, - * and for the key initial and compression permutations. - */ - for (k = 0; k < 8; k++) { - for (i = 0; i < 256; i++) { - *(il = &ip_maskl[k][i]) = 0; - *(ir = &ip_maskr[k][i]) = 0; - *(fl = &fp_maskl[k][i]) = 0; - *(fr = &fp_maskr[k][i]) = 0; - for (j = 0; j < 8; j++) { - inbit = 8 * k + j; - if (i & _des_bits8[j]) { - if ((obit = init_perm[inbit]) < 32) - *il |= _des_bits32[obit]; - else - *ir |= _des_bits32[obit-32]; - if ((obit = final_perm[inbit]) < 32) - *fl |= _des_bits32[obit]; - else - *fr |= _des_bits32[obit - 32]; - } - } - } - for (i = 0; i < 128; i++) { - *(il = &key_perm_maskl[k][i]) = 0; - *(ir = &key_perm_maskr[k][i]) = 0; - for (j = 0; j < 7; j++) { - inbit = 8 * k + j; - if (i & _des_bits8[j + 1]) { - if ((obit = inv_key_perm[inbit]) == 255) - continue; - if (obit < 28) - *il |= bits28[obit]; - else - *ir |= bits28[obit - 28]; - } - } - *(il = &comp_maskl[k][i]) = 0; - *(ir = &comp_maskr[k][i]) = 0; - for (j = 0; j < 7; j++) { - inbit = 7 * k + j; - if (i & _des_bits8[j + 1]) { - if ((obit=inv_comp_perm[inbit]) == 255) - continue; - if (obit < 24) - *il |= bits24[obit]; - else - *ir |= bits24[obit - 24]; - } - } - } - } - - /* - * Invert the P-box permutation, and convert into OR-masks for - * handling the output of the S-box arrays setup above. - */ - for (i = 0; i < 32; i++) - un_pbox[pbox[i] - 1] = i; - - for (b = 0; b < 4; b++) - for (i = 0; i < 256; i++) { - *(p = &psbox[b][i]) = 0; - for (j = 0; j < 8; j++) { - if (i & _des_bits8[j]) - *p |= _des_bits32[un_pbox[8 * b + j]]; - } - } - - _des_initialised = 1; -} - -int -des_setkey(const char *key) -{ - u_int32_t k0, k1, rawkey0, rawkey1; - int shifts, round; - - if (!_des_initialised) - _des_init(); - - rawkey0 = ntohl(*(u_int32_t *) key); - rawkey1 = ntohl(*(u_int32_t *) (key + 4)); - - if ((rawkey0 | rawkey1) - && rawkey0 == old_rawkey0 - && rawkey1 == old_rawkey1) { - /* - * Already setup for this key. - * This optimisation fails on a zero key (which is weak and - * has bad parity anyway) in order to simplify the starting - * conditions. - */ - return(0); - } - old_rawkey0 = rawkey0; - old_rawkey1 = rawkey1; - - /* - * Do key permutation and split into two 28-bit subkeys. - */ - k0 = key_perm_maskl[0][rawkey0 >> 25] - | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] - | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] - | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] - | key_perm_maskl[4][rawkey1 >> 25] - | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] - | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] - | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; - k1 = key_perm_maskr[0][rawkey0 >> 25] - | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] - | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] - | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] - | key_perm_maskr[4][rawkey1 >> 25] - | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] - | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] - | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; - /* - * Rotate subkeys and do compression permutation. - */ - shifts = 0; - for (round = 0; round < 16; round++) { - u_int32_t t0, t1; - - shifts += key_shifts[round]; - - t0 = (k0 << shifts) | (k0 >> (28 - shifts)); - t1 = (k1 << shifts) | (k1 >> (28 - shifts)); - - de_keysl[15 - round] = - en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] - | comp_maskl[1][(t0 >> 14) & 0x7f] - | comp_maskl[2][(t0 >> 7) & 0x7f] - | comp_maskl[3][t0 & 0x7f] - | comp_maskl[4][(t1 >> 21) & 0x7f] - | comp_maskl[5][(t1 >> 14) & 0x7f] - | comp_maskl[6][(t1 >> 7) & 0x7f] - | comp_maskl[7][t1 & 0x7f]; - - de_keysr[15 - round] = - en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f] - | comp_maskr[1][(t0 >> 14) & 0x7f] - | comp_maskr[2][(t0 >> 7) & 0x7f] - | comp_maskr[3][t0 & 0x7f] - | comp_maskr[4][(t1 >> 21) & 0x7f] - | comp_maskr[5][(t1 >> 14) & 0x7f] - | comp_maskr[6][(t1 >> 7) & 0x7f] - | comp_maskr[7][t1 & 0x7f]; - } - return(0); -} - -int -_des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, - int count) -{ - /* - * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. - */ - u_int32_t l, r, *kl, *kr, *kl1, *kr1; - u_int32_t f, r48l, r48r; - int round; - - if (count == 0) { - return(1); - } else if (count > 0) { - /* - * Encrypting - */ - kl1 = en_keysl; - kr1 = en_keysr; - } else { - /* - * Decrypting - */ - count = -count; - kl1 = de_keysl; - kr1 = de_keysr; - } - - /* - * Do initial permutation (IP). - */ - l = ip_maskl[0][l_in >> 24] - | ip_maskl[1][(l_in >> 16) & 0xff] - | ip_maskl[2][(l_in >> 8) & 0xff] - | ip_maskl[3][l_in & 0xff] - | ip_maskl[4][r_in >> 24] - | ip_maskl[5][(r_in >> 16) & 0xff] - | ip_maskl[6][(r_in >> 8) & 0xff] - | ip_maskl[7][r_in & 0xff]; - r = ip_maskr[0][l_in >> 24] - | ip_maskr[1][(l_in >> 16) & 0xff] - | ip_maskr[2][(l_in >> 8) & 0xff] - | ip_maskr[3][l_in & 0xff] - | ip_maskr[4][r_in >> 24] - | ip_maskr[5][(r_in >> 16) & 0xff] - | ip_maskr[6][(r_in >> 8) & 0xff] - | ip_maskr[7][r_in & 0xff]; - - while (count--) { - /* - * Do each round. - */ - kl = kl1; - kr = kr1; - round = 16; - while (round--) { - /* - * Expand R to 48 bits (simulate the E-box). - */ - r48l = ((r & 0x00000001) << 23) - | ((r & 0xf8000000) >> 9) - | ((r & 0x1f800000) >> 11) - | ((r & 0x01f80000) >> 13) - | ((r & 0x001f8000) >> 15); - - r48r = ((r & 0x0001f800) << 7) - | ((r & 0x00001f80) << 5) - | ((r & 0x000001f8) << 3) - | ((r & 0x0000001f) << 1) - | ((r & 0x80000000) >> 31); - /* - * Do XOR with the permuted key. - */ - r48l ^= *kl++; - r48r ^= *kr++; - /* - * Do sbox lookups (which shrink it back to 32 bits) - * and do the pbox permutation at the same time. - */ - f = psbox[0][m_sbox[0][r48l >> 12]] - | psbox[1][m_sbox[1][r48l & 0xfff]] - | psbox[2][m_sbox[2][r48r >> 12]] - | psbox[3][m_sbox[3][r48r & 0xfff]]; - /* - * Now that we've permuted things, complete f(). - */ - f ^= l; - l = r; - r = f; - } - r = l; - l = f; - } - /* - * Do final permutation (inverse of IP). - */ - *l_out = fp_maskl[0][l >> 24] - | fp_maskl[1][(l >> 16) & 0xff] - | fp_maskl[2][(l >> 8) & 0xff] - | fp_maskl[3][l & 0xff] - | fp_maskl[4][r >> 24] - | fp_maskl[5][(r >> 16) & 0xff] - | fp_maskl[6][(r >> 8) & 0xff] - | fp_maskl[7][r & 0xff]; - *r_out = fp_maskr[0][l >> 24] - | fp_maskr[1][(l >> 16) & 0xff] - | fp_maskr[2][(l >> 8) & 0xff] - | fp_maskr[3][l & 0xff] - | fp_maskr[4][r >> 24] - | fp_maskr[5][(r >> 16) & 0xff] - | fp_maskr[6][(r >> 8) & 0xff] - | fp_maskr[7][r & 0xff]; - return(0); -} - -int setkey(const char *key) { - int i, j; - u_int32_t packed_keys[2]; - u_char *p; - - p = (u_char *) packed_keys; - - for (i = 0; i < 8; i++) { - p[i] = 0; - for (j = 0; j < 8; j++) - if (*key++ & 1) - p[i] |= _des_bits8[j]; - } - return(des_setkey((char *)p)); -} - -int encrypt(char *block, int flag) { - u_int32_t io[2]; - u_char *p; - int i, j, retval; - - if (!_des_initialised) - _des_init(); - - p = (u_char *)block; - for (i = 0; i < 2; i++) { - io[i] = 0L; - for (j = 0; j < 32; j++) - if (*p++ & 1) - io[i] |= _des_bits32[j]; - } - retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1); - for (i = 0; i < 2; i++) - for (j = 0; j < 32; j++) - block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0; - return(retval); -} diff --git a/src/netif/ppp/des.h b/src/netif/ppp/des.h deleted file mode 100644 index 9ae70f6a..00000000 --- a/src/netif/ppp/des.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file - * - * DES header - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef DES_H_ -#define DES_H_ - -int setkey(const char *key); -int encrypt(char *block, int flag); - -#endif /* DES_H_ */ diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c deleted file mode 100644 index 8f6bc502..00000000 --- a/src/netif/ppp/ecp.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * ecp.c - PPP Encryption Control Protocol. - * - * Copyright (c) 2002 Google, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Derived from ccp.c, which is: - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "lwip/opt.h" - -#define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $" - -static const char rcsid[] = RCSID; - -#include - -#include "pppd.h" -#include "fsm.h" -#include "ecp.h" - -static option_t ecp_option_list[] = { - { "noecp", o_bool, &ecp_protent.enabled_flag, - "Disable ECP negotiation" }, - { "-ecp", o_bool, &ecp_protent.enabled_flag, - "Disable ECP negotiation", OPT_ALIAS }, - - { NULL } -}; - -/* - * Protocol entry points from main code. - */ -static void ecp_init __P((int unit)); -/* -static void ecp_open __P((int unit)); -static void ecp_close __P((int unit, char *)); -static void ecp_lowerup __P((int unit)); -static void ecp_lowerdown __P((int)); -static void ecp_input __P((int unit, u_char *pkt, int len)); -static void ecp_protrej __P((int unit)); -*/ -static int ecp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); -/* -static void ecp_datainput __P((int unit, u_char *pkt, int len)); -*/ - -struct protent ecp_protent = { - PPP_ECP, - ecp_init, - NULL, /* ecp_input, */ - NULL, /* ecp_protrej, */ - NULL, /* ecp_lowerup, */ - NULL, /* ecp_lowerdown, */ - NULL, /* ecp_open, */ - NULL, /* ecp_close, */ - ecp_printpkt, - NULL, /* ecp_datainput, */ - 0, - "ECP", - "Encrypted", - ecp_option_list, - NULL, - NULL, - NULL -}; - -fsm ecp_fsm[NUM_PPP]; -ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */ -ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ -ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */ -ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */ - -static fsm_callbacks ecp_callbacks = { - NULL, /* ecp_resetci, */ - NULL, /* ecp_cilen, */ - NULL, /* ecp_addci, */ - NULL, /* ecp_ackci, */ - NULL, /* ecp_nakci, */ - NULL, /* ecp_rejci, */ - NULL, /* ecp_reqci, */ - NULL, /* ecp_up, */ - NULL, /* ecp_down, */ - NULL, - NULL, - NULL, - NULL, - NULL, /* ecp_extcode, */ - "ECP" -}; - -/* - * ecp_init - initialize ECP. - */ -static void -ecp_init(unit) - int unit; -{ - fsm *f = &ecp_fsm[unit]; - - f->unit = unit; - f->protocol = PPP_ECP; - f->callbacks = &ecp_callbacks; - fsm_init(f); - - memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options)); - -} - - -static int -ecp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - return 0; -} - diff --git a/src/netif/ppp/ecp.h b/src/netif/ppp/ecp.h deleted file mode 100644 index df6e3ca1..00000000 --- a/src/netif/ppp/ecp.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ecp.h - Definitions for PPP Encryption Control Protocol. - * - * Copyright (c) 2002 Google, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ - */ - -typedef struct ecp_options { - bool required; /* Is ECP required? */ - unsigned enctype; /* Encryption type */ -} ecp_options; - -extern fsm ecp_fsm[]; -extern ecp_options ecp_wantoptions[]; -extern ecp_options ecp_gotoptions[]; -extern ecp_options ecp_allowoptions[]; -extern ecp_options ecp_hisoptions[]; - -extern struct protent ecp_protent; diff --git a/src/netif/ppp/md4.c b/src/netif/ppp/md4.c deleted file mode 100644 index f0831a92..00000000 --- a/src/netif/ppp/md4.c +++ /dev/null @@ -1,301 +0,0 @@ -/* -** ******************************************************************** -** md4.c -- Implementation of MD4 Message Digest Algorithm ** -** Updated: 2/16/90 by Ronald L. Rivest ** -** (C) 1990 RSA Data Security, Inc. ** -** ******************************************************************** -*/ - -#include "lwip/opt.h" - -/* -** To use MD4: -** -- Include md4.h in your program -** -- Declare an MDstruct MD to hold the state of the digest -** computation. -** -- Initialize MD using MDbegin(&MD) -** -- For each full block (64 bytes) X you wish to process, call -** MD4Update(&MD,X,512) -** (512 is the number of bits in a full block.) -** -- For the last block (less than 64 bytes) you wish to process, -** MD4Update(&MD,X,n) -** where n is the number of bits in the partial block. A partial -** block terminates the computation, so every MD computation -** should terminate by processing a partial block, even if it -** has n = 0. -** -- The message digest is available in MD.buffer[0] ... -** MD.buffer[3]. (Least-significant byte of each word -** should be output first.) -** -- You can print out the digest using MDprint(&MD) -*/ - -/* Implementation notes: -** This implementation assumes that ints are 32-bit quantities. -*/ - -#define TRUE 1 -#define FALSE 0 - -/* Compile-time includes -*/ -#include -#include "md4.h" -#include "pppd.h" - -/* Compile-time declarations of MD4 "magic constants". -*/ -#define I0 0x67452301 /* Initial values for MD buffer */ -#define I1 0xefcdab89 -#define I2 0x98badcfe -#define I3 0x10325476 -#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ -#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ -/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 -** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. -** Table 2, page 660. -*/ - -#define fs1 3 /* round 1 shift amounts */ -#define fs2 7 -#define fs3 11 -#define fs4 19 -#define gs1 3 /* round 2 shift amounts */ -#define gs2 5 -#define gs3 9 -#define gs4 13 -#define hs1 3 /* round 3 shift amounts */ -#define hs2 9 -#define hs3 11 -#define hs4 15 - -/* Compile-time macro declarations for MD4. -** Note: The "rot" operator uses the variable "tmp". -** It assumes tmp is declared as unsigned int, so that the >> -** operator will shift in zeros rather than extending the sign bit. -*/ -#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) -#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) -#define h(X,Y,Z) (X^Y^Z) -#define rot(X,S) (tmp=X,(tmp<>(32-S))) -#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) -#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) -#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) - -/* MD4print(MDp) -** Print message digest buffer MDp as 32 hexadecimal digits. -** Order is from low-order byte of buffer[0] to high-order byte of -** buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -** This is a user-callable routine. -*/ -void -MD4Print(MDp) -MD4_CTX *MDp; -{ - int i,j; - for (i=0;i<4;i++) - for (j=0;j<32;j=j+8) - printf("%02x",(MDp->buffer[i]>>j) & 0xFF); -} - -/* MD4Init(MDp) -** Initialize message digest buffer MDp. -** This is a user-callable routine. -*/ -void -MD4Init(MDp) -MD4_CTX *MDp; -{ - int i; - MDp->buffer[0] = I0; - MDp->buffer[1] = I1; - MDp->buffer[2] = I2; - MDp->buffer[3] = I3; - for (i=0;i<8;i++) MDp->count[i] = 0; - MDp->done = 0; -} - -/* MDblock(MDp,X) -** Update message digest buffer MDp->buffer using 16-word data block X. -** Assumes all 16 words of X are full of data. -** Does not update MDp->count. -** This routine is not user-callable. -*/ -static void -MDblock(MDp,Xb) -MD4_CTX *MDp; -unsigned char *Xb; -{ - register unsigned int tmp, A, B, C, D; - unsigned int X[16]; - int i; - - for (i = 0; i < 16; ++i) { - X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); - Xb += 4; - } - - A = MDp->buffer[0]; - B = MDp->buffer[1]; - C = MDp->buffer[2]; - D = MDp->buffer[3]; - /* Update the message digest buffer */ - ff(A , B , C , D , 0 , fs1); /* Round 1 */ - ff(D , A , B , C , 1 , fs2); - ff(C , D , A , B , 2 , fs3); - ff(B , C , D , A , 3 , fs4); - ff(A , B , C , D , 4 , fs1); - ff(D , A , B , C , 5 , fs2); - ff(C , D , A , B , 6 , fs3); - ff(B , C , D , A , 7 , fs4); - ff(A , B , C , D , 8 , fs1); - ff(D , A , B , C , 9 , fs2); - ff(C , D , A , B , 10 , fs3); - ff(B , C , D , A , 11 , fs4); - ff(A , B , C , D , 12 , fs1); - ff(D , A , B , C , 13 , fs2); - ff(C , D , A , B , 14 , fs3); - ff(B , C , D , A , 15 , fs4); - gg(A , B , C , D , 0 , gs1); /* Round 2 */ - gg(D , A , B , C , 4 , gs2); - gg(C , D , A , B , 8 , gs3); - gg(B , C , D , A , 12 , gs4); - gg(A , B , C , D , 1 , gs1); - gg(D , A , B , C , 5 , gs2); - gg(C , D , A , B , 9 , gs3); - gg(B , C , D , A , 13 , gs4); - gg(A , B , C , D , 2 , gs1); - gg(D , A , B , C , 6 , gs2); - gg(C , D , A , B , 10 , gs3); - gg(B , C , D , A , 14 , gs4); - gg(A , B , C , D , 3 , gs1); - gg(D , A , B , C , 7 , gs2); - gg(C , D , A , B , 11 , gs3); - gg(B , C , D , A , 15 , gs4); - hh(A , B , C , D , 0 , hs1); /* Round 3 */ - hh(D , A , B , C , 8 , hs2); - hh(C , D , A , B , 4 , hs3); - hh(B , C , D , A , 12 , hs4); - hh(A , B , C , D , 2 , hs1); - hh(D , A , B , C , 10 , hs2); - hh(C , D , A , B , 6 , hs3); - hh(B , C , D , A , 14 , hs4); - hh(A , B , C , D , 1 , hs1); - hh(D , A , B , C , 9 , hs2); - hh(C , D , A , B , 5 , hs3); - hh(B , C , D , A , 13 , hs4); - hh(A , B , C , D , 3 , hs1); - hh(D , A , B , C , 11 , hs2); - hh(C , D , A , B , 7 , hs3); - hh(B , C , D , A , 15 , hs4); - MDp->buffer[0] += A; - MDp->buffer[1] += B; - MDp->buffer[2] += C; - MDp->buffer[3] += D; -} - -/* MD4Update(MDp,X,count) -** Input: X -- a pointer to an array of unsigned characters. -** count -- the number of bits of X to use. -** (if not a multiple of 8, uses high bits of last byte.) -** Update MDp using the number of bits of X given by count. -** This is the basic input routine for an MD4 user. -** The routine completes the MD computation when count < 512, so -** every MD computation should end with one call to MD4Update with a -** count less than 512. A call with count 0 will be ignored if the -** MD has already been terminated (done != 0), so an extra call with -** count 0 can be given as a "courtesy close" to force termination -** if desired. -*/ -void -MD4Update(MDp,X,count) -MD4_CTX *MDp; -unsigned char *X; -unsigned int count; -{ - unsigned int i, tmp, bit, byte, mask; - unsigned char XX[64]; - unsigned char *p; - - /* return with no error if this is a courtesy close with count - ** zero and MDp->done is true. - */ - if (count == 0 && MDp->done) return; - /* check to see if MD is already done and report error */ - if (MDp->done) - { printf("\nError: MD4Update MD already done."); return; } - - /* Add count to MDp->count */ - tmp = count; - p = MDp->count; - while (tmp) - { tmp += *p; - *p++ = tmp; - tmp = tmp >> 8; - } - - /* Process data */ - if (count == 512) - { /* Full block of data to handle */ - MDblock(MDp,X); - } - else if (count > 512) /* Check for count too large */ - { - printf("\nError: MD4Update called with illegal count value %d.", - count); - return; - } - else /* partial block -- must be last block so finish up */ - { - /* Find out how many bytes and residual bits there are */ - byte = count >> 3; - bit = count & 7; - /* Copy X into XX since we need to modify it */ - if (count) - for (i=0;i<=byte;i++) XX[i] = X[i]; - for (i=byte+1;i<64;i++) XX[i] = 0; - /* Add padding '1' bit and low-order zeros in last byte */ - mask = 1 << (7 - bit); - XX[byte] = (XX[byte] | mask) & ~( mask - 1); - /* If room for bit count, finish up with this block */ - if (byte <= 55) - { - for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; - MDblock(MDp,XX); - } - else /* need to do two blocks to finish up */ - { - MDblock(MDp,XX); - for (i=0;i<56;i++) XX[i] = 0; - for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; - MDblock(MDp,XX); - } - /* Set flag saying we're done with MD computation */ - MDp->done = 1; - } -} - -/* -** Finish up MD4 computation and return message digest. -*/ -void -MD4Final(buf, MD) -unsigned char *buf; -MD4_CTX *MD; -{ - int i, j; - unsigned int w; - - MD4Update(MD, NULL, 0); - for (i = 0; i < 4; ++i) { - w = MD->buffer[i]; - for (j = 0; j < 4; ++j) { - *buf++ = w; - w >>= 8; - } - } -} - -/* -** End of md4.c -****************************(cut)***********************************/ diff --git a/src/netif/ppp/md4.h b/src/netif/ppp/md4.h deleted file mode 100644 index 80e8f9a2..00000000 --- a/src/netif/ppp/md4.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* -** ******************************************************************** -** md4.h -- Header file for implementation of ** -** MD4 Message Digest Algorithm ** -** Updated: 2/13/90 by Ronald L. Rivest ** -** (C) 1990 RSA Data Security, Inc. ** -** ******************************************************************** -*/ - -#ifndef __P -# if defined(__STDC__) || defined(__GNUC__) -# define __P(x) x -# else -# define __P(x) () -# endif -#endif - - -/* MDstruct is the data structure for a message digest computation. -*/ -typedef struct { - unsigned int buffer[4]; /* Holds 4-word result of MD computation */ - unsigned char count[8]; /* Number of bits processed so far */ - unsigned int done; /* Nonzero means MD computation finished */ -} MD4_CTX; - -/* MD4Init(MD4_CTX *) -** Initialize the MD4_CTX prepatory to doing a message digest -** computation. -*/ -extern void MD4Init __P((MD4_CTX *MD)); - -/* MD4Update(MD,X,count) -** Input: X -- a pointer to an array of unsigned characters. -** count -- the number of bits of X to use (an unsigned int). -** Updates MD using the first "count" bits of X. -** The array pointed to by X is not modified. -** If count is not a multiple of 8, MD4Update uses high bits of -** last byte. -** This is the basic input routine for a user. -** The routine terminates the MD computation when count < 512, so -** every MD computation should end with one call to MD4Update with a -** count less than 512. Zero is OK for a count. -*/ -extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); - -/* MD4Print(MD) -** Prints message digest buffer MD as 32 hexadecimal digits. -** Order is from low-order byte of buffer[0] to high-order byte -** of buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -*/ -extern void MD4Print __P((MD4_CTX *)); - -/* MD4Final(buf, MD) -** Returns message digest from MD and terminates the message -** digest computation. -*/ -extern void MD4Final __P((unsigned char *, MD4_CTX *)); - -/* -** End of md4.h -****************************(cut)***********************************/ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index eb212a36..826771e0 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -105,14 +105,8 @@ #include "upap.h" #include "chap-new.h" #include "eap.h" -#include "ccp.h" -#include "ecp.h" #include "pathnames.h" -#if CBCP_SUPPORT -#include "cbcp.h" -#endif - #ifdef AT_CHANGE #include "atcp.h" #endif @@ -165,7 +159,6 @@ int fd_ppp = -1; /* fd for talking PPP */ int phase; /* where the link is at */ int kill_link; int asked_to_quit; -int open_ccp_flag; int listen_time; int got_sigusr2; int got_sigterm; @@ -232,7 +225,6 @@ static void hup __P((int)); static void term __P((int)); static void chld __P((int)); static void toggle_debug __P((int)); -static void open_ccp __P((int)); static void bad_signal __P((int)); static void holdoff_end __P((void *)); static void forget_child __P((int pid, int status)); @@ -271,8 +263,6 @@ struct protent *protocols[] = { #ifdef INET6 &ipv6cp_protent, #endif - &ccp_protent, - &ecp_protent, #ifdef AT_CHANGE &atcp_protent, #endif @@ -513,12 +503,6 @@ int ppp_oldmain() { if (phase == PHASE_MASTER) mp_bundle_terminated(); } - if (open_ccp_flag) { - if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { - ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ - (*ccp_protent.open)(0); - } - } } /* restore FSMs to original state */ lcp_close(0, ""); @@ -574,7 +558,7 @@ handle_events() { struct timeval timo; - kill_link = open_ccp_flag = 0; + kill_link = 0; if (sigsetjmp(sigjmp, 1) == 0) { sigprocmask(SIG_BLOCK, &signals_handled, NULL); if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) { @@ -606,10 +590,6 @@ handle_events() got_sigchld = 0; reap_kids(); /* Don't leave dead kids lying around */ } - if (got_sigusr2) { - open_ccp_flag = 1; - got_sigusr2 = 0; - } } /* @@ -646,7 +626,6 @@ setup_signals() SIGNAL(SIGCHLD, chld); SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ - SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ /* * Install a handler for other signals which would otherwise @@ -1455,23 +1434,6 @@ toggle_debug(sig) } } - -/* - * open_ccp - Catch SIGUSR2 signal. - * - * Try to (re)negotiate compression. - */ -/*ARGSUSED*/ -static void -open_ccp(sig) - int sig; -{ - got_sigusr2 = 1; - if (waiting) - siglongjmp(sigjmp, 1); -} - - /* * bad_signal - We've caught a fatal signal. Clean up state and exit. */ diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c deleted file mode 100644 index d4c48429..00000000 --- a/src/netif/ppp/pppcrypt.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 - * - * Extracted from chap_ms.c by James Carlson. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "lwip/opt.h" - -#include "pppd.h" -#include "pppcrypt.h" -#include "des.h" - -static u_char -Get7Bits(input, startBit) -u_char *input; -int startBit; -{ - unsigned int word; - - word = (unsigned)input[startBit / 8] << 8; - word |= (unsigned)input[startBit / 8 + 1]; - - word >>= 15 - (startBit % 8 + 7); - - return word & 0xFE; -} - -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); -} - -/* - * 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; - } -} - -bool -DesSetkey(key) -u_char *key; -{ - u_char des_key[8]; - u_char crypt_key[66]; - - MakeKey(key, des_key); - Expand(des_key, crypt_key); - setkey((const char *)crypt_key); - return (1); -} - -bool -DesEncrypt(clear, cipher) -u_char *clear; /* IN 8 octets */ -u_char *cipher; /* OUT 8 octets */ -{ - u_char des_input[66]; - - Expand(clear, des_input); - encrypt((char *)des_input, 0); - Collapse(des_input, cipher); - return (1); -} - -bool -DesDecrypt(cipher, clear) -u_char *cipher; /* IN 8 octets */ -u_char *clear; /* OUT 8 octets */ -{ - u_char des_input[66]; - - Expand(cipher, des_input); - encrypt((char *)des_input, 1); - Collapse(des_input, clear); - return (1); -} diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h deleted file mode 100644 index d5deccd0..00000000 --- a/src/netif/ppp/pppcrypt.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 - * - * Extracted from chap_ms.c by James Carlson. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef PPPCRYPT_H -#define PPPCRYPT_H - -extern bool DesSetkey __P((u_char *)); -extern bool DesEncrypt __P((u_char *, u_char *)); -extern bool DesDecrypt __P((u_char *, u_char *)); - -#endif /* PPPCRYPT_H */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index add22efe..ec36cc1b 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -529,7 +529,6 @@ void link_down __P((int)); /* the LCP layer has left the Opened state */ void upper_layers_down __P((int));/* take all NCPs down */ void link_established __P((int)); /* the link is up; authenticate now */ void start_networks __P((int)); /* start all the network control protos */ -void continue_networks __P((int)); /* start network [ip, etc] control protos */ void np_up __P((int, int)); /* a network protocol has come up */ void np_down __P((int, int)); /* a network protocol has gone down */ void np_finished __P((int, int)); /* a network protocol no longer needs link */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 3352b2ba..30a49fe3 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -436,9 +436,7 @@ void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { ppp_settings.refuse_pap = 1; - ppp_settings.refuse_chap = 1; - ppp_settings.refuse_mschap = 1; - ppp_settings.refuse_mschap_v2 = 0; + ppp_settings.refuse_chap = 0; ppp_settings.refuse_eap = 1; /* FIXME: re-enable that */ diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 07099ecd..4084414b 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -46,8 +46,6 @@ struct ppp_settings { u_int explicit_remote : 1; /* remote_name specified with remotename opt */ u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ - u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ - u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ u_int usehostname : 1; /* Use hostname for our_name */ u_int usepeerdns : 1; /* Ask peer for DNS adds */ diff --git a/src/netif/ppp/sha1.c b/src/netif/ppp/sha1.c deleted file mode 100644 index 3b020b8f..00000000 --- a/src/netif/ppp/sha1.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c - * - * SHA-1 in C - * By Steve Reid - * 100% Public Domain - * - * Test Vectors (from FIPS PUB 180-1) - * "abc" - * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D - * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 - * A million repetitions of "a" - * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F - */ - -#include "lwip/opt.h" - -/* #define SHA1HANDSOFF * Copies data before messing with it. */ - -#include -#include /* htonl() */ -#include -#include "sha1.h" - -static void -SHA1_Transform(u_int32_t[5], const unsigned char[64]); - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -/* I got the idea of expanding during the round function from SSLeay */ -#define blk0(i) (block->l[i] = htonl(block->l[i])) -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -static void -SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64]) -{ - u_int32_t a, b, c, d, e; - typedef union { - unsigned char c[64]; - u_int32_t l[16]; - } CHAR64LONG16; - CHAR64LONG16 *block; - -#ifdef SHA1HANDSOFF - static unsigned char workspace[64]; - block = (CHAR64LONG16 *) workspace; - memcpy(block, buffer, 64); -#else - block = (CHAR64LONG16 *) buffer; -#endif - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Wipe variables */ - a = b = c = d = e = 0; -} - - -/* SHA1Init - Initialize new context */ - -void -SHA1_Init(SHA1_CTX *context) -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - - -/* Run your data through this. */ - -void -SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) -{ - unsigned int i, j; - - j = (context->count[0] >> 3) & 63; - if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; - context->count[1] += (len >> 29); - i = 64 - j; - while (len >= i) { - memcpy(&context->buffer[j], data, i); - SHA1_Transform(context->state, context->buffer); - data += i; - len -= i; - i = 64; - j = 0; - } - - memcpy(&context->buffer[j], data, len); -} - - -/* Add padding and return the message digest. */ - -void -SHA1_Final(unsigned char digest[20], SHA1_CTX *context) -{ - u_int32_t i, j; - unsigned char finalcount[8]; - - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ - } - SHA1_Update(context, (unsigned char *) "\200", 1); - while ((context->count[0] & 504) != 448) { - SHA1_Update(context, (unsigned char *) "\0", 1); - } - SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - /* Wipe variables */ - i = j = 0; - memset(context->buffer, 0, 64); - memset(context->state, 0, 20); - memset(context->count, 0, 8); - memset(&finalcount, 0, 8); -#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ - SHA1Transform(context->state, context->buffer); -#endif -} - diff --git a/src/netif/ppp/sha1.h b/src/netif/ppp/sha1.h deleted file mode 100644 index 83f64df2..00000000 --- a/src/netif/ppp/sha1.h +++ /dev/null @@ -1,31 +0,0 @@ -/* sha1.h */ - -/* If OpenSSL is in use, then use that version of SHA-1 */ -#ifdef OPENSSL -#include -#define __SHA1_INCLUDE_ -#endif - -#ifndef __SHA1_INCLUDE_ - -#ifndef SHA1_SIGNATURE_SIZE -#ifdef SHA_DIGESTSIZE -#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE -#else -#define SHA1_SIGNATURE_SIZE 20 -#endif -#endif - -typedef struct { - u_int32_t state[5]; - u_int32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -extern void SHA1_Init(SHA1_CTX *); -extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int); -extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *); - -#define __SHA1_INCLUDE_ -#endif /* __SHA1_INCLUDE_ */ - From 7d43f4a1f4555f81297bd5120624681af520bafb Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 00:03:18 +0200 Subject: [PATCH 031/320] removed useless system header from EAP --- src/netif/ppp/eap.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index b082284a..c5f5844d 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -51,17 +51,6 @@ * TODO: */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "pppd.h" #include "pathnames.h" #include "md5.h" @@ -1121,7 +1110,7 @@ int lenstr; int msglen; outp = outpacket_buf; - + MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); @@ -1152,7 +1141,7 @@ u_char *str; int msglen; outp = outpacket_buf; - + MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); From 795d5807b5f7a4031b5b54184d83d4d413e21d4d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 01:18:36 +0200 Subject: [PATCH 032/320] EAP support is now optional --- src/netif/ppp/auth.c | 60 ++++++++++++++++--- src/netif/ppp/eap.c | 10 +--- src/netif/ppp/eap.h | 4 ++ src/netif/ppp/lcp.c | 135 +++++++++++++++++++++++++++++++++++------- src/netif/ppp/lcp.h | 2 + src/netif/ppp/ppp.c | 4 ++ src/netif/ppp/pppmy.c | 6 +- src/netif/ppp/pppmy.h | 2 + 8 files changed, 185 insertions(+), 38 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 020d53ce..17756f11 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -109,7 +109,9 @@ #include "ipcp.h" #include "upap.h" #include "chap-new.h" +#if EAP_SUPPORT #include "eap.h" +#endif /* EAP_SUPPORT */ #include "pathnames.h" #include "session.h" @@ -329,7 +331,7 @@ option_t auth_options[] = { &lcp_allowoptions[0].chap_mdtype }, #endif #endif - +#if EAP_SUPPORT { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, "Require EAP authentication from peer", OPT_PRIOSUB | 1, &auth_required }, @@ -337,6 +339,7 @@ option_t auth_options[] = { { "refuse-eap", o_bool, &refuse_eap, "Don't agree to authenticate to peer with EAP", 1 }, #endif +#endif /* EAP_SUPPORT */ { "name", o_string, our_name, "Set local name for authentication", OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, @@ -732,7 +735,11 @@ link_established(unit) if (!auth_required && noauth_addrs != NULL) set_allowed_addrs(unit, NULL, NULL); - if (auth_required && !(go->neg_upap || go->neg_chap || go->neg_eap)) { + if (auth_required && !(go->neg_upap || go->neg_chap +#if EAP_SUPPORT + || go->neg_eap +#endif /* EAP_SUPPORT */ + )) { /* * We wanted the peer to authenticate itself, and it refused: * if we have some address(es) it can use without auth, fine, @@ -752,20 +759,26 @@ link_established(unit) new_phase(PHASE_AUTHENTICATE); auth = 0; +#if EAP_SUPPORT if (go->neg_eap) { eap_authpeer(unit, our_name); auth |= EAP_PEER; - } else if (go->neg_chap) { + } else +#endif /* EAP_SUPPORT */ + if (go->neg_chap) { chap_auth_peer(unit, our_name, CHAP_DIGEST(go->chap_mdtype)); auth |= CHAP_PEER; } else if (go->neg_upap) { upap_authpeer(unit); auth |= PAP_PEER; } +#if EAP_SUPPORT if (ho->neg_eap) { eap_authwithpeer(unit, ppp_settings.user); auth |= EAP_WITHPEER; - } else if (ho->neg_chap) { + } else +#endif /* EAP_SUPPORT */ + if (ho->neg_chap) { chap_auth_with_peer(unit, ppp_settings.user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else if (ho->neg_upap) { @@ -795,7 +808,11 @@ network_phase(unit) /* * If the peer had to authenticate, run the auth-up script now. */ - if (go->neg_chap || go->neg_upap || go->neg_eap) { + if (go->neg_chap || go->neg_upap +#if EAP_SUPPORT + || go->neg_eap +#endif /* EAP_SUPPORT */ + ) { notify(auth_up_notifier, 0); } @@ -1179,17 +1196,25 @@ auth_check_options() /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ if (auth_required) { allow_any_ip = 0; - if (!wo->neg_chap && !wo->neg_upap && !wo->neg_eap) { + if (!wo->neg_chap && !wo->neg_upap +#if EAP_SUPPORT + && !wo->neg_eap +#endif /* EAP_SUPPORT */ + ) { wo->neg_chap = chap_mdtype_all != MDTYPE_NONE; wo->chap_mdtype = chap_mdtype_all; wo->neg_upap = 1; +#if EAP_SUPPORT wo->neg_eap = 1; +#endif /* EAP_SUPPORT */ } } else { wo->neg_chap = 0; wo->chap_mdtype = MDTYPE_NONE; wo->neg_upap = 0; +#if EAP_SUPPORT wo->neg_eap = 0; +#endif /* EAP_SUPPORT */ } /* @@ -1199,11 +1224,19 @@ auth_check_options() */ lacks_ip = 0; can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); - if (!can_auth && (wo->neg_chap || wo->neg_eap)) { + if (!can_auth && (wo->neg_chap +#if EAP_SUPPORT + || wo->neg_eap +#endif /* EAP_SUPPORT */ + )) { can_auth = have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, &lacks_ip); } - if (!can_auth && wo->neg_eap) { + if (!can_auth +#if EAP_SUPPORT + && wo->neg_eap +#endif /* EAP_SUPPORT */ + ) { can_auth = have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, &lacks_ip); } @@ -1255,7 +1288,9 @@ auth_reset(unit) ao->neg_upap = !ppp_settings.refuse_pap; +#if EAP_SUPPORT ao->neg_eap = !ppp_settings.refuse_eap; +#endif /* EAP_SUPPORT */ if(!ppp_settings.refuse_chap) { ao->chap_mdtype = MDTYPE_MD5; @@ -1265,7 +1300,9 @@ auth_reset(unit) } else { ao->neg_upap = 0; ao->neg_chap = 0; +#if EAP_SUPPORT ao->neg_eap = 0; +#endif /* EAP_SUPPORT */ ao->chap_mdtype = MDTYPE_NONE; } @@ -1274,7 +1311,9 @@ auth_reset(unit) printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); printf("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT) ); printf("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2) ); +#if EAP_SUPPORT printf("neg_eap: %d\n", ao->neg_eap); +#endif /* EAP_SUPPORT */ //ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); @@ -1292,10 +1331,12 @@ auth_reset(unit) go->neg_upap = 0; go->neg_chap = 0; +#if EAP_SUPPORT go->neg_eap = 0; +#endif /* EAP_SUPPORT */ go->chap_mdtype = MDTYPE_NONE; return; - +#if 0 /* FIXME: find what the below stuff do */ int hadchap; hadchap = -1; @@ -1317,6 +1358,7 @@ auth_reset(unit) !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL)) go->neg_eap = 0; +#endif } /* diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index c5f5844d..ecbcf046 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -44,12 +44,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" - -/* - * TODO: - */ +#if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include "pppd.h" #include "pathnames.h" @@ -67,8 +62,6 @@ #define SHA_DIGESTSIZE 20 #endif -static const char rcsid[] = RCSID; - eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */ #ifdef USE_SRP static char *pn_secret = NULL; /* Pseudonym generating secret */ @@ -2419,3 +2412,4 @@ void *arg; return (inp - pstart); } +#endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/src/netif/ppp/eap.h b/src/netif/ppp/eap.h index 199d1849..ea0147ec 100644 --- a/src/netif/ppp/eap.h +++ b/src/netif/ppp/eap.h @@ -20,6 +20,9 @@ * $Id: eap.h,v 1.2 2003/06/11 23:56:26 paulus Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + #ifndef PPP_EAP_H #define PPP_EAP_H @@ -156,3 +159,4 @@ extern struct protent eap_protent; #endif /* PPP_EAP_H */ +#endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 89250e01..7fff01a5 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -371,7 +371,9 @@ lcp_init(unit) ao->neg_chap = 1; ao->chap_mdtype = chap_mdtype_all; ao->neg_upap = 1; +#if EAP_SUPPORT ao->neg_eap = 1; +#endif /* EAP_SUPPORT */ ao->neg_magicnumber = 1; ao->neg_pcompression = 1; ao->neg_accompression = 1; @@ -696,9 +698,19 @@ lcp_cilen(f) */ return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) + LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + +#if EAP_SUPPORT LENCISHORT(go->neg_eap) + - LENCICHAP(!go->neg_eap && go->neg_chap) + - LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) + +#endif /* EAP_SUPPORT */ + LENCICHAP( +#if EAP_SUPPORT + !go->neg_eap && +#endif /* EAP_SUPPORT */ + go->neg_chap) + + LENCISHORT( +#if EAP_SUPPORT + !go->neg_eap && +#endif /* EAP_SUPPORT */ + !go->neg_chap && go->neg_upap) + LENCILQR(go->neg_lqr) + LENCICBCP(go->neg_cbcp) + LENCILONG(go->neg_magicnumber) + @@ -772,10 +784,19 @@ lcp_addci(f, ucp, lenp) ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, go->asyncmap); +#if EAP_SUPPORT ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); - ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); - ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, - PPP_PAP); +#endif /* EAP_SUPPORT */ + ADDCICHAP(CI_AUTHTYPE, +#if EAP_SUPPORT + !go->neg_eap && +#endif /* EAP_SUPPORT */ + go->neg_chap, go->chap_mdtype); + ADDCISHORT(CI_AUTHTYPE, +#if EAP_SUPPORT + !go->neg_eap && +#endif /* EAP_SUPPORT */ + !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); @@ -921,10 +942,19 @@ lcp_ackci(f, p, len) ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, go->asyncmap); +#if EAP_SUPPORT ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); - ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); - ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, - PPP_PAP); +#endif /* EAP_SUPPORT */ + ACKCICHAP(CI_AUTHTYPE, +#if EAP_SUPPORT + !go->neg_eap && +#endif /* EAP_SUPPORT */ + go->neg_chap, go->chap_mdtype); + ACKCISHORT(CI_AUTHTYPE, +#if EAP_SUPPORT + !go->neg_eap && +#endif /* EAP_SUPPORT */ + !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); @@ -1092,23 +1122,32 @@ lcp_nakci(f, p, len, treat_as_reject) * they are proposing a different protocol, or a different * hash algorithm for CHAP. */ - if ((go->neg_chap || go->neg_upap || go->neg_eap) + if ((go->neg_chap || go->neg_upap +#if EAP_SUPPORT + || go->neg_eap +#endif /* EAP_SUPPORT */ + ) && 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; +#if EAP_SUPPORT no.neg_eap = go->neg_eap; +#endif /* EAP_SUPPORT */ INCPTR(2, p); GETSHORT(cishort, p); if (cishort == PPP_PAP && cilen == CILEN_SHORT) { +#if EAP_SUPPORT /* If we were asking for EAP, then we need to stop that. */ if (go->neg_eap) try.neg_eap = 0; + else +#endif /* EAP_SUPPORT */ /* If we were asking for CHAP, then we need to stop that. */ - else if (go->neg_chap) + if (go->neg_chap) try.neg_chap = 0; /* * If we weren't asking for CHAP or EAP, then we were asking for @@ -1119,13 +1158,16 @@ lcp_nakci(f, p, len, treat_as_reject) } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { GETCHAR(cichar, p); +#if EAP_SUPPORT /* Stop asking for EAP, if we were. */ if (go->neg_eap) { try.neg_eap = 0; /* Try to set up to use their suggestion, if possible */ if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) try.chap_mdtype = CHAP_MDTYPE_D(cichar); - } else if (go->neg_chap) { + } else +#endif /* EAP_SUPPORT */ + if (go->neg_chap) { /* * We were asking for our preferred algorithm, they must * want something different. @@ -1156,6 +1198,7 @@ lcp_nakci(f, p, len, treat_as_reject) } else { +#if EAP_SUPPORT /* * If we were asking for EAP, and they're Conf-Naking EAP, * well, that's just strange. Nobody should do that. @@ -1169,7 +1212,9 @@ lcp_nakci(f, p, len, treat_as_reject) */ if (go->neg_eap) try.neg_eap = 0; - else if (go->neg_chap) + else +#endif /* EAP_SUPPORT */ + if (go->neg_chap) try.neg_chap = 0; else try.neg_upap = 0; @@ -1277,8 +1322,11 @@ lcp_nakci(f, p, len, treat_as_reject) goto bad; break; case CI_AUTHTYPE: - if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap || - go->neg_eap || no.neg_eap) + if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap +#if EAP_SUPPORT + || go->neg_eap || no.neg_eap +#endif /* EAP_SUPPORT */ + ) goto bad; break; case CI_MAGICNUMBER: @@ -1391,6 +1439,7 @@ lcp_rejci(f, p, len) goto bad; \ try.neg = 0; \ } +#if EAP_SUPPORT #define REJCICHAP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CHAP && \ @@ -1406,6 +1455,24 @@ lcp_rejci(f, p, len) try.neg = 0; \ try.neg_eap = try.neg_upap = 0; \ } +#endif /* EAP_SUPPORT */ +#if !EAP_SUPPORT +#define REJCICHAP(opt, neg, val) \ + 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 != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ + goto bad; \ + try.neg = 0; \ + try.neg_upap = 0; \ + } +#endif /* !EAP_SUPPORT */ #define REJCILONG(opt, neg, val) \ if (go->neg && \ len >= CILEN_LONG && \ @@ -1467,13 +1534,17 @@ lcp_rejci(f, p, len) REJCISHORT(CI_MRU, neg_mru, go->mru); REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); +#if EAP_SUPPORT REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP); if (!go->neg_eap) { +#endif /* EAP_SUPPORT */ REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype); if (!go->neg_chap) { REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); } +#if EAP_SUPPORT } +#endif /* EAP_SUPPORT */ REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); @@ -1609,7 +1680,11 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) case CI_AUTHTYPE: if (cilen < CILEN_SHORT || - !(ao->neg_upap || ao->neg_chap || ao->neg_eap)) { + !(ao->neg_upap || ao->neg_chap +#if EAP_SUPPORT + || ao->neg_eap +#endif /* EAP_SUPPORT */ + )) { /* * Reject the option if we're not willing to authenticate. */ @@ -1632,8 +1707,11 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) if (cishort == PPP_PAP) { /* we've already accepted CHAP or EAP */ - if (ho->neg_chap || ho->neg_eap || - cilen != CILEN_SHORT) { + if (ho->neg_chap +#if EAP_SUPPORT + || ho->neg_eap +#endif /* EAP_SUPPORT */ + || cilen != CILEN_SHORT) { LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); orc = CONFREJ; break; @@ -1641,14 +1719,18 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) if (!ao->neg_upap) { /* we don't want to do PAP */ orc = CONFNAK; /* NAK it and suggest CHAP or EAP */ PUTCHAR(CI_AUTHTYPE, nakp); +#if EAP_SUPPORT if (ao->neg_eap) { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_EAP, nakp); } else { +#endif /* EAP_SUPPORT */ PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); +#if EAP_SUPPORT } +#endif /* EAP_SUPPORT */ break; } ho->neg_upap = 1; @@ -1656,8 +1738,11 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) } if (cishort == PPP_CHAP) { /* we've already accepted PAP or EAP */ - if (ho->neg_upap || ho->neg_eap || - cilen != CILEN_CHAP) { + if (ho->neg_upap +#if EAP_SUPPORT + || ho->neg_eap +#endif /* EAP_SUPPORT */ + || cilen != CILEN_CHAP) { LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); orc = CONFREJ; break; @@ -1666,11 +1751,15 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) orc = CONFNAK; /* NAK it and suggest EAP or PAP */ PUTCHAR(CI_AUTHTYPE, nakp); PUTCHAR(CILEN_SHORT, nakp); +#if EAP_SUPPORT if (ao->neg_eap) { PUTSHORT(PPP_EAP, nakp); } else { +#endif /* EAP_SUPPORT */ PUTSHORT(PPP_PAP, nakp); +#if EAP_SUPPORT } +#endif /* EAP_SUPPORT */ break; } GETCHAR(cichar, p); /* get digest type */ @@ -1690,6 +1779,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) ho->neg_chap = 1; break; } +#if EAP_SUPPORT if (cishort == PPP_EAP) { /* we've already accepted CHAP or PAP */ if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) { @@ -1713,6 +1803,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) ho->neg_eap = 1; break; } +#endif /* EAP_SUPPORT */ /* * We don't recognize the protocol they're asking for. @@ -1722,10 +1813,14 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) */ orc = CONFNAK; PUTCHAR(CI_AUTHTYPE, nakp); + +#if EAP_SUPPORT if (ao->neg_eap) { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_EAP, nakp); - } else if (ao->neg_chap) { + } else +#endif /* EAP_SUPPORT */ + if (ao->neg_chap) { PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index d5f8aee0..b440da97 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -93,7 +93,9 @@ typedef struct lcp_options { bool neg_asyncmap; /* Negotiate the async map? */ bool neg_upap; /* Ask for UPAP authentication? */ bool neg_chap; /* Ask for CHAP authentication? */ +#if EAP_SUPPORT bool neg_eap; /* Ask for EAP authentication? */ +#endif /* EAP_SUPPORT */ bool neg_magicnumber; /* Ask for magic number? */ bool neg_pcompression; /* HDLC Protocol Field Compression? */ bool neg_accompression; /* HDLC Address/Control Field Compression? */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 826771e0..8364f02f 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -104,7 +104,9 @@ #endif #include "upap.h" #include "chap-new.h" +#if EAP_SUPPORT #include "eap.h" +#endif /* EAP_SUPPORT */ #include "pathnames.h" #ifdef AT_CHANGE @@ -266,7 +268,9 @@ struct protent *protocols[] = { #ifdef AT_CHANGE &atcp_protent, #endif +#if EAP_SUPPORT &eap_protent, +#endif /* EAP_SUPPORT */ NULL }; diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 30a49fe3..06009361 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -437,7 +437,11 @@ pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { ppp_settings.refuse_pap = 1; ppp_settings.refuse_chap = 0; - ppp_settings.refuse_eap = 1; +#if EAP_SUPPORT + ppp_settings.refuse_pap = 1; + ppp_settings.refuse_chap = 1; + ppp_settings.refuse_eap = 0; +#endif /* EAP_SUPPORT */ /* FIXME: re-enable that */ #if 0 diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 4084414b..a7eb11b4 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -46,7 +46,9 @@ struct ppp_settings { u_int explicit_remote : 1; /* remote_name specified with remotename opt */ u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ +#if EAP_SUPPORT u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ +#endif /* EAP_SUPPORT */ u_int usehostname : 1; /* Use hostname for our_name */ u_int usepeerdns : 1; /* Ask peer for DNS adds */ From b896203dcf008854219c342007a348438874dcce Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 22:04:04 +0200 Subject: [PATCH 033/320] Revert "Removed all stuff requiring encryption." This reverts commit c268c5e07c046eb2cb8e5798a1f3eba7e0ad13c1. Conflicts: src/netif/ppp/auth.c src/netif/ppp/ppp.c src/netif/ppp/pppmy.c src/netif/ppp/pppmy.h --- src/netif/ppp/auth.c | 58 +- src/netif/ppp/cbcp.h | 26 + src/netif/ppp/ccp.c | 1680 ++++++++++++++++++++++++++++++++++++++ src/netif/ppp/ccp.h | 52 ++ src/netif/ppp/chap_ms.c | 943 +++++++++++++++++++++ src/netif/ppp/chap_ms.h | 109 +++ src/netif/ppp/des.c | 530 ++++++++++++ src/netif/ppp/des.h | 40 + src/netif/ppp/ecp.c | 175 ++++ src/netif/ppp/ecp.h | 45 + src/netif/ppp/md4.c | 301 +++++++ src/netif/ppp/md4.h | 64 ++ src/netif/ppp/ppp.c | 40 +- src/netif/ppp/pppcrypt.c | 146 ++++ src/netif/ppp/pppcrypt.h | 40 + src/netif/ppp/pppd.h | 1 + src/netif/ppp/pppmy.c | 6 +- src/netif/ppp/pppmy.h | 2 + src/netif/ppp/sha1.c | 172 ++++ src/netif/ppp/sha1.h | 31 + 20 files changed, 4455 insertions(+), 6 deletions(-) create mode 100644 src/netif/ppp/cbcp.h create mode 100644 src/netif/ppp/ccp.c create mode 100644 src/netif/ppp/ccp.h create mode 100644 src/netif/ppp/chap_ms.c create mode 100644 src/netif/ppp/chap_ms.h create mode 100644 src/netif/ppp/des.c create mode 100644 src/netif/ppp/des.h create mode 100644 src/netif/ppp/ecp.c create mode 100644 src/netif/ppp/ecp.h create mode 100644 src/netif/ppp/md4.c create mode 100644 src/netif/ppp/md4.h create mode 100644 src/netif/ppp/pppcrypt.c create mode 100644 src/netif/ppp/pppcrypt.h create mode 100644 src/netif/ppp/sha1.c create mode 100644 src/netif/ppp/sha1.h diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 17756f11..9b2e8569 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -106,12 +106,17 @@ #include "pppd.h" #include "fsm.h" #include "lcp.h" +#include "ccp.h" +#include "ecp.h" #include "ipcp.h" #include "upap.h" #include "chap-new.h" #if EAP_SUPPORT #include "eap.h" #endif /* EAP_SUPPORT */ +#if CBCP_SUPPORT +#include "cbcp.h" +#endif #include "pathnames.h" #include "session.h" @@ -844,9 +849,48 @@ start_networks(unit) { int i; struct protent *protp; + int ecp_required, mppe_required; new_phase(PHASE_NETWORK); +#ifdef HAVE_MULTILINK + if (multilink) { + if (mp_join_bundle()) { + if (multilink_join_hook) + (*multilink_join_hook)(); + if (updetach && !nodetach) + detach(); + return; + } + } +#endif /* HAVE_MULTILINK */ + +#ifdef PPP_FILTER + if (!demand) + set_filters(&pass_filter, &active_filter); +#endif + /* Start CCP and ECP */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP) + && protp->enabled_flag && protp->open != NULL) + (*protp->open)(0); + + /* + * Bring up other network protocols iff encryption is not required. + */ + ecp_required = ecp_gotoptions[unit].required; + mppe_required = ccp_gotoptions[unit].mppe; + if (!ecp_required && !mppe_required) + continue_networks(unit); +} + +void +continue_networks(unit) + int unit; +{ + int i; + struct protent *protp; + /* * Start the "real" network protocols. */ @@ -1292,10 +1336,15 @@ auth_reset(unit) ao->neg_eap = !ppp_settings.refuse_eap; #endif /* EAP_SUPPORT */ - if(!ppp_settings.refuse_chap) { - ao->chap_mdtype = MDTYPE_MD5; - ao->neg_chap = 1; - } + ao->chap_mdtype = MDTYPE_NONE; + if(!ppp_settings.refuse_chap) + ao->chap_mdtype |= MDTYPE_MD5; + if(!ppp_settings.refuse_mschap) + ao->chap_mdtype |= MDTYPE_MICROSOFT; + if(!ppp_settings.refuse_mschap_v2) + ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; + + ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); } else { ao->neg_upap = 0; @@ -1306,6 +1355,7 @@ auth_reset(unit) ao->chap_mdtype = MDTYPE_NONE; } + printf("neg_upap: %d\n", ao->neg_upap); printf("neg_chap: %d\n", ao->neg_chap); printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); diff --git a/src/netif/ppp/cbcp.h b/src/netif/ppp/cbcp.h new file mode 100644 index 00000000..c2ab3f68 --- /dev/null +++ b/src/netif/ppp/cbcp.h @@ -0,0 +1,26 @@ +#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/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c new file mode 100644 index 00000000..df07a387 --- /dev/null +++ b/src/netif/ppp/ccp.c @@ -0,0 +1,1680 @@ +/* + * ccp.c - PPP Compression Control Protocol. + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $" + +#include +#include + +#include "pppd.h" +#include "fsm.h" +#include "ccp.h" +#include + +#ifdef MPPE +#include "chap_ms.h" /* mppe_xxxx_key, mppe_keys_set */ +#include "lcp.h" /* lcp_close(), lcp_fsm */ +#endif + +static const char rcsid[] = RCSID; + +/* + * Unfortunately there is a bug in zlib which means that using a + * size of 8 (window size = 256) for Deflate compression will cause + * buffer overruns and kernel crashes in the deflate module. + * Until this is fixed we only accept sizes in the range 9 .. 15. + * Thanks to James Carlson for pointing this out. + */ +#define DEFLATE_MIN_WORKS 9 + +/* + * Command-line options. + */ +static int setbsdcomp __P((char **)); +static int setdeflate __P((char **)); +static char bsd_value[8]; +static char deflate_value[8]; + +/* + * Option variables. + */ +#ifdef MPPE +bool refuse_mppe_stateful = 1; /* Allow stateful mode? */ +#endif + +static option_t ccp_option_list[] = { + { "noccp", o_bool, &ccp_protent.enabled_flag, + "Disable CCP negotiation" }, + { "-ccp", o_bool, &ccp_protent.enabled_flag, + "Disable CCP negotiation", OPT_ALIAS }, + + { "bsdcomp", o_special, (void *)setbsdcomp, + "Request BSD-Compress packet compression", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, + { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, + "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].bsd_compress }, + { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, + "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].bsd_compress }, + + { "deflate", o_special, (void *)setdeflate, + "request Deflate compression", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, + { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, + "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].deflate }, + { "-deflate", o_bool, &ccp_wantoptions[0].deflate, + "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].deflate }, + + { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, + "don't use draft deflate #", OPT_A2COPY, + &ccp_allowoptions[0].deflate_draft }, + + { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "request Predictor-1", OPT_PRIO | 1 }, + { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].predictor_1 }, + { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].predictor_1 }, + +#ifdef MPPE + /* MPPE options are symmetrical ... we only set wantoptions here */ + { "require-mppe", o_bool, &ccp_wantoptions[0].mppe, + "require MPPE encryption", + OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, + { "+mppe", o_bool, &ccp_wantoptions[0].mppe, + "require MPPE encryption", + OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, + { "nomppe", o_bool, &ccp_wantoptions[0].mppe, + "don't allow MPPE encryption", OPT_PRIO }, + { "-mppe", o_bool, &ccp_wantoptions[0].mppe, + "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO }, + + /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */ + { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 40-bit encryption", + OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, + { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 40-bit encryption", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + + { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 128-bit encryption", + OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 128-bit encryption", + OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, + { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 128-bit encryption", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + + /* strange one; we always request stateless, but will we allow stateful? */ + { "mppe-stateful", o_bool, &refuse_mppe_stateful, + "allow MPPE stateful mode", OPT_PRIO }, + { "nomppe-stateful", o_bool, &refuse_mppe_stateful, + "disallow MPPE stateful mode", OPT_PRIO | 1 }, +#endif /* MPPE */ + + { NULL } +}; + +/* + * Protocol entry points from main code. + */ +static void ccp_init __P((int unit)); +static void ccp_open __P((int unit)); +static void ccp_close __P((int unit, char *)); +static void ccp_lowerup __P((int unit)); +static void ccp_lowerdown __P((int)); +static void ccp_input __P((int unit, u_char *pkt, int len)); +static void ccp_protrej __P((int unit)); +static int ccp_printpkt __P((u_char *pkt, int len, + void (*printer) __P((void *, char *, ...)), + void *arg)); +static void ccp_datainput __P((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 __P((fsm *)); +static int ccp_cilen __P((fsm *)); +static void ccp_addci __P((fsm *, u_char *, int *)); +static int ccp_ackci __P((fsm *, u_char *, int)); +static int ccp_nakci __P((fsm *, u_char *, int, int)); +static int ccp_rejci __P((fsm *, u_char *, int)); +static int ccp_reqci __P((fsm *, u_char *, int *, int)); +static void ccp_up __P((fsm *)); +static void ccp_down __P((fsm *)); +static int ccp_extcode __P((fsm *, int, int, u_char *, int)); +static void ccp_rack_timeout __P((void *)); +static char *method_name __P((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 \ + || (opt).mppe) + +/* + * 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(argv) + 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; + slprintf(bsd_value, sizeof(bsd_value), + rbits == abits? "%d": "%d,%d", rbits, abits); + + return 1; +} + +static int +setdeflate(argv) + 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 == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { + if (rbits == DEFLATE_MIN_SIZE) + rbits = DEFLATE_MIN_WORKS; + if (abits == DEFLATE_MIN_SIZE) + abits = DEFLATE_MIN_WORKS; + warn("deflate option value of %d changed to %d to avoid zlib bug", + DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); + } + 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; + slprintf(deflate_value, sizeof(deflate_value), + rbits == abits? "%d": "%d,%d", rbits, abits); + + return 1; +} + +/* + * ccp_init - initialize CCP. + */ +static void +ccp_init(unit) + 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(unit) + 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(unit, reason) + 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(unit) + int unit; +{ + fsm_lowerup(&ccp_fsm[unit]); +} + +/* + * ccp_lowerdown - we may not transmit CCP packets. + */ +static void +ccp_lowerdown(unit) + int unit; +{ + fsm_lowerdown(&ccp_fsm[unit]); +} + +/* + * ccp_input - process a received CCP packet. + */ +static void +ccp_input(unit, p, len) + 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."); +#ifdef MPPE + if (ccp_gotoptions[unit].mppe) { + error("MPPE disabled, closing LCP"); + lcp_close(unit, "MPPE disabled by peer"); + } +#endif + } + + /* + * 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(f, code, id, p, len) + fsm *f; + int code, 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(unit) + int unit; +{ + ccp_flags_set(unit, 0, 0); + fsm_lowerdown(&ccp_fsm[unit]); + +#ifdef MPPE + if (ccp_gotoptions[unit].mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(unit, "MPPE required but peer negotiation failed"); + } +#endif + +} + +/* + * ccp_resetci - initialize at start of negotiation. + */ +static void +ccp_resetci(f) + fsm *f; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + u_char opt_buf[CCP_MAX_OPTION_LENGTH]; + + *go = ccp_wantoptions[f->unit]; + all_rejected[f->unit] = 0; + +#ifdef MPPE + if (go->mppe) { + ccp_options *ao = &ccp_allowoptions[f->unit]; + int auth_mschap_bits = auth_done[f->unit]; + int numbits; + + /* + * Start with a basic sanity check: mschap[v2] auth must be in + * exactly one direction. RFC 3079 says that the keys are + * 'derived from the credentials of the peer that initiated the call', + * however the PPP protocol doesn't have such a concept, and pppd + * cannot get this info externally. Instead we do the best we can. + * NB: If MPPE is required, all other compression opts are invalid. + * So, we return right away if we can't do it. + */ + + /* Leave only the mschap auth bits set */ + auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER | + CHAP_MS2_WITHPEER | CHAP_MS2_PEER); + /* Count the mschap auths */ + auth_mschap_bits >>= CHAP_MS_SHIFT; + numbits = 0; + do { + numbits += auth_mschap_bits & 1; + auth_mschap_bits >>= 1; + } while (auth_mschap_bits); + if (numbits > 1) { + error("MPPE required, but auth done in both directions."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + if (!numbits) { + error("MPPE required, but MS-CHAP[v2] auth not performed."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* A plugin (eg radius) may not have obtained key material. */ + if (!mppe_keys_set) { + error("MPPE required, but keys are not available. " + "Possible plugin problem?"); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* LM auth not supported for MPPE */ + if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) { + /* This might be noise */ + if (go->mppe & MPPE_OPT_40) { + notice("Disabling 40-bit MPPE; MS-CHAP LM not supported"); + go->mppe &= ~MPPE_OPT_40; + ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40; + } + } + + /* Last check: can we actually negotiate something? */ + if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) { + /* Could be misconfig, could be 40-bit disabled above. */ + error("MPPE required, but both 40-bit and 128-bit disabled."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* sync options */ + ao->mppe = go->mppe; + /* MPPE is not compatible with other compression types */ + ao->bsd_compress = go->bsd_compress = 0; + ao->predictor_1 = go->predictor_1 = 0; + ao->predictor_2 = go->predictor_2 = 0; + ao->deflate = go->deflate = 0; + } +#endif /* MPPE */ + + /* + * Check whether the kernel knows about the various + * compression methods we might request. + */ +#ifdef MPPE + if (go->mppe) { + opt_buf[0] = CI_MPPE; + opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + /* Key material unimportant here. */ + if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) { + error("MPPE required, but kernel has no support."); + lcp_close(f->unit, "MPPE required but not available"); + } + } +#endif + 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_WORKS); + 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_WORKS); + 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(f) + 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) + + (go->mppe? CILEN_MPPE: 0); +} + +/* + * ccp_addci - put our requests in a packet. + */ +static void +ccp_addci(f, p, lenp) + 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. + */ +#ifdef MPPE + if (go->mppe) { + u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; + + p[0] = opt_buf[0] = CI_MPPE; + p[1] = opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &p[2]); + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN); + res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0); + if (res > 0) + p += CILEN_MPPE; + else + /* This shouldn't happen, we've already tested it! */ + lcp_close(f->unit, "MPPE required but not available in kernel"); + } +#endif + 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; + if (p != p0) { + p += CILEN_DEFLATE; + } else { + for (;;) { + if (go->deflate_size < DEFLATE_MIN_WORKS) { + go->deflate = 0; + break; + } + res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); + if (res > 0) { + p += CILEN_DEFLATE; + break; + } else if (res < 0) { + 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 (;;) { + if (go->bsd_bits < BSD_MIN_BITS) { + go->bsd_compress = 0; + break; + } + res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); + if (res > 0) { + p += CILEN_BSD_COMPRESS; + break; + } else if (res < 0) { + 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(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + u_char *p0 = p; + +#ifdef MPPE + if (go->mppe) { + u_char opt_buf[CILEN_MPPE]; + + opt_buf[0] = CI_MPPE; + opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE)) + return 0; + p += CILEN_MPPE; + len -= CILEN_MPPE; + /* XXX Cope with first/fast ack */ + if (len == 0) + return 1; + } +#endif + 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(f, p, len, treat_as_reject) + fsm *f; + u_char *p; + int len; + int treat_as_reject; +{ + 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; + +#ifdef MPPE + if (go->mppe && len >= CILEN_MPPE + && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { + no.mppe = 1; + /* + * Peer wants us to use a different strength or other setting. + * Fail if we aren't willing to use his suggestion. + */ + MPPE_CI_TO_OPTS(&p[2], try.mppe); + if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) { + error("Refusing MPPE stateful mode offered by peer"); + try.mppe = 0; + } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) { + /* Peer must have set options we didn't request (suggest) */ + try.mppe = 0; + } + + if (!try.mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(f->unit, "MPPE required but peer negotiation failed"); + } + } +#endif /* MPPE */ + 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_WORKS + || 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(f, p, len) + 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; + +#ifdef MPPE + if (go->mppe && len >= CILEN_MPPE + && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { + error("MPPE required but peer refused"); + lcp_close(f->unit, "MPPE required but peer refused"); + p += CILEN_MPPE; + len -= CILEN_MPPE; + } +#endif + if (go->deflate_correct && len >= CILEN_DEFLATE + && p[0] == CI_DEFLATE && 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_correct = 0; + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + } + if (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(f, p, lenp, dont_nak) + 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]; +#ifdef MPPE + bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */ + /* CI_MPPE, or due to other options? */ +#endif + + 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) { +#ifdef MPPE + case CI_MPPE: + if (!ao->mppe || clen != CILEN_MPPE) { + newret = CONFREJ; + break; + } + MPPE_CI_TO_OPTS(&p[2], ho->mppe); + + /* Nak if anything unsupported or unknown are set. */ + if (ho->mppe & MPPE_OPT_UNSUPPORTED) { + newret = CONFNAK; + ho->mppe &= ~MPPE_OPT_UNSUPPORTED; + } + if (ho->mppe & MPPE_OPT_UNKNOWN) { + newret = CONFNAK; + ho->mppe &= ~MPPE_OPT_UNKNOWN; + } + + /* Check state opt */ + if (ho->mppe & MPPE_OPT_STATEFUL) { + /* + * We can Nak and request stateless, but it's a + * lot easier to just assume the peer will request + * it if he can do it; stateful mode is bad over + * the Internet -- which is where we expect MPPE. + */ + if (refuse_mppe_stateful) { + error("Refusing MPPE stateful mode offered by peer"); + newret = CONFREJ; + break; + } + } + + /* Find out which of {S,L} are set. */ + if ((ho->mppe & MPPE_OPT_128) + && (ho->mppe & MPPE_OPT_40)) { + /* Both are set, negotiate the strongest. */ + newret = CONFNAK; + if (ao->mppe & MPPE_OPT_128) + ho->mppe &= ~MPPE_OPT_40; + else if (ao->mppe & MPPE_OPT_40) + ho->mppe &= ~MPPE_OPT_128; + else { + newret = CONFREJ; + break; + } + } else if (ho->mppe & MPPE_OPT_128) { + if (!(ao->mppe & MPPE_OPT_128)) { + newret = CONFREJ; + break; + } + } else if (ho->mppe & MPPE_OPT_40) { + if (!(ao->mppe & MPPE_OPT_40)) { + newret = CONFREJ; + break; + } + } else { + /* Neither are set. */ + /* We cannot accept this. */ + newret = CONFNAK; + /* Give the peer our idea of what can be used, + so it can choose and confirm */ + ho->mppe = ao->mppe; + } + + /* rebuild the opts */ + MPPE_OPTS_TO_CI(ho->mppe, &p[2]); + if (newret == CONFACK) { + u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; + int mtu; + + BCOPY(p, opt_buf, CILEN_MPPE); + BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE], + MPPE_MAX_KEY_LEN); + if (ccp_test(f->unit, opt_buf, + CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) { + /* This shouldn't happen, we've already tested it! */ + error("MPPE required, but kernel has no support."); + lcp_close(f->unit, "MPPE required but not available"); + newret = CONFREJ; + break; + } + /* + * We need to decrease the interface MTU by MPPE_PAD + * because MPPE frames **grow**. The kernel [must] + * allocate MPPE_PAD extra bytes in xmit buffers. + */ + mtu = netif_get_mtu(f->unit); + if (mtu) + netif_set_mtu(f->unit, mtu - MPPE_PAD); + else + newret = CONFREJ; + } + + /* + * We have accepted MPPE or are willing to negotiate + * MPPE parameters. A CONFREJ is due to subsequent + * (non-MPPE) processing. + */ + rej_for_ci_mppe = 0; + break; +#endif /* MPPE */ + 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_WORKS) { + 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_WORKS || 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; + } +#ifdef MPPE + if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(f->unit, "MPPE required but peer negotiation failed"); + } +#endif + return ret; +} + +/* + * Make a string name for a compression method (or 2). + */ +static char * +method_name(opt, opt2) + ccp_options *opt, *opt2; +{ + static char result[64]; + + if (!ANY_COMPRESS(*opt)) + return "(none)"; + switch (opt->method) { +#ifdef MPPE + case CI_MPPE: + { + char *p = result; + char *q = result + sizeof(result); /* 1 past result */ + + slprintf(p, q - p, "MPPE "); + p += 5; + if (opt->mppe & MPPE_OPT_128) { + slprintf(p, q - p, "128-bit "); + p += 8; + } + if (opt->mppe & MPPE_OPT_40) { + slprintf(p, q - p, "40-bit "); + p += 7; + } + if (opt->mppe & MPPE_OPT_STATEFUL) + slprintf(p, q - p, "stateful"); + else + slprintf(p, q - p, "stateless"); + + break; + } +#endif + 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(f) + 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)); +#ifdef MPPE + if (go->mppe) { + BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN); + BZERO(mppe_send_key, MPPE_MAX_KEY_LEN); + continue_networks(f->unit); /* Bring up IP et al */ + } +#endif +} + +/* + * CCP has gone down - inform the kernel driver. + */ +static void +ccp_down(f) + 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); +#ifdef MPPE + if (ccp_gotoptions[f->unit].mppe) { + ccp_gotoptions[f->unit].mppe = 0; + if (lcp_fsm[f->unit].state == OPENED) { + /* If LCP is not already going down, make sure it does. */ + error("MPPE disabled"); + lcp_close(f->unit, "MPPE disabled"); + } + } +#endif +} + +/* + * 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(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((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) { +#ifdef MPPE + case CI_MPPE: + if (optlen >= CILEN_MPPE) { + u_char mppe_opts; + + MPPE_CI_TO_OPTS(&p[2], mppe_opts); + printer(arg, "mppe %s %s %s %s %s %s%s", + (p[2] & MPPE_H_BIT)? "+H": "-H", + (p[5] & MPPE_M_BIT)? "+M": "-M", + (p[5] & MPPE_S_BIT)? "+S": "-S", + (p[5] & MPPE_L_BIT)? "+L": "-L", + (p[5] & MPPE_D_BIT)? "+D": "-D", + (p[5] & MPPE_C_BIT)? "+C": "-C", + (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": ""); + if (mppe_opts & MPPE_OPT_UNKNOWN) + printer(arg, " (%.2x %.2x %.2x %.2x)", + p[2], p[3], p[4], p[5]); + p += CILEN_MPPE; + } + break; +#endif + 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((char *)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(unit, pkt, len) + 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"); +#ifdef MPPE + /* + * If we were doing MPPE, we must also take the link down. + */ + if (ccp_gotoptions[unit].mppe) { + error("Too many MPPE errors, closing LCP"); + lcp_close(unit, "Too many MPPE errors"); + } +#endif + } 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(arg) + 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/src/netif/ppp/ccp.h b/src/netif/ppp/ccp.h new file mode 100644 index 00000000..6f4a2fee --- /dev/null +++ b/src/netif/ppp/ccp.h @@ -0,0 +1,52 @@ +/* + * ccp.h - Definitions for PPP Compression Control Protocol. + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $ + */ + +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? */ + bool mppe; /* do MPPE? */ + 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/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c new file mode 100644 index 00000000..0d3b5347 --- /dev/null +++ b/src/netif/ppp/chap_ms.c @@ -0,0 +1,943 @@ +/* + * chap_ms.c - Microsoft MS-CHAP compatible implementation. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * 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 + */ + +/* + * Modifications by Frank Cusack, frank@google.com, March 2002. + * + * Implemented MS-CHAPv2 functionality, heavily based on sample + * implementation in RFC 2759. Implemented MPPE functionality, + * heavily based on sample implementation in RFC 3079. + * + * Copyright (c) 2002 Google, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $" + +#ifdef CHAPMS + +#include +#include +#include +#include +#include +#include +#include + +#include "pppd.h" +#include "chap-new.h" +#include "chap_ms.h" +#include "md4.h" +#include "sha1.h" +#include "pppcrypt.h" +#include "magic.h" + +static const char rcsid[] = RCSID; + + +static void ascii2unicode __P((char[], int, u_char[])); +static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); +static void ChallengeResponse __P((u_char *, u_char *, u_char[24])); +static void ChapMS_NT __P((u_char *, char *, int, u_char[24])); +static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int, + u_char[24])); +static void GenerateAuthenticatorResponsePlain + __P((char*, int, u_char[24], u_char[16], u_char *, + char *, u_char[41])); +#ifdef MSLANMAN +static void ChapMS_LANMan __P((u_char *, char *, int, u_char *)); +#endif + +#ifdef MPPE +static void Set_Start_Key __P((u_char *, char *, int)); +static void SetMasterKeys __P((char *, int, u_char[24], int)); +#endif + +#ifdef MSLANMAN +bool ms_lanman = 0; /* Use LanMan password instead of NT */ + /* Has meaning only with MS-CHAP challenges */ +#endif + +#ifdef MPPE +u_char mppe_send_key[MPPE_MAX_KEY_LEN]; +u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; +int mppe_keys_set = 0; /* Have the MPPE keys been set? */ + +#ifdef DEBUGMPPEKEY +/* For MPPE debug */ +/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */ +static char *mschap_challenge = NULL; +/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */ +static char *mschap2_peer_challenge = NULL; +#endif + +#include "fsm.h" /* Need to poke MPPE options */ +#include "ccp.h" +#include +#endif + +/* + * Command-line options. + */ +static option_t chapms_option_list[] = { +#ifdef MSLANMAN + { "ms-lanman", o_bool, &ms_lanman, + "Use LanMan passwd when using MS-CHAP", 1 }, +#endif +#ifdef DEBUGMPPEKEY + { "mschap-challenge", o_string, &mschap_challenge, + "specify CHAP challenge" }, + { "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, + "specify CHAP peer challenge" }, +#endif + { NULL } +}; + +/* + * chapms_generate_challenge - generate a challenge for MS-CHAP. + * For MS-CHAP the challenge length is fixed at 8 bytes. + * The length goes in challenge[0] and the actual challenge starts + * at challenge[1]. + */ +static void +chapms_generate_challenge(unsigned char *challenge) +{ + *challenge++ = 8; +#ifdef DEBUGMPPEKEY + if (mschap_challenge && strlen(mschap_challenge) == 8) + memcpy(challenge, mschap_challenge, 8); + else +#endif + random_bytes(challenge, 8); +} + +static void +chapms2_generate_challenge(unsigned char *challenge) +{ + *challenge++ = 16; +#ifdef DEBUGMPPEKEY + if (mschap_challenge && strlen(mschap_challenge) == 16) + memcpy(challenge, mschap_challenge, 16); + else +#endif + random_bytes(challenge, 16); +} + +static int +chapms_verify_response(int id, char *name, + unsigned char *secret, int secret_len, + unsigned char *challenge, unsigned char *response, + char *message, int message_space) +{ + unsigned char md[MS_CHAP_RESPONSE_LEN]; + int diff; + int challenge_len, response_len; + + challenge_len = *challenge++; /* skip length, is 8 */ + response_len = *response++; + if (response_len != MS_CHAP_RESPONSE_LEN) + goto bad; + +#ifndef MSLANMAN + if (!response[MS_CHAP_USENT]) { + /* Should really propagate this into the error packet. */ + notice("Peer request for LANMAN auth not supported"); + goto bad; + } +#endif + + /* Generate the expected response. */ + ChapMS(challenge, (char *)secret, secret_len, md); + +#ifdef MSLANMAN + /* Determine which part of response to verify against */ + if (!response[MS_CHAP_USENT]) + diff = memcmp(&response[MS_CHAP_LANMANRESP], + &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN); + else +#endif + diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP], + MS_CHAP_NTRESP_LEN); + + if (diff == 0) { + slprintf(message, message_space, "Access granted"); + return 1; + } + + bad: + /* See comments below for MS-CHAP V2 */ + slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", + challenge_len, challenge); + return 0; +} + +static int +chapms2_verify_response(int id, char *name, + unsigned char *secret, int secret_len, + unsigned char *challenge, unsigned char *response, + char *message, int message_space) +{ + unsigned char md[MS_CHAP2_RESPONSE_LEN]; + char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; + int challenge_len, response_len; + + challenge_len = *challenge++; /* skip length, is 16 */ + response_len = *response++; + if (response_len != MS_CHAP2_RESPONSE_LEN) + goto bad; /* not even the right length */ + + /* Generate the expected response and our mutual auth. */ + ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name, + (char *)secret, secret_len, md, + (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); + + /* compare MDs and send the appropriate status */ + /* + * Per RFC 2759, success message must be formatted as + * "S= M=" + * where + * is the Authenticator Response (mutual auth) + * is a text message + * + * However, some versions of Windows (win98 tested) do not know + * about the M= part (required per RFC 2759) and flag + * it as an error (reported incorrectly as an encryption error + * to the user). Since the RFC requires it, and it can be + * useful information, we supply it if the peer is a conforming + * system. Luckily (?), win98 sets the Flags field to 0x04 + * (contrary to RFC requirements) so we can use that to + * distinguish between conforming and non-conforming systems. + * + * Special thanks to Alex Swiridov for + * help debugging this. + */ + if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], + MS_CHAP2_NTRESP_LEN) == 0) { + if (response[MS_CHAP2_FLAGS]) + slprintf(message, message_space, "S=%s", saresponse); + else + slprintf(message, message_space, "S=%s M=%s", + saresponse, "Access granted"); + return 1; + } + + bad: + /* + * Failure message must be formatted as + * "E=e R=r C=c V=v M=m" + * where + * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE) + * r = retry (we use 1, ok to retry) + * c = challenge to use for next response, we reuse previous + * v = Change Password version supported, we use 0 + * m = text message + * + * The M=m part is only for MS-CHAPv2. Neither win2k nor + * win98 (others untested) display the message to the user anyway. + * They also both ignore the E=e code. + * + * Note that it's safe to reuse the same challenge as we don't + * actually accept another response based on the error message + * (and no clients try to resend a response anyway). + * + * Basically, this whole bit is useless code, even the small + * implementation here is only because of overspecification. + */ + slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", + challenge_len, challenge, "Access denied"); + return 0; +} + +static void +chapms_make_response(unsigned char *response, int id, char *our_name, + unsigned char *challenge, char *secret, int secret_len, + unsigned char *private) +{ + challenge++; /* skip length, should be 8 */ + *response++ = MS_CHAP_RESPONSE_LEN; + ChapMS(challenge, secret, secret_len, response); +} + +static void +chapms2_make_response(unsigned char *response, int id, char *our_name, + unsigned char *challenge, char *secret, int secret_len, + unsigned char *private) +{ + challenge++; /* skip length, should be 16 */ + *response++ = MS_CHAP2_RESPONSE_LEN; + ChapMS2(challenge, +#ifdef DEBUGMPPEKEY + mschap2_peer_challenge, +#else + NULL, +#endif + our_name, secret, secret_len, response, private, + MS_CHAP2_AUTHENTICATEE); +} + +static int +chapms2_check_success(unsigned char *msg, int len, unsigned char *private) +{ + if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || + strncmp((char *)msg, "S=", 2) != 0) { + /* Packet does not start with "S=" */ + error("MS-CHAPv2 Success packet is badly formed."); + return 0; + } + msg += 2; + len -= 2; + if (len < MS_AUTH_RESPONSE_LENGTH + || memcmp(msg, private, MS_AUTH_RESPONSE_LENGTH)) { + /* Authenticator Response did not match expected. */ + error("MS-CHAPv2 mutual authentication failed."); + return 0; + } + /* Authenticator Response matches. */ + msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */ + len -= MS_AUTH_RESPONSE_LENGTH; + if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) { + msg += 3; /* Eat the delimiter */ + } else if (len) { + /* Packet has extra text which does not begin " M=" */ + error("MS-CHAPv2 Success packet is badly formed."); + return 0; + } + return 1; +} + +static void +chapms_handle_failure(unsigned char *inp, int len) +{ + int err; + char *p, *msg; + + /* We want a null-terminated string for strxxx(). */ + msg = malloc(len + 1); + if (!msg) { + notice("Out of memory in chapms_handle_failure"); + return; + } + BCOPY(inp, msg, len); + msg[len] = 0; + p = msg; + + /* + * Deal with MS-CHAP formatted failure messages; just print the + * M= part (if any). For MS-CHAP we're not really supposed + * to use M=, but it shouldn't hurt. See + * chapms[2]_verify_response. + */ + if (!strncmp(p, "E=", 2)) + err = strtol(p+2, NULL, 10); /* Remember the error code. */ + else + goto print_msg; /* Message is badly formatted. */ + + if (len && ((p = strstr(p, " M=")) != NULL)) { + /* M= field found. */ + p += 3; + } else { + /* No M=; use the error code. */ + switch (err) { + case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS: + p = "E=646 Restricted logon hours"; + break; + + case MS_CHAP_ERROR_ACCT_DISABLED: + p = "E=647 Account disabled"; + break; + + case MS_CHAP_ERROR_PASSWD_EXPIRED: + p = "E=648 Password expired"; + break; + + case MS_CHAP_ERROR_NO_DIALIN_PERMISSION: + p = "E=649 No dialin permission"; + break; + + case MS_CHAP_ERROR_AUTHENTICATION_FAILURE: + p = "E=691 Authentication failure"; + break; + + case MS_CHAP_ERROR_CHANGING_PASSWORD: + /* Should never see this, we don't support Change Password. */ + p = "E=709 Error changing password"; + break; + + default: + free(msg); + error("Unknown MS-CHAP authentication failure: %.*v", + len, inp); + return; + } + } +print_msg: + if (p != NULL) + error("MS-CHAP authentication failed: %v", p); + free(msg); +} + +static void +ChallengeResponse(u_char *challenge, + u_char PasswordHash[MD4_SIGNATURE_SIZE], + u_char response[24]) +{ + u_char ZPasswordHash[21]; + + BZERO(ZPasswordHash, sizeof(ZPasswordHash)); + BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE); + +#if 0 + dbglog("ChallengeResponse - ZPasswordHash %.*B", + sizeof(ZPasswordHash), ZPasswordHash); +#endif + + (void) DesSetkey(ZPasswordHash + 0); + DesEncrypt(challenge, response + 0); + (void) DesSetkey(ZPasswordHash + 7); + DesEncrypt(challenge, response + 8); + (void) DesSetkey(ZPasswordHash + 14); + DesEncrypt(challenge, response + 16); + +#if 0 + dbglog("ChallengeResponse - response %.24B", response); +#endif +} + +void +ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, + char *username, u_char Challenge[8]) + +{ + SHA1_CTX sha1Context; + u_char sha1Hash[SHA1_SIGNATURE_SIZE]; + char *user; + + /* remove domain from "domain\username" */ + if ((user = strrchr(username, '\\')) != NULL) + ++user; + else + user = username; + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PeerChallenge, 16); + SHA1_Update(&sha1Context, rchallenge, 16); + SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user)); + SHA1_Final(sha1Hash, &sha1Context); + + BCOPY(sha1Hash, Challenge, 8); +} + +/* + * Convert the ASCII version of the password to Unicode. + * This implicitly supports 8-bit ISO8859/1 characters. + * This gives us the little-endian representation, which + * is assumed by all M$ CHAP RFCs. (Unicode byte ordering + * is machine-dependent.) + */ +static void +ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) +{ + int i; + + BZERO(unicode, ascii_len * 2); + for (i = 0; i < ascii_len; i++) + unicode[i * 2] = (u_char) ascii[i]; +} + +static void +NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) +{ +#ifdef __NetBSD__ + /* NetBSD uses the libc md4 routines which take bytes instead of bits */ + int mdlen = secret_len; +#else + int mdlen = secret_len * 8; +#endif + MD4_CTX md4Context; + + MD4Init(&md4Context); + /* MD4Update can take at most 64 bytes at a time */ + while (mdlen > 512) { + MD4Update(&md4Context, secret, 512); + secret += 64; + mdlen -= 512; + } + MD4Update(&md4Context, secret, mdlen); + MD4Final(hash, &md4Context); + +} + +static void +ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, + u_char NTResponse[24]) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + + /* Hash the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + + ChallengeResponse(rchallenge, PasswordHash, NTResponse); +} + +static void +ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, + char *secret, int secret_len, u_char NTResponse[24]) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char Challenge[8]; + + ChallengeHash(PeerChallenge, rchallenge, username, Challenge); + + /* Hash the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + + ChallengeResponse(Challenge, PasswordHash, NTResponse); +} + +#ifdef MSLANMAN +static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ + +static void +ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, + unsigned char *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]); + (void) DesSetkey(UcasePassword + 0); + DesEncrypt( StdText, PasswordHash + 0 ); + (void) DesSetkey(UcasePassword + 7); + DesEncrypt( StdText, PasswordHash + 8 ); + ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); +} +#endif + + +void +GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) +{ + /* + * "Magic" constants used in response generation, from RFC 2759. + */ + u_char Magic1[39] = /* "Magic server to client signing constant" */ + { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; + u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ + { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, + 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E }; + + int i; + SHA1_CTX sha1Context; + u_char Digest[SHA1_SIGNATURE_SIZE]; + u_char Challenge[8]; + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, NTResponse, 24); + SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); + SHA1_Final(Digest, &sha1Context); + + ChallengeHash(PeerChallenge, rchallenge, username, Challenge); + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, Digest, sizeof(Digest)); + SHA1_Update(&sha1Context, Challenge, sizeof(Challenge)); + SHA1_Update(&sha1Context, Magic2, sizeof(Magic2)); + SHA1_Final(Digest, &sha1Context); + + /* Convert to ASCII hex string. */ + for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) + sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); +} + + +static void +GenerateAuthenticatorResponsePlain + (char *secret, int secret_len, + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), + PasswordHashHash); + + GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge, + rchallenge, username, authResponse); +} + + +#ifdef MPPE +/* + * Set mppe_xxxx_key from the NTPasswordHashHash. + * RFC 2548 (RADIUS support) requires us to export this function (ugh). + */ +void +mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) +{ + SHA1_CTX sha1Context; + u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, rchallenge, 8); + SHA1_Final(Digest, &sha1Context); + + /* Same key in both directions. */ + BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); + BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); + + mppe_keys_set = 1; +} + +/* + * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) + */ +static void +Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); + + mppe_set_keys(rchallenge, PasswordHashHash); +} + +/* + * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) + * + * This helper function used in the Winbind module, which gets the + * NTHashHash from the server. + */ +void +mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], int IsServer) +{ + SHA1_CTX sha1Context; + u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + + u_char SHApad1[40] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u_char SHApad2[40] = + { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 }; + + /* "This is the MPPE Master Key" */ + u_char Magic1[27] = + { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; + /* "On the client side, this is the send key; " + "on the server side, it is the receive key." */ + u_char Magic2[84] = + { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, + 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, + 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x2e }; + /* "On the client side, this is the receive key; " + "on the server side, it is the send key." */ + u_char Magic3[84] = + { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, + 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, + 0x6b, 0x65, 0x79, 0x2e }; + u_char *s; + + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + SHA1_Update(&sha1Context, NTResponse, 24); + SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); + SHA1_Final(MasterKey, &sha1Context); + + /* + * generate send key + */ + if (IsServer) + s = Magic3; + else + s = Magic2; + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, MasterKey, 16); + SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); + SHA1_Update(&sha1Context, s, 84); + SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); + SHA1_Final(Digest, &sha1Context); + + BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); + + /* + * generate recv key + */ + if (IsServer) + s = Magic2; + else + s = Magic3; + SHA1_Init(&sha1Context); + SHA1_Update(&sha1Context, MasterKey, 16); + SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); + SHA1_Update(&sha1Context, s, 84); + SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); + SHA1_Final(Digest, &sha1Context); + + BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); + + mppe_keys_set = 1; +} + +/* + * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) + */ +static void +SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) +{ + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); + mppe_set_keys2(PasswordHashHash, NTResponse, IsServer); +} + +#endif /* MPPE */ + + +void +ChapMS(u_char *rchallenge, char *secret, int secret_len, + unsigned char *response) +{ + BZERO(response, MS_CHAP_RESPONSE_LEN); + + ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); + +#ifdef MSLANMAN + ChapMS_LANMan(rchallenge, secret, secret_len, + &response[MS_CHAP_LANMANRESP]); + + /* preferred method is set by option */ + response[MS_CHAP_USENT] = !ms_lanman; +#else + response[MS_CHAP_USENT] = 1; +#endif + +#ifdef MPPE + Set_Start_Key(rchallenge, secret, secret_len); +#endif +} + + +/* + * If PeerChallenge is NULL, one is generated and the PeerChallenge + * field of response is filled in. Call this way when generating a response. + * If PeerChallenge is supplied, it is copied into the PeerChallenge field. + * Call this way when verifying a response (or debugging). + * Do not call with PeerChallenge = response. + * + * The PeerChallenge field of response is then used for calculation of the + * Authenticator Response. + */ +void +ChapMS2(u_char *rchallenge, u_char *PeerChallenge, + char *user, char *secret, int secret_len, unsigned char *response, + u_char authResponse[], int authenticator) +{ + /* ARGSUSED */ + u_char *p = &response[MS_CHAP2_PEER_CHALLENGE]; + int i; + + BZERO(response, MS_CHAP2_RESPONSE_LEN); + + /* Generate the Peer-Challenge if requested, or copy it if supplied. */ + if (!PeerChallenge) + for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++) + *p++ = (u_char) (drand48() * 0xff); + else + BCOPY(PeerChallenge, &response[MS_CHAP2_PEER_CHALLENGE], + MS_CHAP2_PEER_CHAL_LEN); + + /* Generate the NT-Response */ + ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, + secret, secret_len, &response[MS_CHAP2_NTRESP]); + + /* Generate the Authenticator Response. */ + GenerateAuthenticatorResponsePlain(secret, secret_len, + &response[MS_CHAP2_NTRESP], + &response[MS_CHAP2_PEER_CHALLENGE], + rchallenge, user, authResponse); + +#ifdef MPPE + SetMasterKeys(secret, secret_len, + &response[MS_CHAP2_NTRESP], authenticator); +#endif +} + +#ifdef MPPE +/* + * Set MPPE options from plugins. + */ +void +set_mppe_enc_types(int policy, int types) +{ + /* Early exit for unknown policies. */ + if (policy != MPPE_ENC_POL_ENC_ALLOWED || + policy != MPPE_ENC_POL_ENC_REQUIRED) + return; + + /* Don't modify MPPE if it's optional and wasn't already configured. */ + if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe) + return; + + /* + * Disable undesirable encryption types. Note that we don't ENABLE + * any encryption types, to avoid overriding manual configuration. + */ + switch(types) { + case MPPE_ENC_TYPES_RC4_40: + ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */ + break; + case MPPE_ENC_TYPES_RC4_128: + ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */ + break; + default: + break; + } +} +#endif /* MPPE */ + +static struct chap_digest_type chapms_digest = { + CHAP_MICROSOFT, /* code */ + chapms_generate_challenge, + chapms_verify_response, + chapms_make_response, + NULL, /* check_success */ + chapms_handle_failure, +}; + +static struct chap_digest_type chapms2_digest = { + CHAP_MICROSOFT_V2, /* code */ + chapms2_generate_challenge, + chapms2_verify_response, + chapms2_make_response, + chapms2_check_success, + chapms_handle_failure, +}; + +void +chapms_init(void) +{ + chap_register_digest(&chapms_digest); + chap_register_digest(&chapms2_digest); + add_options(chapms_option_list); +} + +#endif /* CHAPMS */ diff --git a/src/netif/ppp/chap_ms.h b/src/netif/ppp/chap_ms.h new file mode 100644 index 00000000..040d80ad --- /dev/null +++ b/src/netif/ppp/chap_ms.h @@ -0,0 +1,109 @@ +/* + * chap_ms.h - Challenge Handshake Authentication Protocol definitions. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ + */ + +#ifndef __CHAPMS_INCLUDE__ + +#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ +#define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */ + +#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ +#define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */ +#define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */ + /* as ASCII */ + +/* E=eeeeeeeeee error codes for MS-CHAP failure messages. */ +#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646 +#define MS_CHAP_ERROR_ACCT_DISABLED 647 +#define MS_CHAP_ERROR_PASSWD_EXPIRED 648 +#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649 +#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691 +#define MS_CHAP_ERROR_CHANGING_PASSWORD 709 + +/* + * Offsets within the response field for MS-CHAP + */ +#define MS_CHAP_LANMANRESP 0 +#define MS_CHAP_LANMANRESP_LEN 24 +#define MS_CHAP_NTRESP 24 +#define MS_CHAP_NTRESP_LEN 24 +#define MS_CHAP_USENT 48 + +/* + * Offsets within the response field for MS-CHAP2 + */ +#define MS_CHAP2_PEER_CHALLENGE 0 +#define MS_CHAP2_PEER_CHAL_LEN 16 +#define MS_CHAP2_RESERVED_LEN 8 +#define MS_CHAP2_NTRESP 24 +#define MS_CHAP2_NTRESP_LEN 24 +#define MS_CHAP2_FLAGS 48 + +#ifdef MPPE +#include "mppe.h" /* MPPE_MAX_KEY_LEN */ +extern u_char mppe_send_key[MPPE_MAX_KEY_LEN]; +extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; +extern int mppe_keys_set; + +/* These values are the RADIUS attribute values--see RFC 2548. */ +#define MPPE_ENC_POL_ENC_ALLOWED 1 +#define MPPE_ENC_POL_ENC_REQUIRED 2 +#define MPPE_ENC_TYPES_RC4_40 2 +#define MPPE_ENC_TYPES_RC4_128 4 + +/* used by plugins (using above values) */ +extern void set_mppe_enc_types(int, int); +#endif + +/* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */ +#define MS_CHAP2_AUTHENTICATEE 0 +#define MS_CHAP2_AUTHENTICATOR 1 + +void ChapMS __P((u_char *, char *, int, u_char *)); +void ChapMS2 __P((u_char *, u_char *, char *, char *, int, + u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int)); +#ifdef MPPE +void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE])); +void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], int IsServer); +#endif + +void ChallengeHash __P((u_char[16], u_char *, char *, u_char[8])); + +void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]); + +void chapms_init(void); + +#define __CHAPMS_INCLUDE__ +#endif /* __CHAPMS_INCLUDE__ */ diff --git a/src/netif/ppp/des.c b/src/netif/ppp/des.c new file mode 100644 index 00000000..123c1978 --- /dev/null +++ b/src/netif/ppp/des.c @@ -0,0 +1,530 @@ +/* $OpenBSD: crypt.c,v 1.20 2005/08/08 08:05:33 espie Exp $ */ + +/* + * FreeSec: libcrypt + * + * Copyright (c) 1994 David Burren + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * This is an original implementation of the DES and the crypt(3) interfaces + * by David Burren . + * + * An excellent reference on the underlying algorithm (and related + * algorithms) is: + * + * B. Schneier, Applied Cryptography: protocols, algorithms, + * and source code in C, John Wiley & Sons, 1994. + * + * Note that in that book's description of DES the lookups for the initial, + * pbox, and final permutations are inverted (this has been brought to the + * attention of the author). A list of errata for this book has been + * posted to the sci.crypt newsgroup by the author and is available for FTP. + */ + +#include "lwip/opt.h" +/* FIXME: don't build if not necessary */ + +#include "lwip/def.h" + +static const u_char IP[64] = { + 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 +}; + +static u_char inv_key_perm[64]; +static u_char u_key_perm[56]; +static u_char const key_perm[56] = { + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 +}; + +static const u_char key_shifts[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +static u_char inv_comp_perm[56]; +static const u_char comp_perm[48] = { + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 +}; + +/* + * No E box is used, as it's replaced by some ANDs, shifts, and ORs. + */ + +static u_char u_sbox[8][64]; +static const u_char sbox[8][64] = { + { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 + }, + { + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 + }, + { + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 + }, + { + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 + }, + { + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 + }, + { + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 + }, + { + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 + }, + { + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 + } +}; + +static u_char un_pbox[32]; +static const u_char pbox[32] = { + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 +}; + +const u_int32_t _des_bits32[32] = +{ + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 +}; + +const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + +static const u_int32_t *bits28, *bits24; +static u_char init_perm[64], final_perm[64]; +static u_int32_t en_keysl[16], en_keysr[16]; +static u_int32_t de_keysl[16], de_keysr[16]; +int _des_initialised = 0; +static u_char m_sbox[4][4096]; +static u_int32_t psbox[4][256]; +static u_int32_t ip_maskl[8][256], ip_maskr[8][256]; +static u_int32_t fp_maskl[8][256], fp_maskr[8][256]; +static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; +static u_int32_t comp_maskl[8][128], comp_maskr[8][128]; +static u_int32_t old_rawkey0, old_rawkey1; + +void +_des_init(void) +{ + int i, j, b, k, inbit, obit; + u_int32_t *p, *il, *ir, *fl, *fr; + + old_rawkey0 = old_rawkey1 = 0; + bits24 = (bits28 = _des_bits32 + 4) + 4; + + /* + * Invert the S-boxes, reordering the input bits. + */ + for (i = 0; i < 8; i++) + for (j = 0; j < 64; j++) { + b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); + u_sbox[i][j] = sbox[i][b]; + } + + /* + * Convert the inverted S-boxes into 4 arrays of 8 bits. + * Each will handle 12 bits of the S-box input. + */ + for (b = 0; b < 4; b++) + for (i = 0; i < 64; i++) + for (j = 0; j < 64; j++) + m_sbox[b][(i << 6) | j] = + (u_sbox[(b << 1)][i] << 4) | + u_sbox[(b << 1) + 1][j]; + + /* + * Set up the initial & final permutations into a useful form, and + * initialise the inverted key permutation. + */ + for (i = 0; i < 64; i++) { + init_perm[final_perm[i] = IP[i] - 1] = i; + inv_key_perm[i] = 255; + } + + /* + * Invert the key permutation and initialise the inverted key + * compression permutation. + */ + for (i = 0; i < 56; i++) { + u_key_perm[i] = key_perm[i] - 1; + inv_key_perm[key_perm[i] - 1] = i; + inv_comp_perm[i] = 255; + } + + /* + * Invert the key compression permutation. + */ + for (i = 0; i < 48; i++) { + inv_comp_perm[comp_perm[i] - 1] = i; + } + + /* + * Set up the OR-mask arrays for the initial and final permutations, + * and for the key initial and compression permutations. + */ + for (k = 0; k < 8; k++) { + for (i = 0; i < 256; i++) { + *(il = &ip_maskl[k][i]) = 0; + *(ir = &ip_maskr[k][i]) = 0; + *(fl = &fp_maskl[k][i]) = 0; + *(fr = &fp_maskr[k][i]) = 0; + for (j = 0; j < 8; j++) { + inbit = 8 * k + j; + if (i & _des_bits8[j]) { + if ((obit = init_perm[inbit]) < 32) + *il |= _des_bits32[obit]; + else + *ir |= _des_bits32[obit-32]; + if ((obit = final_perm[inbit]) < 32) + *fl |= _des_bits32[obit]; + else + *fr |= _des_bits32[obit - 32]; + } + } + } + for (i = 0; i < 128; i++) { + *(il = &key_perm_maskl[k][i]) = 0; + *(ir = &key_perm_maskr[k][i]) = 0; + for (j = 0; j < 7; j++) { + inbit = 8 * k + j; + if (i & _des_bits8[j + 1]) { + if ((obit = inv_key_perm[inbit]) == 255) + continue; + if (obit < 28) + *il |= bits28[obit]; + else + *ir |= bits28[obit - 28]; + } + } + *(il = &comp_maskl[k][i]) = 0; + *(ir = &comp_maskr[k][i]) = 0; + for (j = 0; j < 7; j++) { + inbit = 7 * k + j; + if (i & _des_bits8[j + 1]) { + if ((obit=inv_comp_perm[inbit]) == 255) + continue; + if (obit < 24) + *il |= bits24[obit]; + else + *ir |= bits24[obit - 24]; + } + } + } + } + + /* + * Invert the P-box permutation, and convert into OR-masks for + * handling the output of the S-box arrays setup above. + */ + for (i = 0; i < 32; i++) + un_pbox[pbox[i] - 1] = i; + + for (b = 0; b < 4; b++) + for (i = 0; i < 256; i++) { + *(p = &psbox[b][i]) = 0; + for (j = 0; j < 8; j++) { + if (i & _des_bits8[j]) + *p |= _des_bits32[un_pbox[8 * b + j]]; + } + } + + _des_initialised = 1; +} + +int +des_setkey(const char *key) +{ + u_int32_t k0, k1, rawkey0, rawkey1; + int shifts, round; + + if (!_des_initialised) + _des_init(); + + rawkey0 = ntohl(*(u_int32_t *) key); + rawkey1 = ntohl(*(u_int32_t *) (key + 4)); + + if ((rawkey0 | rawkey1) + && rawkey0 == old_rawkey0 + && rawkey1 == old_rawkey1) { + /* + * Already setup for this key. + * This optimisation fails on a zero key (which is weak and + * has bad parity anyway) in order to simplify the starting + * conditions. + */ + return(0); + } + old_rawkey0 = rawkey0; + old_rawkey1 = rawkey1; + + /* + * Do key permutation and split into two 28-bit subkeys. + */ + k0 = key_perm_maskl[0][rawkey0 >> 25] + | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskl[4][rawkey1 >> 25] + | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; + k1 = key_perm_maskr[0][rawkey0 >> 25] + | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskr[4][rawkey1 >> 25] + | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; + /* + * Rotate subkeys and do compression permutation. + */ + shifts = 0; + for (round = 0; round < 16; round++) { + u_int32_t t0, t1; + + shifts += key_shifts[round]; + + t0 = (k0 << shifts) | (k0 >> (28 - shifts)); + t1 = (k1 << shifts) | (k1 >> (28 - shifts)); + + de_keysl[15 - round] = + en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] + | comp_maskl[1][(t0 >> 14) & 0x7f] + | comp_maskl[2][(t0 >> 7) & 0x7f] + | comp_maskl[3][t0 & 0x7f] + | comp_maskl[4][(t1 >> 21) & 0x7f] + | comp_maskl[5][(t1 >> 14) & 0x7f] + | comp_maskl[6][(t1 >> 7) & 0x7f] + | comp_maskl[7][t1 & 0x7f]; + + de_keysr[15 - round] = + en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f] + | comp_maskr[1][(t0 >> 14) & 0x7f] + | comp_maskr[2][(t0 >> 7) & 0x7f] + | comp_maskr[3][t0 & 0x7f] + | comp_maskr[4][(t1 >> 21) & 0x7f] + | comp_maskr[5][(t1 >> 14) & 0x7f] + | comp_maskr[6][(t1 >> 7) & 0x7f] + | comp_maskr[7][t1 & 0x7f]; + } + return(0); +} + +int +_des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, + int count) +{ + /* + * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. + */ + u_int32_t l, r, *kl, *kr, *kl1, *kr1; + u_int32_t f, r48l, r48r; + int round; + + if (count == 0) { + return(1); + } else if (count > 0) { + /* + * Encrypting + */ + kl1 = en_keysl; + kr1 = en_keysr; + } else { + /* + * Decrypting + */ + count = -count; + kl1 = de_keysl; + kr1 = de_keysr; + } + + /* + * Do initial permutation (IP). + */ + l = ip_maskl[0][l_in >> 24] + | ip_maskl[1][(l_in >> 16) & 0xff] + | ip_maskl[2][(l_in >> 8) & 0xff] + | ip_maskl[3][l_in & 0xff] + | ip_maskl[4][r_in >> 24] + | ip_maskl[5][(r_in >> 16) & 0xff] + | ip_maskl[6][(r_in >> 8) & 0xff] + | ip_maskl[7][r_in & 0xff]; + r = ip_maskr[0][l_in >> 24] + | ip_maskr[1][(l_in >> 16) & 0xff] + | ip_maskr[2][(l_in >> 8) & 0xff] + | ip_maskr[3][l_in & 0xff] + | ip_maskr[4][r_in >> 24] + | ip_maskr[5][(r_in >> 16) & 0xff] + | ip_maskr[6][(r_in >> 8) & 0xff] + | ip_maskr[7][r_in & 0xff]; + + while (count--) { + /* + * Do each round. + */ + kl = kl1; + kr = kr1; + round = 16; + while (round--) { + /* + * Expand R to 48 bits (simulate the E-box). + */ + r48l = ((r & 0x00000001) << 23) + | ((r & 0xf8000000) >> 9) + | ((r & 0x1f800000) >> 11) + | ((r & 0x01f80000) >> 13) + | ((r & 0x001f8000) >> 15); + + r48r = ((r & 0x0001f800) << 7) + | ((r & 0x00001f80) << 5) + | ((r & 0x000001f8) << 3) + | ((r & 0x0000001f) << 1) + | ((r & 0x80000000) >> 31); + /* + * Do XOR with the permuted key. + */ + r48l ^= *kl++; + r48r ^= *kr++; + /* + * Do sbox lookups (which shrink it back to 32 bits) + * and do the pbox permutation at the same time. + */ + f = psbox[0][m_sbox[0][r48l >> 12]] + | psbox[1][m_sbox[1][r48l & 0xfff]] + | psbox[2][m_sbox[2][r48r >> 12]] + | psbox[3][m_sbox[3][r48r & 0xfff]]; + /* + * Now that we've permuted things, complete f(). + */ + f ^= l; + l = r; + r = f; + } + r = l; + l = f; + } + /* + * Do final permutation (inverse of IP). + */ + *l_out = fp_maskl[0][l >> 24] + | fp_maskl[1][(l >> 16) & 0xff] + | fp_maskl[2][(l >> 8) & 0xff] + | fp_maskl[3][l & 0xff] + | fp_maskl[4][r >> 24] + | fp_maskl[5][(r >> 16) & 0xff] + | fp_maskl[6][(r >> 8) & 0xff] + | fp_maskl[7][r & 0xff]; + *r_out = fp_maskr[0][l >> 24] + | fp_maskr[1][(l >> 16) & 0xff] + | fp_maskr[2][(l >> 8) & 0xff] + | fp_maskr[3][l & 0xff] + | fp_maskr[4][r >> 24] + | fp_maskr[5][(r >> 16) & 0xff] + | fp_maskr[6][(r >> 8) & 0xff] + | fp_maskr[7][r & 0xff]; + return(0); +} + +int setkey(const char *key) { + int i, j; + u_int32_t packed_keys[2]; + u_char *p; + + p = (u_char *) packed_keys; + + for (i = 0; i < 8; i++) { + p[i] = 0; + for (j = 0; j < 8; j++) + if (*key++ & 1) + p[i] |= _des_bits8[j]; + } + return(des_setkey((char *)p)); +} + +int encrypt(char *block, int flag) { + u_int32_t io[2]; + u_char *p; + int i, j, retval; + + if (!_des_initialised) + _des_init(); + + p = (u_char *)block; + for (i = 0; i < 2; i++) { + io[i] = 0L; + for (j = 0; j < 32; j++) + if (*p++ & 1) + io[i] |= _des_bits32[j]; + } + retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1); + for (i = 0; i < 2; i++) + for (j = 0; j < 32; j++) + block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0; + return(retval); +} diff --git a/src/netif/ppp/des.h b/src/netif/ppp/des.h new file mode 100644 index 00000000..9ae70f6a --- /dev/null +++ b/src/netif/ppp/des.h @@ -0,0 +1,40 @@ +/** + * @file + * + * DES header + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef DES_H_ +#define DES_H_ + +int setkey(const char *key); +int encrypt(char *block, int flag); + +#endif /* DES_H_ */ diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c new file mode 100644 index 00000000..8f6bc502 --- /dev/null +++ b/src/netif/ppp/ecp.c @@ -0,0 +1,175 @@ +/* + * ecp.c - PPP Encryption Control Protocol. + * + * Copyright (c) 2002 Google, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Derived from ccp.c, which is: + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $" + +static const char rcsid[] = RCSID; + +#include + +#include "pppd.h" +#include "fsm.h" +#include "ecp.h" + +static option_t ecp_option_list[] = { + { "noecp", o_bool, &ecp_protent.enabled_flag, + "Disable ECP negotiation" }, + { "-ecp", o_bool, &ecp_protent.enabled_flag, + "Disable ECP negotiation", OPT_ALIAS }, + + { NULL } +}; + +/* + * Protocol entry points from main code. + */ +static void ecp_init __P((int unit)); +/* +static void ecp_open __P((int unit)); +static void ecp_close __P((int unit, char *)); +static void ecp_lowerup __P((int unit)); +static void ecp_lowerdown __P((int)); +static void ecp_input __P((int unit, u_char *pkt, int len)); +static void ecp_protrej __P((int unit)); +*/ +static int ecp_printpkt __P((u_char *pkt, int len, + void (*printer) __P((void *, char *, ...)), + void *arg)); +/* +static void ecp_datainput __P((int unit, u_char *pkt, int len)); +*/ + +struct protent ecp_protent = { + PPP_ECP, + ecp_init, + NULL, /* ecp_input, */ + NULL, /* ecp_protrej, */ + NULL, /* ecp_lowerup, */ + NULL, /* ecp_lowerdown, */ + NULL, /* ecp_open, */ + NULL, /* ecp_close, */ + ecp_printpkt, + NULL, /* ecp_datainput, */ + 0, + "ECP", + "Encrypted", + ecp_option_list, + NULL, + NULL, + NULL +}; + +fsm ecp_fsm[NUM_PPP]; +ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */ +ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ +ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */ +ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */ + +static fsm_callbacks ecp_callbacks = { + NULL, /* ecp_resetci, */ + NULL, /* ecp_cilen, */ + NULL, /* ecp_addci, */ + NULL, /* ecp_ackci, */ + NULL, /* ecp_nakci, */ + NULL, /* ecp_rejci, */ + NULL, /* ecp_reqci, */ + NULL, /* ecp_up, */ + NULL, /* ecp_down, */ + NULL, + NULL, + NULL, + NULL, + NULL, /* ecp_extcode, */ + "ECP" +}; + +/* + * ecp_init - initialize ECP. + */ +static void +ecp_init(unit) + int unit; +{ + fsm *f = &ecp_fsm[unit]; + + f->unit = unit; + f->protocol = PPP_ECP; + f->callbacks = &ecp_callbacks; + fsm_init(f); + + memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options)); + +} + + +static int +ecp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + return 0; +} + diff --git a/src/netif/ppp/ecp.h b/src/netif/ppp/ecp.h new file mode 100644 index 00000000..df6e3ca1 --- /dev/null +++ b/src/netif/ppp/ecp.h @@ -0,0 +1,45 @@ +/* + * ecp.h - Definitions for PPP Encryption Control Protocol. + * + * Copyright (c) 2002 Google, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ + */ + +typedef struct ecp_options { + bool required; /* Is ECP required? */ + unsigned enctype; /* Encryption type */ +} ecp_options; + +extern fsm ecp_fsm[]; +extern ecp_options ecp_wantoptions[]; +extern ecp_options ecp_gotoptions[]; +extern ecp_options ecp_allowoptions[]; +extern ecp_options ecp_hisoptions[]; + +extern struct protent ecp_protent; diff --git a/src/netif/ppp/md4.c b/src/netif/ppp/md4.c new file mode 100644 index 00000000..f0831a92 --- /dev/null +++ b/src/netif/ppp/md4.c @@ -0,0 +1,301 @@ +/* +** ******************************************************************** +** md4.c -- Implementation of MD4 Message Digest Algorithm ** +** Updated: 2/16/90 by Ronald L. Rivest ** +** (C) 1990 RSA Data Security, Inc. ** +** ******************************************************************** +*/ + +#include "lwip/opt.h" + +/* +** To use MD4: +** -- Include md4.h in your program +** -- Declare an MDstruct MD to hold the state of the digest +** computation. +** -- Initialize MD using MDbegin(&MD) +** -- For each full block (64 bytes) X you wish to process, call +** MD4Update(&MD,X,512) +** (512 is the number of bits in a full block.) +** -- For the last block (less than 64 bytes) you wish to process, +** MD4Update(&MD,X,n) +** where n is the number of bits in the partial block. A partial +** block terminates the computation, so every MD computation +** should terminate by processing a partial block, even if it +** has n = 0. +** -- The message digest is available in MD.buffer[0] ... +** MD.buffer[3]. (Least-significant byte of each word +** should be output first.) +** -- You can print out the digest using MDprint(&MD) +*/ + +/* Implementation notes: +** This implementation assumes that ints are 32-bit quantities. +*/ + +#define TRUE 1 +#define FALSE 0 + +/* Compile-time includes +*/ +#include +#include "md4.h" +#include "pppd.h" + +/* Compile-time declarations of MD4 "magic constants". +*/ +#define I0 0x67452301 /* Initial values for MD buffer */ +#define I1 0xefcdab89 +#define I2 0x98badcfe +#define I3 0x10325476 +#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ +#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ +/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 +** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. +** Table 2, page 660. +*/ + +#define fs1 3 /* round 1 shift amounts */ +#define fs2 7 +#define fs3 11 +#define fs4 19 +#define gs1 3 /* round 2 shift amounts */ +#define gs2 5 +#define gs3 9 +#define gs4 13 +#define hs1 3 /* round 3 shift amounts */ +#define hs2 9 +#define hs3 11 +#define hs4 15 + +/* Compile-time macro declarations for MD4. +** Note: The "rot" operator uses the variable "tmp". +** It assumes tmp is declared as unsigned int, so that the >> +** operator will shift in zeros rather than extending the sign bit. +*/ +#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) +#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) +#define h(X,Y,Z) (X^Y^Z) +#define rot(X,S) (tmp=X,(tmp<>(32-S))) +#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) +#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) +#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) + +/* MD4print(MDp) +** Print message digest buffer MDp as 32 hexadecimal digits. +** Order is from low-order byte of buffer[0] to high-order byte of +** buffer[3]. +** Each byte is printed with high-order hexadecimal digit first. +** This is a user-callable routine. +*/ +void +MD4Print(MDp) +MD4_CTX *MDp; +{ + int i,j; + for (i=0;i<4;i++) + for (j=0;j<32;j=j+8) + printf("%02x",(MDp->buffer[i]>>j) & 0xFF); +} + +/* MD4Init(MDp) +** Initialize message digest buffer MDp. +** This is a user-callable routine. +*/ +void +MD4Init(MDp) +MD4_CTX *MDp; +{ + int i; + MDp->buffer[0] = I0; + MDp->buffer[1] = I1; + MDp->buffer[2] = I2; + MDp->buffer[3] = I3; + for (i=0;i<8;i++) MDp->count[i] = 0; + MDp->done = 0; +} + +/* MDblock(MDp,X) +** Update message digest buffer MDp->buffer using 16-word data block X. +** Assumes all 16 words of X are full of data. +** Does not update MDp->count. +** This routine is not user-callable. +*/ +static void +MDblock(MDp,Xb) +MD4_CTX *MDp; +unsigned char *Xb; +{ + register unsigned int tmp, A, B, C, D; + unsigned int X[16]; + int i; + + for (i = 0; i < 16; ++i) { + X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); + Xb += 4; + } + + A = MDp->buffer[0]; + B = MDp->buffer[1]; + C = MDp->buffer[2]; + D = MDp->buffer[3]; + /* Update the message digest buffer */ + ff(A , B , C , D , 0 , fs1); /* Round 1 */ + ff(D , A , B , C , 1 , fs2); + ff(C , D , A , B , 2 , fs3); + ff(B , C , D , A , 3 , fs4); + ff(A , B , C , D , 4 , fs1); + ff(D , A , B , C , 5 , fs2); + ff(C , D , A , B , 6 , fs3); + ff(B , C , D , A , 7 , fs4); + ff(A , B , C , D , 8 , fs1); + ff(D , A , B , C , 9 , fs2); + ff(C , D , A , B , 10 , fs3); + ff(B , C , D , A , 11 , fs4); + ff(A , B , C , D , 12 , fs1); + ff(D , A , B , C , 13 , fs2); + ff(C , D , A , B , 14 , fs3); + ff(B , C , D , A , 15 , fs4); + gg(A , B , C , D , 0 , gs1); /* Round 2 */ + gg(D , A , B , C , 4 , gs2); + gg(C , D , A , B , 8 , gs3); + gg(B , C , D , A , 12 , gs4); + gg(A , B , C , D , 1 , gs1); + gg(D , A , B , C , 5 , gs2); + gg(C , D , A , B , 9 , gs3); + gg(B , C , D , A , 13 , gs4); + gg(A , B , C , D , 2 , gs1); + gg(D , A , B , C , 6 , gs2); + gg(C , D , A , B , 10 , gs3); + gg(B , C , D , A , 14 , gs4); + gg(A , B , C , D , 3 , gs1); + gg(D , A , B , C , 7 , gs2); + gg(C , D , A , B , 11 , gs3); + gg(B , C , D , A , 15 , gs4); + hh(A , B , C , D , 0 , hs1); /* Round 3 */ + hh(D , A , B , C , 8 , hs2); + hh(C , D , A , B , 4 , hs3); + hh(B , C , D , A , 12 , hs4); + hh(A , B , C , D , 2 , hs1); + hh(D , A , B , C , 10 , hs2); + hh(C , D , A , B , 6 , hs3); + hh(B , C , D , A , 14 , hs4); + hh(A , B , C , D , 1 , hs1); + hh(D , A , B , C , 9 , hs2); + hh(C , D , A , B , 5 , hs3); + hh(B , C , D , A , 13 , hs4); + hh(A , B , C , D , 3 , hs1); + hh(D , A , B , C , 11 , hs2); + hh(C , D , A , B , 7 , hs3); + hh(B , C , D , A , 15 , hs4); + MDp->buffer[0] += A; + MDp->buffer[1] += B; + MDp->buffer[2] += C; + MDp->buffer[3] += D; +} + +/* MD4Update(MDp,X,count) +** Input: X -- a pointer to an array of unsigned characters. +** count -- the number of bits of X to use. +** (if not a multiple of 8, uses high bits of last byte.) +** Update MDp using the number of bits of X given by count. +** This is the basic input routine for an MD4 user. +** The routine completes the MD computation when count < 512, so +** every MD computation should end with one call to MD4Update with a +** count less than 512. A call with count 0 will be ignored if the +** MD has already been terminated (done != 0), so an extra call with +** count 0 can be given as a "courtesy close" to force termination +** if desired. +*/ +void +MD4Update(MDp,X,count) +MD4_CTX *MDp; +unsigned char *X; +unsigned int count; +{ + unsigned int i, tmp, bit, byte, mask; + unsigned char XX[64]; + unsigned char *p; + + /* return with no error if this is a courtesy close with count + ** zero and MDp->done is true. + */ + if (count == 0 && MDp->done) return; + /* check to see if MD is already done and report error */ + if (MDp->done) + { printf("\nError: MD4Update MD already done."); return; } + + /* Add count to MDp->count */ + tmp = count; + p = MDp->count; + while (tmp) + { tmp += *p; + *p++ = tmp; + tmp = tmp >> 8; + } + + /* Process data */ + if (count == 512) + { /* Full block of data to handle */ + MDblock(MDp,X); + } + else if (count > 512) /* Check for count too large */ + { + printf("\nError: MD4Update called with illegal count value %d.", + count); + return; + } + else /* partial block -- must be last block so finish up */ + { + /* Find out how many bytes and residual bits there are */ + byte = count >> 3; + bit = count & 7; + /* Copy X into XX since we need to modify it */ + if (count) + for (i=0;i<=byte;i++) XX[i] = X[i]; + for (i=byte+1;i<64;i++) XX[i] = 0; + /* Add padding '1' bit and low-order zeros in last byte */ + mask = 1 << (7 - bit); + XX[byte] = (XX[byte] | mask) & ~( mask - 1); + /* If room for bit count, finish up with this block */ + if (byte <= 55) + { + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,XX); + } + else /* need to do two blocks to finish up */ + { + MDblock(MDp,XX); + for (i=0;i<56;i++) XX[i] = 0; + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,XX); + } + /* Set flag saying we're done with MD computation */ + MDp->done = 1; + } +} + +/* +** Finish up MD4 computation and return message digest. +*/ +void +MD4Final(buf, MD) +unsigned char *buf; +MD4_CTX *MD; +{ + int i, j; + unsigned int w; + + MD4Update(MD, NULL, 0); + for (i = 0; i < 4; ++i) { + w = MD->buffer[i]; + for (j = 0; j < 4; ++j) { + *buf++ = w; + w >>= 8; + } + } +} + +/* +** End of md4.c +****************************(cut)***********************************/ diff --git a/src/netif/ppp/md4.h b/src/netif/ppp/md4.h new file mode 100644 index 00000000..80e8f9a2 --- /dev/null +++ b/src/netif/ppp/md4.h @@ -0,0 +1,64 @@ + +/* +** ******************************************************************** +** md4.h -- Header file for implementation of ** +** MD4 Message Digest Algorithm ** +** Updated: 2/13/90 by Ronald L. Rivest ** +** (C) 1990 RSA Data Security, Inc. ** +** ******************************************************************** +*/ + +#ifndef __P +# if defined(__STDC__) || defined(__GNUC__) +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + + +/* MDstruct is the data structure for a message digest computation. +*/ +typedef struct { + unsigned int buffer[4]; /* Holds 4-word result of MD computation */ + unsigned char count[8]; /* Number of bits processed so far */ + unsigned int done; /* Nonzero means MD computation finished */ +} MD4_CTX; + +/* MD4Init(MD4_CTX *) +** Initialize the MD4_CTX prepatory to doing a message digest +** computation. +*/ +extern void MD4Init __P((MD4_CTX *MD)); + +/* MD4Update(MD,X,count) +** Input: X -- a pointer to an array of unsigned characters. +** count -- the number of bits of X to use (an unsigned int). +** Updates MD using the first "count" bits of X. +** The array pointed to by X is not modified. +** If count is not a multiple of 8, MD4Update uses high bits of +** last byte. +** This is the basic input routine for a user. +** The routine terminates the MD computation when count < 512, so +** every MD computation should end with one call to MD4Update with a +** count less than 512. Zero is OK for a count. +*/ +extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); + +/* MD4Print(MD) +** Prints message digest buffer MD as 32 hexadecimal digits. +** Order is from low-order byte of buffer[0] to high-order byte +** of buffer[3]. +** Each byte is printed with high-order hexadecimal digit first. +*/ +extern void MD4Print __P((MD4_CTX *)); + +/* MD4Final(buf, MD) +** Returns message digest from MD and terminates the message +** digest computation. +*/ +extern void MD4Final __P((unsigned char *, MD4_CTX *)); + +/* +** End of md4.h +****************************(cut)***********************************/ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 8364f02f..259c321a 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -107,8 +107,14 @@ #if EAP_SUPPORT #include "eap.h" #endif /* EAP_SUPPORT */ +#include "ccp.h" +#include "ecp.h" #include "pathnames.h" +#if CBCP_SUPPORT +#include "cbcp.h" +#endif + #ifdef AT_CHANGE #include "atcp.h" #endif @@ -161,6 +167,7 @@ int fd_ppp = -1; /* fd for talking PPP */ int phase; /* where the link is at */ int kill_link; int asked_to_quit; +int open_ccp_flag; int listen_time; int got_sigusr2; int got_sigterm; @@ -227,6 +234,7 @@ static void hup __P((int)); static void term __P((int)); static void chld __P((int)); static void toggle_debug __P((int)); +static void open_ccp __P((int)); static void bad_signal __P((int)); static void holdoff_end __P((void *)); static void forget_child __P((int pid, int status)); @@ -265,6 +273,8 @@ struct protent *protocols[] = { #ifdef INET6 &ipv6cp_protent, #endif + &ccp_protent, + &ecp_protent, #ifdef AT_CHANGE &atcp_protent, #endif @@ -507,6 +517,12 @@ int ppp_oldmain() { if (phase == PHASE_MASTER) mp_bundle_terminated(); } + if (open_ccp_flag) { + if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { + ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ + (*ccp_protent.open)(0); + } + } } /* restore FSMs to original state */ lcp_close(0, ""); @@ -562,7 +578,7 @@ handle_events() { struct timeval timo; - kill_link = 0; + kill_link = open_ccp_flag = 0; if (sigsetjmp(sigjmp, 1) == 0) { sigprocmask(SIG_BLOCK, &signals_handled, NULL); if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) { @@ -594,6 +610,10 @@ handle_events() got_sigchld = 0; reap_kids(); /* Don't leave dead kids lying around */ } + if (got_sigusr2) { + open_ccp_flag = 1; + got_sigusr2 = 0; + } } /* @@ -630,6 +650,7 @@ setup_signals() SIGNAL(SIGCHLD, chld); SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ + SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ /* * Install a handler for other signals which would otherwise @@ -1438,6 +1459,23 @@ toggle_debug(sig) } } + +/* + * open_ccp - Catch SIGUSR2 signal. + * + * Try to (re)negotiate compression. + */ +/*ARGSUSED*/ +static void +open_ccp(sig) + int sig; +{ + got_sigusr2 = 1; + if (waiting) + siglongjmp(sigjmp, 1); +} + + /* * bad_signal - We've caught a fatal signal. Clean up state and exit. */ diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c new file mode 100644 index 00000000..d4c48429 --- /dev/null +++ b/src/netif/ppp/pppcrypt.c @@ -0,0 +1,146 @@ +/* + * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 + * + * Extracted from chap_ms.c by James Carlson. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" + +#include "pppd.h" +#include "pppcrypt.h" +#include "des.h" + +static u_char +Get7Bits(input, startBit) +u_char *input; +int startBit; +{ + unsigned int word; + + word = (unsigned)input[startBit / 8] << 8; + word |= (unsigned)input[startBit / 8 + 1]; + + word >>= 15 - (startBit % 8 + 7); + + return word & 0xFE; +} + +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); +} + +/* + * 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; + } +} + +bool +DesSetkey(key) +u_char *key; +{ + u_char des_key[8]; + u_char crypt_key[66]; + + MakeKey(key, des_key); + Expand(des_key, crypt_key); + setkey((const char *)crypt_key); + return (1); +} + +bool +DesEncrypt(clear, cipher) +u_char *clear; /* IN 8 octets */ +u_char *cipher; /* OUT 8 octets */ +{ + u_char des_input[66]; + + Expand(clear, des_input); + encrypt((char *)des_input, 0); + Collapse(des_input, cipher); + return (1); +} + +bool +DesDecrypt(cipher, clear) +u_char *cipher; /* IN 8 octets */ +u_char *clear; /* OUT 8 octets */ +{ + u_char des_input[66]; + + Expand(cipher, des_input); + encrypt((char *)des_input, 1); + Collapse(des_input, clear); + return (1); +} diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h new file mode 100644 index 00000000..d5deccd0 --- /dev/null +++ b/src/netif/ppp/pppcrypt.h @@ -0,0 +1,40 @@ +/* + * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 + * + * Extracted from chap_ms.c by James Carlson. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef PPPCRYPT_H +#define PPPCRYPT_H + +extern bool DesSetkey __P((u_char *)); +extern bool DesEncrypt __P((u_char *, u_char *)); +extern bool DesDecrypt __P((u_char *, u_char *)); + +#endif /* PPPCRYPT_H */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index ec36cc1b..add22efe 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -529,6 +529,7 @@ void link_down __P((int)); /* the LCP layer has left the Opened state */ void upper_layers_down __P((int));/* take all NCPs down */ void link_established __P((int)); /* the link is up; authenticate now */ void start_networks __P((int)); /* start all the network control protos */ +void continue_networks __P((int)); /* start network [ip, etc] control protos */ void np_up __P((int, int)); /* a network protocol has come up */ void np_down __P((int, int)); /* a network protocol has gone down */ void np_finished __P((int, int)); /* a network protocol no longer needs link */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 06009361..c0b20570 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -436,10 +436,14 @@ void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { ppp_settings.refuse_pap = 1; - ppp_settings.refuse_chap = 0; + ppp_settings.refuse_chap = 1; + ppp_settings.refuse_mschap = 1; + ppp_settings.refuse_mschap_v2 = 0; #if EAP_SUPPORT ppp_settings.refuse_pap = 1; ppp_settings.refuse_chap = 1; + ppp_settings.refuse_mschap = 1; + ppp_settings.refuse_mschap_v2 = 1; ppp_settings.refuse_eap = 0; #endif /* EAP_SUPPORT */ diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index a7eb11b4..042410df 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -46,6 +46,8 @@ struct ppp_settings { u_int explicit_remote : 1; /* remote_name specified with remotename opt */ u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ + u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ + u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #if EAP_SUPPORT u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ #endif /* EAP_SUPPORT */ diff --git a/src/netif/ppp/sha1.c b/src/netif/ppp/sha1.c new file mode 100644 index 00000000..3b020b8f --- /dev/null +++ b/src/netif/ppp/sha1.c @@ -0,0 +1,172 @@ +/* + * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c + * + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + * + * Test Vectors (from FIPS PUB 180-1) + * "abc" + * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + * A million repetitions of "a" + * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F + */ + +#include "lwip/opt.h" + +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#include +#include /* htonl() */ +#include +#include "sha1.h" + +static void +SHA1_Transform(u_int32_t[5], const unsigned char[64]); + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#define blk0(i) (block->l[i] = htonl(block->l[i])) +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +static void +SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64]) +{ + u_int32_t a, b, c, d, e; + typedef union { + unsigned char c[64]; + u_int32_t l[16]; + } CHAR64LONG16; + CHAR64LONG16 *block; + +#ifdef SHA1HANDSOFF + static unsigned char workspace[64]; + block = (CHAR64LONG16 *) workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16 *) buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void +SHA1_Init(SHA1_CTX *context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void +SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) +{ + unsigned int i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + i = 64 - j; + while (len >= i) { + memcpy(&context->buffer[j], data, i); + SHA1_Transform(context->state, context->buffer); + data += i; + len -= i; + i = 64; + j = 0; + } + + memcpy(&context->buffer[j], data, len); +} + + +/* Add padding and return the message digest. */ + +void +SHA1_Final(unsigned char digest[20], SHA1_CTX *context) +{ + u_int32_t i, j; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1_Update(context, (unsigned char *) "\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1_Update(context, (unsigned char *) "\0", 1); + } + SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = j = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ + SHA1Transform(context->state, context->buffer); +#endif +} + diff --git a/src/netif/ppp/sha1.h b/src/netif/ppp/sha1.h new file mode 100644 index 00000000..83f64df2 --- /dev/null +++ b/src/netif/ppp/sha1.h @@ -0,0 +1,31 @@ +/* sha1.h */ + +/* If OpenSSL is in use, then use that version of SHA-1 */ +#ifdef OPENSSL +#include +#define __SHA1_INCLUDE_ +#endif + +#ifndef __SHA1_INCLUDE_ + +#ifndef SHA1_SIGNATURE_SIZE +#ifdef SHA_DIGESTSIZE +#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE +#else +#define SHA1_SIGNATURE_SIZE 20 +#endif +#endif + +typedef struct { + u_int32_t state[5]; + u_int32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +extern void SHA1_Init(SHA1_CTX *); +extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int); +extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *); + +#define __SHA1_INCLUDE_ +#endif /* __SHA1_INCLUDE_ */ + From 82b67b01ffc8d3c31013f269489f7830713490f1 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 22:14:02 +0200 Subject: [PATCH 034/320] Revert "removed salted DES ( known as crypt() function ), we don't need it" This reverts commit 517659640e90ad95338518bac876e53b905f8e5b. --- src/netif/ppp/des.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/des.c b/src/netif/ppp/des.c index 123c1978..56b4f3e7 100644 --- a/src/netif/ppp/des.c +++ b/src/netif/ppp/des.c @@ -47,10 +47,19 @@ */ #include "lwip/opt.h" -/* FIXME: don't build if not necessary */ #include "lwip/def.h" +#include +#include +#include +#include +#include + +#ifdef DEBUG +# include +#endif + static const u_char IP[64] = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, @@ -155,6 +164,8 @@ const u_int32_t _des_bits32[32] = const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; +static u_int32_t saltbits; +static int32_t old_salt; static const u_int32_t *bits28, *bits24; static u_char init_perm[64], final_perm[64]; static u_int32_t en_keysl[16], en_keysr[16]; @@ -175,6 +186,8 @@ _des_init(void) u_int32_t *p, *il, *ir, *fl, *fr; old_rawkey0 = old_rawkey1 = 0; + saltbits = 0; + old_salt = 0; bits24 = (bits28 = _des_bits32 + 4) + 4; /* @@ -447,10 +460,12 @@ _des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, | ((r & 0x0000001f) << 1) | ((r & 0x80000000) >> 31); /* - * Do XOR with the permuted key. + * Do salting for crypt() and friends, and + * XOR with the permuted key. */ - r48l ^= *kl++; - r48r ^= *kr++; + f = (r48l ^ r48r) & saltbits; + r48l ^= f ^ *kl++; + r48r ^= f ^ *kr++; /* * Do sbox lookups (which shrink it back to 32 bits) * and do the pbox permutation at the same time. @@ -515,6 +530,7 @@ int encrypt(char *block, int flag) { if (!_des_initialised) _des_init(); + //_des_setup_salt(0); p = (u_char *)block; for (i = 0; i < 2; i++) { io[i] = 0L; From a7a20a9de42a129600aaf5f0a1dceb4f69c65b5f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 22:14:13 +0200 Subject: [PATCH 035/320] Revert "now using OpenBSD DES implementation" This reverts commit a9672e1a21882a144f12f01d182d3e469074b54c. --- src/netif/ppp/des.c | 546 --------------------------------------- src/netif/ppp/des.h | 40 --- src/netif/ppp/pppcrypt.c | 51 +++- src/netif/ppp/pppcrypt.h | 8 + 4 files changed, 58 insertions(+), 587 deletions(-) delete mode 100644 src/netif/ppp/des.c delete mode 100644 src/netif/ppp/des.h diff --git a/src/netif/ppp/des.c b/src/netif/ppp/des.c deleted file mode 100644 index 56b4f3e7..00000000 --- a/src/netif/ppp/des.c +++ /dev/null @@ -1,546 +0,0 @@ -/* $OpenBSD: crypt.c,v 1.20 2005/08/08 08:05:33 espie Exp $ */ - -/* - * FreeSec: libcrypt - * - * Copyright (c) 1994 David Burren - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the author nor the names of other contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - * This is an original implementation of the DES and the crypt(3) interfaces - * by David Burren . - * - * An excellent reference on the underlying algorithm (and related - * algorithms) is: - * - * B. Schneier, Applied Cryptography: protocols, algorithms, - * and source code in C, John Wiley & Sons, 1994. - * - * Note that in that book's description of DES the lookups for the initial, - * pbox, and final permutations are inverted (this has been brought to the - * attention of the author). A list of errata for this book has been - * posted to the sci.crypt newsgroup by the author and is available for FTP. - */ - -#include "lwip/opt.h" - -#include "lwip/def.h" - -#include -#include -#include -#include -#include - -#ifdef DEBUG -# include -#endif - -static const u_char IP[64] = { - 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 -}; - -static u_char inv_key_perm[64]; -static u_char u_key_perm[56]; -static u_char const key_perm[56] = { - 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 -}; - -static const u_char key_shifts[16] = { - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 -}; - -static u_char inv_comp_perm[56]; -static const u_char comp_perm[48] = { - 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 -}; - -/* - * No E box is used, as it's replaced by some ANDs, shifts, and ORs. - */ - -static u_char u_sbox[8][64]; -static const u_char sbox[8][64] = { - { - 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 - }, - { - 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 - }, - { - 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 - }, - { - 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 - }, - { - 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 - }, - { - 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 - }, - { - 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 - }, - { - 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 - } -}; - -static u_char un_pbox[32]; -static const u_char pbox[32] = { - 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, - 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 -}; - -const u_int32_t _des_bits32[32] = -{ - 0x80000000, 0x40000000, 0x20000000, 0x10000000, - 0x08000000, 0x04000000, 0x02000000, 0x01000000, - 0x00800000, 0x00400000, 0x00200000, 0x00100000, - 0x00080000, 0x00040000, 0x00020000, 0x00010000, - 0x00008000, 0x00004000, 0x00002000, 0x00001000, - 0x00000800, 0x00000400, 0x00000200, 0x00000100, - 0x00000080, 0x00000040, 0x00000020, 0x00000010, - 0x00000008, 0x00000004, 0x00000002, 0x00000001 -}; - -const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; - -static u_int32_t saltbits; -static int32_t old_salt; -static const u_int32_t *bits28, *bits24; -static u_char init_perm[64], final_perm[64]; -static u_int32_t en_keysl[16], en_keysr[16]; -static u_int32_t de_keysl[16], de_keysr[16]; -int _des_initialised = 0; -static u_char m_sbox[4][4096]; -static u_int32_t psbox[4][256]; -static u_int32_t ip_maskl[8][256], ip_maskr[8][256]; -static u_int32_t fp_maskl[8][256], fp_maskr[8][256]; -static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; -static u_int32_t comp_maskl[8][128], comp_maskr[8][128]; -static u_int32_t old_rawkey0, old_rawkey1; - -void -_des_init(void) -{ - int i, j, b, k, inbit, obit; - u_int32_t *p, *il, *ir, *fl, *fr; - - old_rawkey0 = old_rawkey1 = 0; - saltbits = 0; - old_salt = 0; - bits24 = (bits28 = _des_bits32 + 4) + 4; - - /* - * Invert the S-boxes, reordering the input bits. - */ - for (i = 0; i < 8; i++) - for (j = 0; j < 64; j++) { - b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); - u_sbox[i][j] = sbox[i][b]; - } - - /* - * Convert the inverted S-boxes into 4 arrays of 8 bits. - * Each will handle 12 bits of the S-box input. - */ - for (b = 0; b < 4; b++) - for (i = 0; i < 64; i++) - for (j = 0; j < 64; j++) - m_sbox[b][(i << 6) | j] = - (u_sbox[(b << 1)][i] << 4) | - u_sbox[(b << 1) + 1][j]; - - /* - * Set up the initial & final permutations into a useful form, and - * initialise the inverted key permutation. - */ - for (i = 0; i < 64; i++) { - init_perm[final_perm[i] = IP[i] - 1] = i; - inv_key_perm[i] = 255; - } - - /* - * Invert the key permutation and initialise the inverted key - * compression permutation. - */ - for (i = 0; i < 56; i++) { - u_key_perm[i] = key_perm[i] - 1; - inv_key_perm[key_perm[i] - 1] = i; - inv_comp_perm[i] = 255; - } - - /* - * Invert the key compression permutation. - */ - for (i = 0; i < 48; i++) { - inv_comp_perm[comp_perm[i] - 1] = i; - } - - /* - * Set up the OR-mask arrays for the initial and final permutations, - * and for the key initial and compression permutations. - */ - for (k = 0; k < 8; k++) { - for (i = 0; i < 256; i++) { - *(il = &ip_maskl[k][i]) = 0; - *(ir = &ip_maskr[k][i]) = 0; - *(fl = &fp_maskl[k][i]) = 0; - *(fr = &fp_maskr[k][i]) = 0; - for (j = 0; j < 8; j++) { - inbit = 8 * k + j; - if (i & _des_bits8[j]) { - if ((obit = init_perm[inbit]) < 32) - *il |= _des_bits32[obit]; - else - *ir |= _des_bits32[obit-32]; - if ((obit = final_perm[inbit]) < 32) - *fl |= _des_bits32[obit]; - else - *fr |= _des_bits32[obit - 32]; - } - } - } - for (i = 0; i < 128; i++) { - *(il = &key_perm_maskl[k][i]) = 0; - *(ir = &key_perm_maskr[k][i]) = 0; - for (j = 0; j < 7; j++) { - inbit = 8 * k + j; - if (i & _des_bits8[j + 1]) { - if ((obit = inv_key_perm[inbit]) == 255) - continue; - if (obit < 28) - *il |= bits28[obit]; - else - *ir |= bits28[obit - 28]; - } - } - *(il = &comp_maskl[k][i]) = 0; - *(ir = &comp_maskr[k][i]) = 0; - for (j = 0; j < 7; j++) { - inbit = 7 * k + j; - if (i & _des_bits8[j + 1]) { - if ((obit=inv_comp_perm[inbit]) == 255) - continue; - if (obit < 24) - *il |= bits24[obit]; - else - *ir |= bits24[obit - 24]; - } - } - } - } - - /* - * Invert the P-box permutation, and convert into OR-masks for - * handling the output of the S-box arrays setup above. - */ - for (i = 0; i < 32; i++) - un_pbox[pbox[i] - 1] = i; - - for (b = 0; b < 4; b++) - for (i = 0; i < 256; i++) { - *(p = &psbox[b][i]) = 0; - for (j = 0; j < 8; j++) { - if (i & _des_bits8[j]) - *p |= _des_bits32[un_pbox[8 * b + j]]; - } - } - - _des_initialised = 1; -} - -int -des_setkey(const char *key) -{ - u_int32_t k0, k1, rawkey0, rawkey1; - int shifts, round; - - if (!_des_initialised) - _des_init(); - - rawkey0 = ntohl(*(u_int32_t *) key); - rawkey1 = ntohl(*(u_int32_t *) (key + 4)); - - if ((rawkey0 | rawkey1) - && rawkey0 == old_rawkey0 - && rawkey1 == old_rawkey1) { - /* - * Already setup for this key. - * This optimisation fails on a zero key (which is weak and - * has bad parity anyway) in order to simplify the starting - * conditions. - */ - return(0); - } - old_rawkey0 = rawkey0; - old_rawkey1 = rawkey1; - - /* - * Do key permutation and split into two 28-bit subkeys. - */ - k0 = key_perm_maskl[0][rawkey0 >> 25] - | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] - | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] - | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] - | key_perm_maskl[4][rawkey1 >> 25] - | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] - | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] - | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; - k1 = key_perm_maskr[0][rawkey0 >> 25] - | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] - | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] - | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] - | key_perm_maskr[4][rawkey1 >> 25] - | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] - | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] - | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; - /* - * Rotate subkeys and do compression permutation. - */ - shifts = 0; - for (round = 0; round < 16; round++) { - u_int32_t t0, t1; - - shifts += key_shifts[round]; - - t0 = (k0 << shifts) | (k0 >> (28 - shifts)); - t1 = (k1 << shifts) | (k1 >> (28 - shifts)); - - de_keysl[15 - round] = - en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] - | comp_maskl[1][(t0 >> 14) & 0x7f] - | comp_maskl[2][(t0 >> 7) & 0x7f] - | comp_maskl[3][t0 & 0x7f] - | comp_maskl[4][(t1 >> 21) & 0x7f] - | comp_maskl[5][(t1 >> 14) & 0x7f] - | comp_maskl[6][(t1 >> 7) & 0x7f] - | comp_maskl[7][t1 & 0x7f]; - - de_keysr[15 - round] = - en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f] - | comp_maskr[1][(t0 >> 14) & 0x7f] - | comp_maskr[2][(t0 >> 7) & 0x7f] - | comp_maskr[3][t0 & 0x7f] - | comp_maskr[4][(t1 >> 21) & 0x7f] - | comp_maskr[5][(t1 >> 14) & 0x7f] - | comp_maskr[6][(t1 >> 7) & 0x7f] - | comp_maskr[7][t1 & 0x7f]; - } - return(0); -} - -int -_des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, - int count) -{ - /* - * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. - */ - u_int32_t l, r, *kl, *kr, *kl1, *kr1; - u_int32_t f, r48l, r48r; - int round; - - if (count == 0) { - return(1); - } else if (count > 0) { - /* - * Encrypting - */ - kl1 = en_keysl; - kr1 = en_keysr; - } else { - /* - * Decrypting - */ - count = -count; - kl1 = de_keysl; - kr1 = de_keysr; - } - - /* - * Do initial permutation (IP). - */ - l = ip_maskl[0][l_in >> 24] - | ip_maskl[1][(l_in >> 16) & 0xff] - | ip_maskl[2][(l_in >> 8) & 0xff] - | ip_maskl[3][l_in & 0xff] - | ip_maskl[4][r_in >> 24] - | ip_maskl[5][(r_in >> 16) & 0xff] - | ip_maskl[6][(r_in >> 8) & 0xff] - | ip_maskl[7][r_in & 0xff]; - r = ip_maskr[0][l_in >> 24] - | ip_maskr[1][(l_in >> 16) & 0xff] - | ip_maskr[2][(l_in >> 8) & 0xff] - | ip_maskr[3][l_in & 0xff] - | ip_maskr[4][r_in >> 24] - | ip_maskr[5][(r_in >> 16) & 0xff] - | ip_maskr[6][(r_in >> 8) & 0xff] - | ip_maskr[7][r_in & 0xff]; - - while (count--) { - /* - * Do each round. - */ - kl = kl1; - kr = kr1; - round = 16; - while (round--) { - /* - * Expand R to 48 bits (simulate the E-box). - */ - r48l = ((r & 0x00000001) << 23) - | ((r & 0xf8000000) >> 9) - | ((r & 0x1f800000) >> 11) - | ((r & 0x01f80000) >> 13) - | ((r & 0x001f8000) >> 15); - - r48r = ((r & 0x0001f800) << 7) - | ((r & 0x00001f80) << 5) - | ((r & 0x000001f8) << 3) - | ((r & 0x0000001f) << 1) - | ((r & 0x80000000) >> 31); - /* - * Do salting for crypt() and friends, and - * XOR with the permuted key. - */ - f = (r48l ^ r48r) & saltbits; - r48l ^= f ^ *kl++; - r48r ^= f ^ *kr++; - /* - * Do sbox lookups (which shrink it back to 32 bits) - * and do the pbox permutation at the same time. - */ - f = psbox[0][m_sbox[0][r48l >> 12]] - | psbox[1][m_sbox[1][r48l & 0xfff]] - | psbox[2][m_sbox[2][r48r >> 12]] - | psbox[3][m_sbox[3][r48r & 0xfff]]; - /* - * Now that we've permuted things, complete f(). - */ - f ^= l; - l = r; - r = f; - } - r = l; - l = f; - } - /* - * Do final permutation (inverse of IP). - */ - *l_out = fp_maskl[0][l >> 24] - | fp_maskl[1][(l >> 16) & 0xff] - | fp_maskl[2][(l >> 8) & 0xff] - | fp_maskl[3][l & 0xff] - | fp_maskl[4][r >> 24] - | fp_maskl[5][(r >> 16) & 0xff] - | fp_maskl[6][(r >> 8) & 0xff] - | fp_maskl[7][r & 0xff]; - *r_out = fp_maskr[0][l >> 24] - | fp_maskr[1][(l >> 16) & 0xff] - | fp_maskr[2][(l >> 8) & 0xff] - | fp_maskr[3][l & 0xff] - | fp_maskr[4][r >> 24] - | fp_maskr[5][(r >> 16) & 0xff] - | fp_maskr[6][(r >> 8) & 0xff] - | fp_maskr[7][r & 0xff]; - return(0); -} - -int setkey(const char *key) { - int i, j; - u_int32_t packed_keys[2]; - u_char *p; - - p = (u_char *) packed_keys; - - for (i = 0; i < 8; i++) { - p[i] = 0; - for (j = 0; j < 8; j++) - if (*key++ & 1) - p[i] |= _des_bits8[j]; - } - return(des_setkey((char *)p)); -} - -int encrypt(char *block, int flag) { - u_int32_t io[2]; - u_char *p; - int i, j, retval; - - if (!_des_initialised) - _des_init(); - - //_des_setup_salt(0); - p = (u_char *)block; - for (i = 0; i < 2; i++) { - io[i] = 0L; - for (j = 0; j < 32; j++) - if (*p++ & 1) - io[i] |= _des_bits32[j]; - } - retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1); - for (i = 0; i < 2; i++) - for (j = 0; j < 32; j++) - block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0; - return(retval); -} diff --git a/src/netif/ppp/des.h b/src/netif/ppp/des.h deleted file mode 100644 index 9ae70f6a..00000000 --- a/src/netif/ppp/des.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file - * - * DES header - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef DES_H_ -#define DES_H_ - -int setkey(const char *key); -int encrypt(char *block, int flag); - -#endif /* DES_H_ */ diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index d4c48429..1a66f680 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -32,9 +32,9 @@ #include "lwip/opt.h" +#include #include "pppd.h" #include "pppcrypt.h" -#include "des.h" static u_char Get7Bits(input, startBit) @@ -64,8 +64,13 @@ u_char *des_key; /* OUT 64 bit DES key with parity bits added */ 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 } +#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 @@ -115,7 +120,10 @@ u_char *key; MakeKey(key, des_key); Expand(des_key, crypt_key); + errno = 0; setkey((const char *)crypt_key); + if (errno != 0) + return (0); return (1); } @@ -127,7 +135,10 @@ u_char *cipher; /* OUT 8 octets */ u_char des_input[66]; Expand(clear, des_input); + errno = 0; encrypt((char *)des_input, 0); + if (errno != 0) + return (0); Collapse(des_input, cipher); return (1); } @@ -140,7 +151,45 @@ u_char *clear; /* OUT 8 octets */ u_char des_input[66]; Expand(cipher, des_input); + errno = 0; encrypt((char *)des_input, 1); + if (errno != 0) + return (0); Collapse(des_input, clear); return (1); } + +#else /* USE_CRYPT */ +static des_key_schedule key_schedule; + +bool +DesSetkey(key) +u_char *key; +{ + des_cblock des_key; + MakeKey(key, des_key); + des_set_key(&des_key, key_schedule); + return (1); +} + +bool +DesEncrypt(clear, key, cipher) +u_char *clear; /* IN 8 octets */ +u_char *cipher; /* OUT 8 octets */ +{ + des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, + key_schedule, 1); + return (1); +} + +bool +DesDecrypt(cipher, clear) +u_char *cipher; /* IN 8 octets */ +u_char *clear; /* OUT 8 octets */ +{ + des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, + key_schedule, 0); + return (1); +} + +#endif /* USE_CRYPT */ diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h index d5deccd0..adcdcbcb 100644 --- a/src/netif/ppp/pppcrypt.h +++ b/src/netif/ppp/pppcrypt.h @@ -33,6 +33,14 @@ #ifndef PPPCRYPT_H #define PPPCRYPT_H +#ifdef HAVE_CRYPT_H +#include +#endif + +#ifndef USE_CRYPT +#include +#endif + extern bool DesSetkey __P((u_char *)); extern bool DesEncrypt __P((u_char *, u_char *)); extern bool DesDecrypt __P((u_char *, u_char *)); From 83a48dafeac95de38be7ded7ae714d564d917ff9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 22:14:29 +0200 Subject: [PATCH 036/320] Revert "Revert "Replaced md4/md5/sha1 implementations to PolarSSL ones"" This reverts commit ca2fd867b8e6b92ab4338c504e5b9567ab76e414. --- src/netif/ppp/chap-md5.c | 26 +-- src/netif/ppp/chap_ms.c | 97 +++++----- src/netif/ppp/eap.c | 26 +-- src/netif/ppp/magic.c | 24 +-- src/netif/ppp/md4.c | 301 ------------------------------- src/netif/ppp/md4.h | 64 ------- src/netif/ppp/md5.c | 309 -------------------------------- src/netif/ppp/md5.h | 65 ------- src/netif/ppp/polarssl/md4.c | 271 ++++++++++++++++++++++++++++ src/netif/ppp/polarssl/md4.h | 82 +++++++++ src/netif/ppp/polarssl/md5.c | 290 ++++++++++++++++++++++++++++++ src/netif/ppp/polarssl/md5.h | 82 +++++++++ src/netif/ppp/polarssl/sha1.c | 325 ++++++++++++++++++++++++++++++++++ src/netif/ppp/polarssl/sha1.h | 82 +++++++++ src/netif/ppp/sha1.c | 172 ------------------ src/netif/ppp/sha1.h | 31 ---- 16 files changed, 1219 insertions(+), 1028 deletions(-) delete mode 100644 src/netif/ppp/md4.c delete mode 100644 src/netif/ppp/md4.h delete mode 100644 src/netif/ppp/md5.c delete mode 100644 src/netif/ppp/md5.h create mode 100644 src/netif/ppp/polarssl/md4.c create mode 100644 src/netif/ppp/polarssl/md4.h create mode 100644 src/netif/ppp/polarssl/md5.c create mode 100644 src/netif/ppp/polarssl/md5.h create mode 100644 src/netif/ppp/polarssl/sha1.c create mode 100644 src/netif/ppp/polarssl/sha1.h delete mode 100644 src/netif/ppp/sha1.c delete mode 100644 src/netif/ppp/sha1.h diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 513fe430..dec34cfd 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -38,7 +38,7 @@ #include "chap-new.h" #include "chap-md5.h" #include "magic.h" -#include "md5.h" +#include "polarssl/md5.h" #define MD5_HASH_SIZE 16 #define MD5_MIN_CHALLENGE 16 @@ -61,7 +61,7 @@ chap_md5_verify_response(int id, char *name, unsigned char *challenge, unsigned char *response, char *message, int message_space) { - MD5_CTX ctx; + md5_context ctx; unsigned char idbyte = id; unsigned char hash[MD5_HASH_SIZE]; int challenge_len, response_len; @@ -70,11 +70,11 @@ chap_md5_verify_response(int id, char *name, response_len = *response++; if (response_len == MD5_HASH_SIZE) { /* Generate hash of ID, secret, challenge */ - MD5_Init(&ctx); - MD5_Update(&ctx, &idbyte, 1); - MD5_Update(&ctx, secret, secret_len); - MD5_Update(&ctx, challenge, challenge_len); - MD5_Final(hash, &ctx); + md5_starts(&ctx); + md5_update(&ctx, &idbyte, 1); + md5_update(&ctx, secret, secret_len); + md5_update(&ctx, challenge, challenge_len); + md5_finish(&ctx, hash); /* Test if our hash matches the peer's response */ if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { @@ -91,15 +91,15 @@ chap_md5_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { - MD5_CTX ctx; + md5_context ctx; unsigned char idbyte = id; int challenge_len = *challenge++; - MD5_Init(&ctx); - MD5_Update(&ctx, &idbyte, 1); - MD5_Update(&ctx, (u_char *)secret, secret_len); - MD5_Update(&ctx, challenge, challenge_len); - MD5_Final(&response[1], &ctx); + md5_starts(&ctx); + md5_update(&ctx, &idbyte, 1); + md5_update(&ctx, (u_char *)secret, secret_len); + md5_update(&ctx, challenge, challenge_len); + md5_finish(&ctx, &response[1]); response[0] = MD5_HASH_SIZE; } diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 0d3b5347..9efa2066 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -91,13 +91,14 @@ #include "pppd.h" #include "chap-new.h" #include "chap_ms.h" -#include "md4.h" -#include "sha1.h" +#include "polarssl/md4.h" +#include "polarssl/sha1.h" #include "pppcrypt.h" #include "magic.h" static const char rcsid[] = RCSID; +#define SHA1_SIGNATURE_SIZE 20 static void ascii2unicode __P((char[], int, u_char[])); static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); @@ -472,7 +473,7 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, char *username, u_char Challenge[8]) { - SHA1_CTX sha1Context; + sha1_context sha1Context; u_char sha1Hash[SHA1_SIGNATURE_SIZE]; char *user; @@ -482,11 +483,11 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, else user = username; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PeerChallenge, 16); - SHA1_Update(&sha1Context, rchallenge, 16); - SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user)); - SHA1_Final(sha1Hash, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PeerChallenge, 16); + sha1_update(&sha1Context, rchallenge, 16); + sha1_update(&sha1Context, (unsigned char *)user, strlen(user)); + sha1_finish(&sha1Context, sha1Hash); BCOPY(sha1Hash, Challenge, 8); } @@ -517,17 +518,17 @@ NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) #else int mdlen = secret_len * 8; #endif - MD4_CTX md4Context; + md4_context md4Context; - MD4Init(&md4Context); + md4_starts(&md4Context); /* MD4Update can take at most 64 bytes at a time */ while (mdlen > 512) { - MD4Update(&md4Context, secret, 512); + md4_update(&md4Context, secret, 512); secret += 64; mdlen -= 512; } - MD4Update(&md4Context, secret, mdlen); - MD4Final(hash, &md4Context); + md4_update(&md4Context, secret, mdlen); + md4_finish(&md4Context, hash); } @@ -608,23 +609,23 @@ GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], 0x6E }; int i; - SHA1_CTX sha1Context; + sha1_context sha1Context; u_char Digest[SHA1_SIGNATURE_SIZE]; u_char Challenge[8]; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, NTResponse, 24); - SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, NTResponse, 24); + sha1_update(&sha1Context, Magic1, sizeof(Magic1)); + sha1_finish(&sha1Context, Digest); ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, Digest, sizeof(Digest)); - SHA1_Update(&sha1Context, Challenge, sizeof(Challenge)); - SHA1_Update(&sha1Context, Magic2, sizeof(Magic2)); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, Digest, sizeof(Digest)); + sha1_update(&sha1Context, Challenge, sizeof(Challenge)); + sha1_update(&sha1Context, Magic2, sizeof(Magic2)); + sha1_finish(&sha1Context, Digest); /* Convert to ASCII hex string. */ for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) @@ -662,14 +663,14 @@ GenerateAuthenticatorResponsePlain void mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) { - SHA1_CTX sha1Context; + sha1_context sha1Context; u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, rchallenge, 8); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, rchallenge, 8); + sha1_finish(&sha1Context, Digest); /* Same key in both directions. */ BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); @@ -706,7 +707,7 @@ void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], int IsServer) { - SHA1_CTX sha1Context; + sha1_context sha1Context; u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ @@ -752,11 +753,11 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], 0x6b, 0x65, 0x79, 0x2e }; u_char *s; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - SHA1_Update(&sha1Context, NTResponse, 24); - SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); - SHA1_Final(MasterKey, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, NTResponse, 24); + sha1_update(&sha1Context, Magic1, sizeof(Magic1)); + sha1_finish(&sha1Context, MasterKey); /* * generate send key @@ -765,12 +766,12 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], s = Magic3; else s = Magic2; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, MasterKey, 16); - SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); - SHA1_Update(&sha1Context, s, 84); - SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, MasterKey, 16); + sha1_update(&sha1Context, SHApad1, sizeof(SHApad1)); + sha1_update(&sha1Context, s, 84); + sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); + sha1_finish(&sha1Context, Digest); BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); @@ -781,12 +782,12 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], s = Magic2; else s = Magic3; - SHA1_Init(&sha1Context); - SHA1_Update(&sha1Context, MasterKey, 16); - SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1)); - SHA1_Update(&sha1Context, s, 84); - SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2)); - SHA1_Final(Digest, &sha1Context); + sha1_starts(&sha1Context); + sha1_update(&sha1Context, MasterKey, 16); + sha1_update(&sha1Context, SHApad1, sizeof(SHApad1)); + sha1_update(&sha1Context, s, 84); + sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); + sha1_finish(&sha1Context, Digest); BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index ecbcf046..dc2a5285 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -48,7 +48,7 @@ #include "pppd.h" #include "pathnames.h" -#include "md5.h" +#include "polarssl/md5.h" #include "eap.h" #ifdef USE_SRP @@ -1304,7 +1304,7 @@ int len; int secret_len; char secret[MAXWORDLEN]; char rhostname[256]; - MD5_CTX mdContext; + md5_context mdContext; u_char hash[MD5_SIGNATURE_SIZE]; #ifdef USE_SRP struct t_client *tc; @@ -1431,13 +1431,13 @@ int len; eap_send_nak(esp, id, EAPT_SRP); break; } - MD5_Init(&mdContext); + md5_starts(&mdContext); typenum = id; - MD5_Update(&mdContext, &typenum, 1); - MD5_Update(&mdContext, (u_char *)secret, secret_len); + md5_update(&mdContext, &typenum, 1); + md5_update(&mdContext, (u_char *)secret, secret_len); BZERO(secret, sizeof (secret)); - MD5_Update(&mdContext, inp, vallen); - MD5_Final(hash, &mdContext); + md5_update(&mdContext, inp, vallen); + md5_finish(&mdContext, hash); eap_chap_response(esp, id, hash, esp->es_client.ea_name, esp->es_client.ea_namelen); break; @@ -1714,7 +1714,7 @@ int len; int secret_len; char secret[MAXSECRETLEN]; char rhostname[256]; - MD5_CTX mdContext; + md5_context mdContext; u_char hash[MD5_SIGNATURE_SIZE]; #ifdef USE_SRP struct t_server *ts; @@ -1857,12 +1857,12 @@ int len; eap_send_failure(esp); break; } - MD5_Init(&mdContext); - MD5_Update(&mdContext, &esp->es_server.ea_id, 1); - MD5_Update(&mdContext, (u_char *)secret, secret_len); + md5_starts(&mdContext); + md5_update(&mdContext, &esp->es_server.ea_id, 1); + md5_update(&mdContext, (u_char *)secret, secret_len); BZERO(secret, sizeof (secret)); - MD5_Update(&mdContext, esp->es_challenge, esp->es_challen); - MD5_Final(hash, &mdContext); + md5_update(&mdContext, esp->es_challenge, esp->es_challen); + md5_finish(&mdContext, hash); if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { eap_send_failure(esp); break; diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 2360ecc8..de65a96e 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -76,7 +76,7 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "md5.h" +#include "polarssl/md5.h" #include "magic.h" #include "pppd.h" #include "pppmy.h" @@ -108,13 +108,13 @@ static long magic_randcount = 0; /* Pseudo-random incrementer */ * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 */ void magic_churnrand(char *rand_data, u32_t rand_len) { - MD5_CTX md5; + md5_context md5; /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", rand_len, rand_data)); */ - MD5_Init(&md5); - MD5_Update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + md5_starts(&md5); + md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); if (rand_data) { - MD5_Update(&md5, (u_char *)rand_data, rand_len); + md5_update(&md5, (u_char *)rand_data, rand_len); } else { struct { /* INCLUDE fields for any system sources of randomness */ @@ -122,9 +122,9 @@ void magic_churnrand(char *rand_data, u32_t rand_len) { } sys_data; /* Load sys_data fields here. */ - MD5_Update(&md5, (u_char *)&sys_data, sizeof(sys_data)); + md5_update(&md5, (u_char *)&sys_data, sizeof(sys_data)); } - MD5_Final((u_char *)magic_randpool, &md5); + md5_finish(&md5, (u_char *)magic_randpool); /* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ } @@ -161,16 +161,16 @@ void magic_randomize(void) { * it was documented. */ void random_bytes(unsigned char *buf, u32_t buf_len) { - MD5_CTX md5; + md5_context md5; u_char tmp[16]; u32_t n; while (buf_len > 0) { n = LWIP_MIN(buf_len, MAGIC_RANDPOOLSIZE); - MD5_Init(&md5); - MD5_Update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); - MD5_Update(&md5, (u_char *)&magic_randcount, sizeof(magic_randcount)); - MD5_Final(tmp, &md5); + md5_starts(&md5); + md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + md5_update(&md5, (u_char *)&magic_randcount, sizeof(magic_randcount)); + md5_finish(&md5, tmp); magic_randcount++; MEMCPY(buf, tmp, n); buf += n; diff --git a/src/netif/ppp/md4.c b/src/netif/ppp/md4.c deleted file mode 100644 index f0831a92..00000000 --- a/src/netif/ppp/md4.c +++ /dev/null @@ -1,301 +0,0 @@ -/* -** ******************************************************************** -** md4.c -- Implementation of MD4 Message Digest Algorithm ** -** Updated: 2/16/90 by Ronald L. Rivest ** -** (C) 1990 RSA Data Security, Inc. ** -** ******************************************************************** -*/ - -#include "lwip/opt.h" - -/* -** To use MD4: -** -- Include md4.h in your program -** -- Declare an MDstruct MD to hold the state of the digest -** computation. -** -- Initialize MD using MDbegin(&MD) -** -- For each full block (64 bytes) X you wish to process, call -** MD4Update(&MD,X,512) -** (512 is the number of bits in a full block.) -** -- For the last block (less than 64 bytes) you wish to process, -** MD4Update(&MD,X,n) -** where n is the number of bits in the partial block. A partial -** block terminates the computation, so every MD computation -** should terminate by processing a partial block, even if it -** has n = 0. -** -- The message digest is available in MD.buffer[0] ... -** MD.buffer[3]. (Least-significant byte of each word -** should be output first.) -** -- You can print out the digest using MDprint(&MD) -*/ - -/* Implementation notes: -** This implementation assumes that ints are 32-bit quantities. -*/ - -#define TRUE 1 -#define FALSE 0 - -/* Compile-time includes -*/ -#include -#include "md4.h" -#include "pppd.h" - -/* Compile-time declarations of MD4 "magic constants". -*/ -#define I0 0x67452301 /* Initial values for MD buffer */ -#define I1 0xefcdab89 -#define I2 0x98badcfe -#define I3 0x10325476 -#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ -#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ -/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 -** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. -** Table 2, page 660. -*/ - -#define fs1 3 /* round 1 shift amounts */ -#define fs2 7 -#define fs3 11 -#define fs4 19 -#define gs1 3 /* round 2 shift amounts */ -#define gs2 5 -#define gs3 9 -#define gs4 13 -#define hs1 3 /* round 3 shift amounts */ -#define hs2 9 -#define hs3 11 -#define hs4 15 - -/* Compile-time macro declarations for MD4. -** Note: The "rot" operator uses the variable "tmp". -** It assumes tmp is declared as unsigned int, so that the >> -** operator will shift in zeros rather than extending the sign bit. -*/ -#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) -#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) -#define h(X,Y,Z) (X^Y^Z) -#define rot(X,S) (tmp=X,(tmp<>(32-S))) -#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) -#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) -#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) - -/* MD4print(MDp) -** Print message digest buffer MDp as 32 hexadecimal digits. -** Order is from low-order byte of buffer[0] to high-order byte of -** buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -** This is a user-callable routine. -*/ -void -MD4Print(MDp) -MD4_CTX *MDp; -{ - int i,j; - for (i=0;i<4;i++) - for (j=0;j<32;j=j+8) - printf("%02x",(MDp->buffer[i]>>j) & 0xFF); -} - -/* MD4Init(MDp) -** Initialize message digest buffer MDp. -** This is a user-callable routine. -*/ -void -MD4Init(MDp) -MD4_CTX *MDp; -{ - int i; - MDp->buffer[0] = I0; - MDp->buffer[1] = I1; - MDp->buffer[2] = I2; - MDp->buffer[3] = I3; - for (i=0;i<8;i++) MDp->count[i] = 0; - MDp->done = 0; -} - -/* MDblock(MDp,X) -** Update message digest buffer MDp->buffer using 16-word data block X. -** Assumes all 16 words of X are full of data. -** Does not update MDp->count. -** This routine is not user-callable. -*/ -static void -MDblock(MDp,Xb) -MD4_CTX *MDp; -unsigned char *Xb; -{ - register unsigned int tmp, A, B, C, D; - unsigned int X[16]; - int i; - - for (i = 0; i < 16; ++i) { - X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); - Xb += 4; - } - - A = MDp->buffer[0]; - B = MDp->buffer[1]; - C = MDp->buffer[2]; - D = MDp->buffer[3]; - /* Update the message digest buffer */ - ff(A , B , C , D , 0 , fs1); /* Round 1 */ - ff(D , A , B , C , 1 , fs2); - ff(C , D , A , B , 2 , fs3); - ff(B , C , D , A , 3 , fs4); - ff(A , B , C , D , 4 , fs1); - ff(D , A , B , C , 5 , fs2); - ff(C , D , A , B , 6 , fs3); - ff(B , C , D , A , 7 , fs4); - ff(A , B , C , D , 8 , fs1); - ff(D , A , B , C , 9 , fs2); - ff(C , D , A , B , 10 , fs3); - ff(B , C , D , A , 11 , fs4); - ff(A , B , C , D , 12 , fs1); - ff(D , A , B , C , 13 , fs2); - ff(C , D , A , B , 14 , fs3); - ff(B , C , D , A , 15 , fs4); - gg(A , B , C , D , 0 , gs1); /* Round 2 */ - gg(D , A , B , C , 4 , gs2); - gg(C , D , A , B , 8 , gs3); - gg(B , C , D , A , 12 , gs4); - gg(A , B , C , D , 1 , gs1); - gg(D , A , B , C , 5 , gs2); - gg(C , D , A , B , 9 , gs3); - gg(B , C , D , A , 13 , gs4); - gg(A , B , C , D , 2 , gs1); - gg(D , A , B , C , 6 , gs2); - gg(C , D , A , B , 10 , gs3); - gg(B , C , D , A , 14 , gs4); - gg(A , B , C , D , 3 , gs1); - gg(D , A , B , C , 7 , gs2); - gg(C , D , A , B , 11 , gs3); - gg(B , C , D , A , 15 , gs4); - hh(A , B , C , D , 0 , hs1); /* Round 3 */ - hh(D , A , B , C , 8 , hs2); - hh(C , D , A , B , 4 , hs3); - hh(B , C , D , A , 12 , hs4); - hh(A , B , C , D , 2 , hs1); - hh(D , A , B , C , 10 , hs2); - hh(C , D , A , B , 6 , hs3); - hh(B , C , D , A , 14 , hs4); - hh(A , B , C , D , 1 , hs1); - hh(D , A , B , C , 9 , hs2); - hh(C , D , A , B , 5 , hs3); - hh(B , C , D , A , 13 , hs4); - hh(A , B , C , D , 3 , hs1); - hh(D , A , B , C , 11 , hs2); - hh(C , D , A , B , 7 , hs3); - hh(B , C , D , A , 15 , hs4); - MDp->buffer[0] += A; - MDp->buffer[1] += B; - MDp->buffer[2] += C; - MDp->buffer[3] += D; -} - -/* MD4Update(MDp,X,count) -** Input: X -- a pointer to an array of unsigned characters. -** count -- the number of bits of X to use. -** (if not a multiple of 8, uses high bits of last byte.) -** Update MDp using the number of bits of X given by count. -** This is the basic input routine for an MD4 user. -** The routine completes the MD computation when count < 512, so -** every MD computation should end with one call to MD4Update with a -** count less than 512. A call with count 0 will be ignored if the -** MD has already been terminated (done != 0), so an extra call with -** count 0 can be given as a "courtesy close" to force termination -** if desired. -*/ -void -MD4Update(MDp,X,count) -MD4_CTX *MDp; -unsigned char *X; -unsigned int count; -{ - unsigned int i, tmp, bit, byte, mask; - unsigned char XX[64]; - unsigned char *p; - - /* return with no error if this is a courtesy close with count - ** zero and MDp->done is true. - */ - if (count == 0 && MDp->done) return; - /* check to see if MD is already done and report error */ - if (MDp->done) - { printf("\nError: MD4Update MD already done."); return; } - - /* Add count to MDp->count */ - tmp = count; - p = MDp->count; - while (tmp) - { tmp += *p; - *p++ = tmp; - tmp = tmp >> 8; - } - - /* Process data */ - if (count == 512) - { /* Full block of data to handle */ - MDblock(MDp,X); - } - else if (count > 512) /* Check for count too large */ - { - printf("\nError: MD4Update called with illegal count value %d.", - count); - return; - } - else /* partial block -- must be last block so finish up */ - { - /* Find out how many bytes and residual bits there are */ - byte = count >> 3; - bit = count & 7; - /* Copy X into XX since we need to modify it */ - if (count) - for (i=0;i<=byte;i++) XX[i] = X[i]; - for (i=byte+1;i<64;i++) XX[i] = 0; - /* Add padding '1' bit and low-order zeros in last byte */ - mask = 1 << (7 - bit); - XX[byte] = (XX[byte] | mask) & ~( mask - 1); - /* If room for bit count, finish up with this block */ - if (byte <= 55) - { - for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; - MDblock(MDp,XX); - } - else /* need to do two blocks to finish up */ - { - MDblock(MDp,XX); - for (i=0;i<56;i++) XX[i] = 0; - for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; - MDblock(MDp,XX); - } - /* Set flag saying we're done with MD computation */ - MDp->done = 1; - } -} - -/* -** Finish up MD4 computation and return message digest. -*/ -void -MD4Final(buf, MD) -unsigned char *buf; -MD4_CTX *MD; -{ - int i, j; - unsigned int w; - - MD4Update(MD, NULL, 0); - for (i = 0; i < 4; ++i) { - w = MD->buffer[i]; - for (j = 0; j < 4; ++j) { - *buf++ = w; - w >>= 8; - } - } -} - -/* -** End of md4.c -****************************(cut)***********************************/ diff --git a/src/netif/ppp/md4.h b/src/netif/ppp/md4.h deleted file mode 100644 index 80e8f9a2..00000000 --- a/src/netif/ppp/md4.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* -** ******************************************************************** -** md4.h -- Header file for implementation of ** -** MD4 Message Digest Algorithm ** -** Updated: 2/13/90 by Ronald L. Rivest ** -** (C) 1990 RSA Data Security, Inc. ** -** ******************************************************************** -*/ - -#ifndef __P -# if defined(__STDC__) || defined(__GNUC__) -# define __P(x) x -# else -# define __P(x) () -# endif -#endif - - -/* MDstruct is the data structure for a message digest computation. -*/ -typedef struct { - unsigned int buffer[4]; /* Holds 4-word result of MD computation */ - unsigned char count[8]; /* Number of bits processed so far */ - unsigned int done; /* Nonzero means MD computation finished */ -} MD4_CTX; - -/* MD4Init(MD4_CTX *) -** Initialize the MD4_CTX prepatory to doing a message digest -** computation. -*/ -extern void MD4Init __P((MD4_CTX *MD)); - -/* MD4Update(MD,X,count) -** Input: X -- a pointer to an array of unsigned characters. -** count -- the number of bits of X to use (an unsigned int). -** Updates MD using the first "count" bits of X. -** The array pointed to by X is not modified. -** If count is not a multiple of 8, MD4Update uses high bits of -** last byte. -** This is the basic input routine for a user. -** The routine terminates the MD computation when count < 512, so -** every MD computation should end with one call to MD4Update with a -** count less than 512. Zero is OK for a count. -*/ -extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); - -/* MD4Print(MD) -** Prints message digest buffer MD as 32 hexadecimal digits. -** Order is from low-order byte of buffer[0] to high-order byte -** of buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -*/ -extern void MD4Print __P((MD4_CTX *)); - -/* MD4Final(buf, MD) -** Returns message digest from MD and terminates the message -** digest computation. -*/ -extern void MD4Final __P((unsigned char *, MD4_CTX *)); - -/* -** End of md4.h -****************************(cut)***********************************/ diff --git a/src/netif/ppp/md5.c b/src/netif/ppp/md5.c deleted file mode 100644 index 11de7b6d..00000000 --- a/src/netif/ppp/md5.c +++ /dev/null @@ -1,309 +0,0 @@ - - -/* - *********************************************************************** - ** md5.c -- the source code for MD5 routines ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** - *********************************************************************** - */ - -#include "lwip/opt.h" - -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ - -#include -#include "md5.h" - -/* - *********************************************************************** - ** Message-digest routines: ** - ** To form the message digest for a message M ** - ** (1) Initialize a context buffer mdContext using MD5_Init ** - ** (2) Call MD5_Update on mdContext and M ** - ** (3) Call MD5_Final on mdContext ** - ** The message digest is now in mdContext->digest[0...15] ** - *********************************************************************** - */ - -/* forward declaration */ -static void Transform (UINT4 *buf, UINT4 *in); - -static unsigned char PADDING[64] = { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* F, G, H and I are basic MD5 functions */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ -/* Rotation is separate from addition to prevent recomputation */ -#define FF(a, b, c, d, x, s, ac) \ - {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) \ - {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) \ - {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) \ - {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -#ifdef __STDC__ -#define UL(x) x##U -#else -#define UL(x) x -#endif - -/* The routine MD5_Init initializes the message-digest context - mdContext. All fields are set to zero. - */ -void MD5_Init (mdContext) -MD5_CTX *mdContext; -{ - mdContext->i[0] = mdContext->i[1] = (UINT4)0; - - /* Load magic initialization constants. - */ - mdContext->buf[0] = (UINT4)0x67452301; - mdContext->buf[1] = (UINT4)0xefcdab89; - mdContext->buf[2] = (UINT4)0x98badcfe; - mdContext->buf[3] = (UINT4)0x10325476; -} - -/* The routine MD5Update updates the message-digest context to - account for the presence of each of the characters inBuf[0..inLen-1] - in the message whose digest is being computed. - */ -void MD5_Update (mdContext, inBuf, inLen) -MD5_CTX *mdContext; -unsigned char *inBuf; -unsigned int inLen; -{ - UINT4 in[16]; - int mdi; - unsigned int i, ii; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* update number of bits */ - if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) - mdContext->i[1]++; - mdContext->i[0] += ((UINT4)inLen << 3); - mdContext->i[1] += ((UINT4)inLen >> 29); - - while (inLen--) { - /* add new character to buffer, increment mdi */ - mdContext->in[mdi++] = *inBuf++; - - /* transform if necessary */ - if (mdi == 0x40) { - for (i = 0, ii = 0; i < 16; i++, ii += 4) - in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | - (((UINT4)mdContext->in[ii+2]) << 16) | - (((UINT4)mdContext->in[ii+1]) << 8) | - ((UINT4)mdContext->in[ii]); - Transform (mdContext->buf, in); - mdi = 0; - } - } -} - -/* The routine MD5Final terminates the message-digest computation and - ends with the desired message digest in mdContext->digest[0...15]. - */ -void MD5_Final (hash, mdContext) -unsigned char hash[]; -MD5_CTX *mdContext; -{ - UINT4 in[16]; - int mdi; - unsigned int i, ii; - unsigned int padLen; - - /* save number of bits */ - in[14] = mdContext->i[0]; - in[15] = mdContext->i[1]; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* pad out to 56 mod 64 */ - padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); - MD5_Update (mdContext, PADDING, padLen); - - /* append length in bits and transform */ - for (i = 0, ii = 0; i < 14; i++, ii += 4) - in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | - (((UINT4)mdContext->in[ii+2]) << 16) | - (((UINT4)mdContext->in[ii+1]) << 8) | - ((UINT4)mdContext->in[ii]); - Transform (mdContext->buf, in); - - /* store buffer in digest */ - for (i = 0, ii = 0; i < 4; i++, ii += 4) { - mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); - mdContext->digest[ii+1] = - (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); - mdContext->digest[ii+2] = - (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); - mdContext->digest[ii+3] = - (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); - } - memcpy(hash, mdContext->digest, 16); -} - -/* Basic MD5 step. Transforms buf based on in. - */ -static void Transform (buf, in) -UINT4 *buf; -UINT4 *in; -{ - UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - - /* Round 1 */ -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 - FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ - FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ - FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ - FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ - FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ - FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ - FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ - FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ - FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ - FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ - FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ - FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ - FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ - FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ - FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ - FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ - - /* Round 2 */ -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 - GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ - GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ - GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ - GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ - GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ - GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ - GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ - GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ - GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ - GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ - GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ - GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ - GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ - GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ - GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ - GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ - - /* Round 3 */ -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 - HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ - HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ - HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ - HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ - HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ - HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ - HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ - HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ - HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ - HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ - HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ - HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ - HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ - HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ - HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ - HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ - - /* Round 4 */ -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ - II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ - II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ - II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ - II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ - II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ - II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ - II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ - II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ - II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ - II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ - II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ - II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ - II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ - II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ - II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -/* - *********************************************************************** - ** End of md5.c ** - ******************************** (cut) ******************************** - */ diff --git a/src/netif/ppp/md5.h b/src/netif/ppp/md5.h deleted file mode 100644 index 71e8b00e..00000000 --- a/src/netif/ppp/md5.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - *********************************************************************** - ** md5.h -- header file for implementation of MD5 ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** - ** Revised (for MD5): RLR 4/27/91 ** - ** -- G modified to have y&~z instead of y&z ** - ** -- FF, GG, HH modified to add in last register done ** - ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** - ** -- distinct additive constant for each step ** - ** -- round 4 added, working mod 7 ** - *********************************************************************** - */ - -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ - -#ifndef __MD5_INCLUDE__ - -/* typedef a 32-bit type */ -#ifdef _LP64 -typedef unsigned int UINT4; -typedef int INT4; -#else -typedef unsigned long UINT4; -typedef long INT4; -#endif -#define _UINT4_T - -/* Data structure for MD5 (Message-Digest) computation */ -typedef struct { - UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ - UINT4 buf[4]; /* scratch buffer */ - unsigned char in[64]; /* input buffer */ - unsigned char digest[16]; /* actual digest after MD5Final call */ -} MD5_CTX; - -void MD5_Init (MD5_CTX *mdContext); -void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); -void MD5_Final (unsigned char hash[], MD5_CTX *mdContext); - -#define __MD5_INCLUDE__ -#endif /* __MD5_INCLUDE__ */ diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/md4.c new file mode 100644 index 00000000..e5f715bc --- /dev/null +++ b/src/netif/ppp/polarssl/md4.c @@ -0,0 +1,271 @@ +/* + * RFC 1186/1320 compliant MD4 implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD4 algorithm was designed by Ron Rivest in 1990. + * + * http://www.ietf.org/rfc/rfc1186.txt + * http://www.ietf.org/rfc/rfc1320.txt + */ + +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_MD4_C) + +#include "polarssl/md4.h" + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_ULONG_LE +#define GET_ULONG_LE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] ) \ + | ( (unsigned long) (b)[(i) + 1] << 8 ) \ + | ( (unsigned long) (b)[(i) + 2] << 16 ) \ + | ( (unsigned long) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_ULONG_LE +#define PUT_ULONG_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* + * MD4 context setup + */ +void md4_starts( md4_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md4_process( md4_context *ctx, const unsigned char data[64] ) +{ + unsigned long X[16], A, B, C, D; + + GET_ULONG_LE( X[ 0], data, 0 ); + GET_ULONG_LE( X[ 1], data, 4 ); + GET_ULONG_LE( X[ 2], data, 8 ); + GET_ULONG_LE( X[ 3], data, 12 ); + GET_ULONG_LE( X[ 4], data, 16 ); + GET_ULONG_LE( X[ 5], data, 20 ); + GET_ULONG_LE( X[ 6], data, 24 ); + GET_ULONG_LE( X[ 7], data, 28 ); + GET_ULONG_LE( X[ 8], data, 32 ); + GET_ULONG_LE( X[ 9], data, 36 ); + GET_ULONG_LE( X[10], data, 40 ); + GET_ULONG_LE( X[11], data, 44 ); + GET_ULONG_LE( X[12], data, 48 ); + GET_ULONG_LE( X[13], data, 52 ); + GET_ULONG_LE( X[14], data, 56 ); + GET_ULONG_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) ((x & y) | ((~x) & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 1], 7 ); + P( C, D, A, B, X[ 2], 11 ); + P( B, C, D, A, X[ 3], 19 ); + P( A, B, C, D, X[ 4], 3 ); + P( D, A, B, C, X[ 5], 7 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[ 7], 19 ); + P( A, B, C, D, X[ 8], 3 ); + P( D, A, B, C, X[ 9], 7 ); + P( C, D, A, B, X[10], 11 ); + P( B, C, D, A, X[11], 19 ); + P( A, B, C, D, X[12], 3 ); + P( D, A, B, C, X[13], 7 ); + P( C, D, A, B, X[14], 11 ); + P( B, C, D, A, X[15], 19 ); + +#undef P +#undef F + +#define F(x,y,z) ((x & y) | (x & z) | (y & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 4], 5 ); + P( C, D, A, B, X[ 8], 9 ); + P( B, C, D, A, X[12], 13 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 5], 5 ); + P( C, D, A, B, X[ 9], 9 ); + P( B, C, D, A, X[13], 13 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[ 6], 5 ); + P( C, D, A, B, X[10], 9 ); + P( B, C, D, A, X[14], 13 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[ 7], 5 ); + P( C, D, A, B, X[11], 9 ); + P( B, C, D, A, X[15], 13 ); + +#undef P +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 8], 9 ); + P( C, D, A, B, X[ 4], 11 ); + P( B, C, D, A, X[12], 15 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[10], 9 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[14], 15 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 9], 9 ); + P( C, D, A, B, X[ 5], 11 ); + P( B, C, D, A, X[13], 15 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[11], 9 ); + P( C, D, A, B, X[ 7], 11 ); + P( B, C, D, A, X[15], 15 ); + +#undef F +#undef P + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD4 process buffer + */ +void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (unsigned long) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + md4_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md4_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md4_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD4 final digest + */ +void md4_finish( md4_context *ctx, unsigned char output[16] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_LE( low, msglen, 0 ); + PUT_ULONG_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md4_update( ctx, (unsigned char *) md4_padding, padn ); + md4_update( ctx, msglen, 8 ); + + PUT_ULONG_LE( ctx->state[0], output, 0 ); + PUT_ULONG_LE( ctx->state[1], output, 4 ); + PUT_ULONG_LE( ctx->state[2], output, 8 ); + PUT_ULONG_LE( ctx->state[3], output, 12 ); +} + +/* + * output = MD4( input buffer ) + */ +void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + md4_context ctx; + + md4_starts( &ctx ); + md4_update( &ctx, input, ilen ); + md4_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md4_context ) ); +} + +#endif /* LWIP_INCLUDED_POLARSSL_MD4_C */ diff --git a/src/netif/ppp/polarssl/md4.h b/src/netif/ppp/polarssl/md4.h new file mode 100644 index 00000000..1ad8250f --- /dev/null +++ b/src/netif/ppp/polarssl/md4.h @@ -0,0 +1,82 @@ +/** + * \file md4.h + * + * \brief MD4 message digest algorithm (hash function) + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef LWIP_INCLUDED_POLARSSL_MD4_H +#define LWIP_INCLUDED_POLARSSL_MD4_H + +/** + * \brief MD4 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +md4_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD4 context setup + * + * \param ctx context to be initialized + */ +void md4_starts( md4_context *ctx ); + +/** + * \brief MD4 process buffer + * + * \param ctx MD4 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief MD4 final digest + * + * \param ctx MD4 context + * \param output MD4 checksum result + */ +void md4_finish( md4_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = MD4( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD4 checksum result + */ +void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/md5.c new file mode 100644 index 00000000..621a5372 --- /dev/null +++ b/src/netif/ppp/polarssl/md5.c @@ -0,0 +1,290 @@ +/* + * RFC 1321 compliant MD5 implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD5 algorithm was designed by Ron Rivest in 1991. + * + * http://www.ietf.org/rfc/rfc1321.txt + */ + +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_MD5_C) + +#include "polarssl/md5.h" + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_ULONG_LE +#define GET_ULONG_LE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] ) \ + | ( (unsigned long) (b)[(i) + 1] << 8 ) \ + | ( (unsigned long) (b)[(i) + 2] << 16 ) \ + | ( (unsigned long) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_ULONG_LE +#define PUT_ULONG_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* + * MD5 context setup + */ +void md5_starts( md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md5_process( md5_context *ctx, const unsigned char data[64] ) +{ + unsigned long X[16], A, B, C, D; + + GET_ULONG_LE( X[ 0], data, 0 ); + GET_ULONG_LE( X[ 1], data, 4 ); + GET_ULONG_LE( X[ 2], data, 8 ); + GET_ULONG_LE( X[ 3], data, 12 ); + GET_ULONG_LE( X[ 4], data, 16 ); + GET_ULONG_LE( X[ 5], data, 20 ); + GET_ULONG_LE( X[ 6], data, 24 ); + GET_ULONG_LE( X[ 7], data, 28 ); + GET_ULONG_LE( X[ 8], data, 32 ); + GET_ULONG_LE( X[ 9], data, 36 ); + GET_ULONG_LE( X[10], data, 40 ); + GET_ULONG_LE( X[11], data, 44 ); + GET_ULONG_LE( X[12], data, 48 ); + GET_ULONG_LE( X[13], data, 52 ); + GET_ULONG_LE( X[14], data, 56 ); + GET_ULONG_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD5 process buffer + */ +void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (unsigned long) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + md5_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md5_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD5 final digest + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_LE( low, msglen, 0 ); + PUT_ULONG_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md5_update( ctx, (unsigned char *) md5_padding, padn ); + md5_update( ctx, msglen, 8 ); + + PUT_ULONG_LE( ctx->state[0], output, 0 ); + PUT_ULONG_LE( ctx->state[1], output, 4 ); + PUT_ULONG_LE( ctx->state[2], output, 8 ); + PUT_ULONG_LE( ctx->state[3], output, 12 ); +} + +/* + * output = MD5( input buffer ) + */ +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + md5_context ctx; + + md5_starts( &ctx ); + md5_update( &ctx, input, ilen ); + md5_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md5_context ) ); +} + +#endif /* LWIP_INCLUDED_POLARSSL_MD5_C */ diff --git a/src/netif/ppp/polarssl/md5.h b/src/netif/ppp/polarssl/md5.h new file mode 100644 index 00000000..389b4154 --- /dev/null +++ b/src/netif/ppp/polarssl/md5.h @@ -0,0 +1,82 @@ +/** + * \file md5.h + * + * \brief MD5 message digest algorithm (hash function) + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef LWIP_INCLUDED_POLARSSL_MD5_H +#define LWIP_INCLUDED_POLARSSL_MD5_H + +/** + * \brief MD5 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +md5_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD5 context setup + * + * \param ctx context to be initialized + */ +void md5_starts( md5_context *ctx ); + +/** + * \brief MD5 process buffer + * + * \param ctx MD5 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief MD5 final digest + * + * \param ctx MD5 context + * \param output MD5 checksum result + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = MD5( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD5 checksum result + */ +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/sha1.c new file mode 100644 index 00000000..5e9a661f --- /dev/null +++ b/src/netif/ppp/polarssl/sha1.c @@ -0,0 +1,325 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-1 standard was published by NIST in 1993. + * + * http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ + +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_SHA1_C) + +#include "polarssl/sha1.h" + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * SHA-1 context setup + */ +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) +{ + unsigned long temp, W[16], A, B, C, D, E; + + GET_ULONG_BE( W[ 0], data, 0 ); + GET_ULONG_BE( W[ 1], data, 4 ); + GET_ULONG_BE( W[ 2], data, 8 ); + GET_ULONG_BE( W[ 3], data, 12 ); + GET_ULONG_BE( W[ 4], data, 16 ); + GET_ULONG_BE( W[ 5], data, 20 ); + GET_ULONG_BE( W[ 6], data, 24 ); + GET_ULONG_BE( W[ 7], data, 28 ); + GET_ULONG_BE( W[ 8], data, 32 ); + GET_ULONG_BE( W[ 9], data, 36 ); + GET_ULONG_BE( W[10], data, 40 ); + GET_ULONG_BE( W[11], data, 44 ); + GET_ULONG_BE( W[12], data, 48 ); + GET_ULONG_BE( W[13], data, 52 ); + GET_ULONG_BE( W[14], data, 56 ); + GET_ULONG_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ + W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* + * SHA-1 process buffer + */ +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (unsigned long) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-1 final digest + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_BE( high, msglen, 0 ); + PUT_ULONG_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, (unsigned char *) sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_ULONG_BE( ctx->state[0], output, 0 ); + PUT_ULONG_BE( ctx->state[1], output, 4 ); + PUT_ULONG_BE( ctx->state[2], output, 8 ); + PUT_ULONG_BE( ctx->state[3], output, 12 ); + PUT_ULONG_BE( ctx->state[4], output, 16 ); +} + +/* + * output = SHA-1( input buffer ) + */ +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_starts( &ctx ); + sha1_update( &ctx, input, ilen ); + sha1_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha1_context ) ); +} + +#endif /* LWIP_INCLUDED_POLARSSL_SHA1_C */ diff --git a/src/netif/ppp/polarssl/sha1.h b/src/netif/ppp/polarssl/sha1.h new file mode 100644 index 00000000..b01e93f4 --- /dev/null +++ b/src/netif/ppp/polarssl/sha1.h @@ -0,0 +1,82 @@ +/** + * \file sha1.h + * + * \brief SHA-1 cryptographic hash function + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H +#define LWIP_INCLUDED_POLARSSL_SHA1_H + +/** + * \brief SHA-1 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +sha1_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + */ +void sha1_starts( sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ); + +/** + * \brief Output = SHA-1( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-1 checksum result + */ +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ diff --git a/src/netif/ppp/sha1.c b/src/netif/ppp/sha1.c deleted file mode 100644 index 3b020b8f..00000000 --- a/src/netif/ppp/sha1.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c - * - * SHA-1 in C - * By Steve Reid - * 100% Public Domain - * - * Test Vectors (from FIPS PUB 180-1) - * "abc" - * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D - * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 - * A million repetitions of "a" - * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F - */ - -#include "lwip/opt.h" - -/* #define SHA1HANDSOFF * Copies data before messing with it. */ - -#include -#include /* htonl() */ -#include -#include "sha1.h" - -static void -SHA1_Transform(u_int32_t[5], const unsigned char[64]); - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -/* I got the idea of expanding during the round function from SSLeay */ -#define blk0(i) (block->l[i] = htonl(block->l[i])) -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -static void -SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64]) -{ - u_int32_t a, b, c, d, e; - typedef union { - unsigned char c[64]; - u_int32_t l[16]; - } CHAR64LONG16; - CHAR64LONG16 *block; - -#ifdef SHA1HANDSOFF - static unsigned char workspace[64]; - block = (CHAR64LONG16 *) workspace; - memcpy(block, buffer, 64); -#else - block = (CHAR64LONG16 *) buffer; -#endif - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Wipe variables */ - a = b = c = d = e = 0; -} - - -/* SHA1Init - Initialize new context */ - -void -SHA1_Init(SHA1_CTX *context) -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - - -/* Run your data through this. */ - -void -SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) -{ - unsigned int i, j; - - j = (context->count[0] >> 3) & 63; - if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; - context->count[1] += (len >> 29); - i = 64 - j; - while (len >= i) { - memcpy(&context->buffer[j], data, i); - SHA1_Transform(context->state, context->buffer); - data += i; - len -= i; - i = 64; - j = 0; - } - - memcpy(&context->buffer[j], data, len); -} - - -/* Add padding and return the message digest. */ - -void -SHA1_Final(unsigned char digest[20], SHA1_CTX *context) -{ - u_int32_t i, j; - unsigned char finalcount[8]; - - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ - } - SHA1_Update(context, (unsigned char *) "\200", 1); - while ((context->count[0] & 504) != 448) { - SHA1_Update(context, (unsigned char *) "\0", 1); - } - SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - /* Wipe variables */ - i = j = 0; - memset(context->buffer, 0, 64); - memset(context->state, 0, 20); - memset(context->count, 0, 8); - memset(&finalcount, 0, 8); -#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ - SHA1Transform(context->state, context->buffer); -#endif -} - diff --git a/src/netif/ppp/sha1.h b/src/netif/ppp/sha1.h deleted file mode 100644 index 83f64df2..00000000 --- a/src/netif/ppp/sha1.h +++ /dev/null @@ -1,31 +0,0 @@ -/* sha1.h */ - -/* If OpenSSL is in use, then use that version of SHA-1 */ -#ifdef OPENSSL -#include -#define __SHA1_INCLUDE_ -#endif - -#ifndef __SHA1_INCLUDE_ - -#ifndef SHA1_SIGNATURE_SIZE -#ifdef SHA_DIGESTSIZE -#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE -#else -#define SHA1_SIGNATURE_SIZE 20 -#endif -#endif - -typedef struct { - u_int32_t state[5]; - u_int32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -extern void SHA1_Init(SHA1_CTX *); -extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int); -extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *); - -#define __SHA1_INCLUDE_ -#endif /* __SHA1_INCLUDE_ */ - From 0289055948744d27b6b32c3422f785ae2f7274bd Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 22:15:40 +0200 Subject: [PATCH 037/320] Revert "Revert "Added PolarSSL DES library, which is necessary for MSCHAP."" This reverts commit a820f32ec936a1a699ef76adb3fa8ea0915fc152. --- src/netif/ppp/chap_ms.c | 35 ++- src/netif/ppp/eap.c | 6 + src/netif/ppp/polarssl/README | 33 +++ src/netif/ppp/polarssl/des.c | 418 ++++++++++++++++++++++++++++++++++ src/netif/ppp/polarssl/des.h | 88 +++++++ src/netif/ppp/pppcrypt.c | 161 ++----------- src/netif/ppp/pppcrypt.h | 12 +- 7 files changed, 586 insertions(+), 167 deletions(-) create mode 100644 src/netif/ppp/polarssl/README create mode 100644 src/netif/ppp/polarssl/des.c create mode 100644 src/netif/ppp/polarssl/des.h diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 9efa2066..b05ad3c5 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -93,6 +93,7 @@ #include "chap_ms.h" #include "polarssl/md4.h" #include "polarssl/sha1.h" +#include "polarssl/des.h" #include "pppcrypt.h" #include "magic.h" @@ -447,6 +448,8 @@ ChallengeResponse(u_char *challenge, u_char response[24]) { u_char ZPasswordHash[21]; + des_context des; + u_char des_key[8]; BZERO(ZPasswordHash, sizeof(ZPasswordHash)); BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE); @@ -456,12 +459,17 @@ ChallengeResponse(u_char *challenge, sizeof(ZPasswordHash), ZPasswordHash); #endif - (void) DesSetkey(ZPasswordHash + 0); - DesEncrypt(challenge, response + 0); - (void) DesSetkey(ZPasswordHash + 7); - DesEncrypt(challenge, response + 8); - (void) DesSetkey(ZPasswordHash + 14); - DesEncrypt(challenge, response + 16); + pppcrypt_56_to_64_bit_key(ZPasswordHash + 0, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +0); + + pppcrypt_56_to_64_bit_key(ZPasswordHash + 7, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +8); + + pppcrypt_56_to_64_bit_key(ZPasswordHash + 14, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +16); #if 0 dbglog("ChallengeResponse - response %.24B", response); @@ -573,15 +581,22 @@ ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, int i; u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ u_char PasswordHash[MD4_SIGNATURE_SIZE]; + des_context des; + u_char des_key[8]; /* LANMan password is case insensitive */ BZERO(UcasePassword, sizeof(UcasePassword)); for (i = 0; i < secret_len; i++) UcasePassword[i] = (u_char)toupper(secret[i]); - (void) DesSetkey(UcasePassword + 0); - DesEncrypt( StdText, PasswordHash + 0 ); - (void) DesSetkey(UcasePassword + 7); - DesEncrypt( StdText, PasswordHash + 8 ); + + pppcrypt_56_to_64_bit_key(UcasePassword +0, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, StdText, PasswordHash +0); + + pppcrypt_56_to_64_bit_key(UcasePassword +7, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, StdText, PasswordHash +8); + ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); } #endif diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index dc2a5285..c70eff49 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -316,6 +316,7 @@ pncrypt_setkey(int timeoffs) strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); SHA1Update(&ctxt, tbuf, strlen(tbuf)); SHA1Final(dig, &ctxt); + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ return (DesSetkey(dig)); } @@ -458,6 +459,7 @@ int status; for (i = 0; i < 5; i++) { pncrypt_setkey(toffs); toffs -= 86400; + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ if (!DesDecrypt(secbuf, clear)) { dbglog("no DES here; cannot decode " "pseudonym"); @@ -482,6 +484,7 @@ int status; dp += i; sp = secbuf + 8; while (plen > 0) { + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesDecrypt(sp, dp); sp += 8; dp += 8; @@ -763,6 +766,7 @@ eap_state *esp; BCOPY(cp, clear + 1, j); i -= j; cp += j; + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ if (!DesEncrypt(clear, cipher)) { dbglog("no DES here; not generating pseudonym"); break; @@ -771,6 +775,7 @@ eap_state *esp; outp++; /* space for pseudonym length */ outp += b64enc(&b64, cipher, 8, outp); while (i >= 8) { + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesEncrypt(cp, cipher); outp += b64enc(&b64, cipher, 8, outp); cp += 8; @@ -783,6 +788,7 @@ eap_state *esp; *cp++ = drand48() * 0x100; i++; } + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ (void) DesEncrypt(clear, cipher); outp += b64enc(&b64, cipher, 8, outp); } diff --git a/src/netif/ppp/polarssl/README b/src/netif/ppp/polarssl/README new file mode 100644 index 00000000..8efc8ec1 --- /dev/null +++ b/src/netif/ppp/polarssl/README @@ -0,0 +1,33 @@ +About PolarSSL files into lwIP PPP support +------------------------------------------ + +This folder contains some files fetched from the PolarSSL project for +ciphers and encryption methods we need for lwIP PPP support. + +The PolarSSL files were cleaned to contain only the necessary struct +fields and functions needed for lwIP. + + +The PolarSSL API was not changed at all, so if you are already using +PolarSSL you can choose to skip the compilation of the included PolarSSL +library into lwIP: + +The following define are available for flexibility: + +LWIP_INCLUDED_POLARSSL_MD4_C ; Use lwIP internal PolarSSL for MD4 +LWIP_INCLUDED_POLARSSL_MD5_C ; Use lwIP internal PolarSSL for MD5 +LWIP_INCLUDED_POLARSSL_SHA1_C ; Use lwIP internal PolarSSL for SHA1 +LWIP_INCLUDED_POLARSSL_DES_C ; Use lwIP internal PolarSSL for DES + +If set (=1), the default if required by another enabled PPP feature unless +explicitely set to 0, using included lwIP PolarSSL. + +If clear (=0), using external PolarSSL. + +Undefined if not needed. + +Beware of the stack requirements which can be a lot larger if you are not +using our cleaned PolarSSL library. + + +PolarSSL project website: http://polarssl.org/ diff --git a/src/netif/ppp/polarssl/des.c b/src/netif/ppp/polarssl/des.c new file mode 100644 index 00000000..b3d98286 --- /dev/null +++ b/src/netif/ppp/polarssl/des.c @@ -0,0 +1,418 @@ +/* + * FIPS-46-3 compliant Triple-DES implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * DES, on which TDES is based, was originally designed by Horst Feistel + * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). + * + * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + */ + +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_DES_C) + +#include "polarssl/des.h" + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * Expanded DES S-boxes + */ +static const unsigned long SB1[64] = +{ + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static const unsigned long SB2[64] = +{ + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static const unsigned long SB3[64] = +{ + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const unsigned long SB4[64] = +{ + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const unsigned long SB5[64] = +{ + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const unsigned long SB6[64] = +{ + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const unsigned long SB7[64] = +{ + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const unsigned long SB8[64] = +{ + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * PC1: left and right halves bit-swap + */ +static const unsigned long LHs[16] = +{ + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +static const unsigned long RHs[16] = +{ + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Initial Permutation macro + */ +#define DES_IP(X,Y) \ +{ \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ + X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ +} + +/* + * Final Permutation macro + */ +#define DES_FP(X,Y) \ +{ \ + X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ + Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ +} + +/* + * DES round macro + */ +#define DES_ROUND(X,Y) \ +{ \ + T = *SK++ ^ X; \ + Y ^= SB8[ (T ) & 0x3F ] ^ \ + SB6[ (T >> 8) & 0x3F ] ^ \ + SB4[ (T >> 16) & 0x3F ] ^ \ + SB2[ (T >> 24) & 0x3F ]; \ + \ + T = *SK++ ^ ((X << 28) | (X >> 4)); \ + Y ^= SB7[ (T ) & 0x3F ] ^ \ + SB5[ (T >> 8) & 0x3F ] ^ \ + SB3[ (T >> 16) & 0x3F ] ^ \ + SB1[ (T >> 24) & 0x3F ]; \ +} + +#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } + +static void des_setkey( unsigned long SK[32], const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + unsigned long X, Y, T; + + GET_ULONG_BE( X, key, 0 ); + GET_ULONG_BE( Y, key, 4 ); + + /* + * Permuted Choice 1 + */ + T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); + T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); + + X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) + | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) + | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) + | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); + + Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) + | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) + | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) + | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); + + X &= 0x0FFFFFFF; + Y &= 0x0FFFFFFF; + + /* + * calculate subkeys + */ + for( i = 0; i < 16; i++ ) + { + if( i < 2 || i == 8 || i == 15 ) + { + X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; + Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; + } + else + { + X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; + Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; + } + + *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) + | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) + | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) + | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) + | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) + | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) + | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) + | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) + | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) + | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) + | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); + + *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) + | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) + | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) + | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) + | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) + | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) + | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) + | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) + | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) + | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) + | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); + } +} + +/* + * DES key schedule (56-bit, encryption) + */ +int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +{ + des_setkey( ctx->sk, key ); + + return( 0 ); +} + +/* + * DES key schedule (56-bit, decryption) + */ +int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + + des_setkey( ctx->sk, key ); + + for( i = 0; i < 16; i += 2 ) + { + SWAP( ctx->sk[i ], ctx->sk[30 - i] ); + SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); + } + + return( 0 ); +} + +/* + * DES-ECB block encryption/decryption + */ +int des_crypt_ecb( des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + unsigned long X, Y, T, *SK; + + SK = ctx->sk; + + GET_ULONG_BE( X, input, 0 ); + GET_ULONG_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_ULONG_BE( Y, output, 0 ); + PUT_ULONG_BE( X, output, 4 ); + + return( 0 ); +} + +#endif /* LWIP_INCLUDED_POLARSSL_DES_C */ diff --git a/src/netif/ppp/polarssl/des.h b/src/netif/ppp/polarssl/des.h new file mode 100644 index 00000000..21d84601 --- /dev/null +++ b/src/netif/ppp/polarssl/des.h @@ -0,0 +1,88 @@ +/** + * \file des.h + * + * \brief DES block cipher + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef LWIP_INCLUDED_POLARSSL_DES_H +#define LWIP_INCLUDED_POLARSSL_DES_H + +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ + +#define DES_KEY_SIZE 8 + +/** + * \brief DES context structure + */ +typedef struct +{ + int mode; /*!< encrypt/decrypt */ + unsigned long sk[32]; /*!< DES subkeys */ +} +des_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief DES key schedule (56-bit, encryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + */ +int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief DES key schedule (56-bit, decryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + */ +int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief DES-ECB block encryption/decryption + * + * \param ctx DES context + * \param input 64-bit input block + * \param output 64-bit output block + * + * \return 0 if successful + */ +int des_crypt_ecb( des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_DES_H */ diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index 1a66f680..9bde8953 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -32,15 +32,13 @@ #include "lwip/opt.h" -#include +/* FIXME: dont include if not needed */ + #include "pppd.h" #include "pppcrypt.h" -static u_char -Get7Bits(input, startBit) -u_char *input; -int startBit; -{ + +static u_char pppcrypt_get_7bits(u_char *input, int startBit) { unsigned int word; word = (unsigned)input[startBit / 8] << 8; @@ -51,145 +49,16 @@ int startBit; return word & 0xFE; } -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 -} - -#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() +/* IN 56 bit DES key missing parity bits + * OUT 64 bit DES key with parity bits added */ -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; - } +void pppcrypt_56_to_64_bit_key(u_char *key, u_char * des_key) { + des_key[0] = pppcrypt_get_7bits(key, 0); + des_key[1] = pppcrypt_get_7bits(key, 7); + des_key[2] = pppcrypt_get_7bits(key, 14); + des_key[3] = pppcrypt_get_7bits(key, 21); + des_key[4] = pppcrypt_get_7bits(key, 28); + des_key[5] = pppcrypt_get_7bits(key, 35); + des_key[6] = pppcrypt_get_7bits(key, 42); + des_key[7] = pppcrypt_get_7bits(key, 49); } - -/* 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; - } -} - -bool -DesSetkey(key) -u_char *key; -{ - u_char des_key[8]; - u_char crypt_key[66]; - - MakeKey(key, des_key); - Expand(des_key, crypt_key); - errno = 0; - setkey((const char *)crypt_key); - if (errno != 0) - return (0); - return (1); -} - -bool -DesEncrypt(clear, cipher) -u_char *clear; /* IN 8 octets */ -u_char *cipher; /* OUT 8 octets */ -{ - u_char des_input[66]; - - Expand(clear, des_input); - errno = 0; - encrypt((char *)des_input, 0); - if (errno != 0) - return (0); - Collapse(des_input, cipher); - return (1); -} - -bool -DesDecrypt(cipher, clear) -u_char *cipher; /* IN 8 octets */ -u_char *clear; /* OUT 8 octets */ -{ - u_char des_input[66]; - - Expand(cipher, des_input); - errno = 0; - encrypt((char *)des_input, 1); - if (errno != 0) - return (0); - Collapse(des_input, clear); - return (1); -} - -#else /* USE_CRYPT */ -static des_key_schedule key_schedule; - -bool -DesSetkey(key) -u_char *key; -{ - des_cblock des_key; - MakeKey(key, des_key); - des_set_key(&des_key, key_schedule); - return (1); -} - -bool -DesEncrypt(clear, key, cipher) -u_char *clear; /* IN 8 octets */ -u_char *cipher; /* OUT 8 octets */ -{ - des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, - key_schedule, 1); - return (1); -} - -bool -DesDecrypt(cipher, clear) -u_char *cipher; /* IN 8 octets */ -u_char *clear; /* OUT 8 octets */ -{ - des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, - key_schedule, 0); - return (1); -} - -#endif /* USE_CRYPT */ diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h index adcdcbcb..6b5eaf8b 100644 --- a/src/netif/ppp/pppcrypt.h +++ b/src/netif/ppp/pppcrypt.h @@ -33,16 +33,6 @@ #ifndef PPPCRYPT_H #define PPPCRYPT_H -#ifdef HAVE_CRYPT_H -#include -#endif - -#ifndef USE_CRYPT -#include -#endif - -extern bool DesSetkey __P((u_char *)); -extern bool DesEncrypt __P((u_char *, u_char *)); -extern bool DesDecrypt __P((u_char *, u_char *)); +void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key); #endif /* PPPCRYPT_H */ From 4c1b507c07e21917ac7f95db6db3ab2c55252366 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 22:26:20 +0200 Subject: [PATCH 038/320] fixed MS-CHAP and MS-CHAP-V2, MD4 polarssl uses bytes as input length, not bits --- src/netif/ppp/chap_ms.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index b05ad3c5..2c46bbec 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -520,24 +520,11 @@ ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) { -#ifdef __NetBSD__ - /* NetBSD uses the libc md4 routines which take bytes instead of bits */ - int mdlen = secret_len; -#else - int mdlen = secret_len * 8; -#endif md4_context md4Context; md4_starts(&md4Context); - /* MD4Update can take at most 64 bytes at a time */ - while (mdlen > 512) { - md4_update(&md4Context, secret, 512); - secret += 64; - mdlen -= 512; - } - md4_update(&md4Context, secret, mdlen); + md4_update(&md4Context, secret, secret_len); md4_finish(&md4Context, hash); - } static void From 0bfad4392a08dfb6be7a75f604b7f72e03b4afde Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 22:33:37 +0200 Subject: [PATCH 039/320] Commit to prouve we copied the raw BSD PolarSSL files --- src/netif/ppp/polarssl/README | 5 +- src/netif/ppp/polarssl/des.c | 527 ++++++++++++++++++++++++++++++++-- src/netif/ppp/polarssl/des.h | 162 ++++++++--- src/netif/ppp/polarssl/md4.c | 234 +++++++++++++-- src/netif/ppp/polarssl/md4.h | 114 ++++++-- src/netif/ppp/polarssl/md5.c | 338 ++++++++++++++++++++-- src/netif/ppp/polarssl/md5.h | 114 ++++++-- src/netif/ppp/polarssl/sha1.c | 345 ++++++++++++++++++++-- src/netif/ppp/polarssl/sha1.h | 114 ++++++-- 9 files changed, 1748 insertions(+), 205 deletions(-) diff --git a/src/netif/ppp/polarssl/README b/src/netif/ppp/polarssl/README index 8efc8ec1..12e81d97 100644 --- a/src/netif/ppp/polarssl/README +++ b/src/netif/ppp/polarssl/README @@ -1,8 +1,9 @@ About PolarSSL files into lwIP PPP support ------------------------------------------ -This folder contains some files fetched from the PolarSSL project for -ciphers and encryption methods we need for lwIP PPP support. +This folder contains some files fetched from the latest BSD release of +the PolarSSL project for ciphers and encryption methods we need for lwIP +PPP support. The PolarSSL files were cleaned to contain only the necessary struct fields and functions needed for lwIP. diff --git a/src/netif/ppp/polarssl/des.c b/src/netif/ppp/polarssl/des.c index b3d98286..fcefd727 100644 --- a/src/netif/ppp/polarssl/des.c +++ b/src/netif/ppp/polarssl/des.c @@ -1,26 +1,36 @@ /* * FIPS-46-3 compliant Triple-DES implementation * - * Copyright (C) 2006-2010, Brainspark B.V. + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker + * Copyright (C) 2009 Paul Bakker * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * DES, on which TDES is based, was originally designed by Horst Feistel @@ -29,11 +39,14 @@ * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf */ -#include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_DES_C) +#include "polarssl/config.h" + +#if defined(POLARSSL_DES_C) #include "polarssl/des.h" +#include + /* * 32-bit integer manipulation macros (big endian) */ @@ -287,7 +300,7 @@ static const unsigned long RHs[16] = #define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } -static void des_setkey( unsigned long SK[32], const unsigned char key[DES_KEY_SIZE] ) +static void des_setkey( unsigned long SK[32], unsigned char key[8] ) { int i; unsigned long X, Y, T; @@ -359,17 +372,15 @@ static void des_setkey( unsigned long SK[32], const unsigned char key[DES_KEY_SI /* * DES key schedule (56-bit, encryption) */ -int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +void des_setkey_enc( des_context *ctx, unsigned char key[8] ) { des_setkey( ctx->sk, key ); - - return( 0 ); } /* * DES key schedule (56-bit, decryption) */ -int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +void des_setkey_dec( des_context *ctx, unsigned char key[8] ) { int i; @@ -380,15 +391,105 @@ int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) SWAP( ctx->sk[i ], ctx->sk[30 - i] ); SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); } +} - return( 0 ); +static void des3_set2key( unsigned long esk[96], + unsigned long dsk[96], + unsigned char key[16] ) +{ + int i; + + des_setkey( esk, key ); + des_setkey( dsk + 32, key + 8 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[30 - i]; + dsk[i + 1] = esk[31 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + esk[i + 64] = esk[i ]; + esk[i + 65] = esk[i + 1]; + + dsk[i + 64] = dsk[i ]; + dsk[i + 65] = dsk[i + 1]; + } +} + +/* + * Triple-DES key schedule (112-bit, encryption) + */ +void des3_set2key_enc( des3_context *ctx, unsigned char key[16] ) +{ + unsigned long sk[96]; + + des3_set2key( ctx->sk, sk, key ); + memset( sk, 0, sizeof( sk ) ); +} + +/* + * Triple-DES key schedule (112-bit, decryption) + */ +void des3_set2key_dec( des3_context *ctx, unsigned char key[16] ) +{ + unsigned long sk[96]; + + des3_set2key( sk, ctx->sk, key ); + memset( sk, 0, sizeof( sk ) ); +} + +static void des3_set3key( unsigned long esk[96], + unsigned long dsk[96], + unsigned char key[24] ) +{ + int i; + + des_setkey( esk, key ); + des_setkey( dsk + 32, key + 8 ); + des_setkey( esk + 64, key + 16 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[94 - i]; + dsk[i + 1] = esk[95 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + dsk[i + 64] = esk[30 - i]; + dsk[i + 65] = esk[31 - i]; + } +} + +/* + * Triple-DES key schedule (168-bit, encryption) + */ +void des3_set3key_enc( des3_context *ctx, unsigned char key[24] ) +{ + unsigned long sk[96]; + + des3_set3key( ctx->sk, sk, key ); + memset( sk, 0, sizeof( sk ) ); +} + +/* + * Triple-DES key schedule (168-bit, decryption) + */ +void des3_set3key_dec( des3_context *ctx, unsigned char key[24] ) +{ + unsigned long sk[96]; + + des3_set3key( sk, ctx->sk, key ); + memset( sk, 0, sizeof( sk ) ); } /* * DES-ECB block encryption/decryption */ -int des_crypt_ecb( des_context *ctx, - const unsigned char input[8], +void des_crypt_ecb( des_context *ctx, + unsigned char input[8], unsigned char output[8] ) { int i; @@ -411,8 +512,380 @@ int des_crypt_ecb( des_context *ctx, PUT_ULONG_BE( Y, output, 0 ); PUT_ULONG_BE( X, output, 4 ); +} + +/* + * DES-CBC buffer encryption/decryption + */ +void des_crypt_cbc( des_context *ctx, + int mode, + int length, + unsigned char iv[8], + unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[8]; + + if( mode == DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + des_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + des_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } +} + +/* + * 3DES-ECB block encryption/decryption + */ +void des3_crypt_ecb( des3_context *ctx, + unsigned char input[8], + unsigned char output[8] ) +{ + int i; + unsigned long X, Y, T, *SK; + + SK = ctx->sk; + + GET_ULONG_BE( X, input, 0 ); + GET_ULONG_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( X, Y ); + DES_ROUND( Y, X ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_ULONG_BE( Y, output, 0 ); + PUT_ULONG_BE( X, output, 4 ); +} + +/* + * 3DES-CBC buffer encryption/decryption + */ +void des3_crypt_cbc( des3_context *ctx, + int mode, + int length, + unsigned char iv[8], + unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[8]; + + if( mode == DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + des3_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + des3_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } +} + +#if defined(POLARSSL_SELF_TEST) + +#include + +/* + * DES and 3DES test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip + */ +static const unsigned char des3_test_keys[24] = +{ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 +}; + +static const unsigned char des3_test_iv[8] = +{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, +}; + +static const unsigned char des3_test_buf[8] = +{ + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 +}; + +static const unsigned char des3_test_ecb_dec[3][8] = +{ + { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, + { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, + { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } +}; + +static const unsigned char des3_test_ecb_enc[3][8] = +{ + { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, + { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, + { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } +}; + +static const unsigned char des3_test_cbc_dec[3][8] = +{ + { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, + { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, + { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } +}; + +static const unsigned char des3_test_cbc_enc[3][8] = +{ + { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, + { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, + { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } +}; + +/* + * Checkup routine + */ +int des_self_test( int verbose ) +{ + int i, j, u, v; + des_context ctx; + des3_context ctx3; + unsigned char key[24]; + unsigned char buf[8]; + unsigned char prv[8]; + unsigned char iv[8]; + + memset( key, 0, 24 ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + printf( " DES%c-ECB-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + des_setkey_dec( &ctx, (unsigned char *) des3_test_keys ); + break; + + case 1: + des_setkey_enc( &ctx, (unsigned char *) des3_test_keys ); + break; + + case 2: + des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys ); + break; + + case 3: + des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys ); + break; + + case 4: + des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys ); + break; + + case 5: + des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys ); + break; + + default: + return( 1 ); + } + + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + des_crypt_ecb( &ctx, buf, buf ); + else + des3_crypt_ecb( &ctx3, buf, buf ); + } + + if( ( v == DES_DECRYPT && + memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || + ( v != DES_DECRYPT && + memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + printf( " DES%c-CBC-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, des3_test_iv, 8 ); + memcpy( prv, des3_test_iv, 8 ); + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + des_setkey_dec( &ctx, (unsigned char *) des3_test_keys ); + break; + + case 1: + des_setkey_enc( &ctx, (unsigned char *) des3_test_keys ); + break; + + case 2: + des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys ); + break; + + case 3: + des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys ); + break; + + case 4: + des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys ); + break; + + case 5: + des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys ); + break; + + default: + return( 1 ); + } + + if( v == DES_DECRYPT ) + { + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + } + } + else + { + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[8]; + + if( u == 0 ) + des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + + memcpy( tmp, prv, 8 ); + memcpy( prv, buf, 8 ); + memcpy( buf, tmp, 8 ); + } + + memcpy( buf, prv, 8 ); + } + + if( ( v == DES_DECRYPT && + memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || + ( v != DES_DECRYPT && + memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); return( 0 ); } -#endif /* LWIP_INCLUDED_POLARSSL_DES_C */ +#endif + +#endif diff --git a/src/netif/ppp/polarssl/des.h b/src/netif/ppp/polarssl/des.h index 21d84601..d70ac953 100644 --- a/src/netif/ppp/polarssl/des.h +++ b/src/netif/ppp/polarssl/des.h @@ -1,39 +1,43 @@ /** * \file des.h * - * \brief DES block cipher + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker + * Copyright (C) 2009 Paul Bakker * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LWIP_INCLUDED_POLARSSL_DES_H -#define LWIP_INCLUDED_POLARSSL_DES_H +#ifndef POLARSSL_DES_H +#define POLARSSL_DES_H #define DES_ENCRYPT 1 #define DES_DECRYPT 0 -#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ - -#define DES_KEY_SIZE 8 - /** * \brief DES context structure */ @@ -44,6 +48,16 @@ typedef struct } des_context; +/** + * \brief Triple-DES context structure + */ +typedef struct +{ + int mode; /*!< encrypt/decrypt */ + unsigned long sk[96]; /*!< 3DES subkeys */ +} +des3_context; + #ifdef __cplusplus extern "C" { #endif @@ -53,20 +67,48 @@ extern "C" { * * \param ctx DES context to be initialized * \param key 8-byte secret key - * - * \return 0 */ -int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); +void des_setkey_enc( des_context *ctx, unsigned char key[8] ); /** * \brief DES key schedule (56-bit, decryption) * * \param ctx DES context to be initialized * \param key 8-byte secret key - * - * \return 0 */ -int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); +void des_setkey_dec( des_context *ctx, unsigned char key[8] ); + +/** + * \brief Triple-DES key schedule (112-bit, encryption) + * + * \param ctx 3DES context to be initialized + * \param key 16-byte secret key + */ +void des3_set2key_enc( des3_context *ctx, unsigned char key[16] ); + +/** + * \brief Triple-DES key schedule (112-bit, decryption) + * + * \param ctx 3DES context to be initialized + * \param key 16-byte secret key + */ +void des3_set2key_dec( des3_context *ctx, unsigned char key[16] ); + +/** + * \brief Triple-DES key schedule (168-bit, encryption) + * + * \param ctx 3DES context to be initialized + * \param key 24-byte secret key + */ +void des3_set3key_enc( des3_context *ctx, unsigned char key[24] ); + +/** + * \brief Triple-DES key schedule (168-bit, decryption) + * + * \param ctx 3DES context to be initialized + * \param key 24-byte secret key + */ +void des3_set3key_dec( des3_context *ctx, unsigned char key[24] ); /** * \brief DES-ECB block encryption/decryption @@ -74,15 +116,65 @@ int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); * \param ctx DES context * \param input 64-bit input block * \param output 64-bit output block - * - * \return 0 if successful */ -int des_crypt_ecb( des_context *ctx, - const unsigned char input[8], +void des_crypt_ecb( des_context *ctx, + unsigned char input[8], unsigned char output[8] ); +/** + * \brief DES-CBC buffer encryption/decryption + * + * \param ctx DES context + * \param mode DES_ENCRYPT or DES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + */ +void des_crypt_cbc( des_context *ctx, + int mode, + int length, + unsigned char iv[8], + unsigned char *input, + unsigned char *output ); + +/** + * \brief 3DES-ECB block encryption/decryption + * + * \param ctx 3DES context + * \param input 64-bit input block + * \param output 64-bit output block + */ +void des3_crypt_ecb( des3_context *ctx, + unsigned char input[8], + unsigned char output[8] ); + +/** + * \brief 3DES-CBC buffer encryption/decryption + * + * \param ctx 3DES context + * \param mode DES_ENCRYPT or DES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + */ +void des3_crypt_cbc( des3_context *ctx, + int mode, + int length, + unsigned char iv[8], + unsigned char *input, + unsigned char *output ); + +/* + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int des_self_test( int verbose ); + #ifdef __cplusplus } #endif -#endif /* LWIP_INCLUDED_POLARSSL_DES_H */ +#endif /* des.h */ diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/md4.c index e5f715bc..e5f92ee8 100644 --- a/src/netif/ppp/polarssl/md4.c +++ b/src/netif/ppp/polarssl/md4.c @@ -1,26 +1,36 @@ /* * RFC 1186/1320 compliant MD4 implementation * - * Copyright (C) 2006-2010, Brainspark B.V. + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker + * Copyright (C) 2009 Paul Bakker * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * The MD4 algorithm was designed by Ron Rivest in 1990. @@ -29,11 +39,15 @@ * http://www.ietf.org/rfc/rfc1320.txt */ -#include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_MD4_C) +#include "polarssl/config.h" + +#if defined(POLARSSL_MD4_C) #include "polarssl/md4.h" +#include +#include + /* * 32-bit integer manipulation macros (little endian) */ @@ -71,7 +85,7 @@ void md4_starts( md4_context *ctx ) ctx->state[3] = 0x10325476; } -static void md4_process( md4_context *ctx, const unsigned char data[64] ) +static void md4_process( md4_context *ctx, unsigned char data[64] ) { unsigned long X[16], A, B, C, D; @@ -177,9 +191,9 @@ static void md4_process( md4_context *ctx, const unsigned char data[64] ) /* * MD4 process buffer */ -void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ) +void md4_update( md4_context *ctx, unsigned char *input, int ilen ) { - size_t fill; + int fill; unsigned long left; if( ilen <= 0 ) @@ -188,7 +202,7 @@ void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ) left = ctx->total[0] & 0x3F; fill = 64 - left; - ctx->total[0] += (unsigned long) ilen; + ctx->total[0] += ilen; ctx->total[0] &= 0xFFFFFFFF; if( ctx->total[0] < (unsigned long) ilen ) @@ -257,7 +271,7 @@ void md4_finish( md4_context *ctx, unsigned char output[16] ) /* * output = MD4( input buffer ) */ -void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) +void md4( unsigned char *input, int ilen, unsigned char output[16] ) { md4_context ctx; @@ -268,4 +282,176 @@ void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) memset( &ctx, 0, sizeof( md4_context ) ); } -#endif /* LWIP_INCLUDED_POLARSSL_MD4_C */ +/* + * output = MD4( file contents ) + */ +int md4_file( char *path, unsigned char output[16] ) +{ + FILE *f; + size_t n; + md4_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( 1 ); + + md4_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + md4_update( &ctx, buf, (int) n ); + + md4_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md4_context ) ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( 2 ); + } + + fclose( f ); + return( 0 ); +} + +/* + * MD4 HMAC context setup + */ +void md4_hmac_starts( md4_context *ctx, unsigned char *key, int keylen ) +{ + int i; + unsigned char sum[16]; + + if( keylen > 64 ) + { + md4( key, keylen, sum ); + keylen = 16; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + md4_starts( ctx ); + md4_update( ctx, ctx->ipad, 64 ); + + memset( sum, 0, sizeof( sum ) ); +} + +/* + * MD4 HMAC process buffer + */ +void md4_hmac_update( md4_context *ctx, unsigned char *input, int ilen ) +{ + md4_update( ctx, input, ilen ); +} + +/* + * MD4 HMAC final digest + */ +void md4_hmac_finish( md4_context *ctx, unsigned char output[16] ) +{ + unsigned char tmpbuf[16]; + + md4_finish( ctx, tmpbuf ); + md4_starts( ctx ); + md4_update( ctx, ctx->opad, 64 ); + md4_update( ctx, tmpbuf, 16 ); + md4_finish( ctx, output ); + + memset( tmpbuf, 0, sizeof( tmpbuf ) ); +} + +/* + * output = HMAC-MD4( hmac key, input buffer ) + */ +void md4_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen, + unsigned char output[16] ) +{ + md4_context ctx; + + md4_hmac_starts( &ctx, key, keylen ); + md4_hmac_update( &ctx, input, ilen ); + md4_hmac_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md4_context ) ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * RFC 1320 test vectors + */ +static const char md4_test_str[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const unsigned char md4_test_sum[7][16] = +{ + { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, + 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, + { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, + 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, + { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, + 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, + { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, + 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, + { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, + 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, + { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, + 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, + { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, + 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } +}; + +/* + * Checkup routine + */ +int md4_self_test( int verbose ) +{ + int i; + unsigned char md4sum[16]; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + printf( " MD4 test #%d: ", i + 1 ); + + md4( (unsigned char *) md4_test_str[i], + strlen( md4_test_str[i] ), md4sum ); + + if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + return( 0 ); +} + +#endif + +#endif diff --git a/src/netif/ppp/polarssl/md4.h b/src/netif/ppp/polarssl/md4.h index 1ad8250f..9032330a 100644 --- a/src/netif/ppp/polarssl/md4.h +++ b/src/netif/ppp/polarssl/md4.h @@ -1,31 +1,39 @@ /** * \file md4.h * - * \brief MD4 message digest algorithm (hash function) + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker + * Copyright (C) 2009 Paul Bakker * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LWIP_INCLUDED_POLARSSL_MD4_H -#define LWIP_INCLUDED_POLARSSL_MD4_H +#ifndef POLARSSL_MD4_H +#define POLARSSL_MD4_H /** * \brief MD4 context structure @@ -35,6 +43,9 @@ typedef struct unsigned long total[2]; /*!< number of bytes processed */ unsigned long state[4]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ } md4_context; @@ -56,7 +67,7 @@ void md4_starts( md4_context *ctx ); * \param input buffer holding the data * \param ilen length of the input data */ -void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ); +void md4_update( md4_context *ctx, unsigned char *input, int ilen ); /** * \brief MD4 final digest @@ -73,10 +84,67 @@ void md4_finish( md4_context *ctx, unsigned char output[16] ); * \param ilen length of the input data * \param output MD4 checksum result */ -void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ); +void md4( unsigned char *input, int ilen, unsigned char output[16] ); + +/** + * \brief Output = MD4( file contents ) + * + * \param path input file name + * \param output MD4 checksum result + * + * \return 0 if successful, 1 if fopen failed, + * or 2 if fread failed + */ +int md4_file( char *path, unsigned char output[16] ); + +/** + * \brief MD4 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void md4_hmac_starts( md4_context *ctx, unsigned char *key, int keylen ); + +/** + * \brief MD4 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md4_hmac_update( md4_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief MD4 HMAC final digest + * + * \param ctx HMAC context + * \param output MD4 HMAC checksum result + */ +void md4_hmac_finish( md4_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = HMAC-MD4( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-MD4 result + */ +void md4_hmac( unsigned char *key, int keylen, + unsigned char *input, int ilen, + unsigned char output[16] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int md4_self_test( int verbose ); #ifdef __cplusplus } #endif -#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ +#endif /* md4.h */ diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/md5.c index 621a5372..2d381554 100644 --- a/src/netif/ppp/polarssl/md5.c +++ b/src/netif/ppp/polarssl/md5.c @@ -1,26 +1,36 @@ /* * RFC 1321 compliant MD5 implementation * - * Copyright (C) 2006-2010, Brainspark B.V. + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker + * Copyright (C) 2009 Paul Bakker * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * The MD5 algorithm was designed by Ron Rivest in 1991. @@ -28,11 +38,15 @@ * http://www.ietf.org/rfc/rfc1321.txt */ -#include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_MD5_C) +#include "polarssl/config.h" + +#if defined(POLARSSL_MD5_C) #include "polarssl/md5.h" +#include +#include + /* * 32-bit integer manipulation macros (little endian) */ @@ -70,7 +84,7 @@ void md5_starts( md5_context *ctx ) ctx->state[3] = 0x10325476; } -static void md5_process( md5_context *ctx, const unsigned char data[64] ) +static void md5_process( md5_context *ctx, unsigned char data[64] ) { unsigned long X[16], A, B, C, D; @@ -196,9 +210,9 @@ static void md5_process( md5_context *ctx, const unsigned char data[64] ) /* * MD5 process buffer */ -void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) +void md5_update( md5_context *ctx, unsigned char *input, int ilen ) { - size_t fill; + int fill; unsigned long left; if( ilen <= 0 ) @@ -207,7 +221,7 @@ void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) left = ctx->total[0] & 0x3F; fill = 64 - left; - ctx->total[0] += (unsigned long) ilen; + ctx->total[0] += ilen; ctx->total[0] &= 0xFFFFFFFF; if( ctx->total[0] < (unsigned long) ilen ) @@ -276,7 +290,7 @@ void md5_finish( md5_context *ctx, unsigned char output[16] ) /* * output = MD5( input buffer ) */ -void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) +void md5( unsigned char *input, int ilen, unsigned char output[16] ) { md5_context ctx; @@ -287,4 +301,280 @@ void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) memset( &ctx, 0, sizeof( md5_context ) ); } -#endif /* LWIP_INCLUDED_POLARSSL_MD5_C */ +/* + * output = MD5( file contents ) + */ +int md5_file( char *path, unsigned char output[16] ) +{ + FILE *f; + size_t n; + md5_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( 1 ); + + md5_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + md5_update( &ctx, buf, (int) n ); + + md5_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md5_context ) ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( 2 ); + } + + fclose( f ); + return( 0 ); +} + +/* + * MD5 HMAC context setup + */ +void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ) +{ + int i; + unsigned char sum[16]; + + if( keylen > 64 ) + { + md5( key, keylen, sum ); + keylen = 16; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + md5_starts( ctx ); + md5_update( ctx, ctx->ipad, 64 ); + + memset( sum, 0, sizeof( sum ) ); +} + +/* + * MD5 HMAC process buffer + */ +void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ) +{ + md5_update( ctx, input, ilen ); +} + +/* + * MD5 HMAC final digest + */ +void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ) +{ + unsigned char tmpbuf[16]; + + md5_finish( ctx, tmpbuf ); + md5_starts( ctx ); + md5_update( ctx, ctx->opad, 64 ); + md5_update( ctx, tmpbuf, 16 ); + md5_finish( ctx, output ); + + memset( tmpbuf, 0, sizeof( tmpbuf ) ); +} + +/* + * output = HMAC-MD5( hmac key, input buffer ) + */ +void md5_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen, + unsigned char output[16] ) +{ + md5_context ctx; + + md5_hmac_starts( &ctx, key, keylen ); + md5_hmac_update( &ctx, input, ilen ); + md5_hmac_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md5_context ) ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * RFC 1321 test vectors + */ +static unsigned char md5_test_buf[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const int md5_test_buflen[7] = +{ + 0, 1, 3, 14, 26, 62, 80 +}; + +static const unsigned char md5_test_sum[7][16] = +{ + { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, + { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, + 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, + { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, + 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, + { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, + 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, + { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, + 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, + { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, + 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, + { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char md5_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int md5_hmac_test_keylen[7] = +{ + 16, 4, 16, 25, 16, 80, 80 +}; + +static unsigned char md5_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int md5_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char md5_hmac_test_sum[7][16] = +{ + { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C, + 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D }, + { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03, + 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 }, + { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88, + 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 }, + { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA, + 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 }, + { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00, + 0xF9, 0xBA, 0xB9, 0x95 }, + { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F, + 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD }, + { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE, + 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E } +}; + +/* + * Checkup routine + */ +int md5_self_test( int verbose ) +{ + int i, buflen; + unsigned char buf[1024]; + unsigned char md5sum[16]; + md5_context ctx; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + printf( " MD5 test #%d: ", i + 1 ); + + md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); + + if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + printf( " HMAC-MD5 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + md5_hmac_starts( &ctx, buf, buflen ); + } + else + md5_hmac_starts( &ctx, md5_hmac_test_key[i], + md5_hmac_test_keylen[i] ); + + md5_hmac_update( &ctx, md5_hmac_test_buf[i], + md5_hmac_test_buflen[i] ); + + md5_hmac_finish( &ctx, md5sum ); + + buflen = ( i == 4 ) ? 12 : 16; + + if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + return( 0 ); +} + +#endif + +#endif diff --git a/src/netif/ppp/polarssl/md5.h b/src/netif/ppp/polarssl/md5.h index 389b4154..61af7647 100644 --- a/src/netif/ppp/polarssl/md5.h +++ b/src/netif/ppp/polarssl/md5.h @@ -1,31 +1,39 @@ /** * \file md5.h * - * \brief MD5 message digest algorithm (hash function) + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker + * Copyright (C) 2009 Paul Bakker * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LWIP_INCLUDED_POLARSSL_MD5_H -#define LWIP_INCLUDED_POLARSSL_MD5_H +#ifndef POLARSSL_MD5_H +#define POLARSSL_MD5_H /** * \brief MD5 context structure @@ -35,6 +43,9 @@ typedef struct unsigned long total[2]; /*!< number of bytes processed */ unsigned long state[4]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ } md5_context; @@ -56,7 +67,7 @@ void md5_starts( md5_context *ctx ); * \param input buffer holding the data * \param ilen length of the input data */ -void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ); +void md5_update( md5_context *ctx, unsigned char *input, int ilen ); /** * \brief MD5 final digest @@ -73,10 +84,67 @@ void md5_finish( md5_context *ctx, unsigned char output[16] ); * \param ilen length of the input data * \param output MD5 checksum result */ -void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ); +void md5( unsigned char *input, int ilen, unsigned char output[16] ); + +/** + * \brief Output = MD5( file contents ) + * + * \param path input file name + * \param output MD5 checksum result + * + * \return 0 if successful, 1 if fopen failed, + * or 2 if fread failed + */ +int md5_file( char *path, unsigned char output[16] ); + +/** + * \brief MD5 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ); + +/** + * \brief MD5 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief MD5 HMAC final digest + * + * \param ctx HMAC context + * \param output MD5 HMAC checksum result + */ +void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = HMAC-MD5( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-MD5 result + */ +void md5_hmac( unsigned char *key, int keylen, + unsigned char *input, int ilen, + unsigned char output[16] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int md5_self_test( int verbose ); #ifdef __cplusplus } #endif -#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ +#endif /* md5.h */ diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/sha1.c index 5e9a661f..54a4416f 100644 --- a/src/netif/ppp/polarssl/sha1.c +++ b/src/netif/ppp/polarssl/sha1.c @@ -1,26 +1,36 @@ /* * FIPS-180-1 compliant SHA-1 implementation * - * Copyright (C) 2006-2010, Brainspark B.V. + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker + * Copyright (C) 2009 Paul Bakker * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * The SHA-1 standard was published by NIST in 1993. @@ -28,11 +38,15 @@ * http://www.itl.nist.gov/fipspubs/fip180-1.htm */ -#include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_SHA1_C) +#include "polarssl/config.h" + +#if defined(POLARSSL_SHA1_C) #include "polarssl/sha1.h" +#include +#include + /* * 32-bit integer manipulation macros (big endian) */ @@ -71,7 +85,7 @@ void sha1_starts( sha1_context *ctx ) ctx->state[4] = 0xC3D2E1F0; } -static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) +static void sha1_process( sha1_context *ctx, unsigned char data[64] ) { unsigned long temp, W[16], A, B, C, D, E; @@ -230,9 +244,9 @@ static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) /* * SHA-1 process buffer */ -void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) +void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ) { - size_t fill; + int fill; unsigned long left; if( ilen <= 0 ) @@ -241,7 +255,7 @@ void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) left = ctx->total[0] & 0x3F; fill = 64 - left; - ctx->total[0] += (unsigned long) ilen; + ctx->total[0] += ilen; ctx->total[0] &= 0xFFFFFFFF; if( ctx->total[0] < (unsigned long) ilen ) @@ -311,7 +325,7 @@ void sha1_finish( sha1_context *ctx, unsigned char output[20] ) /* * output = SHA-1( input buffer ) */ -void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) +void sha1( unsigned char *input, int ilen, unsigned char output[20] ) { sha1_context ctx; @@ -322,4 +336,287 @@ void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) memset( &ctx, 0, sizeof( sha1_context ) ); } -#endif /* LWIP_INCLUDED_POLARSSL_SHA1_C */ +/* + * output = SHA-1( file contents ) + */ +int sha1_file( char *path, unsigned char output[20] ) +{ + FILE *f; + size_t n; + sha1_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( 1 ); + + sha1_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha1_update( &ctx, buf, (int) n ); + + sha1_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha1_context ) ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( 2 ); + } + + fclose( f ); + return( 0 ); +} + +/* + * SHA-1 HMAC context setup + */ +void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ) +{ + int i; + unsigned char sum[20]; + + if( keylen > 64 ) + { + sha1( key, keylen, sum ); + keylen = 20; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha1_starts( ctx ); + sha1_update( ctx, ctx->ipad, 64 ); + + memset( sum, 0, sizeof( sum ) ); +} + +/* + * SHA-1 HMAC process buffer + */ +void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ) +{ + sha1_update( ctx, input, ilen ); +} + +/* + * SHA-1 HMAC final digest + */ +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned char tmpbuf[20]; + + sha1_finish( ctx, tmpbuf ); + sha1_starts( ctx ); + sha1_update( ctx, ctx->opad, 64 ); + sha1_update( ctx, tmpbuf, 20 ); + sha1_finish( ctx, output ); + + memset( tmpbuf, 0, sizeof( tmpbuf ) ); +} + +/* + * output = HMAC-SHA-1( hmac key, input buffer ) + */ +void sha1_hmac( unsigned char *key, int keylen, + unsigned char *input, int ilen, + unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_hmac_starts( &ctx, key, keylen ); + sha1_hmac_update( &ctx, input, ilen ); + sha1_hmac_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha1_context ) ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * FIPS-180-1 test vectors + */ +static unsigned char sha1_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha1_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha1_test_sum[3][20] = +{ + { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, + { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, + 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char sha1_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int sha1_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 80, 80 +}; + +static unsigned char sha1_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int sha1_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char sha1_hmac_test_sum[7][20] = +{ + { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B, + 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 }, + { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74, + 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 }, + { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3, + 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 }, + { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84, + 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA }, + { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2, + 0x7B, 0xE1 }, + { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70, + 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 }, + { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B, + 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 } +}; + +/* + * Checkup routine + */ +int sha1_self_test( int verbose ) +{ + int i, j, buflen; + unsigned char buf[1024]; + unsigned char sha1sum[20]; + sha1_context ctx; + + /* + * SHA-1 + */ + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + printf( " SHA-1 test #%d: ", i + 1 ); + + sha1_starts( &ctx ); + + if( i == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha1_update( &ctx, buf, buflen ); + } + else + sha1_update( &ctx, sha1_test_buf[i], + sha1_test_buflen[i] ); + + sha1_finish( &ctx, sha1sum ); + + if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + printf( " HMAC-SHA-1 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + sha1_hmac_starts( &ctx, buf, buflen ); + } + else + sha1_hmac_starts( &ctx, sha1_hmac_test_key[i], + sha1_hmac_test_keylen[i] ); + + sha1_hmac_update( &ctx, sha1_hmac_test_buf[i], + sha1_hmac_test_buflen[i] ); + + sha1_hmac_finish( &ctx, sha1sum ); + + buflen = ( i == 4 ) ? 12 : 20; + + if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + return( 0 ); +} + +#endif + +#endif diff --git a/src/netif/ppp/polarssl/sha1.h b/src/netif/ppp/polarssl/sha1.h index b01e93f4..3ca7dc31 100644 --- a/src/netif/ppp/polarssl/sha1.h +++ b/src/netif/ppp/polarssl/sha1.h @@ -1,31 +1,39 @@ /** * \file sha1.h * - * \brief SHA-1 cryptographic hash function + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker + * Copyright (C) 2009 Paul Bakker * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H -#define LWIP_INCLUDED_POLARSSL_SHA1_H +#ifndef POLARSSL_SHA1_H +#define POLARSSL_SHA1_H /** * \brief SHA-1 context structure @@ -35,6 +43,9 @@ typedef struct unsigned long total[2]; /*!< number of bytes processed */ unsigned long state[5]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ } sha1_context; @@ -56,7 +67,7 @@ void sha1_starts( sha1_context *ctx ); * \param input buffer holding the data * \param ilen length of the input data */ -void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ); +void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ); /** * \brief SHA-1 final digest @@ -73,10 +84,67 @@ void sha1_finish( sha1_context *ctx, unsigned char output[20] ); * \param ilen length of the input data * \param output SHA-1 checksum result */ -void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); +void sha1( unsigned char *input, int ilen, unsigned char output[20] ); + +/** + * \brief Output = SHA-1( file contents ) + * + * \param path input file name + * \param output SHA-1 checksum result + * + * \return 0 if successful, 1 if fopen failed, + * or 2 if fread failed + */ +int sha1_file( char *path, unsigned char output[20] ); + +/** + * \brief SHA-1 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ); + +/** + * \brief SHA-1 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief SHA-1 HMAC final digest + * + * \param ctx HMAC context + * \param output SHA-1 HMAC checksum result + */ +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ); + +/** + * \brief Output = HMAC-SHA-1( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-SHA-1 result + */ +void sha1_hmac( unsigned char *key, int keylen, + unsigned char *input, int ilen, + unsigned char output[20] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int sha1_self_test( int verbose ); #ifdef __cplusplus } #endif -#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ +#endif /* sha1.h */ From dea27e105d5dc8e6586f1a00bc4b82ac3e11c909 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 22:48:41 +0200 Subject: [PATCH 040/320] cleaned PolarSSL files --- src/netif/ppp/polarssl/des.c | 475 +--------------------------------- src/netif/ppp/polarssl/des.h | 100 +------ src/netif/ppp/polarssl/md4.c | 182 +------------ src/netif/ppp/polarssl/md4.h | 62 +---- src/netif/ppp/polarssl/md5.c | 286 +------------------- src/netif/ppp/polarssl/md5.h | 63 +---- src/netif/ppp/polarssl/sha1.c | 293 +-------------------- src/netif/ppp/polarssl/sha1.h | 63 +---- 8 files changed, 24 insertions(+), 1500 deletions(-) diff --git a/src/netif/ppp/polarssl/des.c b/src/netif/ppp/polarssl/des.c index fcefd727..ac23cbc2 100644 --- a/src/netif/ppp/polarssl/des.c +++ b/src/netif/ppp/polarssl/des.c @@ -39,14 +39,11 @@ * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf */ -#include "polarssl/config.h" - -#if defined(POLARSSL_DES_C) +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_DES_C) #include "polarssl/des.h" -#include - /* * 32-bit integer manipulation macros (big endian) */ @@ -393,98 +390,6 @@ void des_setkey_dec( des_context *ctx, unsigned char key[8] ) } } -static void des3_set2key( unsigned long esk[96], - unsigned long dsk[96], - unsigned char key[16] ) -{ - int i; - - des_setkey( esk, key ); - des_setkey( dsk + 32, key + 8 ); - - for( i = 0; i < 32; i += 2 ) - { - dsk[i ] = esk[30 - i]; - dsk[i + 1] = esk[31 - i]; - - esk[i + 32] = dsk[62 - i]; - esk[i + 33] = dsk[63 - i]; - - esk[i + 64] = esk[i ]; - esk[i + 65] = esk[i + 1]; - - dsk[i + 64] = dsk[i ]; - dsk[i + 65] = dsk[i + 1]; - } -} - -/* - * Triple-DES key schedule (112-bit, encryption) - */ -void des3_set2key_enc( des3_context *ctx, unsigned char key[16] ) -{ - unsigned long sk[96]; - - des3_set2key( ctx->sk, sk, key ); - memset( sk, 0, sizeof( sk ) ); -} - -/* - * Triple-DES key schedule (112-bit, decryption) - */ -void des3_set2key_dec( des3_context *ctx, unsigned char key[16] ) -{ - unsigned long sk[96]; - - des3_set2key( sk, ctx->sk, key ); - memset( sk, 0, sizeof( sk ) ); -} - -static void des3_set3key( unsigned long esk[96], - unsigned long dsk[96], - unsigned char key[24] ) -{ - int i; - - des_setkey( esk, key ); - des_setkey( dsk + 32, key + 8 ); - des_setkey( esk + 64, key + 16 ); - - for( i = 0; i < 32; i += 2 ) - { - dsk[i ] = esk[94 - i]; - dsk[i + 1] = esk[95 - i]; - - esk[i + 32] = dsk[62 - i]; - esk[i + 33] = dsk[63 - i]; - - dsk[i + 64] = esk[30 - i]; - dsk[i + 65] = esk[31 - i]; - } -} - -/* - * Triple-DES key schedule (168-bit, encryption) - */ -void des3_set3key_enc( des3_context *ctx, unsigned char key[24] ) -{ - unsigned long sk[96]; - - des3_set3key( ctx->sk, sk, key ); - memset( sk, 0, sizeof( sk ) ); -} - -/* - * Triple-DES key schedule (168-bit, decryption) - */ -void des3_set3key_dec( des3_context *ctx, unsigned char key[24] ) -{ - unsigned long sk[96]; - - des3_set3key( sk, ctx->sk, key ); - memset( sk, 0, sizeof( sk ) ); -} - /* * DES-ECB block encryption/decryption */ @@ -514,378 +419,4 @@ void des_crypt_ecb( des_context *ctx, PUT_ULONG_BE( X, output, 4 ); } -/* - * DES-CBC buffer encryption/decryption - */ -void des_crypt_cbc( des_context *ctx, - int mode, - int length, - unsigned char iv[8], - unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[8]; - - if( mode == DES_ENCRYPT ) - { - while( length > 0 ) - { - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - des_crypt_ecb( ctx, output, output ); - memcpy( iv, output, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - else /* DES_DECRYPT */ - { - while( length > 0 ) - { - memcpy( temp, input, 8 ); - des_crypt_ecb( ctx, input, output ); - - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } -} - -/* - * 3DES-ECB block encryption/decryption - */ -void des3_crypt_ecb( des3_context *ctx, - unsigned char input[8], - unsigned char output[8] ) -{ - int i; - unsigned long X, Y, T, *SK; - - SK = ctx->sk; - - GET_ULONG_BE( X, input, 0 ); - GET_ULONG_BE( Y, input, 4 ); - - DES_IP( X, Y ); - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( Y, X ); - DES_ROUND( X, Y ); - } - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( X, Y ); - DES_ROUND( Y, X ); - } - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( Y, X ); - DES_ROUND( X, Y ); - } - - DES_FP( Y, X ); - - PUT_ULONG_BE( Y, output, 0 ); - PUT_ULONG_BE( X, output, 4 ); -} - -/* - * 3DES-CBC buffer encryption/decryption - */ -void des3_crypt_cbc( des3_context *ctx, - int mode, - int length, - unsigned char iv[8], - unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[8]; - - if( mode == DES_ENCRYPT ) - { - while( length > 0 ) - { - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - des3_crypt_ecb( ctx, output, output ); - memcpy( iv, output, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } - else /* DES_DECRYPT */ - { - while( length > 0 ) - { - memcpy( temp, input, 8 ); - des3_crypt_ecb( ctx, input, output ); - - for( i = 0; i < 8; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 8 ); - - input += 8; - output += 8; - length -= 8; - } - } -} - -#if defined(POLARSSL_SELF_TEST) - -#include - -/* - * DES and 3DES test vectors from: - * - * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip - */ -static const unsigned char des3_test_keys[24] = -{ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, - 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 -}; - -static const unsigned char des3_test_iv[8] = -{ - 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, -}; - -static const unsigned char des3_test_buf[8] = -{ - 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 -}; - -static const unsigned char des3_test_ecb_dec[3][8] = -{ - { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, - { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, - { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } -}; - -static const unsigned char des3_test_ecb_enc[3][8] = -{ - { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, - { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, - { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } -}; - -static const unsigned char des3_test_cbc_dec[3][8] = -{ - { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, - { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, - { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } -}; - -static const unsigned char des3_test_cbc_enc[3][8] = -{ - { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, - { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, - { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } -}; - -/* - * Checkup routine - */ -int des_self_test( int verbose ) -{ - int i, j, u, v; - des_context ctx; - des3_context ctx3; - unsigned char key[24]; - unsigned char buf[8]; - unsigned char prv[8]; - unsigned char iv[8]; - - memset( key, 0, 24 ); - - /* - * ECB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - printf( " DES%c-ECB-%3d (%s): ", - ( u == 0 ) ? ' ' : '3', 56 + u * 56, - ( v == DES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( buf, des3_test_buf, 8 ); - - switch( i ) - { - case 0: - des_setkey_dec( &ctx, (unsigned char *) des3_test_keys ); - break; - - case 1: - des_setkey_enc( &ctx, (unsigned char *) des3_test_keys ); - break; - - case 2: - des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys ); - break; - - case 3: - des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys ); - break; - - case 4: - des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys ); - break; - - case 5: - des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys ); - break; - - default: - return( 1 ); - } - - for( j = 0; j < 10000; j++ ) - { - if( u == 0 ) - des_crypt_ecb( &ctx, buf, buf ); - else - des3_crypt_ecb( &ctx3, buf, buf ); - } - - if( ( v == DES_DECRYPT && - memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || - ( v != DES_DECRYPT && - memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - /* - * CBC mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - printf( " DES%c-CBC-%3d (%s): ", - ( u == 0 ) ? ' ' : '3', 56 + u * 56, - ( v == DES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, des3_test_iv, 8 ); - memcpy( prv, des3_test_iv, 8 ); - memcpy( buf, des3_test_buf, 8 ); - - switch( i ) - { - case 0: - des_setkey_dec( &ctx, (unsigned char *) des3_test_keys ); - break; - - case 1: - des_setkey_enc( &ctx, (unsigned char *) des3_test_keys ); - break; - - case 2: - des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys ); - break; - - case 3: - des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys ); - break; - - case 4: - des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys ); - break; - - case 5: - des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys ); - break; - - default: - return( 1 ); - } - - if( v == DES_DECRYPT ) - { - for( j = 0; j < 10000; j++ ) - { - if( u == 0 ) - des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); - else - des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); - } - } - else - { - for( j = 0; j < 10000; j++ ) - { - unsigned char tmp[8]; - - if( u == 0 ) - des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); - else - des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); - - memcpy( tmp, prv, 8 ); - memcpy( prv, buf, 8 ); - memcpy( buf, tmp, 8 ); - } - - memcpy( buf, prv, 8 ); - } - - if( ( v == DES_DECRYPT && - memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || - ( v != DES_DECRYPT && - memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - return( 0 ); -} - -#endif - -#endif +#endif /* LWIP_INCLUDED_POLARSSL_DES_C */ diff --git a/src/netif/ppp/polarssl/des.h b/src/netif/ppp/polarssl/des.h index d70ac953..abe4652a 100644 --- a/src/netif/ppp/polarssl/des.h +++ b/src/netif/ppp/polarssl/des.h @@ -32,8 +32,8 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef POLARSSL_DES_H -#define POLARSSL_DES_H +#ifndef LWIP_INCLUDED_POLARSSL_DES_H +#define LWIP_INCLUDED_POLARSSL_DES_H #define DES_ENCRYPT 1 #define DES_DECRYPT 0 @@ -48,16 +48,6 @@ typedef struct } des_context; -/** - * \brief Triple-DES context structure - */ -typedef struct -{ - int mode; /*!< encrypt/decrypt */ - unsigned long sk[96]; /*!< 3DES subkeys */ -} -des3_context; - #ifdef __cplusplus extern "C" { #endif @@ -78,38 +68,6 @@ void des_setkey_enc( des_context *ctx, unsigned char key[8] ); */ void des_setkey_dec( des_context *ctx, unsigned char key[8] ); -/** - * \brief Triple-DES key schedule (112-bit, encryption) - * - * \param ctx 3DES context to be initialized - * \param key 16-byte secret key - */ -void des3_set2key_enc( des3_context *ctx, unsigned char key[16] ); - -/** - * \brief Triple-DES key schedule (112-bit, decryption) - * - * \param ctx 3DES context to be initialized - * \param key 16-byte secret key - */ -void des3_set2key_dec( des3_context *ctx, unsigned char key[16] ); - -/** - * \brief Triple-DES key schedule (168-bit, encryption) - * - * \param ctx 3DES context to be initialized - * \param key 24-byte secret key - */ -void des3_set3key_enc( des3_context *ctx, unsigned char key[24] ); - -/** - * \brief Triple-DES key schedule (168-bit, decryption) - * - * \param ctx 3DES context to be initialized - * \param key 24-byte secret key - */ -void des3_set3key_dec( des3_context *ctx, unsigned char key[24] ); - /** * \brief DES-ECB block encryption/decryption * @@ -121,60 +79,8 @@ void des_crypt_ecb( des_context *ctx, unsigned char input[8], unsigned char output[8] ); -/** - * \brief DES-CBC buffer encryption/decryption - * - * \param ctx DES context - * \param mode DES_ENCRYPT or DES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - */ -void des_crypt_cbc( des_context *ctx, - int mode, - int length, - unsigned char iv[8], - unsigned char *input, - unsigned char *output ); - -/** - * \brief 3DES-ECB block encryption/decryption - * - * \param ctx 3DES context - * \param input 64-bit input block - * \param output 64-bit output block - */ -void des3_crypt_ecb( des3_context *ctx, - unsigned char input[8], - unsigned char output[8] ); - -/** - * \brief 3DES-CBC buffer encryption/decryption - * - * \param ctx 3DES context - * \param mode DES_ENCRYPT or DES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - */ -void des3_crypt_cbc( des3_context *ctx, - int mode, - int length, - unsigned char iv[8], - unsigned char *input, - unsigned char *output ); - -/* - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int des_self_test( int verbose ); - #ifdef __cplusplus } #endif -#endif /* des.h */ +#endif /* LWIP_INCLUDED_POLARSSL_DES_H */ diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/md4.c index e5f92ee8..0572acee 100644 --- a/src/netif/ppp/polarssl/md4.c +++ b/src/netif/ppp/polarssl/md4.c @@ -39,15 +39,11 @@ * http://www.ietf.org/rfc/rfc1320.txt */ -#include "polarssl/config.h" - -#if defined(POLARSSL_MD4_C) +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_MD4_C) #include "polarssl/md4.h" -#include -#include - /* * 32-bit integer manipulation macros (little endian) */ @@ -282,176 +278,4 @@ void md4( unsigned char *input, int ilen, unsigned char output[16] ) memset( &ctx, 0, sizeof( md4_context ) ); } -/* - * output = MD4( file contents ) - */ -int md4_file( char *path, unsigned char output[16] ) -{ - FILE *f; - size_t n; - md4_context ctx; - unsigned char buf[1024]; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( 1 ); - - md4_starts( &ctx ); - - while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - md4_update( &ctx, buf, (int) n ); - - md4_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md4_context ) ); - - if( ferror( f ) != 0 ) - { - fclose( f ); - return( 2 ); - } - - fclose( f ); - return( 0 ); -} - -/* - * MD4 HMAC context setup - */ -void md4_hmac_starts( md4_context *ctx, unsigned char *key, int keylen ) -{ - int i; - unsigned char sum[16]; - - if( keylen > 64 ) - { - md4( key, keylen, sum ); - keylen = 16; - key = sum; - } - - memset( ctx->ipad, 0x36, 64 ); - memset( ctx->opad, 0x5C, 64 ); - - for( i = 0; i < keylen; i++ ) - { - ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); - ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); - } - - md4_starts( ctx ); - md4_update( ctx, ctx->ipad, 64 ); - - memset( sum, 0, sizeof( sum ) ); -} - -/* - * MD4 HMAC process buffer - */ -void md4_hmac_update( md4_context *ctx, unsigned char *input, int ilen ) -{ - md4_update( ctx, input, ilen ); -} - -/* - * MD4 HMAC final digest - */ -void md4_hmac_finish( md4_context *ctx, unsigned char output[16] ) -{ - unsigned char tmpbuf[16]; - - md4_finish( ctx, tmpbuf ); - md4_starts( ctx ); - md4_update( ctx, ctx->opad, 64 ); - md4_update( ctx, tmpbuf, 16 ); - md4_finish( ctx, output ); - - memset( tmpbuf, 0, sizeof( tmpbuf ) ); -} - -/* - * output = HMAC-MD4( hmac key, input buffer ) - */ -void md4_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen, - unsigned char output[16] ) -{ - md4_context ctx; - - md4_hmac_starts( &ctx, key, keylen ); - md4_hmac_update( &ctx, input, ilen ); - md4_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md4_context ) ); -} - -#if defined(POLARSSL_SELF_TEST) - -/* - * RFC 1320 test vectors - */ -static const char md4_test_str[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" \ - "345678901234567890" } -}; - -static const unsigned char md4_test_sum[7][16] = -{ - { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, - 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, - { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, - 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, - { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, - 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, - { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, - 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, - { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, - 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, - { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, - 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, - { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, - 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } -}; - -/* - * Checkup routine - */ -int md4_self_test( int verbose ) -{ - int i; - unsigned char md4sum[16]; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - printf( " MD4 test #%d: ", i + 1 ); - - md4( (unsigned char *) md4_test_str[i], - strlen( md4_test_str[i] ), md4sum ); - - if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - return( 0 ); -} - -#endif - -#endif +#endif /* LWIP_INCLUDED_POLARSSL_MD4_C */ diff --git a/src/netif/ppp/polarssl/md4.h b/src/netif/ppp/polarssl/md4.h index 9032330a..86493dea 100644 --- a/src/netif/ppp/polarssl/md4.h +++ b/src/netif/ppp/polarssl/md4.h @@ -32,8 +32,8 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef POLARSSL_MD4_H -#define POLARSSL_MD4_H +#ifndef LWIP_INCLUDED_POLARSSL_MD4_H +#define LWIP_INCLUDED_POLARSSL_MD4_H /** * \brief MD4 context structure @@ -86,65 +86,9 @@ void md4_finish( md4_context *ctx, unsigned char output[16] ); */ void md4( unsigned char *input, int ilen, unsigned char output[16] ); -/** - * \brief Output = MD4( file contents ) - * - * \param path input file name - * \param output MD4 checksum result - * - * \return 0 if successful, 1 if fopen failed, - * or 2 if fread failed - */ -int md4_file( char *path, unsigned char output[16] ); - -/** - * \brief MD4 HMAC context setup - * - * \param ctx HMAC context to be initialized - * \param key HMAC secret key - * \param keylen length of the HMAC key - */ -void md4_hmac_starts( md4_context *ctx, unsigned char *key, int keylen ); - -/** - * \brief MD4 HMAC process buffer - * - * \param ctx HMAC context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md4_hmac_update( md4_context *ctx, unsigned char *input, int ilen ); - -/** - * \brief MD4 HMAC final digest - * - * \param ctx HMAC context - * \param output MD4 HMAC checksum result - */ -void md4_hmac_finish( md4_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = HMAC-MD4( hmac key, input buffer ) - * - * \param key HMAC secret key - * \param keylen length of the HMAC key - * \param input buffer holding the data - * \param ilen length of the input data - * \param output HMAC-MD4 result - */ -void md4_hmac( unsigned char *key, int keylen, - unsigned char *input, int ilen, - unsigned char output[16] ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int md4_self_test( int verbose ); #ifdef __cplusplus } #endif -#endif /* md4.h */ +#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/md5.c index 2d381554..cd800a92 100644 --- a/src/netif/ppp/polarssl/md5.c +++ b/src/netif/ppp/polarssl/md5.c @@ -38,15 +38,11 @@ * http://www.ietf.org/rfc/rfc1321.txt */ -#include "polarssl/config.h" - -#if defined(POLARSSL_MD5_C) +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_MD5_C) #include "polarssl/md5.h" -#include -#include - /* * 32-bit integer manipulation macros (little endian) */ @@ -301,280 +297,4 @@ void md5( unsigned char *input, int ilen, unsigned char output[16] ) memset( &ctx, 0, sizeof( md5_context ) ); } -/* - * output = MD5( file contents ) - */ -int md5_file( char *path, unsigned char output[16] ) -{ - FILE *f; - size_t n; - md5_context ctx; - unsigned char buf[1024]; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( 1 ); - - md5_starts( &ctx ); - - while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - md5_update( &ctx, buf, (int) n ); - - md5_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); - - if( ferror( f ) != 0 ) - { - fclose( f ); - return( 2 ); - } - - fclose( f ); - return( 0 ); -} - -/* - * MD5 HMAC context setup - */ -void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ) -{ - int i; - unsigned char sum[16]; - - if( keylen > 64 ) - { - md5( key, keylen, sum ); - keylen = 16; - key = sum; - } - - memset( ctx->ipad, 0x36, 64 ); - memset( ctx->opad, 0x5C, 64 ); - - for( i = 0; i < keylen; i++ ) - { - ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); - ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); - } - - md5_starts( ctx ); - md5_update( ctx, ctx->ipad, 64 ); - - memset( sum, 0, sizeof( sum ) ); -} - -/* - * MD5 HMAC process buffer - */ -void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ) -{ - md5_update( ctx, input, ilen ); -} - -/* - * MD5 HMAC final digest - */ -void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ) -{ - unsigned char tmpbuf[16]; - - md5_finish( ctx, tmpbuf ); - md5_starts( ctx ); - md5_update( ctx, ctx->opad, 64 ); - md5_update( ctx, tmpbuf, 16 ); - md5_finish( ctx, output ); - - memset( tmpbuf, 0, sizeof( tmpbuf ) ); -} - -/* - * output = HMAC-MD5( hmac key, input buffer ) - */ -void md5_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen, - unsigned char output[16] ) -{ - md5_context ctx; - - md5_hmac_starts( &ctx, key, keylen ); - md5_hmac_update( &ctx, input, ilen ); - md5_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); -} - -#if defined(POLARSSL_SELF_TEST) -/* - * RFC 1321 test vectors - */ -static unsigned char md5_test_buf[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" \ - "345678901234567890" } -}; - -static const int md5_test_buflen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md5_test_sum[7][16] = -{ - { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, - 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, - { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, - 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, - { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, - 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, - { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, - 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, - { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, - 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, - { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, - 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, - { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, - 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } -}; - -/* - * RFC 2202 test vectors - */ -static unsigned char md5_hmac_test_key[7][26] = -{ - { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" }, - { "Jefe" }, - { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" }, - { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" - "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, - { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" }, - { "" }, /* 0xAA 80 times */ - { "" } -}; - -static const int md5_hmac_test_keylen[7] = -{ - 16, 4, 16, 25, 16, 80, 80 -}; - -static unsigned char md5_hmac_test_buf[7][74] = -{ - { "Hi There" }, - { "what do ya want for nothing?" }, - { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, - { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, - { "Test With Truncation" }, - { "Test Using Larger Than Block-Size Key - Hash Key First" }, - { "Test Using Larger Than Block-Size Key and Larger" - " Than One Block-Size Data" } -}; - -static const int md5_hmac_test_buflen[7] = -{ - 8, 28, 50, 50, 20, 54, 73 -}; - -static const unsigned char md5_hmac_test_sum[7][16] = -{ - { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C, - 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D }, - { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03, - 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 }, - { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88, - 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 }, - { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA, - 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 }, - { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00, - 0xF9, 0xBA, 0xB9, 0x95 }, - { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F, - 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD }, - { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE, - 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E } -}; - -/* - * Checkup routine - */ -int md5_self_test( int verbose ) -{ - int i, buflen; - unsigned char buf[1024]; - unsigned char md5sum[16]; - md5_context ctx; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - printf( " MD5 test #%d: ", i + 1 ); - - md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); - - if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - printf( " HMAC-MD5 test #%d: ", i + 1 ); - - if( i == 5 || i == 6 ) - { - memset( buf, '\xAA', buflen = 80 ); - md5_hmac_starts( &ctx, buf, buflen ); - } - else - md5_hmac_starts( &ctx, md5_hmac_test_key[i], - md5_hmac_test_keylen[i] ); - - md5_hmac_update( &ctx, md5_hmac_test_buf[i], - md5_hmac_test_buflen[i] ); - - md5_hmac_finish( &ctx, md5sum ); - - buflen = ( i == 4 ) ? 12 : 16; - - if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - return( 0 ); -} - -#endif - -#endif +#endif /* LWIP_INCLUDED_POLARSSL_MD5_C */ diff --git a/src/netif/ppp/polarssl/md5.h b/src/netif/ppp/polarssl/md5.h index 61af7647..95e115f1 100644 --- a/src/netif/ppp/polarssl/md5.h +++ b/src/netif/ppp/polarssl/md5.h @@ -32,8 +32,8 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef POLARSSL_MD5_H -#define POLARSSL_MD5_H +#ifndef LWIP_INCLUDED_POLARSSL_MD5_H +#define LWIP_INCLUDED_POLARSSL_MD5_H /** * \brief MD5 context structure @@ -86,65 +86,8 @@ void md5_finish( md5_context *ctx, unsigned char output[16] ); */ void md5( unsigned char *input, int ilen, unsigned char output[16] ); -/** - * \brief Output = MD5( file contents ) - * - * \param path input file name - * \param output MD5 checksum result - * - * \return 0 if successful, 1 if fopen failed, - * or 2 if fread failed - */ -int md5_file( char *path, unsigned char output[16] ); - -/** - * \brief MD5 HMAC context setup - * - * \param ctx HMAC context to be initialized - * \param key HMAC secret key - * \param keylen length of the HMAC key - */ -void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ); - -/** - * \brief MD5 HMAC process buffer - * - * \param ctx HMAC context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ); - -/** - * \brief MD5 HMAC final digest - * - * \param ctx HMAC context - * \param output MD5 HMAC checksum result - */ -void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = HMAC-MD5( hmac key, input buffer ) - * - * \param key HMAC secret key - * \param keylen length of the HMAC key - * \param input buffer holding the data - * \param ilen length of the input data - * \param output HMAC-MD5 result - */ -void md5_hmac( unsigned char *key, int keylen, - unsigned char *input, int ilen, - unsigned char output[16] ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int md5_self_test( int verbose ); - #ifdef __cplusplus } #endif -#endif /* md5.h */ +#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/sha1.c index 54a4416f..9649ddf4 100644 --- a/src/netif/ppp/polarssl/sha1.c +++ b/src/netif/ppp/polarssl/sha1.c @@ -38,15 +38,11 @@ * http://www.itl.nist.gov/fipspubs/fip180-1.htm */ -#include "polarssl/config.h" - -#if defined(POLARSSL_SHA1_C) +#include "lwip/opt.h" +#if defined(LWIP_INCLUDED_POLARSSL_SHA1_C) #include "polarssl/sha1.h" -#include -#include - /* * 32-bit integer manipulation macros (big endian) */ @@ -336,287 +332,4 @@ void sha1( unsigned char *input, int ilen, unsigned char output[20] ) memset( &ctx, 0, sizeof( sha1_context ) ); } -/* - * output = SHA-1( file contents ) - */ -int sha1_file( char *path, unsigned char output[20] ) -{ - FILE *f; - size_t n; - sha1_context ctx; - unsigned char buf[1024]; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( 1 ); - - sha1_starts( &ctx ); - - while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - sha1_update( &ctx, buf, (int) n ); - - sha1_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); - - if( ferror( f ) != 0 ) - { - fclose( f ); - return( 2 ); - } - - fclose( f ); - return( 0 ); -} - -/* - * SHA-1 HMAC context setup - */ -void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ) -{ - int i; - unsigned char sum[20]; - - if( keylen > 64 ) - { - sha1( key, keylen, sum ); - keylen = 20; - key = sum; - } - - memset( ctx->ipad, 0x36, 64 ); - memset( ctx->opad, 0x5C, 64 ); - - for( i = 0; i < keylen; i++ ) - { - ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); - ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); - } - - sha1_starts( ctx ); - sha1_update( ctx, ctx->ipad, 64 ); - - memset( sum, 0, sizeof( sum ) ); -} - -/* - * SHA-1 HMAC process buffer - */ -void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ) -{ - sha1_update( ctx, input, ilen ); -} - -/* - * SHA-1 HMAC final digest - */ -void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) -{ - unsigned char tmpbuf[20]; - - sha1_finish( ctx, tmpbuf ); - sha1_starts( ctx ); - sha1_update( ctx, ctx->opad, 64 ); - sha1_update( ctx, tmpbuf, 20 ); - sha1_finish( ctx, output ); - - memset( tmpbuf, 0, sizeof( tmpbuf ) ); -} - -/* - * output = HMAC-SHA-1( hmac key, input buffer ) - */ -void sha1_hmac( unsigned char *key, int keylen, - unsigned char *input, int ilen, - unsigned char output[20] ) -{ - sha1_context ctx; - - sha1_hmac_starts( &ctx, key, keylen ); - sha1_hmac_update( &ctx, input, ilen ); - sha1_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); -} - -#if defined(POLARSSL_SELF_TEST) -/* - * FIPS-180-1 test vectors - */ -static unsigned char sha1_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const int sha1_test_buflen[3] = -{ - 3, 56, 1000 -}; - -static const unsigned char sha1_test_sum[3][20] = -{ - { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, - 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, - { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, - 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } -}; - -/* - * RFC 2202 test vectors - */ -static unsigned char sha1_hmac_test_key[7][26] = -{ - { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" - "\x0B\x0B\x0B\x0B" }, - { "Jefe" }, - { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA" }, - { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" - "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, - { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" - "\x0C\x0C\x0C\x0C" }, - { "" }, /* 0xAA 80 times */ - { "" } -}; - -static const int sha1_hmac_test_keylen[7] = -{ - 20, 4, 20, 25, 20, 80, 80 -}; - -static unsigned char sha1_hmac_test_buf[7][74] = -{ - { "Hi There" }, - { "what do ya want for nothing?" }, - { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, - { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, - { "Test With Truncation" }, - { "Test Using Larger Than Block-Size Key - Hash Key First" }, - { "Test Using Larger Than Block-Size Key and Larger" - " Than One Block-Size Data" } -}; - -static const int sha1_hmac_test_buflen[7] = -{ - 8, 28, 50, 50, 20, 54, 73 -}; - -static const unsigned char sha1_hmac_test_sum[7][20] = -{ - { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B, - 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 }, - { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74, - 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 }, - { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3, - 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 }, - { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84, - 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA }, - { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2, - 0x7B, 0xE1 }, - { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70, - 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 }, - { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B, - 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 } -}; - -/* - * Checkup routine - */ -int sha1_self_test( int verbose ) -{ - int i, j, buflen; - unsigned char buf[1024]; - unsigned char sha1sum[20]; - sha1_context ctx; - - /* - * SHA-1 - */ - for( i = 0; i < 3; i++ ) - { - if( verbose != 0 ) - printf( " SHA-1 test #%d: ", i + 1 ); - - sha1_starts( &ctx ); - - if( i == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - sha1_update( &ctx, buf, buflen ); - } - else - sha1_update( &ctx, sha1_test_buf[i], - sha1_test_buflen[i] ); - - sha1_finish( &ctx, sha1sum ); - - if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - printf( " HMAC-SHA-1 test #%d: ", i + 1 ); - - if( i == 5 || i == 6 ) - { - memset( buf, '\xAA', buflen = 80 ); - sha1_hmac_starts( &ctx, buf, buflen ); - } - else - sha1_hmac_starts( &ctx, sha1_hmac_test_key[i], - sha1_hmac_test_keylen[i] ); - - sha1_hmac_update( &ctx, sha1_hmac_test_buf[i], - sha1_hmac_test_buflen[i] ); - - sha1_hmac_finish( &ctx, sha1sum ); - - buflen = ( i == 4 ) ? 12 : 20; - - if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - return( 0 ); -} - -#endif - -#endif +#endif /* LWIP_INCLUDED_POLARSSL_SHA1_C */ diff --git a/src/netif/ppp/polarssl/sha1.h b/src/netif/ppp/polarssl/sha1.h index 3ca7dc31..168b2d7c 100644 --- a/src/netif/ppp/polarssl/sha1.h +++ b/src/netif/ppp/polarssl/sha1.h @@ -32,8 +32,8 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef POLARSSL_SHA1_H -#define POLARSSL_SHA1_H +#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H +#define LWIP_INCLUDED_POLARSSL_SHA1_H /** * \brief SHA-1 context structure @@ -86,65 +86,8 @@ void sha1_finish( sha1_context *ctx, unsigned char output[20] ); */ void sha1( unsigned char *input, int ilen, unsigned char output[20] ); -/** - * \brief Output = SHA-1( file contents ) - * - * \param path input file name - * \param output SHA-1 checksum result - * - * \return 0 if successful, 1 if fopen failed, - * or 2 if fread failed - */ -int sha1_file( char *path, unsigned char output[20] ); - -/** - * \brief SHA-1 HMAC context setup - * - * \param ctx HMAC context to be initialized - * \param key HMAC secret key - * \param keylen length of the HMAC key - */ -void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ); - -/** - * \brief SHA-1 HMAC process buffer - * - * \param ctx HMAC context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ); - -/** - * \brief SHA-1 HMAC final digest - * - * \param ctx HMAC context - * \param output SHA-1 HMAC checksum result - */ -void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ); - -/** - * \brief Output = HMAC-SHA-1( hmac key, input buffer ) - * - * \param key HMAC secret key - * \param keylen length of the HMAC key - * \param input buffer holding the data - * \param ilen length of the input data - * \param output HMAC-SHA-1 result - */ -void sha1_hmac( unsigned char *key, int keylen, - unsigned char *input, int ilen, - unsigned char output[20] ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int sha1_self_test( int verbose ); - #ifdef __cplusplus } #endif -#endif /* sha1.h */ +#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ From d0645273df2c6b64e518a7ac8b6093a15f476aa0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 May 2012 23:02:27 +0200 Subject: [PATCH 041/320] removed HMAC support from ciphers --- src/netif/ppp/polarssl/md4.h | 3 --- src/netif/ppp/polarssl/md5.h | 3 --- src/netif/ppp/polarssl/sha1.h | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/netif/ppp/polarssl/md4.h b/src/netif/ppp/polarssl/md4.h index 86493dea..7fe5985f 100644 --- a/src/netif/ppp/polarssl/md4.h +++ b/src/netif/ppp/polarssl/md4.h @@ -43,9 +43,6 @@ typedef struct unsigned long total[2]; /*!< number of bytes processed */ unsigned long state[4]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ - - unsigned char ipad[64]; /*!< HMAC: inner padding */ - unsigned char opad[64]; /*!< HMAC: outer padding */ } md4_context; diff --git a/src/netif/ppp/polarssl/md5.h b/src/netif/ppp/polarssl/md5.h index 95e115f1..2103f00e 100644 --- a/src/netif/ppp/polarssl/md5.h +++ b/src/netif/ppp/polarssl/md5.h @@ -43,9 +43,6 @@ typedef struct unsigned long total[2]; /*!< number of bytes processed */ unsigned long state[4]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ - - unsigned char ipad[64]; /*!< HMAC: inner padding */ - unsigned char opad[64]; /*!< HMAC: outer padding */ } md5_context; diff --git a/src/netif/ppp/polarssl/sha1.h b/src/netif/ppp/polarssl/sha1.h index 168b2d7c..5f69aef7 100644 --- a/src/netif/ppp/polarssl/sha1.h +++ b/src/netif/ppp/polarssl/sha1.h @@ -43,9 +43,6 @@ typedef struct unsigned long total[2]; /*!< number of bytes processed */ unsigned long state[5]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ - - unsigned char ipad[64]; /*!< HMAC: inner padding */ - unsigned char opad[64]; /*!< HMAC: outer padding */ } sha1_context; From b88dad40344fba328da74d4faedfc63c390cfb34 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 22 May 2012 01:28:30 +0200 Subject: [PATCH 042/320] disabled almost all PPP options strings and support as well as useless file-based auth code --- src/netif/ppp/auth.c | 34 +++++++++++++++++++++++++++++----- src/netif/ppp/ccp.c | 4 ++++ src/netif/ppp/chap-new.c | 4 ++++ src/netif/ppp/chap_ms.c | 4 ++++ src/netif/ppp/eap.c | 4 ++++ src/netif/ppp/ecp.c | 4 ++++ src/netif/ppp/ipcp.c | 8 ++++++++ src/netif/ppp/lcp.c | 4 ++++ src/netif/ppp/options.c | 2 ++ src/netif/ppp/polarssl/README | 4 ++-- src/netif/ppp/ppp.c | 7 +++++++ src/netif/ppp/pppd.h | 6 ++++++ src/netif/ppp/tty.c | 3 ++- src/netif/ppp/upap.c | 4 ++++ 14 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 9b2e8569..fd57769d 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -238,29 +238,36 @@ static void network_phase __P((int)); static void check_idle __P((void *)); static void connect_time_expired __P((void *)); static int null_login __P((int)); +#if 0 /* UNUSED */ /* static int get_pap_passwd __P((char *)); */ static int have_pap_secret __P((int *)); static int have_chap_secret __P((char *, char *, int, int *)); static int have_srp_secret __P((char *client, char *server, int need_ip, int *lacks_ipp)); +#endif /* UNUSED */ static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); +#if 0 /* UNUSED */ static int scan_authfile __P((FILE *, char *, char *, char *, struct wordlist **, struct wordlist **, char *, int)); static void free_wordlist __P((struct wordlist *)); static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *)); +#endif /* UNUSED */ static int some_ip_ok __P((struct wordlist *)); static int setupapfile __P((char **)); static int privgroup __P((char **)); static int set_noauth_addr __P((char **)); static int set_permitted_number __P((char **)); static void check_access __P((FILE *, char *)); +#if 0 /* UNUSED */ static int wordlist_count __P((struct wordlist *)); +#endif /* UNUSED */ #ifdef MAXOCTETS static void check_maxoctets __P((void *)); #endif +#if PPP_OPTIONS /* * Authentication-related options. */ @@ -397,6 +404,7 @@ option_t auth_options[] = { { NULL } }; +#endif /* PPP_OPTIONS */ /* * setupapfile - specifies UPAP info for authenticating with peer. @@ -737,14 +745,18 @@ link_established(unit) (*protp->lowerup)(unit); } +#if PPP_ALLOWED_ADDRS if (!auth_required && noauth_addrs != NULL) set_allowed_addrs(unit, NULL, NULL); +#endif /* PPP_ALLOWED_ADDRS */ if (auth_required && !(go->neg_upap || go->neg_chap #if EAP_SUPPORT || go->neg_eap #endif /* EAP_SUPPORT */ )) { + +#if PPP_ALLOWED_ADDRS /* * We wanted the peer to authenticate itself, and it refused: * if we have some address(es) it can use without auth, fine, @@ -754,7 +766,9 @@ link_established(unit) */ if (noauth_addrs != NULL) { set_allowed_addrs(unit, NULL, NULL); - } else if (!wo->neg_upap || uselogin || !null_login(unit)) { + } else +#endif /* PPP_ALLOWED_ADDRS */ + if (!wo->neg_upap || uselogin || !null_login(unit)) { warn("peer refused to authenticate: terminating link"); status = EXIT_PEER_AUTH_FAILED; lcp_close(unit, "peer refused to authenticate"); @@ -832,6 +846,7 @@ network_phase(unit) } #endif +#if PPP_OPTIONS /* * Process extra options from the secrets file */ @@ -840,6 +855,7 @@ network_phase(unit) free_wordlist(extra_options); extra_options = 0; } +#endif /* PPP_OPTIONS */ start_networks(unit); } @@ -1206,6 +1222,7 @@ connect_time_expired(arg) lcp_close(0, "Connect time expired"); /* Close connection */ } +#if PPP_OPTIONS /* * auth_check_options - called to check authentication options. */ @@ -1315,6 +1332,7 @@ auth_check_options() exit(EXIT_CNID_AUTH_FAILED); } } +#endif /* PPP_OPTIONS */ /* * auth_reset - called when LCP is starting negotiations to recheck @@ -1554,6 +1572,9 @@ static int null_login(unit) int unit; { + return 0; +/* FIXME: clean that */ +#if 0 /* UNUSED */ char *filename; FILE *f; int i, ret; @@ -1592,6 +1613,7 @@ null_login(unit) free_wordlist(addrs); return ret; +#endif } #if 0 @@ -1637,6 +1659,7 @@ get_pap_passwd(passwd) } #endif +#if 0 /* UNUSED */ /* * have_pap_secret - check whether we have a PAP file with any * secrets that we could possibly use for authenticating the peer. @@ -1676,7 +1699,6 @@ have_pap_secret(lacks_ipp) return ret >= 0; } - /* * have_chap_secret - check whether we have a CHAP file with a * secret that we could possibly use for authenticating `client' @@ -1725,7 +1747,6 @@ have_chap_secret(client, server, need_ip, lacks_ipp) return ret >= 0; } - /* * have_srp_secret - check whether we have a SRP file with a * secret that we could possibly use for authenticating `client' @@ -1766,7 +1787,7 @@ have_srp_secret(client, server, need_ip, lacks_ipp) return ret >= 0; } - +#endif /* UNUSED */ /* * get_secret - open the CHAP secret file and return the secret @@ -1927,6 +1948,7 @@ get_srp_secret(unit, client, server, secret, am_server) #endif } +#if 0 /* UNUSED */ /* * set_allowed_addrs() - set the list of allowed addresses. * Also looks for `--' indicating options to apply for this peer @@ -2083,6 +2105,7 @@ set_allowed_addrs(unit, addrs, opts) wo->accept_remote = 1; } } +#endif /* UNUSED */ /* * auth_ip_addr - check whether the peer is authorized to use @@ -2202,7 +2225,7 @@ check_access(f, filename) } } -/* FIXME: useless ! */ +#if 0 /* UNUSED */ /* * scan_authfile - Scan an authorization file for a secret suitable * for authenticating `client' on `server'. The return value is -1 @@ -2406,3 +2429,4 @@ free_wordlist(wp) wp = next; } } +#endif /* UNUSED */ diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index df07a387..6794a5f0 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -71,6 +71,7 @@ static char deflate_value[8]; bool refuse_mppe_stateful = 1; /* Allow stateful mode? */ #endif +#if PPP_OPTIONS static option_t ccp_option_list[] = { { "noccp", o_bool, &ccp_protent.enabled_flag, "Disable CCP negotiation" }, @@ -162,6 +163,7 @@ static option_t ccp_option_list[] = { { NULL } }; +#endif /* PPP_OPTIONS */ /* * Protocol entry points from main code. @@ -192,7 +194,9 @@ struct protent ccp_protent = { 1, "CCP", "Compressed", +#if PPP_OPTIONS ccp_option_list, +#endif /* PPP_OPTIONS */ NULL, NULL, NULL diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 7d773537..fba7d9ca 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -62,6 +62,7 @@ int chap_timeout_time = 3; int chap_max_transmits = 10; int chap_rechallenge_time = 0; +#if PPP_OPTIONS /* * Command-line options. */ @@ -74,6 +75,7 @@ static option_t chap_option_list[] = { "Set interval for rechallenge", OPT_PRIO }, { NULL } }; +#endif /* PPP_OPTIONS */ /* * Internal state. @@ -654,6 +656,8 @@ struct protent chap_protent = { 1, /* enabled_flag */ "CHAP", /* name */ NULL, /* data_name */ +#if PPP_OPTIONS chap_option_list, +#endif /* PPP_OPTIONS */ NULL, /* check_options */ }; diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 2c46bbec..b6c4d81d 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -142,6 +142,7 @@ static char *mschap2_peer_challenge = NULL; #include #endif +#if PPP_OPTIONS /* * Command-line options. */ @@ -158,6 +159,7 @@ static option_t chapms_option_list[] = { #endif { NULL } }; +#endif /* PPP_OPTIONS */ /* * chapms_generate_challenge - generate a challenge for MS-CHAP. @@ -940,7 +942,9 @@ chapms_init(void) { chap_register_digest(&chapms_digest); chap_register_digest(&chapms2_digest); +#if PPP_OPTIONS add_options(chapms_option_list); +#endif /* PPP_OPTIONS */ } #endif /* CHAPMS */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index c70eff49..5b4a2516 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -67,6 +67,7 @@ eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */ static char *pn_secret = NULL; /* Pseudonym generating secret */ #endif +#if PPP_OPTIONS /* * Command-line options. */ @@ -91,6 +92,7 @@ static option_t eap_option_list[] = { #endif { NULL } }; +#endif /* PPP_OPTIONS */ /* * Protocol entry points. @@ -117,7 +119,9 @@ struct protent eap_protent = { 1, /* protocol enabled */ "EAP", /* text name of protocol */ NULL, /* text name of corresponding data protocol */ +#if PPP_OPTIONS eap_option_list, /* list of command-line options */ +#endif /* PPP_OPTIONS */ NULL, /* check requested options; assign defaults */ NULL, /* configure interface for demand-dial */ NULL /* say whether to bring up link for this pkt */ diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index 8f6bc502..ec172e8b 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -69,6 +69,7 @@ static const char rcsid[] = RCSID; #include "fsm.h" #include "ecp.h" +#if PPP_OPTIONS static option_t ecp_option_list[] = { { "noecp", o_bool, &ecp_protent.enabled_flag, "Disable ECP negotiation" }, @@ -77,6 +78,7 @@ static option_t ecp_option_list[] = { { NULL } }; +#endif /* PPP_OPTIONS */ /* * Protocol entry points from main code. @@ -111,7 +113,9 @@ struct protent ecp_protent = { 0, "ECP", "Encrypted", +#if PPP_OPTIONS ecp_option_list, +#endif /* PPP_OPTIONS */ NULL, NULL, NULL diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 085c870c..d05496a9 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -143,6 +143,7 @@ static int setnetmask __P((char **)); int setipaddr __P((char *, char **, int)); static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); +#if PPP_OPTIONS static option_t ipcp_option_list[] = { { "noip", o_bool, &ipcp_protent.enabled_flag, "Disable IP and IPCP" }, @@ -243,6 +244,7 @@ static option_t ipcp_option_list[] = { { NULL } }; +#endif /* PPP_OPTIONS */ /* * Protocol entry points from main code. @@ -275,7 +277,9 @@ struct protent ipcp_protent = { 1, "IPCP", "IP", +#if PPP_OPTIONS ipcp_option_list, +#endif /* PPP_OPTIONS */ ip_check_options, ip_demand_conf, ip_active_pkt @@ -322,8 +326,12 @@ setvjslots(argv) { int value; +/* FIXME: found what int_option() did */ +#if PPP_OPTIONS if (!int_option(*argv, &value)) return 0; +#endif /* PPP_OPTIONS */ + if (value < 2 || value > 16) { option_error("vj-max-slots value must be between 2 and 16"); return 0; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 7fff01a5..3d41eb40 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -90,6 +90,7 @@ static void printendpoint __P((option_t *, void (*)(void *, char *, ...), void *)); #endif /* HAVE_MULTILINK */ +#if PPP_OPTIONS static option_t lcp_option_list[] = { /* LCP options */ { "-all", o_special_noarg, (void *)noopt, @@ -195,6 +196,7 @@ static option_t lcp_option_list[] = { {NULL} }; +#endif /* PPP_OPTIONS */ /* global vars */ fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ @@ -281,7 +283,9 @@ struct protent lcp_protent = { 1, "LCP", NULL, +#if PPP_OPTIONS lcp_option_list, +#endif /* PPP_OPTIONS */ NULL, NULL, NULL diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index f4c913d5..291bb33f 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -184,6 +184,7 @@ struct option_list { static struct option_list *extra_options = NULL; +#if PPP_OPTIONS /* * Valid arguments. */ @@ -1625,3 +1626,4 @@ loadplugin(argv) return 0; } #endif /* PLUGIN */ +#endif /* PPP_OPTIONS */ diff --git a/src/netif/ppp/polarssl/README b/src/netif/ppp/polarssl/README index 12e81d97..c71cabb8 100644 --- a/src/netif/ppp/polarssl/README +++ b/src/netif/ppp/polarssl/README @@ -13,7 +13,7 @@ The PolarSSL API was not changed at all, so if you are already using PolarSSL you can choose to skip the compilation of the included PolarSSL library into lwIP: -The following define are available for flexibility: +The following defines are available for flexibility: LWIP_INCLUDED_POLARSSL_MD4_C ; Use lwIP internal PolarSSL for MD4 LWIP_INCLUDED_POLARSSL_MD5_C ; Use lwIP internal PolarSSL for MD5 @@ -21,7 +21,7 @@ LWIP_INCLUDED_POLARSSL_SHA1_C ; Use lwIP internal PolarSSL for SHA1 LWIP_INCLUDED_POLARSSL_DES_C ; Use lwIP internal PolarSSL for DES If set (=1), the default if required by another enabled PPP feature unless -explicitely set to 0, using included lwIP PolarSSL. +explicitly set to 0, using included lwIP PolarSSL. If clear (=0), using external PolarSSL. diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 259c321a..27a3a54e 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -343,6 +343,7 @@ int ppp_oldmain() { progname = *argv; +#if PPP_OPTIONS /* * Parse, in order, the system options file, the user's options file, * and the command line arguments. @@ -351,6 +352,8 @@ int ppp_oldmain() { || !options_from_user() || !parse_args(argc-1, argv+1)) exit(EXIT_OPTION_ERROR); +#endif /* PPP_OPTIONS */ + devnam_fixed = 1; /* can no longer change device name */ /* @@ -363,6 +366,7 @@ int ppp_oldmain() { if (debug) setlogmask(LOG_UPTO(LOG_DEBUG)); +#if 0 /* * Check that we are running as root. */ @@ -376,7 +380,9 @@ int ppp_oldmain() { option_error("%s", no_ppp_msg); exit(EXIT_NO_KERNEL_SUPPORT); } +#endif +#if PPP_OPTIONS /* * Check that the options given are valid and consistent. */ @@ -399,6 +405,7 @@ int ppp_oldmain() { print_options(pr_log, NULL); end_pr_log(); } +#endif /* PPP_OPTIONS */ if (dryrun) die(0); diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index add22efe..ea0e3980 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -415,8 +415,10 @@ struct protent { char *name; /* Text name of protocol */ char *data_name; /* Text name of corresponding data protocol */ option_t *options; /* List of command-line options */ +#if PPP_OPTIONS /* Check requested options, assign defaults */ void (*check_options) __P((void)); +#endif /* PPP_OPTIONS */ /* Configure interface for demand-dial */ int (*demand_conf) __P((int unit)); /* Say whether to bring up link for this pkt */ @@ -680,8 +682,12 @@ int options_from_list __P((struct wordlist *, int privileged)); /* Parse options from a wordlist */ int getword __P((FILE *f, char *word, int *newlinep, char *filename)); /* Read a word from a file */ +#if PPP_OPTIONS void option_error __P((char *fmt, ...)); /* Print an error message about an option */ +#else +#define option_error(x, ...) +#endif /* PPP_OPTIONS */ int int_option __P((char *, int *)); /* Simplified number_option for decimal ints */ void add_options __P((option_t *)); /* Add extra options */ diff --git a/src/netif/ppp/tty.c b/src/netif/ppp/tty.c index 9a11777f..09697abe 100644 --- a/src/netif/ppp/tty.c +++ b/src/netif/ppp/tty.c @@ -427,7 +427,7 @@ void tty_process_extra_options() fatal("Couldn't stat default device %s: %m", devnam); } - +#if PPP_OPTIONS /* * Parse the tty options file. * The per-tty options file should not change @@ -437,6 +437,7 @@ void tty_process_extra_options() */ if (!options_for_tty()) exit(EXIT_OPTION_ERROR); +#endif /* PPP_OPTIONS */ } /* diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 1321c6d4..60caaae6 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -58,6 +58,7 @@ static const char rcsid[] = RCSID; static bool hide_password = 1; +#if PPP_OPTIONS /* * Command-line options. */ @@ -76,6 +77,7 @@ static option_t pap_option_list[] = { { NULL } }; +#endif /* PPP_OPTIONS */ /* * Protocol entry points. @@ -102,7 +104,9 @@ struct protent pap_protent = { 1, "PAP", NULL, +#if PPP_OPTIONS pap_option_list, +#endif /* PPP_OPTIONS */ NULL, NULL, NULL From 42827cdea205ee61b83e33149b6ab5ecd8eeab3b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 22 May 2012 21:59:23 +0200 Subject: [PATCH 043/320] more and more ppp options removal --- src/netif/ppp/auth.c | 14 +++++++++----- src/netif/ppp/ccp.c | 2 +- src/netif/ppp/chap-new.c | 7 ++++++- src/netif/ppp/eap.c | 2 +- src/netif/ppp/ecp.c | 2 +- src/netif/ppp/ipcp.c | 12 +++++++++--- src/netif/ppp/lcp.c | 2 +- src/netif/ppp/options.c | 11 +++++++++-- src/netif/ppp/ppp.c | 6 ++++++ src/netif/ppp/pppd.h | 12 +++++++++++- src/netif/ppp/tty.c | 15 ++++++++++++++- src/netif/ppp/upap.c | 4 +++- 12 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index fd57769d..72d1edd3 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -140,9 +140,11 @@ int auth_done[NUM_PPP]; /* List of addresses which the peer may use. */ static struct permitted_ip *addresses[NUM_PPP]; +#if 0 /* UNUSED */ /* Wordlist giving addresses which the peer may use without authenticating itself. */ static struct wordlist *noauth_addrs; +#endif /* UNUSED */ /* Remote telephone number, if available */ char remote_number[MAXNAMELEN]; @@ -150,8 +152,10 @@ char remote_number[MAXNAMELEN]; /* Wordlist giving remote telephone numbers which may connect. */ static struct wordlist *permitted_numbers; +#if 0 /* UNUSED */ /* Extra options to apply, from the secrets file entry for the peer. */ static struct wordlist *extra_options; +#endif /* UNUSED */ /* Number of network protocols which we have opened. */ static int num_np_open; @@ -159,8 +163,10 @@ static int num_np_open; /* Number of network protocols which have come up. */ static int num_np_up; +#if 0 /* UNUSED */ /* Set if we require authentication only because we have a default route. */ static bool default_auth; +#endif /* UNUSED */ /* Hook to enable a plugin to control the idle time limit */ int (*idle_time_hook) __P((struct ppp_idle *)) = NULL; @@ -254,12 +260,12 @@ static void free_wordlist __P((struct wordlist *)); static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *)); #endif /* UNUSED */ static int some_ip_ok __P((struct wordlist *)); +#if 0 /* UNUSE */ static int setupapfile __P((char **)); static int privgroup __P((char **)); static int set_noauth_addr __P((char **)); static int set_permitted_number __P((char **)); static void check_access __P((FILE *, char *)); -#if 0 /* UNUSED */ static int wordlist_count __P((struct wordlist *)); #endif /* UNUSED */ @@ -406,6 +412,7 @@ option_t auth_options[] = { }; #endif /* PPP_OPTIONS */ +#if 0 /* UNUSED */ /* * setupapfile - specifies UPAP info for authenticating with peer. */ @@ -469,7 +476,6 @@ setupapfile(argv) return (1); } - /* * privgroup - allow members of the group to have privileged access. */ @@ -538,7 +544,7 @@ set_permitted_number(argv) permitted_numbers = wp; return 1; } - +#endif /* * An Open on LCP has requested a change from Dead to Establish phase. @@ -2105,7 +2111,6 @@ set_allowed_addrs(unit, addrs, opts) wo->accept_remote = 1; } } -#endif /* UNUSED */ /* * auth_ip_addr - check whether the peer is authorized to use @@ -2225,7 +2230,6 @@ check_access(f, filename) } } -#if 0 /* UNUSED */ /* * scan_authfile - Scan an authorization file for a secret suitable * for authenticating `client' on `server'. The return value is -1 diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 6794a5f0..fab7b5f2 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -196,8 +196,8 @@ struct protent ccp_protent = { "Compressed", #if PPP_OPTIONS ccp_option_list, -#endif /* PPP_OPTIONS */ NULL, +#endif /* PPP_OPTIONS */ NULL, NULL }; diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index fba7d9ca..43398cce 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -350,7 +350,10 @@ chap_handle_response(struct chap_server_state *ss, int id, ok = (*verifier)(name, ss->name, id, ss->digest, ss->challenge + PPP_HDRLEN + CHAP_HDRLEN, response, ss->message, sizeof(ss->message)); +#if 0 /* UNUSED */ if (!ok || !auth_number()) { +#endif /* UNUSED */ + if (!ok) { ss->flags |= AUTH_FAILED; warn("Peer %q failed CHAP authentication", name); } @@ -658,6 +661,8 @@ struct protent chap_protent = { NULL, /* data_name */ #if PPP_OPTIONS chap_option_list, -#endif /* PPP_OPTIONS */ NULL, /* check_options */ +#endif /* PPP_OPTIONS */ + NULL, + NULL }; diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 5b4a2516..aa862aa6 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -121,8 +121,8 @@ struct protent eap_protent = { NULL, /* text name of corresponding data protocol */ #if PPP_OPTIONS eap_option_list, /* list of command-line options */ -#endif /* PPP_OPTIONS */ NULL, /* check requested options; assign defaults */ +#endif /* PPP_OPTIONS */ NULL, /* configure interface for demand-dial */ NULL /* say whether to bring up link for this pkt */ }; diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index ec172e8b..e5fbd1d5 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -115,8 +115,8 @@ struct protent ecp_protent = { "Encrypted", #if PPP_OPTIONS ecp_option_list, -#endif /* PPP_OPTIONS */ NULL, +#endif /* PPP_OPTIONS */ NULL, NULL }; diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index d05496a9..06dba35b 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -141,9 +141,10 @@ static int setdnsaddr __P((char **)); static int setwinsaddr __P((char **)); static int setnetmask __P((char **)); int setipaddr __P((char *, char **, int)); -static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); #if PPP_OPTIONS +static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); + static option_t ipcp_option_list[] = { { "noip", o_bool, &ipcp_protent.enabled_flag, "Disable IP and IPCP" }, @@ -279,8 +280,8 @@ struct protent ipcp_protent = { "IP", #if PPP_OPTIONS ipcp_option_list, -#endif /* PPP_OPTIONS */ ip_check_options, +#endif /* PPP_OPTIONS */ ip_demand_conf, ip_active_pkt }; @@ -412,6 +413,7 @@ setwinsaddr(argv) return (1); } +#if 0 /* UNUSED */ /* * setipaddr - Set the IP address * If doit is 0, the call is to check whether this option is @@ -484,7 +486,9 @@ setipaddr(arg, argv, doit) return 1; } +#endif /* UNUSED */ +#if PPP_OPTIONS static void printipaddr(opt, printer, arg) option_t *opt; @@ -499,6 +503,7 @@ printipaddr(opt, printer, arg) if (wo->hisaddr != 0) printer(arg, "%I", wo->hisaddr); } +#endif /* PPP_OPTIONS */ /* * setnetmask - set the netmask to be used on the interface. @@ -1687,6 +1692,7 @@ endswitch: } +#if 0 /* UNUSED */ /* * ip_check_options - check that any IP-related options are OK, * and assign appropriate defaults. @@ -1717,7 +1723,7 @@ ip_check_options() } ask_for_local = wo->ouraddr != 0 || !disable_defaultip; } - +#endif /* UNUSED */ /* * ip_demand_conf - configure the interface as though diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 3d41eb40..3fc7ee28 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -285,8 +285,8 @@ struct protent lcp_protent = { NULL, #if PPP_OPTIONS lcp_option_list, -#endif /* PPP_OPTIONS */ NULL, +#endif /* PPP_OPTIONS */ NULL, NULL }; diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 291bb33f..5045287f 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -128,9 +128,10 @@ int maxoctets_dir = 0; /* default - sum of traffic */ int maxoctets_timeout = 1; /* default 1 second */ #endif - +#if 0 /* UNUSED */ extern option_t auth_options[]; extern struct stat devstat; +#endif /* UNUSED */ #ifdef PPP_FILTER struct bpf_program pass_filter;/* Filter program for packets to pass */ @@ -140,15 +141,20 @@ struct bpf_program active_filter; /* Filter program for link-active pkts */ 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 */ +#if 0 /* UNUSED */ int option_priority = OPRIO_CFGFILE; /* priority of the current options */ +#endif /* UNUSED */ bool devnam_fixed; /* can no longer change device name */ +#if 0 /* UNUSED */ static int logfile_fd = -1; /* fd opened for log file */ static char logfile_name[MAXPATHLEN]; /* name of log file */ +#endif /* UNUSED */ /* * Prototypes */ +#if 0 /* UNUSED */ static int setdomain __P((char **)); static int readfile __P((char **)); static int callfile __P((char **)); @@ -156,6 +162,7 @@ static int showversion __P((char **)); static int showhelp __P((char **)); static void usage __P((void)); static int setlogfile __P((char **)); +#endif /* UNUSED */ #ifdef PLUGIN static int loadplugin __P((char **)); #endif @@ -169,6 +176,7 @@ static int setactivefilter __P((char **)); static int setmodir __P((char **)); #endif +#if 0 /* UNUSED */ static option_t *find_option __P((const char *name)); static int process_option __P((option_t *, char *, char **)); static int n_arguments __P((option_t *)); @@ -184,7 +192,6 @@ struct option_list { static struct option_list *extra_options = NULL; -#if PPP_OPTIONS /* * Valid arguments. */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 27a3a54e..192d00b5 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -190,8 +190,10 @@ int privopen; /* don't lock, open device as root */ char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; +#if 0 /* UNUSED */ GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ int ngroups; /* How many groups valid in groups */ +#endif /* UNUSED */ static struct timeval start_time; /* Time when link was started. */ @@ -322,7 +324,9 @@ int ppp_oldmain() { slprintf(numbuf, sizeof(numbuf), "%d", uid); script_setenv("ORIG_UID", numbuf, 0); +#if 0 /* UNUSED */ ngroups = getgroups(NGROUPS_MAX, groups); +#endif /* UNUSED */ /* * Initialize magic number generator now so that protocols may @@ -356,12 +360,14 @@ int ppp_oldmain() { devnam_fixed = 1; /* can no longer change device name */ +#if 0 /* UNUSED */ /* * Work out the device name, if it hasn't already been specified, * and parse the tty's options file. */ if (the_channel->process_extra_options) (*the_channel->process_extra_options)(); +#endif /* UNUSED */ if (debug) setlogmask(LOG_UPTO(LOG_DEBUG)); diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index ea0e3980..3afa70c2 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -87,6 +87,7 @@ typedef unsigned char bool; +#if 0 enum opt_type { o_special_noarg = 0, o_special = 1, @@ -162,6 +163,7 @@ struct permitted_ip { u_int32_t base; /* match if (addr & mask) == base */ u_int32_t mask; /* base and mask are in network byte order */ }; +#endif /* * Unfortunately, the linux kernel driver uses a different structure @@ -227,7 +229,9 @@ 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 */ +#if 0 extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */ +#endif extern int ngroups; /* How many groups valid in groups */ extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */ extern int link_stats_valid; /* set if link_stats is valid */ @@ -414,8 +418,8 @@ struct protent { 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 */ #if PPP_OPTIONS + option_t *options; /* List of command-line options */ /* Check requested options, assign defaults */ void (*check_options) __P((void)); #endif /* PPP_OPTIONS */ @@ -436,6 +440,7 @@ extern struct protent *protocols[]; * with PPP STREAMS modules pushed onto it). */ struct channel { +#if PPP_OPTIONS /* set of options for this channel */ option_t *options; /* find and process a per-channel options file */ @@ -444,6 +449,7 @@ struct channel { void (*check_options) __P((void)); /* get the channel ready to do PPP, return a file descriptor */ int (*connect) __P((void)); +#endif /* PPP_OPTIONS */ /* we're finished with the channel */ void (*disconnect) __P((void)); /* put the channel into PPP `mode' */ @@ -670,7 +676,9 @@ int get_if_hwaddr __P((u_char *addr, char *name)); char *get_first_ethernet __P((void)); /* Procedures exported from options.c */ +#if 0 /* UNUSED */ int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */ +#endif /* UNUSED */ int parse_args __P((int argc, char **argv)); /* Parse options from arguments given */ int options_from_file __P((char *filename, int must_exist, int check_prot, @@ -688,6 +696,7 @@ void option_error __P((char *fmt, ...)); #else #define option_error(x, ...) #endif /* PPP_OPTIONS */ +#if PPP_OPTIONS int int_option __P((char *, int *)); /* Simplified number_option for decimal ints */ void add_options __P((option_t *)); /* Add extra options */ @@ -696,6 +705,7 @@ int override_value __P((const char *, int, const char *)); /* override value if permitted by priority */ void print_options __P((void (*) __P((void *, char *, ...)), void *)); /* print out values of all options */ +#endif /* PPP_OPTIONS */ int parse_dotted_ip __P((char *, u_int32_t *)); diff --git a/src/netif/ppp/tty.c b/src/netif/ppp/tty.c index 09697abe..a9e52030 100644 --- a/src/netif/ppp/tty.c +++ b/src/netif/ppp/tty.c @@ -112,7 +112,9 @@ static int setdevname __P((char *, char **, int)); static int setspeed __P((char *, char **, int)); static int setxonxoff __P((char **)); static int setescape __P((char **)); +#if 0 /* UNUSED */ static void printescape __P((option_t *, void (*)(void *, char *,...),void *)); +#endif /* UNUSED */ static void finish_tty __P((void)); static int start_charshunt __P((int, int)); static void stop_charshunt __P((void *, int)); @@ -154,7 +156,9 @@ char *pty_socket = NULL; /* Socket to connect to pty */ int using_pty = 0; /* we're allocating a pty as the device */ extern uid_t uid; +#if 0 /* UNUSED */ extern int kill_link; +#endif /* UNUSED */ extern int asked_to_quit; extern int got_sigterm; @@ -163,6 +167,7 @@ extern int privopen; /* don't lock, open device as root */ u_int32_t xmit_accm[8]; /* extended transmit ACCM */ +#if 0 /* UNUSED */ /* option descriptors */ option_t tty_options[] = { /* device name must be first, or change connect_tty() below! */ @@ -243,12 +248,15 @@ option_t tty_options[] = { { NULL } }; +#endif /* UNUSED */ struct channel tty_channel = { +#if PPP_OPTIONS tty_options, &tty_process_extra_options, &tty_check_options, &connect_tty, +#endif /* UNUSED */ &disconnect_tty, &tty_establish_ppp, &tty_disestablish_ppp, @@ -373,6 +381,7 @@ setescape(argv) return ret; } +#if 0 /* UNUSED */ static void printescape(opt, printer, arg) option_t *opt; @@ -396,6 +405,7 @@ printescape(opt, printer, arg) if (first) printer(arg, "oops # nothing escaped"); } +#endif /* UNUSED */ /* * tty_init - do various tty-related initializations. @@ -440,6 +450,7 @@ void tty_process_extra_options() #endif /* PPP_OPTIONS */ } +#if 0 /* UNUSED */ /* * tty_check_options - do consistency checks on the options we were given. */ @@ -508,7 +519,9 @@ tty_check_options() && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev) log_to_fd = -1; } +#endif /* UNUSED */ +#if 0 /* UNUSED */ /* * connect_tty - get the serial port ready to start doing PPP. * That is, open the serial port, set its speed and mode, and run @@ -770,7 +783,7 @@ int connect_tty() asked_to_quit = 1; return -1; } - +#endif /* UNUSED */ void disconnect_tty() { diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 60caaae6..8c8cae6b 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -106,8 +106,8 @@ struct protent pap_protent = { NULL, #if PPP_OPTIONS pap_option_list, -#endif /* PPP_OPTIONS */ NULL, +#endif /* PPP_OPTIONS */ NULL, NULL }; @@ -432,6 +432,7 @@ upap_rauthreq(u, inp, id, len) rpasswdlen, &msg); BZERO(rpasswd, rpasswdlen); +#if 0 /* UNUSED */ /* * Check remote number authorization. A plugin may have filled in * the remote number or added an allowed number, and rather than @@ -444,6 +445,7 @@ upap_rauthreq(u, inp, id, len) warn("calling number %q is not authorized", remote_number); } } +#endif /* UNUSED */ msglen = strlen(msg); if (msglen > 255) From 05aa1f1ae466a814a67e9723a1af41e4108a609a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 22 May 2012 22:13:41 +0200 Subject: [PATCH 044/320] using MEMCPY() instead of memcpy() --- src/netif/ppp/polarssl/md4.c | 6 ++---- src/netif/ppp/polarssl/md5.c | 6 ++---- src/netif/ppp/polarssl/sha1.c | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/md4.c index 0572acee..3d8a8fda 100644 --- a/src/netif/ppp/polarssl/md4.c +++ b/src/netif/ppp/polarssl/md4.c @@ -206,7 +206,7 @@ void md4_update( md4_context *ctx, unsigned char *input, int ilen ) if( left && ilen >= fill ) { - memcpy( (void *) (ctx->buffer + left), + MEMCPY( (void *) (ctx->buffer + left), (void *) input, fill ); md4_process( ctx, ctx->buffer ); input += fill; @@ -223,7 +223,7 @@ void md4_update( md4_context *ctx, unsigned char *input, int ilen ) if( ilen > 0 ) { - memcpy( (void *) (ctx->buffer + left), + MEMCPY( (void *) (ctx->buffer + left), (void *) input, ilen ); } } @@ -274,8 +274,6 @@ void md4( unsigned char *input, int ilen, unsigned char output[16] ) md4_starts( &ctx ); md4_update( &ctx, input, ilen ); md4_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md4_context ) ); } #endif /* LWIP_INCLUDED_POLARSSL_MD4_C */ diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/md5.c index cd800a92..a98e8289 100644 --- a/src/netif/ppp/polarssl/md5.c +++ b/src/netif/ppp/polarssl/md5.c @@ -225,7 +225,7 @@ void md5_update( md5_context *ctx, unsigned char *input, int ilen ) if( left && ilen >= fill ) { - memcpy( (void *) (ctx->buffer + left), + MEMCPY( (void *) (ctx->buffer + left), (void *) input, fill ); md5_process( ctx, ctx->buffer ); input += fill; @@ -242,7 +242,7 @@ void md5_update( md5_context *ctx, unsigned char *input, int ilen ) if( ilen > 0 ) { - memcpy( (void *) (ctx->buffer + left), + MEMCPY( (void *) (ctx->buffer + left), (void *) input, ilen ); } } @@ -293,8 +293,6 @@ void md5( unsigned char *input, int ilen, unsigned char output[16] ) md5_starts( &ctx ); md5_update( &ctx, input, ilen ); md5_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); } #endif /* LWIP_INCLUDED_POLARSSL_MD5_C */ diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/sha1.c index 9649ddf4..6d6e682a 100644 --- a/src/netif/ppp/polarssl/sha1.c +++ b/src/netif/ppp/polarssl/sha1.c @@ -259,7 +259,7 @@ void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ) if( left && ilen >= fill ) { - memcpy( (void *) (ctx->buffer + left), + MEMCPY( (void *) (ctx->buffer + left), (void *) input, fill ); sha1_process( ctx, ctx->buffer ); input += fill; @@ -276,7 +276,7 @@ void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ) if( ilen > 0 ) { - memcpy( (void *) (ctx->buffer + left), + MEMCPY( (void *) (ctx->buffer + left), (void *) input, ilen ); } } @@ -328,8 +328,6 @@ void sha1( unsigned char *input, int ilen, unsigned char output[20] ) sha1_starts( &ctx ); sha1_update( &ctx, input, ilen ); sha1_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); } #endif /* LWIP_INCLUDED_POLARSSL_SHA1_C */ From 7736cdae1cc5c23ef41093bfc6393a218c409737 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 22 May 2012 23:02:02 +0200 Subject: [PATCH 045/320] replaced BCOPY to lwip-MEMCPY --- src/netif/ppp/auth.c | 10 ++++----- src/netif/ppp/ccp.c | 8 +++---- src/netif/ppp/chap_ms.c | 16 +++++++------- src/netif/ppp/eap.c | 48 ++++++++++++++++++++--------------------- src/netif/ppp/fsm.c | 2 +- src/netif/ppp/ipcp.c | 2 +- src/netif/ppp/lcp.c | 8 +++---- src/netif/ppp/pppd.h | 3 ++- src/netif/ppp/upap.c | 6 +++--- 9 files changed, 52 insertions(+), 51 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 72d1edd3..ddc47c76 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -518,7 +518,7 @@ set_noauth_addr(argv) novm("allow-ip argument"); wp->word = (char *) (wp + 1); wp->next = noauth_addrs; - BCOPY(addr, wp->word, l); + MEMCPY(wp->word, addr, l); noauth_addrs = wp; return 1; } @@ -540,7 +540,7 @@ set_permitted_number(argv) novm("allow-number argument"); wp->word = (char *) (wp + 1); wp->next = permitted_numbers; - BCOPY(number, wp->word, l); + MEMCPY(wp->word, number, l); permitted_numbers = wp; return 1; } @@ -987,7 +987,7 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) */ if (namelen > sizeof(peer_authname) - 1) namelen = sizeof(peer_authname) - 1; - BCOPY(name, peer_authname, namelen); + MEMCPY(peer_authname, name, namelen); peer_authname[namelen] = 0; script_setenv("PEERNAME", peer_authname, 0); @@ -1828,7 +1828,7 @@ get_secret(unit, client, server, secret, secret_len, am_server) len = MAXSECRETLEN; } - BCOPY(ppp_settings.passwd, secret, len); + MEMCPY(secret, ppp_settings.passwd, len); *secret_len = len; return 1; @@ -1892,7 +1892,7 @@ get_secret(unit, client, server, secret, secret_len, am_server) error("Secret for %s on %s is too long", client, server); len = MAXSECRETLEN; } - BCOPY(secbuf, secret, len); + MEMCPY(secret, secbuf, len); BZERO(secbuf, sizeof(secbuf)); *secret_len = len; diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index fab7b5f2..d1c7c9a8 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -714,7 +714,7 @@ ccp_addci(f, p, lenp) p[1] = opt_buf[1] = CILEN_MPPE; MPPE_OPTS_TO_CI(go->mppe, &p[2]); MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); - BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN); + MEMCPY(&opt_buf[CILEN_MPPE], mppe_recv_key, MPPE_MAX_KEY_LEN); res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0); if (res > 0) p += CILEN_MPPE; @@ -1178,8 +1178,8 @@ ccp_reqci(f, p, lenp, dont_nak) u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; int mtu; - BCOPY(p, opt_buf, CILEN_MPPE); - BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE], + MEMCPY(opt_buf, p, CILEN_MPPE); + MEMCPY(&opt_buf[CILEN_MPPE], mppe_send_key, MPPE_MAX_KEY_LEN); if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) { @@ -1336,7 +1336,7 @@ ccp_reqci(f, p, lenp, dont_nak) retp = p0; ret = newret; if (p != retp) - BCOPY(p, retp, clen); + MEMCPY(retp, p, clen); retp += clen; } diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index b6c4d81d..e19b2a16 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -385,7 +385,7 @@ chapms_handle_failure(unsigned char *inp, int len) notice("Out of memory in chapms_handle_failure"); return; } - BCOPY(inp, msg, len); + MEMCPY(msg, inp, len); msg[len] = 0; p = msg; @@ -454,7 +454,7 @@ ChallengeResponse(u_char *challenge, u_char des_key[8]; BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE); + MEMCPY(ZPasswordHash, PasswordHash, MD4_SIGNATURE_SIZE); #if 0 dbglog("ChallengeResponse - ZPasswordHash %.*B", @@ -499,7 +499,7 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, sha1_update(&sha1Context, (unsigned char *)user, strlen(user)); sha1_finish(&sha1Context, sha1Hash); - BCOPY(sha1Hash, Challenge, 8); + MEMCPY(Challenge, sha1Hash, 8); } /* @@ -677,8 +677,8 @@ mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) sha1_finish(&sha1Context, Digest); /* Same key in both directions. */ - BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); - BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); + MEMCPY(mppe_send_key, Digest, sizeof(mppe_send_key)); + MEMCPY(mppe_recv_key, Digest, sizeof(mppe_recv_key)); mppe_keys_set = 1; } @@ -777,7 +777,7 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); sha1_finish(&sha1Context, Digest); - BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key)); + MEMCPY(mppe_send_key, Digest, sizeof(mppe_send_key)); /* * generate recv key @@ -793,7 +793,7 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); sha1_finish(&sha1Context, Digest); - BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key)); + MEMCPY(mppe_recv_key, Digest, sizeof(mppe_recv_key)); mppe_keys_set = 1; } @@ -867,7 +867,7 @@ ChapMS2(u_char *rchallenge, u_char *PeerChallenge, for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++) *p++ = (u_char) (drand48() * 0xff); else - BCOPY(PeerChallenge, &response[MS_CHAP2_PEER_CHALLENGE], + MEMCPY(&response[MS_CHAP2_PEER_CHALLENGE], PeerChallenge, MS_CHAP2_PEER_CHAL_LEN); /* Generate the NT-Response */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index aa862aa6..19d5b93a 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -483,7 +483,7 @@ int status; i = 7; esp->es_server.ea_peerlen = plen; dp = (unsigned char *)esp->es_server.ea_peer; - BCOPY(clear + 1, dp, i); + MEMCPY(dp, clear + 1, i); plen -= i; dp += i; sp = secbuf + 8; @@ -687,7 +687,7 @@ eap_state *esp; PUTCHAR(EAPT_IDENTITY, outp); str = "Name"; challen = strlen(str); - BCOPY(str, outp, challen); + MEMCPY(outp, str, challen); INCPTR(challen, outp); break; @@ -705,9 +705,9 @@ eap_state *esp; ptr = esp->es_challenge; while (--challen >= 0) *ptr++ = (u_char) (drand48() * 0x100); - BCOPY(esp->es_challenge, outp, esp->es_challen); + MEMCPY(outp, esp->es_challenge, esp->es_challen); INCPTR(esp->es_challen, outp); - BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); + MEMCPY(outp, esp->es_server.ea_name, esp->es_server.ea_namelen); INCPTR(esp->es_server.ea_namelen, outp); break; @@ -717,26 +717,26 @@ eap_state *esp; PUTCHAR(EAPSRP_CHALLENGE, outp); PUTCHAR(esp->es_server.ea_namelen, outp); - BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); + MEMCPY(outp, esp->es_server.ea_name, esp->es_server.ea_namelen); INCPTR(esp->es_server.ea_namelen, outp); ts = (struct t_server *)esp->es_server.ea_session; assert(ts != NULL); PUTCHAR(ts->s.len, outp); - BCOPY(ts->s.data, outp, ts->s.len); + MEMCPY(outp, ts->s.data, ts->s.len); INCPTR(ts->s.len, outp); if (ts->g.len == 1 && ts->g.data[0] == 2) { PUTCHAR(0, outp); } else { PUTCHAR(ts->g.len, outp); - BCOPY(ts->g.data, outp, ts->g.len); + MEMCPY(outp, ts->g.data, ts->g.len); INCPTR(ts->g.len, outp); } if (ts->n.len != sizeof (wkmodulus) || BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) { - BCOPY(ts->n.data, outp, ts->n.len); + MEMCPY(outp, ts->n.data, ts->n.len); INCPTR(ts->n.len, outp); } break; @@ -747,7 +747,7 @@ eap_state *esp; ts = (struct t_server *)esp->es_server.ea_session; assert(ts != NULL); - BCOPY(ts->B.data, outp, ts->B.len); + MEMCPY(outp, ts->B.data, ts->B.len); INCPTR(ts->B.len, outp); break; @@ -757,7 +757,7 @@ eap_state *esp; PUTLONG(SRPVAL_EBIT, outp); ts = (struct t_server *)esp->es_server.ea_session; assert(ts != NULL); - BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE); + MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE); INCPTR(SHA_DIGESTSIZE, outp); if (pncrypt_setkey(0)) { @@ -767,7 +767,7 @@ eap_state *esp; if ((j = i = esp->es_server.ea_peerlen) > 7) j = 7; clear[0] = i; - BCOPY(cp, clear + 1, j); + MEMCPY(clear + 1, cp, j); i -= j; cp += j; /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ @@ -786,7 +786,7 @@ eap_state *esp; i -= 8; } if (i > 0) { - BCOPY(cp, clear, i); + MEMCPY(clear, cp, i); cp += i; while (i < 8) { *cp++ = drand48() * 0x100; @@ -840,7 +840,7 @@ eap_state *esp; ptr = esp->es_challenge; while (--challen >= 0) *ptr++ = drand48() * 0x100; - BCOPY(esp->es_challenge, outp, esp->es_challen); + MEMCPY(outp, esp->es_challenge, esp->es_challen); INCPTR(esp->es_challen, outp); break; #endif /* USE_SRP */ @@ -1056,7 +1056,7 @@ int lenstr; PUTSHORT(msglen, outp); PUTCHAR(typenum, outp); if (lenstr > 0) { - BCOPY(str, outp, lenstr); + MEMCPY(outp, str, lenstr); } output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); @@ -1088,10 +1088,10 @@ int namelen; PUTSHORT(msglen, outp); PUTCHAR(EAPT_MD5CHAP, outp); PUTCHAR(MD5_SIGNATURE_SIZE, outp); - BCOPY(hash, outp, MD5_SIGNATURE_SIZE); + MEMCPY(outp, hash, MD5_SIGNATURE_SIZE); INCPTR(MD5_SIGNATURE_SIZE, outp); if (namelen > 0) { - BCOPY(name, outp, namelen); + MEMCPY(outp, name, namelen); } output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); @@ -1124,7 +1124,7 @@ int lenstr; PUTCHAR(EAPT_SRP, outp); PUTCHAR(subtypenum, outp); if (lenstr > 0) { - BCOPY(str, outp, lenstr); + MEMCPY(outp, str, lenstr); } output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); @@ -1156,7 +1156,7 @@ u_char *str; PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_CVALIDATOR, outp); PUTLONG(flags, outp); - BCOPY(str, outp, SHA_DIGESTSIZE); + MEMCPY(outp, str, SHA_DIGESTSIZE); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } @@ -1419,10 +1419,10 @@ int len; /* Not so likely to happen. */ if (vallen >= len + sizeof (rhostname)) { dbglog("EAP: trimming really long peer name down"); - BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); + MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; } else { - BCOPY(inp + vallen, rhostname, len - vallen); + MEMCPY(rhostname, inp + vallen, len - vallen); rhostname[len - vallen] = '\0'; } @@ -1491,7 +1491,7 @@ int len; /* Ignore badly-formed messages */ return; } - BCOPY(inp, rhostname, vallen); + MEMCPY(rhostname, inp, vallen); rhostname[vallen] = '\0'; INCPTR(vallen, inp); len -= vallen; @@ -1766,7 +1766,7 @@ int len; eap_figure_next_state(esp, 1); break; } - BCOPY(inp, esp->es_server.ea_peer, len); + MEMCPY(esp->es_server.ea_peer, inp, len); esp->es_server.ea_peer[len] = '\0'; esp->es_server.ea_peerlen = len; eap_figure_next_state(esp, 0); @@ -1845,10 +1845,10 @@ int len; /* Not so likely to happen. */ if (vallen >= len + sizeof (rhostname)) { dbglog("EAP: trimming really long peer name down"); - BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); + MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; } else { - BCOPY(inp + vallen, rhostname, len - vallen); + MEMCPY(rhostname, inp + vallen, len - vallen); rhostname[len - vallen] = '\0'; } diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 33cea3a7..e34e2eb2 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -814,7 +814,7 @@ fsm_sdata(f, code, id, data, datalen) 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); + MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen); outlen = datalen + HEADERLEN; MAKEHEADER(outp, f->protocol); PUTCHAR(code, outp); diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 06dba35b..d94a8e00 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1660,7 +1660,7 @@ endswitch: /* Need to move CI? */ if (ucp != cip) - BCOPY(cip, ucp, cilen); /* Move it */ + MEMCPY(ucp, cip, cilen); /* Move it */ /* Update output pointer */ INCPTR(cilen, ucp); diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 3fc7ee28..ab922637 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1935,7 +1935,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) ho->neg_endpoint = 1; ho->endpoint.class = cichar; ho->endpoint.length = cilen; - BCOPY(p, ho->endpoint.value, cilen); + MEMCPY(ho->endpoint.value, p, cilen); INCPTR(cilen, p); break; @@ -1963,7 +1963,7 @@ endswitch: if (orc == CONFREJ) { /* Reject this CI */ rc = CONFREJ; if (cip != rejp) /* Need to move rejected CI? */ - BCOPY(cip, rejp, cilen); /* Move it */ + MEMCPY(rejp, cip, cilen); /* Move it */ INCPTR(cilen, rejp); /* Update output pointer */ } } @@ -1984,7 +1984,7 @@ endswitch: * Copy the Nak'd options from the nak_buffer to the caller's buffer. */ *lenp = nakp - nak_buffer; - BCOPY(nak_buffer, inp, *lenp); + MEMCPY(inp, nak_buffer, *lenp); break; case CONFREJ: *lenp = rejp - inp; @@ -2267,7 +2267,7 @@ lcp_printpkt(p, plen, printer, arg) if (epd.length > MAX_ENDP_LEN) epd.length = MAX_ENDP_LEN; if (epd.length > 0) { - BCOPY(p, epd.value, epd.length); + MEMCPY(epd.value, p, epd.length); p += epd.length; } printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 3afa70c2..0fc5d229 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -42,6 +42,8 @@ * $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $ */ +#include "lwip/opt.h" + /* * TODO: */ @@ -784,7 +786,6 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) #define UNTIMEOUT(f, a) sys_untimeout((f), (a)) -#define BCOPY(s, d, l) memcpy(d, s, l) #define BZERO(s, n) memset(s, 0, n) #define BCMP(s1, s2, l) memcmp(s1, s2, l) diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 8c8cae6b..d984de05 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -571,10 +571,10 @@ upap_sauthreq(u) PUTCHAR(++u->us_id, outp); PUTSHORT(outlen, outp); PUTCHAR(u->us_userlen, outp); - BCOPY(u->us_user, outp, u->us_userlen); + MEMCPY(outp, u->us_user, u->us_userlen); INCPTR(u->us_userlen, outp); PUTCHAR(u->us_passwdlen, outp); - BCOPY(u->us_passwd, outp, u->us_passwdlen); + MEMCPY(outp, u->us_passwd, u->us_passwdlen); output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); @@ -605,7 +605,7 @@ upap_sresp(u, code, id, msg, msglen) PUTCHAR(id, outp); PUTSHORT(outlen, outp); PUTCHAR(msglen, outp); - BCOPY(msg, outp, msglen); + MEMCPY(outp, msg, msglen); output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } From 6ce5c8eb789ca138235e1107cdbbae20978a875d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 22 May 2012 23:07:28 +0200 Subject: [PATCH 046/320] disabled upap_rauthreq() --- src/netif/ppp/auth.c | 12 +++--------- src/netif/ppp/upap.c | 8 ++++++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index ddc47c76..f5fafc9d 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1435,6 +1435,7 @@ auth_reset(unit) #endif } +#if 0 /* UNUSED */ /* * check_passwd - Check the user name and passwd against the PAP secrets * file. If requested, also check against the system password database, @@ -1455,7 +1456,6 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) char **msg; { return UPAP_AUTHNAK; -#if 0 int ret; char *filename; FILE *f; @@ -1566,8 +1566,8 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) BZERO(secret, sizeof(secret)); return ret; -#endif } +#endif /* * null_login - Check if a username of "" and a password of "" are @@ -1663,9 +1663,7 @@ get_pap_passwd(passwd) BZERO(secret, sizeof(secret)); return 1; } -#endif -#if 0 /* UNUSED */ /* * have_pap_secret - check whether we have a PAP file with any * secrets that we could possibly use for authenticating the peer. @@ -1901,6 +1899,7 @@ get_secret(unit, client, server, secret, secret_len, am_server) } +#if 0 /* UNUSED */ /* * get_srp_secret - open the SRP secret file and return the secret * for authenticating the given client on the given server. @@ -1914,9 +1913,6 @@ get_srp_secret(unit, client, server, secret, am_server) char *secret; int am_server; { - /* FIXME: clean that */ - return 0; -#if 0 FILE *fp; int ret; char *filename; @@ -1951,10 +1947,8 @@ get_srp_secret(unit, client, server, secret, am_server) } return 1; -#endif } -#if 0 /* UNUSED */ /* * set_allowed_addrs() - set the list of allowed addresses. * Also looks for `--' indicating options to apply for this peer diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index d984de05..b86fe1e3 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -116,7 +116,9 @@ upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ static void upap_timeout __P((void *)); static void upap_reqtimeout __P((void *)); +#if 0 /* UNUSED */ static void upap_rauthreq __P((upap_state *, u_char *, int, int)); +#endif /* UNUSED */ static void upap_rauthack __P((upap_state *, u_char *, int, int)); static void upap_rauthnak __P((upap_state *, u_char *, int, int)); static void upap_sauthreq __P((upap_state *)); @@ -353,7 +355,9 @@ upap_input(unit, inpacket, l) */ switch (code) { case UPAP_AUTHREQ: +#if 0 /* UNUSED */ upap_rauthreq(u, inp, id, len); +#endif /* UNUSED */ break; case UPAP_AUTHACK: @@ -369,7 +373,7 @@ upap_input(unit, inpacket, l) } } - +#if 0 /* UNUSED */ /* * upap_rauth - Receive Authenticate. */ @@ -468,7 +472,7 @@ upap_rauthreq(u, inp, id, len) if (u->us_reqtimeout > 0) UNTIMEOUT(upap_reqtimeout, u); } - +#endif /* UNUSED */ /* * upap_rauthack - Receive Authenticate-Ack. From 04f121b88f71283d012ebb4b64bb809132d86bae Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 23 May 2012 00:04:07 +0200 Subject: [PATCH 047/320] less and less auth code --- src/netif/ppp/auth.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index f5fafc9d..774fdf1a 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -137,10 +137,10 @@ static int auth_pending[NUM_PPP]; /* Records which authentication operations have been completed. */ int auth_done[NUM_PPP]; +#if 0 /* UNUSED */ /* List of addresses which the peer may use. */ static struct permitted_ip *addresses[NUM_PPP]; -#if 0 /* UNUSED */ /* Wordlist giving addresses which the peer may use without authenticating itself. */ static struct wordlist *noauth_addrs; @@ -149,10 +149,10 @@ static struct wordlist *noauth_addrs; /* Remote telephone number, if available */ char remote_number[MAXNAMELEN]; +#if 0 /* UNUSED */ /* Wordlist giving remote telephone numbers which may connect. */ static struct wordlist *permitted_numbers; -#if 0 /* UNUSED */ /* Extra options to apply, from the secrets file entry for the peer. */ static struct wordlist *extra_options; #endif /* UNUSED */ @@ -227,40 +227,39 @@ bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ //bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #endif bool usehostname = 0; /* Use hostname for our_name */ +#if 0 /* UNUSED */ bool auth_required = 0; /* Always require authentication from peer */ +#endif /* UNUSED */ bool allow_any_ip = 0; /* Allow peer to use any IP address */ bool explicit_remote = 0; /* User specified explicit remote name */ bool explicit_user = 0; /* Set if "user" option supplied */ bool explicit_passwd = 0; /* Set if "password" option supplied */ char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ +#if 0 /* UNUSED */ static char *uafname; /* name of most recent +ua file */ extern char *crypt __P((const char *, const char *)); - +#endif /* UNUSED */ /* Prototypes for procedures local to this file. */ static void network_phase __P((int)); static void check_idle __P((void *)); static void connect_time_expired __P((void *)); -static int null_login __P((int)); #if 0 /* UNUSED */ +static int null_login __P((int)); /* static int get_pap_passwd __P((char *)); */ static int have_pap_secret __P((int *)); static int have_chap_secret __P((char *, char *, int, int *)); static int have_srp_secret __P((char *client, char *server, int need_ip, int *lacks_ipp)); -#endif /* UNUSED */ static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); -#if 0 /* UNUSED */ static int scan_authfile __P((FILE *, char *, char *, char *, struct wordlist **, struct wordlist **, char *, int)); static void free_wordlist __P((struct wordlist *)); static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *)); -#endif /* UNUSED */ static int some_ip_ok __P((struct wordlist *)); -#if 0 /* UNUSE */ static int setupapfile __P((char **)); static int privgroup __P((char **)); static int set_noauth_addr __P((char **)); @@ -751,6 +750,7 @@ link_established(unit) (*protp->lowerup)(unit); } +#if 0 /* UNUSED */ #if PPP_ALLOWED_ADDRS if (!auth_required && noauth_addrs != NULL) set_allowed_addrs(unit, NULL, NULL); @@ -781,6 +781,7 @@ link_established(unit) return; } } +#endif /* UNUSED */ new_phase(PHASE_AUTHENTICATE); auth = 0; @@ -1567,7 +1568,6 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) return ret; } -#endif /* * null_login - Check if a username of "" and a password of "" are @@ -1578,9 +1578,6 @@ static int null_login(unit) int unit; { - return 0; -/* FIXME: clean that */ -#if 0 /* UNUSED */ char *filename; FILE *f; int i, ret; @@ -1619,10 +1616,8 @@ null_login(unit) free_wordlist(addrs); return ret; -#endif } -#if 0 /* * get_pap_passwd - get a password for authenticating ourselves with * our peer using PAP. Returns 1 on success, 0 if no suitable password From 49bb62d221b8572224be61d207f382b80f5f82b3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 23 May 2012 00:51:59 +0200 Subject: [PATCH 048/320] and less and less useless auth code (will this end ?) --- src/netif/ppp/auth.c | 41 +++++++++++++++++++++++++++++----------- src/netif/ppp/chap-new.c | 4 ++++ src/netif/ppp/pppd.h | 2 ++ src/netif/ppp/session.c | 4 ++++ src/netif/ppp/session.h | 4 ++++ 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 774fdf1a..39f8aab9 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -71,8 +71,6 @@ #include "lwip/opt.h" #include "pppmy.h" -#define RCSID "$Id: auth.c,v 1.117 2008/07/01 12:27:56 paulus Exp $" - #include #include #include @@ -117,16 +115,20 @@ #if CBCP_SUPPORT #include "cbcp.h" #endif + +#if 0 /* UNUSED */ #include "pathnames.h" +#endif /* UNUSED */ + #include "session.h" -static const char rcsid[] = RCSID; - +#if 0 /* UNUSED */ /* Bits in scan_authfile return value */ #define NONWILD_SERVER 1 #define NONWILD_CLIENT 2 #define ISWILD(word) (word[0] == '*' && word[1] == 0) +#endif /* UNUSED */ /* The name by which the peer authenticated itself to us. */ char peer_authname[MAXNAMELEN]; @@ -144,12 +146,10 @@ static struct permitted_ip *addresses[NUM_PPP]; /* Wordlist giving addresses which the peer may use without authenticating itself. */ static struct wordlist *noauth_addrs; -#endif /* UNUSED */ /* Remote telephone number, if available */ char remote_number[MAXNAMELEN]; -#if 0 /* UNUSED */ /* Wordlist giving remote telephone numbers which may connect. */ static struct wordlist *permitted_numbers; @@ -166,7 +166,6 @@ static int num_np_up; #if 0 /* UNUSED */ /* Set if we require authentication only because we have a default route. */ static bool default_auth; -#endif /* UNUSED */ /* Hook to enable a plugin to control the idle time limit */ int (*idle_time_hook) __P((struct ppp_idle *)) = NULL; @@ -197,22 +196,26 @@ int (*null_auth_hook) __P((struct wordlist **paddrs, struct wordlist **popts)) = NULL; int (*allowed_address_hook) __P((u_int32_t addr)) = NULL; +#endif /* UNUSED */ #ifdef HAVE_MULTILINK /* Hook for plugin to hear when an interface joins a multilink bundle */ void (*multilink_join_hook) __P((void)) = NULL; #endif +#if 0 /* UNUSED */ /* A notifier for when the peer has authenticated itself, and we are proceeding to the network phase. */ struct notifier *auth_up_notifier = NULL; /* A notifier for when the link goes down. */ struct notifier *link_down_notifier = NULL; +#endif /* UNUSED */ /* * Option variables. */ +#if 0 /* MOVED TO ppp_settings */ bool uselogin = 0; /* Use /etc/passwd for checking PAP */ bool session_mgmt = 0; /* Do session management (login records) */ bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ @@ -221,21 +224,23 @@ bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ //bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ #ifdef CHAPMS //bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ -//bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +//bool refuse_mschap_v2 = 0; /* Don't wanna auth. oif 0 /* UNUSED */urselves with MS-CHAPv2 */ #else //bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ //bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #endif -bool usehostname = 0; /* Use hostname for our_name */ +#endif /* MOVED TO ppp_settings */ #if 0 /* UNUSED */ +bool usehostname = 0; /* Use hostname for our_name */ bool auth_required = 0; /* Always require authentication from peer */ -#endif /* UNUSED */ bool allow_any_ip = 0; /* Allow peer to use any IP address */ +#endif /* UNUSED */ bool explicit_remote = 0; /* User specified explicit remote name */ +#if 0 /* UNUSED */ bool explicit_user = 0; /* Set if "user" option supplied */ bool explicit_passwd = 0; /* Set if "password" option supplied */ +#endif /* UNUSED */ char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ - #if 0 /* UNUSED */ static char *uafname; /* name of most recent +ua file */ @@ -629,10 +634,12 @@ link_terminated(unit) return; new_phase(PHASE_DISCONNECT); +#if 0 /* UNUSED */ if (pap_logout_hook) { pap_logout_hook(); } session_end(devnam); +#endif /* UNUSED */ if (!doing_multilink) { notice("Connection terminated."); @@ -827,10 +834,13 @@ network_phase(unit) { lcp_options *go = &lcp_gotoptions[unit]; +#if 0 /* UNUSED */ /* Log calling number. */ if (*remote_number) notice("peer from calling number %q authorized", remote_number); +#endif /* UNUSED */ +#if 0 /* UNUSED */ /* * If the peer had to authenticate, run the auth-up script now. */ @@ -841,6 +851,7 @@ network_phase(unit) ) { notify(auth_up_notifier, 0); } +#endif /* UNUSED */ #if CBCP_SUPPORT /* @@ -1092,9 +1103,11 @@ np_up(unit, proto) unsuccess = 0; new_phase(PHASE_RUNNING); +#if 0 /* UNUSED */ if (idle_time_hook != 0) tlim = (*idle_time_hook)(NULL); else +#endif /* UNUSED */ tlim = idle_time_limit; if (tlim > 0) TIMEOUT(check_idle, NULL, tlim); @@ -1200,12 +1213,16 @@ check_idle(arg) if (!get_idle_time(0, &idle)) return; +#if 0 /* UNUSED */ if (idle_time_hook != 0) { tlim = idle_time_hook(&idle); } else { +#endif /* UNUSED */ itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); tlim = idle_time_limit - itime; +#if 0 /* UNUSED */ } +#endif /* UNUSED */ if (tlim <= 0) { /* link is idle: shut it down. */ notice("Terminating connection due to lack of activity."); @@ -1390,6 +1407,7 @@ auth_reset(unit) printf("neg_eap: %d\n", ao->neg_eap); #endif /* EAP_SUPPORT */ +#if 0 /* OLD CODE */ //ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); /* @@ -1403,6 +1421,7 @@ auth_reset(unit) (hadchap == 1 || (hadchap == -1 && have_chap_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL))) || have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); */ +#endif /* OLD CODE */ go->neg_upap = 0; go->neg_chap = 0; diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 43398cce..90d9e289 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -376,6 +376,8 @@ chap_handle_response(struct chap_server_state *ss, int id, if (ss->flags & CHALLENGE_VALID) { ss->flags &= ~CHALLENGE_VALID; if (!(ss->flags & AUTH_DONE) && !(ss->flags & AUTH_FAILED)) { + +#if 0 /* UNUSED */ /* * Auth is OK, so now we need to check session restrictions * to ensure everything is OK, but only if we used a @@ -390,6 +392,8 @@ chap_handle_response(struct chap_server_state *ss, int id, ss->flags |= AUTH_FAILED; warn("Peer %q failed CHAP Session verification", name); } +#endif /* UNUSED */ + } if (ss->flags & AUTH_FAILED) { auth_peer_fail(0, PPP_CHAP); diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 0fc5d229..374f4319 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -265,7 +265,9 @@ extern struct notifier *exitnotify; /* for notification that we're exiting */ extern struct notifier *sigreceived; /* notification of received signal */ extern struct notifier *ip_up_notifier; /* IPCP has come up */ extern struct notifier *ip_down_notifier; /* IPCP has gone down */ +#if 0 /* UNUSED */ extern struct notifier *auth_up_notifier; /* peer has authenticated */ +#endif /* UNUSED */ extern struct notifier *link_down_notifier; /* link has gone down */ extern struct notifier *fork_notifier; /* we are a new child process */ diff --git a/src/netif/ppp/session.c b/src/netif/ppp/session.c index aa4d746a..1c095de1 100644 --- a/src/netif/ppp/session.c +++ b/src/netif/ppp/session.c @@ -68,6 +68,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if 0 /* UNUSED */ + #include "lwip/opt.h" #include @@ -423,3 +425,5 @@ session_end(const char* ttyName) logged_in = 0; } } + +#endif /* UNUSED */ diff --git a/src/netif/ppp/session.h b/src/netif/ppp/session.h index bee8c412..cfdbdfac 100644 --- a/src/netif/ppp/session.h +++ b/src/netif/ppp/session.h @@ -28,6 +28,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if 0 /* UNUSED */ + #ifndef __SESSION_H #define __SESSION_H @@ -89,3 +91,5 @@ void session_end(const char* tty); #endif + +#endif /* UNUSED */ From 28360a7f268705347ef36ab437c09f1608926d75 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 23 May 2012 23:29:19 +0200 Subject: [PATCH 049/320] MSCHAP is now an optional compile-time feature --- src/include/lwip/opt.h | 2 +- src/netif/ppp/auth.c | 26 +++++++++++++++----------- src/netif/ppp/chap-new.c | 4 ++-- src/netif/ppp/chap-new.h | 24 ++++++++++++++++++++++++ src/netif/ppp/chap_ms.c | 9 ++------- src/netif/ppp/chap_ms.h | 5 +++++ src/netif/ppp/lcp.c | 2 ++ src/netif/ppp/pppd.h | 2 ++ src/netif/ppp/pppmy.c | 7 +++++++ src/netif/ppp/pppmy.h | 4 ++++ 10 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index e51f8e55..3b7222e8 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1717,7 +1717,7 @@ #endif /** - * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! + * MSCHAP_SUPPORT==1: Support MSCHAP. */ #ifndef MSCHAP_SUPPORT #define MSCHAP_SUPPORT 0 diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 39f8aab9..af43c0d2 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -222,13 +222,13 @@ 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 refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ -#ifdef CHAPMS +#if MSCHAP_SUPPORT //bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ //bool refuse_mschap_v2 = 0; /* Don't wanna auth. oif 0 /* UNUSED */urselves with MS-CHAPv2 */ -#else +#else /* MSCHAP_SUPPORT */ //bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ //bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ -#endif +#endif /* MSCHAP_SUPPORT */ #endif /* MOVED TO ppp_settings */ #if 0 /* UNUSED */ bool usehostname = 0; /* Use hostname for our_name */ @@ -301,7 +301,7 @@ option_t auth_options[] = { "Require CHAP authentication from peer", OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, &lcp_wantoptions[0].chap_mdtype }, -#ifdef CHAPMS +#if MSCHAP_SUPPORT { "require-mschap", o_bool, &auth_required, "Require MS-CHAP authentication from peer", OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, @@ -318,7 +318,7 @@ option_t auth_options[] = { "Require MS-CHAPv2 authentication from peer", OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, &lcp_wantoptions[0].chap_mdtype }, -#endif +#endif /* MSCHAP_SUPPORT */ #if 0 { "refuse-pap", o_bool, &refuse_pap, "Don't agree to auth to peer with PAP", 1 }, @@ -333,7 +333,7 @@ option_t auth_options[] = { OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5, &lcp_allowoptions[0].chap_mdtype }, #endif -#ifdef CHAPMS +#if MSCHAP_SUPPORT #if 0 { "refuse-mschap", o_bool, &refuse_mschap, "Don't agree to auth to peer with MS-CHAP", @@ -352,7 +352,7 @@ option_t auth_options[] = { OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, &lcp_allowoptions[0].chap_mdtype }, #endif -#endif +#endif /* MSCHAP_SUPPORT*/ #if EAP_SUPPORT { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, "Require EAP authentication from peer", OPT_PRIOSUB | 1, @@ -973,14 +973,14 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) case CHAP_MD5: bit |= CHAP_MD5_PEER; break; -#ifdef CHAPMS +#if MSCHAP_SUPPORT case CHAP_MICROSOFT: bit |= CHAP_MS_PEER; break; case CHAP_MICROSOFT_V2: bit |= CHAP_MS2_PEER; break; -#endif +#endif /* MSCHAP_SUPPORT */ } break; case PPP_PAP: @@ -1049,14 +1049,14 @@ auth_withpeer_success(unit, protocol, prot_flavor) case CHAP_MD5: bit |= CHAP_MD5_WITHPEER; break; -#ifdef CHAPMS +#if MSCHAP_SUPPORT case CHAP_MICROSOFT: bit |= CHAP_MS_WITHPEER; break; case CHAP_MICROSOFT_V2: bit |= CHAP_MS2_WITHPEER; break; -#endif +#endif /* MSCHAP_SUPPORT */ } break; case PPP_PAP: @@ -1381,10 +1381,12 @@ auth_reset(unit) ao->chap_mdtype = MDTYPE_NONE; if(!ppp_settings.refuse_chap) ao->chap_mdtype |= MDTYPE_MD5; +#if MSCHAP_SUPPORT if(!ppp_settings.refuse_mschap) ao->chap_mdtype |= MDTYPE_MICROSOFT; if(!ppp_settings.refuse_mschap_v2) ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; +#endif /* MSCHAP_SUPPORT */ ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); @@ -1401,8 +1403,10 @@ auth_reset(unit) printf("neg_upap: %d\n", ao->neg_upap); printf("neg_chap: %d\n", ao->neg_chap); printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); +#if MSCHAP_SUPPORT printf("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT) ); printf("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2) ); +#endif /* MSCHAP_SUPPORT */ #if EAP_SUPPORT printf("neg_eap: %d\n", ao->neg_eap); #endif /* EAP_SUPPORT */ diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 90d9e289..f3b612e8 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -40,7 +40,7 @@ #include "chap-new.h" #include "chap-md5.h" -#ifdef CHAPMS +#if MSCHAP_SUPPORT #include "chap_ms.h" #define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) #else @@ -149,7 +149,7 @@ chap_init(int unit) memset(&server, 0, sizeof(server)); chap_md5_init(); -#ifdef CHAPMS +#if MSCHAP_SUPPORT chapms_init(); #endif } diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h index 48235d40..02e9b06a 100644 --- a/src/netif/ppp/chap-new.h +++ b/src/netif/ppp/chap-new.h @@ -28,6 +28,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "lwip/opt.h" + /* * CHAP packets begin with a standard header with code, id, len (2 bytes). */ @@ -45,8 +47,10 @@ * CHAP digest codes. */ #define CHAP_MD5 5 +#if MSCHAP_SUPPORT #define CHAP_MICROSOFT 0x80 #define CHAP_MICROSOFT_V2 0x81 +#endif /* MSCHAP_SUPPORT */ /* * Semi-arbitrary limits on challenge and response fields. @@ -55,37 +59,57 @@ #define MAX_RESPONSE_LEN 64 /* bitmask of supported algorithms */ +#if MSCHAP_SUPPORT #define MDTYPE_MICROSOFT_V2 0x1 #define MDTYPE_MICROSOFT 0x2 +#endif /* MSCHAP_SUPPORT */ #define MDTYPE_MD5 0x4 #define MDTYPE_NONE 0 /* hashes supported by this instance of pppd */ extern int chap_mdtype_all; +#if MSCHAP_SUPPORT /* Return the digest alg. ID for the most preferred digest type. */ #define CHAP_DIGEST(mdtype) \ ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \ ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \ 0 +#else /* !MSCHAP_SUPPORT */ +#define CHAP_DIGEST(mdtype) \ + ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ + 0 +#endif /* MSCHAP_SUPPORT */ /* Return the bit flag (lsb set) for our most preferred digest type. */ #define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype) /* Return the bit flag for a given digest algorithm ID. */ +#if MSCHAP_SUPPORT #define CHAP_MDTYPE_D(digest) \ ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \ ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \ ((digest) == CHAP_MD5)? MDTYPE_MD5: \ 0 +#else /* !MSCHAP_SUPPORT */ +#define CHAP_MDTYPE_D(digest) \ + ((digest) == CHAP_MD5)? MDTYPE_MD5: \ + 0 +#endif /* MSCHAP_SUPPORT */ /* Can we do the requested digest? */ +#if MSCHAP_SUPPORT #define CHAP_CANDIGEST(mdtype, digest) \ ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \ ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \ ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ 0 +#else /* !MSCHAP_SUPPORT */ +#define CHAP_CANDIGEST(mdtype, digest) \ + ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ + 0 +#endif /* MSCHAP_SUPPORT */ /* * The code for each digest type has to supply one of these. diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index e19b2a16..f3691bd3 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -75,10 +75,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $" - -#ifdef CHAPMS +#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include #include @@ -97,8 +94,6 @@ #include "pppcrypt.h" #include "magic.h" -static const char rcsid[] = RCSID; - #define SHA1_SIGNATURE_SIZE 20 static void ascii2unicode __P((char[], int, u_char[])); @@ -947,4 +942,4 @@ chapms_init(void) #endif /* PPP_OPTIONS */ } -#endif /* CHAPMS */ +#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/src/netif/ppp/chap_ms.h b/src/netif/ppp/chap_ms.h index 040d80ad..ffff9b66 100644 --- a/src/netif/ppp/chap_ms.h +++ b/src/netif/ppp/chap_ms.h @@ -30,6 +30,9 @@ * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + #ifndef __CHAPMS_INCLUDE__ #define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ @@ -107,3 +110,5 @@ void chapms_init(void); #define __CHAPMS_INCLUDE__ #endif /* __CHAPMS_INCLUDE__ */ + +#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index ab922637..7dfc6a74 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -2177,6 +2177,7 @@ lcp_printpkt(p, plen, printer, arg) printer(arg, " MD5"); ++p; break; +#if MSCHAP_SUPPORT case CHAP_MICROSOFT: printer(arg, " MS"); ++p; @@ -2186,6 +2187,7 @@ lcp_printpkt(p, plen, printer, arg) printer(arg, " MS-v2"); ++p; break; +#endif /* MSCHAP_SUPPORT */ } } break; diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 374f4319..3ac8ceb4 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -365,11 +365,13 @@ extern bool ms_lanman; /* Use LanMan password instead of NT */ /* Values for auth_done only */ #define CHAP_MD5_WITHPEER 0x40 #define CHAP_MD5_PEER 0x80 +#if MSCHAP_SUPPORT #define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ #define CHAP_MS_WITHPEER 0x100 #define CHAP_MS_PEER 0x200 #define CHAP_MS2_WITHPEER 0x400 #define CHAP_MS2_PEER 0x800 +#endif /* MSCHAP_SUPPORT */ extern char *current_option; /* the name of the option being parsed */ extern int privileged_option; /* set iff the current option came from root */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index c0b20570..4efcc982 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -435,10 +435,17 @@ int ppp_init(void) { void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { + /* FIXME: the following may look stupid, but this is just an easy way + * to check different auth by changing compile time option + */ + ppp_settings.refuse_pap = 1; + ppp_settings.refuse_chap = 0; +#if MSCHAP_SUPPORT ppp_settings.refuse_pap = 1; ppp_settings.refuse_chap = 1; ppp_settings.refuse_mschap = 1; ppp_settings.refuse_mschap_v2 = 0; +#endif /* MSCHAP_SUPPORT */ #if EAP_SUPPORT ppp_settings.refuse_pap = 1; ppp_settings.refuse_chap = 1; diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 042410df..f082f460 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -5,6 +5,8 @@ * Author: gradator */ +#include "lwip/opt.h" + #ifndef PPPMY_H_ #define PPPMY_H_ @@ -46,8 +48,10 @@ struct ppp_settings { u_int explicit_remote : 1; /* remote_name specified with remotename opt */ u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ +#if MSCHAP_SUPPORT u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#endif /* MSCHAP_SUPPORT */ #if EAP_SUPPORT u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ #endif /* EAP_SUPPORT */ From 339925e8358828fe412188d1dc351e59c9e35fe9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 24 May 2012 00:52:20 +0200 Subject: [PATCH 050/320] CHAP support is now an optional compile-time feature --- src/netif/ppp/auth.c | 60 +++++++++++++++++--- src/netif/ppp/chap-md5.c | 5 +- src/netif/ppp/chap-md5.h | 5 ++ src/netif/ppp/chap-new.c | 4 ++ src/netif/ppp/chap-new.h | 3 + src/netif/ppp/lcp.c | 116 ++++++++++++++++++++++++++++++++------- src/netif/ppp/lcp.h | 4 ++ src/netif/ppp/ppp.c | 14 ++++- src/netif/ppp/pppmy.c | 10 ++++ src/netif/ppp/pppmy.h | 6 +- 10 files changed, 193 insertions(+), 34 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index af43c0d2..dcc075d6 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -108,7 +108,9 @@ #include "ecp.h" #include "ipcp.h" #include "upap.h" +#if CHAP_SUPPORT #include "chap-new.h" +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT #include "eap.h" #endif /* EAP_SUPPORT */ @@ -763,7 +765,10 @@ link_established(unit) set_allowed_addrs(unit, NULL, NULL); #endif /* PPP_ALLOWED_ADDRS */ - if (auth_required && !(go->neg_upap || go->neg_chap + if (auth_required && !(go->neg_upap +#if CHAP_SUPPORT + || go->neg_chap +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT || go->neg_eap #endif /* EAP_SUPPORT */ @@ -798,10 +803,13 @@ link_established(unit) auth |= EAP_PEER; } else #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT if (go->neg_chap) { chap_auth_peer(unit, our_name, CHAP_DIGEST(go->chap_mdtype)); auth |= CHAP_PEER; - } else if (go->neg_upap) { + } else +#endif /* CHAP_SUPPORT */ + if (go->neg_upap) { upap_authpeer(unit); auth |= PAP_PEER; } @@ -811,10 +819,13 @@ link_established(unit) auth |= EAP_WITHPEER; } else #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT if (ho->neg_chap) { chap_auth_with_peer(unit, ppp_settings.user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; - } else if (ho->neg_upap) { + } else +#endif /* CHAP_SUPPORT */ + if (ho->neg_upap) { upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); auth |= PAP_WITHPEER; } @@ -844,7 +855,11 @@ network_phase(unit) /* * If the peer had to authenticate, run the auth-up script now. */ - if (go->neg_chap || go->neg_upap + if (0 +#if CHAP_SUPPORT + || go->neg_chap +#endif /* CHAP_SUPPORT */ + || go->neg_upap #if EAP_SUPPORT || go->neg_eap #endif /* EAP_SUPPORT */ @@ -967,6 +982,7 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) int bit; switch (protocol) { +#if CHAP_SUPPORT case PPP_CHAP: bit = CHAP_PEER; switch (prot_flavor) { @@ -983,6 +999,7 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) #endif /* MSCHAP_SUPPORT */ } break; +#endif /* CHAP_SUPPORT */ case PPP_PAP: bit = PAP_PEER; break; @@ -1042,6 +1059,7 @@ auth_withpeer_success(unit, protocol, prot_flavor) const char *prot = ""; switch (protocol) { +#if CHAP_SUPPORT case PPP_CHAP: bit = CHAP_WITHPEER; prot = "CHAP"; @@ -1059,6 +1077,7 @@ auth_withpeer_success(unit, protocol, prot_flavor) #endif /* MSCHAP_SUPPORT */ } break; +#endif /* CHAP_SUPPORT */ case PPP_PAP: bit = PAP_WITHPEER; prot = "PAP"; @@ -1274,28 +1293,38 @@ auth_check_options() default_auth = 1; } +#if CHAP_SUPPORT /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ if (wo->chap_mdtype) wo->neg_chap = 1; +#endif /* CHAP_SUPPORT */ /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ if (auth_required) { allow_any_ip = 0; - if (!wo->neg_chap && !wo->neg_upap + if (1 +#if CHAP_SUPPORT + && !wo->neg_chap +#endif /* CHAP_SUPPORT */ + && !wo->neg_upap #if EAP_SUPPORT && !wo->neg_eap #endif /* EAP_SUPPORT */ ) { +#if CHAP_SUPPORT wo->neg_chap = chap_mdtype_all != MDTYPE_NONE; wo->chap_mdtype = chap_mdtype_all; +#endif /* CHAP_SUPPORT */ wo->neg_upap = 1; #if EAP_SUPPORT wo->neg_eap = 1; #endif /* EAP_SUPPORT */ } } else { +#if CHAP_SUPPORT wo->neg_chap = 0; wo->chap_mdtype = MDTYPE_NONE; +#endif /* CHAP_SUPPORT */ wo->neg_upap = 0; #if EAP_SUPPORT wo->neg_eap = 0; @@ -1309,13 +1338,20 @@ auth_check_options() */ lacks_ip = 0; can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); - if (!can_auth && (wo->neg_chap + if (!can_auth && (0 +#if CHAP_SUPPORT + || wo->neg_chap +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT || wo->neg_eap #endif /* EAP_SUPPORT */ )) { +#if CHAP_SUPPORT can_auth = have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, &lacks_ip); +#else + can_auth = 0; +#endif } if (!can_auth #if EAP_SUPPORT @@ -1378,6 +1414,7 @@ auth_reset(unit) ao->neg_eap = !ppp_settings.refuse_eap; #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT ao->chap_mdtype = MDTYPE_NONE; if(!ppp_settings.refuse_chap) ao->chap_mdtype |= MDTYPE_MD5; @@ -1389,24 +1426,29 @@ auth_reset(unit) #endif /* MSCHAP_SUPPORT */ ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); +#endif /* CHAP_SUPPORT */ } else { ao->neg_upap = 0; +#if CHAP_SUPPORT ao->neg_chap = 0; + ao->chap_mdtype = MDTYPE_NONE; +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT ao->neg_eap = 0; #endif /* EAP_SUPPORT */ - ao->chap_mdtype = MDTYPE_NONE; } printf("neg_upap: %d\n", ao->neg_upap); +#if CHAP_SUPPORT printf("neg_chap: %d\n", ao->neg_chap); printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); #if MSCHAP_SUPPORT printf("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT) ); printf("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2) ); #endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT printf("neg_eap: %d\n", ao->neg_eap); #endif /* EAP_SUPPORT */ @@ -1428,11 +1470,13 @@ auth_reset(unit) #endif /* OLD CODE */ go->neg_upap = 0; +#if CHAP_SUPPORT go->neg_chap = 0; + go->chap_mdtype = MDTYPE_NONE; +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT go->neg_eap = 0; #endif /* EAP_SUPPORT */ - go->chap_mdtype = MDTYPE_NONE; return; #if 0 /* FIXME: find what the below stuff do */ diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index dec34cfd..19756937 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -29,8 +29,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: chap-md5.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" +#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include #include @@ -117,3 +116,5 @@ chap_md5_init(void) { chap_register_digest(&md5_digest); } + +#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/netif/ppp/chap-md5.h b/src/netif/ppp/chap-md5.h index 30d06588..cb6c56e3 100644 --- a/src/netif/ppp/chap-md5.h +++ b/src/netif/ppp/chap-md5.h @@ -28,4 +28,9 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "lwip/opt.h" +#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + extern void chap_md5_init(void); + +#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index f3b612e8..34a45898 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -29,6 +29,8 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + #include "pppmy.h" #define RCSID "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $" @@ -670,3 +672,5 @@ struct protent chap_protent = { NULL, NULL }; + +#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h index 02e9b06a..bb21fe22 100644 --- a/src/netif/ppp/chap-new.h +++ b/src/netif/ppp/chap-new.h @@ -29,6 +29,7 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ /* * CHAP packets begin with a standard header with code, id, len (2 bytes). @@ -152,3 +153,5 @@ extern void chap_auth_with_peer(int unit, char *our_name, int digest_code); /* Represents the CHAP protocol to the main pppd code */ extern struct protent chap_protent; + +#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 7dfc6a74..d5722ece 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -42,8 +42,6 @@ #include "lwip/opt.h" -#define RCSID "$Id: lcp.c,v 1.76 2006/05/22 00:04:07 paulus Exp $" - /* * TODO: */ @@ -56,11 +54,11 @@ #include "pppmy.h" #include "fsm.h" #include "lcp.h" +#if CHAP_SUPPORT #include "chap-new.h" +#endif /* CHAP_SUPPORT */ #include "magic.h" -static const char rcsid[] = RCSID; - /* * When the link comes up we want to be able to wait for a short while, * or until seeing some input from the peer, before starting to send @@ -299,7 +297,9 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL; #define CILEN_VOID 2 #define CILEN_CHAR 3 #define CILEN_SHORT 4 /* CILEN_VOID + 2 */ +#if CHAP_SUPPORT #define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ +#endif /* CHAP_SUPPORT */ #define CILEN_LONG 6 /* CILEN_VOID + 4 */ #define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ #define CILEN_CBCP 3 @@ -372,8 +372,10 @@ lcp_init(unit) ao->neg_mru = 1; ao->mru = MAXMRU; ao->neg_asyncmap = 1; +#if CHAP_SUPPORT ao->neg_chap = 1; ao->chap_mdtype = chap_mdtype_all; +#endif /* CHAP_SUPPORT */ ao->neg_upap = 1; #if EAP_SUPPORT ao->neg_eap = 1; @@ -690,7 +692,9 @@ lcp_cilen(f) lcp_options *go = &lcp_gotoptions[f->unit]; #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) +#if CHAP_SUPPORT #define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) +#endif /* CHAP_SUPPORT */ #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) @@ -705,16 +709,21 @@ lcp_cilen(f) #if EAP_SUPPORT LENCISHORT(go->neg_eap) + #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT LENCICHAP( #if EAP_SUPPORT !go->neg_eap && #endif /* EAP_SUPPORT */ go->neg_chap) + +#endif /* CHAP_SUPPORT */ LENCISHORT( #if EAP_SUPPORT !go->neg_eap && #endif /* EAP_SUPPORT */ - !go->neg_chap && go->neg_upap) + +#if CHAP_SUPPORT + !go->neg_chap && +#endif /* CHAP_SUPPORT */ + go->neg_upap) + LENCILQR(go->neg_lqr) + LENCICBCP(go->neg_cbcp) + LENCILONG(go->neg_magicnumber) + @@ -749,6 +758,7 @@ lcp_addci(f, ucp, lenp) PUTCHAR(CILEN_SHORT, ucp); \ PUTSHORT(val, ucp); \ } +#if CHAP_SUPPORT #define ADDCICHAP(opt, neg, val) \ if (neg) { \ PUTCHAR((opt), ucp); \ @@ -756,6 +766,7 @@ lcp_addci(f, ucp, lenp) PUTSHORT(PPP_CHAP, ucp); \ PUTCHAR((CHAP_DIGEST(val)), ucp); \ } +#endif /* CHAP_SUPPORT */ #define ADDCILONG(opt, neg, val) \ if (neg) { \ PUTCHAR(opt, ucp); \ @@ -791,16 +802,21 @@ lcp_addci(f, ucp, lenp) #if EAP_SUPPORT ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT ADDCICHAP(CI_AUTHTYPE, #if EAP_SUPPORT !go->neg_eap && #endif /* EAP_SUPPORT */ go->neg_chap, go->chap_mdtype); +#endif /* CHAP_SUPPORT */ ADDCISHORT(CI_AUTHTYPE, #if EAP_SUPPORT !go->neg_eap && #endif /* EAP_SUPPORT */ - !go->neg_chap && go->neg_upap, PPP_PAP); +#if CHAP_SUPPORT + !go->neg_chap && +#endif /* CHAP_SUPPORT */ + 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); @@ -878,6 +894,7 @@ lcp_ackci(f, p, len) if (cichar != val) \ goto bad; \ } +#if CHAP_SUPPORT #define ACKCICHAP(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_CHAP) < 0) \ @@ -894,6 +911,7 @@ lcp_ackci(f, p, len) if (cichar != (CHAP_DIGEST(val))) \ goto bad; \ } +#endif /* CHAP_SUPPORT */ #define ACKCILONG(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_LONG) < 0) \ @@ -949,16 +967,21 @@ lcp_ackci(f, p, len) #if EAP_SUPPORT ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT ACKCICHAP(CI_AUTHTYPE, #if EAP_SUPPORT !go->neg_eap && #endif /* EAP_SUPPORT */ go->neg_chap, go->chap_mdtype); +#endif /* CHAP_SUPPORT */ ACKCISHORT(CI_AUTHTYPE, #if EAP_SUPPORT !go->neg_eap && #endif /* EAP_SUPPORT */ - !go->neg_chap && go->neg_upap, PPP_PAP); +#if CHAP_SUPPORT + !go->neg_chap && +#endif /* CHAP_SUPPORT */ + 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); @@ -1025,6 +1048,7 @@ lcp_nakci(f, p, len, treat_as_reject) no.neg = 1; \ try.neg = 0; \ } +#if CHAP_SUPPORT #define NAKCICHAP(opt, neg, code) \ if (go->neg && \ len >= CILEN_CHAP && \ @@ -1037,6 +1061,7 @@ lcp_nakci(f, p, len, treat_as_reject) no.neg = 1; \ code \ } +#endif /* CHAP_SUPPORT */ #define NAKCICHAR(opt, neg, code) \ if (go->neg && \ len >= CILEN_CHAR && \ @@ -1126,7 +1151,11 @@ lcp_nakci(f, p, len, treat_as_reject) * they are proposing a different protocol, or a different * hash algorithm for CHAP. */ - if ((go->neg_chap || go->neg_upap + if ((0 +#if CHAP_SUPPORT + || go->neg_chap +#endif /* CHAP_SUPPORT */ + || go->neg_upap #if EAP_SUPPORT || go->neg_eap #endif /* EAP_SUPPORT */ @@ -1135,7 +1164,9 @@ lcp_nakci(f, p, len, treat_as_reject) && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { cilen = p[1]; len -= cilen; +#if CHAP_SUPPORT no.neg_chap = go->neg_chap; +#endif /* CHAP_SUPPORT */ no.neg_upap = go->neg_upap; #if EAP_SUPPORT no.neg_eap = go->neg_eap; @@ -1150,17 +1181,21 @@ lcp_nakci(f, p, len, treat_as_reject) else #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT /* If we were asking for CHAP, then we need to stop that. */ if (go->neg_chap) try.neg_chap = 0; + else +#endif /* CHAP_SUPPORT */ + /* * If we weren't asking for CHAP or EAP, then we were asking for * PAP, in which case this Nak is bad. */ - else goto bad; - - } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { + } +#if CHAP_SUPPORT + else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { GETCHAR(cichar, p); #if EAP_SUPPORT /* Stop asking for EAP, if we were. */ @@ -1200,7 +1235,9 @@ lcp_nakci(f, p, len, treat_as_reject) try.neg_upap = 0; } - } else { + } +#endif /* CHAP_SUPPORT */ + else { #if EAP_SUPPORT /* @@ -1218,9 +1255,12 @@ lcp_nakci(f, p, len, treat_as_reject) try.neg_eap = 0; else #endif /* EAP_SUPPORT */ + +#if CHAP_SUPPORT if (go->neg_chap) try.neg_chap = 0; else +#endif /* CHAP_SUPPORT */ try.neg_upap = 0; p += cilen - CILEN_SHORT; } @@ -1326,7 +1366,11 @@ lcp_nakci(f, p, len, treat_as_reject) goto bad; break; case CI_AUTHTYPE: - if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap + if (0 +#if CHAP_SUPPORT + || go->neg_chap || no.neg_chap +#endif /* CHAP_SUPPORT */ + || go->neg_upap || no.neg_upap #if EAP_SUPPORT || go->neg_eap || no.neg_eap #endif /* EAP_SUPPORT */ @@ -1443,7 +1487,8 @@ lcp_rejci(f, p, len) goto bad; \ try.neg = 0; \ } -#if EAP_SUPPORT + +#if CHAP_SUPPORT && EAP_SUPPORT #define REJCICHAP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CHAP && \ @@ -1459,8 +1504,9 @@ lcp_rejci(f, p, len) try.neg = 0; \ try.neg_eap = try.neg_upap = 0; \ } -#endif /* EAP_SUPPORT */ -#if !EAP_SUPPORT +#endif /* CHAP_SUPPORT && EAP_SUPPORT */ + +#if CHAP_SUPPORT && !EAP_SUPPORT #define REJCICHAP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CHAP && \ @@ -1476,7 +1522,8 @@ lcp_rejci(f, p, len) try.neg = 0; \ try.neg_upap = 0; \ } -#endif /* !EAP_SUPPORT */ +#endif /* CHAP_SUPPORT && !EAP_SUPPORT */ + #define REJCILONG(opt, neg, val) \ if (go->neg && \ len >= CILEN_LONG && \ @@ -1542,10 +1589,14 @@ lcp_rejci(f, p, len) REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP); if (!go->neg_eap) { #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype); if (!go->neg_chap) { +#endif /* CHAP_SUPPORT */ REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); +#if CHAP_SUPPORT } +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT } #endif /* EAP_SUPPORT */ @@ -1684,7 +1735,10 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) case CI_AUTHTYPE: if (cilen < CILEN_SHORT || - !(ao->neg_upap || ao->neg_chap + !(ao->neg_upap +#if CHAP_SUPPORT + || ao->neg_chap +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT || ao->neg_eap #endif /* EAP_SUPPORT */ @@ -1711,7 +1765,10 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) if (cishort == PPP_PAP) { /* we've already accepted CHAP or EAP */ - if (ho->neg_chap + if (0 +#if CHAP_SUPPORT + || ho->neg_chap +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT || ho->neg_eap #endif /* EAP_SUPPORT */ @@ -1729,9 +1786,11 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) PUTSHORT(PPP_EAP, nakp); } else { #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT } #endif /* EAP_SUPPORT */ @@ -1740,6 +1799,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) ho->neg_upap = 1; break; } +#if CHAP_SUPPORT if (cishort == PPP_CHAP) { /* we've already accepted PAP or EAP */ if (ho->neg_upap @@ -1783,10 +1843,15 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) ho->neg_chap = 1; break; } +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT if (cishort == PPP_EAP) { /* we've already accepted CHAP or PAP */ - if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) { + if ( +#if CHAP_SUPPORT + ho->neg_chap || +#endif /* CHAP_SUPPORT */ + ho->neg_upap || cilen != CILEN_SHORT) { LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting...")); orc = CONFREJ; break; @@ -1794,14 +1859,18 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) if (!ao->neg_eap) { /* we don't want to do EAP */ orc = CONFNAK; /* NAK it and suggest CHAP or PAP */ PUTCHAR(CI_AUTHTYPE, nakp); +#if CHAP_SUPPORT if (ao->neg_chap) { PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); } else { +#endif /* CHAP_SUPPORT */ PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_PAP, nakp); +#if CHAP_SUPPORT } +#endif /* CHAP_SUPPORT */ break; } ho->neg_eap = 1; @@ -1824,11 +1893,14 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) PUTSHORT(PPP_EAP, nakp); } else #endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT if (ao->neg_chap) { PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); - } else { + } else +#endif CHAP_SUPPORT + { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_PAP, nakp); } @@ -2169,6 +2241,7 @@ lcp_printpkt(p, plen, printer, arg) case PPP_PAP: printer(arg, "pap"); break; +#if CHAP_SUPPORT case PPP_CHAP: printer(arg, "chap"); if (p < optend) { @@ -2191,6 +2264,7 @@ lcp_printpkt(p, plen, printer, arg) } } break; +#endif /* CHAP_SUPPORT */ case PPP_EAP: printer(arg, "eap"); break; diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index b440da97..524e9738 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -92,7 +92,9 @@ typedef struct lcp_options { bool neg_mru; /* Negotiate the MRU? */ bool neg_asyncmap; /* Negotiate the async map? */ bool neg_upap; /* Ask for UPAP authentication? */ +#if CHAP_SUPPORT bool neg_chap; /* Ask for CHAP authentication? */ +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT bool neg_eap; /* Ask for EAP authentication? */ #endif /* EAP_SUPPORT */ @@ -106,7 +108,9 @@ typedef struct lcp_options { bool neg_endpoint; /* negotiate endpoint discriminator */ int mru; /* Value of MRU */ int mrru; /* Value of MRRU, and multilink enable */ +#if CHAP_SUPPORT u_char chap_mdtype; /* which MD types (hashing algorithm) */ +#endif /* CHAP_SUPPORT */ u_int32_t asyncmap; /* Value of async map */ u_int32_t magicnumber; int numloops; /* Number of loops during magic number neg. */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 192d00b5..3e528466 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -103,7 +103,9 @@ #include "ipv6cp.h" #endif #include "upap.h" +#if CHAP_SUPPORT #include "chap-new.h" +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT #include "eap.h" #endif /* EAP_SUPPORT */ @@ -267,7 +269,9 @@ extern char *getlogin __P((void)); struct protent *protocols[] = { &lcp_protent, &pap_protent, +#if CHAP_SUPPORT &chap_protent, +#endif /* CHAP_SUPPORT */ #if CBCP_SUPPORT &cbcp_protent, #endif @@ -1056,8 +1060,14 @@ get_input() */ if (phase <= PHASE_AUTHENTICATE && !(protocol == PPP_LCP || protocol == PPP_LQR - || protocol == PPP_PAP || protocol == PPP_CHAP || - protocol == PPP_EAP)) { + || protocol == PPP_PAP +#if CHAP_SUPPORT + || protocol == PPP_CHAP +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || protocol == PPP_EAP +#endif /* EAP_SUPPORT */ + )) { dbglog("discarding proto 0x%x in phase %d", protocol, phase); return; diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 4efcc982..4a4d8fe0 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -438,19 +438,29 @@ pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) /* FIXME: the following may look stupid, but this is just an easy way * to check different auth by changing compile time option */ + ppp_settings.refuse_pap = 0; + +#if CHAP_SUPPORT ppp_settings.refuse_pap = 1; ppp_settings.refuse_chap = 0; +#endif /* CHAP_SUPPORT */ + #if MSCHAP_SUPPORT ppp_settings.refuse_pap = 1; ppp_settings.refuse_chap = 1; ppp_settings.refuse_mschap = 1; ppp_settings.refuse_mschap_v2 = 0; #endif /* MSCHAP_SUPPORT */ + #if EAP_SUPPORT ppp_settings.refuse_pap = 1; +#if CHAP_SUPPORT ppp_settings.refuse_chap = 1; +#if MSCHAP_SUPPORT ppp_settings.refuse_mschap = 1; ppp_settings.refuse_mschap_v2 = 1; +#endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ ppp_settings.refuse_eap = 0; #endif /* EAP_SUPPORT */ diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index f082f460..4206947d 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -47,7 +47,9 @@ struct ppp_settings { u_int auth_required : 1; /* Peer is required to authenticate */ u_int explicit_remote : 1; /* remote_name specified with remotename opt */ u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ +#if CHAP_SUPPORT u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ +#endif /* CHAP_SUPPORT */ #if MSCHAP_SUPPORT u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ @@ -112,7 +114,9 @@ enum pppAuthType { PPPAUTHTYPE_NONE, PPPAUTHTYPE_ANY, PPPAUTHTYPE_PAP, - PPPAUTHTYPE_CHAP +#if CHAP_SUPPORT + PPPAUTHTYPE_CHAP, +#endif /* CHAP_SUPPORT */ }; void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); From 4704efa32a85a9c7aff57a1f48dcd4dd6037c42b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 30 May 2012 23:32:30 +0200 Subject: [PATCH 051/320] PAP support is now an optional compile-time feature --- src/netif/ppp/auth.c | 48 ++++++++++++++-- src/netif/ppp/lcp.c | 129 +++++++++++++++++++++++++++++++++++------- src/netif/ppp/lcp.h | 2 + src/netif/ppp/ppp.c | 4 ++ src/netif/ppp/pppd.h | 8 +++ src/netif/ppp/pppmy.c | 20 ++++++- src/netif/ppp/pppmy.h | 2 + src/netif/ppp/upap.c | 7 +-- src/netif/ppp/upap.h | 5 ++ 9 files changed, 193 insertions(+), 32 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index dcc075d6..17dd572e 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -107,7 +107,9 @@ #include "ccp.h" #include "ecp.h" #include "ipcp.h" +#if PAP_SUPPORT #include "upap.h" +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT #include "chap-new.h" #endif /* CHAP_SUPPORT */ @@ -765,7 +767,10 @@ link_established(unit) set_allowed_addrs(unit, NULL, NULL); #endif /* PPP_ALLOWED_ADDRS */ - if (auth_required && !(go->neg_upap + if (auth_required && !(0 +#if PAP_SUPPORT + || go->neg_upap +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT || go->neg_chap #endif /* CHAP_SUPPORT */ @@ -809,10 +814,14 @@ link_established(unit) auth |= CHAP_PEER; } else #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT if (go->neg_upap) { upap_authpeer(unit); auth |= PAP_PEER; - } + } else +#endif /* PAP_SUPPORT */ + {} + #if EAP_SUPPORT if (ho->neg_eap) { eap_authwithpeer(unit, ppp_settings.user); @@ -825,10 +834,14 @@ link_established(unit) auth |= CHAP_WITHPEER; } else #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT if (ho->neg_upap) { upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); auth |= PAP_WITHPEER; - } + } else +#endif /* PAP_SUPPORT */ + {} + auth_pending[unit] = auth; auth_done[unit] = 0; @@ -859,7 +872,9 @@ network_phase(unit) #if CHAP_SUPPORT || go->neg_chap #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT || go->neg_upap +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT || go->neg_eap #endif /* EAP_SUPPORT */ @@ -1000,12 +1015,16 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) } break; #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT case PPP_PAP: bit = PAP_PEER; break; +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT case PPP_EAP: bit = EAP_PEER; break; +#endif /* EAP_SUPPORT */ default: warn("auth_peer_success: unknown protocol %x", protocol); return; @@ -1078,14 +1097,18 @@ auth_withpeer_success(unit, protocol, prot_flavor) } break; #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT case PPP_PAP: bit = PAP_WITHPEER; prot = "PAP"; break; +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT case PPP_EAP: bit = EAP_WITHPEER; prot = "EAP"; break; +#endif /* EAP_SUPPORT */ default: warn("auth_withpeer_success: unknown protocol %x", protocol); bit = 0; @@ -1306,7 +1329,9 @@ auth_check_options() #if CHAP_SUPPORT && !wo->neg_chap #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT && !wo->neg_upap +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT && !wo->neg_eap #endif /* EAP_SUPPORT */ @@ -1315,7 +1340,9 @@ auth_check_options() wo->neg_chap = chap_mdtype_all != MDTYPE_NONE; wo->chap_mdtype = chap_mdtype_all; #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT wo->neg_upap = 1; +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT wo->neg_eap = 1; #endif /* EAP_SUPPORT */ @@ -1325,7 +1352,9 @@ auth_check_options() wo->neg_chap = 0; wo->chap_mdtype = MDTYPE_NONE; #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT wo->neg_upap = 0; +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT wo->neg_eap = 0; #endif /* EAP_SUPPORT */ @@ -1337,7 +1366,11 @@ auth_check_options() * of a CHAP-like exchanges as well as SRP. */ lacks_ip = 0; +#if PAP_SUPPORT can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); +#else + can_auth = 0; +#endif /* PAP_SUPPORT */ if (!can_auth && (0 #if CHAP_SUPPORT || wo->neg_chap @@ -1408,7 +1441,9 @@ auth_reset(unit) if( ppp_settings.passwd[0] ) { +#if PAP_SUPPORT ao->neg_upap = !ppp_settings.refuse_pap; +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT ao->neg_eap = !ppp_settings.refuse_eap; @@ -1429,7 +1464,9 @@ auth_reset(unit) #endif /* CHAP_SUPPORT */ } else { +#if PAP_SUPPORT ao->neg_upap = 0; +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT ao->neg_chap = 0; ao->chap_mdtype = MDTYPE_NONE; @@ -1439,8 +1476,9 @@ auth_reset(unit) #endif /* EAP_SUPPORT */ } - +#if PAP_SUPPORT printf("neg_upap: %d\n", ao->neg_upap); +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT printf("neg_chap: %d\n", ao->neg_chap); printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); @@ -1469,7 +1507,9 @@ auth_reset(unit) have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); */ #endif /* OLD CODE */ +#if PAP_SUPPORT go->neg_upap = 0; +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT go->neg_chap = 0; go->chap_mdtype = MDTYPE_NONE; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index d5722ece..a1a054e4 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -376,7 +376,9 @@ lcp_init(unit) ao->neg_chap = 1; ao->chap_mdtype = chap_mdtype_all; #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT ao->neg_upap = 1; +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT ao->neg_eap = 1; #endif /* EAP_SUPPORT */ @@ -716,6 +718,7 @@ lcp_cilen(f) #endif /* EAP_SUPPORT */ go->neg_chap) + #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT LENCISHORT( #if EAP_SUPPORT !go->neg_eap && @@ -724,6 +727,7 @@ lcp_cilen(f) !go->neg_chap && #endif /* CHAP_SUPPORT */ go->neg_upap) + +#endif /* PAP_SUPPORT */ LENCILQR(go->neg_lqr) + LENCICBCP(go->neg_cbcp) + LENCILONG(go->neg_magicnumber) + @@ -809,6 +813,7 @@ lcp_addci(f, ucp, lenp) #endif /* EAP_SUPPORT */ go->neg_chap, go->chap_mdtype); #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT ADDCISHORT(CI_AUTHTYPE, #if EAP_SUPPORT !go->neg_eap && @@ -817,6 +822,7 @@ lcp_addci(f, ucp, lenp) !go->neg_chap && #endif /* CHAP_SUPPORT */ go->neg_upap, PPP_PAP); +#endif /* PAP_SUPPORT */ 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); @@ -974,6 +980,7 @@ lcp_ackci(f, p, len) #endif /* EAP_SUPPORT */ go->neg_chap, go->chap_mdtype); #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT ACKCISHORT(CI_AUTHTYPE, #if EAP_SUPPORT !go->neg_eap && @@ -982,6 +989,7 @@ lcp_ackci(f, p, len) !go->neg_chap && #endif /* CHAP_SUPPORT */ go->neg_upap, PPP_PAP); +#endif /* PAP_SUPPORT */ 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); @@ -1155,7 +1163,9 @@ lcp_nakci(f, p, len, treat_as_reject) #if CHAP_SUPPORT || go->neg_chap #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT || go->neg_upap +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT || go->neg_eap #endif /* EAP_SUPPORT */ @@ -1167,12 +1177,16 @@ lcp_nakci(f, p, len, treat_as_reject) #if CHAP_SUPPORT no.neg_chap = go->neg_chap; #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT no.neg_upap = go->neg_upap; +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT no.neg_eap = go->neg_eap; #endif /* EAP_SUPPORT */ INCPTR(2, p); GETSHORT(cishort, p); + +#if PAP_SUPPORT if (cishort == PPP_PAP && cilen == CILEN_SHORT) { #if EAP_SUPPORT /* If we were asking for EAP, then we need to stop that. */ @@ -1193,9 +1207,11 @@ lcp_nakci(f, p, len, treat_as_reject) * PAP, in which case this Nak is bad. */ goto bad; - } + } else +#endif /* PAP_SUPPORT */ + #if CHAP_SUPPORT - else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { + if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { GETCHAR(cichar, p); #if EAP_SUPPORT /* Stop asking for EAP, if we were. */ @@ -1232,12 +1248,14 @@ lcp_nakci(f, p, len, treat_as_reject) /* * Stop asking for PAP if we were asking for it. */ +#if PAP_SUPPORT try.neg_upap = 0; +#endif /* PAP_SUPPORT */ } - } + } else #endif /* CHAP_SUPPORT */ - else { + { #if EAP_SUPPORT /* @@ -1261,7 +1279,14 @@ lcp_nakci(f, p, len, treat_as_reject) try.neg_chap = 0; else #endif /* CHAP_SUPPORT */ + +#if PAP_SUPPORT + if(1) try.neg_upap = 0; + else +#endif /* PAP_SUPPORT */ + {} + p += cilen - CILEN_SHORT; } } @@ -1370,7 +1395,9 @@ lcp_nakci(f, p, len, treat_as_reject) #if CHAP_SUPPORT || go->neg_chap || no.neg_chap #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT || go->neg_upap || no.neg_upap +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT || go->neg_eap || no.neg_eap #endif /* EAP_SUPPORT */ @@ -1488,7 +1515,7 @@ lcp_rejci(f, p, len) try.neg = 0; \ } -#if CHAP_SUPPORT && EAP_SUPPORT +#if CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT #define REJCICHAP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CHAP && \ @@ -1504,9 +1531,9 @@ lcp_rejci(f, p, len) try.neg = 0; \ try.neg_eap = try.neg_upap = 0; \ } -#endif /* CHAP_SUPPORT && EAP_SUPPORT */ +#endif /* CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT */ -#if CHAP_SUPPORT && !EAP_SUPPORT +#if CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT #define REJCICHAP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CHAP && \ @@ -1522,7 +1549,42 @@ lcp_rejci(f, p, len) try.neg = 0; \ try.neg_upap = 0; \ } -#endif /* CHAP_SUPPORT && !EAP_SUPPORT */ +#endif /* CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT */ + +#if CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT +#define REJCICHAP(opt, neg, val) \ + 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 != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ + goto bad; \ + try.neg = 0; \ + try.neg_eap = 0; \ + } +#endif /* CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT */ + +#if CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT +#define REJCICHAP(opt, neg, val) \ + 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 != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ + goto bad; \ + try.neg = 0; \ + } +#endif /* CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT */ #define REJCILONG(opt, neg, val) \ if (go->neg && \ @@ -1593,7 +1655,9 @@ lcp_rejci(f, p, len) REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype); if (!go->neg_chap) { #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT } #endif /* CHAP_SUPPORT */ @@ -1735,7 +1799,10 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) case CI_AUTHTYPE: if (cilen < CILEN_SHORT || - !(ao->neg_upap + !(0 +#if PAP_SUPPORT + || ao->neg_upap +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT || ao->neg_chap #endif /* CHAP_SUPPORT */ @@ -1763,6 +1830,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) * the ordering of the CIs in the peer's Configure-Request. */ +#if PAP_SUPPORT if (cishort == PPP_PAP) { /* we've already accepted CHAP or EAP */ if (0 @@ -1799,14 +1867,18 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) ho->neg_upap = 1; break; } +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT if (cishort == PPP_CHAP) { /* we've already accepted PAP or EAP */ - if (ho->neg_upap + if ( +#if PAP_SUPPORT + ho->neg_upap || +#endif /* PAP_SUPPORT */ #if EAP_SUPPORT - || ho->neg_eap + ho->neg_eap || #endif /* EAP_SUPPORT */ - || cilen != CILEN_CHAP) { + cilen != CILEN_CHAP) { LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); orc = CONFREJ; break; @@ -1818,12 +1890,15 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) #if EAP_SUPPORT if (ao->neg_eap) { PUTSHORT(PPP_EAP, nakp); - } else { + } else #endif /* EAP_SUPPORT */ +#if PAP_SUPPORT + if(1) { PUTSHORT(PPP_PAP, nakp); -#if EAP_SUPPORT } -#endif /* EAP_SUPPORT */ + else +#endif /* PAP_SUPPORT */ + {} break; } GETCHAR(cichar, p); /* get digest type */ @@ -1851,7 +1926,10 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) #if CHAP_SUPPORT ho->neg_chap || #endif /* CHAP_SUPPORT */ - ho->neg_upap || cilen != CILEN_SHORT) { +#if PAP_SUPPORT + ho->neg_upap || +#endif /* PAP_SUPPORT */ + cilen != CILEN_SHORT) { LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting...")); orc = CONFREJ; break; @@ -1864,13 +1942,15 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); - } else { + } else #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + if(1) { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_PAP, nakp); -#if CHAP_SUPPORT - } -#endif /* CHAP_SUPPORT */ + } else +#endif /* PAP_SUPPORT */ + {} break; } ho->neg_eap = 1; @@ -1900,10 +1980,13 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); } else #endif CHAP_SUPPORT - { +#if PAP_SUPPORT + if(1) { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_PAP, nakp); - } + } else +#endif /* PAP_SUPPORT */ + {} break; case CI_QUALITY: @@ -2238,9 +2321,11 @@ lcp_printpkt(p, plen, printer, arg) printer(arg, "auth "); GETSHORT(cishort, p); switch (cishort) { +#if PAP_SUPPORT case PPP_PAP: printer(arg, "pap"); break; +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT case PPP_CHAP: printer(arg, "chap"); diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index 524e9738..a97b73a7 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -91,7 +91,9 @@ typedef struct lcp_options { bool restart; /* Restart vs. exit after close */ bool neg_mru; /* Negotiate the MRU? */ bool neg_asyncmap; /* Negotiate the async map? */ +#if PAP_SUPPORT bool neg_upap; /* Ask for UPAP authentication? */ +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT bool neg_chap; /* Ask for CHAP authentication? */ #endif /* CHAP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 3e528466..65703f03 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -102,7 +102,9 @@ #ifdef INET6 #include "ipv6cp.h" #endif +#if PAP_SUPPORT #include "upap.h" +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT #include "chap-new.h" #endif /* CHAP_SUPPORT */ @@ -268,7 +270,9 @@ extern char *getlogin __P((void)); */ struct protent *protocols[] = { &lcp_protent, +#if PAP_SUPPORT &pap_protent, +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT &chap_protent, #endif /* CHAP_SUPPORT */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 3ac8ceb4..8e3cdc79 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -355,14 +355,21 @@ extern bool ms_lanman; /* Use LanMan password instead of NT */ #endif /* Values for auth_pending, auth_done */ +#if PAP_SUPPORT #define PAP_WITHPEER 0x1 #define PAP_PEER 0x2 +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT #define CHAP_WITHPEER 0x4 #define CHAP_PEER 0x8 +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT #define EAP_WITHPEER 0x10 #define EAP_PEER 0x20 +#endif /* EAP_SUPPORT */ /* Values for auth_done only */ +#if CHAP_SUPPORT #define CHAP_MD5_WITHPEER 0x40 #define CHAP_MD5_PEER 0x80 #if MSCHAP_SUPPORT @@ -372,6 +379,7 @@ extern bool ms_lanman; /* Use LanMan password instead of NT */ #define CHAP_MS2_WITHPEER 0x400 #define CHAP_MS2_PEER 0x800 #endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ extern char *current_option; /* the name of the option being parsed */ extern int privileged_option; /* set iff the current option came from root */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 4a4d8fe0..4c34dbbd 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -197,8 +197,16 @@ static void ppp_input(void *arg) { */ if (phase <= PHASE_AUTHENTICATE && !(protocol == PPP_LCP || protocol == PPP_LQR - || protocol == PPP_PAP || protocol == PPP_CHAP || - protocol == PPP_EAP)) { +#if PAP_SUPPORT + || protocol == PPP_PAP +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + || protocol == PPP_CHAP +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || protocol == PPP_EAP +#endif /* EAP_SUPPORT */ + )) { dbglog("discarding proto 0x%x in phase %d", protocol, phase); return; @@ -438,22 +446,30 @@ pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) /* FIXME: the following may look stupid, but this is just an easy way * to check different auth by changing compile time option */ +#if PAP_SUPPORT ppp_settings.refuse_pap = 0; +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT +#if PAP_SUPPORT ppp_settings.refuse_pap = 1; +#endif /* PAP_SUPPORT */ ppp_settings.refuse_chap = 0; #endif /* CHAP_SUPPORT */ #if MSCHAP_SUPPORT +#if PAP_SUPPORT ppp_settings.refuse_pap = 1; +#endif /* PAP_SUPPORT */ ppp_settings.refuse_chap = 1; ppp_settings.refuse_mschap = 1; ppp_settings.refuse_mschap_v2 = 0; #endif /* MSCHAP_SUPPORT */ #if EAP_SUPPORT +#if PAP_SUPPORT ppp_settings.refuse_pap = 1; +#endif/* PAP_SUPPORT */ #if CHAP_SUPPORT ppp_settings.refuse_chap = 1; #if MSCHAP_SUPPORT diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 4206947d..c5bea67a 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -46,7 +46,9 @@ struct ppp_settings { u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ u_int auth_required : 1; /* Peer is required to authenticate */ u_int explicit_remote : 1; /* remote_name specified with remotename opt */ +#if PAP_SUPPORT u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ #endif /* CHAP_SUPPORT */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index b86fe1e3..fb268b60 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -41,8 +41,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: upap.c,v 1.30 2005/07/13 10:41:58 paulus Exp $" +#if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ /* * TODO: @@ -54,8 +53,6 @@ #include "pppd.h" #include "upap.h" -static const char rcsid[] = RCSID; - static bool hide_password = 1; #if PPP_OPTIONS @@ -692,3 +689,5 @@ upap_printpkt(p, plen, printer, arg) return p - pstart; } + +#endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/src/netif/ppp/upap.h b/src/netif/ppp/upap.h index 5cb59e98..139b917e 100644 --- a/src/netif/ppp/upap.h +++ b/src/netif/ppp/upap.h @@ -42,6 +42,9 @@ * $Id: upap.h,v 1.8 2002/12/04 23:03:33 paulus Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + /* * Packet header = Code, id, length. */ @@ -108,3 +111,5 @@ void upap_authwithpeer __P((int, char *, char *)); void upap_authpeer __P((int)); extern struct protent pap_protent; + +#endif /* PPP_SUPPORT && PAP_SUPPORT */ From 26e8372c758d9e73348bcbf99842c32ab699eedc Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 1 Jun 2012 00:59:15 +0200 Subject: [PATCH 052/320] changed PolarSSL compile-time condition --- src/netif/ppp/polarssl/README | 8 ++++---- src/netif/ppp/polarssl/des.c | 4 ++-- src/netif/ppp/polarssl/md4.c | 4 ++-- src/netif/ppp/polarssl/md5.c | 4 ++-- src/netif/ppp/polarssl/sha1.c | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/netif/ppp/polarssl/README b/src/netif/ppp/polarssl/README index c71cabb8..71f78fa9 100644 --- a/src/netif/ppp/polarssl/README +++ b/src/netif/ppp/polarssl/README @@ -15,10 +15,10 @@ library into lwIP: The following defines are available for flexibility: -LWIP_INCLUDED_POLARSSL_MD4_C ; Use lwIP internal PolarSSL for MD4 -LWIP_INCLUDED_POLARSSL_MD5_C ; Use lwIP internal PolarSSL for MD5 -LWIP_INCLUDED_POLARSSL_SHA1_C ; Use lwIP internal PolarSSL for SHA1 -LWIP_INCLUDED_POLARSSL_DES_C ; Use lwIP internal PolarSSL for DES +LWIP_INCLUDED_POLARSSL_MD4 ; Use lwIP internal PolarSSL for MD4 +LWIP_INCLUDED_POLARSSL_MD5 ; Use lwIP internal PolarSSL for MD5 +LWIP_INCLUDED_POLARSSL_SHA1 ; Use lwIP internal PolarSSL for SHA1 +LWIP_INCLUDED_POLARSSL_DES ; Use lwIP internal PolarSSL for DES If set (=1), the default if required by another enabled PPP feature unless explicitly set to 0, using included lwIP PolarSSL. diff --git a/src/netif/ppp/polarssl/des.c b/src/netif/ppp/polarssl/des.c index ac23cbc2..76b10743 100644 --- a/src/netif/ppp/polarssl/des.c +++ b/src/netif/ppp/polarssl/des.c @@ -40,7 +40,7 @@ */ #include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_DES_C) +#if LWIP_INCLUDED_POLARSSL_DES #include "polarssl/des.h" @@ -419,4 +419,4 @@ void des_crypt_ecb( des_context *ctx, PUT_ULONG_BE( X, output, 4 ); } -#endif /* LWIP_INCLUDED_POLARSSL_DES_C */ +#endif /* LWIP_INCLUDED_POLARSSL_DES */ diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/md4.c index 3d8a8fda..5bbc1710 100644 --- a/src/netif/ppp/polarssl/md4.c +++ b/src/netif/ppp/polarssl/md4.c @@ -40,7 +40,7 @@ */ #include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_MD4_C) +#if LWIP_INCLUDED_POLARSSL_MD4 #include "polarssl/md4.h" @@ -276,4 +276,4 @@ void md4( unsigned char *input, int ilen, unsigned char output[16] ) md4_finish( &ctx, output ); } -#endif /* LWIP_INCLUDED_POLARSSL_MD4_C */ +#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/md5.c index a98e8289..bb124940 100644 --- a/src/netif/ppp/polarssl/md5.c +++ b/src/netif/ppp/polarssl/md5.c @@ -39,7 +39,7 @@ */ #include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_MD5_C) +#if LWIP_INCLUDED_POLARSSL_MD5 #include "polarssl/md5.h" @@ -295,4 +295,4 @@ void md5( unsigned char *input, int ilen, unsigned char output[16] ) md5_finish( &ctx, output ); } -#endif /* LWIP_INCLUDED_POLARSSL_MD5_C */ +#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/sha1.c index 6d6e682a..1fc51989 100644 --- a/src/netif/ppp/polarssl/sha1.c +++ b/src/netif/ppp/polarssl/sha1.c @@ -39,7 +39,7 @@ */ #include "lwip/opt.h" -#if defined(LWIP_INCLUDED_POLARSSL_SHA1_C) +#if LWIP_INCLUDED_POLARSSL_SHA1 #include "polarssl/sha1.h" @@ -330,4 +330,4 @@ void sha1( unsigned char *input, int ilen, unsigned char output[20] ) sha1_finish( &ctx, output ); } -#endif /* LWIP_INCLUDED_POLARSSL_SHA1_C */ +#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ From 8bb4ea85b8b0877e9d78cde6e5b97cdb5e7d4c02 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 1 Jun 2012 01:07:27 +0200 Subject: [PATCH 053/320] removed some useless Linux calls --- src/netif/ppp/ppp.c | 12 +-- src/netif/ppp/pppd.h | 3 - src/netif/ppp/sys-linux.c | 160 -------------------------------------- 3 files changed, 1 insertion(+), 174 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 65703f03..45e333a6 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -389,11 +389,6 @@ int ppp_oldmain() { argv[0]); exit(EXIT_NOT_ROOT); } - - if (!ppp_available()) { - option_error("%s", no_ppp_msg); - exit(EXIT_NO_KERNEL_SUPPORT); - } #endif #if PPP_OPTIONS @@ -435,11 +430,6 @@ int ppp_oldmain() { fd_devnull = i; } - /* - * Initialize system-dependent stuff. - */ - linux_sys_init(); - /* * Detach ourselves from the terminal, if required, * and identify who is running us. @@ -454,7 +444,7 @@ int ppp_oldmain() { else p = "(unknown)"; } - syslog(LOG_NOTICE, "pppd %s started by %s, uid %d", VERSION, p, uid); + syslog(LOG_NOTICE, "pppd started by %s, uid %d", p, uid); script_setenv("PPPLOGNAME", p, 0); if (devnam[0]) diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 8e3cdc79..39765e7a 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -57,7 +57,6 @@ #include /* for u_int32_t, if defined */ #include /* for struct timeval */ #include -#include "patchlevel.h" #if defined(__STDC__) #include @@ -603,11 +602,9 @@ int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ #endif /* Procedures exported from sys-*.c */ -void sys_init __P((void)); /* Do system-dependent initialization */ void sys_cleanup __P((void)); /* Restore system state before exiting */ int sys_check_options __P((void)); /* Check options specified */ void sys_close __P((void)); /* Clean up in a child before execing */ -int ppp_available __P((void)); /* Test whether ppp kernel support exists */ int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */ int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */ int tty_establish_ppp __P((int)); /* Turn serial port into a ppp interface */ diff --git a/src/netif/ppp/sys-linux.c b/src/netif/ppp/sys-linux.c index 9fdf6c73..c3f1d172 100644 --- a/src/netif/ppp/sys-linux.c +++ b/src/netif/ppp/sys-linux.c @@ -294,28 +294,6 @@ static int modify_flags(int fd, int clear_bits, int set_bits) return -1; } -/******************************************************************** - * - * sys_init - System-dependent initialization. - */ - -void linux_sys_init(void) -{ - /* Get an internet socket for doing socket ioctls. */ - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - fatal("Couldn't create IP socket: %m(%d)", errno); - -#ifdef INET6 - sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (sock6_fd < 0) - sock6_fd = -errno; /* save errno for later */ -#endif - - FD_ZERO(&in_fds); - max_in_fd = 0; -} - /******************************************************************** * * sys_cleanup - restore any system state we modified before exiting: @@ -2061,144 +2039,6 @@ ppp_registered(void) return ret; } -/******************************************************************** - * - * 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, fd, err; - struct ifreq ifr; - int size; - int my_version, my_modification, my_patch; - int osmaj, osmin, ospatch; - - /* get the kernel version now, since we are called before sys_init */ - uname(&utsname); - osmaj = osmin = ospatch = 0; - sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch); - kernel_version = KVERSION(osmaj, osmin, ospatch); - - fd = open("/dev/ppp", O_RDWR); - if (fd >= 0) { - new_style_driver = 1; - - /* XXX should get from driver */ - driver_version = 2; - driver_modification = 4; - driver_patch = 0; - close(fd); - return 1; - } - err = errno; - - if (kernel_version >= KVERSION(2,3,13)) { - error("Couldn't open the /dev/ppp device: %m"); - if (errno == ENOENT) - no_ppp_msg = - "You need to create the /dev/ppp device node by\n" - "executing the following command as root:\n" - " mknod /dev/ppp c 108 0\n"; - else if (errno == ENODEV || errno == ENXIO) - no_ppp_msg = - "Please load the ppp_generic kernel module.\n"; - return 0; - } - - /* we are running on a really really old kernel */ - no_ppp_msg = - "This system lacks kernel support for PPP. This could be because\n" - "the PPP kernel module could not be loaded, or because PPP was not\n" - "included in the kernel configuration. If PPP was included as a\n" - "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n" - "ppp.o exists in /lib/modules/`uname -r`/net.\n" - "See README.linux file in the ppp distribution for more details.\n"; - -/* - * Open a socket for doing the ioctl operations. - */ - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) - return 0; - - strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; -/* - * If the device did not exist then attempt to create one by putting the - * current tty into the PPP discipline. If this works then obtain the - * flags for the device again. - */ - if (!ok) { - if (ppp_registered()) { - strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; - } - } -/* - * Ensure that the hardware address is for PPP and not something else - */ - if (ok) - ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0; - - if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP)) - ok = 0; - -/* - * This is the PPP device. Validate the version of the driver at this - * point to ensure that this program will work with the driver. - */ - if (ok) { - char abBuffer [1024]; - - ifr.ifr_data = abBuffer; - size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr); - if (size < 0) { - error("Couldn't read driver version: %m"); - ok = 0; - no_ppp_msg = "Sorry, couldn't verify kernel driver version\n"; - - } else { - decode_version(abBuffer, - &driver_version, - &driver_modification, - &driver_patch); -/* - * Validate the version of the driver against the version that we used. - */ - decode_version(VERSION, - &my_version, - &my_modification, - &my_patch); - - /* The version numbers must match */ - if (driver_version != my_version) - ok = 0; - - /* The modification levels must be legal */ - if (driver_modification < 3) { - if (driver_modification >= 2) { - /* we can cope with 2.2.0 and above */ - driver_is_old = 1; - } else { - ok = 0; - } - } - - close (s); - if (!ok) { - slprintf(route_buffer, sizeof(route_buffer), - "Sorry - PPP driver version %d.%d.%d is out of date\n", - driver_version, driver_modification, driver_patch); - - no_ppp_msg = route_buffer; - } - } - } - return ok; -} - /******************************************************************** * * Update the wtmp file with the appropriate user name and tty device. From a17ea134534d66b227ca2b3650feccc0b7479459 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 1 Jun 2012 01:10:02 +0200 Subject: [PATCH 054/320] autoselecting which PolarSSL files to use support added --- src/include/lwip/opt.h | 55 ++++++++++++++++++++++++++++++++++++++ src/netif/ppp/cbcp.h | 26 ------------------ src/netif/ppp/magic.c | 1 - src/netif/ppp/magic.h | 1 - src/netif/ppp/patchlevel.h | 2 -- src/netif/ppp/pppcrypt.c | 5 ++-- src/netif/ppp/pppcrypt.h | 5 ++++ 7 files changed, 63 insertions(+), 32 deletions(-) delete mode 100644 src/netif/ppp/cbcp.h delete mode 100644 src/netif/ppp/patchlevel.h diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 3b7222e8..c80fd17c 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1722,6 +1722,10 @@ #ifndef MSCHAP_SUPPORT #define MSCHAP_SUPPORT 0 #endif +#if MSCHAP_SUPPORT +#undef CHAP_SUPPORT +#define CHAP_SUPPORT 1 /* MSCHAP require CHAP support */ +#endif /* MSCHAP_SUPPORT */ /** * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! @@ -1751,6 +1755,57 @@ #define MD5_SUPPORT 0 #endif +/** + * PolarSSL library, used if necessary and not previously disabled + * + * + * lwIP contains some files fetched from the latest BSD release of + * the PolarSSL project for ciphers and encryption methods we need for lwIP + * PPP support. + * + * The PolarSSL files were cleaned to contain only the necessary struct + * fields and functions needed for lwIP. + * + * The PolarSSL API was not changed at all, so if you are already using + * PolarSSL you can choose to skip the compilation of the included PolarSSL + * library into lwIP: + * + * The following defines are available for flexibility: + * + * LWIP_INCLUDED_POLARSSL_MD4 ; Use lwIP internal PolarSSL for MD4 + * LWIP_INCLUDED_POLARSSL_MD5 ; Use lwIP internal PolarSSL for MD5 + * LWIP_INCLUDED_POLARSSL_SHA1 ; Use lwIP internal PolarSSL for SHA1 + * LWIP_INCLUDED_POLARSSL_DES ; Use lwIP internal PolarSSL for DES + * + * If set (=1), the default if required by another enabled PPP feature unless + * explicitly set to 0, using included lwIP PolarSSL. + * + * If clear (=0), using external PolarSSL. + * + * Undefined if not needed. + * + * Beware of the stack requirements which can be a lot larger if you are not + * using our cleaned PolarSSL library. + */ + +#if CHAP_SUPPORT || EAP_SUPPORT +#ifndef LWIP_INCLUDED_POLARSSL_MD5 +#define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP and EAP require MD5 support */ +#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ +#endif /* CHAP_SUPPORT || EAP_SUPPORT */ + +#if MSCHAP_SUPPORT +#ifndef LWIP_INCLUDED_POLARSSL_MD4 +#define LWIP_INCLUDED_POLARSSL_MD4 1 /* MSCHAP require MD4 support */ +#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ +#ifndef LWIP_INCLUDED_POLARSSL_SHA1 +#define LWIP_INCLUDED_POLARSSL_SHA1 1 /* MSCHAP require SHA1 support */ +#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ +#ifndef LWIP_INCLUDED_POLARSSL_DES +#define LWIP_INCLUDED_POLARSSL_DES 1 /* MSCHAP require DES support */ +#endif /* LWIP_INCLUDED_POLARSSL_DES */ +#endif /* MSCHAP_SUPPORT */ + /* * Timeouts */ diff --git a/src/netif/ppp/cbcp.h b/src/netif/ppp/cbcp.h deleted file mode 100644 index c2ab3f68..00000000 --- a/src/netif/ppp/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/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index de65a96e..c5587ce5 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -73,7 +73,6 @@ *****************************************************************************/ #include "lwip/opt.h" - #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include "polarssl/md5.h" diff --git a/src/netif/ppp/magic.h b/src/netif/ppp/magic.h index 2c714140..8c4c016e 100644 --- a/src/netif/ppp/magic.h +++ b/src/netif/ppp/magic.h @@ -78,7 +78,6 @@ #define MAGIC_H #include "lwip/opt.h" - #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ /*********************** diff --git a/src/netif/ppp/patchlevel.h b/src/netif/ppp/patchlevel.h deleted file mode 100644 index b7d6ce33..00000000 --- a/src/netif/ppp/patchlevel.h +++ /dev/null @@ -1,2 +0,0 @@ -#define VERSION "2.4.5" -#define DATE "17 November 2009" diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index 9bde8953..3baa16d1 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -31,8 +31,7 @@ */ #include "lwip/opt.h" - -/* FIXME: dont include if not needed */ +#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */ #include "pppd.h" #include "pppcrypt.h" @@ -62,3 +61,5 @@ void pppcrypt_56_to_64_bit_key(u_char *key, u_char * des_key) { des_key[6] = pppcrypt_get_7bits(key, 42); des_key[7] = pppcrypt_get_7bits(key, 49); } + +#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/src/netif/ppp/pppcrypt.h b/src/netif/ppp/pppcrypt.h index 6b5eaf8b..ef2e87de 100644 --- a/src/netif/ppp/pppcrypt.h +++ b/src/netif/ppp/pppcrypt.h @@ -30,9 +30,14 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "lwip/opt.h" +#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + #ifndef PPPCRYPT_H #define PPPCRYPT_H void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key); #endif /* PPPCRYPT_H */ + +#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ From fc074937f5efccf5b3ef8372b401228130594dbb Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 00:19:40 +0200 Subject: [PATCH 055/320] Linux ioctl() gone, ECP support optional, CCP support optional Removed all the used Linux ioctl(), sys_linux.c is entirely disabled. Replaced unecessary functions to set up a PPP link to null fonctions, however all stuff necessary to shutdown a PPP link should be done. Some utils functions related to I/O files are disabled too. ECP and CCP support only set PPP attributes into the PPP kernel support, they are now compile-time options and are disabled by default and obviously not supported (yet? :p) --- src/netif/ppp/auth.c | 35 ++++++++++- src/netif/ppp/ccp.c | 2 + src/netif/ppp/ccp.h | 5 ++ src/netif/ppp/demand.c | 4 ++ src/netif/ppp/ecp.c | 2 + src/netif/ppp/ecp.h | 5 ++ src/netif/ppp/options.c | 2 +- src/netif/ppp/ppp.c | 45 +++++++++++--- src/netif/ppp/pppd.h | 13 +++++ src/netif/ppp/pppmy.c | 120 ++++++++++++++++++++++++++++++++++++++ src/netif/ppp/sys-linux.c | 4 +- src/netif/ppp/tty.c | 15 ++++- src/netif/ppp/utils.c | 6 ++ 13 files changed, 244 insertions(+), 14 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 17dd572e..d0b7e2cb 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -913,7 +913,12 @@ start_networks(unit) { int i; struct protent *protp; - int ecp_required, mppe_required; +#if ECP_SUPPORT + int ecp_required; +#endif /* ECP_SUPPORT */ +#ifdef MPPE + int mppe_required; +#endif /* MPPE */ new_phase(PHASE_NETWORK); @@ -933,18 +938,40 @@ start_networks(unit) if (!demand) set_filters(&pass_filter, &active_filter); #endif +#if CCP_SUPPORT || ECP_SUPPORT /* Start CCP and ECP */ for (i = 0; (protp = protocols[i]) != NULL; ++i) - if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP) + if ( + (0 +#if ECP_SUPPORT + || protp->protocol == PPP_ECP +#endif /* ECP_SUPPORT */ +#if CCP_SUPPORT + || protp->protocol == PPP_CCP +#endif /* CCP_SUPPORT */ + ) && protp->enabled_flag && protp->open != NULL) (*protp->open)(0); +#endif /* CCP_SUPPORT || ECP_SUPPORT */ /* * Bring up other network protocols iff encryption is not required. */ +#if ECP_SUPPORT ecp_required = ecp_gotoptions[unit].required; +#endif /* ECP_SUPPORT */ +#ifdef MPPE mppe_required = ccp_gotoptions[unit].mppe; - if (!ecp_required && !mppe_required) +#endif /* MPPE */ + + if (1 +#if ECP_SUPPORT + && !ecp_required +#endif /* ECP_SUPPORT */ +#ifdef MPPE + && !mppe_required +#endif /* MPPE */ + ) continue_networks(unit); } @@ -1166,11 +1193,13 @@ np_up(unit, proto) TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); #endif +#if 0 /* Unused */ /* * Detach now, if the updetach option was given. */ if (updetach && !nodetach) detach(); +#endif /* Unused */ } ++num_np_up; } diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index d1c7c9a8..6c6ce7a2 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -29,6 +29,7 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #define RCSID "$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $" @@ -1682,3 +1683,4 @@ ccp_rack_timeout(arg) ccp_localstate[f->unit] &= ~RACK_PENDING; } +#endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/src/netif/ppp/ccp.h b/src/netif/ppp/ccp.h index 6f4a2fee..b5dee384 100644 --- a/src/netif/ppp/ccp.h +++ b/src/netif/ppp/ccp.h @@ -30,6 +30,9 @@ * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + typedef struct ccp_options { bool bsd_compress; /* do BSD Compress? */ bool deflate; /* do Deflate? */ @@ -50,3 +53,5 @@ extern ccp_options ccp_allowoptions[]; extern ccp_options ccp_hisoptions[]; extern struct protent ccp_protent; + +#endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index 7016c5a6..570846d3 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -115,8 +115,12 @@ demand_conf() */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) + ((*protp->demand_conf)(0)); +/* FIXME: find a way to die() here */ +#if 0 if (!((*protp->demand_conf)(0))) die(1); +#endif } diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index e5fbd1d5..3c02e091 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -58,6 +58,7 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $" @@ -177,3 +178,4 @@ ecp_printpkt(p, plen, printer, arg) return 0; } +#endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/src/netif/ppp/ecp.h b/src/netif/ppp/ecp.h index df6e3ca1..d6887758 100644 --- a/src/netif/ppp/ecp.h +++ b/src/netif/ppp/ecp.h @@ -31,6 +31,9 @@ * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + typedef struct ecp_options { bool required; /* Is ECP required? */ unsigned enctype; /* Encryption type */ @@ -43,3 +46,5 @@ extern ecp_options ecp_allowoptions[]; extern ecp_options ecp_hisoptions[]; extern struct protent ecp_protent; + +#endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 5045287f..ff0cdd8d 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -118,7 +118,7 @@ int req_unit = -1; /* requested interface unit */ bool multilink = 0; /* Enable multilink operation */ char *bundle_name = NULL; /* bundle name for multilink */ bool dump_options; /* print out option values */ -bool dryrun; /* print out option values and exit */ +//bool dryrun; /* print out option values and exit */ char *domain; /* domain name set by domain option */ int child_wait = 5; /* # seconds to wait for children at exit */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 45e333a6..0dcd9acd 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -228,10 +228,10 @@ static struct subprocess *children; /* Prototypes for procedures local to this file. */ -static void setup_signals __P((void)); +//static void setup_signals __P((void)); static void create_pidfile __P((int pid)); static void create_linkpidfile __P((int pid)); -static void cleanup __P((void)); +//static void cleanup __P((void)); static void get_input __P((void)); static void calltimeout __P((void)); static struct timeval *timeleft __P((struct timeval *)); @@ -283,8 +283,12 @@ struct protent *protocols[] = { #ifdef INET6 &ipv6cp_protent, #endif +#if CCP_SUPPORT &ccp_protent, +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT &ecp_protent, +#endif /* ECP_SUPPORT */ #ifdef AT_CHANGE &atcp_protent, #endif @@ -301,6 +305,7 @@ struct protent *protocols[] = { #define PPP_DRV_NAME "ppp" #endif /* !defined(PPP_DRV_NAME) */ +#if 0 int ppp_oldmain() { int argc = 0; char *argv[0]; @@ -348,10 +353,12 @@ int ppp_oldmain() { for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(0); +#if 0 /* * Initialize the default channel. */ tty_init(); +#endif progname = *argv; @@ -416,8 +423,10 @@ int ppp_oldmain() { } #endif /* PPP_OPTIONS */ +#if 0 if (dryrun) die(0); +#endif /* Make sure fds 0, 1, 2 are open to somewhere. */ fd_devnull = open(_PATH_DEVNULL, O_RDWR); @@ -430,12 +439,15 @@ int ppp_oldmain() { fd_devnull = i; } +#if 0 /* Unused */ /* * Detach ourselves from the terminal, if required, * and identify who is running us. */ if (!nodetach && !updetach) detach(); +#endif /* Unused */ + p = getlogin(); if (p == NULL) { pw = getpwuid(uid); @@ -452,7 +464,7 @@ int ppp_oldmain() { slprintf(numbuf, sizeof(numbuf), "%d", getpid()); script_setenv("PPPD_PID", numbuf, 1); - setup_signals(); + //setup_signals(); create_linkpidfile(getpid()); @@ -465,8 +477,8 @@ int ppp_oldmain() { /* * Open the loopback channel and set it up to be the ppp interface. */ - fd_loop = open_ppp_loopback(); - set_ifunit(1); + //fd_loop = open_ppp_loopback(); + //set_ifunit(1); /* * Configure the interface and mark it up, etc. */ @@ -580,7 +592,9 @@ int ppp_oldmain() { die(status); return 0; } +#endif +#if 0 /* * handle_events - wait for something to happen and respond to it. */ @@ -626,7 +640,9 @@ handle_events() got_sigusr2 = 0; } } +#endif +#if 0 /* * setup_signals - initialize signal handling. */ @@ -709,6 +725,7 @@ setup_signals() */ signal(SIGPIPE, SIG_IGN); } +#endif /* * set_ifunit - do things we need to do once we know which ppp @@ -727,6 +744,7 @@ set_ifunit(iskey) } } +#if 0 /* * detach - detach us from the controlling terminal. */ @@ -771,6 +789,7 @@ detach() complete_read(pipefd[0], numbuf, 1); close(pipefd[0]); } +#endif /* * reopen_log - (re)open our connection to syslog. @@ -1147,6 +1166,7 @@ new_phase(p) notify(phasechange, p); } +#if 0 /* * die - clean up state and exit with the specified status. */ @@ -1161,7 +1181,9 @@ die(status) syslog(LOG_INFO, "Exit."); exit(status); } +#endif +#if 0 /* * cleanup - restore anything which needs to be restored before we exit */ @@ -1177,6 +1199,7 @@ cleanup() (*the_channel->cleanup)(); remove_pidfiles(); } +#endif void print_link_stats() @@ -1200,8 +1223,10 @@ void reset_link_stats(u) int u; { +#if 0 if (!get_ppp_stats(u, &old_link_stats)) return; +#endif gettimeofday(&start_time, NULL); } @@ -1215,9 +1240,11 @@ update_link_stats(u) struct timeval now; char numbuf[32]; +#if 0 if (!get_ppp_stats(u, &link_stats) || gettimeofday(&now, NULL) < 0) return; +#endif link_connect_time = now.tv_sec - start_time.tv_sec; link_stats_valid = 1; @@ -1492,7 +1519,7 @@ open_ccp(sig) siglongjmp(sigjmp, 1); } - +#if 0 /* * bad_signal - We've caught a fatal signal. Clean up state and exit. */ @@ -1511,7 +1538,9 @@ bad_signal(sig) notify(sigreceived, sig); die(127); } +#endif +#if 0 /* * safe_fork - Create a child process. The child closes all the * file descriptors that we don't want to leak to a script. @@ -1593,6 +1622,7 @@ safe_fork(int infd, int outfd, int errfd) return 0; } +#endif /* * device_script - run a program to talk to the specified fds @@ -1615,7 +1645,8 @@ device_script(program, in, out, dont_wait) errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); ++conn_running; - pid = safe_fork(in, out, errfd); + //pid = safe_fork(in, out, errfd); + pid = -1; if (pid != 0 && log_to_fd < 0) close(errfd); diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 39765e7a..297c64ef 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -487,7 +487,11 @@ extern struct channel *the_channel; /* Procedures exported from main.c. */ void set_ifunit __P((int)); /* set stuff that depends on ifunit */ + +#if 0 void detach __P((void)); /* Detach from controlling tty */ +#endif + void die __P((int)); /* Cleanup and exit */ void quit __P((void)); /* like die(1) */ void novm __P((char *)); /* Say we ran out of memory, and die */ @@ -496,7 +500,11 @@ void timeout __P((void (*func)(void *), void *arg, int s, int us)); void untimeout __P((void (*func)(void *), void *arg)); /* Cancel call to func(arg) */ void record_child __P((int, char *, void (*) (void *), void *, int)); + +#if 0 pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ +#endif + int device_script __P((char *cmd, int in, int out, int dont_wait)); /* Run `cmd' with given stdin and stdout */ void reopen_log __P((void)); /* (re)open the connection to syslog */ @@ -539,8 +547,11 @@ void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ void end_pr_log __P((void)); /* finish up after using pr_log */ void dump_packet __P((const char *, u_char *, int)); /* dump packet to debug log if interesting */ + +#if 0 /* Unused */ ssize_t complete_read __P((int, void *, size_t)); /* read a complete buffer */ +#endif /* Unused */ /* Procedures exported from auth.c */ void link_required __P((int)); /* we are starting to use the link */ @@ -668,9 +679,11 @@ int sifproxyarp __P((int, u_int32_t)); int cifproxyarp __P((int, u_int32_t)); /* Delete proxy ARP entry for peer */ u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ +#if 0 /* Unused */ int lock __P((char *)); /* Create lock file for device */ int relock __P((int)); /* Rewrite lock file with new pid */ void unlock __P((void)); /* Delete previously-created lock file */ +#endif /* Unused */ void logwtmp __P((const char *, const char *, const char *)); /* Write entry to wtmp file */ int get_host_seed __P((void)); /* Get host-dependent random number seed */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 4c34dbbd..af1329ad 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -1093,6 +1093,27 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, return st; } +/******************************************************************** + * + * cifaddr - Clear the interface IP addresses, and delete routes + * through the interface if possible. + */ +int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { + /* FIXME: do the code which clear a IP on a PPP interface */ + return 0; +} + + +/******************************************************************** + * + * sifdown - Disable the indicated protocol and config the interface + * down if there are no remaining protocols. + */ +int sifdown (int u) { + /* FIXME: do the code which shutdown a PPP interface */ + return 1; +} + /* * pppifNetifInit - netif init callback */ @@ -1156,3 +1177,102 @@ sifnpmode(int u, int proto, enum NPmode mode) return 0; } +/* + * netif_set_mtu - set the MTU on the PPP network interface. + */ +void netif_set_mtu(int unit, int mtu) { + /* FIXME: set lwIP MTU */ +} + +/******************************************************************** + * + * sifdefaultroute - assign a default route through the address given. + * + * If the global default_rt_repl_rest flag is set, then this function + * already replaced the original system defaultroute with some other + * route and it should just replace the current defaultroute with + * another one, without saving the current route. Use: demand mode, + * when pppd sets first a defaultroute it it's temporary ppp0 addresses + * and then changes the temporary addresses to the addresses for the real + * ppp connection when it has come up. + */ + +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { + /* FIXME: do the code which add the default route */ + return 0; +} + +/******************************************************************** + * + * cifdefaultroute - delete a default route through the address given. + */ + +int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { + /* FIXME: do the code which remove the default route */ + return 0; +} + +/******************************************************************** + * + * sifproxyarp - Make a proxy ARP entry for the peer. + */ + +int sifproxyarp (int unit, u_int32_t his_adr) { + /* FIXME: do we really need that in IPCP ? */ + return 0; +} + +/******************************************************************** + * + * cifproxyarp - Delete the proxy ARP entry for the peer. + */ + +int cifproxyarp (int unit, u_int32_t his_adr) { + /* FIXME: do we really need that in IPCP ? */ + return 0; +} + +/******************************************************************** + * + * sifvjcomp - config tcp header compression + */ +int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) { + /* FIXME: add VJ support */ + return 1; +} + +/******************************************************************** + * + * get_idle_time - return how long the link has been idle. + */ +int get_idle_time(int u, struct ppp_idle *ip) { + /* FIXME: add idle time support */ + return 1; +} + + +/******************************************************************** + * + * get_loop_output - get outgoing packets from the ppp device, + * 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) { + /* FIXME: necessary for "demand", do we really need to support on-demand ? */ + 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. + */ + +u_int32_t GetMask (u_int32_t addr) { + /* FIXME: do we really need that in IPCP ? */ + return 0; +} diff --git a/src/netif/ppp/sys-linux.c b/src/netif/ppp/sys-linux.c index c3f1d172..188b172c 100644 --- a/src/netif/ppp/sys-linux.c +++ b/src/netif/ppp/sys-linux.c @@ -69,7 +69,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "lwip/opt.h" +#if 0 /* BAH */ #include #include @@ -2694,3 +2694,5 @@ ether_to_eui64(eui64_t *p_eui64) return 1; } #endif + +#endif /* BAH */ diff --git a/src/netif/ppp/tty.c b/src/netif/ppp/tty.c index a9e52030..5008f4b0 100644 --- a/src/netif/ppp/tty.c +++ b/src/netif/ppp/tty.c @@ -68,7 +68,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "lwip/opt.h" +#if 0 /* NEED OUR OWN PORT */ #define RCSID "$Id: tty.c,v 1.27 2008/07/01 12:27:56 paulus Exp $" @@ -123,7 +123,10 @@ static void charshunt __P((int, int, char *)); static int record_write __P((FILE *, int code, u_char *buf, int nb, struct timeval *)); static int open_socket __P((char *)); + +#if 0 static void maybe_relock __P((void *, int)); +#endif static int pty_master; /* fd for master side of pty */ static int pty_slave; /* fd for slave side of pty */ @@ -407,6 +410,7 @@ printescape(opt, printer, arg) } #endif /* UNUSED */ +#if 0 /* * tty_init - do various tty-related initializations. */ @@ -416,6 +420,7 @@ void tty_init() the_channel = &tty_channel; xmit_accm[3] = 0x60000000; } +#endif /* * tty_process_extra_options - work out which tty device we are using @@ -815,10 +820,12 @@ void cleanup_tty() if (real_ttyfd >= 0) finish_tty(); tty_close_fds(); +#if 0 if (locked) { unlock(); locked = 0; } +#endif } /* @@ -864,6 +871,7 @@ finish_tty() real_ttyfd = -1; } +#if 0 /* * maybe_relock - our PID has changed, maybe update the lock file. */ @@ -875,6 +883,7 @@ maybe_relock(arg, pid) if (locked) relock(pid); } +#endif /* * open_socket - establish a stream socket connection to the nominated @@ -940,7 +949,7 @@ start_charshunt(ifd, ofd) { int cpid; - cpid = safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2)); + cpid = -1; // safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2)); if (cpid == -1) { error("Can't fork process for character shunt: %m"); return 0; @@ -1276,3 +1285,5 @@ record_write(f, code, buf, nb, tp) } return 1; } + +#endif /* NEED OUR OWN PORT */ diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 9df19db1..885f3bd7 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -698,7 +698,10 @@ fatal __V((char *fmt, ...)) logit(LOG_ERR, fmt, pvar); va_end(pvar); +/* FIXME: find a way to die */ +#if 0 die(1); /* as promised */ +#endif } /* @@ -832,6 +835,8 @@ dump_packet(const char *tag, unsigned char *p, int len) dbglog("%s %P", tag, p, len); } +#if 0 /* Unused */ + /* * complete_read - read a full `count' bytes from fd, * unless end-of-file or an error other than EINTR is encountered. @@ -1054,3 +1059,4 @@ unlock() } } +#endif /* Unused */ From ee5fca7a2bd824112485e0229c74478afa24f07a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 00:33:37 +0200 Subject: [PATCH 056/320] removed pathnames.h and pidfile support --- src/netif/ppp/auth.c | 4 --- src/netif/ppp/eap.c | 1 - src/netif/ppp/ipcp.c | 1 - src/netif/ppp/options.c | 1 - src/netif/ppp/pathnames.h | 63 --------------------------------------- src/netif/ppp/ppp.c | 20 ++++++++----- src/netif/ppp/pppd.h | 4 +-- 7 files changed, 14 insertions(+), 80 deletions(-) delete mode 100644 src/netif/ppp/pathnames.h diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index d0b7e2cb..c067545a 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -120,10 +120,6 @@ #include "cbcp.h" #endif -#if 0 /* UNUSED */ -#include "pathnames.h" -#endif /* UNUSED */ - #include "session.h" #if 0 /* UNUSED */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 19d5b93a..bac849d0 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -47,7 +47,6 @@ #if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include "pppd.h" -#include "pathnames.h" #include "polarssl/md5.h" #include "eap.h" diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index d94a8e00..4c353730 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -61,7 +61,6 @@ #include "pppd.h" #include "fsm.h" #include "ipcp.h" -#include "pathnames.h" static const char rcsid[] = RCSID; diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index ff0cdd8d..6aebbf3d 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -75,7 +75,6 @@ #endif /* PPP_FILTER */ #include "pppd.h" -#include "pathnames.h" #if defined(ultrix) || defined(NeXT) char *strdup __P((char *)); diff --git a/src/netif/ppp/pathnames.h b/src/netif/ppp/pathnames.h deleted file mode 100644 index bc81a8ce..00000000 --- a/src/netif/ppp/pathnames.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * define path names - * - * $Id: pathnames.h,v 1.18 2005/08/25 23:59:34 paulus Exp $ - */ - -#ifdef HAVE_PATHS_H -#include - -#else /* HAVE_PATHS_H */ -#ifndef _PATH_VARRUN -#define _PATH_VARRUN "/etc/ppp/" -#endif -#define _PATH_DEVNULL "/dev/null" -#endif /* HAVE_PATHS_H */ - -#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_SRPFILE _ROOT_PATH "/etc/ppp/srp-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_IPPREUP _ROOT_PATH "/etc/ppp/ip-pre-up" -#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" -#define _PATH_PSEUDONYM ".ppp_pseudonym" - -#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 */ - -#ifdef __STDC__ -#define _PATH_PPPDB _ROOT_PATH _PATH_VARRUN "pppd2.tdb" -#else /* __STDC__ */ -#ifdef HAVE_PATHS_H -#define _PATH_PPPDB "/var/run/pppd2.tdb" -#else -#define _PATH_PPPDB "/etc/ppp/pppd2.tdb" -#endif -#endif /* __STDC__ */ - -#ifdef PLUGIN -#ifdef __STDC__ -#define _PATH_PLUGIN DESTDIR "/lib/pppd/" VERSION -#else /* __STDC__ */ -#define _PATH_PLUGIN "/usr/lib/pppd" -#endif /* __STDC__ */ - -#endif /* PLUGIN */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0dcd9acd..c33922da 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -113,7 +113,6 @@ #endif /* EAP_SUPPORT */ #include "ccp.h" #include "ecp.h" -#include "pathnames.h" #if CBCP_SUPPORT #include "cbcp.h" @@ -133,8 +132,8 @@ struct channel *the_channel; char *progname; /* Name of this program */ char hostname[MAXNAMELEN]; /* Our hostname */ -static char pidfilename[MAXPATHLEN]; /* name of pid file */ -static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ +//static char pidfilename[MAXPATHLEN]; /* name of pid file */ +//static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ uid_t uid; /* Our real user-id */ struct notifier *pidchange = NULL; @@ -229,8 +228,8 @@ static struct subprocess *children; /* Prototypes for procedures local to this file. */ //static void setup_signals __P((void)); -static void create_pidfile __P((int pid)); -static void create_linkpidfile __P((int pid)); +//static void create_pidfile __P((int pid)); +//static void create_linkpidfile __P((int pid)); //static void cleanup __P((void)); static void get_input __P((void)); static void calltimeout __P((void)); @@ -739,8 +738,8 @@ set_ifunit(iskey) slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); script_setenv("IFNAME", ifname, iskey); if (iskey) { - create_pidfile(getpid()); /* write pid to file */ - create_linkpidfile(getpid()); +// create_pidfile(getpid()); /* write pid to file */ +// create_linkpidfile(getpid()); } } @@ -801,6 +800,7 @@ reopen_log() setlogmask(LOG_UPTO(LOG_INFO)); } +#if 0 /* * Create a file containing our process ID. */ @@ -820,7 +820,9 @@ create_pidfile(pid) pidfilename[0] = 0; } } +#endif +#if 0 void create_linkpidfile(pid) int pid; @@ -855,6 +857,7 @@ void remove_pidfiles() warn("unable to delete pid file %s: %m", linkpidfile); linkpidfile[0] = 0; } +#endif /* * holdoff_end - called via a timeout when the holdoff period ends. @@ -1624,6 +1627,7 @@ safe_fork(int infd, int outfd, int errfd) } #endif +#if 0 /* * device_script - run a program to talk to the specified fds * (e.g. to run the connector or disconnector script). @@ -1685,7 +1689,7 @@ device_script(program, in, out, dont_wait) exit(99); /* NOTREACHED */ } - +#endif /* * record_child - add a child process to the list for reap_kids diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 297c64ef..cdf4403c 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -505,7 +505,7 @@ void record_child __P((int, char *, void (*) (void *), void *, int)); pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ #endif -int device_script __P((char *cmd, int in, int out, int dont_wait)); +//int device_script __P((char *cmd, int in, int out, int dont_wait)); /* Run `cmd' with given stdin and stdout */ void reopen_log __P((void)); /* (re)open the connection to syslog */ void print_link_stats __P((void)); /* Print stats, if available */ @@ -520,7 +520,7 @@ void notify __P((struct notifier *, int)); int ppp_send_config __P((int, int, u_int32_t, int, int)); int ppp_recv_config __P((int, int, u_int32_t, int, int)); const char *protocol_name __P((int)); -void remove_pidfiles __P((void)); +//void remove_pidfiles __P((void)); void lock_db __P((void)); void unlock_db __P((void)); From 8b866beaebbc3b7db6955def09fc70f9adefe799 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 00:53:25 +0200 Subject: [PATCH 057/320] demand support is now a compile-time option Obviously, it requires some wiring to know if there is new activity on a not-yet established PPP interface with the default route already set. I don't think any lwIP user will ever need that, all should know when to bring the link up and down. --- src/netif/ppp/ccp.c | 2 ++ src/netif/ppp/chap-new.c | 2 ++ src/netif/ppp/demand.c | 5 +++-- src/netif/ppp/eap.c | 2 ++ src/netif/ppp/ecp.c | 2 ++ src/netif/ppp/ipcp.c | 19 ++++++++++++++++--- src/netif/ppp/lcp.c | 2 ++ src/netif/ppp/options.c | 2 ++ src/netif/ppp/pppd.h | 2 ++ src/netif/ppp/upap.c | 2 ++ 10 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 6c6ce7a2..3cc8d8f3 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -199,8 +199,10 @@ struct protent ccp_protent = { ccp_option_list, NULL, #endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT NULL, NULL +#endif /* DEMAND_SUPPORT */ }; fsm ccp_fsm[NUM_PPP]; diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 34a45898..a517b23d 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -669,8 +669,10 @@ struct protent chap_protent = { chap_option_list, NULL, /* check_options */ #endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT NULL, NULL +#endif /* DEMAND_SUPPORT */ }; #endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index 570846d3..4e922cde 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -29,8 +29,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: demand.c,v 1.20 2005/08/25 12:14:18 paulus Exp $" +#if PPP_SUPPORT && DEMAND_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include #include @@ -466,3 +465,5 @@ active_packet(p, len) } return 0; /* not a supported protocol !!?? */ } + +#endif /* PPP_SUPPORT && DEMAND_SUPPORT */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index bac849d0..b08f6c68 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -122,8 +122,10 @@ struct protent eap_protent = { eap_option_list, /* list of command-line options */ NULL, /* check requested options; assign defaults */ #endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT NULL, /* configure interface for demand-dial */ NULL /* say whether to bring up link for this pkt */ +#endif /* DEMAND_SUPPORT */ }; #ifdef USE_SRP diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index 3c02e091..ef20e791 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -118,8 +118,10 @@ struct protent ecp_protent = { ecp_option_list, NULL, #endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT NULL, NULL +#endif /* DEMAND_SUPPORT */ }; fsm ecp_fsm[NUM_PPP]; diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 4c353730..646f52ac 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -259,8 +259,10 @@ static void ipcp_protrej __P((int)); static int ipcp_printpkt __P((u_char *, int, void (*) __P((void *, char *, ...)), void *)); static void ip_check_options __P((void)); +#if DEMAND_SUPPORT static int ip_demand_conf __P((int)); static int ip_active_pkt __P((u_char *, int)); +#endif /* DEMAND_SUPPORT */ static void create_resolv __P((u_int32_t, u_int32_t)); struct protent ipcp_protent = { @@ -281,8 +283,10 @@ struct protent ipcp_protent = { ipcp_option_list, ip_check_options, #endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT ip_demand_conf, ip_active_pkt +#endif /* DEMAND_SUPPORT */ }; static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool)); @@ -1724,6 +1728,7 @@ ip_check_options() } #endif /* UNUSED */ +#if DEMAND_SUPPORT /* * ip_demand_conf - configure the interface as though * IPCP were up, for use with dial-on-demand. @@ -1765,7 +1770,7 @@ ip_demand_conf(u) return 1; } - +#endif /* DEMAND_SUPPORT */ /* * ipcp_up - IPCP has come UP. @@ -1837,6 +1842,7 @@ ipcp_up(f) /* set tcp compression */ sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); +#if DEMAND_SUPPORT /* * If we are doing dial-on-demand, the interface is already * configured, so we put out any saved-up packets, then set the @@ -1883,7 +1889,9 @@ ipcp_up(f) demand_rexmit(PPP_IP,go->ouraddr); sifnpmode(f->unit, PPP_IP, NPMODE_PASS); - } else { + } else +#endif /* DEMAND_SUPPORT */ + { /* * Set IP addresses and (if specified) netmask. */ @@ -1978,13 +1986,16 @@ ipcp_down(f) * because print_link_stats() sets link_stats_valid * to 0 (zero) */ +#if DEMAND_SUPPORT /* * 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 { + } else +#endif /* DEMAND_SUPPORT */ + { sifnpmode(f->unit, PPP_IP, NPMODE_DROP); sifdown(f->unit); ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, @@ -2188,6 +2199,7 @@ ipcp_printpkt(p, plen, printer, arg) #define TCP_HDRLEN 20 #define TH_FIN 0x01 +#if DEMAND_SUPPORT /* * 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. @@ -2224,3 +2236,4 @@ ip_active_pkt(pkt, len) return 0; return 1; } +#endif /* DEMAND_SUPPORT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index a1a054e4..cc83f528 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -285,8 +285,10 @@ struct protent lcp_protent = { lcp_option_list, NULL, #endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT NULL, NULL +#endif /* DEMAND_SUPPORT */ }; int lcp_loopbackfail = DEFLOOPBACKFAIL; diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 6aebbf3d..62ba3b63 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -102,7 +102,9 @@ int maxconnect = 0; /* Maximum connect time */ //char passwd[MAXSECRETLEN]; /* Password for PAP */ bool persist = 0; /* Reopen link after it goes down */ char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ +#if DEMAND_SUPPORT bool demand = 0; /* do dial-on-demand */ +#endif /* DEMAND_SUPPORT */ 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 */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index cdf4403c..3f30d29c 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -436,10 +436,12 @@ struct protent { /* Check requested options, assign defaults */ void (*check_options) __P((void)); #endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT /* Configure interface for demand-dial */ int (*demand_conf) __P((int unit)); /* Say whether to bring up link for this pkt */ int (*active_pkt) __P((u_char *pkt, int len)); +#endif /* DEMAND_SUPPORT */ }; /* Table of pointers to supported protocols */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index fb268b60..e989a430 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -105,8 +105,10 @@ struct protent pap_protent = { pap_option_list, NULL, #endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT NULL, NULL +#endif /* DEMAND_SUPPORT */ }; upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ From cf18e0776db6e5a0c960a6cbece39aa2526d66ed Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 01:55:24 +0200 Subject: [PATCH 058/320] removed demand prototypes if not compiled-in --- src/netif/ppp/pppd.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 3f30d29c..8056c74b 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -591,6 +591,7 @@ int bad_ip_adrs __P((u_int32_t)); /* check if IP address is unreasonable */ /* Procedures exported from demand.c */ +#if DEMAND_SUPPORT void demand_conf __P((void)); /* config interface(s) for demand-dial */ void demand_block __P((void)); /* set all NPs to queue up packets */ void demand_unblock __P((void)); /* set all NPs to pass packets */ @@ -598,6 +599,7 @@ void demand_discard __P((void)); /* set all NPs to discard packets */ void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ +#endif /* DEMAND_SUPPORT */ /* Procedures exported from multilink.c */ #ifdef HAVE_MULTILINK From 2c4bd7162fb05af23242f44b64c9039b05d0e8b6 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 02:07:49 +0200 Subject: [PATCH 059/320] print packet functions are now optional --- src/netif/ppp/ccp.c | 6 ++++++ src/netif/ppp/chap-new.c | 6 ++++++ src/netif/ppp/eap.c | 7 +++++++ src/netif/ppp/ecp.c | 6 ++++++ src/netif/ppp/ipcp.c | 8 +++++++- src/netif/ppp/lcp.c | 6 ++++++ src/netif/ppp/pppd.h | 2 ++ src/netif/ppp/upap.c | 6 ++++++ src/netif/ppp/utils.c | 6 ++++++ 9 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 3cc8d8f3..6c3aa63a 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -176,9 +176,11 @@ static void ccp_lowerup __P((int unit)); static void ccp_lowerdown __P((int)); static void ccp_input __P((int unit, u_char *pkt, int len)); static void ccp_protrej __P((int unit)); +#if PRINTPKT_SUPPORT static int ccp_printpkt __P((u_char *pkt, int len, void (*printer) __P((void *, char *, ...)), void *arg)); +#endif /* PRINTPKT_SUPPORT */ static void ccp_datainput __P((int unit, u_char *pkt, int len)); struct protent ccp_protent = { @@ -190,7 +192,9 @@ struct protent ccp_protent = { ccp_lowerdown, ccp_open, ccp_close, +#if PRINTPKT_SUPPORT ccp_printpkt, +#endif /* PRINTPKT_SUPPORT */ ccp_datainput, 1, "CCP", @@ -1484,6 +1488,7 @@ ccp_down(f) #endif } +#if PRINTPKT_SUPPORT /* * Print the contents of a CCP packet. */ @@ -1614,6 +1619,7 @@ ccp_printpkt(p, plen, printer, arg) return p - p0; } +#endif /* PRINTPKT_SUPPORT */ /* * We have received a packet that the decompressor failed to diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index a517b23d..fbb73da4 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -135,8 +135,10 @@ static void chap_handle_status(struct chap_client_state *cs, int code, int id, unsigned char *pkt, int len); static void chap_protrej(int unit); static void chap_input(int unit, unsigned char *pkt, int pktlen); +#if PRINTPKT_SUPPORT static int chap_print_pkt(unsigned char *p, int plen, void (*printer) __P((void *, char *, ...)), void *arg); +#endif /* PRINTPKT_SUPPORT */ /* List of digest types that we know about */ static struct chap_digest_type *chap_digests; @@ -589,6 +591,7 @@ chap_protrej(int unit) } } +#if PRINTPKT_SUPPORT /* * chap_print_pkt - print the contents of a CHAP packet. */ @@ -650,6 +653,7 @@ chap_print_pkt(unsigned char *p, int plen, return len + CHAP_HDRLEN; } +#endif /* PRINTPKT_SUPPORT */ struct protent chap_protent = { PPP_CHAP, @@ -660,7 +664,9 @@ struct protent chap_protent = { chap_lowerdown, NULL, /* open */ NULL, /* close */ +#if PRINTPKT_SUPPORT chap_print_pkt, +#endif /* PRINTPKT_SUPPORT */ NULL, /* datainput */ 1, /* enabled_flag */ "CHAP", /* name */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index b08f6c68..06aac356 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -101,8 +101,10 @@ static void eap_input __P((int unit, u_char *inp, int inlen)); static void eap_protrej __P((int unit)); static void eap_lowerup __P((int unit)); static void eap_lowerdown __P((int unit)); +#if PRINTPKT_SUPPORT static int eap_printpkt __P((u_char *inp, int inlen, void (*)(void *arg, char *fmt, ...), void *arg)); +#endif /* PRINTPKT_SUPPORT */ struct protent eap_protent = { PPP_EAP, /* protocol number */ @@ -113,7 +115,9 @@ struct protent eap_protent = { eap_lowerdown, /* lower layer has gone down */ NULL, /* open the protocol */ NULL, /* close the protocol */ +#if PRINTPKT_SUPPORT eap_printpkt, /* print a packet in readable form */ +#endif /* PRINTPKT_SUPPORT */ NULL, /* process a received data packet */ 1, /* protocol enabled */ "EAP", /* text name of protocol */ @@ -2122,6 +2126,7 @@ int inlen; } } +#if PRINTPKT_SUPPORT /* * eap_printpkt - print the contents of an EAP packet. */ @@ -2423,4 +2428,6 @@ void *arg; return (inp - pstart); } +#endif /* PRINTPKT_SUPPORT */ + #endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index ef20e791..a8c7ce67 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -93,9 +93,11 @@ static void ecp_lowerdown __P((int)); static void ecp_input __P((int unit, u_char *pkt, int len)); static void ecp_protrej __P((int unit)); */ +#if PRINTPKT_SUPPORT static int ecp_printpkt __P((u_char *pkt, int len, void (*printer) __P((void *, char *, ...)), void *arg)); +#endif /* PRINTPKT_SUPPORT */ /* static void ecp_datainput __P((int unit, u_char *pkt, int len)); */ @@ -109,7 +111,9 @@ struct protent ecp_protent = { NULL, /* ecp_lowerdown, */ NULL, /* ecp_open, */ NULL, /* ecp_close, */ +#if PRINTPKT_SUPPORT ecp_printpkt, +#endif /* PRINTPKT_SUPPORT */ NULL, /* ecp_datainput, */ 0, "ECP", @@ -170,6 +174,7 @@ ecp_init(unit) } +#if PRINTPKT_SUPPORT static int ecp_printpkt(p, plen, printer, arg) u_char *p; @@ -179,5 +184,6 @@ ecp_printpkt(p, plen, printer, arg) { return 0; } +#endif /* PRINTPKT_SUPPORT */ #endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 646f52ac..40343ab0 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -256,8 +256,10 @@ static void ipcp_lowerup __P((int)); static void ipcp_lowerdown __P((int)); static void ipcp_input __P((int, u_char *, int)); static void ipcp_protrej __P((int)); +#if PRINTPKT_SUPPORT static int ipcp_printpkt __P((u_char *, int, void (*) __P((void *, char *, ...)), void *)); +#endif /* PRINTPKT_SUPPORT */ static void ip_check_options __P((void)); #if DEMAND_SUPPORT static int ip_demand_conf __P((int)); @@ -274,7 +276,9 @@ struct protent ipcp_protent = { ipcp_lowerdown, ipcp_open, ipcp_close, +#if PRINTPKT_SUPPORT ipcp_printpkt, +#endif /* PRINTPKT_SUPPORT */ NULL, 1, "IPCP", @@ -2059,6 +2063,7 @@ create_resolv(peerdns1, peerdns2) /* FIXME: do we need to set here the DNS servers ? */ } +#if PRINTPKT_SUPPORT /* * ipcp_printpkt - print the contents of an IPCP packet. */ @@ -2185,7 +2190,9 @@ ipcp_printpkt(p, plen, printer, arg) return p - pstart; } +#endif /* PRINTPKT_SUPPORT */ +#if DEMAND_SUPPORT /* * 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 @@ -2199,7 +2206,6 @@ ipcp_printpkt(p, plen, printer, arg) #define TCP_HDRLEN 20 #define TH_FIN 0x01 -#if DEMAND_SUPPORT /* * 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. diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index cc83f528..4f8f17cb 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -264,8 +264,10 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ static void lcp_init __P((int)); static void lcp_input __P((int, u_char *, int)); static void lcp_protrej __P((int)); +#if PRINTPKT_SUPPORT static int lcp_printpkt __P((u_char *, int, void (*) __P((void *, char *, ...)), void *)); +#endif /* PRINTPKT_SUPPORT */ struct protent lcp_protent = { PPP_LCP, @@ -276,7 +278,9 @@ struct protent lcp_protent = { lcp_lowerdown, lcp_open, lcp_close, +#if PRINTPKT_SUPPORT lcp_printpkt, +#endif /* PRINTPKT_SUPPORT */ NULL, 1, "LCP", @@ -2249,6 +2253,7 @@ lcp_finished(f) } +#if PRINTPKT_SUPPORT /* * lcp_printpkt - print the contents of an LCP packet. */ @@ -2503,6 +2508,7 @@ lcp_printpkt(p, plen, printer, arg) return p - pstart; } +#endif /* PRINTPKT_SUPPORT */ /* * Time to shut down the link because there is nothing out there. diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 8056c74b..6bf117d4 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -422,10 +422,12 @@ struct protent { void (*open) __P((int unit)); /* Close the protocol */ void (*close) __P((int unit, char *reason)); +#if PRINTPKT_SUPPORT /* Print a packet in readable form */ int (*printpkt) __P((u_char *pkt, int len, void (*printer) __P((void *, char *, ...)), void *arg)); +#endif /* PRINTPKT_SUPPORT */ /* Process a received data packet */ void (*datainput) __P((int unit, u_char *pkt, int len)); bool enabled_flag; /* 0 iff protocol is disabled */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index e989a430..239eae11 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -84,8 +84,10 @@ static void upap_lowerup __P((int)); static void upap_lowerdown __P((int)); static void upap_input __P((int, u_char *, int)); static void upap_protrej __P((int)); +#if PRINTPKT_SUPPORT static int upap_printpkt __P((u_char *, int, void (*) __P((void *, char *, ...)), void *)); +#endif /* PRINTPKT_SUPPORT */ struct protent pap_protent = { PPP_PAP, @@ -96,7 +98,9 @@ struct protent pap_protent = { upap_lowerdown, NULL, NULL, +#if PRINTPKT_SUPPORT upap_printpkt, +#endif /* PRINTPKT_SUPPORT */ NULL, 1, "PAP", @@ -612,6 +616,7 @@ upap_sresp(u, code, id, msg, msglen) output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } +#if PRINTPKT_SUPPORT /* * upap_printpkt - print the contents of a PAP packet. */ @@ -691,5 +696,6 @@ upap_printpkt(p, plen, printer, arg) return p - pstart; } +#endif /* PRINTPKT_SUPPORT */ #endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 885f3bd7..21fb4e5b 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -70,8 +70,10 @@ extern char *strerror(); static void logit __P((int, char *, va_list)); static void log_write __P((int, char *)); static void vslp_printer __P((void *, char *, ...)); +#if PRINTPKT_SUPPORT static void format_packet __P((u_char *, int, void (*) (void *, char *, ...), void *)); +#endif /* PRINTPKT_SUPPORT */ struct buffer_info { char *ptr; @@ -354,6 +356,7 @@ vslprintf(buf, buflen, fmt, args) OUTCHAR(c); } continue; +#if PRINTPKT_SUPPORT case 'P': /* print PPP packet */ bufinfo.ptr = buf; bufinfo.len = buflen + 1; @@ -363,6 +366,7 @@ vslprintf(buf, buflen, fmt, args) buf = bufinfo.ptr; buflen = bufinfo.len - 1; continue; +#endif /* PRINTPKT_SUPPORT */ case 'B': p = va_arg(args, unsigned char *); for (n = prec; n > 0; --n) { @@ -469,6 +473,7 @@ log_packet(p, len, prefix, level) } #endif /* unused */ +#if PRINTPKT_SUPPORT /* * format_packet - make a readable representation of a packet, * calling `printer(arg, format, ...)' to output it. @@ -518,6 +523,7 @@ format_packet(p, len, printer, arg) else printer(arg, "%.*B", len, p); } +#endif /* PRINTPKT_SUPPORT */ /* * init_pr_log, end_pr_log - initialize and finish use of pr_log. From 6c908ac7278715ef13145974623717d0ac39b98c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 02:14:19 +0200 Subject: [PATCH 060/320] removed more protent fields only used by print packets functions --- src/netif/ppp/ccp.c | 2 ++ src/netif/ppp/chap-new.c | 2 ++ src/netif/ppp/eap.c | 2 ++ src/netif/ppp/ecp.c | 2 ++ src/netif/ppp/ipcp.c | 2 ++ src/netif/ppp/lcp.c | 2 ++ src/netif/ppp/pppd.h | 2 ++ src/netif/ppp/upap.c | 2 ++ 8 files changed, 16 insertions(+) diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 6c3aa63a..7bd65192 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -197,8 +197,10 @@ struct protent ccp_protent = { #endif /* PRINTPKT_SUPPORT */ ccp_datainput, 1, +#if PRINTPKT_SUPPORT "CCP", "Compressed", +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS ccp_option_list, NULL, diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index fbb73da4..bb20d18b 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -669,8 +669,10 @@ struct protent chap_protent = { #endif /* PRINTPKT_SUPPORT */ NULL, /* datainput */ 1, /* enabled_flag */ +#if PRINTPKT_SUPPORT "CHAP", /* name */ NULL, /* data_name */ +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS chap_option_list, NULL, /* check_options */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 06aac356..e1542e4d 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -120,8 +120,10 @@ struct protent eap_protent = { #endif /* PRINTPKT_SUPPORT */ NULL, /* process a received data packet */ 1, /* protocol enabled */ +#if PRINTPKT_SUPPORT "EAP", /* text name of protocol */ NULL, /* text name of corresponding data protocol */ +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS eap_option_list, /* list of command-line options */ NULL, /* check requested options; assign defaults */ diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index a8c7ce67..9b2fdabc 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -116,8 +116,10 @@ struct protent ecp_protent = { #endif /* PRINTPKT_SUPPORT */ NULL, /* ecp_datainput, */ 0, +#if PRINTPKT_SUPPORT "ECP", "Encrypted", +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS ecp_option_list, NULL, diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 40343ab0..1fb9652b 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -281,8 +281,10 @@ struct protent ipcp_protent = { #endif /* PRINTPKT_SUPPORT */ NULL, 1, +#if PRINTPKT_SUPPORT "IPCP", "IP", +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS ipcp_option_list, ip_check_options, diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 4f8f17cb..0768efdc 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -283,8 +283,10 @@ struct protent lcp_protent = { #endif /* PRINTPKT_SUPPORT */ NULL, 1, +#if PRINTPKT_SUPPORT "LCP", NULL, +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS lcp_option_list, NULL, diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 6bf117d4..91e88188 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -431,8 +431,10 @@ struct protent { /* Process a received data packet */ void (*datainput) __P((int unit, u_char *pkt, int len)); bool enabled_flag; /* 0 iff protocol is disabled */ +#if PRINTPKT_SUPPORT char *name; /* Text name of protocol */ char *data_name; /* Text name of corresponding data protocol */ +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS option_t *options; /* List of command-line options */ /* Check requested options, assign defaults */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 239eae11..298114fc 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -103,8 +103,10 @@ struct protent pap_protent = { #endif /* PRINTPKT_SUPPORT */ NULL, 1, +#if PRINTPKT_SUPPORT "PAP", NULL, +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS pap_option_list, NULL, From 668d5d9d9282e1871fa7523b89a22f8715b6bc3d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 02:23:56 +0200 Subject: [PATCH 061/320] removed set/getenv functions --- src/netif/ppp/auth.c | 3 ++- src/netif/ppp/ipcp.c | 4 ++++ src/netif/ppp/ppp.c | 9 ++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index c067545a..45989347 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1056,11 +1056,12 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) /* * Save the authenticated name of the peer for later. */ + /* FIXME: do we need that ? */ if (namelen > sizeof(peer_authname) - 1) namelen = sizeof(peer_authname) - 1; MEMCPY(peer_authname, name, namelen); peer_authname[namelen] = 0; - script_setenv("PEERNAME", peer_authname, 0); + //script_setenv("PEERNAME", peer_authname, 0); /* Save the authentication method for later. */ auth_done[unit] |= bit; diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 1fb9652b..89ec6c4a 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1816,14 +1816,17 @@ ipcp_up(f) warn("Could not determine remote IP address: defaulting to %I", ho->hisaddr); } +#if 0 /* UNUSED */ script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); if (ho->hisaddr != 0) script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); +#endif /* UNUSED */ if (!go->req_dns1) go->dnsaddr[0] = 0; if (!go->req_dns2) go->dnsaddr[1] = 0; +#if 0 /* UNUSED */ if (go->dnsaddr[0]) script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); if (go->dnsaddr[1]) @@ -1832,6 +1835,7 @@ ipcp_up(f) script_setenv("USEPEERDNS", "1", 0); create_resolv(go->dnsaddr[0], go->dnsaddr[1]); } +#endif /* UNUSED */ /* FIXME: check why it fails, just to know */ #if 0 /* Unused */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index c33922da..e94172f3 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -726,6 +726,7 @@ setup_signals() } #endif +#if 0 /* * set_ifunit - do things we need to do once we know which ppp * unit we are using. @@ -742,6 +743,7 @@ set_ifunit(iskey) // create_linkpidfile(getpid()); } } +#endif #if 0 /* @@ -1256,12 +1258,14 @@ update_link_stats(u) link_stats.pkts_in -= old_link_stats.pkts_in; link_stats.pkts_out -= old_link_stats.pkts_out; +#if 0 slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time); script_setenv("CONNECT_TIME", numbuf, 0); slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out); script_setenv("BYTES_SENT", numbuf, 0); slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in); script_setenv("BYTES_RCVD", numbuf, 0); +#endif } @@ -1804,7 +1808,8 @@ add_notifier(notif, func, arg) np = malloc(sizeof(struct notifier)); if (np == 0) - novm("notifier struct"); + return; + //novm("notifier struct"); np->next = *notif; np->func = func; np->arg = arg; @@ -1848,6 +1853,7 @@ notify(notif, val) } } +#if 0 /* UNUSED */ /* * novm - log an error message saying we ran out of memory, and die. */ @@ -1934,3 +1940,4 @@ script_unsetenv(var) } } } +#endif /* UNUSED */ From 88ef3ffa505e6155da2097b850ac66c18d6231ea Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 02:30:43 +0200 Subject: [PATCH 062/320] POSIX signal support removed --- src/netif/ppp/ppp.c | 15 ++++++++++++++- src/netif/ppp/pppd.h | 4 ++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index e94172f3..4145bac4 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -231,9 +231,12 @@ static struct subprocess *children; //static void create_pidfile __P((int pid)); //static void create_linkpidfile __P((int pid)); //static void cleanup __P((void)); +#if 0 static void get_input __P((void)); +#endif static void calltimeout __P((void)); static struct timeval *timeleft __P((struct timeval *)); +#if 0 static void kill_my_pg __P((int)); static void hup __P((int)); static void term __P((int)); @@ -241,12 +244,15 @@ static void chld __P((int)); static void toggle_debug __P((int)); static void open_ccp __P((int)); static void bad_signal __P((int)); +#endif static void holdoff_end __P((void *)); +#if 0 static void forget_child __P((int pid, int status)); static int reap_kids __P((void)); static void childwait_end __P((void *)); static void handle_events __P((void)); +#endif void print_link_stats __P((void)); extern char *ttyname __P((int)); @@ -1021,6 +1027,7 @@ protocol_name(proto) return NULL; } +#if 0 /* * get_input - called when incoming data is available. */ @@ -1115,7 +1122,9 @@ get_input() } lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); } +#endif +#if 0 /* * ppp_send_config - configure the transmit-side characteristics of * the ppp interface. Returns -1, indicating an error, if the channel @@ -1157,6 +1166,7 @@ old_ppp_recv_config(unit, mru, accm, pcomp, accomp) (*the_channel->recv_config)(mru, accm, pcomp, accomp); return (error_count != errs)? -1: 0; } +#endif /* * new_phase - signal the start of a new phase of pppd's operation. @@ -1390,7 +1400,7 @@ timeleft(tvp) return tvp; } - +#if 0 /* * kill_my_pg - send a signal to our process group, and ignore it ourselves. * We assume that sig is currently blocked. @@ -1525,6 +1535,7 @@ open_ccp(sig) if (waiting) siglongjmp(sigjmp, 1); } +#endif #if 0 /* @@ -1695,6 +1706,7 @@ device_script(program, in, out, dont_wait) } #endif +#if 0 /* UNUSED */ /* * record_child - add a child process to the list for reap_kids * to use. @@ -1794,6 +1806,7 @@ reap_kids() } return 0; } +#endif /* UNUSED */ /* * add_notifier - add a new function to be called when something happens. diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 91e88188..867f701b 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -505,7 +505,9 @@ void timeout __P((void (*func)(void *), void *arg, int s, int us)); /* Call func(arg) after s.us seconds */ void untimeout __P((void (*func)(void *), void *arg)); /* Cancel call to func(arg) */ +#if 0 void record_child __P((int, char *, void (*) (void *), void *, int)); +#endif #if 0 pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ @@ -517,8 +519,10 @@ void reopen_log __P((void)); /* (re)open the connection to syslog */ void print_link_stats __P((void)); /* Print stats, if available */ void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */ void update_link_stats __P((int)); /* Get stats at link termination */ +#if 0 /* UNUSED */ void script_setenv __P((char *, char *, int)); /* set script env var */ void script_unsetenv __P((char *)); /* unset script env var */ +#endif /* UNUSED */ void new_phase __P((int)); /* signal start of new phase */ void add_notifier __P((struct notifier **, notify_func, void *)); void remove_notifier __P((struct notifier **, notify_func, void *)); From 89ab39071925d7e70c3be08e8ba012af8b7830b5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 02:44:18 +0200 Subject: [PATCH 063/320] added necessary pppSingleBuf() call before passing the packet to the appropriate PPP subsystem --- src/netif/ppp/pppmy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index af1329ad..e52c5e2d 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -273,6 +273,7 @@ static void ppp_input(void *arg) { */ for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { + nb = pppSingleBuf(nb); (*protp->input)(pd, nb->payload, nb->len); goto out; } From 0de1293ff5001d2927ff0e1292d649b3db2fd63e Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 13:03:43 +0200 Subject: [PATCH 064/320] clarifying what is actually the "datainput" entry in protent --- src/netif/ppp/pppd.h | 3 +++ src/netif/ppp/pppmy.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 867f701b..df88d71f 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -428,6 +428,9 @@ struct protent { void (*printer) __P((void *, char *, ...)), void *arg)); #endif /* PRINTPKT_SUPPORT */ + /* FIXME: data input is only used by CCP, which is not supported at this time, + * should we remove this entry and save some flash ? + */ /* Process a received data packet */ void (*datainput) __P((int unit, u_char *pkt, int len)); bool enabled_flag; /* 0 iff protocol is disabled */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index e52c5e2d..9c00727c 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -277,13 +277,21 @@ static void ppp_input(void *arg) { (*protp->input)(pd, nb->payload, nb->len); goto out; } -#if 0 /* Unused ? */ +#if 0 /* UNUSED + * + * This is actually a (hacked?) way for the PPP kernel implementation to pass a + * data packet to the PPP daemon. The PPP daemon normally only do signaling + * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. + * + * This is only used by CCP, which we cannot support until we have a CCP data + * implementation. + */ if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag && protp->datainput != NULL) { (*protp->datainput)(pd, nb->payload, nb->len); goto out; } -#endif /* Unused */ +#endif /* UNUSED */ } if (debug) { From 0f1c18e675ac8169b6ecbcab3436da77e525aba4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 13:46:45 +0200 Subject: [PATCH 065/320] PPP interval timeout support disabled (using lwIP timeout support), protocol_name() moved to our PPP impl and disabled by default --- src/netif/ppp/lcp.c | 20 ++++-- src/netif/ppp/ppp.c | 158 ++---------------------------------------- src/netif/ppp/pppd.h | 1 - src/netif/ppp/pppmy.c | 152 ++++++++++++++++++++++++++++++++++++++++ src/netif/ppp/pppmy.h | 5 ++ 5 files changed, 175 insertions(+), 161 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 0768efdc..21090ae3 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -587,7 +587,9 @@ lcp_rprotrej(f, inp, len) int i; struct protent *protp; u_short prot; +#if PPP_PROTOCOLNAME const char *pname; +#endif /* PPP_PROTOCOLNAME */ if (len < 2) { LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); @@ -605,27 +607,33 @@ lcp_rprotrej(f, inp, len) return; } +#if PPP_PROTOCOLNAME pname = protocol_name(prot); +#endif /* PPP_PROTOCOLNAME */ /* * Upcall the proper Protocol-Reject routine. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->protocol == prot && protp->enabled_flag) { - if (pname == NULL) - dbglog("Protocol-Reject for 0x%x received", prot); - else +#if PPP_PROTOCOLNAME + if (pname != NULL) dbglog("Protocol-Reject for '%s' (0x%x) received", pname, prot); + else +#endif /* PPP_PROTOCOLNAME */ + dbglog("Protocol-Reject for 0x%x received", prot); (*protp->protrej)(f->unit); return; } - if (pname == NULL) - warn("Protocol-Reject for unsupported protocol 0x%x", prot); - else +#if PPP_PROTOCOLNAME + if (pname != NULL) warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname, prot); + else +#endif /* #if PPP_PROTOCOLNAME */ + warn("Protocol-Reject for unsupported protocol 0x%x", prot); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 4145bac4..584770ff 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -233,10 +233,8 @@ static struct subprocess *children; //static void cleanup __P((void)); #if 0 static void get_input __P((void)); -#endif static void calltimeout __P((void)); static struct timeval *timeleft __P((struct timeval *)); -#if 0 static void kill_my_pg __P((int)); static void hup __P((int)); static void term __P((int)); @@ -244,9 +242,7 @@ static void chld __P((int)); static void toggle_debug __P((int)); static void open_ccp __P((int)); static void bad_signal __P((int)); -#endif static void holdoff_end __P((void *)); -#if 0 static void forget_child __P((int pid, int status)); static int reap_kids __P((void)); static void childwait_end __P((void *)); @@ -867,6 +863,7 @@ void remove_pidfiles() } #endif +#if 0 /* * holdoff_end - called via a timeout when the holdoff period ends. */ @@ -876,156 +873,7 @@ holdoff_end(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" }, - { 0x51, "KNX Bridging Data" }, - { 0x53, "Encryption" }, - { 0x55, "Individual Link Encryption" }, - { 0x57, "IPv6" }, - { 0x59, "PPP Muxing" }, - { 0x5b, "Vendor-Specific Network Protocol" }, - { 0x61, "RTP IPHC Full Header" }, - { 0x63, "RTP IPHC Compressed TCP" }, - { 0x65, "RTP IPHC Compressed non-TCP" }, - { 0x67, "RTP IPHC Compressed UDP 8" }, - { 0x69, "RTP IPHC Compressed RTP 8" }, - { 0x6f, "Stampede Bridging" }, - { 0x73, "MP+" }, - { 0xc1, "NTCITS IPI" }, - { 0xfb, "single-link compression" }, - { 0xfd, "Compressed Datagram" }, - { 0x0201, "802.1d Hello Packets" }, - { 0x0203, "IBM Source Routing BPDU" }, - { 0x0205, "DEC LANBridge100 Spanning Tree" }, - { 0x0207, "Cisco Discovery Protocol" }, - { 0x0209, "Netcs Twin Routing" }, - { 0x020b, "STP - Scheduled Transfer Protocol" }, - { 0x020d, "EDP - Extreme Discovery Protocol" }, - { 0x0211, "Optical Supervisory Channel Protocol" }, - { 0x0213, "Optical Supervisory Channel Protocol" }, - { 0x0231, "Luxcom" }, - { 0x0233, "Sigma Network Systems" }, - { 0x0235, "Apple Client Server Protocol" }, - { 0x0281, "MPLS Unicast" }, - { 0x0283, "MPLS Multicast" }, - { 0x0285, "IEEE p1284.4 standard - data packets" }, - { 0x0287, "ETSI TETRA Network Protocol Type 1" }, - { 0x0289, "Multichannel Flow Treatment Protocol" }, - { 0x2063, "RTP IPHC Compressed TCP No Delta" }, - { 0x2065, "RTP IPHC Context State" }, - { 0x2067, "RTP IPHC Compressed UDP 16" }, - { 0x2069, "RTP IPHC Compressed RTP 16" }, - { 0x4001, "Cray Communications Control Protocol" }, - { 0x4003, "CDPD Mobile Network Registration Protocol" }, - { 0x4005, "Expand accelerator protocol" }, - { 0x4007, "ODSICP NCP" }, - { 0x4009, "DOCSIS DLL" }, - { 0x400B, "Cetacean Network Detection Protocol" }, - { 0x4021, "Stacker LZS" }, - { 0x4023, "RefTek Protocol" }, - { 0x4025, "Fibre Channel" }, - { 0x4027, "EMIT Protocols" }, - { 0x405b, "Vendor-Specific Protocol (VSP)" }, - { 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" }, - { 0x8051, "KNX Bridging Control Protocol" }, - { 0x8053, "Encryption Control Protocol" }, - { 0x8055, "Individual Link Encryption Control Protocol" }, - { 0x8057, "IPv6 Control Protocol" }, - { 0x8059, "PPP Muxing Control Protocol" }, - { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, - { 0x806f, "Stampede Bridging Control Protocol" }, - { 0x8073, "MP+ Control Protocol" }, - { 0x80c1, "NTCITS IPI Control Protocol" }, - { 0x80fb, "Single Link Compression Control Protocol" }, - { 0x80fd, "Compression Control Protocol" }, - { 0x8207, "Cisco Discovery Protocol Control" }, - { 0x8209, "Netcs Twin Routing" }, - { 0x820b, "STP - Control Protocol" }, - { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, - { 0x8235, "Apple Client Server Protocol Control" }, - { 0x8281, "MPLSCP" }, - { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, - { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, - { 0x8289, "Multichannel Flow Treatment Protocol" }, - { 0xc021, "Link Control Protocol" }, - { 0xc023, "Password Authentication Protocol" }, - { 0xc025, "Link Quality Report" }, - { 0xc027, "Shiva Password Authentication Protocol" }, - { 0xc029, "CallBack Control Protocol (CBCP)" }, - { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, - { 0xc02d, "BAP" }, - { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, - { 0xc081, "Container Control Protocol" }, - { 0xc223, "Challenge Handshake Authentication Protocol" }, - { 0xc225, "RSA Authentication Protocol" }, - { 0xc227, "Extensible Authentication Protocol" }, - { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, - { 0xc26f, "Stampede Bridging Authorization Protocol" }, - { 0xc281, "Proprietary Authentication Protocol" }, - { 0xc283, "Proprietary Authentication Protocol" }, - { 0xc481, "Proprietary Node ID Authentication Protocol" }, - { 0, NULL }, -}; - -/* - * protocol_name - find a name for a PPP protocol. - */ -const char * -protocol_name(proto) - int proto; -{ - struct protocol_list *lp; - - for (lp = protocol_list; lp->proto != 0; ++lp) - if (proto == lp->proto) - return lp->name; - return NULL; -} +#endif #if 0 /* @@ -1351,6 +1199,7 @@ untimeout(func, arg) } #endif +#if 0 /* * calltimeout - Call any timeout routines which are now due. */ @@ -1399,6 +1248,7 @@ timeleft(tvp) return tvp; } +#endif #if 0 /* diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index df88d71f..6a5825e7 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -532,7 +532,6 @@ void remove_notifier __P((struct notifier **, notify_func, void *)); void notify __P((struct notifier *, int)); int ppp_send_config __P((int, int, u_int32_t, int, int)); int ppp_recv_config __P((int, int, u_int32_t, int, int)); -const char *protocol_name __P((int)); //void remove_pidfiles __P((void)); void lock_db __P((void)); void unlock_db __P((void)); diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 9c00727c..2ddb7739 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -295,10 +295,12 @@ static void ppp_input(void *arg) { } if (debug) { +#if PPP_PROTOCOLNAME const char *pname = protocol_name(protocol); if (pname != NULL) warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); else +#endif /* PPP_PROTOCOLNAME */ warn("Unsupported protocol 0x%x received", protocol); } if (pbuf_header(nb, sizeof(protocol))) { @@ -1285,3 +1287,153 @@ u_int32_t GetMask (u_int32_t addr) { /* FIXME: do we really need that in IPCP ? */ return 0; } + + +#if PPP_PROTOCOLNAME +/* 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" }, + { 0x51, "KNX Bridging Data" }, + { 0x53, "Encryption" }, + { 0x55, "Individual Link Encryption" }, + { 0x57, "IPv6" }, + { 0x59, "PPP Muxing" }, + { 0x5b, "Vendor-Specific Network Protocol" }, + { 0x61, "RTP IPHC Full Header" }, + { 0x63, "RTP IPHC Compressed TCP" }, + { 0x65, "RTP IPHC Compressed non-TCP" }, + { 0x67, "RTP IPHC Compressed UDP 8" }, + { 0x69, "RTP IPHC Compressed RTP 8" }, + { 0x6f, "Stampede Bridging" }, + { 0x73, "MP+" }, + { 0xc1, "NTCITS IPI" }, + { 0xfb, "single-link compression" }, + { 0xfd, "Compressed Datagram" }, + { 0x0201, "802.1d Hello Packets" }, + { 0x0203, "IBM Source Routing BPDU" }, + { 0x0205, "DEC LANBridge100 Spanning Tree" }, + { 0x0207, "Cisco Discovery Protocol" }, + { 0x0209, "Netcs Twin Routing" }, + { 0x020b, "STP - Scheduled Transfer Protocol" }, + { 0x020d, "EDP - Extreme Discovery Protocol" }, + { 0x0211, "Optical Supervisory Channel Protocol" }, + { 0x0213, "Optical Supervisory Channel Protocol" }, + { 0x0231, "Luxcom" }, + { 0x0233, "Sigma Network Systems" }, + { 0x0235, "Apple Client Server Protocol" }, + { 0x0281, "MPLS Unicast" }, + { 0x0283, "MPLS Multicast" }, + { 0x0285, "IEEE p1284.4 standard - data packets" }, + { 0x0287, "ETSI TETRA Network Protocol Type 1" }, + { 0x0289, "Multichannel Flow Treatment Protocol" }, + { 0x2063, "RTP IPHC Compressed TCP No Delta" }, + { 0x2065, "RTP IPHC Context State" }, + { 0x2067, "RTP IPHC Compressed UDP 16" }, + { 0x2069, "RTP IPHC Compressed RTP 16" }, + { 0x4001, "Cray Communications Control Protocol" }, + { 0x4003, "CDPD Mobile Network Registration Protocol" }, + { 0x4005, "Expand accelerator protocol" }, + { 0x4007, "ODSICP NCP" }, + { 0x4009, "DOCSIS DLL" }, + { 0x400B, "Cetacean Network Detection Protocol" }, + { 0x4021, "Stacker LZS" }, + { 0x4023, "RefTek Protocol" }, + { 0x4025, "Fibre Channel" }, + { 0x4027, "EMIT Protocols" }, + { 0x405b, "Vendor-Specific Protocol (VSP)" }, + { 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" }, + { 0x8051, "KNX Bridging Control Protocol" }, + { 0x8053, "Encryption Control Protocol" }, + { 0x8055, "Individual Link Encryption Control Protocol" }, + { 0x8057, "IPv6 Control Protocol" }, + { 0x8059, "PPP Muxing Control Protocol" }, + { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, + { 0x806f, "Stampede Bridging Control Protocol" }, + { 0x8073, "MP+ Control Protocol" }, + { 0x80c1, "NTCITS IPI Control Protocol" }, + { 0x80fb, "Single Link Compression Control Protocol" }, + { 0x80fd, "Compression Control Protocol" }, + { 0x8207, "Cisco Discovery Protocol Control" }, + { 0x8209, "Netcs Twin Routing" }, + { 0x820b, "STP - Control Protocol" }, + { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, + { 0x8235, "Apple Client Server Protocol Control" }, + { 0x8281, "MPLSCP" }, + { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, + { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, + { 0x8289, "Multichannel Flow Treatment Protocol" }, + { 0xc021, "Link Control Protocol" }, + { 0xc023, "Password Authentication Protocol" }, + { 0xc025, "Link Quality Report" }, + { 0xc027, "Shiva Password Authentication Protocol" }, + { 0xc029, "CallBack Control Protocol (CBCP)" }, + { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, + { 0xc02d, "BAP" }, + { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, + { 0xc081, "Container Control Protocol" }, + { 0xc223, "Challenge Handshake Authentication Protocol" }, + { 0xc225, "RSA Authentication Protocol" }, + { 0xc227, "Extensible Authentication Protocol" }, + { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, + { 0xc26f, "Stampede Bridging Authorization Protocol" }, + { 0xc281, "Proprietary Authentication Protocol" }, + { 0xc283, "Proprietary Authentication Protocol" }, + { 0xc481, "Proprietary Node ID Authentication Protocol" }, + { 0, NULL }, +}; + +/* + * protocol_name - find a name for a PPP protocol. + */ +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; +} +#endif /* PPP_PROTOCOLNAME */ diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index c5bea67a..c71899ac 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -135,4 +135,9 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha void pppInProcOverEthernet(int pd, struct pbuf *pb); + +#if PPP_PROTOCOLNAME +const char * protocol_name(int proto); +#endif /* PPP_PROTOCOLNAME */ + #endif /* PPPMY_H_ */ From 55c1ec29258d43c6daeaa333ea89aaa890fbc5c4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 14:12:54 +0200 Subject: [PATCH 066/320] re-enabled auth notifiers --- src/netif/ppp/auth.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 45989347..09acdee5 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -203,14 +203,12 @@ int (*allowed_address_hook) __P((u_int32_t addr)) = NULL; void (*multilink_join_hook) __P((void)) = NULL; #endif -#if 0 /* UNUSED */ /* A notifier for when the peer has authenticated itself, and we are proceeding to the network phase. */ struct notifier *auth_up_notifier = NULL; /* A notifier for when the link goes down. */ struct notifier *link_down_notifier = NULL; -#endif /* UNUSED */ /* * Option variables. @@ -704,6 +702,8 @@ void link_down(unit) int unit; { + notify(link_down_notifier, 0); + if (!doing_multilink) { upper_layers_down(unit); if (phase != PHASE_DEAD && phase != PHASE_MASTER) @@ -860,9 +860,8 @@ network_phase(unit) notice("peer from calling number %q authorized", remote_number); #endif /* UNUSED */ -#if 0 /* UNUSED */ /* - * If the peer had to authenticate, run the auth-up script now. + * If the peer had to authenticate, notify it now. */ if (0 #if CHAP_SUPPORT @@ -877,7 +876,6 @@ network_phase(unit) ) { notify(auth_up_notifier, 0); } -#endif /* UNUSED */ #if CBCP_SUPPORT /* From 6727c4344130afb0fa8c183cdfb1768c26f18a1c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 14:48:04 +0200 Subject: [PATCH 067/320] PPP notifier support is now a compile time option However, as of now, the notify() function is empty, so it requires some work if someone want to use it. The notify feature allows someone to be able to follow the state of the PPP stack (auth ok, ipcp up, initialise, ...), this is like the callback feature set by pppOverEthernetOpen() and others, but with more details. --- src/netif/ppp/auth.c | 34 +++++++++++++++++++++++++++++++++- src/netif/ppp/ipcp.c | 6 ++++++ src/netif/ppp/lcp.c | 2 ++ src/netif/ppp/ppp.c | 6 ++++++ src/netif/ppp/pppd.h | 12 +++++++++--- src/netif/ppp/pppmy.c | 9 +++++++++ src/netif/ppp/pppmy.h | 5 ++++- 7 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 09acdee5..44c254aa 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -203,12 +203,14 @@ int (*allowed_address_hook) __P((u_int32_t addr)) = NULL; void (*multilink_join_hook) __P((void)) = NULL; #endif +#if PPP_NOTIFY /* A notifier for when the peer has authenticated itself, and we are proceeding to the network phase. */ struct notifier *auth_up_notifier = NULL; /* A notifier for when the link goes down. */ struct notifier *link_down_notifier = NULL; +#endif /* PPP_NOTIFY */ /* * Option variables. @@ -567,7 +569,9 @@ void start_link(unit) char *msg; status = EXIT_NEGOTIATION_FAILED; +#if PPP_NOTIFY new_phase(PHASE_SERIALCONN); +#endif /* PPP_NOTIFY */ hungup = 0; devfd = the_channel->connect(); @@ -603,18 +607,24 @@ void start_link(unit) notice("Starting negotiation on %s", ppp_devnam); add_fd(fd_ppp); +#if PPP_NOTIFY new_phase(PHASE_ESTABLISH); +#endif /* PPP_NOTIFY */ lcp_lowerup(0); return; disconnect: +#if PPP_NOTIFY new_phase(PHASE_DISCONNECT); +#endif /* PPP_NOTIFY */ if (the_channel->disconnect) the_channel->disconnect(); fail: +#if PPP_NOTIFY new_phase(PHASE_DEAD); +#endif /* PPP_NOTIFY */ if (the_channel->cleanup) (*the_channel->cleanup)(); } @@ -630,7 +640,9 @@ link_terminated(unit) { if (phase == PHASE_DEAD || phase == PHASE_MASTER) return; +#if PPP_NOTIFY new_phase(PHASE_DISCONNECT); +#endif /* PPP_NOTIFY */ #if 0 /* UNUSED */ if (pap_logout_hook) { @@ -647,6 +659,10 @@ link_terminated(unit) lcp_lowerdown(0); +#if PPP_NOTIFY + new_phase(PHASE_DEAD); +#endif /* PPP_NOTIFY */ + #if 0 /* * Delete pid files before disestablishing ppp. Otherwise it @@ -702,12 +718,16 @@ void link_down(unit) int unit; { +#if PPP_NOTIFY notify(link_down_notifier, 0); +#endif /* #if PPP_NOTIFY */ if (!doing_multilink) { upper_layers_down(unit); +#if PPP_NOTIFY if (phase != PHASE_DEAD && phase != PHASE_MASTER) new_phase(PHASE_ESTABLISH); +#endif /* PPP_NOTIFY */ } /* XXX if doing_multilink, should do something to stop network-layer traffic on the link */ @@ -796,7 +816,9 @@ link_established(unit) } #endif /* UNUSED */ +#if PPP_NOTIFY new_phase(PHASE_AUTHENTICATE); +#endif /* PPP_NOTIFY */ auth = 0; #if EAP_SUPPORT if (go->neg_eap) { @@ -860,6 +882,7 @@ network_phase(unit) notice("peer from calling number %q authorized", remote_number); #endif /* UNUSED */ +#if PPP_NOTIFY /* * If the peer had to authenticate, notify it now. */ @@ -876,13 +899,16 @@ network_phase(unit) ) { notify(auth_up_notifier, 0); } +#endif /* PPP_NOTIFY */ #if CBCP_SUPPORT /* * If we negotiated callback, do it now. */ if (go->neg_cbcp) { +#if PPP_NOTIFY new_phase(PHASE_CALLBACK); +#endif /* PPP_NOTIFY */ (*cbcp_protent.open)(unit); return; } @@ -914,7 +940,9 @@ start_networks(unit) int mppe_required; #endif /* MPPE */ +#if PPP_NOTIFY new_phase(PHASE_NETWORK); +#endif /* PPP_NOTIFY */ #ifdef HAVE_MULTILINK if (multilink) { @@ -1165,7 +1193,9 @@ np_up(unit, proto) */ status = EXIT_OK; unsuccess = 0; +#if PPP_NOTIFY new_phase(PHASE_RUNNING); +#endif /* PPP_NOTIFY */ #if 0 /* UNUSED */ if (idle_time_hook != 0) @@ -1211,8 +1241,10 @@ np_down(unit, proto) UNTIMEOUT(connect_time_expired, NULL); #ifdef MAXOCTETS UNTIMEOUT(check_maxoctets, NULL); -#endif +#endif +#if PPP_NOTIFY new_phase(PHASE_NETWORK); +#endif /* PPP_NOTIFY */ } } diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 89ec6c4a..0e2eb857 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -84,9 +84,11 @@ void (*ip_down_hook) __P((void)) = NULL; /* Hook for a plugin to choose the remote IP address */ void (*ip_choose_hook) __P((u_int32_t *)) = NULL; +#if PPP_NOTIFY /* Notifiers for when IPCP goes up and down */ struct notifier *ip_up_notifier = NULL; struct notifier *ip_down_notifier = NULL; +#endif /* PPP_NOTIFY */ /* local vars */ static int default_route_set[NUM_PPP]; /* Have set up a default route */ @@ -1961,7 +1963,9 @@ ipcp_up(f) np_up(f->unit, PPP_IP); ipcp_is_up = 1; +#if PPP_NOTIFY notify(ip_up_notifier, 0); +#endif /* PPP_NOTIFY */ if (ip_up_hook) ip_up_hook(); } @@ -1983,7 +1987,9 @@ ipcp_down(f) /* XXX more correct: we must get the stats before running the notifiers, * at least for the radius plugin */ update_link_stats(f->unit); +#if PPP_NOTIFY notify(ip_down_notifier, 0); +#endif /* PPP_NOTIFY */ if (ip_down_hook) ip_down_hook(); if (ipcp_is_up) { diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 21090ae3..442d08ad 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -427,8 +427,10 @@ lcp_close(unit, reason) fsm *f = &lcp_fsm[unit]; int oldstate; +#if PPP_NOTIFY if (phase != PHASE_DEAD && phase != PHASE_MASTER) new_phase(PHASE_TERMINATE); +#endif /* PPP_NOTIFY */ if (f->flags & DELAYED_UP) { UNTIMEOUT(lcp_delayed_up, f); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 584770ff..7cf76c34 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1016,6 +1016,7 @@ old_ppp_recv_config(unit, mru, accm, pcomp, accomp) } #endif +#if 0 /* * new_phase - signal the start of a new phase of pppd's operation. */ @@ -1028,6 +1029,7 @@ new_phase(p) (*new_phase_hook)(p); notify(phasechange, p); } +#endif #if 0 /* @@ -1658,6 +1660,7 @@ reap_kids() } #endif /* UNUSED */ +#if 0 /* UNUSED */ /* * add_notifier - add a new function to be called when something happens. */ @@ -1699,7 +1702,9 @@ remove_notifier(notif, func, arg) } } } +#endif /* UNUSED */ +#if 0 /* * notify - call a set of functions registered with add_notifier. */ @@ -1715,6 +1720,7 @@ notify(notif, val) (*np->func)(np->arg, val); } } +#endif #if 0 /* UNUSED */ /* diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 6a5825e7..4d33a7a9 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -201,6 +201,7 @@ struct epdisc { #define EPD_MAGIC 4 #define EPD_PHONENUM 5 +#if 0 /* UNUSED */ typedef void (*notify_func) __P((void *, int)); struct notifier { @@ -208,6 +209,7 @@ struct notifier { notify_func func; void *arg; }; +#endif /* UNUSED */ /* * Global variables. @@ -262,12 +264,14 @@ extern struct notifier *pidchange; /* for notifications of pid changing */ extern struct notifier *phasechange; /* for notifications of phase changes */ extern struct notifier *exitnotify; /* for notification that we're exiting */ extern struct notifier *sigreceived; /* notification of received signal */ + +#if PPP_NOTIFY extern struct notifier *ip_up_notifier; /* IPCP has come up */ extern struct notifier *ip_down_notifier; /* IPCP has gone down */ -#if 0 /* UNUSED */ extern struct notifier *auth_up_notifier; /* peer has authenticated */ -#endif /* UNUSED */ extern struct notifier *link_down_notifier; /* link has gone down */ +#endif /* PPP_NOTIFY */ + extern struct notifier *fork_notifier; /* we are a new child process */ /* Values for do_callback and doing_callback */ @@ -526,10 +530,12 @@ void update_link_stats __P((int)); /* Get stats at link termination */ void script_setenv __P((char *, char *, int)); /* set script env var */ void script_unsetenv __P((char *)); /* unset script env var */ #endif /* UNUSED */ -void new_phase __P((int)); /* signal start of new phase */ +//void new_phase __P((int)); /* signal start of new phase */ +#if 0 /* UNUSED */ void add_notifier __P((struct notifier **, notify_func, void *)); void remove_notifier __P((struct notifier **, notify_func, void *)); void notify __P((struct notifier *, int)); +#endif /* UNUSED */ int ppp_send_config __P((int, int, u_int32_t, int, int)); int ppp_recv_config __P((int, int, u_int32_t, int, int)); //void remove_pidfiles __P((void)); diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 2ddb7739..4d757746 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -1437,3 +1437,12 @@ const char * protocol_name(int proto) { return NULL; } #endif /* PPP_PROTOCOLNAME */ + +#if PPP_NOTIFY +/* + * new_phase - signal the start of a new phase of pppd's operation. + */ +void new_phase(int p) { + +} +#endif /* PPP_NOTIFY */ diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index c71899ac..44999734 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -135,9 +135,12 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha void pppInProcOverEthernet(int pd, struct pbuf *pb); - #if PPP_PROTOCOLNAME const char * protocol_name(int proto); #endif /* PPP_PROTOCOLNAME */ +#if PPP_NOTIFY +void new_phase(int p); +#endif /* PPP_NOTIFY */ + #endif /* PPPMY_H_ */ From 4158222e86f2225a5e20dea155b20a06f7a8ed4c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 15:00:18 +0200 Subject: [PATCH 068/320] moved new_phase() to our own implementation, re-enabled new_phase() support --- src/netif/ppp/auth.c | 24 ------------------------ src/netif/ppp/lcp.c | 2 -- src/netif/ppp/ppp.c | 2 +- src/netif/ppp/pppmy.c | 10 +++++++--- src/netif/ppp/pppmy.h | 2 -- 5 files changed, 8 insertions(+), 32 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 44c254aa..c773ce1d 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -569,9 +569,7 @@ void start_link(unit) char *msg; status = EXIT_NEGOTIATION_FAILED; -#if PPP_NOTIFY new_phase(PHASE_SERIALCONN); -#endif /* PPP_NOTIFY */ hungup = 0; devfd = the_channel->connect(); @@ -607,24 +605,18 @@ void start_link(unit) notice("Starting negotiation on %s", ppp_devnam); add_fd(fd_ppp); -#if PPP_NOTIFY new_phase(PHASE_ESTABLISH); -#endif /* PPP_NOTIFY */ lcp_lowerup(0); return; disconnect: -#if PPP_NOTIFY new_phase(PHASE_DISCONNECT); -#endif /* PPP_NOTIFY */ if (the_channel->disconnect) the_channel->disconnect(); fail: -#if PPP_NOTIFY new_phase(PHASE_DEAD); -#endif /* PPP_NOTIFY */ if (the_channel->cleanup) (*the_channel->cleanup)(); } @@ -640,9 +632,7 @@ link_terminated(unit) { if (phase == PHASE_DEAD || phase == PHASE_MASTER) return; -#if PPP_NOTIFY new_phase(PHASE_DISCONNECT); -#endif /* PPP_NOTIFY */ #if 0 /* UNUSED */ if (pap_logout_hook) { @@ -659,9 +649,7 @@ link_terminated(unit) lcp_lowerdown(0); -#if PPP_NOTIFY new_phase(PHASE_DEAD); -#endif /* PPP_NOTIFY */ #if 0 /* @@ -724,10 +712,8 @@ link_down(unit) if (!doing_multilink) { upper_layers_down(unit); -#if PPP_NOTIFY if (phase != PHASE_DEAD && phase != PHASE_MASTER) new_phase(PHASE_ESTABLISH); -#endif /* PPP_NOTIFY */ } /* XXX if doing_multilink, should do something to stop network-layer traffic on the link */ @@ -816,9 +802,7 @@ link_established(unit) } #endif /* UNUSED */ -#if PPP_NOTIFY new_phase(PHASE_AUTHENTICATE); -#endif /* PPP_NOTIFY */ auth = 0; #if EAP_SUPPORT if (go->neg_eap) { @@ -906,9 +890,7 @@ network_phase(unit) * If we negotiated callback, do it now. */ if (go->neg_cbcp) { -#if PPP_NOTIFY new_phase(PHASE_CALLBACK); -#endif /* PPP_NOTIFY */ (*cbcp_protent.open)(unit); return; } @@ -940,9 +922,7 @@ start_networks(unit) int mppe_required; #endif /* MPPE */ -#if PPP_NOTIFY new_phase(PHASE_NETWORK); -#endif /* PPP_NOTIFY */ #ifdef HAVE_MULTILINK if (multilink) { @@ -1193,9 +1173,7 @@ np_up(unit, proto) */ status = EXIT_OK; unsuccess = 0; -#if PPP_NOTIFY new_phase(PHASE_RUNNING); -#endif /* PPP_NOTIFY */ #if 0 /* UNUSED */ if (idle_time_hook != 0) @@ -1242,9 +1220,7 @@ np_down(unit, proto) #ifdef MAXOCTETS UNTIMEOUT(check_maxoctets, NULL); #endif -#if PPP_NOTIFY new_phase(PHASE_NETWORK); -#endif /* PPP_NOTIFY */ } } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 442d08ad..21090ae3 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -427,10 +427,8 @@ lcp_close(unit, reason) fsm *f = &lcp_fsm[unit]; int oldstate; -#if PPP_NOTIFY if (phase != PHASE_DEAD && phase != PHASE_MASTER) new_phase(PHASE_TERMINATE); -#endif /* PPP_NOTIFY */ if (f->flags & DELAYED_UP) { UNTIMEOUT(lcp_delayed_up, f); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 7cf76c34..fa7af00c 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -167,7 +167,7 @@ static int fd_loop; /* fd for getting demand-dial packets */ int fd_devnull; /* fd for /dev/null */ int devfd = -1; /* fd of underlying device */ int fd_ppp = -1; /* fd for talking PPP */ -int phase; /* where the link is at */ +//int phase; /* where the link is at */ int kill_link; int asked_to_quit; int open_ccp_flag; diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 4d757746..ca8451b0 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -23,6 +23,9 @@ #include "netif/ppp_oe.h" #endif /* PPPOE_SUPPORT */ +/* FIXME: add a phase per PPP session */ +int phase; /* where the link is at */ + /* PPP packet parser states. Current state indicates operation yet to be * completed. */ typedef enum { @@ -1438,11 +1441,12 @@ const char * protocol_name(int proto) { } #endif /* PPP_PROTOCOLNAME */ -#if PPP_NOTIFY /* * new_phase - signal the start of a new phase of pppd's operation. */ void new_phase(int p) { - -} + phase = p; +#if PPP_NOTIFY + /* The one willing notify support should add here the code to be notified of phase changes */ #endif /* PPP_NOTIFY */ +} diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 44999734..5a38cf40 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -139,8 +139,6 @@ void pppInProcOverEthernet(int pd, struct pbuf *pb); const char * protocol_name(int proto); #endif /* PPP_PROTOCOLNAME */ -#if PPP_NOTIFY void new_phase(int p); -#endif /* PPP_NOTIFY */ #endif /* PPPMY_H_ */ From 922d3716ff4a1ab3c152e3ab3da7385ddf42f330 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 16:41:09 +0200 Subject: [PATCH 069/320] PPP statistics optional (non working) compile time option added --- src/netif/ppp/auth.c | 8 ++- src/netif/ppp/ipcp.c | 6 ++ src/netif/ppp/lcp.c | 2 + src/netif/ppp/multilink.c | 2 + src/netif/ppp/ppp.c | 17 +++-- src/netif/ppp/pppd.h | 44 +++++++----- src/netif/ppp/pppmy.c | 145 +++++++++++++++++++++++--------------- src/netif/ppp/pppmy.h | 80 +++++++++++++++++++++ 8 files changed, 224 insertions(+), 80 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index c773ce1d..2e9a89c3 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -643,7 +643,9 @@ link_terminated(unit) if (!doing_multilink) { notice("Connection terminated."); +#if PPP_STATS_SUPPORT print_link_stats(); +#endif /* PPP_STATS_SUPPORT */ } else notice("Link terminated."); @@ -1242,11 +1244,12 @@ static void check_maxoctets(arg) void *arg; { +#if PPP_STATS_SUPPORT unsigned int used; update_link_stats(ifunit); link_stats_valid=0; - + switch(maxoctets_dir) { case PPP_OCTETS_DIRECTION_IN: used = link_stats.bytes_in; @@ -1270,8 +1273,9 @@ check_maxoctets(arg) } else { TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); } +#endif /* PPP_STATS_SUPPORT */ } -#endif +#endif /* MAXOCTETS */ /* * check_idle - check whether the link has been idle for long diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 0e2eb857..a9c4755a 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1958,7 +1958,9 @@ ipcp_up(f) notice("secondary DNS address %I", go->dnsaddr[1]); } +#if PPP_STATS_SUPPORT reset_link_stats(f->unit); +#endif /* PPP_STATS_SUPPORT */ np_up(f->unit, PPP_IP); ipcp_is_up = 1; @@ -1982,11 +1984,13 @@ ipcp_down(f) fsm *f; { IPCPDEBUG(("ipcp: down")); +#if PPP_STATS_SUPPORT /* XXX a bit IPv4-centric here, we only need to get the stats * before the interface is marked down. */ /* XXX more correct: we must get the stats before running the notifiers, * at least for the radius plugin */ update_link_stats(f->unit); +#endif /* PPP_STATS_SUPPORT */ #if PPP_NOTIFY notify(ip_down_notifier, 0); #endif /* PPP_NOTIFY */ @@ -1998,9 +2002,11 @@ ipcp_down(f) } sifvjcomp(f->unit, 0, 0, 0); +#if PPP_STATS_SUPPORT print_link_stats(); /* _after_ running the notifiers and ip_down_hook(), * because print_link_stats() sets link_stats_valid * to 0 (zero) */ +#endif /* PPP_STATS_SUPPORT */ #if DEMAND_SUPPORT /* diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 21090ae3..9c21eb22 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -2629,8 +2629,10 @@ LcpSendEchoRequest (f) if (lcp_echo_adaptive) { static unsigned int last_pkts_in = 0; +#if PPP_STATS_SUPPORT update_link_stats(f->unit); link_stats_valid = 0; +#endif /* PPP_STATS_SUPPORT */ if (link_stats.pkts_in != last_pkts_in) { last_pkts_in = link_stats.pkts_in; diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 47a34688..3d71e086 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -279,7 +279,9 @@ void mp_bundle_terminated() bundle_terminating = 1; upper_layers_down(0); notice("Connection terminated."); +#if PPP_STATS_SUPPORT print_link_stats(); +#endif /* PPP_STATS_SUPPORT */ if (!demand) { remove_pidfiles(); script_unsetenv("IFNAME"); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index fa7af00c..4e020fb8 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -198,12 +198,12 @@ GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ int ngroups; /* How many groups valid in groups */ #endif /* UNUSED */ -static struct timeval start_time; /* Time when link was started. */ +//static struct timeval start_time; /* Time when link was started. */ -static struct pppd_stats old_link_stats; -struct pppd_stats link_stats; -unsigned link_connect_time; -int link_stats_valid; +//static struct pppd_stats old_link_stats; +//struct pppd_stats link_stats; +//unsigned link_connect_time; +//int link_stats_valid; int error_count; @@ -249,7 +249,9 @@ static void childwait_end __P((void *)); static void handle_events __P((void)); #endif +#if 0 void print_link_stats __P((void)); +#endif extern char *ttyname __P((int)); extern char *getlogin __P((void)); @@ -794,6 +796,7 @@ detach() } #endif +#if 0 /* * reopen_log - (re)open our connection to syslog. */ @@ -803,6 +806,7 @@ reopen_log() openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); setlogmask(LOG_UPTO(LOG_INFO)); } +#endif #if 0 /* @@ -1066,6 +1070,7 @@ cleanup() } #endif +#if 0 void print_link_stats() { @@ -1127,7 +1132,7 @@ update_link_stats(u) script_setenv("BYTES_RCVD", numbuf, 0); #endif } - +#endif struct callout { struct timeval c_time; /* time at which to call routine */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 4d33a7a9..05a1a851 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -86,7 +86,9 @@ * Option descriptor structure. */ +#ifndef bool typedef unsigned char bool; +#endif #if 0 enum opt_type { @@ -166,6 +168,7 @@ struct permitted_ip { }; #endif +#if 0 /* * Unfortunately, the linux kernel driver uses a different structure * for statistics from the rest of the ports. @@ -178,6 +181,7 @@ struct pppd_stats { unsigned int pkts_in; unsigned int pkts_out; }; +#endif /* Used for storing a sequence of words. Usually malloced. */ struct wordlist { @@ -236,9 +240,11 @@ extern int detached; /* Have detached from controlling tty */ extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */ #endif extern int ngroups; /* How many groups valid in groups */ +#if PPP_STATS_SUPPORT extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */ extern int link_stats_valid; /* set if link_stats is valid */ extern unsigned link_connect_time; /* time the link was up for */ +#endif /* PPP_STATS_SUPPORT */ 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 bool log_default; /* log_to_fd is default (stdout) */ @@ -522,10 +528,14 @@ pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ //int device_script __P((char *cmd, int in, int out, int dont_wait)); /* Run `cmd' with given stdin and stdout */ +#if 0 void reopen_log __P((void)); /* (re)open the connection to syslog */ +#endif +#if 0 void print_link_stats __P((void)); /* Print stats, if available */ void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */ void update_link_stats __P((int)); /* Get stats at link termination */ +#endif #if 0 /* UNUSED */ void script_setenv __P((char *, char *, int)); /* set script env var */ void script_unsetenv __P((char *)); /* unset script env var */ @@ -536,8 +546,8 @@ void add_notifier __P((struct notifier **, notify_func, void *)); void remove_notifier __P((struct notifier **, notify_func, void *)); void notify __P((struct notifier *, int)); #endif /* UNUSED */ -int ppp_send_config __P((int, int, u_int32_t, int, int)); -int ppp_recv_config __P((int, int, u_int32_t, int, int)); +//int ppp_send_config __P((int, int, u_int32_t, int, int)); +//int ppp_recv_config __P((int, int, u_int32_t, int, int)); //void remove_pidfiles __P((void)); void lock_db __P((void)); void unlock_db __P((void)); @@ -668,21 +678,21 @@ int ccp_test __P((int, u_char *, int, int)); void ccp_flags_set __P((int, int, int)); /* Set kernel CCP state */ int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */ -int get_idle_time __P((int, struct ppp_idle *)); +//int get_idle_time __P((int, struct ppp_idle *)); /* Find out how long link has been idle */ -int get_ppp_stats __P((int, struct pppd_stats *)); +//int get_ppp_stats __P((int, struct pppd_stats *)); /* Return link statistics */ -void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */ -int netif_get_mtu __P((int)); /* Get PPP interface MTU */ -int sifvjcomp __P((int, int, int, int)); +//void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */ +//int netif_get_mtu __P((int)); /* Get PPP interface MTU */ +//int sifvjcomp __P((int, int, int, int)); /* Configure VJ TCP header compression */ -int sifup __P((int)); /* Configure i/f up for one protocol */ -int sifnpmode __P((int u, int proto, enum NPmode mode)); +//int sifup __P((int)); /* Configure i/f up for one protocol */ +//int sifnpmode __P((int u, int proto, enum NPmode mode)); /* Set mode for handling packets for proto */ -int sifdown __P((int)); /* Configure i/f down for one protocol */ -int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t)); +//int sifdown __P((int)); /* Configure i/f down for one protocol */ +//int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t)); /* Configure IPv4 addresses for i/f */ -int cifaddr __P((int, u_int32_t, u_int32_t)); +//int cifaddr __P((int, u_int32_t, u_int32_t)); /* Reset i/f IP addresses */ #ifdef INET6 int sif6addr __P((int, eui64_t, eui64_t)); @@ -690,15 +700,15 @@ int sif6addr __P((int, eui64_t, eui64_t)); int cif6addr __P((int, eui64_t, eui64_t)); /* Remove an IPv6 address from i/f */ #endif -int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt)); +//int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt)); /* Create default route through i/f */ -int cifdefaultroute __P((int, u_int32_t, u_int32_t)); +//int cifdefaultroute __P((int, u_int32_t, u_int32_t)); /* Delete default route through i/f */ -int sifproxyarp __P((int, u_int32_t)); +//int sifproxyarp __P((int, u_int32_t)); /* Add proxy ARP entry for peer */ -int cifproxyarp __P((int, u_int32_t)); +//int cifproxyarp __P((int, u_int32_t)); /* Delete proxy ARP entry for peer */ -u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ +//u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ #if 0 /* Unused */ int lock __P((char *)); /* Create lock file for device */ int relock __P((int)); /* Rewrite lock file with new pid */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index ca8451b0..af89e824 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -26,6 +26,15 @@ /* FIXME: add a phase per PPP session */ int phase; /* where the link is at */ +/* FIXME: add stats per PPP session */ +#if PPP_STATS_SUPPORT +static struct timeval start_time; /* Time when link was started. */ +static struct pppd_stats old_link_stats; +struct pppd_stats link_stats; +unsigned link_connect_time; +int link_stats_valid; +#endif /* PPP_STATS_SUPPORT */ + /* PPP packet parser states. Current state indicates operation yet to be * completed. */ typedef enum { @@ -148,8 +157,7 @@ PACK_STRUCT_END /** Initiate LCP open request */ -static void pppStart(int pd) -{ +static void pppStart(int pd) { PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd)); lcp_open(pd); /* Start protocol */ lcp_lowerup(pd); @@ -454,9 +462,7 @@ int ppp_init(void) { (*protp->init)(0); } -void -pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) -{ +void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { /* FIXME: the following may look stupid, but this is just an easy way * to check different auth by changing compile time option */ @@ -649,9 +655,7 @@ drop: return; } -void -pppOverEthernetInitFailed(int pd) -{ +void pppOverEthernetInitFailed(int pd) { PPPControl* pc; //pppHup(pd); @@ -666,9 +670,7 @@ pppOverEthernetInitFailed(int pd) } } -static void -pppOverEthernetLinkStatusCB(int pd, int up) -{ +static void pppOverEthernetLinkStatusCB(int pd, int up) { printf("pppOverEthernetLinkStatusCB: called, pd = %d, up = %d\n", pd, up); if(up) { PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); @@ -680,9 +682,7 @@ pppOverEthernetLinkStatusCB(int pd, int up) #endif #if PPPOE_SUPPORT -static err_t -pppifOutputOverEthernet(int pd, struct pbuf *p) -{ +static err_t pppifOutputOverEthernet(int pd, struct pbuf *p) { PPPControl *pc = &pppControl[pd]; struct pbuf *pb; u_short protocol = PPP_IP; @@ -724,9 +724,7 @@ pppifOutputOverEthernet(int pd, struct pbuf *p) #endif /* PPPOE_SUPPORT */ /* Send a packet on the given connection. */ -static err_t -pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) -{ +static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { int pd = (int)(size_t)netif->state; PPPControl *pc = &pppControl[pd]; #if PPPOS_SUPPORT @@ -877,9 +875,7 @@ pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) /* * Return the Maximum Transmission Unit for the given PPP connection. */ -u_short -pppMTU(int pd) -{ +u_short pppMTU(int pd) { PPPControl *pc = &pppControl[pd]; u_short st; @@ -894,9 +890,7 @@ pppMTU(int pd) } #if PPPOE_SUPPORT -int -pppWriteOverEthernet(int pd, const u_char *s, int n) -{ +int pppWriteOverEthernet(int pd, const u_char *s, int n) { PPPControl *pc = &pppControl[pd]; struct pbuf *pb; @@ -939,9 +933,7 @@ pppWriteOverEthernet(int pd, const u_char *s, int n) * RETURN: >= 0 Number of characters written * -1 Failed to write to device */ -int -pppWrite(int pd, const u_char *s, int n) -{ +int pppWrite(int pd, const u_char *s, int n) { PPPControl *pc = &pppControl[pd]; #if PPPOS_SUPPORT u_char c; @@ -1030,12 +1022,7 @@ void output (int unit, unsigned char *p, int len) * ppp_send_config - configure the transmit-side characteristics of * the ppp interface. */ -int -ppp_send_config(unit, mtu, accm, pcomp, accomp) - int unit, mtu; - u_int32_t accm; - int pcomp, accomp; -{ +int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { PPPControl *pc = &pppControl[unit]; int i; @@ -1050,18 +1037,14 @@ ppp_send_config(unit, mtu, accm, pcomp, accomp) PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", unit, pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); + return 0; } /* * ppp_recv_config - configure the receive-side characteristics of * the ppp interface. */ -int -ppp_recv_config(unit, mru, accm, pcomp, accomp) - int unit, mru; - u_int32_t accm; - int pcomp, accomp; -{ +int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { PPPControl *pc = &pppControl[unit]; int i; SYS_ARCH_DECL_PROTECT(lev); @@ -1080,17 +1063,15 @@ ppp_recv_config(unit, mru, accm, pcomp, accomp) PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", unit, pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); + return 0; } - - /* * sifaddr - Config the interface IP addresses and netmask. */ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, - u_int32_t net_mask) -{ + u_int32_t net_mask) { PPPControl *pc = &pppControl[unit]; int st = 1; @@ -1118,16 +1099,6 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { } -/******************************************************************** - * - * sifdown - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ -int sifdown (int u) { - /* FIXME: do the code which shutdown a PPP interface */ - return 1; -} - /* * pppifNetifInit - netif init callback */ @@ -1178,13 +1149,20 @@ int sifup(int u) return st; } +/******************************************************************** + * + * sifdown - Disable the indicated protocol and config the interface + * down if there are no remaining protocols. + */ +int sifdown (int u) { + /* FIXME: do the code which shutdown a PPP interface */ + return 1; +} /* * sifnpmode - Set the mode for handling packets for a given NP. */ -int -sifnpmode(int u, int proto, enum NPmode mode) -{ +int sifnpmode(int u, int proto, enum NPmode mode) { LWIP_UNUSED_ARG(u); LWIP_UNUSED_ARG(proto); LWIP_UNUSED_ARG(mode); @@ -1197,6 +1175,12 @@ sifnpmode(int u, int proto, enum NPmode mode) void netif_set_mtu(int unit, int mtu) { /* FIXME: set lwIP MTU */ } +/* + * netif_get_mtu - get PPP interface MTU + */ +int netif_get_mtu(int mtu) { + /* FIXME: get lwIP MTU */ +} /******************************************************************** * @@ -1450,3 +1434,54 @@ void new_phase(int p) { /* The one willing notify support should add here the code to be notified of phase changes */ #endif /* PPP_NOTIFY */ } + +#if PPP_STATS_SUPPORT + +/* ---- Note on PPP Stats support ---- + * + * The one willing link stats support should add the get_ppp_stats() + * to fetch statistics from lwIP. + */ + +/* + * reset_link_stats - "reset" stats when link goes up. + */ +void reset_link_stats(int u) { + if (!get_ppp_stats(u, &old_link_stats)) + return; + gettimeofday(&start_time, NULL); +} + +/* + * 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; + + link_stats.bytes_in -= old_link_stats.bytes_in; + link_stats.bytes_out -= old_link_stats.bytes_out; + link_stats.pkts_in -= old_link_stats.pkts_in; + link_stats.pkts_out -= old_link_stats.pkts_out; +} + +void print_link_stats() { + /* + * Print connect time and statistics. + */ + if (link_stats_valid) { + int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ + info("Connect time %d.%d minutes.", t/10, t%10); + info("Sent %u bytes, received %u bytes.", + link_stats.bytes_out, link_stats.bytes_in); + link_stats_valid = 0; + } +} +#endif PPP_STATS_SUPPORT diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 5a38cf40..2579c550 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -12,9 +12,16 @@ #include /* FIXME: temporary */ + #include "lwip/netif.h" #include "lwip/def.h" +#ifndef bool +typedef unsigned char bool; +#endif + + + /************************* *** PUBLIC DEFINITIONS *** *************************/ @@ -38,6 +45,17 @@ struct ppp_addrs { ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; }; +#if PPP_STATS_SUPPORT +/* + * PPP statistics structure + */ +struct pppd_stats { + unsigned int bytes_in; + unsigned int bytes_out; + unsigned int pkts_in; + unsigned int pkts_out; +}; +#endif /* PPP_STATS_SUPPORT */ /* FIXME: use PPP option instead ? */ @@ -121,6 +139,14 @@ enum pppAuthType { #endif /* CHAP_SUPPORT */ }; +struct pbuf * pppSingleBuf(struct pbuf *p); + +static void pppStart(int pd); + +static void ppp_input(void *arg); + +int ppp_init(void); + void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); /* Link status callback function prototype */ @@ -132,8 +158,56 @@ typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); + void pppInProcOverEthernet(int pd, struct pbuf *pb); +void pppOverEthernetInitFailed(int pd); + +static void pppOverEthernetLinkStatusCB(int pd, int up); + +static err_t pppifOutputOverEthernet(int pd, struct pbuf *p); + +static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); + +u_short pppMTU(int pd); + +int pppWriteOverEthernet(int pd, const u_char *s, int n); + +int pppWrite(int pd, const u_char *s, int n); + +void pppInProcOverEthernet(int pd, struct pbuf *pb); + +void output (int unit, unsigned char *p, int len); + +int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp); +int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp); + +int sifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); +int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr); + +static err_t pppifNetifInit(struct netif *netif); + +int sifup(int u); +int sifdown (int u); + +int sifnpmode(int u, int proto, enum NPmode mode); + +void netif_set_mtu(int unit, int mtu); +int netif_get_mtu(int mtu); + +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace); +int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway); + +int sifproxyarp (int unit, u_int32_t his_adr); +int cifproxyarp (int unit, u_int32_t his_adr); + +int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid); + +int get_idle_time(int u, struct ppp_idle *ip); + +int get_loop_output(void); + +u_int32_t GetMask (u_int32_t addr); #if PPP_PROTOCOLNAME const char * protocol_name(int proto); @@ -141,4 +215,10 @@ const char * protocol_name(int proto); void new_phase(int p); +#if PPP_STATS_SUPPORT +void print_link_stats(void); /* Print stats, if available */ +void reset_link_stats(int u); /* Reset (init) stats when link goes up */ +void update_link_stats(int u); /* Get stats at link termination */ +#endif /* PPP_STATS_SUPPORT */ + #endif /* PPPMY_H_ */ From d3d1b69c7aaa4aa142768e0ff58de23134645544 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 16:56:20 +0200 Subject: [PATCH 070/320] more ppp.c cleaning --- src/netif/ppp/ppp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 4e020fb8..0d9f6b6d 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -301,12 +301,15 @@ struct protent *protocols[] = { NULL }; + +#if 0 /* * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. */ #if !defined(PPP_DRV_NAME) #define PPP_DRV_NAME "ppp" #endif /* !defined(PPP_DRV_NAME) */ +#endif #if 0 int ppp_oldmain() { @@ -1134,6 +1137,7 @@ update_link_stats(u) } #endif +#if 0 struct callout { struct timeval c_time; /* time at which to call routine */ void *c_arg; /* argument to routine */ @@ -1143,6 +1147,7 @@ struct callout { static struct callout *callout = NULL; /* Callout list */ static struct timeval timenow; /* Current time */ +#endif #if 0 /* From adb8b881b4c8d8ea80468a085e5521b16d482728 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 17:04:46 +0200 Subject: [PATCH 071/320] resolve conflit, ipcp.c defines ip_ntoa() which is already defined by lwIP, disabled ipcp.c::ip_ntoa() and using lwIP one --- src/netif/ppp/ipcp.c | 3 +++ src/netif/ppp/ipcp.h | 2 ++ src/netif/ppp/pppmy.h | 1 + 3 files changed, 6 insertions(+) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index a9c4755a..eaffe6f1 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -58,6 +58,7 @@ #include #include +#include "pppmy.h" #include "pppd.h" #include "fsm.h" #include "ipcp.h" @@ -312,6 +313,7 @@ static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool)); #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") +#if 0 /* UNUSED, already defined by lwIP */ /* * Make a string representation of a network IP address. */ @@ -324,6 +326,7 @@ u_int32_t ipaddr; slprintf(b, sizeof(b), "%I", ipaddr); return b; } +#endif /* UNUSED, already defined by lwIP */ /* * Option parsing. diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index 7ecfa79d..332575e7 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -92,6 +92,8 @@ extern ipcp_options ipcp_gotoptions[]; extern ipcp_options ipcp_allowoptions[]; extern ipcp_options ipcp_hisoptions[]; +#if 0 /* UNUSED, already defined by lwIP */ char *ip_ntoa __P((u_int32_t)); +#endif /* UNUSED, already defined by lwIP */ extern struct protent ipcp_protent; diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index 2579c550..d88c6e45 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -12,6 +12,7 @@ #include /* FIXME: temporary */ +#include /* FIXME: merge linux/ppp_defs.h content here */ #include "lwip/netif.h" #include "lwip/def.h" From 7f9fea18aebd4390a04aec18e671a1be2ccbb871 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 17:12:55 +0200 Subject: [PATCH 072/320] added pppmy.h in all .c files to easily find conflicts --- src/netif/ppp/auth.c | 2 +- src/netif/ppp/ccp.c | 1 + src/netif/ppp/chap-md5.c | 1 + src/netif/ppp/chap-new.c | 3 +-- src/netif/ppp/chap_ms.c | 1 + src/netif/ppp/eap.c | 1 + src/netif/ppp/ecp.c | 1 + src/netif/ppp/fsm.c | 1 + src/netif/ppp/ipcp.c | 2 +- src/netif/ppp/multilink.c | 1 + src/netif/ppp/options.c | 1 + src/netif/ppp/ppp.c | 2 +- src/netif/ppp/pppcrypt.c | 1 + src/netif/ppp/session.c | 1 + src/netif/ppp/sys-linux.c | 1 + src/netif/ppp/tty.c | 1 + src/netif/ppp/upap.c | 1 + src/netif/ppp/utils.c | 1 + 18 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 2e9a89c3..cc5e9231 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -69,7 +69,6 @@ */ #include "lwip/opt.h" -#include "pppmy.h" #include #include @@ -102,6 +101,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "lcp.h" #include "ccp.h" diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 7bd65192..18676c59 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -37,6 +37,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "ccp.h" #include diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 19756937..1a768836 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -34,6 +34,7 @@ #include #include #include "pppd.h" +#include "pppmy.h" #include "chap-new.h" #include "chap-md5.h" #include "magic.h" diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index bb20d18b..2d2c409f 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -31,13 +31,12 @@ #include "lwip/opt.h" #if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "pppmy.h" - #define RCSID "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $" #include #include #include "pppd.h" +#include "pppmy.h" #include "session.h" #include "chap-new.h" #include "chap-md5.h" diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index f3691bd3..02b16675 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -86,6 +86,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "chap-new.h" #include "chap_ms.h" #include "polarssl/md4.h" diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index e1542e4d..f65185ad 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -47,6 +47,7 @@ #if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include "pppd.h" +#include "pppmy.h" #include "polarssl/md5.h" #include "eap.h" diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index 9b2fdabc..9d08c734 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -67,6 +67,7 @@ static const char rcsid[] = RCSID; #include #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "ecp.h" diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index e34e2eb2..a63fc4e3 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -55,6 +55,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "fsm.h" static const char rcsid[] = RCSID; diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index eaffe6f1..2dd1962d 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -58,8 +58,8 @@ #include #include -#include "pppmy.h" #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "ipcp.h" diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 3d71e086..30d71aa3 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -51,6 +51,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "lcp.h" #include "tdb.h" diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 62ba3b63..1b96012d 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -75,6 +75,7 @@ #endif /* PPP_FILTER */ #include "pppd.h" +#include "pppmy.h" #if defined(ultrix) || defined(NeXT) char *strdup __P((char *)); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0d9f6b6d..b513ece6 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -67,7 +67,6 @@ */ #include "lwip/opt.h" -#include "pppmy.h" #define RCSID "$Id: main.c,v 1.156 2008/06/23 11:47:18 paulus Exp $" @@ -95,6 +94,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "magic.h" #include "fsm.h" #include "lcp.h" diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index 3baa16d1..ce9ded8f 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -34,6 +34,7 @@ #if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */ #include "pppd.h" +#include "pppmy.h" #include "pppcrypt.h" diff --git a/src/netif/ppp/session.c b/src/netif/ppp/session.c index 1c095de1..4194f44a 100644 --- a/src/netif/ppp/session.c +++ b/src/netif/ppp/session.c @@ -85,6 +85,7 @@ #include #include #include "pppd.h" +#include "pppmy.h" #include "session.h" #ifdef USE_PAM diff --git a/src/netif/ppp/sys-linux.c b/src/netif/ppp/sys-linux.c index 188b172c..7088c2bb 100644 --- a/src/netif/ppp/sys-linux.c +++ b/src/netif/ppp/sys-linux.c @@ -124,6 +124,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "ipcp.h" diff --git a/src/netif/ppp/tty.c b/src/netif/ppp/tty.c index 5008f4b0..e6fcb6e4 100644 --- a/src/netif/ppp/tty.c +++ b/src/netif/ppp/tty.c @@ -97,6 +97,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "lcp.h" diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 298114fc..5eb00944 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -51,6 +51,7 @@ #include #include "pppd.h" +#include "pppmy.h" #include "upap.h" static bool hide_password = 1; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 21fb4e5b..72ec0911 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -58,6 +58,7 @@ #endif #include "pppd.h" +#include "pppmy.h" #include "fsm.h" #include "lcp.h" From 4dd297cef257f42d4d2414e2182b3b67b41cd263 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 17:22:12 +0200 Subject: [PATCH 073/320] protent table moved to our PPP impl --- src/netif/ppp/ppp.c | 3 ++- src/netif/ppp/pppd.h | 2 ++ src/netif/ppp/pppmy.c | 63 ++++++++++++++++++++++++++++++++++++++----- src/netif/ppp/pppmy.h | 51 +++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index b513ece6..7bbe99d5 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -266,6 +266,7 @@ extern char *getlogin __P((void)); #define setlogmask(x) #endif +#if 0 /* * PPP Data Link Layer "protocol" table. * One entry per supported protocol. @@ -300,7 +301,7 @@ struct protent *protocols[] = { #endif /* EAP_SUPPORT */ NULL }; - +#endif #if 0 /* diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 05a1a851..3409d6c3 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -412,6 +412,7 @@ extern int option_priority; /* priority of current options */ #define PHASE_HOLDOFF 11 #define PHASE_MASTER 12 +#if 0 /* * The following struct gives the addresses of procedures to call * for a particular protocol. @@ -463,6 +464,7 @@ struct protent { /* Table of pointers to supported protocols */ extern struct protent *protocols[]; +#endif /* * This struct contains pointers to a set of procedures for diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index af89e824..34ef073c 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -11,17 +11,33 @@ #include "lwip/stats.h" #include "lwip/sys.h" +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ + #include "pppd.h" +#include "pppdebug.h" +#include "pppmy.h" + #include "fsm.h" #include "lcp.h" #include "ipcp.h" -#include "pppdebug.h" -#include "pppmy.h" - -#if PPPOE_SUPPORT -#include "netif/ppp_oe.h" -#endif /* PPPOE_SUPPORT */ +#if PAP_SUPPORT +#include "upap.h" +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#include "chap-new.h" +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +#include "eap.h" +#endif /* EAP_SUPPORT */ +#if CCP_SUPPORT +#include "ccp.h" +#endif /* EAP_SUPPORT */ +#if ECP_SUPPORT +#include "ecp.h" +#endif /* EAP_SUPPORT */ /* FIXME: add a phase per PPP session */ int phase; /* where the link is at */ @@ -35,6 +51,41 @@ unsigned link_connect_time; int link_stats_valid; #endif /* PPP_STATS_SUPPORT */ +/* + * PPP Data Link Layer "protocol" table. + * One entry per supported protocol. + * The last entry must be NULL. + */ +struct protent *protocols[] = { + &lcp_protent, +#if PAP_SUPPORT + &pap_protent, +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + &chap_protent, +#endif /* CHAP_SUPPORT */ +#if CBCP_SUPPORT + &cbcp_protent, +#endif + &ipcp_protent, +#ifdef INET6 + &ipv6cp_protent, +#endif +#if CCP_SUPPORT + &ccp_protent, +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT + &ecp_protent, +#endif /* ECP_SUPPORT */ +#ifdef AT_CHANGE + &atcp_protent, +#endif +#if EAP_SUPPORT + &eap_protent, +#endif /* EAP_SUPPORT */ + NULL +}; + /* PPP packet parser states. Current state indicates operation yet to be * completed. */ typedef enum { diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index d88c6e45..e53c0e14 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -21,6 +21,57 @@ typedef unsigned char bool; #endif +/* + * 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) __P((int unit)); + /* Process a received packet */ + void (*input) __P((int unit, u_char *pkt, int len)); + /* Process a received protocol-reject */ + void (*protrej) __P((int unit)); + /* Lower layer has come up */ + void (*lowerup) __P((int unit)); + /* Lower layer has gone down */ + void (*lowerdown) __P((int unit)); + /* Open the protocol */ + void (*open) __P((int unit)); + /* Close the protocol */ + void (*close) __P((int unit, char *reason)); +#if PRINTPKT_SUPPORT + /* Print a packet in readable form */ + int (*printpkt) __P((u_char *pkt, int len, + void (*printer) __P((void *, char *, ...)), + void *arg)); +#endif /* PRINTPKT_SUPPORT */ + /* FIXME: data input is only used by CCP, which is not supported at this time, + * should we remove this entry and save some flash ? + */ + /* Process a received data packet */ + void (*datainput) __P((int unit, u_char *pkt, int len)); + bool enabled_flag; /* 0 iff protocol is disabled */ +#if PRINTPKT_SUPPORT + char *name; /* Text name of protocol */ + char *data_name; /* Text name of corresponding data protocol */ +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + option_t *options; /* List of command-line options */ + /* Check requested options, assign defaults */ + void (*check_options) __P((void)); +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + /* Configure interface for demand-dial */ + int (*demand_conf) __P((int unit)); + /* Say whether to bring up link for this pkt */ + int (*active_pkt) __P((u_char *pkt, int len)); +#endif /* DEMAND_SUPPORT */ +}; + +/* Table of pointers to supported protocols */ +extern struct protent *protocols[]; /************************* From a5dd1ccfaa0ca07da04687c46866f37be395eae0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 18:07:34 +0200 Subject: [PATCH 074/320] ppp.c disabled, everything required for lwIP moved to our impl --- src/netif/ppp/ppp.c | 35 +++++++++++++++++++++++++++++++---- src/netif/ppp/pppd.h | 22 +++++++++++++--------- src/netif/ppp/pppmy.c | 22 +++++++++++++++++++++- src/netif/ppp/pppmy.h | 14 ++++++++++++++ 4 files changed, 79 insertions(+), 14 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 7bbe99d5..144943a1 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -66,9 +66,9 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "lwip/opt.h" +#if 0 /* PPP.C DISABLED */ -#define RCSID "$Id: main.c,v 1.156 2008/06/23 11:47:18 paulus Exp $" +#include "lwip/opt.h" #include #include @@ -122,26 +122,32 @@ #include "atcp.h" #endif -static const char rcsid[] = RCSID; - +#if 0 /* interface vars */ char ifname[32]; /* Interface name */ int ifunit; /* Interface unit number */ +#endif +#if 0 struct channel *the_channel; +#endif +#if 0 char *progname; /* Name of this program */ char hostname[MAXNAMELEN]; /* Our hostname */ //static char pidfilename[MAXPATHLEN]; /* name of pid file */ //static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ uid_t uid; /* Our real user-id */ + struct notifier *pidchange = NULL; struct notifier *phasechange = NULL; struct notifier *exitnotify = NULL; struct notifier *sigreceived = NULL; struct notifier *fork_notifier = NULL; +#endif +#if 0 int hungup; /* terminal has been hung up */ int privileged; /* we're running as real uid root */ int need_holdoff; /* need holdoff period before restarting */ @@ -153,17 +159,25 @@ int doing_callback; /* != 0 if we are doing callback */ int ppp_session_number; /* Session number, for channels with such a concept (eg PPPoE) */ int childwait_done; /* have timed out waiting for children */ +#endif +#if 0 char db_key[32]; +#endif +#if 0 int (*holdoff_hook) __P((void)) = NULL; int (*new_phase_hook) __P((int)) = NULL; void (*snoop_recv_hook) __P((unsigned char *p, int len)) = NULL; void (*snoop_send_hook) __P((unsigned char *p, int len)) = NULL; +#endif +#if 0 static int conn_running; /* we have a [dis]connector running */ static int fd_loop; /* fd for getting demand-dial packets */ +#endif +#if 0 int fd_devnull; /* fd for /dev/null */ int devfd = -1; /* fd of underlying device */ int fd_ppp = -1; /* fd for talking PPP */ @@ -175,29 +189,37 @@ int listen_time; int got_sigusr2; int got_sigterm; int got_sighup; +#endif +#if 0 static sigset_t signals_handled; static int waiting; static sigjmp_buf sigjmp; char **script_env; /* Env. variable values for scripts */ int s_env_nalloc; /* # words avail at script_env */ +#endif +#if 0 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ +#endif +#if 0 static int n_children; /* # child processes still running */ static int got_sigchld; /* set if we have received a SIGCHLD */ int privopen; /* don't lock, open device as root */ char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; +#endif #if 0 /* UNUSED */ GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ int ngroups; /* How many groups valid in groups */ #endif /* UNUSED */ +#if 0 //static struct timeval start_time; /* Time when link was started. */ //static struct pppd_stats old_link_stats; @@ -224,6 +246,7 @@ struct subprocess { }; static struct subprocess *children; +#endif /* Prototypes for procedures local to this file. */ @@ -253,9 +276,11 @@ static void handle_events __P((void)); void print_link_stats __P((void)); #endif +#if 0 extern char *ttyname __P((int)); extern char *getlogin __P((void)); //int main __P((int, char *[])); +#endif #ifdef ultrix #undef O_NONBLOCK @@ -1821,3 +1846,5 @@ script_unsetenv(var) } } #endif /* UNUSED */ + +#endif /* PPP.C DISABLED */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 3409d6c3..ee535a2d 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -220,10 +220,10 @@ struct notifier { */ extern int hungup; /* Physical layer has disconnected */ -extern int ifunit; /* Interface unit number */ -extern char ifname[]; /* Interface name */ +//extern int ifunit; /* Interface unit number */ +//extern char ifname[]; /* Interface name */ extern char hostname[]; /* Our hostname */ -extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ +//extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ extern int devfd; /* fd of underlying device */ extern int fd_ppp; /* fd for talking PPP */ extern int phase; /* Current state of link - see values below */ @@ -233,7 +233,7 @@ extern int redirect_stderr;/* Connector's stderr should go to file */ extern char peer_authname[];/* Authenticated name of peer */ extern int auth_done[NUM_PPP]; /* Methods actually used for auth */ extern int privileged; /* We were run by real-uid root */ -extern int need_holdoff; /* Need holdoff period after link terminates */ +//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 */ #if 0 @@ -249,18 +249,18 @@ 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 bool log_default; /* log_to_fd is default (stdout) */ extern char *no_ppp_msg; /* message to print if ppp not in kernel */ -extern volatile int status; /* exit status for pppd */ +//extern volatile int status; /* exit status for pppd */ extern bool devnam_fixed; /* can no longer change devnam */ -extern int unsuccess; /* # unsuccessful connection attempts */ +//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 int error_count; /* # of times error() has been called */ -extern char ppp_devnam[MAXPATHLEN]; +//extern int error_count; /* # of times error() has been called */ +//extern char ppp_devnam[MAXPATHLEN]; extern char remote_number[MAXNAMELEN]; /* Remote telephone number, if avail. */ extern int ppp_session_number; /* Session number (eg PPPoE session) */ extern int fd_devnull; /* fd open to /dev/null */ -extern int listen_time; /* time to listen first (ms) */ +//extern int listen_time; /* time to listen first (ms) */ extern bool doing_multilink; extern bool multilink_master; extern bool bundle_eof; @@ -466,6 +466,7 @@ struct protent { extern struct protent *protocols[]; #endif +#if 0 /* * This struct contains pointers to a set of procedures for * doing operations on a "channel". A channel provides a way @@ -501,6 +502,7 @@ struct channel { }; extern struct channel *the_channel; +#endif /* * Prototypes. @@ -768,6 +770,7 @@ int parse_dotted_ip __P((char *, u_int32_t *)); /* * Hooks to enable plugins to change various things. */ +#if 0 extern int (*new_phase_hook) __P((int)); extern int (*idle_time_hook) __P((struct ppp_idle *)); extern int (*holdoff_hook) __P((void)); @@ -789,6 +792,7 @@ extern void (*multilink_join_hook) __P((void)); /* Let a plugin snoop sent and received packets. Useful for L2TP */ extern void (*snoop_recv_hook) __P((unsigned char *p, int len)); extern void (*snoop_send_hook) __P((unsigned char *p, int len)); +#endif /* * Inline versions of get/put char/short/long. diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 34ef073c..38bed369 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -39,8 +39,27 @@ #include "ecp.h" #endif /* EAP_SUPPORT */ -/* FIXME: add a phase per PPP session */ + +/* + * Global variables. + */ +/* FIXME: global variables per PPP session */ +/* FIXME: clean global variables */ int phase; /* where the link is at */ +int error_count; /* # of times error() has been called */ +int unsuccess; /* # unsuccessful connection attempts */ +int listen_time; /* time to listen first (ms) */ +int status; /* exit status for pppd */ +int need_holdoff; /* need holdoff period before restarting */ +/* FIXME: remove ifunit */ +int ifunit; /* Interface unit number */ + +/* FIXME: outpacket_buf per PPP session */ +u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ + +#if PPPOS_SUPPORT +u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ +#endif /* PPPOS_SUPPORT */ /* FIXME: add stats per PPP session */ #if PPP_STATS_SUPPORT @@ -491,6 +510,7 @@ int ppp_init(void) { struct protent *protp; debug = 1; + ifunit = 1; /* FIXME: remove ifunit */ openlog("LWIP-PPP", LOG_PID | LOG_NDELAY, LOG_PPP); setlogmask(LOG_UPTO(LOG_DEBUG)); diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index e53c0e14..d799514c 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -21,6 +21,20 @@ typedef unsigned char bool; #endif +/* FIXME: global variables per PPP session */ + +/* + * Global variables. + */ +extern int error_count; /* # of times error() has been called */ +extern int unsuccess; /* # unsuccessful connection attempts */ +extern int listen_time; /* time to listen first (ms) */ +extern int status; /* exit status for pppd */ +extern int need_holdoff; /* Need holdoff period after link terminates */ +/* FIXME: remove ifunit */ +extern int ifunit; /* Interface unit number */ +extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ + /* * The following struct gives the addresses of procedures to call * for a particular protocol. From 323aebf1f543455d50a23598f6ba690518463bf7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 18:47:53 +0200 Subject: [PATCH 075/320] cleaning unused stuff in pppd.h, syslog() is no more used --- src/netif/ppp/options.c | 2 + src/netif/ppp/pppd.h | 41 +++++++-- src/netif/ppp/pppdebug.h | 30 +++---- src/netif/ppp/pppmy.c | 4 +- src/netif/ppp/pppmy.h | 174 ++++++++++++++++++++++++++++++++++++++- src/netif/ppp/utils.c | 10 ++- 6 files changed, 235 insertions(+), 26 deletions(-) diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 1b96012d..f1eb1f5c 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -110,7 +110,9 @@ 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 */ +#if 0 int log_to_fd = 1; /* send log messages to this fd too */ +#endif bool log_default = 1; /* log_to_fd is default (stdout) */ int maxfail = 10; /* max # of unsuccessful connection attempts */ char linkname[MAXPATHLEN]; /* logical name for link */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index ee535a2d..13eba6d7 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -44,6 +44,8 @@ #include "lwip/opt.h" +#include "pppmy.h" + /* * TODO: */ @@ -72,6 +74,7 @@ #include "eui64.h" #endif +#if 0 /* * Limits. */ @@ -81,7 +84,9 @@ #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 */ +#endif +#if 0 /* * Option descriptor structure. */ @@ -89,6 +94,7 @@ #ifndef bool typedef unsigned char bool; #endif +#endif #if 0 enum opt_type { @@ -183,12 +189,15 @@ struct pppd_stats { }; #endif +#if 0 /* Used for storing a sequence of words. Usually malloced. */ struct wordlist { struct wordlist *next; char *word; }; +#endif +#if 0 /* An endpoint discriminator, used with multilink. */ #define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ struct epdisc { @@ -204,6 +213,7 @@ struct epdisc { #define EPD_MAC 3 #define EPD_MAGIC 4 #define EPD_PHONENUM 5 +#endif #if 0 /* UNUSED */ typedef void (*notify_func) __P((void *, int)); @@ -363,6 +373,7 @@ extern bool ms_lanman; /* Use LanMan password instead of NT */ /* Has meaning only with MS-CHAP challenges */ #endif +#if 0 /* Values for auth_pending, auth_done */ #if PAP_SUPPORT #define PAP_WITHPEER 0x1 @@ -389,12 +400,16 @@ extern bool ms_lanman; /* Use LanMan password instead of NT */ #define CHAP_MS2_PEER 0x800 #endif /* MSCHAP_SUPPORT */ #endif /* CHAP_SUPPORT */ +#endif +#if 0 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 */ extern int option_priority; /* priority of current options */ +#endif +#if 0 /* * Values for phase. */ @@ -411,6 +426,7 @@ extern int option_priority; /* priority of current options */ #define PHASE_DISCONNECT 10 #define PHASE_HOLDOFF 11 #define PHASE_MASTER 12 +#endif #if 0 /* @@ -508,13 +524,16 @@ extern struct channel *the_channel; * Prototypes. */ +#if 0 /* Procedures exported from main.c. */ void set_ifunit __P((int)); /* set stuff that depends on ifunit */ +#endif #if 0 void detach __P((void)); /* Detach from controlling tty */ #endif +#if 0 void die __P((int)); /* Cleanup and exit */ void quit __P((void)); /* like die(1) */ void novm __P((char *)); /* Say we ran out of memory, and die */ @@ -522,6 +541,7 @@ void timeout __P((void (*func)(void *), void *arg, int s, int us)); /* Call func(arg) after s.us seconds */ void untimeout __P((void (*func)(void *), void *arg)); /* Cancel call to func(arg) */ +#endif #if 0 void record_child __P((int, char *, void (*) (void *), void *, int)); #endif @@ -553,11 +573,15 @@ void notify __P((struct notifier *, int)); //int ppp_send_config __P((int, int, u_int32_t, int, int)); //int ppp_recv_config __P((int, int, u_int32_t, int, int)); //void remove_pidfiles __P((void)); +#if 0 void lock_db __P((void)); void unlock_db __P((void)); +#endif +#if 0 /* Procedures exported from tty.c. */ void tty_init __P((void)); +#endif /* Procedures exported from utils.c. */ void log_packet __P((u_char *, int, char *, int)); @@ -794,6 +818,7 @@ extern void (*snoop_recv_hook) __P((unsigned char *p, int len)); extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #endif +#if 0 /* * Inline versions of get/put char/short/long. * Pointer is advanced; we assume that both arguments @@ -836,13 +861,8 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); /* * System dependent definitions for user-level 4.3BSD UNIX implementation. */ -/* #define TIMEOUT(r, f, t) timeout((r), (f), (t), 0) #define UNTIMEOUT(r, f) untimeout((r), (f)) -*/ -#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) -#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) -#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) #define BZERO(s, n) memset(s, 0, n) #define BCMP(s1, s2, l) memcmp(s1, s2, l) @@ -884,7 +904,10 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #define EXIT_TRAFFIC_LIMIT 20 #endif #define EXIT_CNID_AUTH_FAILED 21 +#endif + +#if 0 /* * Debug macros. Slightly useful for finding bugs in pppd, not particularly * useful for finding out why your connection isn't being established. @@ -899,6 +922,7 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #define DEBUGCHAP 1 #endif +#if 0 #ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */ #if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \ || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \ @@ -908,6 +932,7 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #define LOG_PPP LOG_DAEMON #endif #endif /* LOG_PPP */ +#endif #ifdef DEBUGMAIN #define MAINDEBUG(x) if (debug) dbglog x @@ -963,6 +988,9 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #define IPXCPDEBUG(x) #endif +#endif + +#if 0 #ifndef SIGTYPE #if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) #define SIGTYPE void @@ -970,9 +998,12 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #define SIGTYPE int #endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */ #endif /* SIGTYPE */ +#endif +#if 0 #ifndef offsetof #define offsetof(type, member) ((size_t) &((type *)0)->member) #endif +#endif #endif /* __PPP_H__ */ diff --git a/src/netif/ppp/pppdebug.h b/src/netif/ppp/pppdebug.h index 43f583ae..b8bae15f 100644 --- a/src/netif/ppp/pppdebug.h +++ b/src/netif/ppp/pppdebug.h @@ -45,26 +45,28 @@ #define LOG_DETAIL (PPP_DEBUG) #define LOG_DEBUG (PPP_DEBUG) -#define TRACELCP PPP_DEBUG - #if PPP_DEBUG -//#define AUTHDEBUG(a, b) LWIP_DEBUGF(a, b) -//#define IPCPDEBUG(a, b) LWIP_DEBUGF(a, b) -//#define UPAPDEBUG(a, b) LWIP_DEBUGF(a, b) -//#define LCPDEBUG(a, b) LWIP_DEBUGF(a, b) -//#define FSMDEBUG(a, b) LWIP_DEBUGF(a, b) -//#define CHAPDEBUG(a, b) LWIP_DEBUGF(a, b) +#define MAINDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define SYSDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define FSMDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define LCPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define IPCPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define IPV6CPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define UPAPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define CHAPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) #define PPPDEBUG(a, b) LWIP_DEBUGF(a, b) #else /* PPP_DEBUG */ -//#define AUTHDEBUG(a, b) -//#define IPCPDEBUG(a, b) -//#define UPAPDEBUG(a, b) -//#define LCPDEBUG(a, b) -//#define FSMDEBUG(a, b) -//#define CHAPDEBUG(a, b) +#define MAINDEBUG(a) +#define SYSDEBUG(a) +#define FSMDEBUG(a) +#define LCPDEBUG(a) +#define IPCPDEBUG(a) +#define IPV6CPDEBUG(a) +#define UPAPDEBUG(a) +#define CHAPDEBUG(a) #define PPPDEBUG(a, b) #endif /* PPP_DEBUG */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c index 38bed369..3dbb13a3 100644 --- a/src/netif/ppp/pppmy.c +++ b/src/netif/ppp/pppmy.c @@ -512,9 +512,11 @@ int ppp_init(void) { debug = 1; ifunit = 1; /* FIXME: remove ifunit */ - openlog("LWIP-PPP", LOG_PID | LOG_NDELAY, LOG_PPP); + /* + openlog("LWIP-PPP", LOG_PID | LOG_NDELAY, LOG_DAEMON); setlogmask(LOG_UPTO(LOG_DEBUG)); syslog(LOG_DEBUG, "hello, this is gradator lwIP PPP!"); + */ memset(&ppp_settings, 0, sizeof(ppp_settings)); ppp_settings.usepeerdns = 1; diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index d799514c..f53e031b 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -10,17 +10,51 @@ #ifndef PPPMY_H_ #define PPPMY_H_ -#include /* FIXME: temporary */ +#include "lwip/netif.h" +#include "lwip/def.h" + +#include "pppdebug.h" #include /* FIXME: merge linux/ppp_defs.h content here */ -#include "lwip/netif.h" -#include "lwip/def.h" +#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 */ #ifndef bool typedef unsigned char bool; #endif +/* FIXME: make endpoint discriminator optional */ + +/* An endpoint discriminator, used with multilink. */ +#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ +struct epdisc { + unsigned char class; + unsigned char length; + unsigned char value[MAX_ENDP_LEN]; +}; + +/* values for epdisc.class */ +#define EPD_NULL 0 /* null discriminator, no data */ +#define EPD_LOCAL 1 +#define EPD_IP 2 +#define EPD_MAC 3 +#define EPD_MAGIC 4 +#define EPD_PHONENUM 5 + /* FIXME: global variables per PPP session */ /* @@ -88,6 +122,51 @@ struct protent { extern struct protent *protocols[]; +/* Values for auth_pending, auth_done */ +#if PAP_SUPPORT +#define PAP_WITHPEER 0x1 +#define PAP_PEER 0x2 +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#define CHAP_WITHPEER 0x4 +#define CHAP_PEER 0x8 +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +#define EAP_WITHPEER 0x10 +#define EAP_PEER 0x20 +#endif /* EAP_SUPPORT */ + +/* Values for auth_done only */ +#if CHAP_SUPPORT +#define CHAP_MD5_WITHPEER 0x40 +#define CHAP_MD5_PEER 0x80 +#if MSCHAP_SUPPORT +#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ +#define CHAP_MS_WITHPEER 0x100 +#define CHAP_MS_PEER 0x200 +#define CHAP_MS2_WITHPEER 0x400 +#define CHAP_MS2_PEER 0x800 +#endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ + +/* + * 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 +#define PHASE_MASTER 12 + + /************************* *** PUBLIC DEFINITIONS *** *************************/ @@ -288,3 +367,92 @@ void update_link_stats(int u); /* Get stats at link termination */ #endif /* PPP_STATS_SUPPORT */ #endif /* PPPMY_H_ */ + + + +/* + * 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(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) +#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) +#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) + +#define BZERO(s, n) memset(s, 0, n) +#define BCMP(s1, s2, l) memcmp(s1, s2, l) + +#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 +#ifdef MAXOCTETS +#define EXIT_TRAFFIC_LIMIT 20 +#endif +#define EXIT_CNID_AUTH_FAILED 21 diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 72ec0911..2a95b81e 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -40,7 +40,7 @@ #include #include #include -#include +//#include #include #include #include @@ -557,7 +557,7 @@ end_pr_log() } /* - * pr_log - printer routine for outputting to syslog + * pr_log - printer routine for outputting to log */ void pr_log __V((void *arg, char *fmt, ...)) @@ -674,7 +674,10 @@ log_write(level, buf) int level; char *buf; { - syslog(level, "%s", buf); +/* FIXME: replace this with a log callback */ + // if(level >= min_log_level) /* FIXME: add a minimum log level */ + printf("LOG: %s\n", buf); +#if 0 if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { int n = strlen(buf); @@ -684,6 +687,7 @@ log_write(level, buf) || write(log_to_fd, "\n", 1) != 1) log_to_fd = -1; } +#endif } /* From 29c5ee6b197821d19eb10f2e19cf2769bd86689f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 19:19:51 +0200 Subject: [PATCH 076/320] pppd.h disabled, renamed MAX() to LWIP_MAX() --- src/netif/ppp/auth.c | 4 ++ src/netif/ppp/chap_ms.c | 2 +- src/netif/ppp/lcp.c | 2 +- src/netif/ppp/options.c | 6 +- src/netif/ppp/pppd.h | 35 ++++++++++- src/netif/ppp/pppmy.h | 125 +++++++++++++++++++++++++++++++++++++++- src/netif/ppp/utils.c | 2 + 7 files changed, 168 insertions(+), 8 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index cc5e9231..9088456a 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -104,8 +104,12 @@ #include "pppmy.h" #include "fsm.h" #include "lcp.h" +#if CCP_SUPPORT #include "ccp.h" +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT #include "ecp.h" +#endif /* ECP_SUPPORT */ #include "ipcp.h" #if PAP_SUPPORT #include "upap.h" diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 02b16675..98dba558 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -628,7 +628,7 @@ GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], sha1_finish(&sha1Context, Digest); /* Convert to ASCII hex string. */ - for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) + for (i = 0; i < LWIP_MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 9c21eb22..9754499d 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -2197,7 +2197,7 @@ lcp_up(f) * MTU we want to use, and our link MRU. */ mtu = ho->neg_mru? ho->mru: PPP_MRU; - mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; + mru = go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU; #ifdef HAVE_MULTILINK if (!(multilink && go->neg_mrru && ho->neg_mrru)) #endif /* HAVE_MULTILINK */ diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index f1eb1f5c..6e6b1915 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -50,7 +50,7 @@ #include #include #include -#include +//#include #include #include #ifdef PLUGIN @@ -95,7 +95,7 @@ struct option_value { 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 */ +//char devnam[MAXPATHLEN]; /* Device name */ bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ int maxconnect = 0; /* Maximum connect time */ @@ -115,7 +115,7 @@ int log_to_fd = 1; /* send log messages to this fd too */ #endif bool log_default = 1; /* log_to_fd is default (stdout) */ int maxfail = 10; /* max # of unsuccessful connection attempts */ -char linkname[MAXPATHLEN]; /* logical name for link */ +//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 */ int req_unit = -1; /* requested interface unit */ diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h index 13eba6d7..657cc915 100644 --- a/src/netif/ppp/pppd.h +++ b/src/netif/ppp/pppd.h @@ -42,6 +42,8 @@ * $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $ */ +#if 0 /* PPPD.H DISABLED */ + #include "lwip/opt.h" #include "pppmy.h" @@ -60,6 +62,7 @@ #include /* for struct timeval */ #include +#if 0 #if defined(__STDC__) #include #define __V(x) x @@ -74,6 +77,8 @@ #include "eui64.h" #endif +#endif + #if 0 /* * Limits. @@ -225,6 +230,7 @@ struct notifier { }; #endif /* UNUSED */ +#if 0 /* * Global variables. */ @@ -271,10 +277,13 @@ extern int ppp_session_number; /* Session number (eg PPPoE session) */ extern int fd_devnull; /* fd open to /dev/null */ //extern int listen_time; /* time to listen first (ms) */ + +#if 0 extern bool doing_multilink; extern bool multilink_master; extern bool bundle_eof; extern bool bundle_terminating; +#endif extern struct notifier *pidchange; /* for notifications of pid changing */ extern struct notifier *phasechange; /* for notifications of phase changes */ @@ -373,7 +382,11 @@ extern bool ms_lanman; /* Use LanMan password instead of NT */ /* Has meaning only with MS-CHAP challenges */ #endif +#endif + + #if 0 + /* Values for auth_pending, auth_done */ #if PAP_SUPPORT #define PAP_WITHPEER 0x1 @@ -400,6 +413,7 @@ extern bool ms_lanman; /* Use LanMan password instead of NT */ #define CHAP_MS2_PEER 0x800 #endif /* MSCHAP_SUPPORT */ #endif /* CHAP_SUPPORT */ + #endif #if 0 @@ -583,9 +597,8 @@ void unlock_db __P((void)); void tty_init __P((void)); #endif +#if 0 /* Procedures exported from utils.c. */ -void log_packet __P((u_char *, int, char *, int)); - /* Format a packet and log it with syslog */ void print_string __P((char *, int, void (*) (void *, char *, ...), void *)); /* Format a string for output */ int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ @@ -601,14 +614,18 @@ void fatal __P((char *, ...)); /* log an error message and die(1) */ void init_pr_log __P((const char *, int)); /* initialize for using pr_log */ void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ void end_pr_log __P((void)); /* finish up after using pr_log */ +#if PRINTPKT_SUPPORT void dump_packet __P((const char *, u_char *, int)); /* dump packet to debug log if interesting */ +#endif /* PRINTPKT_SUPPORT */ +#endif #if 0 /* Unused */ ssize_t complete_read __P((int, void *, size_t)); /* read a complete buffer */ #endif /* Unused */ +#if 0 /* Procedures exported from auth.c */ void link_required __P((int)); /* we are starting to use the link */ void start_link __P((int)); /* bring the link up now */ @@ -643,7 +660,9 @@ int auth_ip_addr __P((int, u_int32_t)); int auth_number __P((void)); /* check if remote number is authorized */ int bad_ip_adrs __P((u_int32_t)); /* check if IP address is unreasonable */ +#endif +#if 0 /* Procedures exported from demand.c */ #if DEMAND_SUPPORT void demand_conf __P((void)); /* config interface(s) for demand-dial */ @@ -654,7 +673,9 @@ void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ #endif /* DEMAND_SUPPORT */ +#endif +#if 0 /* Procedures exported from multilink.c */ #ifdef HAVE_MULTILINK void mp_check_options __P((void)); /* Check multilink-related options */ @@ -669,7 +690,9 @@ int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ #define doing_multilink 0 #define multilink_master 0 #endif +#endif +#if 0 /* Procedures exported from sys-*.c */ void sys_cleanup __P((void)); /* Restore system state before exiting */ int sys_check_options __P((void)); /* Check options specified */ @@ -756,7 +779,9 @@ int cipxfaddr __P((int)); #endif int get_if_hwaddr __P((u_char *addr, char *name)); char *get_first_ethernet __P((void)); +#endif +#if 0 /* Procedures exported from options.c */ #if 0 /* UNUSED */ int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */ @@ -788,8 +813,12 @@ int override_value __P((const char *, int, const char *)); void print_options __P((void (*) __P((void *, char *, ...)), void *)); /* print out values of all options */ #endif /* PPP_OPTIONS */ +#endif +#if 0 +/* Procedures exported from ipcp.c */ int parse_dotted_ip __P((char *, u_int32_t *)); +#endif /* * Hooks to enable plugins to change various things. @@ -1007,3 +1036,5 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #endif #endif /* __PPP_H__ */ + +#endif /* PPPD.H DISABLED */ diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/pppmy.h index f53e031b..00426892 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/pppmy.h @@ -21,7 +21,15 @@ #include "eui64.h" #endif - +#if defined(__STDC__) +#include +#define __V(x) x +#else +#include +#define __V(x) (va_alist) va_dcl +#define const +#define volatile +#endif /* * Limits. @@ -60,6 +68,18 @@ struct epdisc { /* * Global variables. */ +/* FIXME: improve debug flag */ +extern int debug; /* Debug flag */ + +/* FIXME: is our_name really necessary ? */ +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 */ + +/* FIXME: make it a compile time option */ +extern int idle_time_limit;/* Shut down link if idle for this long */ + +extern int phase; /* Current state of link - see values below */ extern int error_count; /* # of times error() has been called */ extern int unsuccess; /* # unsuccessful connection attempts */ extern int listen_time; /* time to listen first (ms) */ @@ -69,6 +89,35 @@ extern int need_holdoff; /* Need holdoff period after link terminates */ extern int ifunit; /* Interface unit number */ extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ +/* FIXME: add more HAVE_MULTILINK */ +extern bool multilink; /* enable multilink operation */ + +/* FIXME: it is really necessary ? */ +extern int maxconnect; /* Maximum connect time (seconds) */ + +#ifdef HAVE_MULTILINK +extern bool doing_multilink; +extern bool multilink_master; +extern bool bundle_eof; +extern bool bundle_terminating; +#endif + +#ifdef MAXOCTETS +extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ +extern int maxoctets_dir; /* Direction : + 0 - in+out (default) + 1 - in + 2 - out + 3 - max(in,out) */ +extern int maxoctets_timeout; /* Timeout for check of octets limit */ +#define PPP_OCTETS_DIRECTION_SUM 0 +#define PPP_OCTETS_DIRECTION_IN 1 +#define PPP_OCTETS_DIRECTION_OUT 2 +#define PPP_OCTETS_DIRECTION_MAXOVERAL 3 +/* same as previos, but little different on RADIUS side */ +#define PPP_OCTETS_DIRECTION_MAXSESSION 4 +#endif + /* * The following struct gives the addresses of procedures to call * for a particular protocol. @@ -456,3 +505,77 @@ void update_link_stats(int u); /* Get stats at link termination */ #define EXIT_TRAFFIC_LIMIT 20 #endif #define EXIT_CNID_AUTH_FAILED 21 + +/* Procedures exported from auth.c */ +void link_required __P((int)); /* we are starting to use the link */ +void link_terminated __P((int)); /* we are finished with the link */ +void link_down __P((int)); /* the LCP layer has left the Opened state */ +void upper_layers_down __P((int));/* take all NCPs down */ +void link_established __P((int)); /* the link is up; authenticate now */ +void start_networks __P((int)); /* start all the network control protos */ +void continue_networks __P((int)); /* start network [ip, etc] control protos */ + +void auth_peer_fail __P((int, int)); + /* peer failed to authenticate itself */ +void auth_peer_success __P((int, int, int, char *, int)); + /* peer successfully authenticated itself */ +void auth_withpeer_fail __P((int, int)); + /* we failed to authenticate ourselves */ +void auth_withpeer_success __P((int, int, int)); + /* we successfully authenticated ourselves */ +void np_up __P((int, int)); /* a network protocol has come up */ +void np_down __P((int, int)); /* a network protocol has gone down */ +void np_finished __P((int, int)); /* a network protocol no longer needs link */ +void auth_reset __P((int)); /* check what secrets we have */ +int get_secret __P((int, char *, char *, char *, int *, int)); + /* get "secret" for chap */ + +/* Procedures exported from ipcp.c */ +int parse_dotted_ip __P((char *, u_int32_t *)); + +/* Procedures exported from demand.c */ +#if DEMAND_SUPPORT +void demand_conf __P((void)); /* config interface(s) for demand-dial */ +void demand_block __P((void)); /* set all NPs to queue up packets */ +void demand_unblock __P((void)); /* set all NPs to pass packets */ +void demand_discard __P((void)); /* set all NPs to discard packets */ +void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ +int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ +int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ +#endif /* DEMAND_SUPPORT */ + +/* Procedures exported from multilink.c */ +#ifdef HAVE_MULTILINK +void mp_check_options __P((void)); /* Check multilink-related options */ +int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ +void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */ +void mp_bundle_terminated __P((void)); +char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ +int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ +#else +#define mp_bundle_terminated() /* nothing */ +#define mp_exit_bundle() /* nothing */ +#define doing_multilink 0 +#define multilink_master 0 +#endif + +/* Procedures exported from utils.c. */ +void print_string __P((char *, int, void (*) (void *, char *, ...), + void *)); /* Format a string for output */ +int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ +int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ +size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ +size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ +void dbglog __P((char *, ...)); /* log a debug message */ +void info __P((char *, ...)); /* log an informational message */ +void notice __P((char *, ...)); /* log a notice-level message */ +void warn __P((char *, ...)); /* log a warning message */ +void error __P((char *, ...)); /* log an error message */ +void fatal __P((char *, ...)); /* log an error message and die(1) */ +void init_pr_log __P((const char *, int)); /* initialize for using pr_log */ +void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ +void end_pr_log __P((void)); /* finish up after using pr_log */ +#if PRINTPKT_SUPPORT +void dump_packet __P((const char *, u_char *, int)); + /* dump packet to debug log if interesting */ +#endif /* PRINTPKT_SUPPORT */ diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 2a95b81e..6acbb72c 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -816,6 +816,7 @@ dbglog __V((char *fmt, ...)) va_end(pvar); } +#if PRINTPKT_SUPPORT /* * dump_packet - print out a packet in readable form if it is interesting. * Assumes len >= PPP_HDRLEN. @@ -845,6 +846,7 @@ dump_packet(const char *tag, unsigned char *p, int len) dbglog("%s %P", tag, p, len); } +#endif /* PRINTPKT_SUPPORT */ #if 0 /* Unused */ From 86ebc8e46c858c93d53bd6c37bdd921b2aa12ba0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 19:30:31 +0200 Subject: [PATCH 077/320] removed pppd.h and ppp.c, renamed pppmy.c to ppp.c and pppmy.h to ppp.h --- src/netif/ppp/auth.c | 4 +- src/netif/ppp/ccp.c | 4 +- src/netif/ppp/chap-md5.c | 5 +- src/netif/ppp/chap-new.c | 5 +- src/netif/ppp/chap_ms.c | 4 +- src/netif/ppp/demand.c | 4 +- src/netif/ppp/eap.c | 4 +- src/netif/ppp/ecp.c | 4 +- src/netif/ppp/fsm.c | 4 +- src/netif/ppp/ipcp.c | 4 +- src/netif/ppp/lcp.c | 4 +- src/netif/ppp/magic.c | 5 +- src/netif/ppp/multilink.c | 4 +- src/netif/ppp/options.c | 3 +- src/netif/ppp/ppp.c | 3136 ++++++++++++++---------------- src/netif/ppp/{pppmy.h => ppp.h} | 2 +- src/netif/ppp/ppp_oe.c | 5 +- src/netif/ppp/pppcrypt.c | 4 +- src/netif/ppp/pppd.h | 1040 ---------- src/netif/ppp/pppmy.c | 1560 --------------- src/netif/ppp/session.c | 5 +- src/netif/ppp/sys-linux.c | 4 +- src/netif/ppp/tty.c | 4 +- src/netif/ppp/upap.c | 4 +- src/netif/ppp/utils.c | 4 +- 25 files changed, 1466 insertions(+), 4360 deletions(-) rename src/netif/ppp/{pppmy.h => ppp.h} (99%) delete mode 100644 src/netif/ppp/pppd.h delete mode 100644 src/netif/ppp/pppmy.c diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 9088456a..b8c65355 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -100,8 +100,8 @@ #endif #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "lcp.h" #if CCP_SUPPORT diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 18676c59..5c1cac58 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -36,8 +36,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "ccp.h" #include diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 1a768836..e7ed182a 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -33,8 +33,9 @@ #include #include -#include "pppd.h" -#include "pppmy.h" + +#include "ppp.h" + #include "chap-new.h" #include "chap-md5.h" #include "magic.h" diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 2d2c409f..3319f0f5 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -35,8 +35,9 @@ #include #include -#include "pppd.h" -#include "pppmy.h" + +#include "ppp.h" + #include "session.h" #include "chap-new.h" #include "chap-md5.h" diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 98dba558..fa838d06 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -85,8 +85,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "chap-new.h" #include "chap_ms.h" #include "polarssl/md4.h" diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index 4e922cde..2b93b4ce 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -52,8 +52,8 @@ #include #endif -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "ipcp.h" #include "lcp.h" diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index f65185ad..7d3b2981 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -46,8 +46,8 @@ #include "lwip/opt.h" #if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "polarssl/md5.h" #include "eap.h" diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index 9d08c734..18b1d89f 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -66,8 +66,8 @@ static const char rcsid[] = RCSID; #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "ecp.h" diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index a63fc4e3..55030a02 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -54,8 +54,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" static const char rcsid[] = RCSID; diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 2dd1962d..70713701 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -58,8 +58,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "ipcp.h" diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 9754499d..5ee79659 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -50,8 +50,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "lcp.h" #if CHAP_SUPPORT diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index c5587ce5..ea92060c 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -75,11 +75,10 @@ #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#include "ppp.h" + #include "polarssl/md5.h" #include "magic.h" -#include "pppd.h" -#include "pppmy.h" - #if MD5_SUPPORT /* Using MD5 for better randomness if MD5 support is enabled */ diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 30d71aa3..792da323 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -50,8 +50,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "lcp.h" #include "tdb.h" diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 6e6b1915..620a2e6d 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -74,8 +74,7 @@ #endif #endif /* PPP_FILTER */ -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" #if defined(ultrix) || defined(NeXT) char *strdup __P((char *)); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 144943a1..df279dc4 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1,107 +1,26 @@ /* - * main.c - Point-to-Point Protocol main module + * ppp.c * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Copyright (c) 1999-2004 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * Created on: May 12, 2012 + * Author: gradator */ -#if 0 /* PPP.C DISABLED */ - #include "lwip/opt.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/sys.h" + +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ + +#include "ppp.h" -#include "pppd.h" -#include "pppmy.h" -#include "magic.h" #include "fsm.h" #include "lcp.h" #include "ipcp.h" -#ifdef INET6 -#include "ipv6cp.h" -#endif + #if PAP_SUPPORT #include "upap.h" #endif /* PAP_SUPPORT */ @@ -111,187 +30,44 @@ #if EAP_SUPPORT #include "eap.h" #endif /* EAP_SUPPORT */ +#if CCP_SUPPORT #include "ccp.h" +#endif /* EAP_SUPPORT */ +#if ECP_SUPPORT #include "ecp.h" +#endif /* EAP_SUPPORT */ -#if CBCP_SUPPORT -#include "cbcp.h" -#endif - -#ifdef AT_CHANGE -#include "atcp.h" -#endif - -#if 0 -/* interface vars */ -char ifname[32]; /* Interface name */ -int ifunit; /* Interface unit number */ -#endif - -#if 0 -struct channel *the_channel; -#endif - -#if 0 -char *progname; /* Name of this program */ -char hostname[MAXNAMELEN]; /* Our hostname */ -//static char pidfilename[MAXPATHLEN]; /* name of pid file */ -//static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ -char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ -uid_t uid; /* Our real user-id */ - -struct notifier *pidchange = NULL; -struct notifier *phasechange = NULL; -struct notifier *exitnotify = NULL; -struct notifier *sigreceived = NULL; -struct notifier *fork_notifier = NULL; -#endif - -#if 0 -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 */ -volatile int 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 */ -int ppp_session_number; /* Session number, for channels with such a - concept (eg PPPoE) */ -int childwait_done; /* have timed out waiting for children */ -#endif - -#if 0 -char db_key[32]; -#endif - -#if 0 -int (*holdoff_hook) __P((void)) = NULL; -int (*new_phase_hook) __P((int)) = NULL; -void (*snoop_recv_hook) __P((unsigned char *p, int len)) = NULL; -void (*snoop_send_hook) __P((unsigned char *p, int len)) = NULL; -#endif - -#if 0 -static int conn_running; /* we have a [dis]connector running */ -static int fd_loop; /* fd for getting demand-dial packets */ -#endif - -#if 0 -int fd_devnull; /* fd for /dev/null */ -int devfd = -1; /* fd of underlying device */ -int fd_ppp = -1; /* fd for talking PPP */ -//int phase; /* where the link is at */ -int kill_link; -int asked_to_quit; -int open_ccp_flag; -int listen_time; -int got_sigusr2; -int got_sigterm; -int got_sighup; -#endif - -#if 0 -static sigset_t signals_handled; -static int waiting; -static sigjmp_buf sigjmp; - -char **script_env; /* Env. variable values for scripts */ -int s_env_nalloc; /* # words avail at script_env */ -#endif - -#if 0 -u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ -u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ -#endif - -#if 0 -static int n_children; /* # child processes still running */ -static int got_sigchld; /* set if we have received a SIGCHLD */ - -int privopen; /* don't lock, open device as root */ - -char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; -#endif - -#if 0 /* UNUSED */ -GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ -int ngroups; /* How many groups valid in groups */ -#endif /* UNUSED */ - -#if 0 -//static struct timeval start_time; /* Time when link was started. */ - -//static struct pppd_stats old_link_stats; -//struct pppd_stats link_stats; -//unsigned link_connect_time; -//int link_stats_valid; - -int error_count; - -bool bundle_eof; -bool bundle_terminating; /* - * We maintain a list of child process pids and - * functions to call when they exit. + * Global variables. */ -struct subprocess { - pid_t pid; - char *prog; - void (*done) __P((void *)); - void *arg; - int killable; - struct subprocess *next; -}; +/* FIXME: global variables per PPP session */ +/* FIXME: clean global variables */ +int phase; /* where the link is at */ +int error_count; /* # of times error() has been called */ +int unsuccess; /* # unsuccessful connection attempts */ +int listen_time; /* time to listen first (ms) */ +int status; /* exit status for pppd */ +int need_holdoff; /* need holdoff period before restarting */ +/* FIXME: remove ifunit */ +int ifunit; /* Interface unit number */ -static struct subprocess *children; -#endif +/* FIXME: outpacket_buf per PPP session */ +u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ -/* Prototypes for procedures local to this file. */ +#if PPPOS_SUPPORT +u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ +#endif /* PPPOS_SUPPORT */ -//static void setup_signals __P((void)); -//static void create_pidfile __P((int pid)); -//static void create_linkpidfile __P((int pid)); -//static void cleanup __P((void)); -#if 0 -static void get_input __P((void)); -static void calltimeout __P((void)); -static struct timeval *timeleft __P((struct timeval *)); -static void kill_my_pg __P((int)); -static void hup __P((int)); -static void term __P((int)); -static void chld __P((int)); -static void toggle_debug __P((int)); -static void open_ccp __P((int)); -static void bad_signal __P((int)); -static void holdoff_end __P((void *)); -static void forget_child __P((int pid, int status)); -static int reap_kids __P((void)); -static void childwait_end __P((void *)); +/* FIXME: add stats per PPP session */ +#if PPP_STATS_SUPPORT +static struct timeval start_time; /* Time when link was started. */ +static struct pppd_stats old_link_stats; +struct pppd_stats link_stats; +unsigned link_connect_time; +int link_stats_valid; +#endif /* PPP_STATS_SUPPORT */ -static void handle_events __P((void)); -#endif -#if 0 -void print_link_stats __P((void)); -#endif - -#if 0 -extern char *ttyname __P((int)); -extern char *getlogin __P((void)); -//int main __P((int, char *[])); -#endif - -#ifdef ultrix -#undef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - -#ifdef ULTRIX -#define setlogmask(x) -#endif - -#if 0 /* * PPP Data Link Layer "protocol" table. * One entry per supported protocol. @@ -326,52 +102,423 @@ struct protent *protocols[] = { #endif /* EAP_SUPPORT */ NULL }; -#endif -#if 0 +/* PPP packet parser states. Current state indicates operation yet to be + * completed. */ +typedef enum { + PDIDLE = 0, /* Idle state - waiting. */ + PDSTART, /* Process start flag. */ + PDADDRESS, /* Process address field. */ + PDCONTROL, /* Process control field. */ + PDPROTOCOL1, /* Process protocol field 1. */ + PDPROTOCOL2, /* Process protocol field 2. */ + PDDATA /* Process data byte. */ +} PPPDevStates; + +typedef struct PPPControlRx_s { + /** unit number / ppp descriptor */ + int pd; + /** the rx file descriptor */ +#if PPPOS_SUPPORT /* FIXME: enable sio_fd_t back */ + sio_fd_t fd; +#endif +#if PPPOE_SUPPORT + int fd; +#endif + /** receive buffer - encoded data is stored here */ +#if PPP_INPROC_OWNTHREAD + u_char rxbuf[PPPOS_RX_BUFSIZE]; +#endif /* PPP_INPROC_OWNTHREAD */ + + /* The input packet. */ + struct pbuf *inHead, *inTail; + +#if PPPOS_SUPPORT + u16_t inProtocol; /* The input protocol code. */ + u16_t inFCS; /* Input Frame Check Sequence value. */ +#endif /* PPPOS_SUPPORT */ + PPPDevStates inState; /* The input process state. */ + char inEscaped; /* Escape next character. */ + ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ +} PPPControlRx; + /* - * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. + * PPP interface control block. */ -#if !defined(PPP_DRV_NAME) -#define PPP_DRV_NAME "ppp" -#endif /* !defined(PPP_DRV_NAME) */ +typedef struct PPPControl_s { + PPPControlRx rx; + char openFlag; /* True when in use. */ +#if PPPOE_SUPPORT + struct netif *ethif; + struct pppoe_softc *pppoe_sc; +#endif /* PPPOE_SUPPORT */ + int if_up; /* True when the interface is up. */ + int errCode; /* Code indicating why interface is down. */ +#if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ +#endif /* PPPOS_SUPPORT */ + u16_t mtu; /* Peer's mru */ + int pcomp; /* Does peer accept protocol compression? */ + int accomp; /* Does peer accept addr/ctl compression? */ + u_long lastXMit; /* Time of last transmission. */ + ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ +#if PPPOS_SUPPORT && VJ_SUPPORT + int vjEnabled; /* Flag indicating VJ compression enabled. */ + struct vjcompress vjComp; /* Van Jacobson compression header. */ +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + struct netif netif; + + struct ppp_addrs addrs; + + void (*linkStatusCB)(void *ctx, int errCode, void *arg); + void *linkStatusCtx; + +} PPPControl; + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ +static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ + + +struct pbuf * pppSingleBuf(struct pbuf *p) { + struct pbuf *q, *b; + u_char *pl; + + if(p->tot_len == p->len) { + return p; + } + + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(!q) { + PPPDEBUG(LOG_ERR, + ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); + return p; /* live dangerously */ + } + + for(b = p, pl = q->payload; b != NULL; b = b->next) { + MEMCPY(pl, b->payload, b->len); + pl += b->len; + } + + pbuf_free(p); + + return q; +} + +/** Input helper struct, must be packed since it is stored to pbuf->payload, + * which might be unaligned. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppInputHeader { + PACK_STRUCT_FIELD(int unit); + PACK_STRUCT_FIELD(u16_t proto); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" #endif -#if 0 -int ppp_oldmain() { - int argc = 0; - char *argv[0]; - int i, t; - char *p; - struct passwd *pw; - struct protent *protp; - char numbuf[16]; - link_stats_valid = 0; - new_phase(PHASE_INITIALIZE); +/** Initiate LCP open request */ +static void pppStart(int pd) { + PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd)); + lcp_open(pd); /* Start protocol */ + lcp_lowerup(pd); + PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n")); +} - script_env = NULL; - /* Initialize syslog facilities */ - reopen_log(); +/* + * Pass the processed input packet to the appropriate handler. + * This function and all handlers run in the context of the tcpip_thread + */ - if (gethostname(hostname, MAXNAMELEN) < 0 ) { - option_error("Couldn't get hostname: %m"); - exit(1); - } - hostname[MAXNAMELEN-1] = 0; +/* FIXME: maybe we should pass in two arguments pppInputHeader and payload + * this is totally stupid to make room for it and then modify the packet directly + * or it is used in output ? have to find out... + */ +static void ppp_input(void *arg) { + struct pbuf *nb = (struct pbuf *)arg; + u16_t protocol; + int pd; - /* make sure we don't create world or group writable files. */ - umask(umask(0777) | 022); + pd = ((struct pppInputHeader *)nb->payload)->unit; + protocol = ((struct pppInputHeader *)nb->payload)->proto; + printf("ppp_input() called, pd = %d, protocol = 0x%x\n", pd, protocol); - uid = getuid(); - privileged = uid == 0; - slprintf(numbuf, sizeof(numbuf), "%d", uid); - script_setenv("ORIG_UID", numbuf, 0); + if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } -#if 0 /* UNUSED */ - ngroups = getgroups(NGROUPS_MAX, groups); + LINK_STATS_INC(link.recv); + snmp_inc_ifinucastpkts(&pppControl[pd].netif); + snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); + + /* + * Toss all non-LCP packets unless LCP is OPEN. + */ + if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { + dbglog("Discarded non-LCP packet when LCP not open"); + return; + } + + /* FIXME: add a phase per connection */ + + /* + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if (phase <= PHASE_AUTHENTICATE + && !(protocol == PPP_LCP || protocol == PPP_LQR +#if PAP_SUPPORT + || protocol == PPP_PAP +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + || protocol == PPP_CHAP +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || protocol == PPP_EAP +#endif /* EAP_SUPPORT */ + )) { + dbglog("discarding proto 0x%x in phase %d", + protocol, phase); + return; + } + + /* FIXME: should we write protent to do that ? */ + + switch(protocol) { + case PPP_VJC_COMP: /* VJ compressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, + ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", + pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_IP: /* Internet Protocol */ + printf("IP packet received\n"); + PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + if (pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + break; + + default: { + + int i; + struct protent *protp; + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + nb = pppSingleBuf(nb); + (*protp->input)(pd, nb->payload, nb->len); + goto out; + } +#if 0 /* UNUSED + * + * This is actually a (hacked?) way for the PPP kernel implementation to pass a + * data packet to the PPP daemon. The PPP daemon normally only do signaling + * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. + * + * This is only used by CCP, which we cannot support until we have a CCP data + * implementation. + */ + if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag + && protp->datainput != NULL) { + (*protp->datainput)(pd, nb->payload, nb->len); + goto out; + } #endif /* UNUSED */ + } + + if (debug) { +#if PPP_PROTOCOLNAME + const char *pname = protocol_name(protocol); + if (pname != NULL) + warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); + else +#endif /* PPP_PROTOCOLNAME */ + warn("Unsupported protocol 0x%x received", protocol); + } + if (pbuf_header(nb, sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + lcp_sprotrej(pd, nb->payload, nb->len); + } + break; + } + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pd].netif); + +out: + pbuf_free(nb); + return; + + #if 0 + /* + * Toss all non-LCP packets unless LCP is OPEN. + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { + if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || + (lcp_phase[pd] != PHASE_AUTHENTICATE)) { + PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); + goto drop; + } + } + + switch(protocol) { + case PPP_VJC_COMP: /* VJ compressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, + ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", + pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_IP: /* Internet Protocol */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + if (pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + break; + + default: { + struct protent *protp; + int i; + + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); + nb = pppSingleBuf(nb); + (*protp->input)(pd, nb->payload, nb->len); + PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); + goto out; + } + } + + /* No handler for this protocol so reject the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); + if (pbuf_header(nb, sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } +#if BYTE_ORDER == LITTLE_ENDIAN + protocol = htons(protocol); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + SMEMCPY(nb->payload, &protocol, sizeof(protocol)); + lcp_sprotrej(pd, nb->payload, nb->len); + } + break; + } +#endif + + +} + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* Initialize the PPP subsystem. */ + +int ppp_init(void) { + int i; + struct protent *protp; + + debug = 1; + ifunit = 1; /* FIXME: remove ifunit */ + + /* + openlog("LWIP-PPP", LOG_PID | LOG_NDELAY, LOG_DAEMON); + setlogmask(LOG_UPTO(LOG_DEBUG)); + syslog(LOG_DEBUG, "hello, this is gradator lwIP PPP!"); + */ + + memset(&ppp_settings, 0, sizeof(ppp_settings)); + ppp_settings.usepeerdns = 1; + pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL); /* * Initialize magic number generator now so that protocols may @@ -384,725 +531,1019 @@ int ppp_oldmain() { */ for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(0); - -#if 0 - /* - * Initialize the default channel. - */ - tty_init(); -#endif - - progname = *argv; - -#if PPP_OPTIONS - /* - * Parse, in order, the system options file, the user's options file, - * and the command line arguments. - */ - if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) - || !options_from_user() - || !parse_args(argc-1, argv+1)) - exit(EXIT_OPTION_ERROR); -#endif /* PPP_OPTIONS */ - - devnam_fixed = 1; /* can no longer change device name */ - -#if 0 /* UNUSED */ - /* - * Work out the device name, if it hasn't already been specified, - * and parse the tty's options file. - */ - if (the_channel->process_extra_options) - (*the_channel->process_extra_options)(); -#endif /* UNUSED */ - - if (debug) - setlogmask(LOG_UPTO(LOG_DEBUG)); - -#if 0 - /* - * Check that we are running as root. - */ - if (geteuid() != 0) { - option_error("must be root to run %s, since it is not setuid-root", - argv[0]); - exit(EXIT_NOT_ROOT); - } -#endif - -#if PPP_OPTIONS - /* - * Check that the options given are valid and consistent. - */ - check_options(); - if (!sys_check_options()) - exit(EXIT_OPTION_ERROR); - auth_check_options(); -#ifdef HAVE_MULTILINK - mp_check_options(); -#endif - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->check_options != NULL) - (*protp->check_options)(); - if (the_channel->check_options) - (*the_channel->check_options)(); - - - if (dump_options || dryrun) { - init_pr_log(NULL, LOG_INFO); - print_options(pr_log, NULL); - end_pr_log(); - } -#endif /* PPP_OPTIONS */ - -#if 0 - if (dryrun) - die(0); -#endif - - /* Make sure fds 0, 1, 2 are open to somewhere. */ - fd_devnull = open(_PATH_DEVNULL, O_RDWR); - if (fd_devnull < 0) - fatal("Couldn't open %s: %m", _PATH_DEVNULL); - while (fd_devnull <= 2) { - i = dup(fd_devnull); - if (i < 0) - fatal("Critical shortage of file descriptors: dup failed: %m"); - fd_devnull = i; - } - -#if 0 /* Unused */ - /* - * Detach ourselves from the terminal, if required, - * and identify who is running us. - */ - if (!nodetach && !updetach) - detach(); -#endif /* Unused */ - - p = getlogin(); - if (p == NULL) { - pw = getpwuid(uid); - if (pw != NULL && pw->pw_name != NULL) - p = pw->pw_name; - else - p = "(unknown)"; - } - syslog(LOG_NOTICE, "pppd started by %s, uid %d", p, uid); - script_setenv("PPPLOGNAME", p, 0); - - if (devnam[0]) - script_setenv("DEVICE", devnam, 1); - slprintf(numbuf, sizeof(numbuf), "%d", getpid()); - script_setenv("PPPD_PID", numbuf, 1); - - //setup_signals(); - - create_linkpidfile(getpid()); - - waiting = 0; - - /* - * If we're doing dial-on-demand, set up the interface now. - */ - if (demand) { - /* - * Open the loopback channel and set it up to be the ppp interface. - */ - //fd_loop = open_ppp_loopback(); - //set_ifunit(1); - /* - * Configure the interface and mark it up, etc. - */ - demand_conf(); - } - - do_callback = 0; - for (;;) { - - bundle_eof = 0; - bundle_terminating = 0; - listen_time = 0; - need_holdoff = 1; - devfd = -1; - status = EXIT_OK; - ++unsuccess; - doing_callback = do_callback; - do_callback = 0; - - if (demand && !doing_callback) { - /* - * Don't do anything until we see some activity. - */ - new_phase(PHASE_DORMANT); - demand_unblock(); - add_fd(fd_loop); - for (;;) { - handle_events(); - if (asked_to_quit) - break; - if (get_loop_output()) - break; - } - remove_fd(fd_loop); - if (asked_to_quit) - break; - - /* - * Now we want to bring up the link. - */ - demand_block(); - info("Starting link"); - } - - gettimeofday(&start_time, NULL); - script_unsetenv("CONNECT_TIME"); - script_unsetenv("BYTES_SENT"); - script_unsetenv("BYTES_RCVD"); - - lcp_open(0); /* Start protocol */ - //start_link(0); - while (phase != PHASE_DEAD) { - handle_events(); - get_input(); - if (kill_link) - lcp_close(0, "User request"); - if (asked_to_quit) { - bundle_terminating = 1; - if (phase == PHASE_MASTER) - mp_bundle_terminated(); - } - if (open_ccp_flag) { - if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { - ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ - (*ccp_protent.open)(0); - } - } - } - /* restore FSMs to original state */ - lcp_close(0, ""); - - if (!persist || asked_to_quit || (maxfail > 0 && unsuccess >= maxfail)) - break; - - 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 { - handle_events(); - if (kill_link) - new_phase(PHASE_DORMANT); /* allow signal to end holdoff */ - } while (phase == PHASE_HOLDOFF); - if (!persist) - break; - } - } - - /* Wait for scripts to finish */ - reap_kids(); - if (n_children > 0) { - if (child_wait > 0) - TIMEOUT(childwait_end, NULL, child_wait); - if (debug) { - struct subprocess *chp; - dbglog("Waiting for %d child processes...", n_children); - for (chp = children; chp != NULL; chp = chp->next) - dbglog(" script %s, pid %d", chp->prog, chp->pid); - } - while (n_children > 0 && !childwait_done) { - handle_events(); - if (kill_link && !childwait_done) - childwait_end(NULL); - } - } - - die(status); - return 0; -} -#endif - -#if 0 -/* - * handle_events - wait for something to happen and respond to it. - */ -static void -handle_events() -{ - struct timeval timo; - - kill_link = open_ccp_flag = 0; - if (sigsetjmp(sigjmp, 1) == 0) { - sigprocmask(SIG_BLOCK, &signals_handled, NULL); - if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) { - sigprocmask(SIG_UNBLOCK, &signals_handled, NULL); - } else { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &signals_handled, NULL); - wait_input(timeleft(&timo)); - } - } - waiting = 0; - calltimeout(); - if (got_sighup) { - info("Hangup (SIGHUP)"); - kill_link = 1; - got_sighup = 0; - if (status != EXIT_HANGUP) - status = EXIT_USER_REQUEST; - } - if (got_sigterm) { - info("Terminating on signal %d", got_sigterm); - kill_link = 1; - asked_to_quit = 1; - persist = 0; - status = EXIT_USER_REQUEST; - got_sigterm = 0; - } - if (got_sigchld) { - got_sigchld = 0; - reap_kids(); /* Don't leave dead kids lying around */ - } - if (got_sigusr2) { - open_ccp_flag = 1; - got_sigusr2 = 0; - } -} -#endif - -#if 0 -/* - * setup_signals - initialize signal handling. - */ -static void -setup_signals() -{ - struct sigaction sa; - - /* - * Compute mask of all interesting signals and install signal handlers - * for each. Only one signal handler may be active at a time. Therefore, - * all other signals should be masked when any handler is executing. - */ - sigemptyset(&signals_handled); - sigaddset(&signals_handled, SIGHUP); - sigaddset(&signals_handled, SIGINT); - sigaddset(&signals_handled, SIGTERM); - sigaddset(&signals_handled, SIGCHLD); - sigaddset(&signals_handled, SIGUSR2); - -#define SIGNAL(s, handler) do { \ - sa.sa_handler = handler; \ - if (sigaction(s, &sa, NULL) < 0) \ - fatal("Couldn't establish signal handler (%d): %m", s); \ - } while (0) - - sa.sa_mask = signals_handled; - sa.sa_flags = 0; - SIGNAL(SIGHUP, hup); /* Hangup */ - SIGNAL(SIGINT, term); /* Interrupt */ - SIGNAL(SIGTERM, term); /* Terminate */ - SIGNAL(SIGCHLD, chld); - - SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ - SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ - - /* - * Install a handler for other signals which would otherwise - * cause pppd to exit without cleaning up. - */ - SIGNAL(SIGABRT, bad_signal); - SIGNAL(SIGALRM, bad_signal); - SIGNAL(SIGFPE, bad_signal); - SIGNAL(SIGILL, bad_signal); - SIGNAL(SIGPIPE, bad_signal); - SIGNAL(SIGQUIT, bad_signal); - SIGNAL(SIGSEGV, bad_signal); -#ifdef SIGBUS - SIGNAL(SIGBUS, bad_signal); -#endif -#ifdef SIGEMT - SIGNAL(SIGEMT, bad_signal); -#endif -#ifdef SIGPOLL - SIGNAL(SIGPOLL, bad_signal); -#endif -#ifdef SIGPROF - SIGNAL(SIGPROF, bad_signal); -#endif -#ifdef SIGSYS - SIGNAL(SIGSYS, bad_signal); -#endif -#ifdef SIGTRAP - SIGNAL(SIGTRAP, bad_signal); -#endif -#ifdef SIGVTALRM - SIGNAL(SIGVTALRM, bad_signal); -#endif -#ifdef SIGXCPU - SIGNAL(SIGXCPU, bad_signal); -#endif -#ifdef SIGXFSZ - SIGNAL(SIGXFSZ, bad_signal); -#endif - - /* - * Apparently we can get a SIGPIPE when we call syslog, if - * syslogd has died and been restarted. Ignoring it seems - * be sufficient. - */ - signal(SIGPIPE, SIG_IGN); -} -#endif - -#if 0 -/* - * set_ifunit - do things we need to do once we know which ppp - * unit we are using. - */ -void -set_ifunit(iskey) - int iskey; -{ - info("Using interface %s%d", PPP_DRV_NAME, ifunit); - slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); - script_setenv("IFNAME", ifname, iskey); - if (iskey) { -// create_pidfile(getpid()); /* write pid to file */ -// create_linkpidfile(getpid()); - } -} -#endif - -#if 0 -/* - * detach - detach us from the controlling terminal. - */ -void -detach() -{ - int pid; - char numbuf[16]; - int pipefd[2]; - - if (detached) - return; - if (pipe(pipefd) == -1) - pipefd[0] = pipefd[1] = -1; - if ((pid = fork()) < 0) { - error("Couldn't detach (fork failed: %m)"); - die(1); /* or just return? */ - } - if (pid != 0) { - /* parent */ - notify(pidchange, pid); - /* update pid files if they have been written already */ - if (pidfilename[0]) - create_pidfile(pid); - if (linkpidfile[0]) - create_linkpidfile(pid); - exit(0); /* parent dies */ - } - setsid(); - chdir("/"); - dup2(fd_devnull, 0); - dup2(fd_devnull, 1); - dup2(fd_devnull, 2); - detached = 1; - if (log_default) - log_to_fd = -1; - slprintf(numbuf, sizeof(numbuf), "%d", getpid()); - script_setenv("PPPD_PID", numbuf, 1); - - /* wait for parent to finish updating pid & lock files and die */ - close(pipefd[1]); - complete_read(pipefd[0], numbuf, 1); - close(pipefd[0]); -} -#endif - -#if 0 -/* - * reopen_log - (re)open our connection to syslog. - */ -void -reopen_log() -{ - openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); - setlogmask(LOG_UPTO(LOG_INFO)); -} -#endif - -#if 0 -/* - * Create a file containing our process ID. - */ -static void -create_pidfile(pid) - int pid; -{ - FILE *pidfile; - - slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid", - _PATH_VARRUN, ifname); - if ((pidfile = fopen(pidfilename, "w")) != NULL) { - fprintf(pidfile, "%d\n", pid); - (void) fclose(pidfile); - } else { - error("Failed to create pid file %s: %m", pidfilename); - pidfilename[0] = 0; - } -} -#endif - -#if 0 -void -create_linkpidfile(pid) - int pid; -{ - FILE *pidfile; - - if (linkname[0] == 0) - return; - script_setenv("LINKNAME", linkname, 1); - slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid", - _PATH_VARRUN, linkname); - if ((pidfile = fopen(linkpidfile, "w")) != NULL) { - fprintf(pidfile, "%d\n", pid); - if (ifname[0]) - fprintf(pidfile, "%s\n", ifname); - (void) fclose(pidfile); - } else { - error("Failed to create pid file %s: %m", linkpidfile); - linkpidfile[0] = 0; - } } -/* - * remove_pidfile - remove our pid files - */ -void remove_pidfiles() -{ - if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) - warn("unable to delete pid file %s: %m", pidfilename); - pidfilename[0] = 0; - if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) - warn("unable to delete pid file %s: %m", linkpidfile); - linkpidfile[0] = 0; -} -#endif +void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { + /* FIXME: the following may look stupid, but this is just an easy way + * to check different auth by changing compile time option + */ +#if PAP_SUPPORT + ppp_settings.refuse_pap = 0; +#endif /* PAP_SUPPORT */ -#if 0 -/* - * holdoff_end - called via a timeout when the holdoff period ends. - */ -static void -holdoff_end(arg) - void *arg; -{ - new_phase(PHASE_DORMANT); -} -#endif - -#if 0 -/* - * get_input - called when incoming data is available. - */ -static void -get_input() -{ - int len, i; - u_char *p; - u_short protocol; - struct protent *protp; - - p = inpacket_buf; /* point to beginning of packet buffer */ - - len = read_packet(inpacket_buf); - if (len < 0) - return; - - if (len == 0) { - if (bundle_eof && multilink_master) { - notice("Last channel has disconnected"); - mp_bundle_terminated(); - return; - } - notice("Modem hangup"); - hungup = 1; - status = EXIT_HANGUP; - lcp_lowerdown(0); /* serial link is no longer available */ - link_terminated(0); - return; - } - - if (len < PPP_HDRLEN) { - dbglog("received short packet:%.*B", len, p); - return; - } - - dump_packet("rcvd", p, len); - if (snoop_recv_hook) snoop_recv_hook(p, len); - - 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) { - dbglog("Discarded non-LCP packet when LCP not open"); - return; - } - - /* - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if (phase <= PHASE_AUTHENTICATE - && !(protocol == PPP_LCP || protocol == PPP_LQR - || protocol == PPP_PAP #if CHAP_SUPPORT - || protocol == PPP_CHAP +#if PAP_SUPPORT + ppp_settings.refuse_pap = 1; +#endif /* PAP_SUPPORT */ + ppp_settings.refuse_chap = 0; #endif /* CHAP_SUPPORT */ + +#if MSCHAP_SUPPORT +#if PAP_SUPPORT + ppp_settings.refuse_pap = 1; +#endif /* PAP_SUPPORT */ + ppp_settings.refuse_chap = 1; + ppp_settings.refuse_mschap = 1; + ppp_settings.refuse_mschap_v2 = 0; +#endif /* MSCHAP_SUPPORT */ + #if EAP_SUPPORT - || protocol == PPP_EAP +#if PAP_SUPPORT + ppp_settings.refuse_pap = 1; +#endif/* PAP_SUPPORT */ +#if CHAP_SUPPORT + ppp_settings.refuse_chap = 1; +#if MSCHAP_SUPPORT + ppp_settings.refuse_mschap = 1; + ppp_settings.refuse_mschap_v2 = 1; +#endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ + ppp_settings.refuse_eap = 0; #endif /* EAP_SUPPORT */ - )) { - dbglog("discarding proto 0x%x in phase %d", - protocol, phase); - return; + +/* FIXME: re-enable that */ +#if 0 + switch(authType) { + case PPPAUTHTYPE_NONE: + default: +#ifdef LWIP_PPP_STRICT_PAP_REJECT + ppp_settings.refuse_pap = 1; +#else /* LWIP_PPP_STRICT_PAP_REJECT */ + /* some providers request pap and accept an empty login/pw */ + ppp_settings.refuse_pap = 0; +#endif /* LWIP_PPP_STRICT_PAP_REJECT */ + ppp_settings.refuse_chap = 1; + break; + + case PPPAUTHTYPE_ANY: + /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. + * RFC 1994 says: + * + * In practice, within or associated with each PPP server, there is a + * database which associates "user" names with authentication + * information ("secrets"). It is not anticipated that a particular + * named user would be authenticated by multiple methods. This would + * make the user vulnerable to attacks which negotiate the least secure + * method from among a set (such as PAP rather than CHAP). If the same + * secret was used, PAP would reveal the secret to be used later with + * CHAP. + * + * Instead, for each user name there should be an indication of exactly + * one method used to authenticate that user name. If a user needs to + * make use of different authentication methods under different + * circumstances, then distinct user names SHOULD be employed, each of + * which identifies exactly one authentication method. + * + */ + ppp_settings.refuse_pap = 0; + ppp_settings.refuse_chap = 0; + break; + + case PPPAUTHTYPE_PAP: + ppp_settings.refuse_pap = 0; + ppp_settings.refuse_chap = 1; + break; + + case PPPAUTHTYPE_CHAP: + ppp_settings.refuse_pap = 1; + ppp_settings.refuse_chap = 0; + break; + } +#endif + + if(user) { + strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); + ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0'; + } else { + ppp_settings.user[0] = '\0'; + } + + if(passwd) { + strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1); + ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0'; + } else { + ppp_settings.passwd[0] = '\0'; + } +} + +#if PPPOE_SUPPORT +static void pppOverEthernetLinkStatusCB(int pd, int up); + +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, + pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) +{ + PPPControl *pc; + int pd; + + LWIP_UNUSED_ARG(service_name); + LWIP_UNUSED_ARG(concentrator_name); + + if (linkStatusCB == NULL) { + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + return PPPERR_PARAM; + } + + /* Find a free PPP session descriptor. Critical region? */ + for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + if (pd >= NUM_PPP) { + pd = PPPERR_OPEN; + } else { + pc = &pppControl[pd]; + memset(pc, 0, sizeof(PPPControl)); + pc->openFlag = 1; + pc->ethif = ethif; + + pc->linkStatusCB = linkStatusCB; + pc->linkStatusCtx = linkStatusCtx; + + lcp_wantoptions[pd].mru = PPPOE_MAXMTU; + lcp_wantoptions[pd].neg_asyncmap = 0; + lcp_wantoptions[pd].neg_pcompression = 0; + lcp_wantoptions[pd].neg_accompression = 0; + + lcp_allowoptions[pd].mru = PPPOE_MAXMTU; + lcp_allowoptions[pd].neg_asyncmap = 0; + lcp_allowoptions[pd].neg_pcompression = 0; + lcp_allowoptions[pd].neg_accompression = 0; + + if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) { + pc->openFlag = 0; + return PPPERR_OPEN; } - /* - * 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; - } - } + pppoe_connect(pc->pppoe_sc); + } - 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 pd; +} + +/* FIXME: maybe we should pass in two arguments pppInputHeader and payload + * this is totally stupid to make room for it and then modify the packet directly + * or it is used in output ? have to find out... + */ +void pppInProcOverEthernet(int pd, struct pbuf *pb) { + struct pppInputHeader *pih; + u16_t inProtocol; + + if(pb->len < sizeof(inProtocol)) { + PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n")); + goto drop; + } + + inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; + printf("pppInProcOverEthernet() called, pd = %d, inprotocol = 0x%x\n", pd, inProtocol); + + /* make room for pppInputHeader - should not fail */ + if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { + PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n")); + goto drop; + } + + pih = pb->payload; + + pih->unit = pd; + pih->proto = inProtocol; + + /* Dispatch the packet thereby consuming it. */ + ppp_input(pb); + return; + +drop: + LINK_STATS_INC(link.drop); +// snmp_inc_ifindiscards(&pppControl[pd].netif); + pbuf_free(pb); + return; +} + +void pppOverEthernetInitFailed(int pd) { + PPPControl* pc; + + //pppHup(pd); + //pppStop(pd); + + pc = &pppControl[pd]; + pppoe_destroy(&pc->netif); + pc->openFlag = 0; + + if(pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + } +} + +static void pppOverEthernetLinkStatusCB(int pd, int up) { + printf("pppOverEthernetLinkStatusCB: called, pd = %d, up = %d\n", pd, up); + if(up) { + PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); + pppStart(pd); + } else { + pppOverEthernetInitFailed(pd); + } } #endif -#if 0 +#if PPPOE_SUPPORT +static err_t pppifOutputOverEthernet(int pd, struct pbuf *p) { + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + u_short protocol = PPP_IP; + int i=0; + u16_t tot_len; + + /* @todo: try to use pbuf_header() here! */ + pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return ERR_MEM; + } + + pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + + pc->lastXMit = sys_jiffies(); + + if (!pc->pcomp || protocol > 0xFF) { + *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; + } + *((u_char*)pb->payload + i) = protocol & 0xFF; + + pbuf_chain(pb, p); + tot_len = pb->tot_len; + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pc->netif, tot_len); + snmp_inc_ifoutucastpkts(&pc->netif); + LINK_STATS_INC(link.xmit); + return ERR_OK; +} +#endif /* PPPOE_SUPPORT */ + +/* Send a packet on the given connection. */ +static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { + int pd = (int)(size_t)netif->state; + PPPControl *pc = &pppControl[pd]; +#if PPPOS_SUPPORT + u_short protocol = PPP_IP; + u_int fcsOut = PPP_INITFCS; + struct pbuf *headMB = NULL, *tailMB = NULL, *p; + u_char c; +#endif /* PPPOS_SUPPORT */ + + LWIP_UNUSED_ARG(ipaddr); + + /* Validate parameters. */ + /* We let any protocol value go through - it can't hurt us + * and the peer will just drop it if it's not accepting it. */ + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", + pd, PPP_IP, pb)); + LINK_STATS_INC(link.opterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_ARG; + } + + /* Check that the link is up. */ + if (phase == PHASE_DEAD) { + PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd)); + LINK_STATS_INC(link.rterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_RTE; + } + +#if PPPOE_SUPPORT + if(pc->ethif) { + return pppifOutputOverEthernet(pd, pb); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOS_SUPPORT + /* Grab an output buffer. */ + headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (headMB == NULL) { + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd)); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_MEM; + } + +#if VJ_SUPPORT + /* + * Attempt Van Jacobson header compression if VJ is configured and + * this is an IP packet. + */ + if (protocol == PPP_IP && pc->vjEnabled) { + switch (vj_compress_tcp(&pc->vjComp, pb)) { + case TYPE_IP: + /* No change... + protocol = PPP_IP_PROTOCOL; */ + break; + case TYPE_COMPRESSED_TCP: + protocol = PPP_VJC_COMP; + break; + case TYPE_UNCOMPRESSED_TCP: + protocol = PPP_VJC_UNCOMP; + break; + default: + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd)); + LINK_STATS_INC(link.proterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + pbuf_free(headMB); + return ERR_VAL; + } + } +#endif /* VJ_SUPPORT */ + + tailMB = headMB; + + /* Build the PPP header. */ + if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + } + + pc->lastXMit = sys_jiffies(); + if (!pc->accomp) { + fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS); + tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM); + fcsOut = PPP_FCS(fcsOut, PPP_UI); + tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM); + } + if (!pc->pcomp || protocol > 0xFF) { + c = (protocol >> 8) & 0xFF; + fcsOut = PPP_FCS(fcsOut, c); + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + c = protocol & 0xFF; + fcsOut = PPP_FCS(fcsOut, c); + tailMB = pppAppend(c, tailMB, &pc->outACCM); + + /* Load packet. */ + for(p = pb; p; p = p->next) { + int n; + u_char *sPtr; + + sPtr = (u_char*)p->payload; + n = p->len; + while (n-- > 0) { + c = *sPtr++; + + /* Update FCS before checking for special characters. */ + fcsOut = PPP_FCS(fcsOut, c); + + /* Copy to output buffer escaping special characters. */ + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + } + + /* Add FCS and trailing flag. */ + c = ~fcsOut & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + c = (~fcsOut >> 8) & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + + /* If we failed to complete the packet, throw it away. */ + if (!tailMB) { + PPPDEBUG(LOG_WARNING, + ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", + pd, protocol)); + pbuf_free(headMB); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_MEM; + } + + /* Send it. */ + PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); + + nPut(pc, headMB); +#endif /* PPPOS_SUPPORT */ + + return ERR_OK; +} + + +/* + * Return the Maximum Transmission Unit for the given PPP connection. + */ +u_short pppMTU(int pd) { + PPPControl *pc = &pppControl[pd]; + u_short st; + + /* Validate parameters. */ + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + } else { + st = pc->mtu; + } + + return st; +} + +#if PPPOE_SUPPORT +int pppWriteOverEthernet(int pd, const u_char *s, int n) { + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + + printf("pppWriteOverEthernet() called\n"); + + /* skip address & flags */ + s += 2; + n -= 2; + + LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + + pc->lastXMit = sys_jiffies(); + + MEMCPY(pb->payload, s, n); + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pc->netif, (u16_t)n); + snmp_inc_ifoutucastpkts(&pc->netif); + LINK_STATS_INC(link.xmit); + return PPPERR_NONE; +} +#endif /* PPPOE_SUPPORT */ + +/* + * Write n characters to a ppp link. + * RETURN: >= 0 Number of characters written + * -1 Failed to write to device + */ +int pppWrite(int pd, const u_char *s, int n) { + PPPControl *pc = &pppControl[pd]; +#if PPPOS_SUPPORT + u_char c; + u_int fcsOut; + struct pbuf *headMB, *tailMB; +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT + if(pc->ethif) { + return pppWriteOverEthernet(pd, s, n); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOS_SUPPORT + headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (headMB == NULL) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + tailMB = headMB; + + /* If the link has been idle, we'll send a fresh flag character to + * flush any noise. */ + if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + } + pc->lastXMit = sys_jiffies(); + + fcsOut = PPP_INITFCS; + /* Load output buffer. */ + while (n-- > 0) { + c = *s++; + + /* Update FCS before checking for special characters. */ + fcsOut = PPP_FCS(fcsOut, c); + + /* Copy to output buffer escaping special characters. */ + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + + /* Add FCS and trailing flag. */ + c = ~fcsOut & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + c = (~fcsOut >> 8) & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + + /* If we failed to complete the packet, throw it away. + * Otherwise send it. */ + if (!tailMB) { + PPPDEBUG(LOG_WARNING, + ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); + /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + pbuf_free(headMB); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len)); + /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + nPut(pc, headMB); +#endif /* PPPOS_SUPPORT */ + + return PPPERR_NONE; +} + + +/* FIXME: rename all output() to pppWrite() */ +/******************************************************************** + * + * output - Output PPP packet. + */ + +void output (int unit, unsigned char *p, int len) +{ + pppWrite(unit, p, len); +} + + /* * ppp_send_config - configure the transmit-side characteristics of - * the ppp interface. Returns -1, indicating an error, if the channel - * send_config procedure called error() (or incremented error_count - * itself), otherwise 0. + * the ppp interface. */ -int -old_ppp_send_config(unit, mtu, accm, pcomp, accomp) - int unit, mtu; - u_int32_t accm; - int pcomp, accomp; -{ - int errs; +int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { + PPPControl *pc = &pppControl[unit]; + int i; - if (the_channel->send_config == NULL) - return 0; - errs = error_count; - (*the_channel->send_config)(mtu, accm, pcomp, accomp); - return (error_count != errs)? -1: 0; + pc->mtu = mtu; + pc->pcomp = pcomp; + pc->accomp = accomp; + + /* Load the ACCM bits for the 32 control codes. */ + for (i = 0; i < 32/8; i++) { + pc->outACCM[i] = (u_char)((accm >> (8 * i)) & 0xFF); + } + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", + unit, + pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); + return 0; } /* * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. Returns -1, indicating an error, if the channel - * recv_config procedure called error() (or incremented error_count - * itself), otherwise 0. + * the ppp interface. */ -int -old_ppp_recv_config(unit, mru, accm, pcomp, accomp) - int unit, mru; - u_int32_t accm; - int pcomp, accomp; -{ - int errs; +int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { + PPPControl *pc = &pppControl[unit]; + int i; + SYS_ARCH_DECL_PROTECT(lev); - if (the_channel->recv_config == NULL) - return 0; - errs = error_count; - (*the_channel->recv_config)(mru, accm, pcomp, accomp); - return (error_count != errs)? -1: 0; + LWIP_UNUSED_ARG(accomp); + LWIP_UNUSED_ARG(pcomp); + LWIP_UNUSED_ARG(mru); + + /* Load the ACCM bits for the 32 control codes. */ + SYS_ARCH_PROTECT(lev); + for (i = 0; i < 32 / 8; i++) { + /* @todo: does this work? ext_accm has been modified from pppd! */ + pc->rx.inACCM[i] = (u_char)(accm >> (i * 8)); + } + SYS_ARCH_UNPROTECT(lev); + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", + unit, + pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); + return 0; } -#endif -#if 0 + +/* + * sifaddr - Config the interface IP addresses and netmask. + */ +int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, + u_int32_t net_mask) { + PPPControl *pc = &pppControl[unit]; + int st = 1; + + if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); + } else { + SMEMCPY(&pc->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); + SMEMCPY(&pc->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); + SMEMCPY(&pc->addrs.netmask, &net_mask, sizeof(net_mask)); +// SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); +// SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); + } + return st; +} + +/******************************************************************** + * + * cifaddr - Clear the interface IP addresses, and delete routes + * through the interface if possible. + */ +int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { + /* FIXME: do the code which clear a IP on a PPP interface */ + return 0; +} + + +/* + * pppifNetifInit - netif init callback + */ +static err_t +pppifNetifInit(struct netif *netif) +{ + netif->name[0] = 'p'; + netif->name[1] = 'p'; + netif->output = pppifOutput; + netif->mtu = pppMTU((int)(size_t)netif->state); + netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; +#if LWIP_NETIF_HOSTNAME + /* @todo: Initialize interface hostname */ + /* netif_set_hostname(netif, "lwip"); */ +#endif /* LWIP_NETIF_HOSTNAME */ + return ERR_OK; +} + +/* + * sifup - Config the interface up and enable IP packets to pass. + */ +int sifup(int u) +{ + PPPControl *pc = &pppControl[u]; + int st = 1; + + if (u < 0 || u >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", u)); + } else { + netif_remove(&pc->netif); + if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, + &pc->addrs.his_ipaddr, (void *)(size_t)u, pppifNetifInit, ip_input)) { + netif_set_up(&pc->netif); + pc->if_up = 1; + pc->errCode = PPPERR_NONE; + + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", u, pc->linkStatusCB, pc->errCode)); + if (pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); + } + } else { + st = 0; + PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", u)); + } + } + + return st; +} + +/******************************************************************** + * + * sifdown - Disable the indicated protocol and config the interface + * down if there are no remaining protocols. + */ +int sifdown (int u) { + /* FIXME: do the code which shutdown a PPP interface */ + return 1; +} + +/* + * sifnpmode - Set the mode for handling packets for a given NP. + */ +int sifnpmode(int u, int proto, enum NPmode mode) { + LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(proto); + LWIP_UNUSED_ARG(mode); + return 0; +} + +/* + * netif_set_mtu - set the MTU on the PPP network interface. + */ +void netif_set_mtu(int unit, int mtu) { + /* FIXME: set lwIP MTU */ +} +/* + * netif_get_mtu - get PPP interface MTU + */ +int netif_get_mtu(int mtu) { + /* FIXME: get lwIP MTU */ +} + +/******************************************************************** + * + * sifdefaultroute - assign a default route through the address given. + * + * If the global default_rt_repl_rest flag is set, then this function + * already replaced the original system defaultroute with some other + * route and it should just replace the current defaultroute with + * another one, without saving the current route. Use: demand mode, + * when pppd sets first a defaultroute it it's temporary ppp0 addresses + * and then changes the temporary addresses to the addresses for the real + * ppp connection when it has come up. + */ + +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { + /* FIXME: do the code which add the default route */ + return 0; +} + +/******************************************************************** + * + * cifdefaultroute - delete a default route through the address given. + */ + +int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { + /* FIXME: do the code which remove the default route */ + return 0; +} + +/******************************************************************** + * + * sifproxyarp - Make a proxy ARP entry for the peer. + */ + +int sifproxyarp (int unit, u_int32_t his_adr) { + /* FIXME: do we really need that in IPCP ? */ + return 0; +} + +/******************************************************************** + * + * cifproxyarp - Delete the proxy ARP entry for the peer. + */ + +int cifproxyarp (int unit, u_int32_t his_adr) { + /* FIXME: do we really need that in IPCP ? */ + return 0; +} + +/******************************************************************** + * + * sifvjcomp - config tcp header compression + */ +int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) { + /* FIXME: add VJ support */ + return 1; +} + +/******************************************************************** + * + * get_idle_time - return how long the link has been idle. + */ +int get_idle_time(int u, struct ppp_idle *ip) { + /* FIXME: add idle time support */ + return 1; +} + + +/******************************************************************** + * + * get_loop_output - get outgoing packets from the ppp device, + * 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) { + /* FIXME: necessary for "demand", do we really need to support on-demand ? */ + 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. + */ + +u_int32_t GetMask (u_int32_t addr) { + /* FIXME: do we really need that in IPCP ? */ + return 0; +} + + +#if PPP_PROTOCOLNAME +/* 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" }, + { 0x51, "KNX Bridging Data" }, + { 0x53, "Encryption" }, + { 0x55, "Individual Link Encryption" }, + { 0x57, "IPv6" }, + { 0x59, "PPP Muxing" }, + { 0x5b, "Vendor-Specific Network Protocol" }, + { 0x61, "RTP IPHC Full Header" }, + { 0x63, "RTP IPHC Compressed TCP" }, + { 0x65, "RTP IPHC Compressed non-TCP" }, + { 0x67, "RTP IPHC Compressed UDP 8" }, + { 0x69, "RTP IPHC Compressed RTP 8" }, + { 0x6f, "Stampede Bridging" }, + { 0x73, "MP+" }, + { 0xc1, "NTCITS IPI" }, + { 0xfb, "single-link compression" }, + { 0xfd, "Compressed Datagram" }, + { 0x0201, "802.1d Hello Packets" }, + { 0x0203, "IBM Source Routing BPDU" }, + { 0x0205, "DEC LANBridge100 Spanning Tree" }, + { 0x0207, "Cisco Discovery Protocol" }, + { 0x0209, "Netcs Twin Routing" }, + { 0x020b, "STP - Scheduled Transfer Protocol" }, + { 0x020d, "EDP - Extreme Discovery Protocol" }, + { 0x0211, "Optical Supervisory Channel Protocol" }, + { 0x0213, "Optical Supervisory Channel Protocol" }, + { 0x0231, "Luxcom" }, + { 0x0233, "Sigma Network Systems" }, + { 0x0235, "Apple Client Server Protocol" }, + { 0x0281, "MPLS Unicast" }, + { 0x0283, "MPLS Multicast" }, + { 0x0285, "IEEE p1284.4 standard - data packets" }, + { 0x0287, "ETSI TETRA Network Protocol Type 1" }, + { 0x0289, "Multichannel Flow Treatment Protocol" }, + { 0x2063, "RTP IPHC Compressed TCP No Delta" }, + { 0x2065, "RTP IPHC Context State" }, + { 0x2067, "RTP IPHC Compressed UDP 16" }, + { 0x2069, "RTP IPHC Compressed RTP 16" }, + { 0x4001, "Cray Communications Control Protocol" }, + { 0x4003, "CDPD Mobile Network Registration Protocol" }, + { 0x4005, "Expand accelerator protocol" }, + { 0x4007, "ODSICP NCP" }, + { 0x4009, "DOCSIS DLL" }, + { 0x400B, "Cetacean Network Detection Protocol" }, + { 0x4021, "Stacker LZS" }, + { 0x4023, "RefTek Protocol" }, + { 0x4025, "Fibre Channel" }, + { 0x4027, "EMIT Protocols" }, + { 0x405b, "Vendor-Specific Protocol (VSP)" }, + { 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" }, + { 0x8051, "KNX Bridging Control Protocol" }, + { 0x8053, "Encryption Control Protocol" }, + { 0x8055, "Individual Link Encryption Control Protocol" }, + { 0x8057, "IPv6 Control Protocol" }, + { 0x8059, "PPP Muxing Control Protocol" }, + { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, + { 0x806f, "Stampede Bridging Control Protocol" }, + { 0x8073, "MP+ Control Protocol" }, + { 0x80c1, "NTCITS IPI Control Protocol" }, + { 0x80fb, "Single Link Compression Control Protocol" }, + { 0x80fd, "Compression Control Protocol" }, + { 0x8207, "Cisco Discovery Protocol Control" }, + { 0x8209, "Netcs Twin Routing" }, + { 0x820b, "STP - Control Protocol" }, + { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, + { 0x8235, "Apple Client Server Protocol Control" }, + { 0x8281, "MPLSCP" }, + { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, + { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, + { 0x8289, "Multichannel Flow Treatment Protocol" }, + { 0xc021, "Link Control Protocol" }, + { 0xc023, "Password Authentication Protocol" }, + { 0xc025, "Link Quality Report" }, + { 0xc027, "Shiva Password Authentication Protocol" }, + { 0xc029, "CallBack Control Protocol (CBCP)" }, + { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, + { 0xc02d, "BAP" }, + { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, + { 0xc081, "Container Control Protocol" }, + { 0xc223, "Challenge Handshake Authentication Protocol" }, + { 0xc225, "RSA Authentication Protocol" }, + { 0xc227, "Extensible Authentication Protocol" }, + { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, + { 0xc26f, "Stampede Bridging Authorization Protocol" }, + { 0xc281, "Proprietary Authentication Protocol" }, + { 0xc283, "Proprietary Authentication Protocol" }, + { 0xc481, "Proprietary Node ID Authentication Protocol" }, + { 0, NULL }, +}; + +/* + * protocol_name - find a name for a PPP protocol. + */ +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; +} +#endif /* PPP_PROTOCOLNAME */ + /* * new_phase - signal the start of a new phase of pppd's operation. */ -void -new_phase(p) - int p; -{ +void new_phase(int p) { phase = p; - if (new_phase_hook) - (*new_phase_hook)(p); - notify(phasechange, p); +#if PPP_NOTIFY + /* The one willing notify support should add here the code to be notified of phase changes */ +#endif /* PPP_NOTIFY */ } -#endif -#if 0 -/* - * die - clean up state and exit with the specified status. +#if PPP_STATS_SUPPORT + +/* ---- Note on PPP Stats support ---- + * + * The one willing link stats support should add the get_ppp_stats() + * to fetch statistics from lwIP. */ -void -die(status) - int status; -{ - if (!doing_multilink || multilink_master) - print_link_stats(); - cleanup(); - notify(exitnotify, status); - syslog(LOG_INFO, "Exit."); - exit(status); -} -#endif -#if 0 /* - * cleanup - restore anything which needs to be restored before we exit + * reset_link_stats - "reset" stats when link goes up. */ -/* ARGSUSED */ -static void -cleanup() -{ - sys_cleanup(); - - if (fd_ppp >= 0) - the_channel->disestablish_ppp(devfd); - if (the_channel->cleanup) - (*the_channel->cleanup)(); - remove_pidfiles(); +void reset_link_stats(int u) { + if (!get_ppp_stats(u, &old_link_stats)) + return; + gettimeofday(&start_time, NULL); } -#endif -#if 0 -void -print_link_stats() -{ +/* + * 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; + + link_stats.bytes_in -= old_link_stats.bytes_in; + link_stats.bytes_out -= old_link_stats.bytes_out; + link_stats.pkts_in -= old_link_stats.pkts_in; + link_stats.pkts_out -= old_link_stats.pkts_out; +} + +void print_link_stats() { /* * Print connect time and statistics. */ @@ -1114,737 +1555,4 @@ print_link_stats() link_stats_valid = 0; } } - -/* - * reset_link_stats - "reset" stats when link goes up. - */ -void -reset_link_stats(u) - int u; -{ -#if 0 - if (!get_ppp_stats(u, &old_link_stats)) - return; -#endif - gettimeofday(&start_time, NULL); -} - -/* - * update_link_stats - get stats at link termination. - */ -void -update_link_stats(u) - int u; -{ - struct timeval now; - char numbuf[32]; - -#if 0 - if (!get_ppp_stats(u, &link_stats) - || gettimeofday(&now, NULL) < 0) - return; -#endif - link_connect_time = now.tv_sec - start_time.tv_sec; - link_stats_valid = 1; - - link_stats.bytes_in -= old_link_stats.bytes_in; - link_stats.bytes_out -= old_link_stats.bytes_out; - link_stats.pkts_in -= old_link_stats.pkts_in; - link_stats.pkts_out -= old_link_stats.pkts_out; - -#if 0 - slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time); - script_setenv("CONNECT_TIME", numbuf, 0); - slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out); - script_setenv("BYTES_SENT", numbuf, 0); - slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in); - script_setenv("BYTES_RCVD", numbuf, 0); -#endif -} -#endif - -#if 0 -struct callout { - struct timeval c_time; /* time at which to call routine */ - void *c_arg; /* argument to routine */ - void (*c_func) __P((void *)); /* routine */ - struct callout *c_next; -}; - -static struct callout *callout = NULL; /* Callout list */ -static struct timeval timenow; /* Current time */ -#endif - -#if 0 -/* - * timeout - Schedule a timeout. - */ -void -timeout(func, arg, secs, usecs) - void (*func) __P((void *)); - void *arg; - int secs, usecs; -{ - struct callout *newp, *p, **pp; - - /* - * 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 + secs; - newp->c_time.tv_usec = timenow.tv_usec + usecs; - if (newp->c_time.tv_usec >= 1000000) { - newp->c_time.tv_sec += newp->c_time.tv_usec / 1000000; - newp->c_time.tv_usec %= 1000000; - } - - /* - * 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 -untimeout(func, arg) - void (*func) __P((void *)); - void *arg; -{ - struct callout **copp, *freep; - - /* - * 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; - } -} -#endif - -#if 0 -/* - * calltimeout - Call any timeout routines which are now due. - */ -static void -calltimeout() -{ - 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(tvp) - 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; -} -#endif - -#if 0 -/* - * kill_my_pg - send a signal to our process group, and ignore it ourselves. - * We assume that sig is currently blocked. - */ -static void -kill_my_pg(sig) - int sig; -{ - struct sigaction act, oldact; - struct subprocess *chp; - - if (!detached) { - /* - * There might be other things in our process group that we - * didn't start that would get hit if we did a kill(0), so - * just send the signal individually to our children. - */ - for (chp = children; chp != NULL; chp = chp->next) - if (chp->killable) - kill(chp->pid, sig); - return; - } - - /* We've done a setsid(), so we can just use a kill(0) */ - sigemptyset(&act.sa_mask); /* unnecessary in fact */ - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - kill(0, sig); - /* - * The kill() above made the signal pending for us, as well as - * the rest of our process group, but we don't want it delivered - * to us. It is blocked at the moment. Setting it to be ignored - * will cause the pending signal to be discarded. If we did the - * kill() after setting the signal to be ignored, it is unspecified - * (by POSIX) whether the signal is immediately discarded or left - * pending, and in fact Linux would leave it pending, and so it - * would be delivered after the current signal handler exits, - * leading to an infinite loop. - */ - sigaction(sig, &act, &oldact); - sigaction(sig, &oldact, NULL); -} - - -/* - * hup - Catch SIGHUP signal. - * - * Indicates that the physical layer has been disconnected. - * We don't rely on this indication; if the user has sent this - * signal, we just take the link down. - */ -static void -hup(sig) - int sig; -{ - /* can't log a message here, it can deadlock */ - got_sighup = 1; - if (conn_running) - /* Send the signal to the [dis]connector process(es) also */ - kill_my_pg(sig); - notify(sigreceived, sig); - if (waiting) - siglongjmp(sigjmp, 1); -} - - -/* - * term - Catch SIGTERM signal and SIGINT signal (^C/del). - * - * Indicates that we should initiate a graceful disconnect and exit. - */ -/*ARGSUSED*/ -static void -term(sig) - int sig; -{ - /* can't log a message here, it can deadlock */ - got_sigterm = sig; - if (conn_running) - /* Send the signal to the [dis]connector process(es) also */ - kill_my_pg(sig); - notify(sigreceived, sig); - if (waiting) - siglongjmp(sigjmp, 1); -} - - -/* - * chld - Catch SIGCHLD signal. - * Sets a flag so we will call reap_kids in the mainline. - */ -static void -chld(sig) - int sig; -{ - got_sigchld = 1; - if (waiting) - siglongjmp(sigjmp, 1); -} - - -/* - * toggle_debug - Catch SIGUSR1 signal. - * - * Toggle debug flag. - */ -/*ARGSUSED*/ -static void -toggle_debug(sig) - int sig; -{ - debug = !debug; - if (debug) { - setlogmask(LOG_UPTO(LOG_DEBUG)); - } else { - setlogmask(LOG_UPTO(LOG_WARNING)); - } -} - - -/* - * open_ccp - Catch SIGUSR2 signal. - * - * Try to (re)negotiate compression. - */ -/*ARGSUSED*/ -static void -open_ccp(sig) - int sig; -{ - got_sigusr2 = 1; - if (waiting) - siglongjmp(sigjmp, 1); -} -#endif - -#if 0 -/* - * bad_signal - We've caught a fatal signal. Clean up state and exit. - */ -static void -bad_signal(sig) - int sig; -{ - static int crashed = 0; - - if (crashed) - _exit(127); - crashed = 1; - error("Fatal signal %d", sig); - if (conn_running) - kill_my_pg(SIGTERM); - notify(sigreceived, sig); - die(127); -} -#endif - -#if 0 -/* - * safe_fork - Create a child process. The child closes all the - * file descriptors that we don't want to leak to a script. - * The parent waits for the child to do this before returning. - * This also arranges for the specified fds to be dup'd to - * fds 0, 1, 2 in the child. - */ -pid_t -safe_fork(int infd, int outfd, int errfd) -{ - pid_t pid; - int fd, pipefd[2]; - char buf[1]; - - /* make sure fds 0, 1, 2 are occupied (probably not necessary) */ - while ((fd = dup(fd_devnull)) >= 0) { - if (fd > 2) { - close(fd); - break; - } - } - - if (pipe(pipefd) == -1) - pipefd[0] = pipefd[1] = -1; - pid = fork(); - if (pid < 0) { - error("fork failed: %m"); - return -1; - } - if (pid > 0) { - /* parent */ - close(pipefd[1]); - /* this read() blocks until the close(pipefd[1]) below */ - complete_read(pipefd[0], buf, 1); - close(pipefd[0]); - return pid; - } - - /* Executing in the child */ - sys_close(); - - /* make sure infd, outfd and errfd won't get tromped on below */ - if (infd == 1 || infd == 2) - infd = dup(infd); - if (outfd == 0 || outfd == 2) - outfd = dup(outfd); - if (errfd == 0 || errfd == 1) - errfd = dup(errfd); - - closelog(); - - /* dup the in, out, err fds to 0, 1, 2 */ - if (infd != 0) - dup2(infd, 0); - if (outfd != 1) - dup2(outfd, 1); - if (errfd != 2) - dup2(errfd, 2); - - if (log_to_fd > 2) - close(log_to_fd); - if (the_channel->close) - (*the_channel->close)(); - else - close(devfd); /* some plugins don't have a close function */ - close(fd_ppp); - close(fd_devnull); - if (infd != 0) - close(infd); - if (outfd != 1) - close(outfd); - if (errfd != 2) - close(errfd); - - notify(fork_notifier, 0); - close(pipefd[0]); - /* this close unblocks the read() call above in the parent */ - close(pipefd[1]); - - return 0; -} -#endif - -#if 0 -/* - * device_script - run a program to talk to the specified fds - * (e.g. to run the connector or disconnector script). - * stderr gets connected to the log fd or to the _PATH_CONNERRS file. - */ -int -device_script(program, in, out, dont_wait) - char *program; - int in, out; - int dont_wait; -{ - int pid; - int status = -1; - int errfd; - - if (log_to_fd >= 0) - errfd = log_to_fd; - else - errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); - - ++conn_running; - //pid = safe_fork(in, out, errfd); - pid = -1; - - if (pid != 0 && log_to_fd < 0) - close(errfd); - - if (pid < 0) { - --conn_running; - error("Failed to create child process: %m"); - return -1; - } - - if (pid != 0) { - record_child(pid, program, NULL, NULL, 1); - status = 0; - if (!dont_wait) { - while (waitpid(pid, &status, 0) < 0) { - if (errno == EINTR) - continue; - fatal("error waiting for (dis)connection process: %m"); - } - forget_child(pid, status); - --conn_running; - } - return (status == 0 ? 0 : -1); - } - - /* here we are executing in the child */ - - setgid(getgid()); - setuid(uid); - if (getuid() != uid) { - fprintf(stderr, "pppd: setuid failed\n"); - exit(1); - } - execl("/bin/sh", "sh", "-c", program, (char *)0); - perror("pppd: could not exec /bin/sh"); - exit(99); - /* NOTREACHED */ -} -#endif - -#if 0 /* UNUSED */ -/* - * record_child - add a child process to the list for reap_kids - * to use. - */ -void -record_child(pid, prog, done, arg, killable) - int pid; - char *prog; - void (*done) __P((void *)); - void *arg; - int killable; -{ - struct subprocess *chp; - - ++n_children; - - chp = (struct subprocess *) malloc(sizeof(struct subprocess)); - if (chp == NULL) { - warn("losing track of %s process", prog); - } else { - chp->pid = pid; - chp->prog = prog; - chp->done = done; - chp->arg = arg; - chp->next = children; - chp->killable = killable; - children = chp; - } -} - -/* - * childwait_end - we got fed up waiting for the child processes to - * exit, send them all a SIGTERM. - */ -static void -childwait_end(arg) - void *arg; -{ - struct subprocess *chp; - - for (chp = children; chp != NULL; chp = chp->next) { - if (debug) - dbglog("sending SIGTERM to process %d", chp->pid); - kill(chp->pid, SIGTERM); - } - childwait_done = 1; -} - -/* - * forget_child - clean up after a dead child - */ -static void -forget_child(pid, status) - int pid, status; -{ - struct subprocess *chp, **prevp; - - for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) { - if (chp->pid == pid) { - --n_children; - *prevp = chp->next; - break; - } - } - if (WIFSIGNALED(status)) { - warn("Child process %s (pid %d) terminated with signal %d", - (chp? chp->prog: "??"), pid, WTERMSIG(status)); - } else if (debug) - dbglog("Script %s finished (pid %d), status = 0x%x", - (chp? chp->prog: "??"), pid, - WIFEXITED(status) ? WEXITSTATUS(status) : status); - if (chp && chp->done) - (*chp->done)(chp->arg); - if (chp) - free(chp); -} - -/* - * reap_kids - get status from any dead child processes, - * and log a message for abnormal terminations. - */ -static int -reap_kids() -{ - int pid, status; - - if (n_children == 0) - return 0; - while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) { - forget_child(pid, status); - } - if (pid == -1) { - if (errno == ECHILD) - return -1; - if (errno != EINTR) - error("Error waiting for child process: %m"); - } - return 0; -} -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* - * add_notifier - add a new function to be called when something happens. - */ -void -add_notifier(notif, func, arg) - struct notifier **notif; - notify_func func; - void *arg; -{ - struct notifier *np; - - np = malloc(sizeof(struct notifier)); - if (np == 0) - return; - //novm("notifier struct"); - np->next = *notif; - np->func = func; - np->arg = arg; - *notif = np; -} - -/* - * remove_notifier - remove a function from the list of things to - * be called when something happens. - */ -void -remove_notifier(notif, func, arg) - struct notifier **notif; - notify_func func; - void *arg; -{ - struct notifier *np; - - for (; (np = *notif) != 0; notif = &np->next) { - if (np->func == func && np->arg == arg) { - *notif = np->next; - free(np); - break; - } - } -} -#endif /* UNUSED */ - -#if 0 -/* - * notify - call a set of functions registered with add_notifier. - */ -void -notify(notif, val) - struct notifier *notif; - int val; -{ - struct notifier *np; - - while ((np = notif) != 0) { - notif = np->next; - (*np->func)(np->arg, val); - } -} -#endif - -#if 0 /* UNUSED */ -/* - * novm - log an error message saying we ran out of memory, and die. - */ -void -novm(msg) - char *msg; -{ - fatal("Virtual memory exhausted allocating %s\n", msg); -} - -/* - * script_setenv - set an environment variable value to be used - * for scripts that we run (e.g. ip-up, auth-up, etc.) - */ -void -script_setenv(var, value, iskey) - char *var, *value; - int iskey; -{ - size_t varl = strlen(var); - size_t vl = varl + strlen(value) + 2; - int i; - char *p, *newstring; - - newstring = (char *) malloc(vl+1); - if (newstring == 0) - return; - *newstring++ = iskey; - slprintf(newstring, vl, "%s=%s", var, value); - - /* check if this variable is already set */ - if (script_env != 0) { - for (i = 0; (p = script_env[i]) != 0; ++i) { - if (strncmp(p, var, varl) == 0 && p[varl] == '=') { - free(p-1); - script_env[i] = newstring; - return; - } - } - } else { - /* no space allocated for script env. ptrs. yet */ - i = 0; - script_env = (char **) malloc(16 * sizeof(char *)); - if (script_env == 0) - return; - s_env_nalloc = 16; - } - - /* reallocate script_env with more space if needed */ - if (i + 1 >= s_env_nalloc) { - int new_n = i + 17; - char **newenv = (char **) realloc((void *)script_env, - new_n * sizeof(char *)); - if (newenv == 0) - return; - script_env = newenv; - s_env_nalloc = new_n; - } - - script_env[i] = newstring; - script_env[i+1] = 0; -} - -/* - * script_unsetenv - remove a variable from the environment - * for scripts. - */ -void -script_unsetenv(var) - char *var; -{ - int vl = strlen(var); - int i; - char *p; - - if (script_env == 0) - return; - for (i = 0; (p = script_env[i]) != 0; ++i) { - if (strncmp(p, var, vl) == 0 && p[vl] == '=') { - free(p-1); - while ((script_env[i] = script_env[i+1]) != 0) - ++i; - break; - } - } -} -#endif /* UNUSED */ - -#endif /* PPP.C DISABLED */ +#endif PPP_STATS_SUPPORT diff --git a/src/netif/ppp/pppmy.h b/src/netif/ppp/ppp.h similarity index 99% rename from src/netif/ppp/pppmy.h rename to src/netif/ppp/ppp.h index 00426892..6bcc14ad 100644 --- a/src/netif/ppp/pppmy.h +++ b/src/netif/ppp/ppp.h @@ -1,5 +1,5 @@ /* - * pppmy.h + * ppp.h * * Created on: May 12, 2012 * Author: gradator diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index cdb448bc..d897ef0c 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -74,10 +74,7 @@ #include "netif/ppp_oe.h" -//#include "ppp_impl.h" -#include "pppdebug.h" -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" #include "lwip/timers.h" #include "lwip/memp.h" diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index ce9ded8f..6a3a4ab6 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -33,8 +33,8 @@ #include "lwip/opt.h" #if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */ -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "pppcrypt.h" diff --git a/src/netif/ppp/pppd.h b/src/netif/ppp/pppd.h deleted file mode 100644 index 657cc915..00000000 --- a/src/netif/ppp/pppd.h +++ /dev/null @@ -1,1040 +0,0 @@ -/* - * pppd.h - PPP daemon global declarations. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $ - */ - -#if 0 /* PPPD.H DISABLED */ - -#include "lwip/opt.h" - -#include "pppmy.h" - -/* - * TODO: - */ - -#ifndef __PPPD_H__ -#define __PPPD_H__ - -#include /* for FILE */ -#include /* for NGROUPS_MAX */ -#include /* for MAXPATHLEN and BSD4_4, if defined */ -#include /* for u_int32_t, if defined */ -#include /* for struct timeval */ -#include - -#if 0 -#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 - -#endif - -#if 0 -/* - * 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 */ -#endif - -#if 0 -/* - * Option descriptor structure. - */ - -#ifndef bool -typedef unsigned char bool; -#endif -#endif - -#if 0 -enum opt_type { - o_special_noarg = 0, - o_special = 1, - o_bool, - o_int, - o_uint32, - o_string, - o_wild -}; - -typedef struct { - char *name; /* name of the option */ - enum opt_type type; - void *addr; - char *description; - unsigned int flags; - void *addr2; - int upper_limit; - int lower_limit; - const char *source; - short int priority; - short int winner; -} option_t; - -/* Values for flags */ -#define OPT_VALUE 0xff /* mask for presupplied value */ -#define OPT_HEX 0x100 /* int option is in hex */ -#define OPT_NOARG 0x200 /* option doesn't take argument */ -#define OPT_OR 0x400 /* for u32, OR in argument to value */ -#define OPT_INC 0x400 /* for o_int, increment value */ -#define OPT_A2OR 0x800 /* for o_bool, OR arg to *(u_char *)addr2 */ -#define OPT_PRIV 0x1000 /* privileged option */ -#define OPT_STATIC 0x2000 /* string option goes into static array */ -#define OPT_NOINCR 0x2000 /* for o_int, value mustn't be increased */ -#define OPT_LLIMIT 0x4000 /* check value against lower limit */ -#define OPT_ULIMIT 0x8000 /* check value against upper limit */ -#define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT) -#define OPT_ZEROOK 0x10000 /* 0 value is OK even if not within limits */ -#define OPT_HIDE 0x10000 /* for o_string, print value as ?????? */ -#define OPT_A2LIST 0x20000 /* for o_special, keep list of values */ -#define OPT_A2CLRB 0x20000 /* o_bool, clr val bits in *(u_char *)addr2 */ -#define OPT_ZEROINF 0x40000 /* with OPT_NOINCR, 0 == infinity */ -#define OPT_PRIO 0x80000 /* process option priorities for this option */ -#define OPT_PRIOSUB 0x100000 /* subsidiary member of priority group */ -#define OPT_ALIAS 0x200000 /* option is alias for previous option */ -#define OPT_A2COPY 0x400000 /* addr2 -> second location to rcv value */ -#define OPT_ENABLE 0x800000 /* use *addr2 as enable for option */ -#define OPT_A2CLR 0x1000000 /* clear *(bool *)addr2 */ -#define OPT_PRIVFIX 0x2000000 /* user can't override if set by root */ -#define OPT_INITONLY 0x4000000 /* option can only be set in init phase */ -#define OPT_DEVEQUIV 0x8000000 /* equiv to device name */ -#define OPT_DEVNAM (OPT_INITONLY | OPT_DEVEQUIV) -#define OPT_A2PRINTER 0x10000000 /* *addr2 is a fn for printing option */ -#define OPT_A2STRVAL 0x20000000 /* *addr2 points to current string value */ -#define OPT_NOPRINT 0x40000000 /* don't print this option at all */ - -#define OPT_VAL(x) ((x) & OPT_VALUE) - -/* Values for priority */ -#define OPRIO_DEFAULT 0 /* a default value */ -#define OPRIO_CFGFILE 1 /* value from a configuration file */ -#define OPRIO_CMDLINE 2 /* value from the command line */ -#define OPRIO_SECFILE 3 /* value from options in a secrets file */ -#define OPRIO_ROOT 100 /* added to priority if OPT_PRIVFIX && root */ - -#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 */ - u_int32_t base; /* match if (addr & mask) == base */ - u_int32_t mask; /* base and mask are in network byte order */ -}; -#endif - -#if 0 -/* - * 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; - unsigned int pkts_in; - unsigned int pkts_out; -}; -#endif - -#if 0 -/* Used for storing a sequence of words. Usually malloced. */ -struct wordlist { - struct wordlist *next; - char *word; -}; -#endif - -#if 0 -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class; - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; - -/* values for epdisc.class */ -#define EPD_NULL 0 /* null discriminator, no data */ -#define EPD_LOCAL 1 -#define EPD_IP 2 -#define EPD_MAC 3 -#define EPD_MAGIC 4 -#define EPD_PHONENUM 5 -#endif - -#if 0 /* UNUSED */ -typedef void (*notify_func) __P((void *, int)); - -struct notifier { - struct notifier *next; - notify_func func; - void *arg; -}; -#endif /* UNUSED */ - -#if 0 -/* - * Global variables. - */ - -extern int hungup; /* Physical layer has disconnected */ -//extern int ifunit; /* Interface unit number */ -//extern char ifname[]; /* Interface name */ -extern char hostname[]; /* Our hostname */ -//extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ -extern int devfd; /* fd of underlying device */ -extern int fd_ppp; /* fd for talking PPP */ -extern int phase; /* Current state of link - see values below */ -extern int baud_rate; /* Current link speed in bits/sec */ -extern char *progname; /* Name of this program */ -extern int redirect_stderr;/* Connector's stderr should go to file */ -extern char peer_authname[];/* Authenticated name of peer */ -extern int auth_done[NUM_PPP]; /* Methods actually used for auth */ -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 */ -#if 0 -extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */ -#endif -extern int ngroups; /* How many groups valid in groups */ -#if PPP_STATS_SUPPORT -extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */ -extern int link_stats_valid; /* set if link_stats is valid */ -extern unsigned link_connect_time; /* time the link was up for */ -#endif /* PPP_STATS_SUPPORT */ -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 bool log_default; /* log_to_fd is default (stdout) */ -extern char *no_ppp_msg; /* message to print if ppp not in kernel */ -//extern volatile int status; /* exit status for pppd */ -extern bool 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 int error_count; /* # of times error() has been called */ -//extern char ppp_devnam[MAXPATHLEN]; -extern char remote_number[MAXNAMELEN]; /* Remote telephone number, if avail. */ -extern int ppp_session_number; /* Session number (eg PPPoE session) */ -extern int fd_devnull; /* fd open to /dev/null */ - -//extern int listen_time; /* time to listen first (ms) */ - -#if 0 -extern bool doing_multilink; -extern bool multilink_master; -extern bool bundle_eof; -extern bool bundle_terminating; -#endif - -extern struct notifier *pidchange; /* for notifications of pid changing */ -extern struct notifier *phasechange; /* for notifications of phase changes */ -extern struct notifier *exitnotify; /* for notification that we're exiting */ -extern struct notifier *sigreceived; /* notification of received signal */ - -#if PPP_NOTIFY -extern struct notifier *ip_up_notifier; /* IPCP has come up */ -extern struct notifier *ip_down_notifier; /* IPCP has gone down */ -extern struct notifier *auth_up_notifier; /* peer has authenticated */ -extern struct notifier *link_down_notifier; /* link has gone down */ -#endif /* PPP_NOTIFY */ - -extern struct notifier *fork_notifier; /* we are a new child process */ - -/* 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 u_int32_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 bool session_mgmt; /* Do session management (login records) */ -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 *pty_socket; /* Socket to connect to pty */ -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 */ -extern int max_data_rate; /* max bytes/sec through charshunt */ -extern int req_unit; /* interface unit number to use */ -extern bool multilink; /* enable multilink operation */ -extern bool noendpoint; /* don't send or accept endpt. discrim. */ -extern char *bundle_name; /* bundle name for multilink */ -extern bool dump_options; /* print out option values */ -extern bool dryrun; /* check everything, print options, exit */ -extern int child_wait; /* # seconds to wait for children at end */ - -#ifdef MAXOCTETS -extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ -extern int maxoctets_dir; /* Direction : - 0 - in+out (default) - 1 - in - 2 - out - 3 - max(in,out) */ -extern int maxoctets_timeout; /* Timeout for check of octets limit */ -#define PPP_OCTETS_DIRECTION_SUM 0 -#define PPP_OCTETS_DIRECTION_IN 1 -#define PPP_OCTETS_DIRECTION_OUT 2 -#define PPP_OCTETS_DIRECTION_MAXOVERAL 3 -/* same as previos, but little different on RADIUS side */ -#define PPP_OCTETS_DIRECTION_MAXSESSION 4 -#endif - -#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 - -#endif - - -#if 0 - -/* Values for auth_pending, auth_done */ -#if PAP_SUPPORT -#define PAP_WITHPEER 0x1 -#define PAP_PEER 0x2 -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#define CHAP_WITHPEER 0x4 -#define CHAP_PEER 0x8 -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#define EAP_WITHPEER 0x10 -#define EAP_PEER 0x20 -#endif /* EAP_SUPPORT */ - -/* Values for auth_done only */ -#if CHAP_SUPPORT -#define CHAP_MD5_WITHPEER 0x40 -#define CHAP_MD5_PEER 0x80 -#if MSCHAP_SUPPORT -#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ -#define CHAP_MS_WITHPEER 0x100 -#define CHAP_MS_PEER 0x200 -#define CHAP_MS2_WITHPEER 0x400 -#define CHAP_MS2_PEER 0x800 -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ - -#endif - -#if 0 -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 */ -extern int option_priority; /* priority of current options */ -#endif - -#if 0 -/* - * 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 -#define PHASE_MASTER 12 -#endif - -#if 0 -/* - * 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) __P((int unit)); - /* Process a received packet */ - void (*input) __P((int unit, u_char *pkt, int len)); - /* Process a received protocol-reject */ - void (*protrej) __P((int unit)); - /* Lower layer has come up */ - void (*lowerup) __P((int unit)); - /* Lower layer has gone down */ - void (*lowerdown) __P((int unit)); - /* Open the protocol */ - void (*open) __P((int unit)); - /* Close the protocol */ - void (*close) __P((int unit, char *reason)); -#if PRINTPKT_SUPPORT - /* Print a packet in readable form */ - int (*printpkt) __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); -#endif /* PRINTPKT_SUPPORT */ - /* FIXME: data input is only used by CCP, which is not supported at this time, - * should we remove this entry and save some flash ? - */ - /* Process a received data packet */ - void (*datainput) __P((int unit, u_char *pkt, int len)); - bool enabled_flag; /* 0 iff protocol is disabled */ -#if PRINTPKT_SUPPORT - char *name; /* Text name of protocol */ - char *data_name; /* Text name of corresponding data protocol */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - option_t *options; /* List of command-line options */ - /* Check requested options, assign defaults */ - void (*check_options) __P((void)); -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - /* Configure interface for demand-dial */ - int (*demand_conf) __P((int unit)); - /* Say whether to bring up link for this pkt */ - int (*active_pkt) __P((u_char *pkt, int len)); -#endif /* DEMAND_SUPPORT */ -}; - -/* Table of pointers to supported protocols */ -extern struct protent *protocols[]; -#endif - -#if 0 -/* - * This struct contains pointers to a set of procedures for - * doing operations on a "channel". A channel provides a way - * to send and receive PPP packets - the canonical example is - * a serial port device in PPP line discipline (or equivalently - * with PPP STREAMS modules pushed onto it). - */ -struct channel { -#if PPP_OPTIONS - /* set of options for this channel */ - option_t *options; - /* find and process a per-channel options file */ - void (*process_extra_options) __P((void)); - /* check all the options that have been given */ - void (*check_options) __P((void)); - /* get the channel ready to do PPP, return a file descriptor */ - int (*connect) __P((void)); -#endif /* PPP_OPTIONS */ - /* we're finished with the channel */ - void (*disconnect) __P((void)); - /* put the channel into PPP `mode' */ - int (*establish_ppp) __P((int)); - /* take the channel out of PPP `mode', restore loopback if demand */ - void (*disestablish_ppp) __P((int)); - /* set the transmit-side PPP parameters of the channel */ - void (*send_config) __P((int, u_int32_t, int, int)); - /* set the receive-side PPP parameters of the channel */ - void (*recv_config) __P((int, u_int32_t, int, int)); - /* cleanup on error or normal exit */ - void (*cleanup) __P((void)); - /* close the device, called in children after fork */ - void (*close) __P((void)); -}; - -extern struct channel *the_channel; -#endif - -/* - * Prototypes. - */ - -#if 0 -/* Procedures exported from main.c. */ -void set_ifunit __P((int)); /* set stuff that depends on ifunit */ -#endif - -#if 0 -void detach __P((void)); /* Detach from controlling tty */ -#endif - -#if 0 -void die __P((int)); /* Cleanup and exit */ -void quit __P((void)); /* like die(1) */ -void novm __P((char *)); /* Say we ran out of memory, and die */ -void timeout __P((void (*func)(void *), void *arg, int s, int us)); - /* Call func(arg) after s.us seconds */ -void untimeout __P((void (*func)(void *), void *arg)); - /* Cancel call to func(arg) */ -#endif -#if 0 -void record_child __P((int, char *, void (*) (void *), void *, int)); -#endif - -#if 0 -pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ -#endif - -//int device_script __P((char *cmd, int in, int out, int dont_wait)); - /* Run `cmd' with given stdin and stdout */ -#if 0 -void reopen_log __P((void)); /* (re)open the connection to syslog */ -#endif -#if 0 -void print_link_stats __P((void)); /* Print stats, if available */ -void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */ -void update_link_stats __P((int)); /* Get stats at link termination */ -#endif -#if 0 /* UNUSED */ -void script_setenv __P((char *, char *, int)); /* set script env var */ -void script_unsetenv __P((char *)); /* unset script env var */ -#endif /* UNUSED */ -//void new_phase __P((int)); /* signal start of new phase */ -#if 0 /* UNUSED */ -void add_notifier __P((struct notifier **, notify_func, void *)); -void remove_notifier __P((struct notifier **, notify_func, void *)); -void notify __P((struct notifier *, int)); -#endif /* UNUSED */ -//int ppp_send_config __P((int, int, u_int32_t, int, int)); -//int ppp_recv_config __P((int, int, u_int32_t, int, int)); -//void remove_pidfiles __P((void)); -#if 0 -void lock_db __P((void)); -void unlock_db __P((void)); -#endif - -#if 0 -/* Procedures exported from tty.c. */ -void tty_init __P((void)); -#endif - -#if 0 -/* Procedures exported from utils.c. */ -void print_string __P((char *, int, void (*) (void *, char *, ...), - void *)); /* Format a string for output */ -int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ -int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ -size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ -size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ -void dbglog __P((char *, ...)); /* log a debug message */ -void info __P((char *, ...)); /* log an informational message */ -void notice __P((char *, ...)); /* log a notice-level message */ -void warn __P((char *, ...)); /* log a warning message */ -void error __P((char *, ...)); /* log an error message */ -void fatal __P((char *, ...)); /* log an error message and die(1) */ -void init_pr_log __P((const char *, int)); /* initialize for using pr_log */ -void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ -void end_pr_log __P((void)); /* finish up after using pr_log */ -#if PRINTPKT_SUPPORT -void dump_packet __P((const char *, u_char *, int)); - /* dump packet to debug log if interesting */ -#endif /* PRINTPKT_SUPPORT */ -#endif - -#if 0 /* Unused */ -ssize_t complete_read __P((int, void *, size_t)); - /* read a complete buffer */ -#endif /* Unused */ - -#if 0 -/* Procedures exported from auth.c */ -void link_required __P((int)); /* we are starting to use the link */ -void start_link __P((int)); /* bring the link up now */ -void link_terminated __P((int)); /* we are finished with the link */ -void link_down __P((int)); /* the LCP layer has left the Opened state */ -void upper_layers_down __P((int));/* take all NCPs down */ -void link_established __P((int)); /* the link is up; authenticate now */ -void start_networks __P((int)); /* start all the network control protos */ -void continue_networks __P((int)); /* start network [ip, etc] control protos */ -void np_up __P((int, int)); /* a network protocol has come up */ -void np_down __P((int, int)); /* a network protocol has gone down */ -void np_finished __P((int, int)); /* a network protocol no longer needs link */ -void auth_peer_fail __P((int, int)); - /* peer failed to authenticate itself */ -void auth_peer_success __P((int, int, int, char *, int)); - /* peer successfully authenticated itself */ -void auth_withpeer_fail __P((int, int)); - /* we failed to authenticate ourselves */ -void auth_withpeer_success __P((int, int, int)); - /* we successfully authenticated ourselves */ -void auth_check_options __P((void)); - /* check authentication options supplied */ -void auth_reset __P((int)); /* check what secrets we have */ -int check_passwd __P((int, char *, int, char *, int, char **)); - /* Check peer-supplied username/password */ -int get_secret __P((int, char *, char *, char *, int *, int)); - /* get "secret" for chap */ -int get_srp_secret __P((int unit, char *client, char *server, char *secret, - int am_server)); -int auth_ip_addr __P((int, u_int32_t)); - /* check if IP address is authorized */ -int auth_number __P((void)); /* check if remote number is authorized */ -int bad_ip_adrs __P((u_int32_t)); - /* check if IP address is unreasonable */ -#endif - -#if 0 -/* Procedures exported from demand.c */ -#if DEMAND_SUPPORT -void demand_conf __P((void)); /* config interface(s) for demand-dial */ -void demand_block __P((void)); /* set all NPs to queue up packets */ -void demand_unblock __P((void)); /* set all NPs to pass packets */ -void demand_discard __P((void)); /* set all NPs to discard packets */ -void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ -int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ -int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ -#endif /* DEMAND_SUPPORT */ -#endif - -#if 0 -/* Procedures exported from multilink.c */ -#ifdef HAVE_MULTILINK -void mp_check_options __P((void)); /* Check multilink-related options */ -int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ -void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */ -void mp_bundle_terminated __P((void)); -char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ -int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ -#else -#define mp_bundle_terminated() /* nothing */ -#define mp_exit_bundle() /* nothing */ -#define doing_multilink 0 -#define multilink_master 0 -#endif -#endif - -#if 0 -/* Procedures exported from sys-*.c */ -void sys_cleanup __P((void)); /* Restore system state before exiting */ -int sys_check_options __P((void)); /* Check options specified */ -void sys_close __P((void)); /* Clean up in a child before execing */ -int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */ -int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */ -int tty_establish_ppp __P((int)); /* Turn serial port into a ppp interface */ -void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */ -void generic_disestablish_ppp __P((int dev_fd)); /* Restore device setting */ -int generic_establish_ppp __P((int dev_fd)); /* Make a ppp interface */ -void make_new_bundle __P((int, int, int, int)); /* Create new bundle */ -int bundle_attach __P((int)); /* Attach link to existing bundle */ -void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */ -void destroy_bundle __P((void)); /* Tell driver to destroy bundle */ -void clean_check __P((void)); /* Check if line was 8-bit clean */ -void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */ -void restore_tty __P((int)); /* Restore port's original parameters */ -void setdtr __P((int, int)); /* Raise or lower port's DTR line */ -void output __P((int, u_char *, int)); /* Output a PPP packet */ -void wait_input __P((struct timeval *)); - /* Wait for input, with timeout */ -void add_fd __P((int)); /* Add fd to set to wait for */ -void remove_fd __P((int)); /* Remove fd from set to wait for */ -int read_packet __P((u_char *)); /* Read PPP packet */ -int get_loop_output __P((void)); /* Read pkts from loopback */ -void tty_send_config __P((int, u_int32_t, int, int)); - /* Configure i/f transmit parameters */ -void tty_set_xaccm __P((ext_accm)); - /* Set extended transmit ACCM */ -void tty_recv_config __P((int, u_int32_t, int, int)); - /* Configure i/f receive parameters */ -int ccp_test __P((int, u_char *, int, int)); - /* Test support for compression scheme */ -void ccp_flags_set __P((int, int, int)); - /* Set kernel CCP state */ -int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */ -//int get_idle_time __P((int, struct ppp_idle *)); - /* Find out how long link has been idle */ -//int get_ppp_stats __P((int, struct pppd_stats *)); - /* Return link statistics */ -//void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */ -//int netif_get_mtu __P((int)); /* Get PPP interface MTU */ -//int sifvjcomp __P((int, int, int, int)); - /* Configure VJ TCP header compression */ -//int sifup __P((int)); /* Configure i/f up for one protocol */ -//int sifnpmode __P((int u, int proto, enum NPmode mode)); - /* Set mode for handling packets for proto */ -//int sifdown __P((int)); /* Configure i/f down for one protocol */ -//int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t)); - /* Configure IPv4 addresses for i/f */ -//int cifaddr __P((int, u_int32_t, u_int32_t)); - /* Reset i/f IP addresses */ -#ifdef INET6 -int sif6addr __P((int, eui64_t, eui64_t)); - /* Configure IPv6 addresses for i/f */ -int cif6addr __P((int, eui64_t, eui64_t)); - /* Remove an IPv6 address from i/f */ -#endif -//int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt)); - /* Create default route through i/f */ -//int cifdefaultroute __P((int, u_int32_t, u_int32_t)); - /* Delete default route through i/f */ -//int sifproxyarp __P((int, u_int32_t)); - /* Add proxy ARP entry for peer */ -//int cifproxyarp __P((int, u_int32_t)); - /* Delete proxy ARP entry for peer */ -//u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ -#if 0 /* Unused */ -int lock __P((char *)); /* Create lock file for device */ -int relock __P((int)); /* Rewrite lock file with new pid */ -void unlock __P((void)); /* Delete previously-created lock file */ -#endif /* Unused */ -void logwtmp __P((const char *, const char *, const char *)); - /* Write entry to wtmp file */ -int get_host_seed __P((void)); /* Get host-dependent random number seed */ -int have_route_to __P((u_int32_t)); /* Check if route to addr exists */ -#ifdef PPP_FILTER -int set_filters __P((struct bpf_program *pass, struct bpf_program *active)); - /* Set filter programs in kernel */ -#endif -#ifdef IPX_CHANGE -int sipxfaddr __P((int, unsigned long, unsigned char *)); -int cipxfaddr __P((int)); -#endif -int get_if_hwaddr __P((u_char *addr, char *name)); -char *get_first_ethernet __P((void)); -#endif - -#if 0 -/* Procedures exported from options.c */ -#if 0 /* UNUSED */ -int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */ -#endif /* UNUSED */ -int parse_args __P((int argc, char **argv)); - /* Parse options from arguments given */ -int options_from_file __P((char *filename, int must_exist, int check_prot, - int privileged)); - /* Parse options from an options file */ -int options_from_user __P((void)); /* Parse options from user's .ppprc */ -int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */ -int options_from_list __P((struct wordlist *, int privileged)); - /* Parse options from a wordlist */ -int getword __P((FILE *f, char *word, int *newlinep, char *filename)); - /* Read a word from a file */ -#if PPP_OPTIONS -void option_error __P((char *fmt, ...)); - /* Print an error message about an option */ -#else -#define option_error(x, ...) -#endif /* PPP_OPTIONS */ -#if PPP_OPTIONS -int int_option __P((char *, int *)); - /* Simplified number_option for decimal ints */ -void add_options __P((option_t *)); /* Add extra options */ -void check_options __P((void)); /* check values after all options parsed */ -int override_value __P((const char *, int, const char *)); - /* override value if permitted by priority */ -void print_options __P((void (*) __P((void *, char *, ...)), void *)); - /* print out values of all options */ -#endif /* PPP_OPTIONS */ -#endif - -#if 0 -/* Procedures exported from ipcp.c */ -int parse_dotted_ip __P((char *, u_int32_t *)); -#endif - -/* - * Hooks to enable plugins to change various things. - */ -#if 0 -extern int (*new_phase_hook) __P((int)); -extern int (*idle_time_hook) __P((struct ppp_idle *)); -extern int (*holdoff_hook) __P((void)); -extern int (*pap_check_hook) __P((void)); -extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts)); -extern void (*pap_logout_hook) __P((void)); -extern int (*pap_passwd_hook) __P((char *user, char *passwd)); -extern int (*allowed_address_hook) __P((u_int32_t addr)); -extern void (*ip_up_hook) __P((void)); -extern void (*ip_down_hook) __P((void)); -extern void (*ip_choose_hook) __P((u_int32_t *)); - -extern int (*chap_check_hook) __P((void)); -extern int (*chap_passwd_hook) __P((char *user, char *passwd)); -extern void (*multilink_join_hook) __P((void)); - -/* Let a plugin snoop sent and received packets. Useful for L2TP */ -extern void (*snoop_recv_hook) __P((unsigned char *p, int len)); -extern void (*snoop_send_hook) __P((unsigned char *p, int len)); -#endif - -#if 0 -/* - * 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) timeout((r), (f), (t), 0) -#define UNTIMEOUT(r, f) untimeout((r), (f)) - -#define BZERO(s, n) memset(s, 0, n) -#define BCMP(s1, s2, l) memcmp(s1, s2, l) - -#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 -#ifdef MAXOCTETS -#define EXIT_TRAFFIC_LIMIT 20 -#endif -#define EXIT_CNID_AUTH_FAILED 21 -#endif - - -#if 0 -/* - * 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 - -#if 0 -#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */ -#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \ - || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \ - || defined(DEBUGCHAP) || defined(DEBUG) || defined(DEBUGIPV6CP) -#define LOG_PPP LOG_LOCAL2 -#else -#define LOG_PPP LOG_DAEMON -#endif -#endif /* LOG_PPP */ -#endif - -#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 - -#endif - -#if 0 -#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 - -#if 0 -#ifndef offsetof -#define offsetof(type, member) ((size_t) &((type *)0)->member) -#endif -#endif - -#endif /* __PPP_H__ */ - -#endif /* PPPD.H DISABLED */ diff --git a/src/netif/ppp/pppmy.c b/src/netif/ppp/pppmy.c deleted file mode 100644 index 3dbb13a3..00000000 --- a/src/netif/ppp/pppmy.c +++ /dev/null @@ -1,1560 +0,0 @@ -/* - * pppmy.c - * - * Created on: May 12, 2012 - * Author: gradator - */ - -#include "lwip/opt.h" - -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/sys.h" - -#if PPPOE_SUPPORT -#include "netif/ppp_oe.h" -#endif /* PPPOE_SUPPORT */ - -#include "pppd.h" -#include "pppdebug.h" -#include "pppmy.h" - -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" - -#if PAP_SUPPORT -#include "upap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "chap-new.h" -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#include "eap.h" -#endif /* EAP_SUPPORT */ -#if CCP_SUPPORT -#include "ccp.h" -#endif /* EAP_SUPPORT */ -#if ECP_SUPPORT -#include "ecp.h" -#endif /* EAP_SUPPORT */ - - -/* - * Global variables. - */ -/* FIXME: global variables per PPP session */ -/* FIXME: clean global variables */ -int phase; /* where the link is at */ -int error_count; /* # of times error() has been called */ -int unsuccess; /* # unsuccessful connection attempts */ -int listen_time; /* time to listen first (ms) */ -int status; /* exit status for pppd */ -int need_holdoff; /* need holdoff period before restarting */ -/* FIXME: remove ifunit */ -int ifunit; /* Interface unit number */ - -/* FIXME: outpacket_buf per PPP session */ -u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ - -#if PPPOS_SUPPORT -u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ -#endif /* PPPOS_SUPPORT */ - -/* FIXME: add stats per PPP session */ -#if PPP_STATS_SUPPORT -static struct timeval start_time; /* Time when link was started. */ -static struct pppd_stats old_link_stats; -struct pppd_stats link_stats; -unsigned link_connect_time; -int link_stats_valid; -#endif /* PPP_STATS_SUPPORT */ - -/* - * PPP Data Link Layer "protocol" table. - * One entry per supported protocol. - * The last entry must be NULL. - */ -struct protent *protocols[] = { - &lcp_protent, -#if PAP_SUPPORT - &pap_protent, -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - &chap_protent, -#endif /* CHAP_SUPPORT */ -#if CBCP_SUPPORT - &cbcp_protent, -#endif - &ipcp_protent, -#ifdef INET6 - &ipv6cp_protent, -#endif -#if CCP_SUPPORT - &ccp_protent, -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT - &ecp_protent, -#endif /* ECP_SUPPORT */ -#ifdef AT_CHANGE - &atcp_protent, -#endif -#if EAP_SUPPORT - &eap_protent, -#endif /* EAP_SUPPORT */ - NULL -}; - -/* PPP packet parser states. Current state indicates operation yet to be - * completed. */ -typedef enum { - PDIDLE = 0, /* Idle state - waiting. */ - PDSTART, /* Process start flag. */ - PDADDRESS, /* Process address field. */ - PDCONTROL, /* Process control field. */ - PDPROTOCOL1, /* Process protocol field 1. */ - PDPROTOCOL2, /* Process protocol field 2. */ - PDDATA /* Process data byte. */ -} PPPDevStates; - -typedef struct PPPControlRx_s { - /** unit number / ppp descriptor */ - int pd; - /** the rx file descriptor */ -#if PPPOS_SUPPORT /* FIXME: enable sio_fd_t back */ - sio_fd_t fd; -#endif -#if PPPOE_SUPPORT - int fd; -#endif - /** receive buffer - encoded data is stored here */ -#if PPP_INPROC_OWNTHREAD - u_char rxbuf[PPPOS_RX_BUFSIZE]; -#endif /* PPP_INPROC_OWNTHREAD */ - - /* The input packet. */ - struct pbuf *inHead, *inTail; - -#if PPPOS_SUPPORT - u16_t inProtocol; /* The input protocol code. */ - u16_t inFCS; /* Input Frame Check Sequence value. */ -#endif /* PPPOS_SUPPORT */ - PPPDevStates inState; /* The input process state. */ - char inEscaped; /* Escape next character. */ - ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ -} PPPControlRx; - -/* - * PPP interface control block. - */ -typedef struct PPPControl_s { - PPPControlRx rx; - char openFlag; /* True when in use. */ -#if PPPOE_SUPPORT - struct netif *ethif; - struct pppoe_softc *pppoe_sc; -#endif /* PPPOE_SUPPORT */ - int if_up; /* True when the interface is up. */ - int errCode; /* Code indicating why interface is down. */ -#if PPPOS_SUPPORT - sio_fd_t fd; /* File device ID of port. */ -#endif /* PPPOS_SUPPORT */ - u16_t mtu; /* Peer's mru */ - int pcomp; /* Does peer accept protocol compression? */ - int accomp; /* Does peer accept addr/ctl compression? */ - u_long lastXMit; /* Time of last transmission. */ - ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ -#if PPPOS_SUPPORT && VJ_SUPPORT - int vjEnabled; /* Flag indicating VJ compression enabled. */ - struct vjcompress vjComp; /* Van Jacobson compression header. */ -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - - struct netif netif; - - struct ppp_addrs addrs; - - void (*linkStatusCB)(void *ctx, int errCode, void *arg); - void *linkStatusCtx; - -} PPPControl; - -/******************************/ -/*** PUBLIC DATA STRUCTURES ***/ -/******************************/ -static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ - - -struct pbuf * pppSingleBuf(struct pbuf *p) { - struct pbuf *q, *b; - u_char *pl; - - if(p->tot_len == p->len) { - return p; - } - - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if(!q) { - PPPDEBUG(LOG_ERR, - ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); - return p; /* live dangerously */ - } - - for(b = p, pl = q->payload; b != NULL; b = b->next) { - MEMCPY(pl, b->payload, b->len); - pl += b->len; - } - - pbuf_free(p); - - return q; -} - -/** Input helper struct, must be packed since it is stored to pbuf->payload, - * which might be unaligned. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppInputHeader { - PACK_STRUCT_FIELD(int unit); - PACK_STRUCT_FIELD(u16_t proto); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -/** Initiate LCP open request */ -static void pppStart(int pd) { - PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd)); - lcp_open(pd); /* Start protocol */ - lcp_lowerup(pd); - PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n")); -} - - -/* - * Pass the processed input packet to the appropriate handler. - * This function and all handlers run in the context of the tcpip_thread - */ - -/* FIXME: maybe we should pass in two arguments pppInputHeader and payload - * this is totally stupid to make room for it and then modify the packet directly - * or it is used in output ? have to find out... - */ -static void ppp_input(void *arg) { - struct pbuf *nb = (struct pbuf *)arg; - u16_t protocol; - int pd; - - pd = ((struct pppInputHeader *)nb->payload)->unit; - protocol = ((struct pppInputHeader *)nb->payload)->proto; - printf("ppp_input() called, pd = %d, protocol = 0x%x\n", pd, protocol); - - if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } - - LINK_STATS_INC(link.recv); - snmp_inc_ifinucastpkts(&pppControl[pd].netif); - snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); - - /* - * Toss all non-LCP packets unless LCP is OPEN. - */ - if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { - dbglog("Discarded non-LCP packet when LCP not open"); - return; - } - - /* FIXME: add a phase per connection */ - - /* - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if (phase <= PHASE_AUTHENTICATE - && !(protocol == PPP_LCP || protocol == PPP_LQR -#if PAP_SUPPORT - || protocol == PPP_PAP -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - || protocol == PPP_CHAP -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || protocol == PPP_EAP -#endif /* EAP_SUPPORT */ - )) { - dbglog("discarding proto 0x%x in phase %d", - protocol, phase); - return; - } - - /* FIXME: should we write protent to do that ? */ - - switch(protocol) { - case PPP_VJC_COMP: /* VJ compressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", - pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_IP: /* Internet Protocol */ - printf("IP packet received\n"); - PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - break; - - default: { - - int i; - struct protent *protp; - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - nb = pppSingleBuf(nb); - (*protp->input)(pd, nb->payload, nb->len); - goto out; - } -#if 0 /* UNUSED - * - * This is actually a (hacked?) way for the PPP kernel implementation to pass a - * data packet to the PPP daemon. The PPP daemon normally only do signaling - * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. - * - * This is only used by CCP, which we cannot support until we have a CCP data - * implementation. - */ - if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag - && protp->datainput != NULL) { - (*protp->datainput)(pd, nb->payload, nb->len); - goto out; - } -#endif /* UNUSED */ - } - - if (debug) { -#if PPP_PROTOCOLNAME - const char *pname = protocol_name(protocol); - if (pname != NULL) - warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); - else -#endif /* PPP_PROTOCOLNAME */ - warn("Unsupported protocol 0x%x received", protocol); - } - if (pbuf_header(nb, sizeof(protocol))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } - lcp_sprotrej(pd, nb->payload, nb->len); - } - break; - } - -drop: - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); - -out: - pbuf_free(nb); - return; - - #if 0 - /* - * Toss all non-LCP packets unless LCP is OPEN. - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { - if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || - (lcp_phase[pd] != PHASE_AUTHENTICATE)) { - PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); - goto drop; - } - } - - switch(protocol) { - case PPP_VJC_COMP: /* VJ compressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", - pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - break; - - default: { - struct protent *protp; - int i; - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); - nb = pppSingleBuf(nb); - (*protp->input)(pd, nb->payload, nb->len); - PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); - goto out; - } - } - - /* No handler for this protocol so reject the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); - if (pbuf_header(nb, sizeof(protocol))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } -#if BYTE_ORDER == LITTLE_ENDIAN - protocol = htons(protocol); -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - SMEMCPY(nb->payload, &protocol, sizeof(protocol)); - lcp_sprotrej(pd, nb->payload, nb->len); - } - break; - } -#endif - - -} - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -/* Initialize the PPP subsystem. */ - -int ppp_init(void) { - int i; - struct protent *protp; - - debug = 1; - ifunit = 1; /* FIXME: remove ifunit */ - - /* - openlog("LWIP-PPP", LOG_PID | LOG_NDELAY, LOG_DAEMON); - setlogmask(LOG_UPTO(LOG_DEBUG)); - syslog(LOG_DEBUG, "hello, this is gradator lwIP PPP!"); - */ - - memset(&ppp_settings, 0, sizeof(ppp_settings)); - ppp_settings.usepeerdns = 1; - pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL); - - /* - * Initialize magic number generator now so that protocols may - * use magic numbers in initialization. - */ - magic_init(); - - /* - * Initialize each protocol. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - (*protp->init)(0); -} - -void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { - /* FIXME: the following may look stupid, but this is just an easy way - * to check different auth by changing compile time option - */ -#if PAP_SUPPORT - ppp_settings.refuse_pap = 0; -#endif /* PAP_SUPPORT */ - -#if CHAP_SUPPORT -#if PAP_SUPPORT - ppp_settings.refuse_pap = 1; -#endif /* PAP_SUPPORT */ - ppp_settings.refuse_chap = 0; -#endif /* CHAP_SUPPORT */ - -#if MSCHAP_SUPPORT -#if PAP_SUPPORT - ppp_settings.refuse_pap = 1; -#endif /* PAP_SUPPORT */ - ppp_settings.refuse_chap = 1; - ppp_settings.refuse_mschap = 1; - ppp_settings.refuse_mschap_v2 = 0; -#endif /* MSCHAP_SUPPORT */ - -#if EAP_SUPPORT -#if PAP_SUPPORT - ppp_settings.refuse_pap = 1; -#endif/* PAP_SUPPORT */ -#if CHAP_SUPPORT - ppp_settings.refuse_chap = 1; -#if MSCHAP_SUPPORT - ppp_settings.refuse_mschap = 1; - ppp_settings.refuse_mschap_v2 = 1; -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ - ppp_settings.refuse_eap = 0; -#endif /* EAP_SUPPORT */ - -/* FIXME: re-enable that */ -#if 0 - switch(authType) { - case PPPAUTHTYPE_NONE: - default: -#ifdef LWIP_PPP_STRICT_PAP_REJECT - ppp_settings.refuse_pap = 1; -#else /* LWIP_PPP_STRICT_PAP_REJECT */ - /* some providers request pap and accept an empty login/pw */ - ppp_settings.refuse_pap = 0; -#endif /* LWIP_PPP_STRICT_PAP_REJECT */ - ppp_settings.refuse_chap = 1; - break; - - case PPPAUTHTYPE_ANY: - /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. - * RFC 1994 says: - * - * In practice, within or associated with each PPP server, there is a - * database which associates "user" names with authentication - * information ("secrets"). It is not anticipated that a particular - * named user would be authenticated by multiple methods. This would - * make the user vulnerable to attacks which negotiate the least secure - * method from among a set (such as PAP rather than CHAP). If the same - * secret was used, PAP would reveal the secret to be used later with - * CHAP. - * - * Instead, for each user name there should be an indication of exactly - * one method used to authenticate that user name. If a user needs to - * make use of different authentication methods under different - * circumstances, then distinct user names SHOULD be employed, each of - * which identifies exactly one authentication method. - * - */ - ppp_settings.refuse_pap = 0; - ppp_settings.refuse_chap = 0; - break; - - case PPPAUTHTYPE_PAP: - ppp_settings.refuse_pap = 0; - ppp_settings.refuse_chap = 1; - break; - - case PPPAUTHTYPE_CHAP: - ppp_settings.refuse_pap = 1; - ppp_settings.refuse_chap = 0; - break; - } -#endif - - if(user) { - strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); - ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0'; - } else { - ppp_settings.user[0] = '\0'; - } - - if(passwd) { - strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1); - ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0'; - } else { - ppp_settings.passwd[0] = '\0'; - } -} - -#if PPPOE_SUPPORT -static void pppOverEthernetLinkStatusCB(int pd, int up); - -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, - pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) -{ - PPPControl *pc; - int pd; - - LWIP_UNUSED_ARG(service_name); - LWIP_UNUSED_ARG(concentrator_name); - - if (linkStatusCB == NULL) { - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ - return PPPERR_PARAM; - } - - /* Find a free PPP session descriptor. Critical region? */ - for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); - if (pd >= NUM_PPP) { - pd = PPPERR_OPEN; - } else { - pc = &pppControl[pd]; - memset(pc, 0, sizeof(PPPControl)); - pc->openFlag = 1; - pc->ethif = ethif; - - pc->linkStatusCB = linkStatusCB; - pc->linkStatusCtx = linkStatusCtx; - - lcp_wantoptions[pd].mru = PPPOE_MAXMTU; - lcp_wantoptions[pd].neg_asyncmap = 0; - lcp_wantoptions[pd].neg_pcompression = 0; - lcp_wantoptions[pd].neg_accompression = 0; - - lcp_allowoptions[pd].mru = PPPOE_MAXMTU; - lcp_allowoptions[pd].neg_asyncmap = 0; - lcp_allowoptions[pd].neg_pcompression = 0; - lcp_allowoptions[pd].neg_accompression = 0; - - if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) { - pc->openFlag = 0; - return PPPERR_OPEN; - } - - pppoe_connect(pc->pppoe_sc); - } - - return pd; -} - -/* FIXME: maybe we should pass in two arguments pppInputHeader and payload - * this is totally stupid to make room for it and then modify the packet directly - * or it is used in output ? have to find out... - */ -void pppInProcOverEthernet(int pd, struct pbuf *pb) { - struct pppInputHeader *pih; - u16_t inProtocol; - - if(pb->len < sizeof(inProtocol)) { - PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n")); - goto drop; - } - - inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - printf("pppInProcOverEthernet() called, pd = %d, inprotocol = 0x%x\n", pd, inProtocol); - - /* make room for pppInputHeader - should not fail */ - if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { - PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n")); - goto drop; - } - - pih = pb->payload; - - pih->unit = pd; - pih->proto = inProtocol; - - /* Dispatch the packet thereby consuming it. */ - ppp_input(pb); - return; - -drop: - LINK_STATS_INC(link.drop); -// snmp_inc_ifindiscards(&pppControl[pd].netif); - pbuf_free(pb); - return; -} - -void pppOverEthernetInitFailed(int pd) { - PPPControl* pc; - - //pppHup(pd); - //pppStop(pd); - - pc = &pppControl[pd]; - pppoe_destroy(&pc->netif); - pc->openFlag = 0; - - if(pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); - } -} - -static void pppOverEthernetLinkStatusCB(int pd, int up) { - printf("pppOverEthernetLinkStatusCB: called, pd = %d, up = %d\n", pd, up); - if(up) { - PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); - pppStart(pd); - } else { - pppOverEthernetInitFailed(pd); - } -} -#endif - -#if PPPOE_SUPPORT -static err_t pppifOutputOverEthernet(int pd, struct pbuf *p) { - PPPControl *pc = &pppControl[pd]; - struct pbuf *pb; - u_short protocol = PPP_IP; - int i=0; - u16_t tot_len; - - /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return ERR_MEM; - } - - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - - pc->lastXMit = sys_jiffies(); - - if (!pc->pcomp || protocol > 0xFF) { - *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; - } - *((u_char*)pb->payload + i) = protocol & 0xFF; - - pbuf_chain(pb, p); - tot_len = pb->tot_len; - - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { - LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_DEVICE; - } - - snmp_add_ifoutoctets(&pc->netif, tot_len); - snmp_inc_ifoutucastpkts(&pc->netif); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} -#endif /* PPPOE_SUPPORT */ - -/* Send a packet on the given connection. */ -static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { - int pd = (int)(size_t)netif->state; - PPPControl *pc = &pppControl[pd]; -#if PPPOS_SUPPORT - u_short protocol = PPP_IP; - u_int fcsOut = PPP_INITFCS; - struct pbuf *headMB = NULL, *tailMB = NULL, *p; - u_char c; -#endif /* PPPOS_SUPPORT */ - - LWIP_UNUSED_ARG(ipaddr); - - /* Validate parameters. */ - /* We let any protocol value go through - it can't hurt us - * and the peer will just drop it if it's not accepting it. */ - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", - pd, PPP_IP, pb)); - LINK_STATS_INC(link.opterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_ARG; - } - - /* Check that the link is up. */ - if (phase == PHASE_DEAD) { - PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd)); - LINK_STATS_INC(link.rterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_RTE; - } - -#if PPPOE_SUPPORT - if(pc->ethif) { - return pppifOutputOverEthernet(pd, pb); - } -#endif /* PPPOE_SUPPORT */ - -#if PPPOS_SUPPORT - /* Grab an output buffer. */ - headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (headMB == NULL) { - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd)); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_MEM; - } - -#if VJ_SUPPORT - /* - * Attempt Van Jacobson header compression if VJ is configured and - * this is an IP packet. - */ - if (protocol == PPP_IP && pc->vjEnabled) { - switch (vj_compress_tcp(&pc->vjComp, pb)) { - case TYPE_IP: - /* No change... - protocol = PPP_IP_PROTOCOL; */ - break; - case TYPE_COMPRESSED_TCP: - protocol = PPP_VJC_COMP; - break; - case TYPE_UNCOMPRESSED_TCP: - protocol = PPP_VJC_UNCOMP; - break; - default: - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd)); - LINK_STATS_INC(link.proterr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - pbuf_free(headMB); - return ERR_VAL; - } - } -#endif /* VJ_SUPPORT */ - - tailMB = headMB; - - /* Build the PPP header. */ - if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - } - - pc->lastXMit = sys_jiffies(); - if (!pc->accomp) { - fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS); - tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM); - fcsOut = PPP_FCS(fcsOut, PPP_UI); - tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM); - } - if (!pc->pcomp || protocol > 0xFF) { - c = (protocol >> 8) & 0xFF; - fcsOut = PPP_FCS(fcsOut, c); - tailMB = pppAppend(c, tailMB, &pc->outACCM); - } - c = protocol & 0xFF; - fcsOut = PPP_FCS(fcsOut, c); - tailMB = pppAppend(c, tailMB, &pc->outACCM); - - /* Load packet. */ - for(p = pb; p; p = p->next) { - int n; - u_char *sPtr; - - sPtr = (u_char*)p->payload; - n = p->len; - while (n-- > 0) { - c = *sPtr++; - - /* Update FCS before checking for special characters. */ - fcsOut = PPP_FCS(fcsOut, c); - - /* Copy to output buffer escaping special characters. */ - tailMB = pppAppend(c, tailMB, &pc->outACCM); - } - } - - /* Add FCS and trailing flag. */ - c = ~fcsOut & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - c = (~fcsOut >> 8) & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - - /* If we failed to complete the packet, throw it away. */ - if (!tailMB) { - PPPDEBUG(LOG_WARNING, - ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", - pd, protocol)); - pbuf_free(headMB); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); - return ERR_MEM; - } - - /* Send it. */ - PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); - - nPut(pc, headMB); -#endif /* PPPOS_SUPPORT */ - - return ERR_OK; -} - - -/* - * Return the Maximum Transmission Unit for the given PPP connection. - */ -u_short pppMTU(int pd) { - PPPControl *pc = &pppControl[pd]; - u_short st; - - /* Validate parameters. */ - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { - st = 0; - } else { - st = pc->mtu; - } - - return st; -} - -#if PPPOE_SUPPORT -int pppWriteOverEthernet(int pd, const u_char *s, int n) { - PPPControl *pc = &pppControl[pd]; - struct pbuf *pb; - - printf("pppWriteOverEthernet() called\n"); - - /* skip address & flags */ - s += 2; - n -= 2; - - LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - - pc->lastXMit = sys_jiffies(); - - MEMCPY(pb->payload, s, n); - - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { - LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_DEVICE; - } - - snmp_add_ifoutoctets(&pc->netif, (u16_t)n); - snmp_inc_ifoutucastpkts(&pc->netif); - LINK_STATS_INC(link.xmit); - return PPPERR_NONE; -} -#endif /* PPPOE_SUPPORT */ - -/* - * Write n characters to a ppp link. - * RETURN: >= 0 Number of characters written - * -1 Failed to write to device - */ -int pppWrite(int pd, const u_char *s, int n) { - PPPControl *pc = &pppControl[pd]; -#if PPPOS_SUPPORT - u_char c; - u_int fcsOut; - struct pbuf *headMB, *tailMB; -#endif /* PPPOS_SUPPORT */ - -#if PPPOE_SUPPORT - if(pc->ethif) { - return pppWriteOverEthernet(pd, s, n); - } -#endif /* PPPOE_SUPPORT */ - -#if PPPOS_SUPPORT - headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (headMB == NULL) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - tailMB = headMB; - - /* If the link has been idle, we'll send a fresh flag character to - * flush any noise. */ - if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - } - pc->lastXMit = sys_jiffies(); - - fcsOut = PPP_INITFCS; - /* Load output buffer. */ - while (n-- > 0) { - c = *s++; - - /* Update FCS before checking for special characters. */ - fcsOut = PPP_FCS(fcsOut, c); - - /* Copy to output buffer escaping special characters. */ - tailMB = pppAppend(c, tailMB, &pc->outACCM); - } - - /* Add FCS and trailing flag. */ - c = ~fcsOut & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - c = (~fcsOut >> 8) & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); - - /* If we failed to complete the packet, throw it away. - * Otherwise send it. */ - if (!tailMB) { - PPPDEBUG(LOG_WARNING, - ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); - /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ - pbuf_free(headMB); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len)); - /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ - nPut(pc, headMB); -#endif /* PPPOS_SUPPORT */ - - return PPPERR_NONE; -} - - -/* FIXME: rename all output() to pppWrite() */ -/******************************************************************** - * - * output - Output PPP packet. - */ - -void output (int unit, unsigned char *p, int len) -{ - pppWrite(unit, p, len); -} - - -/* - * ppp_send_config - configure the transmit-side characteristics of - * the ppp interface. - */ -int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { - PPPControl *pc = &pppControl[unit]; - int i; - - pc->mtu = mtu; - pc->pcomp = pcomp; - pc->accomp = accomp; - - /* Load the ACCM bits for the 32 control codes. */ - for (i = 0; i < 32/8; i++) { - pc->outACCM[i] = (u_char)((accm >> (8 * i)) & 0xFF); - } - PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", - unit, - pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); - return 0; -} - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { - PPPControl *pc = &pppControl[unit]; - int i; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_UNUSED_ARG(accomp); - LWIP_UNUSED_ARG(pcomp); - LWIP_UNUSED_ARG(mru); - - /* Load the ACCM bits for the 32 control codes. */ - SYS_ARCH_PROTECT(lev); - for (i = 0; i < 32 / 8; i++) { - /* @todo: does this work? ext_accm has been modified from pppd! */ - pc->rx.inACCM[i] = (u_char)(accm >> (i * 8)); - } - SYS_ARCH_UNPROTECT(lev); - PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", - unit, - pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); - return 0; -} - - -/* - * sifaddr - Config the interface IP addresses and netmask. - */ -int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, - u_int32_t net_mask) { - PPPControl *pc = &pppControl[unit]; - int st = 1; - - if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); - } else { - SMEMCPY(&pc->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); - SMEMCPY(&pc->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); - SMEMCPY(&pc->addrs.netmask, &net_mask, sizeof(net_mask)); -// SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); -// SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); - } - return st; -} - -/******************************************************************** - * - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ -int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { - /* FIXME: do the code which clear a IP on a PPP interface */ - return 0; -} - - -/* - * pppifNetifInit - netif init callback - */ -static err_t -pppifNetifInit(struct netif *netif) -{ - netif->name[0] = 'p'; - netif->name[1] = 'p'; - netif->output = pppifOutput; - netif->mtu = pppMTU((int)(size_t)netif->state); - netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; -#if LWIP_NETIF_HOSTNAME - /* @todo: Initialize interface hostname */ - /* netif_set_hostname(netif, "lwip"); */ -#endif /* LWIP_NETIF_HOSTNAME */ - return ERR_OK; -} - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int sifup(int u) -{ - PPPControl *pc = &pppControl[u]; - int st = 1; - - if (u < 0 || u >= NUM_PPP || !pc->openFlag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", u)); - } else { - netif_remove(&pc->netif); - if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, - &pc->addrs.his_ipaddr, (void *)(size_t)u, pppifNetifInit, ip_input)) { - netif_set_up(&pc->netif); - pc->if_up = 1; - pc->errCode = PPPERR_NONE; - - PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", u, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); - } - } else { - st = 0; - PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", u)); - } - } - - return st; -} - -/******************************************************************** - * - * sifdown - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ -int sifdown (int u) { - /* FIXME: do the code which shutdown a PPP interface */ - return 1; -} - -/* - * sifnpmode - Set the mode for handling packets for a given NP. - */ -int sifnpmode(int u, int proto, enum NPmode mode) { - LWIP_UNUSED_ARG(u); - LWIP_UNUSED_ARG(proto); - LWIP_UNUSED_ARG(mode); - return 0; -} - -/* - * netif_set_mtu - set the MTU on the PPP network interface. - */ -void netif_set_mtu(int unit, int mtu) { - /* FIXME: set lwIP MTU */ -} -/* - * netif_get_mtu - get PPP interface MTU - */ -int netif_get_mtu(int mtu) { - /* FIXME: get lwIP MTU */ -} - -/******************************************************************** - * - * sifdefaultroute - assign a default route through the address given. - * - * If the global default_rt_repl_rest flag is set, then this function - * already replaced the original system defaultroute with some other - * route and it should just replace the current defaultroute with - * another one, without saving the current route. Use: demand mode, - * when pppd sets first a defaultroute it it's temporary ppp0 addresses - * and then changes the temporary addresses to the addresses for the real - * ppp connection when it has come up. - */ - -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { - /* FIXME: do the code which add the default route */ - return 0; -} - -/******************************************************************** - * - * cifdefaultroute - delete a default route through the address given. - */ - -int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { - /* FIXME: do the code which remove the default route */ - return 0; -} - -/******************************************************************** - * - * sifproxyarp - Make a proxy ARP entry for the peer. - */ - -int sifproxyarp (int unit, u_int32_t his_adr) { - /* FIXME: do we really need that in IPCP ? */ - return 0; -} - -/******************************************************************** - * - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ - -int cifproxyarp (int unit, u_int32_t his_adr) { - /* FIXME: do we really need that in IPCP ? */ - return 0; -} - -/******************************************************************** - * - * sifvjcomp - config tcp header compression - */ -int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) { - /* FIXME: add VJ support */ - return 1; -} - -/******************************************************************** - * - * get_idle_time - return how long the link has been idle. - */ -int get_idle_time(int u, struct ppp_idle *ip) { - /* FIXME: add idle time support */ - return 1; -} - - -/******************************************************************** - * - * get_loop_output - get outgoing packets from the ppp device, - * 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) { - /* FIXME: necessary for "demand", do we really need to support on-demand ? */ - 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. - */ - -u_int32_t GetMask (u_int32_t addr) { - /* FIXME: do we really need that in IPCP ? */ - return 0; -} - - -#if PPP_PROTOCOLNAME -/* 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" }, - { 0x51, "KNX Bridging Data" }, - { 0x53, "Encryption" }, - { 0x55, "Individual Link Encryption" }, - { 0x57, "IPv6" }, - { 0x59, "PPP Muxing" }, - { 0x5b, "Vendor-Specific Network Protocol" }, - { 0x61, "RTP IPHC Full Header" }, - { 0x63, "RTP IPHC Compressed TCP" }, - { 0x65, "RTP IPHC Compressed non-TCP" }, - { 0x67, "RTP IPHC Compressed UDP 8" }, - { 0x69, "RTP IPHC Compressed RTP 8" }, - { 0x6f, "Stampede Bridging" }, - { 0x73, "MP+" }, - { 0xc1, "NTCITS IPI" }, - { 0xfb, "single-link compression" }, - { 0xfd, "Compressed Datagram" }, - { 0x0201, "802.1d Hello Packets" }, - { 0x0203, "IBM Source Routing BPDU" }, - { 0x0205, "DEC LANBridge100 Spanning Tree" }, - { 0x0207, "Cisco Discovery Protocol" }, - { 0x0209, "Netcs Twin Routing" }, - { 0x020b, "STP - Scheduled Transfer Protocol" }, - { 0x020d, "EDP - Extreme Discovery Protocol" }, - { 0x0211, "Optical Supervisory Channel Protocol" }, - { 0x0213, "Optical Supervisory Channel Protocol" }, - { 0x0231, "Luxcom" }, - { 0x0233, "Sigma Network Systems" }, - { 0x0235, "Apple Client Server Protocol" }, - { 0x0281, "MPLS Unicast" }, - { 0x0283, "MPLS Multicast" }, - { 0x0285, "IEEE p1284.4 standard - data packets" }, - { 0x0287, "ETSI TETRA Network Protocol Type 1" }, - { 0x0289, "Multichannel Flow Treatment Protocol" }, - { 0x2063, "RTP IPHC Compressed TCP No Delta" }, - { 0x2065, "RTP IPHC Context State" }, - { 0x2067, "RTP IPHC Compressed UDP 16" }, - { 0x2069, "RTP IPHC Compressed RTP 16" }, - { 0x4001, "Cray Communications Control Protocol" }, - { 0x4003, "CDPD Mobile Network Registration Protocol" }, - { 0x4005, "Expand accelerator protocol" }, - { 0x4007, "ODSICP NCP" }, - { 0x4009, "DOCSIS DLL" }, - { 0x400B, "Cetacean Network Detection Protocol" }, - { 0x4021, "Stacker LZS" }, - { 0x4023, "RefTek Protocol" }, - { 0x4025, "Fibre Channel" }, - { 0x4027, "EMIT Protocols" }, - { 0x405b, "Vendor-Specific Protocol (VSP)" }, - { 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" }, - { 0x8051, "KNX Bridging Control Protocol" }, - { 0x8053, "Encryption Control Protocol" }, - { 0x8055, "Individual Link Encryption Control Protocol" }, - { 0x8057, "IPv6 Control Protocol" }, - { 0x8059, "PPP Muxing Control Protocol" }, - { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, - { 0x806f, "Stampede Bridging Control Protocol" }, - { 0x8073, "MP+ Control Protocol" }, - { 0x80c1, "NTCITS IPI Control Protocol" }, - { 0x80fb, "Single Link Compression Control Protocol" }, - { 0x80fd, "Compression Control Protocol" }, - { 0x8207, "Cisco Discovery Protocol Control" }, - { 0x8209, "Netcs Twin Routing" }, - { 0x820b, "STP - Control Protocol" }, - { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, - { 0x8235, "Apple Client Server Protocol Control" }, - { 0x8281, "MPLSCP" }, - { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, - { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, - { 0x8289, "Multichannel Flow Treatment Protocol" }, - { 0xc021, "Link Control Protocol" }, - { 0xc023, "Password Authentication Protocol" }, - { 0xc025, "Link Quality Report" }, - { 0xc027, "Shiva Password Authentication Protocol" }, - { 0xc029, "CallBack Control Protocol (CBCP)" }, - { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, - { 0xc02d, "BAP" }, - { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, - { 0xc081, "Container Control Protocol" }, - { 0xc223, "Challenge Handshake Authentication Protocol" }, - { 0xc225, "RSA Authentication Protocol" }, - { 0xc227, "Extensible Authentication Protocol" }, - { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, - { 0xc26f, "Stampede Bridging Authorization Protocol" }, - { 0xc281, "Proprietary Authentication Protocol" }, - { 0xc283, "Proprietary Authentication Protocol" }, - { 0xc481, "Proprietary Node ID Authentication Protocol" }, - { 0, NULL }, -}; - -/* - * protocol_name - find a name for a PPP protocol. - */ -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; -} -#endif /* PPP_PROTOCOLNAME */ - -/* - * new_phase - signal the start of a new phase of pppd's operation. - */ -void new_phase(int p) { - phase = p; -#if PPP_NOTIFY - /* The one willing notify support should add here the code to be notified of phase changes */ -#endif /* PPP_NOTIFY */ -} - -#if PPP_STATS_SUPPORT - -/* ---- Note on PPP Stats support ---- - * - * The one willing link stats support should add the get_ppp_stats() - * to fetch statistics from lwIP. - */ - -/* - * reset_link_stats - "reset" stats when link goes up. - */ -void reset_link_stats(int u) { - if (!get_ppp_stats(u, &old_link_stats)) - return; - gettimeofday(&start_time, NULL); -} - -/* - * 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; - - link_stats.bytes_in -= old_link_stats.bytes_in; - link_stats.bytes_out -= old_link_stats.bytes_out; - link_stats.pkts_in -= old_link_stats.pkts_in; - link_stats.pkts_out -= old_link_stats.pkts_out; -} - -void print_link_stats() { - /* - * Print connect time and statistics. - */ - if (link_stats_valid) { - int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ - info("Connect time %d.%d minutes.", t/10, t%10); - info("Sent %u bytes, received %u bytes.", - link_stats.bytes_out, link_stats.bytes_in); - link_stats_valid = 0; - } -} -#endif PPP_STATS_SUPPORT diff --git a/src/netif/ppp/session.c b/src/netif/ppp/session.c index 4194f44a..3885a759 100644 --- a/src/netif/ppp/session.c +++ b/src/netif/ppp/session.c @@ -84,8 +84,9 @@ #include #include #include -#include "pppd.h" -#include "pppmy.h" + +#include "ppp.h" + #include "session.h" #ifdef USE_PAM diff --git a/src/netif/ppp/sys-linux.c b/src/netif/ppp/sys-linux.c index 7088c2bb..a60cb075 100644 --- a/src/netif/ppp/sys-linux.c +++ b/src/netif/ppp/sys-linux.c @@ -123,8 +123,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "ipcp.h" diff --git a/src/netif/ppp/tty.c b/src/netif/ppp/tty.c index e6fcb6e4..1476c1d1 100644 --- a/src/netif/ppp/tty.c +++ b/src/netif/ppp/tty.c @@ -96,8 +96,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "lcp.h" diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 5eb00944..80aaea8b 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -50,8 +50,8 @@ #include #include -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "upap.h" static bool hide_password = 1; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 6acbb72c..8fe63ebd 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -57,8 +57,8 @@ #include #endif -#include "pppd.h" -#include "pppmy.h" +#include "ppp.h" + #include "fsm.h" #include "lcp.h" From 2ee2a1b730799f021470824afe0d46e17d0b5986 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 19:34:37 +0200 Subject: [PATCH 078/320] removed sys-linux.c --- src/netif/ppp/sys-linux.c | 2699 ------------------------------------- 1 file changed, 2699 deletions(-) delete mode 100644 src/netif/ppp/sys-linux.c diff --git a/src/netif/ppp/sys-linux.c b/src/netif/ppp/sys-linux.c deleted file mode 100644 index a60cb075..00000000 --- a/src/netif/ppp/sys-linux.c +++ /dev/null @@ -1,2699 +0,0 @@ -/* - * sys-linux.c - System-dependent procedures for setting up - * PPP interfaces on Linux systems - * - * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Derived from main.c and pppd.h, which are: - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if 0 /* BAH */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* This is in netdevice.h. However, this compile will fail miserably if - you attempt to include netdevice.h because it has so many references - to __memcpy functions which it should not attempt to do. So, since I - really don't use it, but it must be defined, define it now. */ - -#ifndef MAX_ADDR_LEN -#define MAX_ADDR_LEN 7 -#endif - -#if __GLIBC__ >= 2 -#include /* glibc 2 conflicts with linux/types.h */ -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#endif -#include -#include - -#include -#include - -#include "ppp.h" - -#include "fsm.h" -#include "ipcp.h" - -#ifdef PPP_FILTER -#include -#include -#endif /* PPP_FILTER */ - -#ifdef LOCKLIB -#include -#endif - -#ifdef INET6 -#ifndef _LINUX_IN6_H -/* - * This is in linux/include/net/ipv6.h. - */ - -struct in6_ifreq { - struct in6_addr ifr6_addr; - __u32 ifr6_prefixlen; - unsigned int ifr6_ifindex; -}; -#endif - -#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \ - memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \ - sin6.s6_addr16[0] = htons(0xfe80); \ - eui64_copy(eui64, sin6.s6_addr32[2]); \ - } while (0) - -#endif /* INET6 */ - -/* We can get an EIO error on an ioctl if the modem has hung up */ -#define ok_error(num) ((num)==EIO) - -static int tty_disc = N_TTY; /* The TTY discipline */ -static int ppp_disc = N_PPP; /* The PPP discpline */ -static int initfdflags = -1; /* Initial file descriptor flags for fd */ -static int ppp_fd = -1; /* fd which is set to PPP discipline */ -static int sock_fd = -1; /* socket for doing interface ioctls */ -static int slave_fd = -1; /* pty for old-style demand mode, slave */ -static int master_fd = -1; /* pty for old-style demand mode, master */ -#ifdef INET6 -static int sock6_fd = -1; -#endif /* INET6 */ - -/* - * For the old-style kernel driver, this is the same as ppp_fd. - * For the new-style driver, it is the fd of an instance of /dev/ppp - * which is attached to the ppp unit and is used for controlling it. - */ -int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */ - -static int chindex; /* channel index (new style driver) */ - -static fd_set in_fds; /* set of fds that wait_input waits for */ -static int max_in_fd; /* highest fd set in in_fds */ - -static int has_proxy_arp = 0; -static int driver_version = 0; -static int driver_modification = 0; -static int driver_patch = 0; -static int driver_is_old = 0; -static int restore_term = 0; /* 1 => we've munged the terminal */ -static struct termios inittermios; /* Initial TTY termios */ - -int new_style_driver = 0; - -static char loop_name[20]; -static unsigned char inbuf[512]; /* buffer for chars read from loopback */ - -static int if_is_up; /* Interface has been marked up */ -static int have_default_route; /* Gateway for default route added */ -static struct rtentry old_def_rt; /* Old default route */ -static int default_rt_repl_rest; /* replace and restore old default rt */ -static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ -static char proxy_arp_dev[16]; /* Device for proxy arp entry */ -static u_int32_t our_old_addr; /* for detecting address changes */ -static int dynaddr_set; /* 1 if ip_dynaddr set */ -static int looped; /* 1 if using loop */ -static int link_mtu; /* mtu for the link (not bundle) */ - -static struct utsname utsname; /* for the kernel version */ -static int kernel_version; -#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p)) - -#define MAX_IFS 100 - -#define FLAGS_GOOD (IFF_UP | IFF_BROADCAST) -#define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \ - IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP) - -#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr) - -/* Prototypes for procedures local to this file. */ -static int modify_flags(int fd, int clear_bits, int set_bits); -static int translate_speed (int bps); -static int baud_rate_of (int speed); -static void close_route_table (void); -static int open_route_table (void); -static int read_route_table (struct rtentry *rt); -static int defaultroute_exists (struct rtentry *rt); -static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, - char *name, int namelen); -static void decode_version (char *buf, int *version, int *mod, int *patch); -static int set_kdebugflag(int level); -static int ppp_registered(void); -static int make_ppp_unit(void); - -extern u_char inpacket_buf[]; /* borrowed from main.c */ - -/* - * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, - * if it exists. - */ - -#define SET_SA_FAMILY(addr, family) \ - memset ((char *) &(addr), '\0', sizeof(addr)); \ - addr.sa_family = (family); - -/* - * Determine if the PPP connection should still be present. - */ - -extern int hungup; - -/* new_fd is the fd of a tty */ -static void set_ppp_fd (int new_fd) -{ - ppp_fd = new_fd; - if (!new_style_driver) - ppp_dev_fd = new_fd; -} - -static int still_ppp(void) -{ - if (new_style_driver) - return !hungup && ppp_fd >= 0; - if (!hungup || ppp_fd == slave_fd) - return 1; - if (slave_fd >= 0) { - set_ppp_fd(slave_fd); - return 1; - } - return 0; -} - -/* - * modify_flags - set and clear flag bits controlling the kernel - * PPP driver. - */ -static int modify_flags(int fd, int clear_bits, int set_bits) -{ - int flags; - - if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1) - goto err; - flags = (flags & ~clear_bits) | set_bits; - if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1) - goto err; - - return 0; - - err: - if (errno != EIO) - error("Failed to set PPP kernel option flags: %m"); - return -1; -} - -/******************************************************************** - * - * sys_cleanup - restore any system state we modified before exiting: - * mark the interface down, delete default route and/or proxy arp entry. - * This shouldn't call die() because it's called from die(). - */ - -void sys_cleanup(void) -{ -/* - * Take down the device - */ - if (if_is_up) { - if_is_up = 0; - sifdown(0); - } -/* - * Delete any routes through the device. - */ - if (have_default_route) - cifdefaultroute(0, 0, 0); - - if (has_proxy_arp) - cifproxyarp(0, proxy_arp_addr); -} - -/******************************************************************** - * - * sys_close - Clean up in a child process before execing. - */ -void -sys_close(void) -{ - if (new_style_driver && ppp_dev_fd >= 0) - close(ppp_dev_fd); - if (sock_fd >= 0) - close(sock_fd); -#ifdef INET6 - if (sock6_fd >= 0) - close(sock6_fd); -#endif - if (slave_fd >= 0) - close(slave_fd); - if (master_fd >= 0) - close(master_fd); -} - -/******************************************************************** - * - * set_kdebugflag - Define the debugging level for the kernel - */ - -static int set_kdebugflag (int requested_level) -{ - if (ppp_dev_fd < 0) - return 1; - if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) { - if ( ! ok_error (errno) ) - error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__); - return (0); - } - return (1); -} - -/******************************************************************** - * - * tty_establish_ppp - Turn the serial port into a ppp interface. - */ - -int tty_establish_ppp (int tty_fd) -{ - int ret_fd; - -/* - * Ensure that the tty device is in exclusive mode. - */ - if (ioctl(tty_fd, TIOCEXCL, 0) < 0) { - if ( ! ok_error ( errno )) - warn("Couldn't make tty exclusive: %m"); - } -/* - * Demand mode - prime the old ppp device to relinquish the unit. - */ - if (!new_style_driver && looped - && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) { - error("ioctl(transfer ppp unit): %m, line %d", __LINE__); - return -1; - } -/* - * Set the current tty to the PPP discpline - */ - -#ifndef N_SYNC_PPP -#define N_SYNC_PPP 14 -#endif - ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP; - if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) { - if ( ! ok_error (errno) ) { - error("Couldn't set tty to PPP discipline: %m"); - return -1; - } - } - - ret_fd = generic_establish_ppp(tty_fd); - -#define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP) -#define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \ - | SC_LOG_FLUSH) - - if (ret_fd >= 0) { - modify_flags(ppp_fd, SC_RCVB | SC_LOGB, - (kdebugflag * SC_DEBUG) & SC_LOGB); - } else { - if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno)) - warn("Couldn't reset tty to normal line discipline: %m"); - } - - return ret_fd; -} - -/******************************************************************** - * - * generic_establish_ppp - Turn the fd into a ppp interface. - */ -int generic_establish_ppp (int fd) -{ - int x; - - if (new_style_driver) { - int flags; - - /* Open an instance of /dev/ppp and connect the channel to it */ - if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) { - error("Couldn't get channel number: %m"); - goto err; - } - dbglog("using channel %d", chindex); - fd = open("/dev/ppp", O_RDWR); - if (fd < 0) { - error("Couldn't reopen /dev/ppp: %m"); - goto err; - } - (void) fcntl(fd, F_SETFD, FD_CLOEXEC); - if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) { - error("Couldn't attach to channel %d: %m", chindex); - goto err_close; - } - flags = fcntl(fd, F_GETFL); - if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("Couldn't set /dev/ppp (channel) to nonblock: %m"); - set_ppp_fd(fd); - - if (!looped) - ifunit = -1; - if (!looped && !multilink) { - /* - * Create a new PPP unit. - */ - if (make_ppp_unit() < 0) - goto err_close; - } - - if (looped) - modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0); - - if (!multilink) { - add_fd(ppp_dev_fd); - if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) { - error("Couldn't attach to PPP unit %d: %m", ifunit); - goto err_close; - } - } - - } else { - /* - * Old-style driver: find out which interface we were given. - */ - set_ppp_fd (fd); - if (ioctl(fd, PPPIOCGUNIT, &x) < 0) { - if (ok_error (errno)) - goto err; - fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__); - } - /* Check that we got the same unit again. */ - if (looped && x != ifunit) - fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x); - ifunit = x; - - /* - * Fetch the initial file flags and reset blocking mode on the file. - */ - initfdflags = fcntl(fd, F_GETFL); - if (initfdflags == -1 || - fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { - if ( ! ok_error (errno)) - warn("Couldn't set device to non-blocking mode: %m"); - } - } - - /* - * Enable debug in the driver if requested. - */ - if (!looped) - set_kdebugflag (kdebugflag); - - looped = 0; - - return ppp_fd; - - err_close: - close(fd); - err: - return -1; -} - -/******************************************************************** - * - * tty_disestablish_ppp - Restore the serial port to normal operation. - * This shouldn't call die() because it's called from die(). - */ - -void tty_disestablish_ppp(int tty_fd) -{ - if (!hungup) { -/* - * Flush the tty output buffer so that the TIOCSETD doesn't hang. - */ - if (tcflush(tty_fd, TCIOFLUSH) < 0) - { - warn("tcflush failed: %m"); - goto flushfailed; - } -/* - * Restore the previous line discipline - */ - if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) { - if ( ! ok_error (errno)) - error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__); - } - - if (ioctl(tty_fd, TIOCNXCL, 0) < 0) { - if ( ! ok_error (errno)) - warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__); - } - - /* Reset non-blocking mode on fd. */ - if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) { - if ( ! ok_error (errno)) - warn("Couldn't restore device fd flags: %m"); - } - } -flushfailed: - initfdflags = -1; - - generic_disestablish_ppp(tty_fd); -} - -/******************************************************************** - * - * generic_disestablish_ppp - Restore device components to normal - * operation, and reconnect the ppp unit to the loopback if in demand - * mode. This shouldn't call die() because it's called from die(). - */ -void generic_disestablish_ppp(int dev_fd) -{ - if (new_style_driver) { - close(ppp_fd); - ppp_fd = -1; - if (demand) { - modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC); - looped = 1; - } else if (!doing_multilink && ppp_dev_fd >= 0) { - close(ppp_dev_fd); - remove_fd(ppp_dev_fd); - ppp_dev_fd = -1; - } - } else { - /* old-style driver */ - if (demand) - set_ppp_fd(slave_fd); - else - ppp_dev_fd = -1; - } -} - -/* - * make_ppp_unit - make a new ppp unit for ppp_dev_fd. - * Assumes new_style_driver. - */ -static int make_ppp_unit() -{ - int x, flags; - - if (ppp_dev_fd >= 0) { - dbglog("in make_ppp_unit, already had /dev/ppp open?"); - close(ppp_dev_fd); - } - ppp_dev_fd = open("/dev/ppp", O_RDWR); - if (ppp_dev_fd < 0) - fatal("Couldn't open /dev/ppp: %m"); - flags = fcntl(ppp_dev_fd, F_GETFL); - if (flags == -1 - || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("Couldn't set /dev/ppp to nonblock: %m"); - - ifunit = req_unit; - x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); - if (x < 0 && req_unit >= 0 && errno == EEXIST) { - warn("Couldn't allocate PPP unit %d as it is already in use", req_unit); - ifunit = -1; - x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); - } - if (x < 0) - error("Couldn't create new ppp unit: %m"); - return x; -} - -/* - * cfg_bundle - configure the existing bundle. - * Used in demand mode. - */ -void cfg_bundle(int mrru, int mtru, int rssn, int tssn) -{ - if (!new_style_driver) - return; - - /* set the mrru, mtu and flags */ - if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0) - error("Couldn't set MRRU: %m"); - - modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK, - ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0) - | (mrru? SC_MULTILINK: 0))); - - /* connect up the channel */ - if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0) - fatal("Couldn't attach to PPP unit %d: %m", ifunit); - add_fd(ppp_dev_fd); -} - -/* - * make_new_bundle - create a new PPP unit (i.e. a bundle) - * and connect our channel to it. This should only get called - * if `multilink' was set at the time establish_ppp was called. - * In demand mode this uses our existing bundle instead of making - * a new one. - */ -void make_new_bundle(int mrru, int mtru, int rssn, int tssn) -{ - if (!new_style_driver) - return; - - /* make us a ppp unit */ - if (make_ppp_unit() < 0) - die(1); - - /* set the mrru and flags */ - cfg_bundle(mrru, mtru, rssn, tssn); -} - -/* - * bundle_attach - attach our link to a given PPP unit. - * We assume the unit is controlled by another pppd. - */ -int bundle_attach(int ifnum) -{ - int master_fd; - - if (!new_style_driver) - return -1; - - master_fd = open("/dev/ppp", O_RDWR); - if (master_fd < 0) - fatal("Couldn't open /dev/ppp: %m"); - if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) { - if (errno == ENXIO) { - close(master_fd); - return 0; /* doesn't still exist */ - } - fatal("Couldn't attach to interface unit %d: %m\n", ifnum); - } - if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0) - fatal("Couldn't connect to interface unit %d: %m", ifnum); - modify_flags(master_fd, 0, SC_MULTILINK); - close(master_fd); - - ifunit = ifnum; - return 1; -} - -/* - * destroy_bundle - tell the driver to destroy our bundle. - */ -void destroy_bundle(void) -{ - if (ppp_dev_fd >= 0) { - close(ppp_dev_fd); - remove_fd(ppp_dev_fd); - ppp_dev_fd = -1; - } -} - -/******************************************************************** - * - * clean_check - Fetch the flags for the device and generate - * appropriate error messages. - */ -void clean_check(void) -{ - int x; - char *s; - - if (still_ppp()) { - 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 = "all had bit 7 set to 1"; - break; - - case SC_RCV_B7_1: - s = "all had bit 7 set to 0"; - break; - - case SC_RCV_EVNP: - s = "all had odd parity"; - break; - - case SC_RCV_ODDP: - s = "all had even parity"; - break; - } - - if (s != NULL) { - warn("Receive serial link is not 8-bit clean:"); - warn("Problem: %s", s); - } - } - } -} - - -/* - * List of valid speeds. - */ - -struct speed { - int speed_int, speed_val; -} speeds[] = { -#ifdef B50 - { 50, B50 }, -#endif -#ifdef B75 - { 75, B75 }, -#endif -#ifdef B110 - { 110, B110 }, -#endif -#ifdef B134 - { 134, B134 }, -#endif -#ifdef B150 - { 150, B150 }, -#endif -#ifdef B200 - { 200, B200 }, -#endif -#ifdef B300 - { 300, B300 }, -#endif -#ifdef B600 - { 600, B600 }, -#endif -#ifdef B1200 - { 1200, B1200 }, -#endif -#ifdef B1800 - { 1800, B1800 }, -#endif -#ifdef B2000 - { 2000, B2000 }, -#endif -#ifdef B2400 - { 2400, B2400 }, -#endif -#ifdef B3600 - { 3600, B3600 }, -#endif -#ifdef B4800 - { 4800, B4800 }, -#endif -#ifdef B7200 - { 7200, B7200 }, -#endif -#ifdef B9600 - { 9600, B9600 }, -#endif -#ifdef B19200 - { 19200, B19200 }, -#endif -#ifdef B38400 - { 38400, B38400 }, -#endif -#ifdef B57600 - { 57600, B57600 }, -#endif -#ifdef B76800 - { 76800, B76800 }, -#endif -#ifdef B115200 - { 115200, B115200 }, -#endif -#ifdef EXTA - { 19200, EXTA }, -#endif -#ifdef EXTB - { 38400, EXTB }, -#endif -#ifdef B230400 - { 230400, B230400 }, -#endif -#ifdef B460800 - { 460800, B460800 }, -#endif -#ifdef B921600 - { 921600, B921600 }, -#endif -#ifdef B1000000 - { 1000000, B1000000 }, -#endif -#ifdef B1152000 - { 1152000, B1152000 }, -#endif -#ifdef B1500000 - { 1500000, B1500000 }, -#endif -#ifdef B2000000 - { 2000000, B2000000 }, -#endif -#ifdef B2500000 - { 2500000, B2500000 }, -#endif -#ifdef B3000000 - { 3000000, B3000000 }, -#endif -#ifdef B3500000 - { 3500000, B3500000 }, -#endif -#ifdef B4000000 - { 4000000, B4000000 }, -#endif - { 0, 0 } -}; - -/******************************************************************** - * - * Translate from bits/second to a speed_t. - */ - -static int translate_speed (int bps) -{ - struct speed *speedp; - - if (bps != 0) { - for (speedp = speeds; speedp->speed_int; speedp++) { - if (bps == speedp->speed_int) - return speedp->speed_val; - } - warn("speed %d not supported", bps); - } - return 0; -} - -/******************************************************************** - * - * Translate from a speed_t to bits/second. - */ - -static int baud_rate_of (int speed) -{ - struct speed *speedp; - - if (speed != 0) { - for (speedp = speeds; speedp->speed_int; speedp++) { - if (speed == speedp->speed_val) - return speedp->speed_int; - } - } - return 0; -} - -/******************************************************************** - * - * 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. - */ - -void set_up_tty(int tty_fd, int local) -{ - int speed; - struct termios tios; - - setdtr(tty_fd, 1); - if (tcgetattr(tty_fd, &tios) < 0) { - if (!ok_error(errno)) - fatal("tcgetattr: %m (line %d)", __LINE__); - return; - } - - if (!restore_term) - inittermios = tios; - - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); - tios.c_cflag |= CS8 | CREAD | HUPCL; - - tios.c_iflag = IGNBRK | IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - tios.c_cc[VMIN] = 1; - tios.c_cc[VTIME] = 0; - - if (local || !modem) - tios.c_cflag ^= (CLOCAL | HUPCL); - - switch (crtscts) { - case 1: - tios.c_cflag |= CRTSCTS; - break; - - case -2: - tios.c_iflag |= IXON | IXOFF; - tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ - tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ - break; - - case -1: - tios.c_cflag &= ~CRTSCTS; - break; - - default: - break; - } - - speed = translate_speed(inspeed); - if (speed) { - cfsetospeed (&tios, speed); - cfsetispeed (&tios, speed); - } -/* - * We can't proceed if the serial port speed is B0, - * since that implies that the serial port is disabled. - */ - else { - speed = cfgetospeed(&tios); - if (speed == B0) - fatal("Baud rate for %s is 0; need explicit baud rate", devnam); - } - - while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno)) - if (errno != EINTR) - fatal("tcsetattr: %m (line %d)", __LINE__); - - baud_rate = baud_rate_of(speed); - restore_term = 1; -} - -/******************************************************************** - * - * setdtr - control the DTR line on the serial port. - * This is called from die(), so it shouldn't call die(). - */ - -void setdtr (int tty_fd, int on) -{ - int modembits = TIOCM_DTR; - - ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits); -} - -/******************************************************************** - * - * restore_tty - restore the terminal to the saved settings. - */ - -void restore_tty (int tty_fd) -{ - if (restore_term) { - restore_term = 0; -/* - * 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. - */ - if (!default_device) - inittermios.c_lflag &= ~(ECHO | ECHONL); - - if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) { - if (! ok_error (errno)) - warn("tcsetattr: %m (line %d)", __LINE__); - } - } -} - -/******************************************************************** - * - * output - Output PPP packet. - */ - -void old_output (int unit, unsigned char *p, int len) -{ - int fd = ppp_fd; - int proto; - - dump_packet("sent", p, len); - if (snoop_send_hook) snoop_send_hook(p, len); - - if (len < PPP_HDRLEN) - return; - if (new_style_driver) { - p += 2; - len -= 2; - proto = (p[0] << 8) + p[1]; - if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG)) - fd = ppp_dev_fd; - } - if (write(fd, p, len) < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS - || errno == ENXIO || errno == EIO || errno == EINTR) - warn("write: warning: %m (%d)", errno); - else - error("write: %m (%d)", errno); - } -} - -/******************************************************************** - * - * 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) -{ - fd_set ready, exc; - int n; - - ready = in_fds; - exc = in_fds; - n = select(max_in_fd + 1, &ready, NULL, &exc, timo); - if (n < 0 && errno != EINTR) - fatal("select: %m"); -} - -/* - * add_fd - add an fd to the set that wait_input waits for. - */ -void add_fd(int fd) -{ - if (fd >= FD_SETSIZE) - fatal("internal error: file descriptor too large (%d)", fd); - FD_SET(fd, &in_fds); - if (fd > max_in_fd) - max_in_fd = fd; -} - -/* - * remove_fd - remove an fd from the set that wait_input waits for. - */ -void remove_fd(int fd) -{ - FD_CLR(fd, &in_fds); -} - - -/******************************************************************** - * - * read_packet - get a PPP packet from the serial device. - */ - -int read_packet (unsigned char *buf) -{ - int len, nr; - - len = PPP_MRU + PPP_HDRLEN; - if (new_style_driver) { - *buf++ = PPP_ALLSTATIONS; - *buf++ = PPP_UI; - len -= 2; - } - nr = -1; - if (ppp_fd >= 0) { - nr = read(ppp_fd, buf, len); - if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN - && errno != EIO && errno != EINTR) - error("read: %m"); - if (nr < 0 && errno == ENXIO) - return 0; - } - if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) { - /* N.B. we read ppp_fd first since LCP packets come in there. */ - nr = read(ppp_dev_fd, buf, len); - if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN - && errno != EIO && errno != EINTR) - error("read /dev/ppp: %m"); - if (nr < 0 && errno == ENXIO) - nr = 0; - if (nr == 0 && doing_multilink) { - remove_fd(ppp_dev_fd); - bundle_eof = 1; - } - } - if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0) - nr = 0; - return (new_style_driver && nr > 0)? nr+2: nr; -} - -/******************************************************************** - * - * get_loop_output - get outgoing packets from the ppp device, - * 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; - - if (new_style_driver) { - while ((n = read_packet(inpacket_buf)) > 0) - if (loop_frame(inpacket_buf, n)) - rv = 1; - return rv; - } - - while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0) - if (loop_chars(inbuf, n)) - rv = 1; - - if (n == 0) - fatal("eof on loopback"); - - if (errno != EWOULDBLOCK && errno != EAGAIN) - fatal("read from loopback: %m(%d)", errno); - - return rv; -} - -/* - * netif_set_mtu - set the MTU on the PPP network interface. - */ -void -netif_set_mtu(int unit, int mtu) -{ - struct ifreq ifr; - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - - if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) - error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__); -} - -/* - * netif_get_mtu - get the MTU on the PPP network interface. - */ -int -netif_get_mtu(int unit) -{ - struct ifreq ifr; - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - - if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) { - error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__); - return 0; - } - return ifr.ifr_mtu; -} - -/******************************************************************** - * - * tty_send_config - configure the transmit characteristics of - * the ppp interface. - */ - -void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp) -{ - int x; - - if (!still_ppp()) - return; - link_mtu = mtu; - if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { - if (errno != EIO && errno != ENOTTY) - error("Couldn't set transmit async character map: %m"); - ++error_count; - return; - } - - x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0) - | (sync_serial? SC_SYNC: 0); - modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x); -} - -/******************************************************************** - * - * tty_set_xaccm - set the extended transmit ACCM for the interface. - */ - -void tty_set_xaccm (ext_accm accm) -{ - if (!still_ppp()) - return; - if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) { - if ( ! ok_error (errno)) - warn("ioctl(set extended ACCM): %m (line %d)", __LINE__); - } -} - -/******************************************************************** - * - * tty_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ - -void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp) -{ -/* - * If we were called because the link has gone down then there is nothing - * which may be done. Just return without incident. - */ - if (!still_ppp()) - return; -/* - * Set the receiver parameters - */ - if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { - if (errno != EIO && errno != ENOTTY) - error("Couldn't set channel receive MRU: %m"); - } - if (new_style_driver && ppp_dev_fd >= 0 - && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) - error("Couldn't set MRU in generic PPP layer: %m"); - - if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { - if (errno != EIO && errno != ENOTTY) - error("Couldn't set channel receive asyncmap: %m"); - } -} - -/******************************************************************** - * - * ccp_test - ask kernel whether a given compression method - * is acceptable for use. - */ - -int -ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit) -{ - struct ppp_option_data data; - - memset (&data, '\0', sizeof (data)); - data.ptr = opt_ptr; - data.length = opt_len; - data.transmit = for_transmit; - - if (ioctl(ppp_dev_fd, 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; - - x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0); - if (still_ppp() && ppp_dev_fd >= 0) - modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x); -} - -#ifdef PPP_FILTER -/* - * set_filters - set the active and pass filters in the kernel driver. - */ -int set_filters(struct bpf_program *pass, struct bpf_program *active) -{ - struct sock_fprog fp; - - fp.len = pass->bf_len; - fp.filter = (struct sock_filter *) pass->bf_insns; - if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) { - if (errno == ENOTTY) - warn("kernel does not support PPP filtering"); - else - error("Couldn't set pass-filter in kernel: %m"); - return 0; - } - fp.len = active->bf_len; - fp.filter = (struct sock_filter *) active->bf_insns; - if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) { - error("Couldn't set active-filter in kernel: %m"); - return 0; - } - return 1; -} -#endif /* PPP_FILTER */ - -/******************************************************************** - * - * get_idle_time - return how long the link has been idle. - */ -int -get_idle_time(u, ip) - int u; - struct ppp_idle *ip; -{ - return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0; -} - -/******************************************************************** - * - * get_ppp_stats - return statistics for the link. - */ -int -get_ppp_stats(u, stats) - int u; - struct pppd_stats *stats; -{ - printf("REPLACEORTOSSME: get_ppp_stats()\n"); -#if 0 - struct ifpppstatsreq req; - - memset (&req, 0, sizeof (req)); - - req.stats_ptr = (caddr_t) &req.stats; - strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name)); - if (ioctl(sock_fd, 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; - stats->pkts_in = req.stats.p.ppp_ipackets; - stats->pkts_out = req.stats.p.ppp_opackets; -#endif - stats->bytes_in = 0; - stats->bytes_out = 0; - stats->pkts_in = 0; - stats->pkts_out = 0; - return 1; -} - -/******************************************************************** - * - * 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 flags; - - if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) { - error("Couldn't read compression error flags: %m"); - flags = 0; - } - return flags & SC_DC_FERROR; -} - -/******************************************************************** - * - * path_to_procfs - find the path to the proc file system mount point - */ -static char proc_path[MAXPATHLEN]; -static int proc_path_len; - -static char *path_to_procfs(const char *tail) -{ - struct mntent *mntent; - FILE *fp; - - if (proc_path_len == 0) { - /* Default the mount location of /proc */ - strlcpy (proc_path, "/proc", sizeof(proc_path)); - proc_path_len = 5; - fp = fopen(MOUNTED, "r"); - if (fp != NULL) { - while ((mntent = getmntent(fp)) != NULL) { - if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) - continue; - if (strcmp(mntent->mnt_type, "proc") == 0) { - strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path)); - proc_path_len = strlen(proc_path); - break; - } - } - fclose (fp); - } - } - - strlcpy(proc_path + proc_path_len, tail, - sizeof(proc_path) - proc_path_len); - return proc_path; -} - -/* - * /proc/net/route parsing stuff. - */ -#define ROUTE_MAX_COLS 12 -FILE *route_fd = (FILE *) 0; -static char route_buffer[512]; -static int route_dev_col, route_dest_col, route_gw_col; -static int route_flags_col, route_mask_col; -static int route_num_cols; - -static int open_route_table (void); -static void close_route_table (void); -static int read_route_table (struct rtentry *rt); - -/******************************************************************** - * - * close_route_table - close the interface to the route table - */ - -static void close_route_table (void) -{ - if (route_fd != (FILE *) 0) { - fclose (route_fd); - route_fd = (FILE *) 0; - } -} - -/******************************************************************** - * - * open_route_table - open the interface to the route table - */ -static char route_delims[] = " \t\n"; - -static int open_route_table (void) -{ - char *path; - - close_route_table(); - - path = path_to_procfs("/net/route"); - route_fd = fopen (path, "r"); - if (route_fd == NULL) { - error("can't open routing table %s: %m", path); - return 0; - } - - route_dev_col = 0; /* default to usual columns */ - route_dest_col = 1; - route_gw_col = 2; - route_flags_col = 3; - route_mask_col = 7; - route_num_cols = 8; - - /* parse header line */ - if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) { - char *p = route_buffer, *q; - int col; - for (col = 0; col < ROUTE_MAX_COLS; ++col) { - int used = 1; - if ((q = strtok(p, route_delims)) == 0) - break; - if (strcasecmp(q, "iface") == 0) - route_dev_col = col; - else if (strcasecmp(q, "destination") == 0) - route_dest_col = col; - else if (strcasecmp(q, "gateway") == 0) - route_gw_col = col; - else if (strcasecmp(q, "flags") == 0) - route_flags_col = col; - else if (strcasecmp(q, "mask") == 0) - route_mask_col = col; - else - used = 0; - if (used && col >= route_num_cols) - route_num_cols = col + 1; - p = NULL; - } - } - - return 1; -} - -/******************************************************************** - * - * read_route_table - read the next entry from the route table - */ - -static int read_route_table(struct rtentry *rt) -{ - char *cols[ROUTE_MAX_COLS], *p; - int col; - - memset (rt, '\0', sizeof (struct rtentry)); - - if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) - return 0; - - p = route_buffer; - for (col = 0; col < route_num_cols; ++col) { - cols[col] = strtok(p, route_delims); - if (cols[col] == NULL) - return 0; /* didn't get enough columns */ - p = NULL; - } - - SET_SA_FAMILY (rt->rt_dst, AF_INET); - SET_SA_FAMILY (rt->rt_gateway, AF_INET); - - SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); - SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); - SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); - - rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); - rt->rt_dev = cols[route_dev_col]; - - return 1; -} - -/******************************************************************** - * - * defaultroute_exists - determine if there is a default route - */ - -static int defaultroute_exists (struct rtentry *rt) -{ - int result = 0; - - if (!open_route_table()) - return 0; - - while (read_route_table(rt) != 0) { - if ((rt->rt_flags & RTF_UP) == 0) - continue; - - if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) - continue; - if (SIN_ADDR(rt->rt_dst) == 0L) { - result = 1; - break; - } - } - - close_route_table(); - return result; -} - -/* - * have_route_to - determine if the system has any route to - * a given IP address. `addr' is in network byte order. - * Return value is 1 if yes, 0 if no, -1 if don't know. - * For demand mode to work properly, we have to ignore routes - * through our own interface. - */ -int have_route_to(u_int32_t addr) -{ - struct rtentry rt; - int result = 0; - - if (!open_route_table()) - return -1; /* don't know */ - - while (read_route_table(&rt)) { - if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0) - continue; - if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) { - result = 1; - break; - } - } - - close_route_table(); - return result; -} - -/******************************************************************** - * - * sifdefaultroute - assign a default route through the address given. - * - * If the global default_rt_repl_rest flag is set, then this function - * already replaced the original system defaultroute with some other - * route and it should just replace the current defaultroute with - * another one, without saving the current route. Use: demand mode, - * when pppd sets first a defaultroute it it's temporary ppp0 addresses - * and then changes the temporary addresses to the addresses for the real - * ppp connection when it has come up. - */ - -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) -{ - struct rtentry rt, tmp_rt; - struct rtentry *del_rt = NULL; - - if (default_rt_repl_rest) { - /* We have already reclaced the original defaultroute, if we - are called again, we will delete the current default route - and set the new default route in this function. - - this is normally only the case the doing demand: */ - if (defaultroute_exists(&tmp_rt)) - del_rt = &tmp_rt; - } else if (defaultroute_exists(&old_def_rt) && - strcmp(old_def_rt.rt_dev, ifname) != 0) { - /* We did not yet replace an existing default route, let's - check if we should save and replace a default route: */ - if (old_def_rt.rt_flags & RTF_GATEWAY) { - if (!replace) { - error("not replacing existing default route via %I", - SIN_ADDR(old_def_rt.rt_gateway)); - return 0; - } else { - /* we need to copy rt_dev because we need it permanent too: */ - char *tmp_dev = malloc(strlen(old_def_rt.rt_dev) + 1); - strcpy(tmp_dev, old_def_rt.rt_dev); - old_def_rt.rt_dev = tmp_dev; - - notice("replacing old default route to %s [%I]", - old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway)); - default_rt_repl_rest = 1; - del_rt = &old_def_rt; - } - } else - error("not replacing existing default route through %s", - old_def_rt.rt_dev); - } - - memset (&rt, 0, sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - - rt.rt_dev = ifname; - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = 0L; - } - - rt.rt_flags = RTF_UP; - if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { - if (!ok_error(errno)) - error("default route ioctl(SIOCADDRT): %m"); - return 0; - } - if (default_rt_repl_rest && del_rt) - if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) { - if (!ok_error(errno)) - error("del old default route ioctl(SIOCDELRT): %m"); - return 0; - } - - have_default_route = 1; - return 1; -} - -/******************************************************************** - * - * cifdefaultroute - delete a default route through the address given. - */ - -int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) -{ - struct rtentry rt; - - have_default_route = 0; - - memset (&rt, '\0', sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - - rt.rt_dev = ifname; - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = 0L; - } - - rt.rt_flags = RTF_UP; - if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { - if (still_ppp()) { - if (!ok_error(errno)) - error("default route ioctl(SIOCDELRT): %m"); - return 0; - } - } - if (default_rt_repl_rest) { - notice("restoring old default route to %s [%I]", - old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway)); - if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) { - if (!ok_error(errno)) - error("restore default route ioctl(SIOCADDRT): %m"); - return 0; - } - default_rt_repl_rest = 0; - } - - return 1; -} - -/******************************************************************** - * - * sifproxyarp - Make a proxy ARP entry for the peer. - */ - -int sifproxyarp (int unit, u_int32_t his_adr) -{ - struct arpreq arpreq; - char *forw_path; - - if (has_proxy_arp == 0) { - memset (&arpreq, '\0', sizeof(arpreq)); - - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - SIN_ADDR(arpreq.arp_pa) = his_adr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; -/* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev, - sizeof(proxy_arp_dev))) { - error("Cannot determine ethernet address for proxy ARP"); - return 0; - } - strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); - - if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) { - if ( ! ok_error ( errno )) - error("ioctl(SIOCSARP): %m"); - return 0; - } - proxy_arp_addr = his_adr; - has_proxy_arp = 1; - - if (tune_kernel) { - forw_path = path_to_procfs("/sys/net/ipv4/ip_forward"); - if (forw_path != 0) { - int fd = open(forw_path, O_WRONLY); - if (fd >= 0) { - if (write(fd, "1", 1) != 1) - error("Couldn't enable IP forwarding: %m"); - close(fd); - } - } - } - } - - return 1; -} - -/******************************************************************** - * - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ - -int cifproxyarp (int unit, u_int32_t his_adr) -{ - struct arpreq arpreq; - - if (has_proxy_arp) { - has_proxy_arp = 0; - memset (&arpreq, '\0', sizeof(arpreq)); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - SIN_ADDR(arpreq.arp_pa) = his_adr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; - strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); - - if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { - if ( ! ok_error ( errno )) - warn("ioctl(SIOCDARP): %m"); - return 0; - } - } - return 1; -} - -/******************************************************************** - * - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. - */ - -static int get_ether_addr (u_int32_t ipaddr, - struct sockaddr *hwaddr, - char *name, int namelen) -{ - struct ifreq *ifr, *ifend; - u_int32_t ina, mask; - char *aliasp; - struct ifreq ifreq, bestifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - - u_int32_t bestmask=0; - int found_interface = 0; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) { - if ( ! ok_error ( errno )) - error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__); - return 0; - } - -/* - * Scan through looking for an interface with an Internet - * address on the same subnet as `ipaddr'. - */ - ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { - if (ifr->ifr_addr.sa_family == AF_INET) { - ina = SIN_ADDR(ifr->ifr_addr); - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); -/* - * Check that the interface is up, and not point-to-point - * nor loopback. - */ - if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) - continue; - - if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) - continue; -/* - * Get its netmask and check that it's on the right subnet. - */ - if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - - mask = SIN_ADDR(ifreq.ifr_addr); - - if (((ipaddr ^ ina) & mask) != 0) - continue; /* no match */ - /* matched */ - if (mask >= bestmask) { - /* Compare using >= instead of > -- it is possible for - an interface to have a netmask of 0.0.0.0 */ - found_interface = 1; - bestifreq = ifreq; - bestmask = mask; - } - } - } - - if (!found_interface) return 0; - - strlcpy(name, bestifreq.ifr_name, namelen); - - /* trim off the :1 in eth0:1 */ - aliasp = strchr(name, ':'); - if (aliasp != 0) - *aliasp = 0; - - info("found interface %s for proxy arp", name); -/* - * Now get the hardware address. - */ - memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); - if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) { - error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name); - return 0; - } - - memcpy (hwaddr, - &bestifreq.ifr_hwaddr, - sizeof (struct sockaddr)); - - return 1; -} - -/* - * get_if_hwaddr - get the hardware address for the specified - * network interface device. - */ -int -get_if_hwaddr(u_char *addr, char *name) -{ - struct ifreq ifreq; - int ret, sock_fd; - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - return 0; - memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); - strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name)); - ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); - close(sock_fd); - if (ret >= 0) - memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6); - return ret; -} - -/* - * get_first_ethernet - return the name of the first ethernet-style - * interface on this system. - */ -char * -get_first_ethernet() -{ - return "eth0"; -} - -/******************************************************************** - * - * 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. - */ - -u_int32_t GetMask (u_int32_t addr) -{ - u_int32_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(sock_fd, SIOCGIFCONF, &ifc) < 0) { - if ( ! ok_error ( errno )) - warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__); - return mask; - } - - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { -/* - * Check the interface's internet address. - */ - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - ina = SIN_ADDR(ifr->ifr_addr); - if (((ntohl(ina) ^ addr) & nmask) != 0) - continue; -/* - * Check that the interface is up, and not point-to-point nor loopback. - */ - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) - continue; - - if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) - continue; -/* - * Get its netmask and OR it into our mask. - */ - if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask |= SIN_ADDR(ifreq.ifr_addr); - break; - } - return mask; -} - -/******************************************************************** - * - * Internal routine to decode the version.modification.patch level - */ - -static void decode_version (char *buf, int *version, - int *modification, int *patch) -{ - char *endp; - - *version = (int) strtoul (buf, &endp, 10); - *modification = 0; - *patch = 0; - - if (endp != buf && *endp == '.') { - buf = endp + 1; - *modification = (int) strtoul (buf, &endp, 10); - if (endp != buf && *endp == '.') { - buf = endp + 1; - *patch = (int) strtoul (buf, &buf, 10); - } - } -} - -/******************************************************************** - * - * Procedure to determine if the PPP line discipline is registered. - */ - -static int -ppp_registered(void) -{ - int local_fd; - int mfd = -1; - int ret = 0; - char slave[16]; - - /* - * We used to open the serial device and set it to the ppp line - * discipline here, in order to create a ppp unit. But that is - * not a good idea - the user might have specified a device that - * they can't open (permission, or maybe it doesn't really exist). - * So we grab a pty master/slave pair and use that. - */ - if (!get_pty(&mfd, &local_fd, slave, 0)) { - no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)"; - return 0; - } - - /* - * Try to put the device into the PPP discipline. - */ - if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) { - error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__); - } else - ret = 1; - - close(local_fd); - close(mfd); - return ret; -} - -/******************************************************************** - * - * Update the wtmp file with the appropriate user name and tty device. - */ - -void logwtmp (const char *line, const char *name, const char *host) -{ - struct utmp ut, *utp; - pid_t mypid = getpid(); -#if __GLIBC__ < 2 - int wtmp; -#endif - -/* - * Update the signon database for users. - * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996 - */ - utmpname(_PATH_UTMP); - setutent(); - while ((utp = getutent()) && (utp->ut_pid != mypid)) - /* nothing */; - - if (utp) - memcpy(&ut, utp, sizeof(ut)); - else - /* some gettys/telnetds don't initialize utmp... */ - memset(&ut, 0, sizeof(ut)); - - if (ut.ut_id[0] == 0) - strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); - - strncpy(ut.ut_user, name, sizeof(ut.ut_user)); - strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - - time(&ut.ut_time); - - ut.ut_type = USER_PROCESS; - ut.ut_pid = mypid; - - /* Insert the host name if one is supplied */ - if (*host) - strncpy (ut.ut_host, host, sizeof(ut.ut_host)); - - /* Insert the IP address of the remote system if IP is enabled */ - if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr) - memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr, - sizeof(ut.ut_addr)); - - /* CL: Makes sure that the logout works */ - if (*host == 0 && *name==0) - ut.ut_host[0]=0; - - pututline(&ut); - endutent(); -/* - * Update the wtmp file. - */ -#if __GLIBC__ >= 2 - updwtmp(_PATH_WTMP, &ut); -#else - wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY); - if (wtmp >= 0) { - flock(wtmp, LOCK_EX); - - if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut)) - warn("error writing %s: %m", _PATH_WTMP); - - flock(wtmp, LOCK_UN); - - close (wtmp); - } -#endif -} - - -/******************************************************************** - * - * sifvjcomp - config tcp header compression - */ - -int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) -{ - u_int x; - - if (vjcomp) { - if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) - error("Couldn't set up TCP header compression: %m"); - vjcomp = 0; - } - - x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID); - modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x); - - return 1; -} - -#if 0 -/******************************************************************** - * - * sifup - Config the interface up and enable IP packets to pass. - */ - -int sifup(int u) -{ - printf("REPLACE ME: sifup() called\n"); - return 1; - - struct ifreq ifr; - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__); - return 0; - } - - ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT); - if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__); - return 0; - } - if_is_up++; - - return 1; -} -#endif - -/******************************************************************** - * - * sifdown - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ - -int sifdown (int u) -{ - printf("REPLACE ME: sifdown() called\n"); - return 1; - - struct ifreq ifr; - - if (if_is_up && --if_is_up > 0) - return 1; - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__); - return 0; - } - - ifr.ifr_flags &= ~IFF_UP; - ifr.ifr_flags |= IFF_POINTOPOINT; - if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__); - return 0; - } - return 1; -} - -#if 0 -/******************************************************************** - * - * sifaddr - Config the interface IP addresses and netmask. - */ - -int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, - u_int32_t net_mask) -{ - printf("REPLACE ME: sifaddr() called\n"); - return 1; - - struct ifreq ifr; - struct rtentry rt; - - memset (&ifr, '\0', sizeof (ifr)); - memset (&rt, '\0', sizeof (rt)); - - SET_SA_FAMILY (ifr.ifr_addr, AF_INET); - SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); - SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); - - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); -/* - * Set our IP address - */ - SIN_ADDR(ifr.ifr_addr) = our_adr; - if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (errno != EEXIST) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); - } - else { - warn("ioctl(SIOCSIFADDR): Address already exists"); - } - return (0); - } -/* - * Set the gateway address - */ - if (his_adr != 0) { - SIN_ADDR(ifr.ifr_dstaddr) = his_adr; - if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__); - return (0); - } - } -/* - * Set the netmask. - * For recent kernels, force the netmask to 255.255.255.255. - */ - if (kernel_version >= KVERSION(2,1,16)) - net_mask = ~0L; - if (net_mask != 0) { - SIN_ADDR(ifr.ifr_netmask) = net_mask; - if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__); - return (0); - } - } -/* - * Add the device route - */ - if (kernel_version < KVERSION(2,1,16)) { - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; - - SIN_ADDR(rt.rt_gateway) = 0L; - SIN_ADDR(rt.rt_dst) = his_adr; - rt.rt_flags = RTF_UP | RTF_HOST; - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = -1L; - } - - if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__); - return (0); - } - } - - /* set ip_dynaddr in demand mode if address changes */ - if (demand && tune_kernel && !dynaddr_set - && our_old_addr && our_old_addr != our_adr) { - /* set ip_dynaddr if possible */ - char *path; - int fd; - - path = path_to_procfs("/sys/net/ipv4/ip_dynaddr"); - if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) { - if (write(fd, "1", 1) != 1) - error("Couldn't enable dynamic IP addressing: %m"); - close(fd); - } - dynaddr_set = 1; /* only 1 attempt */ - } - our_old_addr = 0; - - return 1; -} -#endif - -/******************************************************************** - * - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ - -int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) -{ - printf("REPLACE ME: cifaddr() called\n"); - return 1; - - struct ifreq ifr; - - if (kernel_version < KVERSION(2,1,16)) { -/* - * Delete the route through the device - */ - struct rtentry rt; - memset (&rt, '\0', sizeof (rt)); - - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; - - SIN_ADDR(rt.rt_gateway) = 0; - SIN_ADDR(rt.rt_dst) = his_adr; - rt.rt_flags = RTF_UP | RTF_HOST; - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = -1L; - } - - if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { - if (still_ppp() && ! ok_error (errno)) - error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__); - return (0); - } - } - - /* This way it is possible to have an IPX-only or IPv6-only interface */ - memset(&ifr, 0, sizeof(ifr)); - SET_SA_FAMILY(ifr.ifr_addr, AF_INET); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) { - error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); - return 0; - } - } - - our_old_addr = our_adr; - - return 1; -} - -#ifdef INET6 -/******************************************************************** - * - * sif6addr - Config the interface with an IPv6 link-local address - */ -int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) -{ - struct in6_ifreq ifr6; - struct ifreq ifr; - struct in6_rtmsg rt6; - - if (sock6_fd < 0) { - errno = -sock6_fd; - error("IPv6 socket creation failed: %m"); - return 0; - } - memset(&ifr, 0, sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { - error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__); - return 0; - } - - /* Local interface */ - memset(&ifr6, 0, sizeof(ifr6)); - IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); - ifr6.ifr6_ifindex = ifr.ifr_ifindex; - ifr6.ifr6_prefixlen = 10; - - if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { - error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); - return 0; - } - - /* Route to remote host */ - memset(&rt6, 0, sizeof(rt6)); - IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); - rt6.rtmsg_flags = RTF_UP; - rt6.rtmsg_dst_len = 10; - rt6.rtmsg_ifindex = ifr.ifr_ifindex; - rt6.rtmsg_metric = 1; - - if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { - error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__); - return 0; - } - - return 1; -} - - -/******************************************************************** - * - * cif6addr - Remove IPv6 address from interface - */ -int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) -{ - struct ifreq ifr; - struct in6_ifreq ifr6; - - if (sock6_fd < 0) { - errno = -sock6_fd; - error("IPv6 socket creation failed: %m"); - return 0; - } - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { - error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__); - return 0; - } - - memset(&ifr6, 0, sizeof(ifr6)); - IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); - ifr6.ifr6_ifindex = ifr.ifr_ifindex; - ifr6.ifr6_prefixlen = 10; - - if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { - if (errno != EADDRNOTAVAIL) { - if (! ok_error (errno)) - error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__); - } - else { - warn("cif6addr: ioctl(SIOCDIFADDR): No such address"); - } - return (0); - } - return 1; -} -#endif /* INET6 */ - -/* - * get_pty - get a pty master/slave pair and chown the slave side - * to the uid given. Assumes slave_name points to >= 16 bytes of space. - */ -int -get_pty(master_fdp, slave_fdp, slave_name, uid) - int *master_fdp; - int *slave_fdp; - char *slave_name; - int uid; -{ - int i, mfd, sfd = -1; - char pty_name[16]; - struct termios tios; - -#ifdef TIOCGPTN - /* - * Try the unix98 way first. - */ - mfd = open("/dev/ptmx", O_RDWR); - if (mfd >= 0) { - int ptn; - if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { - slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn); - chmod(pty_name, S_IRUSR | S_IWUSR); -#ifdef TIOCSPTLCK - ptn = 0; - if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) - warn("Couldn't unlock pty slave %s: %m", pty_name); -#endif - if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) - warn("Couldn't open pty slave %s: %m", pty_name); - } - } -#endif /* TIOCGPTN */ - - if (sfd < 0) { - /* the old way - scan through the pty name space */ - for (i = 0; i < 64; ++i) { - slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", - 'p' + i / 16, i % 16); - mfd = open(pty_name, O_RDWR, 0); - if (mfd >= 0) { - pty_name[5] = 't'; - sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); - if (sfd >= 0) { - fchown(sfd, uid, -1); - fchmod(sfd, S_IRUSR | S_IWUSR); - break; - } - close(mfd); - } - } - } - - if (sfd < 0) - return 0; - - strlcpy(slave_name, pty_name, 16); - *master_fdp = mfd; - *slave_fdp = sfd; - if (tcgetattr(sfd, &tios) == 0) { - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); - tios.c_cflag |= CS8 | CREAD | CLOCAL; - tios.c_iflag = IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) - warn("couldn't set attributes on pty: %m"); - } else - warn("couldn't get attributes on pty: %m"); - - return 1; -} - -/******************************************************************** - * - * open_loopback - open the device we use for getting packets - * in demand mode. Under Linux, we use a pty master/slave pair. - */ -int -open_ppp_loopback(void) -{ - int flags; - - looped = 1; - if (new_style_driver) { - /* allocate ourselves a ppp unit */ - if (make_ppp_unit() < 0) - die(1); - modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC); - set_kdebugflag(kdebugflag); - ppp_fd = -1; - return ppp_dev_fd; - } - - if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) - fatal("No free pty for loopback"); - - set_ppp_fd(slave_fd); - - flags = fcntl(master_fd, F_GETFL); - if (flags == -1 || - fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set master loopback to nonblock: %m"); - - flags = fcntl(ppp_fd, F_GETFL); - if (flags == -1 || - fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set slave loopback to nonblock: %m"); - - if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) - fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__); -/* - * Find out which interface we were given. - */ - if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) - fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__); -/* - * Enable debug in the driver if requested. - */ - set_kdebugflag (kdebugflag); - - return master_fd; -} - -#if 0 -/******************************************************************** - * - * sifnpmode - Set the mode for handling packets for a given NP. - */ - -int -sifnpmode(u, proto, mode) - int u; - int proto; - enum NPmode mode; -{ - printf("REPLACE ME: sifnpmode() called\n"); - return 1; - - struct npioctl npi; - - npi.protocol = proto; - npi.mode = mode; - if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { - if (! ok_error (errno)) - error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode); - return 0; - } - return 1; -} -#endif - -/* - * Use the hostname as part of the random number seed. - */ -int -get_host_seed() -{ - int h; - char *p = hostname; - - h = 407; - for (p = hostname; *p != 0; ++p) - h = h * 37 + *p; - return h; -} - -/******************************************************************** - * - * sys_check_options - check the options that the user specified - */ - -int -sys_check_options(void) -{ - if (demand && driver_is_old) { - option_error("demand dialling is not supported by kernel driver " - "version %d.%d.%d", driver_version, driver_modification, - driver_patch); - return 0; - } - if (multilink && !new_style_driver) { - warn("Warning: multilink is not supported by the kernel driver"); - multilink = 0; - } - return 1; -} - -#ifdef INET6 -/* - * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI - * - * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes - * that the system has a properly configured Ethernet interface for this - * function to return non-zero. - */ -int -ether_to_eui64(eui64_t *p_eui64) -{ - struct ifreq ifr; - int skfd; - const unsigned char *ptr; - - skfd = socket(PF_INET6, SOCK_DGRAM, 0); - if(skfd == -1) - { - warn("could not open IPv6 socket"); - return 0; - } - - strcpy(ifr.ifr_name, "eth0"); - if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) - { - close(skfd); - warn("could not obtain hardware address for eth0"); - return 0; - } - close(skfd); - - /* - * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] - */ - ptr = ifr.ifr_hwaddr.sa_data; - p_eui64->e8[0] = ptr[0] | 0x02; - p_eui64->e8[1] = ptr[1]; - p_eui64->e8[2] = ptr[2]; - p_eui64->e8[3] = 0xFF; - p_eui64->e8[4] = 0xFE; - p_eui64->e8[5] = ptr[3]; - p_eui64->e8[6] = ptr[4]; - p_eui64->e8[7] = ptr[5]; - - return 1; -} -#endif - -#endif /* BAH */ From b4d59fd52de45c8c4012590f1a9ca6bb1eedfa26 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 19:37:40 +0200 Subject: [PATCH 079/320] removed headers that were initially copied but not used (yet) --- src/netif/ppp/eui64.h | 114 --------------------------- src/netif/ppp/ipv6cp.h | 171 ----------------------------------------- src/netif/ppp/mppe.h | 121 ----------------------------- 3 files changed, 406 deletions(-) delete mode 100644 src/netif/ppp/eui64.h delete mode 100644 src/netif/ppp/ipv6cp.h delete mode 100644 src/netif/ppp/mppe.h diff --git a/src/netif/ppp/eui64.h b/src/netif/ppp/eui64.h deleted file mode 100644 index 0f6b6fd4..00000000 --- a/src/netif/ppp/eui64.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * eui64.h - EUI64 routines for IPv6CP. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $ -*/ - -#ifndef __EUI64_H__ -#define __EUI64_H__ - -#if !defined(INET6) -#error "this file should only be included when INET6 is defined" -#endif /* not defined(INET6) */ - -#if defined(SOL2) -#include - -typedef union { - uint8_t e8[8]; /* lower 64-bit IPv6 address */ - uint32_t e32[2]; /* lower 64-bit IPv6 address */ -} eui64_t; - -/* - * Declare the two below, since in.h only defines them when _KERNEL - * is declared - which shouldn't be true when dealing with user-land programs - */ -#define s6_addr8 _S6_un._S6_u8 -#define s6_addr32 _S6_un._S6_u32 - -#else /* else if not defined(SOL2) */ - -/* - * TODO: - * - * Maybe this should be done by processing struct in6_addr directly... - */ -typedef union -{ - u_int8_t e8[8]; - u_int16_t e16[4]; - u_int32_t e32[2]; -} eui64_t; - -#endif /* defined(SOL2) */ - -#define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) -#define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ - ((e).e32[1] == (o).e32[1])) -#define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; - -#define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) - -#define eui64_magic(e) do { \ - (e).e32[0] = magic(); \ - (e).e32[1] = magic(); \ - (e).e8[0] &= ~2; \ - } while (0) -#define eui64_magic_nz(x) do { \ - eui64_magic(x); \ - } while (eui64_iszero(x)) -#define eui64_magic_ne(x, y) do { \ - eui64_magic(x); \ - } while (eui64_equals(x, y)) - -#define eui64_get(ll, cp) do { \ - eui64_copy((*cp), (ll)); \ - (cp) += sizeof(eui64_t); \ - } while (0) - -#define eui64_put(ll, cp) do { \ - eui64_copy((ll), (*cp)); \ - (cp) += sizeof(eui64_t); \ - } while (0) - -#define eui64_set32(e, l) do { \ - (e).e32[0] = 0; \ - (e).e32[1] = htonl(l); \ - } while (0) -#define eui64_setlo32(e, l) eui64_set32(e, l) - -char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */ - -#endif /* __EUI64_H__ */ - diff --git a/src/netif/ppp/ipv6cp.h b/src/netif/ppp/ipv6cp.h deleted file mode 100644 index cc4568de..00000000 --- a/src/netif/ppp/ipv6cp.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * ipv6cp.h - PPP IPV6 Control Protocol. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -/* Original version, based on RFC2023 : - - Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt - Économique ayant pour membres BULL S.A. et l'INRIA). - - Ce logiciel informatique est disponible aux conditions - usuelles dans la recherche, c'est-à-dire qu'il peut - être utilisé, copié, modifié, distribué à l'unique - condition que ce texte soit conservé afin que - l'origine de ce logiciel soit reconnue. - - Le nom de l'Institut National de Recherche en Informatique - et en Automatique (INRIA), de l'IMAG, ou d'une personne morale - ou physique ayant participé à l'élaboration de ce logiciel ne peut - être utilisé sans son accord préalable explicite. - - Ce logiciel est fourni tel quel sans aucune garantie, - support ou responsabilité d'aucune sorte. - Ce logiciel est dérivé de sources d'origine - "University of California at Berkeley" et - "Digital Equipment Corporation" couvertes par des copyrights. - - L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) - est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National - Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant - sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). - - This work has been done in the context of GIE DYADE (joint R & D venture - between BULL S.A. and INRIA). - - This software is available with usual "research" terms - with the aim of retain credits of the software. - Permission to use, copy, modify and distribute this software for any - purpose and without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies, - and the name of INRIA, IMAG, or any contributor not be used in advertising - or publicity pertaining to this material without the prior explicit - permission. The software is provided "as is" without any - warranties, support or liabilities of any kind. - This software is derived from source code from - "University of California at Berkeley" and - "Digital Equipment Corporation" protected by copyrights. - - Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) - is a federation of seven research units funded by the CNRS, National - Polytechnic Institute of Grenoble and University Joseph Fourier. - The research unit in Software, Systems, Networks (LSR) is member of IMAG. -*/ - -/* - * Derived from : - * - * - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $ - */ - -/* - * Options. - */ -#define CI_IFACEID 1 /* Interface Identifier */ -#define CI_COMPRESSTYPE 2 /* Compression Type */ - -/* No compression types yet defined. - *#define IPV6CP_COMP 0x004f - */ -typedef struct ipv6cp_options { - int neg_ifaceid; /* Negotiate interface identifier? */ - int req_ifaceid; /* Ask peer to send interface identifier? */ - int accept_local; /* accept peer's value for iface id? */ - int opt_local; /* ourtoken set by option */ - int opt_remote; /* histoken set by option */ - int use_ip; /* use IP as interface identifier */ -#if defined(SOL2) || defined(__linux__) - int use_persistent; /* use uniquely persistent value for address */ -#endif /* defined(SOL2) */ - int neg_vj; /* Van Jacobson Compression? */ - u_short vj_protocol; /* protocol value to use in VJ option */ - eui64_t ourid, hisid; /* Interface identifiers */ -} ipv6cp_options; - -extern fsm ipv6cp_fsm[]; -extern ipv6cp_options ipv6cp_wantoptions[]; -extern ipv6cp_options ipv6cp_gotoptions[]; -extern ipv6cp_options ipv6cp_allowoptions[]; -extern ipv6cp_options ipv6cp_hisoptions[]; - -extern struct protent ipv6cp_protent; diff --git a/src/netif/ppp/mppe.h b/src/netif/ppp/mppe.h deleted file mode 100644 index 5eb3b37a..00000000 --- a/src/netif/ppp/mppe.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * mppe.h - Definitions for MPPE - * - * Copyright (c) 2008 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define MPPE_PAD 4 /* MPPE growth per frame */ -#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ - -/* option bits for ccp_options.mppe */ -#define MPPE_OPT_40 0x01 /* 40 bit */ -#define MPPE_OPT_128 0x02 /* 128 bit */ -#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */ -/* unsupported opts */ -#define MPPE_OPT_56 0x08 /* 56 bit */ -#define MPPE_OPT_MPPC 0x10 /* MPPC compression */ -#define MPPE_OPT_D 0x20 /* Unknown */ -#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D) -#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */ - -/* - * This is not nice ... the alternative is a bitfield struct though. - * And unfortunately, we cannot share the same bits for the option - * names above since C and H are the same bit. We could do a u_int32 - * but then we have to do a htonl() all the time and/or we still need - * to know which octet is which. - */ -#define MPPE_C_BIT 0x01 /* MPPC */ -#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */ -#define MPPE_L_BIT 0x20 /* 40-bit */ -#define MPPE_S_BIT 0x40 /* 128-bit */ -#define MPPE_M_BIT 0x80 /* 56-bit, not supported */ -#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */ - -/* Does not include H bit; used for least significant octet only. */ -#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT) - -/* Build a CI from mppe opts (see RFC 3078) */ -#define MPPE_OPTS_TO_CI(opts, ci) \ - do { \ - u_char *ptr = ci; /* u_char[4] */ \ - \ - /* H bit */ \ - if (opts & MPPE_OPT_STATEFUL) \ - *ptr++ = 0x0; \ - else \ - *ptr++ = MPPE_H_BIT; \ - *ptr++ = 0; \ - *ptr++ = 0; \ - \ - /* S,L bits */ \ - *ptr = 0; \ - if (opts & MPPE_OPT_128) \ - *ptr |= MPPE_S_BIT; \ - if (opts & MPPE_OPT_40) \ - *ptr |= MPPE_L_BIT; \ - /* M,D,C bits not supported */ \ - } while (/* CONSTCOND */ 0) - -/* The reverse of the above */ -#define MPPE_CI_TO_OPTS(ci, opts) \ - do { \ - u_char *ptr = ci; /* u_char[4] */ \ - \ - opts = 0; \ - \ - /* H bit */ \ - if (!(ptr[0] & MPPE_H_BIT)) \ - opts |= MPPE_OPT_STATEFUL; \ - \ - /* S,L bits */ \ - if (ptr[3] & MPPE_S_BIT) \ - opts |= MPPE_OPT_128; \ - if (ptr[3] & MPPE_L_BIT) \ - opts |= MPPE_OPT_40; \ - \ - /* M,D,C bits */ \ - if (ptr[3] & MPPE_M_BIT) \ - opts |= MPPE_OPT_56; \ - if (ptr[3] & MPPE_D_BIT) \ - opts |= MPPE_OPT_D; \ - if (ptr[3] & MPPE_C_BIT) \ - opts |= MPPE_OPT_MPPC; \ - \ - /* Other bits */ \ - if (ptr[0] & ~MPPE_H_BIT) \ - opts |= MPPE_OPT_UNKNOWN; \ - if (ptr[1] || ptr[2]) \ - opts |= MPPE_OPT_UNKNOWN; \ - if (ptr[3] & ~MPPE_ALL_BITS) \ - opts |= MPPE_OPT_UNKNOWN; \ - } while (/* CONSTCOND */ 0) From d143acfc762338b3f571ebf807424549127afb04 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 20:46:52 +0200 Subject: [PATCH 080/320] fixed all PPP compilation warnings with -Wall --- src/netif/ppp/auth.c | 11 ++++-- src/netif/ppp/fsm.c | 2 +- src/netif/ppp/ipcp.c | 25 ++++++++----- src/netif/ppp/lcp.c | 6 ++- src/netif/ppp/magic.c | 2 +- src/netif/ppp/ppp.c | 84 +++++++++++++++++++++++++----------------- src/netif/ppp/ppp.h | 32 +++------------- src/netif/ppp/ppp_oe.c | 8 ++-- src/netif/ppp/upap.c | 7 +++- src/netif/ppp/upap.h | 2 + src/netif/ppp/utils.c | 9 +++-- 11 files changed, 105 insertions(+), 83 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index b8c65355..72b40561 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -751,7 +751,9 @@ link_established(unit) int unit; { int auth; +#if 0 /* UNUSED */ lcp_options *wo = &lcp_wantoptions[unit]; +#endif /* UNUSED */ lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ho = &lcp_hisoptions[unit]; int i; @@ -864,7 +866,9 @@ static void network_phase(unit) int unit; { +#if 0 /* UNUSED */ lcp_options *go = &lcp_gotoptions[unit]; +#endif /* UNUSED */ #if 0 /* UNUSED */ /* Log calling number. */ @@ -919,8 +923,10 @@ void start_networks(unit) int unit; { +#if CCP_SUPPORT || ECP_SUPPORT int i; struct protent *protp; +#endif /* CCP_SUPPORT || ECP_SUPPORT */ #if ECP_SUPPORT int ecp_required; #endif /* ECP_SUPPORT */ @@ -1950,14 +1956,11 @@ get_secret(unit, client, server, secret, secret_len, am_server) int am_server; { int len; - struct wordlist *addrs; LWIP_UNUSED_ARG(unit); LWIP_UNUSED_ARG(server); LWIP_UNUSED_ARG(am_server); - addrs = NULL; - if(!client || !client[0] || strcmp(client, ppp_settings.user)) { return 0; } @@ -1993,6 +1996,8 @@ get_secret(unit, client, server, secret, secret_len, am_server) char *filename; struct wordlist *addrs, *opts; char secbuf[MAXWORDLEN]; + struct wordlist *addrs; + addrs = NULL; if (!am_server && ppp_settings.passwd[0] != 0) { strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf)); diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 55030a02..fa94ea5f 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -423,7 +423,7 @@ fsm_rconfreq(f, id, inp, len) { int code, reject_if_disagree; - printf("fsm_rconfreq() called, f->state = %d\n"); + printf("fsm_rconfreq() called, f->state = %d\n", f->state); switch( f->state ){ case CLOSED: diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 70713701..992db3cd 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -98,8 +98,10 @@ static bool usepeerdns; /* Ask peer for DNS addrs */ static int ipcp_is_up; /* have called np_up() */ static int ipcp_is_open; /* haven't called np_finished() */ static bool ask_for_local; /* request our address from peer */ +#if 0 /* UNUSED */ static char vj_value[8]; /* string form of vj option value */ static char netmask_str[20]; /* string form of netmask value */ +#endif /* UNUSED */ /* * Callbacks for fsm code. (CI = Configuration Information) @@ -138,13 +140,13 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ /* * Command-line options. */ +#if PPP_OPTIONS static int setvjslots __P((char **)); static int setdnsaddr __P((char **)); static int setwinsaddr __P((char **)); static int setnetmask __P((char **)); int setipaddr __P((char *, char **, int)); -#if PPP_OPTIONS static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); static option_t ipcp_option_list[] = { @@ -263,12 +265,16 @@ static void ipcp_protrej __P((int)); static int ipcp_printpkt __P((u_char *, int, void (*) __P((void *, char *, ...)), void *)); #endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS static void ip_check_options __P((void)); +#endif /* PPP_OPTIONS */ #if DEMAND_SUPPORT static int ip_demand_conf __P((int)); static int ip_active_pkt __P((u_char *, int)); #endif /* DEMAND_SUPPORT */ +#if 0 /* UNUSED */ static void create_resolv __P((u_int32_t, u_int32_t)); +#endif /* UNUSED */ struct protent ipcp_protent = { PPP_IPCP, @@ -331,7 +337,7 @@ u_int32_t ipaddr; /* * Option parsing. */ - +#if PPP_OPTIONS /* * setvjslots - set maximum number of connection slots for VJ compression */ @@ -427,7 +433,6 @@ setwinsaddr(argv) return (1); } -#if 0 /* UNUSED */ /* * setipaddr - Set the IP address * If doit is 0, the call is to check whether this option is @@ -500,9 +505,7 @@ setipaddr(arg, argv, doit) return 1; } -#endif /* UNUSED */ -#if PPP_OPTIONS static void printipaddr(opt, printer, arg) option_t *opt; @@ -517,7 +520,6 @@ printipaddr(opt, printer, arg) if (wo->hisaddr != 0) printer(arg, "%I", wo->hisaddr); } -#endif /* PPP_OPTIONS */ /* * setnetmask - set the netmask to be used on the interface. @@ -582,7 +584,7 @@ parse_dotted_ip(p, vp) *vp = v; return p - p0; } - +#endif /* PPP_OPTIONS */ /* * ipcp_init - Initialize IPCP. @@ -1836,11 +1838,14 @@ ipcp_up(f) script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); if (go->dnsaddr[1]) script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); +#endif /* UNUSED */ if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + /* FIXME: set here the DNS servers ? */ +#if 0 /* UNUSED */ script_setenv("USEPEERDNS", "1", 0); create_resolv(go->dnsaddr[0], go->dnsaddr[1]); - } #endif /* UNUSED */ + } /* FIXME: check why it fails, just to know */ #if 0 /* Unused */ @@ -2074,6 +2079,7 @@ ipcp_finished(f) } +#if 0 /* UNUSED */ /* * create_resolv - create the replacement resolv.conf file */ @@ -2081,8 +2087,9 @@ static void create_resolv(peerdns1, peerdns2) u_int32_t peerdns1, peerdns2; { - /* FIXME: do we need to set here the DNS servers ? */ + } +#endif /* UNUSED */ #if PRINTPKT_SUPPORT /* diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 5ee79659..52ca0fee 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -80,7 +80,9 @@ bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ bool lax_recv = 0; /* accept control chars in asyncmap */ bool noendpoint = 0; /* don't send/accept endpoint discriminator */ +#if PPP_OPTIONS static int noopt __P((char **)); +#endif /* PPP_OPTIONS */ #ifdef HAVE_MULTILINK static int setendpoint __P((char **)); @@ -315,6 +317,7 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL; #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") +#if PPP_OPTIONS /* * noopt - Disable all options (why?). */ @@ -327,6 +330,7 @@ noopt(argv) return (1); } +#endif /* PPP_OPTIONS */ #ifdef HAVE_MULTILINK static int @@ -1995,7 +1999,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); } else -#endif CHAP_SUPPORT +#endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if(1) { PUTCHAR(CILEN_SHORT, nakp); diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index ea92060c..9fe4e08b 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -182,7 +182,7 @@ void random_bytes(unsigned char *buf, u32_t buf_len) { u32_t magic() { u32_t new_rand; - random_bytes((char *)&new_rand, sizeof(new_rand)); + random_bytes((unsigned char *)&new_rand, sizeof(new_rand)); return new_rand; } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index df279dc4..79fc54db 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -10,16 +10,16 @@ #include "lwip/pbuf.h" #include "lwip/stats.h" #include "lwip/sys.h" - -#if PPPOE_SUPPORT -#include "netif/ppp_oe.h" -#endif /* PPPOE_SUPPORT */ +#include "lwip/tcpip.h" +#include "lwip/api.h" +#include "lwip/snmp.h" #include "ppp.h" #include "fsm.h" #include "lcp.h" #include "ipcp.h" +#include "magic.h" #if PAP_SUPPORT #include "upap.h" @@ -37,6 +37,9 @@ #include "ecp.h" #endif /* EAP_SUPPORT */ +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ /* * Global variables. @@ -176,37 +179,22 @@ typedef struct PPPControl_s { } PPPControl; + +/* Prototypes for procedures local to this file. */ + +static void pppStart(int pd); /** Initiate LCP open request */ +static void ppp_input(void *arg); +static void pppOverEthernetLinkStatusCB(int pd, int up); +static err_t pppifOutputOverEthernet(int pd, struct pbuf *p); +static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); +static err_t pppifNetifInit(struct netif *netif); + + /******************************/ /*** PUBLIC DATA STRUCTURES ***/ /******************************/ static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ - -struct pbuf * pppSingleBuf(struct pbuf *p) { - struct pbuf *q, *b; - u_char *pl; - - if(p->tot_len == p->len) { - return p; - } - - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if(!q) { - PPPDEBUG(LOG_ERR, - ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); - return p; /* live dangerously */ - } - - for(b = p, pl = q->payload; b != NULL; b = b->next) { - MEMCPY(pl, b->payload, b->len); - pl += b->len; - } - - pbuf_free(p); - - return q; -} - /** Input helper struct, must be packed since it is stored to pbuf->payload, * which might be unaligned. */ @@ -309,7 +297,7 @@ static void ppp_input(void *arg) { PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); + PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d\n", pd, nb->len)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; @@ -329,8 +317,8 @@ static void ppp_input(void *arg) { #else /* PPPOS_SUPPORT && VJ_SUPPORT */ /* No handler for this protocol so drop the packet. */ PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", - pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); + ("pppInput[%d]: drop VJ UnComp in %d\n", + pd, nb->len)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; @@ -531,6 +519,8 @@ int ppp_init(void) { */ for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(0); + + return 0; } void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { @@ -688,6 +678,31 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha return pd; } +struct pbuf * pppSingleBuf(struct pbuf *p) { + struct pbuf *q, *b; + u_char *pl; + + if(p->tot_len == p->len) { + return p; + } + + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(!q) { + PPPDEBUG(LOG_ERR, + ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); + return p; /* live dangerously */ + } + + for(b = p, pl = q->payload; b != NULL; b = b->next) { + MEMCPY(pl, b->payload, b->len); + pl += b->len; + } + + pbuf_free(p); + + return q; +} + /* FIXME: maybe we should pass in two arguments pppInputHeader and payload * this is totally stupid to make room for it and then modify the packet directly * or it is used in output ? have to find out... @@ -1251,6 +1266,7 @@ void netif_set_mtu(int unit, int mtu) { */ int netif_get_mtu(int mtu) { /* FIXME: get lwIP MTU */ + return 1492; } /******************************************************************** @@ -1555,4 +1571,4 @@ void print_link_stats() { link_stats_valid = 0; } } -#endif PPP_STATS_SUPPORT +#endif /* PPP_STATS_SUPPORT */ diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 6bcc14ad..502b539d 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -12,6 +12,7 @@ #include "lwip/netif.h" #include "lwip/def.h" +#include "lwip/timers.h" #include "pppdebug.h" @@ -286,17 +287,6 @@ struct ppp_settings { struct ppp_settings ppp_settings; -/* FIXME: move all private stuff into a new include */ - -/************************* - *** PRIVATE FUNCTIONS *** - *************************/ - -/** Initiate LCP open request */ -static void pppStart(int pd); - -struct pbuf *pppSingleBuf(struct pbuf *p); - /************************ *** PUBLIC FUNCTIONS *** @@ -333,12 +323,6 @@ enum pppAuthType { #endif /* CHAP_SUPPORT */ }; -struct pbuf * pppSingleBuf(struct pbuf *p); - -static void pppStart(int pd); - -static void ppp_input(void *arg); - int ppp_init(void); void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); @@ -353,16 +337,14 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); +/* -- private */ + +struct pbuf * pppSingleBuf(struct pbuf *p); + void pppInProcOverEthernet(int pd, struct pbuf *pb); void pppOverEthernetInitFailed(int pd); -static void pppOverEthernetLinkStatusCB(int pd, int up); - -static err_t pppifOutputOverEthernet(int pd, struct pbuf *p); - -static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); - u_short pppMTU(int pd); int pppWriteOverEthernet(int pd, const u_char *s, int n); @@ -379,8 +361,6 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp); int sifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr); -static err_t pppifNetifInit(struct netif *netif); - int sifup(int u); int sifdown (int u); @@ -531,7 +511,7 @@ int get_secret __P((int, char *, char *, char *, int *, int)); /* get "secret" for chap */ /* Procedures exported from ipcp.c */ -int parse_dotted_ip __P((char *, u_int32_t *)); +//int parse_dotted_ip __P((char *, u_int32_t *)); /* Procedures exported from demand.c */ #if DEMAND_SUPPORT diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index d897ef0c..64d6f2b0 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -645,8 +645,8 @@ pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) ethhdr = (struct eth_hdr *)pb->payload; etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; ethhdr->type = htons(etype); - MEMCPY(ethhdr->dest.addr, sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); - MEMCPY(ethhdr->src.addr, ((struct eth_addr *)sc->sc_ethif->hwaddr)->addr, sizeof(ethhdr->src.addr)); + MEMCPY(ðhdr->dest.addr, &sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); + MEMCPY(ðhdr->src.addr, &sc->sc_ethif->hwaddr, sizeof(ethhdr->src.addr)); PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype, @@ -957,8 +957,8 @@ pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) ethhdr = (struct eth_hdr *)pb->payload; ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); - MEMCPY(ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); - MEMCPY(ethhdr->src.addr, ((struct eth_addr *)outgoing_if->hwaddr)->addr, sizeof(ethhdr->src.addr)); + MEMCPY(ðhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); + MEMCPY(ðhdr->src.addr, &outgoing_if->hwaddr, sizeof(ethhdr->src.addr)); p = (u8_t*)(ethhdr + 1); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 80aaea8b..a6be5837 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -54,7 +54,9 @@ #include "upap.h" +#if 0 /* UNUSED */ static bool hide_password = 1; +#endif /* UNUSED */ #if PPP_OPTIONS /* @@ -128,7 +130,9 @@ static void upap_rauthreq __P((upap_state *, u_char *, int, int)); static void upap_rauthack __P((upap_state *, u_char *, int, int)); static void upap_rauthnak __P((upap_state *, u_char *, int, int)); static void upap_sauthreq __P((upap_state *)); +#if 0 /* UNUSED */ static void upap_sresp __P((upap_state *, int, int, char *, int)); +#endif /* UNUSED */ /* @@ -593,7 +597,7 @@ upap_sauthreq(u) u->us_clientstate = UPAPCS_AUTHREQ; } - +#if 0 /* UNUSED */ /* * upap_sresp - Send a response (ack or nak). */ @@ -618,6 +622,7 @@ upap_sresp(u, code, id, msg, msglen) MEMCPY(outp, msg, msglen); output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } +#endif /* UNUSED */ #if PRINTPKT_SUPPORT /* diff --git a/src/netif/ppp/upap.h b/src/netif/ppp/upap.h index 139b917e..7e51b351 100644 --- a/src/netif/ppp/upap.h +++ b/src/netif/ppp/upap.h @@ -102,7 +102,9 @@ typedef struct upap_state { /* * Timeouts. */ +#if 0 /* moved to opt.h */ #define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */ +#endif /* moved to opt.h */ #define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ extern upap_state upap[]; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 8fe63ebd..03b9c373 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -70,8 +70,8 @@ extern char *strerror(); static void logit __P((int, char *, va_list)); static void log_write __P((int, char *)); -static void vslp_printer __P((void *, char *, ...)); #if PRINTPKT_SUPPORT +static void vslp_printer __P((void *, char *, ...)); static void format_packet __P((u_char *, int, void (*) (void *, char *, ...), void *)); #endif /* PRINTPKT_SUPPORT */ @@ -172,7 +172,9 @@ vslprintf(buf, buflen, fmt, args) time_t t; u_int32_t ip; static char hexchars[] = "0123456789abcdef"; +#if PRINTPKT_SUPPORT struct buffer_info bufinfo; +#endif /* PRINTPKT_SUPPORT */ buf0 = buf; --buflen; @@ -428,6 +430,7 @@ vslprintf(buf, buflen, fmt, args) return buf - buf0; } +#if PRINTPKT_SUPPORT /* * vslp_printer - used in processing a %P format */ @@ -455,6 +458,7 @@ vslp_printer __V((void *arg, char *fmt, ...)) bi->ptr += n; bi->len -= n; } +#endif /* PRINTPKT_SUPPORT */ #ifdef unused /* @@ -662,10 +666,9 @@ logit(level, fmt, args) char *fmt; va_list args; { - int n; char buf[1024]; - n = vslprintf(buf, sizeof(buf), fmt, args); + vslprintf(buf, sizeof(buf), fmt, args); log_write(level, buf); } From 44c2a0a7fc1d5c461aabff08720fa90a285d9908 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 21:25:58 +0200 Subject: [PATCH 081/320] fixed most PPP compilation warnings with -pedantic --- src/netif/ppp/auth.c | 22 +++++----- src/netif/ppp/ipcp.c | 11 ++--- src/netif/ppp/lcp.c | 93 ++++++++++++++++++++++++----------------- src/netif/ppp/options.c | 22 +++++++--- src/netif/ppp/ppp.c | 16 ++++--- src/netif/ppp/ppp.h | 12 +++--- src/netif/ppp/tty.c | 2 +- src/netif/ppp/utils.c | 6 ++- 8 files changed, 106 insertions(+), 78 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 72b40561..614549d0 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -223,15 +223,15 @@ struct notifier *link_down_notifier = NULL; bool uselogin = 0; /* Use /etc/passwd for checking PAP */ bool session_mgmt = 0; /* Do session management (login records) */ 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 refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ +bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ +bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ +bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ #if MSCHAP_SUPPORT -//bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ -//bool refuse_mschap_v2 = 0; /* Don't wanna auth. oif 0 /* UNUSED */urselves with MS-CHAPv2 */ +bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ +bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #else /* MSCHAP_SUPPORT */ -//bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ -//bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ +bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #endif /* MSCHAP_SUPPORT */ #endif /* MOVED TO ppp_settings */ #if 0 /* UNUSED */ @@ -1079,7 +1079,9 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) namelen = sizeof(peer_authname) - 1; MEMCPY(peer_authname, name, namelen); peer_authname[namelen] = 0; - //script_setenv("PEERNAME", peer_authname, 0); +#if 0 /* UNUSED */ + script_setenv("PEERNAME", peer_authname, 0); +#endif /* UNUSED */ /* Save the authentication method for later. */ auth_done[unit] |= bit; @@ -1538,7 +1540,7 @@ auth_reset(unit) #endif /* EAP_SUPPORT */ #if 0 /* OLD CODE */ - //ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); + ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); /* ao->neg_chap = (!ppp_settings.refuse_chap || !refuse_mschap || !refuse_mschap_v2) @@ -1978,7 +1980,7 @@ get_secret(unit, client, server, secret, secret_len, am_server) /* FIXME: clean that */ #if 0 - // strlcpy(rname, ppp_settings.user, sizeof(rname)); + strlcpy(rname, ppp_settings.user, sizeof(rname)); /* diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 992db3cd..6d94ec30 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -304,7 +304,7 @@ struct protent ipcp_protent = { #endif /* DEMAND_SUPPORT */ }; -static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool)); +static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute); /* * Lengths of configuration options. @@ -2038,13 +2038,8 @@ ipcp_down(f) * ipcp_clear_addrs() - clear the interface addresses, routes, * proxy arp entries, etc. */ -static void -ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute) - int unit; - u_int32_t ouraddr; /* local address */ - u_int32_t hisaddr; /* remote address */ - bool replacedefaultroute; -{ +static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute) { + if (proxy_arp_set[unit]) { cifproxyarp(unit, hisaddr); proxy_arp_set[unit] = 0; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 52ca0fee..645da392 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -731,22 +731,27 @@ lcp_cilen(f) #if EAP_SUPPORT LENCISHORT(go->neg_eap) + #endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - LENCICHAP( +#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ #if EAP_SUPPORT - !go->neg_eap && + LENCICHAP(!go->neg_eap && go->neg_chap) + #endif /* EAP_SUPPORT */ - go->neg_chap) + +#if !EAP_SUPPORT + LENCICHAP(go->neg_chap) + +#endif /* !EAP_SUPPORT */ #endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - LENCISHORT( -#if EAP_SUPPORT - !go->neg_eap && -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - !go->neg_chap && -#endif /* CHAP_SUPPORT */ - go->neg_upap) + +#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT && CHAP_SUPPORT + LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) + +#endif /* EAP_SUPPORT && CHAP_SUPPORT */ +#if EAP_SUPPORT && !CHAP_SUPPORT + LENCISHORT(!go->neg_eap && go->neg_upap) + +#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ +#if !EAP_SUPPORT && CHAP_SUPPORT + LENCISHORT(!go->neg_chap && go->neg_upap) + +#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ +#if !EAP_SUPPORT && !CHAP_SUPPORT + LENCISHORT(go->neg_upap) + +#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ #endif /* PAP_SUPPORT */ LENCILQR(go->neg_lqr) + LENCICBCP(go->neg_cbcp) + @@ -826,22 +831,27 @@ lcp_addci(f, ucp, lenp) #if EAP_SUPPORT ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); #endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - ADDCICHAP(CI_AUTHTYPE, +#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ #if EAP_SUPPORT - !go->neg_eap && + ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); #endif /* EAP_SUPPORT */ - go->neg_chap, go->chap_mdtype); +#if !EAP_SUPPORT + ADDCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); +#endif /* !EAP_SUPPORT */ #endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, -#if EAP_SUPPORT - !go->neg_eap && -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - !go->neg_chap && -#endif /* CHAP_SUPPORT */ - go->neg_upap, PPP_PAP); +#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT && CHAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); +#endif /* EAP_SUPPORT && CHAP_SUPPORT */ +#if EAP_SUPPORT && !CHAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP); +#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ +#if !EAP_SUPPORT && CHAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); +#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ +#if !EAP_SUPPORT && !CHAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); +#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ #endif /* PAP_SUPPORT */ ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); @@ -993,22 +1003,27 @@ lcp_ackci(f, p, len) #if EAP_SUPPORT ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); #endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - ACKCICHAP(CI_AUTHTYPE, +#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ #if EAP_SUPPORT - !go->neg_eap && + ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); #endif /* EAP_SUPPORT */ - go->neg_chap, go->chap_mdtype); +#if !EAP_SUPPORT + ACKCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); +#endif /* !EAP_SUPPORT */ #endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, -#if EAP_SUPPORT - !go->neg_eap && -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - !go->neg_chap && -#endif /* CHAP_SUPPORT */ - go->neg_upap, PPP_PAP); +#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT && CHAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); +#endif /* EAP_SUPPORT && CHAP_SUPPORT */ +#if EAP_SUPPORT && !CHAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP); +#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ +#if !EAP_SUPPORT && CHAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); +#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ +#if !EAP_SUPPORT && !CHAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); +#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ #endif /* PAP_SUPPORT */ ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 620a2e6d..fbe3404a 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -50,7 +50,9 @@ #include #include #include -//#include +#if 0 +#include +#endif #include #include #ifdef PLUGIN @@ -94,12 +96,16 @@ struct option_value { 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 */ +#if 0 +char devnam[MAXPATHLEN]; /* Device name */ +#endif bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ int maxconnect = 0; /* Maximum connect time */ -//char user[MAXNAMELEN]; /* Username for PAP */ -//char passwd[MAXSECRETLEN]; /* Password for PAP */ +#if 0 +char user[MAXNAMELEN]; /* Username for PAP */ +char passwd[MAXSECRETLEN]; /* Password for PAP */ +#endif bool persist = 0; /* Reopen link after it goes down */ char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ #if DEMAND_SUPPORT @@ -114,14 +120,18 @@ int log_to_fd = 1; /* send log messages to this fd too */ #endif bool log_default = 1; /* log_to_fd is default (stdout) */ int maxfail = 10; /* max # of unsuccessful connection attempts */ -//char linkname[MAXPATHLEN]; /* logical name for link */ +#if 0 +char linkname[MAXPATHLEN]; /* logical name for link */ +#endif bool tune_kernel; /* may alter kernel settings */ int connect_delay = 1000; /* wait this many ms after connect script */ int req_unit = -1; /* requested interface unit */ bool multilink = 0; /* Enable multilink operation */ char *bundle_name = NULL; /* bundle name for multilink */ bool dump_options; /* print out option values */ -//bool dryrun; /* print out option values and exit */ +#if 0 +bool dryrun; /* print out option values and exit */ +#endif char *domain; /* domain name set by domain option */ int child_wait = 5; /* # seconds to wait for children at exit */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 79fc54db..49476b24 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -736,7 +736,7 @@ void pppInProcOverEthernet(int pd, struct pbuf *pb) { drop: LINK_STATS_INC(link.drop); -// snmp_inc_ifindiscards(&pppControl[pd].netif); + snmp_inc_ifindiscards(&pppControl[pd].netif); pbuf_free(pb); return; } @@ -744,8 +744,10 @@ drop: void pppOverEthernetInitFailed(int pd) { PPPControl* pc; - //pppHup(pd); - //pppStop(pd); + /* FIXME: re-enable that + * pppHup(pd); + * pppStop(pd); + */ pc = &pppControl[pd]; pppoe_destroy(&pc->netif); @@ -827,7 +829,7 @@ static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr * and the peer will just drop it if it's not accepting it. */ if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", - pd, PPP_IP, pb)); + pd, PPP_IP, (void*)pb)); LINK_STATS_INC(link.opterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -1168,8 +1170,10 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, SMEMCPY(&pc->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); SMEMCPY(&pc->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); SMEMCPY(&pc->addrs.netmask, &net_mask, sizeof(net_mask)); -// SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); -// SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); +/* FIXME: re-enable DNS + * SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); + * SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); + */ } return st; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 502b539d..d5123724 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -281,8 +281,8 @@ struct ppp_settings { char user [MAXNAMELEN + 1]; /* Username for PAP */ char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ - // FIXME: re-enable that - // char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ + /* FIXME: re-enable that */ + /* char remote_name[MAXNAMELEN + 1]; */ /* Peer's name for authentication */ }; struct ppp_settings ppp_settings; @@ -315,12 +315,12 @@ int ppp_init(void); * */ enum pppAuthType { - PPPAUTHTYPE_NONE, - PPPAUTHTYPE_ANY, - PPPAUTHTYPE_PAP, #if CHAP_SUPPORT PPPAUTHTYPE_CHAP, #endif /* CHAP_SUPPORT */ + PPPAUTHTYPE_PAP, + PPPAUTHTYPE_ANY, + PPPAUTHTYPE_NONE }; int ppp_init(void); @@ -511,7 +511,7 @@ int get_secret __P((int, char *, char *, char *, int *, int)); /* get "secret" for chap */ /* Procedures exported from ipcp.c */ -//int parse_dotted_ip __P((char *, u_int32_t *)); +/* int parse_dotted_ip __P((char *, u_int32_t *)); */ /* Procedures exported from demand.c */ #if DEMAND_SUPPORT diff --git a/src/netif/ppp/tty.c b/src/netif/ppp/tty.c index 1476c1d1..53941c6e 100644 --- a/src/netif/ppp/tty.c +++ b/src/netif/ppp/tty.c @@ -950,7 +950,7 @@ start_charshunt(ifd, ofd) { int cpid; - cpid = -1; // safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2)); + cpid = -1; /* safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2)); */ if (cpid == -1) { error("Can't fork process for character shunt: %m"); return 0; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 03b9c373..4dc4080e 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -40,7 +40,9 @@ #include #include #include -//#include +#if 0 +#include +#endif #include #include #include @@ -678,7 +680,7 @@ log_write(level, buf) char *buf; { /* FIXME: replace this with a log callback */ - // if(level >= min_log_level) /* FIXME: add a minimum log level */ + /* if(level >= min_log_level) */ /* FIXME: add a minimum log level */ printf("LOG: %s\n", buf); #if 0 if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { From 28b9dd50ff8839ddd0ce1e0195722b60a585a009 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 21:31:13 +0200 Subject: [PATCH 082/320] build PolarSSL MD5 if MD5_SUPPORT is enabled (for randm) --- src/include/lwip/opt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index c80fd17c..15167289 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1788,11 +1788,11 @@ * using our cleaned PolarSSL library. */ -#if CHAP_SUPPORT || EAP_SUPPORT +#if CHAP_SUPPORT || EAP_SUPPORT || MD5_SUPPORT #ifndef LWIP_INCLUDED_POLARSSL_MD5 #define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP and EAP require MD5 support */ #endif /* LWIP_INCLUDED_POLARSSL_MD5 */ -#endif /* CHAP_SUPPORT || EAP_SUPPORT */ +#endif /* CHAP_SUPPORT || EAP_SUPPORT || MD5_SUPPORT */ #if MSCHAP_SUPPORT #ifndef LWIP_INCLUDED_POLARSSL_MD4 From 5531bca078283c866fed29eb68cc2bc6f7cd6d35 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 23:04:03 +0200 Subject: [PATCH 083/320] make it build with avr32-gcc Disabled Unix-centric non necessary include files Changed some include paths Removed all printf() I put there and there for debugging. It builds with the avr32 gcc toolchain, meaning we removed all the pppd code requiring a unix base. --- src/netif/ppp/auth.c | 22 ++++++++++------------ src/netif/ppp/fsm.c | 5 ----- src/netif/ppp/ipcp.c | 4 ++++ src/netif/ppp/lcp.c | 2 -- src/netif/ppp/polarssl/des.c | 2 +- src/netif/ppp/polarssl/md4.c | 2 +- src/netif/ppp/polarssl/md5.c | 2 +- src/netif/ppp/polarssl/sha1.c | 2 +- src/netif/ppp/ppp.c | 6 ------ src/netif/ppp/ppp.h | 3 +-- src/netif/ppp/utils.c | 8 ++++++-- 11 files changed, 25 insertions(+), 33 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 614549d0..abf9d75f 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -80,16 +80,20 @@ #include #include #include +#if 0 #include #include +#endif #include #if defined(_PATH_LASTLOG) && defined(__linux__) #include #endif +#if 0 #include #include #include +#endif #ifdef HAS_SHADOW @@ -759,8 +763,6 @@ link_established(unit) int i; struct protent *protp; - printf("AUTH: link_established() called"); - /* * Tell higher-level protocols that LCP is up. */ @@ -1525,18 +1527,18 @@ auth_reset(unit) } #if PAP_SUPPORT - printf("neg_upap: %d\n", ao->neg_upap); + PPPDEBUG(LOG_DEBUG, ("neg_upap: %d\n", ao->neg_upap) ); #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT - printf("neg_chap: %d\n", ao->neg_chap); - printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) ); + PPPDEBUG(LOG_DEBUG, ("neg_chap: %d\n", ao->neg_chap) ); + PPPDEBUG(LOG_DEBUG, ("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5)) ); #if MSCHAP_SUPPORT - printf("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT) ); - printf("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2) ); + PPPDEBUG(LOG_DEBUG, ("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT)) ); + PPPDEBUG(LOG_DEBUG, ("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2)) ); #endif /* MSCHAP_SUPPORT */ #endif /* CHAP_SUPPORT */ #if EAP_SUPPORT - printf("neg_eap: %d\n", ao->neg_eap); + PPPDEBUG(LOG_DEBUG, ("neg_eap: %d\n", ao->neg_eap) ); #endif /* EAP_SUPPORT */ #if 0 /* OLD CODE */ @@ -1987,10 +1989,6 @@ get_secret(unit, client, server, secret, secret_len, am_server) strlcpy(rname, ppp_settings.user, sizeof(rname)); strlcpy(secret, ppp_settings.passwd, sizeof(secret)); secret_len = strlen(secret); - - printf("CHAP USER = %s\n", ppp_settings.user); - printf("CHAP PASS = %s\n", ppp_settings.passwd); - printf("CHAP PASS LEN = %s\n", strlen(secret)); */ FILE *f; diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index fa94ea5f..f3c834e2 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -343,8 +343,6 @@ fsm_input(f, inpacket, l) u_char code, id; int len; - printf("fsm_input: l = %d\n", l); - /* * Parse header (code, id and length). * If packet too short, drop it. @@ -423,8 +421,6 @@ fsm_rconfreq(f, id, inp, len) { int code, reject_if_disagree; - printf("fsm_rconfreq() called, f->state = %d\n", f->state); - switch( f->state ){ case CLOSED: /* Go away, we're closed */ @@ -464,7 +460,6 @@ fsm_rconfreq(f, id, inp, len) /* send the Ack, Nak or Rej to the peer */ fsm_sdata(f, code, id, inp, len); - printf("fsm_rconfreq() code = %d, f->state = %d\n", code, f->state); if (code == CONFACK) { if (f->state == ACKRCVD) { UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 6d94ec30..0c53f887 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -51,12 +51,16 @@ #include #include #include +#if 0 #include +#endif #include #include +#if 0 #include #include #include +#endif #include "ppp.h" diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 645da392..bf85bb8c 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -2199,8 +2199,6 @@ lcp_up(f) lcp_options *ao = &lcp_allowoptions[f->unit]; int mtu, mru; - printf("LCP IS UP !\n"); - if (!go->neg_magicnumber) go->magicnumber = 0; if (!ho->neg_magicnumber) diff --git a/src/netif/ppp/polarssl/des.c b/src/netif/ppp/polarssl/des.c index 76b10743..2e2a61c3 100644 --- a/src/netif/ppp/polarssl/des.c +++ b/src/netif/ppp/polarssl/des.c @@ -42,7 +42,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_DES -#include "polarssl/des.h" +#include "des.h" /* * 32-bit integer manipulation macros (big endian) diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/md4.c index 5bbc1710..bf7f9347 100644 --- a/src/netif/ppp/polarssl/md4.c +++ b/src/netif/ppp/polarssl/md4.c @@ -42,7 +42,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_MD4 -#include "polarssl/md4.h" +#include "md4.h" /* * 32-bit integer manipulation macros (little endian) diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/md5.c index bb124940..e2854a1b 100644 --- a/src/netif/ppp/polarssl/md5.c +++ b/src/netif/ppp/polarssl/md5.c @@ -41,7 +41,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_MD5 -#include "polarssl/md5.h" +#include "md5.h" /* * 32-bit integer manipulation macros (little endian) diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/sha1.c index 1fc51989..5d7a59c8 100644 --- a/src/netif/ppp/polarssl/sha1.c +++ b/src/netif/ppp/polarssl/sha1.c @@ -41,7 +41,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_SHA1 -#include "polarssl/sha1.h" +#include "sha1.h" /* * 32-bit integer manipulation macros (big endian) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 49476b24..2627c315 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -237,7 +237,6 @@ static void ppp_input(void *arg) { pd = ((struct pppInputHeader *)nb->payload)->unit; protocol = ((struct pppInputHeader *)nb->payload)->proto; - printf("ppp_input() called, pd = %d, protocol = 0x%x\n", pd, protocol); if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { LWIP_ASSERT("pbuf_header failed\n", 0); @@ -323,7 +322,6 @@ static void ppp_input(void *arg) { break; case PPP_IP: /* Internet Protocol */ - printf("IP packet received\n"); PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); if (pppControl[pd].netif.input) { pppControl[pd].netif.input(nb, &pppControl[pd].netif); @@ -717,7 +715,6 @@ void pppInProcOverEthernet(int pd, struct pbuf *pb) { } inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - printf("pppInProcOverEthernet() called, pd = %d, inprotocol = 0x%x\n", pd, inProtocol); /* make room for pppInputHeader - should not fail */ if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { @@ -759,7 +756,6 @@ void pppOverEthernetInitFailed(int pd) { } static void pppOverEthernetLinkStatusCB(int pd, int up) { - printf("pppOverEthernetLinkStatusCB: called, pd = %d, up = %d\n", pd, up); if(up) { PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); pppStart(pd); @@ -982,8 +978,6 @@ int pppWriteOverEthernet(int pd, const u_char *s, int n) { PPPControl *pc = &pppControl[pd]; struct pbuf *pb; - printf("pppWriteOverEthernet() called\n"); - /* skip address & flags */ s += 2; n -= 2; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index d5123724..331db515 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -15,8 +15,7 @@ #include "lwip/timers.h" #include "pppdebug.h" - -#include /* FIXME: merge linux/ppp_defs.h content here */ +#include "net/ppp_defs.h" /* FIXME: merge linux/ppp_defs.h content here */ #ifdef INET6 #include "eui64.h" diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 4dc4080e..6d9966af 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -42,10 +42,12 @@ #include #if 0 #include -#endif #include +#endif #include +#if 0 #include +#endif #include #include #include @@ -53,8 +55,10 @@ #include #include #include +#if 0 #include #include +#endif #ifdef SVR4 #include #endif @@ -681,7 +685,7 @@ log_write(level, buf) { /* FIXME: replace this with a log callback */ /* if(level >= min_log_level) */ /* FIXME: add a minimum log level */ - printf("LOG: %s\n", buf); + PPPDEBUG(LOG_DEBUG, ("LOG: %s\n", buf) ); #if 0 if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { int n = strlen(buf); From e1261c96209def183f58bc4cb061ef207719cd65 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 2 Jun 2012 23:29:40 +0200 Subject: [PATCH 084/320] removed all system headers except the strict minimum --- src/netif/ppp/auth.c | 8 +++----- src/netif/ppp/chap-md5.c | 2 ++ src/netif/ppp/chap-new.c | 2 ++ src/netif/ppp/chap_ms.c | 2 ++ src/netif/ppp/fsm.c | 2 ++ src/netif/ppp/ipcp.c | 6 ++---- src/netif/ppp/lcp.c | 2 ++ src/netif/ppp/ppp.h | 22 ++++++++++++---------- src/netif/ppp/ppp_oe.c | 12 ++++++------ src/netif/ppp/upap.c | 2 ++ src/netif/ppp/utils.c | 14 ++++++++------ 11 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index abf9d75f..9b17144b 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -70,6 +70,7 @@ #include "lwip/opt.h" +#if 0 /* UNUSED */ #include #include #include @@ -80,21 +81,16 @@ #include #include #include -#if 0 #include #include -#endif #include #if defined(_PATH_LASTLOG) && defined(__linux__) #include #endif -#if 0 #include #include #include -#endif - #ifdef HAS_SHADOW #include @@ -102,7 +98,9 @@ #define PW_PPP PW_LOGIN #endif #endif + #include +#endif /* UNUSED */ #include "ppp.h" diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index e7ed182a..3f6734e1 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -31,8 +31,10 @@ #include "lwip/opt.h" #if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#if 0 /* UNUSED */ #include #include +#endif /* UNUSED */ #include "ppp.h" diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 3319f0f5..8f0a7d6f 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -33,8 +33,10 @@ #define RCSID "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $" +#if 0 /* UNUSED */ #include #include +#endif /* UNUSED */ #include "ppp.h" diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index fa838d06..e70c28fc 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -77,6 +77,7 @@ #include "lwip/opt.h" #if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#if 0 /* UNUSED */ #include #include #include @@ -84,6 +85,7 @@ #include #include #include +#endif /* UNUSED */ #include "ppp.h" diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index f3c834e2..cb0a8829 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -50,9 +50,11 @@ * Deal with variable outgoing MTU. */ +#if 0 /* UNUSED */ #include #include #include +#endif /* UNUSED */ #include "ppp.h" diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 0c53f887..f0ebea2e 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -48,19 +48,17 @@ * TODO: */ +#if 0 /* UNUSED */ #include #include #include -#if 0 #include -#endif #include #include -#if 0 #include #include #include -#endif +#endif /* UNUSED */ #include "ppp.h" diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index bf85bb8c..b0aee641 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -46,9 +46,11 @@ * TODO: */ +#if 0 /* UNUSED */ #include #include #include +#endif /* UNUSED */ #include "ppp.h" diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 331db515..abdbcc1c 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -10,16 +10,7 @@ #ifndef PPPMY_H_ #define PPPMY_H_ -#include "lwip/netif.h" -#include "lwip/def.h" -#include "lwip/timers.h" - -#include "pppdebug.h" -#include "net/ppp_defs.h" /* FIXME: merge linux/ppp_defs.h content here */ - -#ifdef INET6 -#include "eui64.h" -#endif +#include /* formats */ #if defined(__STDC__) #include @@ -31,6 +22,17 @@ #define volatile #endif +#include "lwip/netif.h" +#include "lwip/def.h" +#include "lwip/timers.h" + +#include "pppdebug.h" +#include "net/ppp_defs.h" /* FIXME: merge linux/ppp_defs.h content here */ + +#ifdef INET6 +#include "eui64.h" +#endif + /* * Limits. */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 64d6f2b0..2b7912bf 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -69,20 +69,20 @@ */ #include "lwip/opt.h" - #if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "netif/ppp_oe.h" - -#include "ppp.h" +#if 0 /* UNUSED */ +#include +#include +#endif /* UNUSED */ #include "lwip/timers.h" #include "lwip/memp.h" #include "lwip/stats.h" -#include -#include +#include "ppp.h" +#include "netif/ppp_oe.h" /* Add a 16 bit unsigned value to a buffer pointed to by PTR */ #define PPPOE_ADD_16(PTR, VAL) \ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index a6be5837..ed8e496b 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -47,8 +47,10 @@ * TODO: */ +#if 0 /* UNUSED */ #include #include +#endif /* UNUSED */ #include "ppp.h" diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 6d9966af..679d0ef8 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -32,6 +32,7 @@ #define RCSID "$Id: utils.c,v 1.25 2008/06/03 12:06:37 paulus Exp $" +#if 0 /* UNUSED */ #include #include #include @@ -40,14 +41,10 @@ #include #include #include -#if 0 #include #include -#endif #include -#if 0 #include -#endif #include #include #include @@ -55,13 +52,14 @@ #include #include #include -#if 0 #include #include -#endif #ifdef SVR4 #include #endif +#endif /* UNUSED */ + +#include /* isdigit() */ #include "ppp.h" @@ -175,7 +173,9 @@ vslprintf(buf, buflen, fmt, args) char *str, *f, *buf0; unsigned char *p; char num[32]; +#if 0 /* need port */ time_t t; +#endif /* need port */ u_int32_t ip; static char hexchars[] = "0123456789abcdef"; #if PRINTPKT_SUPPORT @@ -313,12 +313,14 @@ vslprintf(buf, buflen, fmt, args) buflen -= n; continue; #endif +#if 0 /* need port */ case 't': time(&t); str = ctime(&t); str += 4; /* chop off the day name */ str[15] = 0; /* chop off year and newline */ break; +#endif /* need port */ case 'v': /* "visible" string */ case 'q': /* quoted string */ quoted = c == 'q'; From b5b075eb0443a72df5a78db5a1e0852fd74c7aa7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 00:30:12 +0200 Subject: [PATCH 085/320] demystified a bit the PPP impl, renamed output() to ppp_output() to prevent conflict --- src/netif/ppp/chap-new.c | 6 +-- src/netif/ppp/eap.c | 16 +++--- src/netif/ppp/fsm.c | 2 +- src/netif/ppp/ppp.c | 102 +++++++++++++++++++++------------------ src/netif/ppp/ppp.h | 27 +++++++---- src/netif/ppp/upap.c | 4 +- 6 files changed, 88 insertions(+), 69 deletions(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 8f0a7d6f..cbaf09d5 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -276,7 +276,7 @@ chap_timeout(void *arg) return; } - output(0, ss->challenge, ss->challenge_pktlen); + ppp_output(0, ss->challenge, ss->challenge_pktlen); ++ss->challenge_xmits; ss->flags |= TIMEOUT_PENDING; TIMEOUT(chap_timeout, arg, chap_timeout_time); @@ -377,7 +377,7 @@ chap_handle_response(struct chap_server_state *ss, int id, p[3] = len; if (mlen > 0) memcpy(p + CHAP_HDRLEN, ss->message, mlen); - output(0, outpacket_buf, PPP_HDRLEN + len); + ppp_output(0, outpacket_buf, PPP_HDRLEN + len); if (ss->flags & CHALLENGE_VALID) { ss->flags &= ~CHALLENGE_VALID; @@ -499,7 +499,7 @@ chap_respond(struct chap_client_state *cs, int id, p[2] = len >> 8; p[3] = len; - output(0, response, PPP_HDRLEN + len); + ppp_output(0, response, PPP_HDRLEN + len); } static void diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 7d3b2981..aa650f85 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -274,7 +274,7 @@ eap_state *esp; PUTCHAR(esp->es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); + ppp_output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); esp->es_server.ea_state = eapBadAuth; auth_peer_fail(esp->es_unit, PPP_EAP); @@ -299,7 +299,7 @@ eap_state *esp; PUTCHAR(esp->es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); + ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); auth_peer_success(esp->es_unit, PPP_EAP, 0, esp->es_server.ea_peer, esp->es_server.ea_peerlen); @@ -860,7 +860,7 @@ eap_state *esp; outlen = (outp - outpacket_buf) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); - output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); esp->es_server.ea_requests++; @@ -1067,7 +1067,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } /* @@ -1102,7 +1102,7 @@ int namelen; MEMCPY(outp, name, namelen); } - output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #ifdef USE_SRP @@ -1135,7 +1135,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } /* @@ -1166,7 +1166,7 @@ u_char *str; PUTLONG(flags, outp); MEMCPY(outp, str, SHA_DIGESTSIZE); - output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #endif /* USE_SRP */ @@ -1191,7 +1191,7 @@ u_char type; PUTCHAR(EAPT_NAK, outp); PUTCHAR(type, outp); - output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #ifdef USE_SRP diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index cb0a8829..a0624c57 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -818,5 +818,5 @@ fsm_sdata(f, code, id, data, datalen) PUTCHAR(code, outp); PUTCHAR(id, outp); PUTSHORT(outlen, outp); - output(f->unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_output(f->unit, outpacket_buf, outlen + PPP_HDRLEN); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 2627c315..b089c3ce 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -184,10 +184,12 @@ typedef struct PPPControl_s { static void pppStart(int pd); /** Initiate LCP open request */ static void ppp_input(void *arg); +#if PPPOE_SUPPORT static void pppOverEthernetLinkStatusCB(int pd, int up); static err_t pppifOutputOverEthernet(int pd, struct pbuf *p); -static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); -static err_t pppifNetifInit(struct netif *netif); +#endif /* PPPOE_SUPPORT */ +static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); +static err_t ppp_netif_init_cb(struct netif *netif); /******************************/ @@ -807,8 +809,12 @@ static err_t pppifOutputOverEthernet(int pd, struct pbuf *p) { } #endif /* PPPOE_SUPPORT */ -/* Send a packet on the given connection. */ -static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { + +/* Send a packet on the given connection. + * + * This is the low level function that send the PPP packet. + */ +static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { int pd = (int)(size_t)netif->state; PPPControl *pc = &pppControl[pd]; #if PPPOS_SUPPORT @@ -824,7 +830,7 @@ static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr /* We let any protocol value go through - it can't hurt us * and the peer will just drop it if it's not accepting it. */ if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", + PPPDEBUG(LOG_WARNING, ("ppp_low_level_output[%d]: bad parms prot=%d pb=%p\n", pd, PPP_IP, (void*)pb)); LINK_STATS_INC(link.opterr); LINK_STATS_INC(link.drop); @@ -834,7 +840,7 @@ static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr /* Check that the link is up. */ if (phase == PHASE_DEAD) { - PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd)); + PPPDEBUG(LOG_ERR, ("ppp_low_level_output[%d]: link not up\n", pd)); LINK_STATS_INC(link.rterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -851,7 +857,7 @@ static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr /* Grab an output buffer. */ headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (headMB == NULL) { - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_low_level_output[%d]: first alloc fail\n", pd)); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -876,7 +882,7 @@ static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr protocol = PPP_VJC_UNCOMP; break; default: - PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_low_level_output[%d]: bad IP packet\n", pd)); LINK_STATS_INC(link.proterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -937,7 +943,7 @@ static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr /* If we failed to complete the packet, throw it away. */ if (!tailMB) { PPPDEBUG(LOG_WARNING, - ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", + ("ppp_low_level_output[%d]: Alloc err - dropping proto=%d\n", pd, protocol)); pbuf_free(headMB); LINK_STATS_INC(link.memerr); @@ -947,7 +953,7 @@ static err_t pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr } /* Send it. */ - PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); + PPPDEBUG(LOG_INFO, ("ppp_low_level_output[%d]: proto=0x%"X16_F"\n", pd, protocol)); nPut(pc, headMB); #endif /* PPPOS_SUPPORT */ @@ -1015,7 +1021,7 @@ int pppWriteOverEthernet(int pd, const u_char *s, int n) { * RETURN: >= 0 Number of characters written * -1 Failed to write to device */ -int pppWrite(int pd, const u_char *s, int n) { +int ppp_output(int pd, const u_char *s, int n) { PPPControl *pc = &pppControl[pd]; #if PPPOS_SUPPORT u_char c; @@ -1070,8 +1076,8 @@ int pppWrite(int pd, const u_char *s, int n) { * Otherwise send it. */ if (!tailMB) { PPPDEBUG(LOG_WARNING, - ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); - /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + ("ppp_output[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); + /*"ppp_output[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ pbuf_free(headMB); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); @@ -1079,8 +1085,8 @@ int pppWrite(int pd, const u_char *s, int n) { return PPPERR_ALLOC; } - PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len)); - /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + PPPDEBUG(LOG_INFO, ("ppp_output[%d]: len=%d\n", pd, headMB->len)); + /* "ppp_output[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ nPut(pc, headMB); #endif /* PPPOS_SUPPORT */ @@ -1093,13 +1099,30 @@ int pppWrite(int pd, const u_char *s, int n) { * * output - Output PPP packet. */ - +/* void output (int unit, unsigned char *p, int len) { pppWrite(unit, p, len); } +*/ +/************************************************************************ + * Functions called by various PPP subsystems to configure + * the PPP interface or change the PPP phase. + */ + + +/* + * new_phase - signal the start of a new phase of pppd's operation. + */ +void new_phase(int p) { + phase = p; +#if PPP_NOTIFY + /* The one willing notify support should add here the code to be notified of phase changes */ +#endif /* PPP_NOTIFY */ +} + /* * ppp_send_config - configure the transmit-side characteristics of * the ppp interface. @@ -1182,25 +1205,6 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { return 0; } - -/* - * pppifNetifInit - netif init callback - */ -static err_t -pppifNetifInit(struct netif *netif) -{ - netif->name[0] = 'p'; - netif->name[1] = 'p'; - netif->output = pppifOutput; - netif->mtu = pppMTU((int)(size_t)netif->state); - netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; -#if LWIP_NETIF_HOSTNAME - /* @todo: Initialize interface hostname */ - /* netif_set_hostname(netif, "lwip"); */ -#endif /* LWIP_NETIF_HOSTNAME */ - return ERR_OK; -} - /* * sifup - Config the interface up and enable IP packets to pass. */ @@ -1215,7 +1219,7 @@ int sifup(int u) } else { netif_remove(&pc->netif); if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, - &pc->addrs.his_ipaddr, (void *)(size_t)u, pppifNetifInit, ip_input)) { + &pc->addrs.his_ipaddr, (void *)(size_t)u, ppp_netif_init_cb, ip_input)) { netif_set_up(&pc->netif); pc->if_up = 1; pc->errCode = PPPERR_NONE; @@ -1233,6 +1237,22 @@ int sifup(int u) return st; } +/* + * ppp_netif_init_cb - netif init callback + */ +static err_t ppp_netif_init_cb(struct netif *netif) { + netif->name[0] = 'p'; + netif->name[1] = 'p'; + netif->output = ppp_low_level_output; + netif->mtu = pppMTU((int)(size_t)netif->state); + netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; +#if LWIP_NETIF_HOSTNAME + /* @todo: Initialize interface hostname */ + /* netif_set_hostname(netif, "lwip"); */ +#endif /* LWIP_NETIF_HOSTNAME */ + return ERR_OK; +} + /******************************************************************** * * sifdown - Disable the indicated protocol and config the interface @@ -1510,16 +1530,6 @@ const char * protocol_name(int proto) { } #endif /* PPP_PROTOCOLNAME */ -/* - * new_phase - signal the start of a new phase of pppd's operation. - */ -void new_phase(int p) { - phase = p; -#if PPP_NOTIFY - /* The one willing notify support should add here the code to be notified of phase changes */ -#endif /* PPP_NOTIFY */ -} - #if PPP_STATS_SUPPORT /* ---- Note on PPP Stats support ---- diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index abdbcc1c..0dde323d 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -293,9 +293,6 @@ struct ppp_settings ppp_settings; *** PUBLIC FUNCTIONS *** ************************/ -/* Initialize the PPP subsystem. */ -int ppp_init(void); - /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. * RFC 1994 says: * @@ -324,6 +321,7 @@ enum pppAuthType { PPPAUTHTYPE_NONE }; +/* Initialize the PPP subsystem. */ int ppp_init(void); void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); @@ -338,8 +336,12 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); -/* -- private */ + +/* --- EVERYTHING BELOW SHOULD BE CONSIDERED PRIVATE ---- */ + +/* PPP flow functions + */ struct pbuf * pppSingleBuf(struct pbuf *p); void pppInProcOverEthernet(int pd, struct pbuf *pb); @@ -350,11 +352,15 @@ u_short pppMTU(int pd); int pppWriteOverEthernet(int pd, const u_char *s, int n); -int pppWrite(int pd, const u_char *s, int n); +int ppp_output(int pd, const u_char *s, int n); void pppInProcOverEthernet(int pd, struct pbuf *pb); -void output (int unit, unsigned char *p, int len); + +/* Functions called by various PPP subsystems to configure + * the PPP interface or change the PPP phase. + */ +void new_phase(int p); int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp); int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp); @@ -384,20 +390,20 @@ int get_loop_output(void); u_int32_t GetMask (u_int32_t addr); + +/* Optional protocol names list, to make our messages a little more informative. */ #if PPP_PROTOCOLNAME const char * protocol_name(int proto); #endif /* PPP_PROTOCOLNAME */ -void new_phase(int p); +/* Optional stats support, to get some statistics on the PPP interface */ #if PPP_STATS_SUPPORT void print_link_stats(void); /* Print stats, if available */ void reset_link_stats(int u); /* Reset (init) stats when link goes up */ void update_link_stats(int u); /* Get stats at link termination */ #endif /* PPP_STATS_SUPPORT */ -#endif /* PPPMY_H_ */ - /* @@ -560,3 +566,6 @@ void end_pr_log __P((void)); /* finish up after using pr_log */ void dump_packet __P((const char *, u_char *, int)); /* dump packet to debug log if interesting */ #endif /* PRINTPKT_SUPPORT */ + + +#endif /* PPPMY_H_ */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index ed8e496b..33c26e07 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -592,7 +592,7 @@ upap_sauthreq(u) PUTCHAR(u->us_passwdlen, outp); MEMCPY(outp, u->us_passwd, u->us_passwdlen); - output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); TIMEOUT(upap_timeout, u, u->us_timeouttime); ++u->us_transmits; @@ -622,7 +622,7 @@ upap_sresp(u, code, id, msg, msglen) PUTSHORT(outlen, outp); PUTCHAR(msglen, outp); MEMCPY(outp, msg, msglen); - output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } #endif /* UNUSED */ From 9c35403b982e620f2549a447f7d5c461abcf5a4a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 01:46:46 +0200 Subject: [PATCH 086/320] clarified a bit more ppp.[ch] --- src/netif/ppp/chap-new.c | 6 +- src/netif/ppp/eap.c | 16 +- src/netif/ppp/fsm.c | 2 +- src/netif/ppp/ppp.c | 904 ++++++++++++++++++++------------------- src/netif/ppp/ppp.h | 14 +- src/netif/ppp/ppp_oe.c | 6 +- src/netif/ppp/upap.c | 4 +- 7 files changed, 477 insertions(+), 475 deletions(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index cbaf09d5..e3520bb6 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -276,7 +276,7 @@ chap_timeout(void *arg) return; } - ppp_output(0, ss->challenge, ss->challenge_pktlen); + ppp_write(0, ss->challenge, ss->challenge_pktlen); ++ss->challenge_xmits; ss->flags |= TIMEOUT_PENDING; TIMEOUT(chap_timeout, arg, chap_timeout_time); @@ -377,7 +377,7 @@ chap_handle_response(struct chap_server_state *ss, int id, p[3] = len; if (mlen > 0) memcpy(p + CHAP_HDRLEN, ss->message, mlen); - ppp_output(0, outpacket_buf, PPP_HDRLEN + len); + ppp_write(0, outpacket_buf, PPP_HDRLEN + len); if (ss->flags & CHALLENGE_VALID) { ss->flags &= ~CHALLENGE_VALID; @@ -499,7 +499,7 @@ chap_respond(struct chap_client_state *cs, int id, p[2] = len >> 8; p[3] = len; - ppp_output(0, response, PPP_HDRLEN + len); + ppp_write(0, response, PPP_HDRLEN + len); } static void diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index aa650f85..737f5411 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -274,7 +274,7 @@ eap_state *esp; PUTCHAR(esp->es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); + ppp_write(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); esp->es_server.ea_state = eapBadAuth; auth_peer_fail(esp->es_unit, PPP_EAP); @@ -299,7 +299,7 @@ eap_state *esp; PUTCHAR(esp->es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); + ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); auth_peer_success(esp->es_unit, PPP_EAP, 0, esp->es_server.ea_peer, esp->es_server.ea_peerlen); @@ -860,7 +860,7 @@ eap_state *esp; outlen = (outp - outpacket_buf) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); - ppp_output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); esp->es_server.ea_requests++; @@ -1067,7 +1067,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } /* @@ -1102,7 +1102,7 @@ int namelen; MEMCPY(outp, name, namelen); } - ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #ifdef USE_SRP @@ -1135,7 +1135,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } /* @@ -1166,7 +1166,7 @@ u_char *str; PUTLONG(flags, outp); MEMCPY(outp, str, SHA_DIGESTSIZE); - ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #endif /* USE_SRP */ @@ -1191,7 +1191,7 @@ u_char type; PUTCHAR(EAPT_NAK, outp); PUTCHAR(type, outp); - ppp_output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #ifdef USE_SRP diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index a0624c57..40c1f954 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -818,5 +818,5 @@ fsm_sdata(f, code, id, data, datalen) PUTCHAR(code, outp); PUTCHAR(id, outp); PUTSHORT(outlen, outp); - ppp_output(f->unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(f->unit, outpacket_buf, outlen + PPP_HDRLEN); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index b089c3ce..ee8912c1 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -179,18 +179,25 @@ typedef struct PPPControl_s { } PPPControl; - /* Prototypes for procedures local to this file. */ -static void pppStart(int pd); /** Initiate LCP open request */ -static void ppp_input(void *arg); #if PPPOE_SUPPORT static void pppOverEthernetLinkStatusCB(int pd, int up); -static err_t pppifOutputOverEthernet(int pd, struct pbuf *p); #endif /* PPPOE_SUPPORT */ -static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); -static err_t ppp_netif_init_cb(struct netif *netif); +static void ppp_start(int pd); /** Initiate LCP open request */ +static void ppp_input(void *arg); + +static err_t ppp_netif_init_cb(struct netif *netif); +static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); +#if PPPOE_SUPPORT +static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p); +#endif /* PPPOE_SUPPORT */ + +#if PPPOE_SUPPORT +/* function called by ppp_write() */ +static int ppp_write_over_ethernet(int pd, const u_char *s, int n); +#endif /* PPPOE_SUPPORT */ /******************************/ /*** PUBLIC DATA STRUCTURES ***/ @@ -213,279 +220,6 @@ PACK_STRUCT_END # include "arch/epstruct.h" #endif - -/** Initiate LCP open request */ -static void pppStart(int pd) { - PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd)); - lcp_open(pd); /* Start protocol */ - lcp_lowerup(pd); - PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n")); -} - - -/* - * Pass the processed input packet to the appropriate handler. - * This function and all handlers run in the context of the tcpip_thread - */ - -/* FIXME: maybe we should pass in two arguments pppInputHeader and payload - * this is totally stupid to make room for it and then modify the packet directly - * or it is used in output ? have to find out... - */ -static void ppp_input(void *arg) { - struct pbuf *nb = (struct pbuf *)arg; - u16_t protocol; - int pd; - - pd = ((struct pppInputHeader *)nb->payload)->unit; - protocol = ((struct pppInputHeader *)nb->payload)->proto; - - if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } - - LINK_STATS_INC(link.recv); - snmp_inc_ifinucastpkts(&pppControl[pd].netif); - snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); - - /* - * Toss all non-LCP packets unless LCP is OPEN. - */ - if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { - dbglog("Discarded non-LCP packet when LCP not open"); - return; - } - - /* FIXME: add a phase per connection */ - - /* - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if (phase <= PHASE_AUTHENTICATE - && !(protocol == PPP_LCP || protocol == PPP_LQR -#if PAP_SUPPORT - || protocol == PPP_PAP -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - || protocol == PPP_CHAP -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || protocol == PPP_EAP -#endif /* EAP_SUPPORT */ - )) { - dbglog("discarding proto 0x%x in phase %d", - protocol, phase); - return; - } - - /* FIXME: should we write protent to do that ? */ - - switch(protocol) { - case PPP_VJC_COMP: /* VJ compressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d\n", pd, nb->len)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d\n", - pd, nb->len)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - break; - - default: { - - int i; - struct protent *protp; - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - nb = pppSingleBuf(nb); - (*protp->input)(pd, nb->payload, nb->len); - goto out; - } -#if 0 /* UNUSED - * - * This is actually a (hacked?) way for the PPP kernel implementation to pass a - * data packet to the PPP daemon. The PPP daemon normally only do signaling - * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. - * - * This is only used by CCP, which we cannot support until we have a CCP data - * implementation. - */ - if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag - && protp->datainput != NULL) { - (*protp->datainput)(pd, nb->payload, nb->len); - goto out; - } -#endif /* UNUSED */ - } - - if (debug) { -#if PPP_PROTOCOLNAME - const char *pname = protocol_name(protocol); - if (pname != NULL) - warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); - else -#endif /* PPP_PROTOCOLNAME */ - warn("Unsupported protocol 0x%x received", protocol); - } - if (pbuf_header(nb, sizeof(protocol))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } - lcp_sprotrej(pd, nb->payload, nb->len); - } - break; - } - -drop: - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); - -out: - pbuf_free(nb); - return; - - #if 0 - /* - * Toss all non-LCP packets unless LCP is OPEN. - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { - if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || - (lcp_phase[pd] != PHASE_AUTHENTICATE)) { - PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); - goto drop; - } - } - - switch(protocol) { - case PPP_VJC_COMP: /* VJ compressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", - pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); - return; - } - break; - - default: { - struct protent *protp; - int i; - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); - nb = pppSingleBuf(nb); - (*protp->input)(pd, nb->payload, nb->len); - PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); - goto out; - } - } - - /* No handler for this protocol so reject the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); - if (pbuf_header(nb, sizeof(protocol))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } -#if BYTE_ORDER == LITTLE_ENDIAN - protocol = htons(protocol); -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - SMEMCPY(nb->payload, &protocol, sizeof(protocol)); - lcp_sprotrej(pd, nb->payload, nb->len); - } - break; - } -#endif - - -} - /***********************************/ /*** PUBLIC FUNCTION DEFINITIONS ***/ /***********************************/ @@ -678,67 +412,6 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha return pd; } -struct pbuf * pppSingleBuf(struct pbuf *p) { - struct pbuf *q, *b; - u_char *pl; - - if(p->tot_len == p->len) { - return p; - } - - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if(!q) { - PPPDEBUG(LOG_ERR, - ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); - return p; /* live dangerously */ - } - - for(b = p, pl = q->payload; b != NULL; b = b->next) { - MEMCPY(pl, b->payload, b->len); - pl += b->len; - } - - pbuf_free(p); - - return q; -} - -/* FIXME: maybe we should pass in two arguments pppInputHeader and payload - * this is totally stupid to make room for it and then modify the packet directly - * or it is used in output ? have to find out... - */ -void pppInProcOverEthernet(int pd, struct pbuf *pb) { - struct pppInputHeader *pih; - u16_t inProtocol; - - if(pb->len < sizeof(inProtocol)) { - PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n")); - goto drop; - } - - inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - - /* make room for pppInputHeader - should not fail */ - if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { - PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n")); - goto drop; - } - - pih = pb->payload; - - pih->unit = pd; - pih->proto = inProtocol; - - /* Dispatch the packet thereby consuming it. */ - ppp_input(pb); - return; - -drop: - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); - pbuf_free(pb); - return; -} void pppOverEthernetInitFailed(int pd) { PPPControl* pc; @@ -760,61 +433,351 @@ void pppOverEthernetInitFailed(int pd) { static void pppOverEthernetLinkStatusCB(int pd, int up) { if(up) { PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); - pppStart(pd); + ppp_start(pd); } else { pppOverEthernetInitFailed(pd); } } #endif + + +/** Initiate LCP open request */ +static void ppp_start(int pd) { + PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pd)); + lcp_open(pd); /* Start protocol */ + lcp_lowerup(pd); + PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); +} + +/* + * Pass the processed input packet to the appropriate handler. + * This function and all handlers run in the context of the tcpip_thread + */ + +/* FIXME: maybe we should pass in two arguments pppInputHeader and payload + * this is totally stupid to make room for it and then modify the packet directly + * or it is used in output ? have to find out... + */ +static void ppp_input(void *arg) { + struct pbuf *nb = (struct pbuf *)arg; + u16_t protocol; + int pd; + + pd = ((struct pppInputHeader *)nb->payload)->unit; + protocol = ((struct pppInputHeader *)nb->payload)->proto; + + if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + + LINK_STATS_INC(link.recv); + snmp_inc_ifinucastpkts(&pppControl[pd].netif); + snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); + + /* + * Toss all non-LCP packets unless LCP is OPEN. + */ + if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { + dbglog("Discarded non-LCP packet when LCP not open"); + return; + } + + /* FIXME: add a phase per connection */ + + /* + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if (phase <= PHASE_AUTHENTICATE + && !(protocol == PPP_LCP || protocol == PPP_LQR +#if PAP_SUPPORT + || protocol == PPP_PAP +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + || protocol == PPP_CHAP +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || protocol == PPP_EAP +#endif /* EAP_SUPPORT */ + )) { + dbglog("discarding proto 0x%x in phase %d", + protocol, phase); + return; + } + + /* FIXME: should we write protent to do that ? */ + + switch(protocol) { + case PPP_VJC_COMP: /* VJ compressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d\n", pd, nb->len)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, + ("pppInput[%d]: drop VJ UnComp in %d\n", + pd, nb->len)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_IP: /* Internet Protocol */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + if (pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + break; + + default: { + + int i; + struct protent *protp; + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + nb = ppp_singlebuf(nb); + (*protp->input)(pd, nb->payload, nb->len); + goto out; + } +#if 0 /* UNUSED + * + * This is actually a (hacked?) way for the PPP kernel implementation to pass a + * data packet to the PPP daemon. The PPP daemon normally only do signaling + * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. + * + * This is only used by CCP, which we cannot support until we have a CCP data + * implementation. + */ + if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag + && protp->datainput != NULL) { + (*protp->datainput)(pd, nb->payload, nb->len); + goto out; + } +#endif /* UNUSED */ + } + + if (debug) { +#if PPP_PROTOCOLNAME + const char *pname = protocol_name(protocol); + if (pname != NULL) + warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); + else +#endif /* PPP_PROTOCOLNAME */ + warn("Unsupported protocol 0x%x received", protocol); + } + if (pbuf_header(nb, sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + lcp_sprotrej(pd, nb->payload, nb->len); + } + break; + } + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pd].netif); + +out: + pbuf_free(nb); + return; + + #if 0 + /* + * Toss all non-LCP packets unless LCP is OPEN. + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { + if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || + (lcp_phase[pd] != PHASE_AUTHENTICATE)) { + PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); + goto drop; + } + } + + switch(protocol) { + case PPP_VJC_COMP: /* VJ compressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, + ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", + pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_IP: /* Internet Protocol */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + if (pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + break; + + default: { + struct protent *protp; + int i; + + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); + nb = ppp_singlebuf(nb); + (*protp->input)(pd, nb->payload, nb->len); + PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); + goto out; + } + } + + /* No handler for this protocol so reject the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); + if (pbuf_header(nb, sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } +#if BYTE_ORDER == LITTLE_ENDIAN + protocol = htons(protocol); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + SMEMCPY(nb->payload, &protocol, sizeof(protocol)); + lcp_sprotrej(pd, nb->payload, nb->len); + } + break; + } +#endif + + +} + #if PPPOE_SUPPORT -static err_t pppifOutputOverEthernet(int pd, struct pbuf *p) { - PPPControl *pc = &pppControl[pd]; - struct pbuf *pb; - u_short protocol = PPP_IP; - int i=0; - u16_t tot_len; +/* ppp_input_over_ethernet + * + * take a packet from PPPoE subsystem and pass it to the PPP stack through ppp_input() + */ - /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return ERR_MEM; +/* FIXME: maybe we should pass in two arguments pppInputHeader and payload + * this is totally stupid to make room for it and then modify the packet directly + * or it is used in output ? have to find out... + */ +void ppp_input_over_ethernet(int pd, struct pbuf *pb) { + struct pppInputHeader *pih; + u16_t inProtocol; + + if(pb->len < sizeof(inProtocol)) { + PPPDEBUG(LOG_ERR, ("ppp_input_over_ethernet: too small for protocol field\n")); + goto drop; } - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - pc->lastXMit = sys_jiffies(); - - if (!pc->pcomp || protocol > 0xFF) { - *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; - } - *((u_char*)pb->payload + i) = protocol & 0xFF; - - pbuf_chain(pb, p); - tot_len = pb->tot_len; - - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { - LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_DEVICE; + /* make room for pppInputHeader - should not fail */ + if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { + PPPDEBUG(LOG_ERR, ("ppp_input_over_ethernet: could not allocate room for header\n")); + goto drop; } - snmp_add_ifoutoctets(&pc->netif, tot_len); - snmp_inc_ifoutucastpkts(&pc->netif); - LINK_STATS_INC(link.xmit); - return ERR_OK; + pih = pb->payload; + + pih->unit = pd; + pih->proto = inProtocol; + + /* Dispatch the packet thereby consuming it. */ + ppp_input(pb); + return; + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pd].netif); + pbuf_free(pb); + return; } #endif /* PPPOE_SUPPORT */ +/* + * ppp_netif_init_cb - netif init callback + */ +static err_t ppp_netif_init_cb(struct netif *netif) { + netif->name[0] = 'p'; + netif->name[1] = 'p'; + netif->output = ppp_netif_output; + netif->mtu = pppMTU((int)(size_t)netif->state); + netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; +#if LWIP_NETIF_HOSTNAME + /* @todo: Initialize interface hostname */ + /* netif_set_hostname(netif, "lwip"); */ +#endif /* LWIP_NETIF_HOSTNAME */ + return ERR_OK; +} /* Send a packet on the given connection. * * This is the low level function that send the PPP packet. */ -static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { +static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { int pd = (int)(size_t)netif->state; PPPControl *pc = &pppControl[pd]; #if PPPOS_SUPPORT @@ -830,7 +793,7 @@ static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_ /* We let any protocol value go through - it can't hurt us * and the peer will just drop it if it's not accepting it. */ if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { - PPPDEBUG(LOG_WARNING, ("ppp_low_level_output[%d]: bad parms prot=%d pb=%p\n", + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad parms prot=%d pb=%p\n", pd, PPP_IP, (void*)pb)); LINK_STATS_INC(link.opterr); LINK_STATS_INC(link.drop); @@ -840,7 +803,7 @@ static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_ /* Check that the link is up. */ if (phase == PHASE_DEAD) { - PPPDEBUG(LOG_ERR, ("ppp_low_level_output[%d]: link not up\n", pd)); + PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pd)); LINK_STATS_INC(link.rterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -849,7 +812,7 @@ static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_ #if PPPOE_SUPPORT if(pc->ethif) { - return pppifOutputOverEthernet(pd, pb); + return ppp_netif_output_over_ethernet(pd, pb); } #endif /* PPPOE_SUPPORT */ @@ -857,7 +820,7 @@ static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_ /* Grab an output buffer. */ headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (headMB == NULL) { - PPPDEBUG(LOG_WARNING, ("ppp_low_level_output[%d]: first alloc fail\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: first alloc fail\n", pd)); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -882,7 +845,7 @@ static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_ protocol = PPP_VJC_UNCOMP; break; default: - PPPDEBUG(LOG_WARNING, ("ppp_low_level_output[%d]: bad IP packet\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pd)); LINK_STATS_INC(link.proterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -943,7 +906,7 @@ static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_ /* If we failed to complete the packet, throw it away. */ if (!tailMB) { PPPDEBUG(LOG_WARNING, - ("ppp_low_level_output[%d]: Alloc err - dropping proto=%d\n", + ("ppp_netif_output[%d]: Alloc err - dropping proto=%d\n", pd, protocol)); pbuf_free(headMB); LINK_STATS_INC(link.memerr); @@ -953,7 +916,7 @@ static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_ } /* Send it. */ - PPPDEBUG(LOG_INFO, ("ppp_low_level_output[%d]: proto=0x%"X16_F"\n", pd, protocol)); + PPPDEBUG(LOG_INFO, ("ppp_netif_output[%d]: proto=0x%"X16_F"\n", pd, protocol)); nPut(pc, headMB); #endif /* PPPOS_SUPPORT */ @@ -961,6 +924,48 @@ static err_t ppp_low_level_output(struct netif *netif, struct pbuf *pb, ip_addr_ return ERR_OK; } +#if PPPOE_SUPPORT +static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + u_short protocol = PPP_IP; + int i=0; + u16_t tot_len; + + /* @todo: try to use pbuf_header() here! */ + pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return ERR_MEM; + } + + pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + + pc->lastXMit = sys_jiffies(); + + if (!pc->pcomp || protocol > 0xFF) { + *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; + } + *((u_char*)pb->payload + i) = protocol & 0xFF; + + pbuf_chain(pb, p); + tot_len = pb->tot_len; + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pc->netif, tot_len); + snmp_inc_ifoutucastpkts(&pc->netif); + LINK_STATS_INC(link.xmit); + return ERR_OK; +} +#endif /* PPPOE_SUPPORT */ + /* * Return the Maximum Transmission Unit for the given PPP connection. @@ -979,49 +984,12 @@ u_short pppMTU(int pd) { return st; } -#if PPPOE_SUPPORT -int pppWriteOverEthernet(int pd, const u_char *s, int n) { - PPPControl *pc = &pppControl[pd]; - struct pbuf *pb; - - /* skip address & flags */ - s += 2; - n -= 2; - - LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_ALLOC; - } - - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - - pc->lastXMit = sys_jiffies(); - - MEMCPY(pb->payload, s, n); - - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { - LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); - return PPPERR_DEVICE; - } - - snmp_add_ifoutoctets(&pc->netif, (u16_t)n); - snmp_inc_ifoutucastpkts(&pc->netif); - LINK_STATS_INC(link.xmit); - return PPPERR_NONE; -} -#endif /* PPPOE_SUPPORT */ - /* * Write n characters to a ppp link. * RETURN: >= 0 Number of characters written * -1 Failed to write to device */ -int ppp_output(int pd, const u_char *s, int n) { +int ppp_write(int pd, const u_char *s, int n) { PPPControl *pc = &pppControl[pd]; #if PPPOS_SUPPORT u_char c; @@ -1031,7 +999,7 @@ int ppp_output(int pd, const u_char *s, int n) { #if PPPOE_SUPPORT if(pc->ethif) { - return pppWriteOverEthernet(pd, s, n); + return ppp_write_over_ethernet(pd, s, n); } #endif /* PPPOE_SUPPORT */ @@ -1076,8 +1044,8 @@ int ppp_output(int pd, const u_char *s, int n) { * Otherwise send it. */ if (!tailMB) { PPPDEBUG(LOG_WARNING, - ("ppp_output[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); - /*"ppp_output[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + ("ppp_write[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); + /*"ppp_write[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ pbuf_free(headMB); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); @@ -1085,26 +1053,77 @@ int ppp_output(int pd, const u_char *s, int n) { return PPPERR_ALLOC; } - PPPDEBUG(LOG_INFO, ("ppp_output[%d]: len=%d\n", pd, headMB->len)); - /* "ppp_output[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pd, headMB->len)); + /* "ppp_write[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ nPut(pc, headMB); #endif /* PPPOS_SUPPORT */ return PPPERR_NONE; } +#if PPPOE_SUPPORT +static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; -/* FIXME: rename all output() to pppWrite() */ -/******************************************************************** - * - * output - Output PPP packet. - */ -/* -void output (int unit, unsigned char *p, int len) -{ - pppWrite(unit, p, len); + /* skip address & flags */ + s += 2; + n -= 2; + + LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + + pc->lastXMit = sys_jiffies(); + + MEMCPY(pb->payload, s, n); + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pc->netif, (u16_t)n); + snmp_inc_ifoutucastpkts(&pc->netif); + LINK_STATS_INC(link.xmit); + return PPPERR_NONE; +} +#endif /* PPPOE_SUPPORT */ + + + +struct pbuf * ppp_singlebuf(struct pbuf *p) { + struct pbuf *q, *b; + u_char *pl; + + if(p->tot_len == p->len) { + return p; + } + + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(!q) { + PPPDEBUG(LOG_ERR, + ("ppp_singlebuf: unable to alloc new buf (%d)\n", p->tot_len)); + return p; /* live dangerously */ + } + + for(b = p, pl = q->payload; b != NULL; b = b->next) { + MEMCPY(pl, b->payload, b->len); + pl += b->len; + } + + pbuf_free(p); + + return q; } -*/ /************************************************************************ @@ -1112,7 +1131,6 @@ void output (int unit, unsigned char *p, int len) * the PPP interface or change the PPP phase. */ - /* * new_phase - signal the start of a new phase of pppd's operation. */ @@ -1237,22 +1255,6 @@ int sifup(int u) return st; } -/* - * ppp_netif_init_cb - netif init callback - */ -static err_t ppp_netif_init_cb(struct netif *netif) { - netif->name[0] = 'p'; - netif->name[1] = 'p'; - netif->output = ppp_low_level_output; - netif->mtu = pppMTU((int)(size_t)netif->state); - netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; -#if LWIP_NETIF_HOSTNAME - /* @todo: Initialize interface hostname */ - /* netif_set_hostname(netif, "lwip"); */ -#endif /* LWIP_NETIF_HOSTNAME */ - return ERR_OK; -} - /******************************************************************** * * sifdown - Disable the indicated protocol and config the interface diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 0dde323d..09a49ff1 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -342,19 +342,19 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha /* PPP flow functions */ -struct pbuf * pppSingleBuf(struct pbuf *p); - -void pppInProcOverEthernet(int pd, struct pbuf *pb); - void pppOverEthernetInitFailed(int pd); u_short pppMTU(int pd); -int pppWriteOverEthernet(int pd, const u_char *s, int n); +#if PPPOE_SUPPORT +/* function called by pppoe.c */ +void ppp_input_over_ethernet(int pd, struct pbuf *pb); +#endif /* PPPOE_SUPPORT */ -int ppp_output(int pd, const u_char *s, int n); +/* function called by all PPP subsystems to send packets */ +int ppp_write(int pd, const u_char *s, int n); -void pppInProcOverEthernet(int pd, struct pbuf *pb); +struct pbuf * ppp_singlebuf(struct pbuf *p); /* Functions called by various PPP subsystems to configure diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 2b7912bf..b265c75b 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -300,7 +300,7 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) int off, err; struct eth_hdr *ethhdr; - pb = pppSingleBuf(pb); + pb = ppp_singlebuf(pb); strcpy(devname, "pppoe"); /* as long as we don't know which instance */ err_msg = NULL; @@ -574,7 +574,7 @@ pppoe_data_input(struct netif *netif, struct pbuf *pb) goto drop; } - pb = pppSingleBuf (pb); + pb = ppp_singlebuf (pb); if (pb->len <= PPPOE_HEADERLEN) { PPPDEBUG(LOG_DEBUG, ("pppoe (data): dropping too short packet: %d bytes\n", pb->len)); @@ -622,7 +622,7 @@ pppoe_data_input(struct netif *netif, struct pbuf *pb) goto drop; } - pppInProcOverEthernet(sc->sc_pd, pb); + ppp_input_over_ethernet(sc->sc_pd, pb); return; diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 33c26e07..8eae19d5 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -592,7 +592,7 @@ upap_sauthreq(u) PUTCHAR(u->us_passwdlen, outp); MEMCPY(outp, u->us_passwd, u->us_passwdlen); - ppp_output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); TIMEOUT(upap_timeout, u, u->us_timeouttime); ++u->us_transmits; @@ -622,7 +622,7 @@ upap_sresp(u, code, id, msg, msglen) PUTSHORT(outlen, outp); PUTCHAR(msglen, outp); MEMCPY(outp, msg, msglen); - ppp_output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } #endif /* UNUSED */ From 05c84a147d135dd3a20a5fa4f82ae6e45eb107e6 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 13:07:46 +0200 Subject: [PATCH 087/320] added ECP_SUPPORT in opt.h (disabled by default); renamed MD5_SUPPORT to PPP_MD5_RANDM, which is more meaningful --- src/include/lwip/opt.h | 17 ++++++++++++----- src/netif/ppp/magic.c | 6 +++--- src/netif/ppp/magic.h | 4 ++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 15167289..f0848d2e 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1741,6 +1741,13 @@ #define CCP_SUPPORT 0 #endif +/** + * ECP_SUPPORT==1: Support ECP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef ECP_SUPPORT +#define ECP_SUPPORT 0 +#endif + /** * VJ_SUPPORT==1: Support VJ header compression. */ @@ -1749,10 +1756,10 @@ #endif /** - * MD5_SUPPORT==1: Support MD5 (see also CHAP). + * PPP_MD5_RANDM==1: Use MD5 for better randomness. */ -#ifndef MD5_SUPPORT -#define MD5_SUPPORT 0 +#ifndef PPP_MD5_RANDM +#define PPP_MD5_RANDM 0 #endif /** @@ -1788,11 +1795,11 @@ * using our cleaned PolarSSL library. */ -#if CHAP_SUPPORT || EAP_SUPPORT || MD5_SUPPORT +#if CHAP_SUPPORT || EAP_SUPPORT || PPP_MD5_RANDM #ifndef LWIP_INCLUDED_POLARSSL_MD5 #define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP and EAP require MD5 support */ #endif /* LWIP_INCLUDED_POLARSSL_MD5 */ -#endif /* CHAP_SUPPORT || EAP_SUPPORT || MD5_SUPPORT */ +#endif /* CHAP_SUPPORT || EAP_SUPPORT || PPP_MD5_RANDM */ #if MSCHAP_SUPPORT #ifndef LWIP_INCLUDED_POLARSSL_MD4 diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 9fe4e08b..73377cf7 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -80,7 +80,7 @@ #include "polarssl/md5.h" #include "magic.h" -#if MD5_SUPPORT /* Using MD5 for better randomness if MD5 support is enabled */ +#if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */ #define MAGIC_RANDPOOLSIZE 16 /* Bytes stored in the pool of randomness. */ @@ -187,7 +187,7 @@ u32_t magic() { return new_rand; } -#else /* MD5_SUPPORT */ +#else /* PPP_MD5_RANDM */ /*****************************/ /*** LOCAL DATA STRUCTURES ***/ @@ -258,6 +258,6 @@ u32_t magic() { return ((((u32_t)rand() << 16) + rand()) + magic_randomseed); } -#endif /* MD5_SUPPORT */ +#endif /* PPP_MD5_RANDM */ #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/magic.h b/src/netif/ppp/magic.h index 8c4c016e..75bab1ca 100644 --- a/src/netif/ppp/magic.h +++ b/src/netif/ppp/magic.h @@ -100,7 +100,7 @@ void magic_randomize(void); */ u32_t magic(void); /* Returns the next magic number */ -#if MD5_SUPPORT +#if PPP_MD5_RANDM /* * Fill buffer with random bytes * @@ -112,7 +112,7 @@ u32_t magic(void); /* Returns the next magic number */ * the first use. */ void random_bytes(unsigned char *buf, u32_t len); -#endif /* MD5_SUPPORT */ +#endif /* PPP_MD5_RANDM */ #endif /* PPP_SUPPORT */ #endif /* MAGIC_H */ From 5464ed666106cb09cdf21db42ace17d4a697d26e Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 13:53:45 +0200 Subject: [PATCH 088/320] removed all useless header files, merged ppp_defs.h to ppp.h removed session.[ch] and tty.c which are Unix-centric files and disabled --- src/netif/ppp/auth.c | 9 +- src/netif/ppp/chap-new.c | 3 + src/netif/ppp/linux/if_ppp.h | 178 ---- src/netif/ppp/linux/if_pppol2tp.h | 79 -- src/netif/ppp/linux/ppp-comp.h | 213 ----- src/netif/ppp/linux/ppp_defs.h | 195 ----- src/netif/ppp/net/if_ppp.h | 156 ---- src/netif/ppp/net/ppp-comp.h | 179 ---- src/netif/ppp/net/ppp_defs.h | 197 ----- src/netif/ppp/net/pppio.h | 107 --- src/netif/ppp/net/slcompress.h | 148 ---- src/netif/ppp/net/vjcompress.h | 144 ---- src/netif/ppp/ppp.c | 19 +- src/netif/ppp/ppp.h | 180 +++- src/netif/ppp/session.c | 431 ---------- src/netif/ppp/session.h | 95 --- src/netif/ppp/tty.c | 1290 ----------------------------- 17 files changed, 192 insertions(+), 3431 deletions(-) delete mode 100644 src/netif/ppp/linux/if_ppp.h delete mode 100644 src/netif/ppp/linux/if_pppol2tp.h delete mode 100644 src/netif/ppp/linux/ppp-comp.h delete mode 100644 src/netif/ppp/linux/ppp_defs.h delete mode 100644 src/netif/ppp/net/if_ppp.h delete mode 100644 src/netif/ppp/net/ppp-comp.h delete mode 100644 src/netif/ppp/net/ppp_defs.h delete mode 100644 src/netif/ppp/net/pppio.h delete mode 100644 src/netif/ppp/net/slcompress.h delete mode 100644 src/netif/ppp/net/vjcompress.h delete mode 100644 src/netif/ppp/session.c delete mode 100644 src/netif/ppp/session.h delete mode 100644 src/netif/ppp/tty.c diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 9b17144b..d96ab99f 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -126,7 +126,9 @@ #include "cbcp.h" #endif +#if 0 /* UNUSED */ #include "session.h" +#endif /* UNUSED */ #if 0 /* UNUSED */ /* Bits in scan_authfile return value */ @@ -1001,7 +1003,12 @@ continue_networks(unit) */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->protocol < 0xC000 - && protp->protocol != PPP_CCP && protp->protocol != PPP_ECP +#if CCP_SUPPORT + && protp->protocol != PPP_CCP +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT + && protp->protocol != PPP_ECP +#endif /* ECP_SUPPORT */ && protp->enabled_flag && protp->open != NULL) { (*protp->open)(0); ++num_np_open; diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index e3520bb6..c92ab19d 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -40,7 +40,10 @@ #include "ppp.h" +#if 0 /* UNUSED */ #include "session.h" +#endif /* UNUSED */ + #include "chap-new.h" #include "chap-md5.h" diff --git a/src/netif/ppp/linux/if_ppp.h b/src/netif/ppp/linux/if_ppp.h deleted file mode 100644 index 1101fc78..00000000 --- a/src/netif/ppp/linux/if_ppp.h +++ /dev/null @@ -1,178 +0,0 @@ -/* $Id: if_ppp.h,v 1.23 2002/12/06 09:49:15 paulus Exp $ */ - -/* - * if_ppp.h - Point-to-Point Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -/* - * ==FILEVERSION 20000724== - * - * NOTE TO MAINTAINERS: - * If you modify this file at all, please set the above date. - * if_ppp.h is shipped with a PPP distribution as well as with the kernel; - * if everyone increases the FILEVERSION number above, then scripts - * can do the right thing when deciding whether to install a new if_ppp.h - * file. Don't change the format of that line otherwise, so the - * installation script can recognize it. - */ - -#ifndef _IF_PPP_H_ -#define _IF_PPP_H_ - -/* - * Packet sizes - */ - -#define PPP_MTU 1500 /* Default MTU (size of Info field) */ -#define PPP_MAXMRU 65000 /* Largest MRU we allow */ -#define PROTO_IPX 0x002b /* protocol numbers */ -#define PROTO_DNA_RT 0x0027 /* DNA Routing */ - - -/* - * Bit definitions for flags. - */ - -#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */ -#define SC_COMP_AC 0x00000002 /* header compression (output) */ -#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */ -#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */ -#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */ -#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */ -#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */ -#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */ -#define SC_ENABLE_IP 0x00000100 /* IP packets may be exchanged */ -#define SC_LOOP_TRAFFIC 0x00000200 /* send traffic to pppd */ -#define SC_MULTILINK 0x00000400 /* do multilink encapsulation */ -#define SC_MP_SHORTSEQ 0x00000800 /* use short MP sequence numbers */ -#define SC_COMP_RUN 0x00001000 /* compressor has been inited */ -#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */ -#define SC_MP_XSHORTSEQ 0x00004000 /* transmit short MP seq numbers */ -#define SC_DEBUG 0x00010000 /* enable debug messages */ -#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */ -#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ -#define SC_LOG_RAWIN 0x00080000 /* log all chars received */ -#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ -#define SC_SYNC 0x00200000 /* synchronous serial mode */ -#define SC_MASK 0x0f200fff /* bits that user can change */ - -/* state bits */ -#define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */ -#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ -#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ -#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */ -#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ -#define SC_DC_FERROR 0x00800000 /* fatal decomp error detected */ -#define SC_DC_ERROR 0x00400000 /* non-fatal decomp error detected */ - -/* - * Ioctl definitions. - */ - -struct npioctl { - int protocol; /* PPP protocol, e.g. PPP_IP */ - enum NPmode mode; -}; - -/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ -struct ppp_option_data { - __u8 *ptr; - __u32 length; - int transmit; -}; - -struct ifpppstatsreq { - struct ifreq b; - struct ppp_stats stats; /* statistic information */ -}; - -struct ifpppcstatsreq { - struct ifreq b; - struct ppp_comp_stats stats; -}; - -#define ifr__name b.ifr_ifrn.ifrn_name -#define stats_ptr b.ifr_ifru.ifru_data - -/* - * Ioctl definitions. - */ - -#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */ -#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */ -#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */ -#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */ -#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */ -#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */ -#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */ -#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */ -#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */ -#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */ -#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */ -#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */ -#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */ -#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data) -#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */ -#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */ -#define PPPIOCSPASS _IOW('t', 71, struct sock_fprog) /* set pass filter */ -#define PPPIOCSACTIVE _IOW('t', 70, struct sock_fprog) /* set active filt */ -#define PPPIOCGDEBUG _IOR('t', 65, int) /* Read debug level */ -#define PPPIOCSDEBUG _IOW('t', 64, int) /* Set debug level */ -#define PPPIOCGIDLE _IOR('t', 63, struct ppp_idle) /* get idle time */ -#define PPPIOCNEWUNIT _IOWR('t', 62, int) /* create new ppp unit */ -#define PPPIOCATTACH _IOW('t', 61, int) /* attach to ppp unit */ -#define PPPIOCDETACH _IOW('t', 60, int) /* detach from ppp unit/chan */ -#define PPPIOCSMRRU _IOW('t', 59, int) /* set multilink MRU */ -#define PPPIOCCONNECT _IOW('t', 58, int) /* connect channel to unit */ -#define PPPIOCDISCONN _IO('t', 57) /* disconnect channel */ -#define PPPIOCATTCHAN _IOW('t', 56, int) /* attach to ppp channel */ -#define PPPIOCGCHAN _IOR('t', 55, int) /* get ppp channel number */ - -#define SIOCGPPPSTATS (SIOCDEVPRIVATE + 0) -#define SIOCGPPPVER (SIOCDEVPRIVATE + 1) /* NEVER change this!! */ -#define SIOCGPPPCSTATS (SIOCDEVPRIVATE + 2) - -#if !defined(ifr_mtu) -#define ifr_mtu ifr_ifru.ifru_metric -#endif - -#endif /* _IF_PPP_H_ */ diff --git a/src/netif/ppp/linux/if_pppol2tp.h b/src/netif/ppp/linux/if_pppol2tp.h deleted file mode 100644 index 7ee86b24..00000000 --- a/src/netif/ppp/linux/if_pppol2tp.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * Linux PPP over L2TP (PPPoL2TP) Socket Implementation (RFC 2661) - * - * This file supplies definitions required by the PPP over L2TP driver - * (l2tp_ppp.c). All version information wrt this file is located in l2tp_ppp.c - * - * License: - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#ifndef __LINUX_IF_PPPOL2TP_H -#define __LINUX_IF_PPPOL2TP_H - -#include - - -/* Structure used to connect() the socket to a particular tunnel UDP - * socket. - */ -struct pppol2tp_addr { - __kernel_pid_t pid; /* pid that owns the fd. - * 0 => current */ - int fd; /* FD of UDP socket to use */ - - struct sockaddr_in addr; /* IP address and port to send to */ - - __u16 s_tunnel, s_session; /* For matching incoming packets */ - __u16 d_tunnel, d_session; /* For sending outgoing packets */ -}; - -/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32 - * bits. So we need a different sockaddr structure. - */ -struct pppol2tpv3_addr { - pid_t pid; /* pid that owns the fd. - * 0 => current */ - int fd; /* FD of UDP or IP socket to use */ - - struct sockaddr_in addr; /* IP address and port to send to */ - - __u32 s_tunnel, s_session; /* For matching incoming packets */ - __u32 d_tunnel, d_session; /* For sending outgoing packets */ -}; - -/* Socket options: - * DEBUG - bitmask of debug message categories - * SENDSEQ - 0 => don't send packets with sequence numbers - * 1 => send packets with sequence numbers - * RECVSEQ - 0 => receive packet sequence numbers are optional - * 1 => drop receive packets without sequence numbers - * LNSMODE - 0 => act as LAC. - * 1 => act as LNS. - * REORDERTO - reorder timeout (in millisecs). If 0, don't try to reorder. - */ -enum { - PPPOL2TP_SO_DEBUG = 1, - PPPOL2TP_SO_RECVSEQ = 2, - PPPOL2TP_SO_SENDSEQ = 3, - PPPOL2TP_SO_LNSMODE = 4, - PPPOL2TP_SO_REORDERTO = 5, -}; - -/* Debug message categories for the DEBUG socket option */ -enum { - PPPOL2TP_MSG_DEBUG = (1 << 0), /* verbose debug (if - * compiled in) */ - PPPOL2TP_MSG_CONTROL = (1 << 1), /* userspace - kernel - * interface */ - PPPOL2TP_MSG_SEQ = (1 << 2), /* sequence numbers */ - PPPOL2TP_MSG_DATA = (1 << 3), /* data packets */ -}; - - - -#endif diff --git a/src/netif/ppp/linux/ppp-comp.h b/src/netif/ppp/linux/ppp-comp.h deleted file mode 100644 index d30cacbd..00000000 --- a/src/netif/ppp/linux/ppp-comp.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * ppp-comp.h - Definitions for doing PPP packet compression. - * - * Copyright (c) 1984 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ppp-comp.h,v 1.10 2002/12/06 09:49:15 paulus Exp $ - */ - -/* - * ==FILEVERSION 20020319== - * - * NOTE TO MAINTAINERS: - * If you modify this file at all, please set the above date. - * ppp-comp.h is shipped with a PPP distribution as well as with the kernel; - * if everyone increases the FILEVERSION number above, then scripts - * can do the right thing when deciding whether to install a new ppp-comp.h - * file. Don't change the format of that line otherwise, so the - * installation script can recognize it. - */ - -#ifndef _NET_PPP_COMP_H -#define _NET_PPP_COMP_H - -/* - * The following symbols control whether we include code for - * various compression methods. - */ - -#ifndef DO_BSD_COMPRESS -#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ -#endif -#ifndef DO_DEFLATE -#define DO_DEFLATE 1 /* by default, include Deflate */ -#endif -#define DO_PREDICTOR_1 0 -#define DO_PREDICTOR_2 0 - -/* - * Structure giving methods for compression/decompression. - */ - -struct compressor { - int compress_proto; /* CCP compression protocol number */ - - /* Allocate space for a compressor (transmit side) */ - void *(*comp_alloc) (unsigned char *options, int opt_len); - - /* Free space used by a compressor */ - void (*comp_free) (void *state); - - /* Initialize a compressor */ - int (*comp_init) (void *state, unsigned char *options, - int opt_len, int unit, int opthdr, int debug); - - /* Reset a compressor */ - void (*comp_reset) (void *state); - - /* Compress a packet */ - int (*compress) (void *state, unsigned char *rptr, - unsigned char *obuf, int isize, int osize); - - /* Return compression statistics */ - void (*comp_stat) (void *state, struct compstat *stats); - - /* Allocate space for a decompressor (receive side) */ - void *(*decomp_alloc) (unsigned char *options, int opt_len); - - /* Free space used by a decompressor */ - void (*decomp_free) (void *state); - - /* Initialize a decompressor */ - int (*decomp_init) (void *state, unsigned char *options, - int opt_len, int unit, int opthdr, int mru, - int debug); - - /* Reset a decompressor */ - void (*decomp_reset) (void *state); - - /* Decompress a packet. */ - int (*decompress) (void *state, unsigned char *ibuf, int isize, - unsigned char *obuf, int osize); - - /* Update state for an incompressible packet received */ - void (*incomp) (void *state, unsigned char *ibuf, int icnt); - - /* Return decompression statistics */ - void (*decomp_stat) (void *state, struct compstat *stats); -}; - -/* - * The return value from decompress routine is the length of the - * decompressed packet if successful, otherwise DECOMP_ERROR - * or DECOMP_FATALERROR if an error occurred. - * - * We need to make this distinction so that we can disable certain - * useful functionality, namely sending a CCP reset-request as a result - * of an error detected after decompression. This is to avoid infringing - * a patent held by Motorola. - * Don't you just lurve software patents. - */ - -#define DECOMP_ERROR -1 /* error detected before decomp. */ -#define DECOMP_FATALERROR -2 /* error detected after decomp. */ - -/* - * CCP codes. - */ - -#define CCP_CONFREQ 1 -#define CCP_CONFACK 2 -#define CCP_TERMREQ 5 -#define CCP_TERMACK 6 -#define CCP_RESETREQ 14 -#define CCP_RESETACK 15 - -/* - * Max # bytes for a CCP option - */ - -#define CCP_MAX_OPTION_LENGTH 32 - -/* - * Parts of a CCP packet. - */ - -#define CCP_CODE(dp) ((dp)[0]) -#define CCP_ID(dp) ((dp)[1]) -#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) -#define CCP_HDRLEN 4 - -#define CCP_OPT_CODE(dp) ((dp)[0]) -#define CCP_OPT_LENGTH(dp) ((dp)[1]) -#define CCP_OPT_MINLEN 2 - -/* - * Definitions for BSD-Compress. - */ - -#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ -#define CILEN_BSD_COMPRESS 3 /* length of config. option */ - -/* Macros for handling the 3rd byte of the BSD-Compress config option. */ -#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ -#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ -#define BSD_CURRENT_VERSION 1 /* current version number */ -#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) - -#define BSD_MIN_BITS 9 /* smallest code size supported */ -#define BSD_MAX_BITS 15 /* largest code size supported */ - -/* - * Definitions for Deflate. - */ - -#define CI_DEFLATE 26 /* config option for Deflate */ -#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ -#define CILEN_DEFLATE 4 /* length of its config option */ - -#define DEFLATE_MIN_SIZE 8 -#define DEFLATE_MAX_SIZE 15 -#define DEFLATE_METHOD_VAL 8 -#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) -#define DEFLATE_METHOD(x) ((x) & 0x0F) -#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ - + DEFLATE_METHOD_VAL) -#define DEFLATE_CHK_SEQUENCE 0 - -/* - * Definitions for MPPE. - */ - -#define CI_MPPE 18 /* config option for MPPE */ -#define CILEN_MPPE 6 /* length of config option */ - -/* - * Definitions for other, as yet unsupported, compression methods. - */ - -#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ -#define CILEN_PREDICTOR_1 2 /* length of its config option */ -#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ -#define CILEN_PREDICTOR_2 2 /* length of its config option */ - -#endif /* _NET_PPP_COMP_H */ diff --git a/src/netif/ppp/linux/ppp_defs.h b/src/netif/ppp/linux/ppp_defs.h deleted file mode 100644 index 314339e9..00000000 --- a/src/netif/ppp/linux/ppp_defs.h +++ /dev/null @@ -1,195 +0,0 @@ -/* $Id: ppp_defs.h,v 1.11 2002/12/06 09:49:15 paulus Exp $ */ - -/* - * ppp_defs.h - PPP definitions. - * - * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * ==FILEVERSION 20020521== - * - * NOTE TO MAINTAINERS: - * If you modify this file at all, please set the above date. - * ppp_defs.h is shipped with a PPP distribution as well as with the kernel; - * if everyone increases the FILEVERSION number above, then scripts - * can do the right thing when deciding whether to install a new ppp_defs.h - * file. Don't change the format of that line otherwise, so the - * installation script can recognize it. - */ - -#ifndef _PPP_DEFS_H_ -#define _PPP_DEFS_H_ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ -#define PPP_MRU 1500 /* default MRU = max length of info field */ - -#define PPP_ADDRESS(p) (((__u8 *)(p))[0]) -#define PPP_CONTROL(p) (((__u8 *)(p))[1]) -#define PPP_PROTOCOL(p) ((((__u8 *)(p))[2] << 8) + ((__u8 *)(p))[3]) - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_IPX 0x2b /* IPX protocol */ -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#define PPP_MP 0x3d /* Multilink protocol */ -#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ -#define PPP_COMPFRAG 0xfb /* fragment compressed below bundle */ -#define PPP_COMP 0xfd /* compressed packet */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_IPXCP 0x802b /* IPX Control Protocol */ -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#define PPP_CCPFRAG 0x80fb /* CCP at link level (below MP bundle) */ -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#define PPP_ECPFRAG 0x8055 /* ECP at link level (below MP bundle) */ -#define PPP_ECP 0x8053 /* Encryption Control Protocol */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ - -/* - * Values for FCS calculations. - */ - -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) - -/* - * Extended asyncmap - allows any character to be escaped. - */ - -typedef __u32 ext_accm[8]; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Statistics for LQRP and pppstats - */ -struct pppstat { - __u32 ppp_discards; /* # frames discarded */ - - __u32 ppp_ibytes; /* bytes received */ - __u32 ppp_ioctects; /* bytes received not in error */ - __u32 ppp_ipackets; /* packets received */ - __u32 ppp_ierrors; /* receive errors */ - __u32 ppp_ilqrs; /* # LQR frames received */ - - __u32 ppp_obytes; /* raw bytes sent */ - __u32 ppp_ooctects; /* frame bytes sent */ - __u32 ppp_opackets; /* packets sent */ - __u32 ppp_oerrors; /* transmit errors */ - __u32 ppp_olqrs; /* # LQR frames sent */ -}; - -struct vjstat { - __u32 vjs_packets; /* outbound packets */ - __u32 vjs_compressed; /* outbound compressed packets */ - __u32 vjs_searches; /* searches for connection state */ - __u32 vjs_misses; /* times couldn't find conn. state */ - __u32 vjs_uncompressedin; /* inbound uncompressed packets */ - __u32 vjs_compressedin; /* inbound compressed packets */ - __u32 vjs_errorin; /* inbound unknown type packets */ - __u32 vjs_tossed; /* inbound packets tossed because of error */ -}; - -struct compstat { - __u32 unc_bytes; /* total uncompressed bytes */ - __u32 unc_packets; /* total uncompressed packets */ - __u32 comp_bytes; /* compressed bytes */ - __u32 comp_packets; /* compressed packets */ - __u32 inc_bytes; /* incompressible bytes */ - __u32 inc_packets; /* incompressible packets */ - - /* the compression ratio is defined as in_count / bytes_out */ - __u32 in_count; /* Bytes received */ - __u32 bytes_out; /* Bytes transmitted */ - - double ratio; /* not computed in kernel. */ -}; - -struct ppp_stats { - struct pppstat p; /* basic PPP statistics */ - struct vjstat vj; /* VJ header compression statistics */ -}; - -struct ppp_comp_stats { - struct compstat c; /* packet compression statistics */ - struct compstat d; /* packet decompression statistics */ -}; - -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - time_t xmit_idle; /* time since last NP packet sent */ - time_t recv_idle; /* time since last NP packet received */ -}; - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - -#endif /* _PPP_DEFS_H_ */ diff --git a/src/netif/ppp/net/if_ppp.h b/src/netif/ppp/net/if_ppp.h deleted file mode 100644 index bfec6064..00000000 --- a/src/netif/ppp/net/if_ppp.h +++ /dev/null @@ -1,156 +0,0 @@ -/* $Id: if_ppp.h,v 1.19 2002/12/06 09:49:15 paulus Exp $ */ - -/* - * if_ppp.h - Point-to-Point Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _IF_PPP_H_ -#define _IF_PPP_H_ - -/* - * Bit definitions for flags. - */ -#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */ -#define SC_COMP_AC 0x00000002 /* header compression (output) */ -#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */ -#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */ -#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */ -#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */ -#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */ -#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */ -#define SC_DEBUG 0x00010000 /* enable debug messages */ -#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */ -#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ -#define SC_LOG_RAWIN 0x00080000 /* log all chars received */ -#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ -#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ -#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */ -#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ -#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ -#define SC_SYNC 0x00200000 /* use synchronous HDLC framing */ -#define SC_MASK 0x0fff00ff /* bits that user can change */ - -/* - * State bits in sc_flags, not changeable by user. - */ -#define SC_TIMEOUT 0x00000400 /* timeout is currently pending */ -#define SC_VJ_RESET 0x00000800 /* need to reset VJ decomp */ -#define SC_COMP_RUN 0x00001000 /* compressor has been inited */ -#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */ -#define SC_DC_ERROR 0x00004000 /* non-fatal decomp error detected */ -#define SC_DC_FERROR 0x00008000 /* fatal decomp error detected */ -#define SC_TBUSY 0x10000000 /* xmitter doesn't need a packet yet */ -#define SC_PKTLOST 0x20000000 /* have lost or dropped a packet */ -#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */ -#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */ - -/* - * Ioctl definitions. - */ - -struct npioctl { - int protocol; /* PPP procotol, e.g. PPP_IP */ - enum NPmode mode; -}; - -/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ -struct ppp_option_data { - u_char *ptr; - u_int length; - int transmit; -}; - -struct ifpppstatsreq { - char ifr_name[IFNAMSIZ]; - struct ppp_stats stats; -}; - -struct ifpppcstatsreq { - char ifr_name[IFNAMSIZ]; - struct ppp_comp_stats stats; -}; - -/* - * Ioctl definitions. - */ - -#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */ -#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */ -#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */ -#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */ -#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */ -#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */ -#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */ -#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */ -#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */ -#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */ -#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */ -#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */ -#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */ -#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data) -#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */ -#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */ -#define PPPIOCGIDLE _IOR('t', 74, struct ppp_idle) /* get idle time */ -#ifdef PPP_FILTER -#define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */ -#define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */ -#endif /* PPP_FILTER */ - -/* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */ -#define PPPIOCGMTU _IOR('t', 73, int) /* get interface MTU */ -#define PPPIOCSMTU _IOW('t', 72, int) /* set interface MTU */ - -/* - * These two are interface ioctls so that pppstats can do them on - * a socket without having to open the serial device. - */ -#define SIOCGPPPSTATS _IOWR('i', 123, struct ifpppstatsreq) -#define SIOCGPPPCSTATS _IOWR('i', 122, struct ifpppcstatsreq) - -#if !defined(ifr_mtu) -#define ifr_mtu ifr_ifru.ifru_metric -#endif - -#if (defined(_KERNEL) || defined(KERNEL)) && !defined(NeXT) -void pppattach __P((void)); -void pppintr __P((void)); -#endif -#endif /* _IF_PPP_H_ */ diff --git a/src/netif/ppp/net/ppp-comp.h b/src/netif/ppp/net/ppp-comp.h deleted file mode 100644 index 088c73e9..00000000 --- a/src/netif/ppp/net/ppp-comp.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * ppp-comp.h - Definitions for doing PPP packet compression. - * - * Copyright (c) 1984 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ppp-comp.h,v 1.13 2002/12/06 09:49:15 paulus Exp $ - */ - -#ifndef _NET_PPP_COMP_H -#define _NET_PPP_COMP_H - -/* - * The following symbols control whether we include code for - * various compression methods. - */ -#ifndef DO_BSD_COMPRESS -#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ -#endif -#ifndef DO_DEFLATE -#define DO_DEFLATE 1 /* by default, include Deflate */ -#endif -#define DO_PREDICTOR_1 0 -#define DO_PREDICTOR_2 0 - -/* - * Structure giving methods for compression/decompression. - */ -#ifdef PACKETPTR -struct compressor { - int compress_proto; /* CCP compression protocol number */ - - /* Allocate space for a compressor (transmit side) */ - void *(*comp_alloc) __P((u_char *options, int opt_len)); - /* Free space used by a compressor */ - void (*comp_free) __P((void *state)); - /* Initialize a compressor */ - int (*comp_init) __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int debug)); - /* Reset a compressor */ - void (*comp_reset) __P((void *state)); - /* Compress a packet */ - int (*compress) __P((void *state, PACKETPTR *mret, - PACKETPTR mp, int orig_len, int max_len)); - /* Return compression statistics */ - void (*comp_stat) __P((void *state, struct compstat *stats)); - - /* Allocate space for a decompressor (receive side) */ - void *(*decomp_alloc) __P((u_char *options, int opt_len)); - /* Free space used by a decompressor */ - void (*decomp_free) __P((void *state)); - /* Initialize a decompressor */ - int (*decomp_init) __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); - /* Reset a decompressor */ - void (*decomp_reset) __P((void *state)); - /* Decompress a packet. */ - int (*decompress) __P((void *state, PACKETPTR mp, - PACKETPTR *dmpp)); - /* Update state for an incompressible packet received */ - void (*incomp) __P((void *state, PACKETPTR mp)); - /* Return decompression statistics */ - void (*decomp_stat) __P((void *state, struct compstat *stats)); -}; -#endif /* PACKETPTR */ - -/* - * Return values for decompress routine. - * We need to make these distinctions so that we can disable certain - * useful functionality, namely sending a CCP reset-request as a result - * of an error detected after decompression. This is to avoid infringing - * a patent held by Motorola. - * Don't you just lurve software patents. - */ -#define DECOMP_OK 0 /* everything went OK */ -#define DECOMP_ERROR 1 /* error detected before decomp. */ -#define DECOMP_FATALERROR 2 /* error detected after decomp. */ - -/* - * CCP codes. - */ -#define CCP_CONFREQ 1 -#define CCP_CONFACK 2 -#define CCP_TERMREQ 5 -#define CCP_TERMACK 6 -#define CCP_RESETREQ 14 -#define CCP_RESETACK 15 - -/* - * Max # bytes for a CCP option - */ -#define CCP_MAX_OPTION_LENGTH 32 - -/* - * Parts of a CCP packet. - */ -#define CCP_CODE(dp) ((dp)[0]) -#define CCP_ID(dp) ((dp)[1]) -#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) -#define CCP_HDRLEN 4 - -#define CCP_OPT_CODE(dp) ((dp)[0]) -#define CCP_OPT_LENGTH(dp) ((dp)[1]) -#define CCP_OPT_MINLEN 2 - -/* - * Definitions for BSD-Compress. - */ -#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ -#define CILEN_BSD_COMPRESS 3 /* length of config. option */ - -/* Macros for handling the 3rd byte of the BSD-Compress config option. */ -#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ -#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ -#define BSD_CURRENT_VERSION 1 /* current version number */ -#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) - -#define BSD_MIN_BITS 9 /* smallest code size supported */ -#define BSD_MAX_BITS 15 /* largest code size supported */ - -/* - * Definitions for Deflate. - */ -#define CI_DEFLATE 26 /* config option for Deflate */ -#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ -#define CILEN_DEFLATE 4 /* length of its config option */ - -#define DEFLATE_MIN_SIZE 8 -#define DEFLATE_MAX_SIZE 15 -#define DEFLATE_METHOD_VAL 8 -#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) -#define DEFLATE_METHOD(x) ((x) & 0x0F) -#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ - + DEFLATE_METHOD_VAL) -#define DEFLATE_CHK_SEQUENCE 0 - -/* - * Definitions for MPPE. - */ -#define CI_MPPE 18 /* config option for MPPE */ -#define CILEN_MPPE 6 /* length of config option */ - -/* - * Definitions for other, as yet unsupported, compression methods. - */ -#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ -#define CILEN_PREDICTOR_1 2 /* length of its config option */ -#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ -#define CILEN_PREDICTOR_2 2 /* length of its config option */ - -#endif /* _NET_PPP_COMP_H */ diff --git a/src/netif/ppp/net/ppp_defs.h b/src/netif/ppp/net/ppp_defs.h deleted file mode 100644 index 2baf70a6..00000000 --- a/src/netif/ppp/net/ppp_defs.h +++ /dev/null @@ -1,197 +0,0 @@ -/* $Id: ppp_defs.h,v 1.17 2002/12/06 09:49:15 paulus Exp $ */ - -/* - * ppp_defs.h - PPP definitions. - * - * Copyright (c) 1984 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _PPP_DEFS_H_ -#define _PPP_DEFS_H_ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - -/* - * Packet sizes - * - * Note - lcp shouldn't be allowed to negotiate stuff outside these - * limits. See lcp.h in the pppd directory. - * (XXX - these constants should simply be shared by lcp.c instead - * of living in lcp.h) - */ -#if 0 /* defined in opt.h */ -#define PPP_MTU 1500 /* Default MTU (size of Info field) */ -#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) -#define PPP_MINMTU 64 -#define PPP_MRU 1500 /* default MRU = max length of info field */ -#define PPP_MAXMRU 65000 /* Largest MRU we allow */ -#define PPP_MINMRU 128 -#endif - -#define PPP_ADDRESS(p) (((u_char *)(p))[0]) -#define PPP_CONTROL(p) (((u_char *)(p))[1]) -#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) - - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_IPX 0x2b /* IPX protocol */ -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ -#define PPP_COMP 0xfd /* compressed packet */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_IPXCP 0x802b /* IPX Control Protocol */ -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#define PPP_ECP 0x8053 /* Encryption Control Protocol */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ -#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ - -/* - * Values for FCS calculations. - */ -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) - -/* - * A 32-bit unsigned integral type. - */ - -#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \ - && !defined(__FreeBSD__) && (NS_TARGET < 40) -#ifdef UINT32_T -typedef UINT32_T u_int32_t; -#else -typedef unsigned int u_int32_t; -typedef unsigned short u_int16_t; -#endif -#endif - -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u_int32_t ext_accm[8]; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Statistics. - */ -struct pppstat { - unsigned int ppp_ibytes; /* bytes received */ - unsigned int ppp_ipackets; /* packets received */ - unsigned int ppp_ierrors; /* receive errors */ - unsigned int ppp_obytes; /* bytes sent */ - unsigned int ppp_opackets; /* packets sent */ - unsigned int ppp_oerrors; /* transmit errors */ -}; - -struct vjstat { - unsigned int vjs_packets; /* outbound packets */ - unsigned int vjs_compressed; /* outbound compressed packets */ - unsigned int vjs_searches; /* searches for connection state */ - unsigned int vjs_misses; /* times couldn't find conn. state */ - unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ - unsigned int vjs_compressedin; /* inbound compressed packets */ - unsigned int vjs_errorin; /* inbound unknown type packets */ - unsigned int vjs_tossed; /* inbound packets tossed because of error */ -}; - -struct ppp_stats { - struct pppstat p; /* basic PPP statistics */ - struct vjstat vj; /* VJ header compression statistics */ -}; - -struct compstat { - unsigned int unc_bytes; /* total uncompressed bytes */ - unsigned int unc_packets; /* total uncompressed packets */ - unsigned int comp_bytes; /* compressed bytes */ - unsigned int comp_packets; /* compressed packets */ - unsigned int inc_bytes; /* incompressible bytes */ - unsigned int inc_packets; /* incompressible packets */ - unsigned int ratio; /* recent compression ratio << 8 */ -}; - -struct ppp_comp_stats { - struct compstat c; /* packet compression statistics */ - struct compstat d; /* packet decompression statistics */ -}; - -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - time_t xmit_idle; /* time since last NP packet sent */ - time_t recv_idle; /* time since last NP packet received */ -}; - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - -#endif /* _PPP_DEFS_H_ */ diff --git a/src/netif/ppp/net/pppio.h b/src/netif/ppp/net/pppio.h deleted file mode 100644 index 54cfe445..00000000 --- a/src/netif/ppp/net/pppio.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * pppio.h - ioctl and other misc. definitions for STREAMS modules. - * - * Copyright (c) 1994 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: pppio.h,v 1.9 2002/12/06 09:49:15 paulus Exp $ - */ - -#define _PPPIO(n) (('p' << 8) + (n)) - -#define PPPIO_NEWPPA _PPPIO(130) /* allocate a new PPP unit */ -#define PPPIO_GETSTAT _PPPIO(131) /* get PPP statistics */ -#define PPPIO_GETCSTAT _PPPIO(132) /* get PPP compression stats */ -#define PPPIO_MTU _PPPIO(133) /* set max transmission unit */ -#define PPPIO_MRU _PPPIO(134) /* set max receive unit */ -#define PPPIO_CFLAGS _PPPIO(135) /* set/clear/get compression flags */ -#define PPPIO_XCOMP _PPPIO(136) /* alloc transmit compressor */ -#define PPPIO_RCOMP _PPPIO(137) /* alloc receive decompressor */ -#define PPPIO_XACCM _PPPIO(138) /* set transmit asyncmap */ -#define PPPIO_RACCM _PPPIO(139) /* set receive asyncmap */ -#define PPPIO_VJINIT _PPPIO(140) /* initialize VJ comp/decomp */ -#define PPPIO_ATTACH _PPPIO(141) /* attach to a ppa (without putmsg) */ -#define PPPIO_LASTMOD _PPPIO(142) /* mark last ppp module */ -#define PPPIO_GCLEAN _PPPIO(143) /* get 8-bit-clean flags */ -#define PPPIO_DEBUG _PPPIO(144) /* request debug information */ -#define PPPIO_BIND _PPPIO(145) /* bind to SAP */ -#define PPPIO_NPMODE _PPPIO(146) /* set mode for handling data pkts */ -#define PPPIO_GIDLE _PPPIO(147) /* get time since last data pkt */ -#define PPPIO_PASSFILT _PPPIO(148) /* set filter for packets to pass */ -#define PPPIO_ACTIVEFILT _PPPIO(149) /* set filter for "link active" pkts */ - -/* - * Values for PPPIO_CFLAGS - */ -#define COMP_AC 0x1 /* compress address/control */ -#define DECOMP_AC 0x2 /* decompress address/control */ -#define COMP_PROT 0x4 /* compress PPP protocol */ -#define DECOMP_PROT 0x8 /* decompress PPP protocol */ - -#define COMP_VJC 0x10 /* compress TCP/IP headers */ -#define COMP_VJCCID 0x20 /* compress connection ID as well */ -#define DECOMP_VJC 0x40 /* decompress TCP/IP headers */ -#define DECOMP_VJCCID 0x80 /* accept compressed connection ID */ - -#define CCP_ISOPEN 0x100 /* look at CCP packets */ -#define CCP_ISUP 0x200 /* do packet comp/decomp */ -#define CCP_ERROR 0x400 /* (status) error in packet decomp */ -#define CCP_FATALERROR 0x800 /* (status) fatal error ditto */ -#define CCP_COMP_RUN 0x1000 /* (status) seen CCP ack sent */ -#define CCP_DECOMP_RUN 0x2000 /* (status) seen CCP ack rcvd */ - -/* - * Values for 8-bit-clean flags. - */ -#define RCV_B7_0 1 /* have rcvd char with bit 7 = 0 */ -#define RCV_B7_1 2 /* have rcvd char with bit 7 = 1 */ -#define RCV_EVNP 4 /* have rcvd char with even parity */ -#define RCV_ODDP 8 /* have rcvd char with odd parity */ - -/* - * Values for the first byte of M_CTL messages passed between - * PPP modules. - */ -#define PPPCTL_OERROR 0xe0 /* output error [up] */ -#define PPPCTL_IERROR 0xe1 /* input error (e.g. FCS) [up] */ -#define PPPCTL_MTU 0xe2 /* set MTU [down] */ -#define PPPCTL_MRU 0xe3 /* set MRU [down] */ -#define PPPCTL_UNIT 0xe4 /* note PPP unit number [down] */ - -/* - * Values for the integer argument to PPPIO_DEBUG. - */ -#define PPPDBG_DUMP 0x10000 /* print out debug info now */ -#define PPPDBG_LOG 0x100 /* log various things */ -#define PPPDBG_DRIVER 0 /* identifies ppp driver as target */ -#define PPPDBG_IF 1 /* identifies ppp network i/f target */ -#define PPPDBG_COMP 2 /* identifies ppp compression target */ -#define PPPDBG_AHDLC 3 /* identifies ppp async hdlc target */ diff --git a/src/netif/ppp/net/slcompress.h b/src/netif/ppp/net/slcompress.h deleted file mode 100644 index d887dfc2..00000000 --- a/src/netif/ppp/net/slcompress.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Definitions for tcp compression routines. - * - * $Id: slcompress.h,v 1.4 1994/09/21 06:50:08 paulus Exp $ - * - * Copyright (c) 1989 Regents of the University of California. - * 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 University of California, Berkeley. 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. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - */ - -#ifndef _SLCOMPRESS_H_ -#define _SLCOMPRESS_H_ - -#define MAX_STATES 16 /* must be > 2 and < 256 */ -#define MAX_HDR MLEN /* XXX 4bsd-ism: should really be 128 */ - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowlegement, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - -/* packet types */ -#define TYPE_IP 0x40 -#define TYPE_UNCOMPRESSED_TCP 0x70 -#define TYPE_COMPRESSED_TCP 0x80 -#define TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - struct cstate *cs_next; /* next most recently used cstate (xmit only) */ - u_short cs_hlen; /* size of hdr (receive only) */ - u_char cs_id; /* connection # associated with this state */ - u_char cs_filler; - union { - char csu_hdr[MAX_HDR]; - struct ip csu_ip; /* ip/tcp hdr from most recent packet */ - } slcs_u; -}; -#define cs_ip slcs_u.csu_ip -#define cs_hdr slcs_u.csu_hdr - -/* - * all the state data for one serial line (we need one of these - * per line). - */ -struct slcompress { - struct cstate *last_cs; /* most recently used tstate */ - u_char last_recv; /* last rcvd conn. id */ - u_char last_xmit; /* last sent conn. id */ - u_short flags; -#ifndef SL_NO_STATS - int sls_packets; /* outbound packets */ - int sls_compressed; /* outbound compressed packets */ - int sls_searches; /* searches for connection state */ - int sls_misses; /* times couldn't find conn. state */ - int sls_uncompressedin; /* inbound uncompressed packets */ - int sls_compressedin; /* inbound compressed packets */ - int sls_errorin; /* inbound unknown type packets */ - int sls_tossed; /* inbound packets tossed because of error */ -#endif - struct cstate tstate[MAX_STATES]; /* xmit connection states */ - struct cstate rstate[MAX_STATES]; /* receive connection states */ -}; -/* flag values */ -#define SLF_TOSS 1 /* tossing rcvd frames because of input err */ - -void sl_compress_init __P((struct slcompress *)); -void sl_compress_setup __P((struct slcompress *, int)); -u_int sl_compress_tcp __P((struct mbuf *, - struct ip *, struct slcompress *, int)); -int sl_uncompress_tcp __P((u_char **, int, u_int, struct slcompress *)); -int sl_uncompress_tcp_core __P((u_char *, int, int, u_int, - struct slcompress *, u_char **, u_int *)); - -#endif /* _SLCOMPRESS_H_ */ diff --git a/src/netif/ppp/net/vjcompress.h b/src/netif/ppp/net/vjcompress.h deleted file mode 100644 index 03a33bf7..00000000 --- a/src/netif/ppp/net/vjcompress.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Definitions for tcp compression routines. - * - * $Id: vjcompress.h,v 1.3 1996/05/28 00:55:33 paulus Exp $ - * - * Copyright (c) 1989 Regents of the University of California. - * 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 University of California, Berkeley. 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. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - */ - -#ifndef _VJCOMPRESS_H_ -#define _VJCOMPRESS_H_ - -#define MAX_STATES 16 /* must be > 2 and < 256 */ -#define MAX_HDR 128 - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowlegement, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - -/* packet types */ -#define TYPE_IP 0x40 -#define TYPE_UNCOMPRESSED_TCP 0x70 -#define TYPE_COMPRESSED_TCP 0x80 -#define TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - struct cstate *cs_next; /* next most recently used state (xmit only) */ - u_short cs_hlen; /* size of hdr (receive only) */ - u_char cs_id; /* connection # associated with this state */ - u_char cs_filler; - union { - char csu_hdr[MAX_HDR]; - struct ip csu_ip; /* ip/tcp hdr from most recent packet */ - } vjcs_u; -}; -#define cs_ip vjcs_u.csu_ip -#define cs_hdr vjcs_u.csu_hdr - -/* - * all the state data for one serial line (we need one of these per line). - */ -struct vjcompress { - struct cstate *last_cs; /* most recently used tstate */ - u_char last_recv; /* last rcvd conn. id */ - u_char last_xmit; /* last sent conn. id */ - u_short flags; -#ifndef VJ_NO_STATS - struct vjstat stats; -#endif - struct cstate tstate[MAX_STATES]; /* xmit connection states */ - struct cstate rstate[MAX_STATES]; /* receive connection states */ -}; - -/* flag values */ -#define VJF_TOSS 1 /* tossing rcvd frames because of input err */ - -extern void vj_compress_init __P((struct vjcompress *comp, int max_state)); -extern u_int vj_compress_tcp __P((struct ip *ip, u_int mlen, - struct vjcompress *comp, int compress_cid_flag, - u_char **vjhdrp)); -extern void vj_uncompress_err __P((struct vjcompress *comp)); -extern int vj_uncompress_uncomp __P((u_char *buf, int buflen, - struct vjcompress *comp)); -extern int vj_uncompress_tcp __P((u_char *buf, int buflen, int total_len, - struct vjcompress *comp, u_char **hdrp, - u_int *hlenp)); - -#endif /* _VJCOMPRESS_H_ */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index ee8912c1..a3331037 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -510,8 +510,9 @@ static void ppp_input(void *arg) { /* FIXME: should we write protent to do that ? */ switch(protocol) { - case PPP_VJC_COMP: /* VJ compressed TCP */ + #if PPPOS_SUPPORT && VJ_SUPPORT + case PPP_VJC_COMP: /* VJ compressed TCP */ PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); /* * Clip off the VJ header and prepend the rebuilt TCP/IP header and @@ -523,14 +524,9 @@ static void ppp_input(void *arg) { } /* Something's wrong so drop it. */ PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d\n", pd, nb->len)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); /* * Process the TCP/IP header for VJ header compression and then pass @@ -542,13 +538,8 @@ static void ppp_input(void *arg) { } /* Something's wrong so drop it. */ PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d\n", - pd, nb->len)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ case PPP_IP: /* Internet Protocol */ PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); @@ -614,7 +605,7 @@ out: pbuf_free(nb); return; - #if 0 +#if 0 /* * Toss all non-LCP packets unless LCP is OPEN. * Until we get past the authentication phase, toss all packets @@ -1351,7 +1342,7 @@ int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) { * get_idle_time - return how long the link has been idle. */ int get_idle_time(int u, struct ppp_idle *ip) { - /* FIXME: add idle time support */ + /* FIXME: add idle time support and make it optional */ return 1; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 09a49ff1..5e18d6b7 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -22,12 +22,23 @@ #define volatile #endif +#ifndef __P +#ifdef __STDC__ +#define __P(x) x +#else +#define __P(x) () +#endif +#endif + +#ifndef bool +typedef unsigned char bool; +#endif + #include "lwip/netif.h" #include "lwip/def.h" #include "lwip/timers.h" #include "pppdebug.h" -#include "net/ppp_defs.h" /* FIXME: merge linux/ppp_defs.h content here */ #ifdef INET6 #include "eui64.h" @@ -36,16 +47,177 @@ /* * 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 */ -#ifndef bool -typedef unsigned char bool; + +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ + +#define PPP_ADDRESS(p) (((u_char *)(p))[0]) +#define PPP_CONTROL(p) (((u_char *)(p))[1]) +#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) + +/* + * Significant octet values. + */ +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_FLAG 0x7e /* Flag Sequence */ +#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ +#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* + * Protocol field values. + */ +#define PPP_IP 0x21 /* Internet Protocol */ +#if 0 /* UNUSED */ +#define PPP_AT 0x29 /* AppleTalk Protocol */ +#define PPP_IPX 0x2b /* IPX protocol */ +#endif /* UNUSED */ +#if VJ_SUPPORT +#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ +#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ +#endif /* VJ_SUPPORT */ +#ifdef INET6 +#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ +#endif /* INET6 */ +#if CCP_SUPPORT +#define PPP_COMP 0xfd /* compressed packet */ +#endif /* CCP_SUPPORT */ +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#if 0 /* UNUSED */ +#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ +#define PPP_IPXCP 0x802b /* IPX Control Protocol */ +#endif /* UNUSED */ +#ifdef INET6 +#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#endif /* INET6 */ +#if CCP_SUPPORT +#define PPP_CCP 0x80fd /* Compression Control Protocol */ +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT +#define PPP_ECP 0x8053 /* Encryption Control Protocol */ +#endif /* ECP_SUPPORT */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#if PAP_SUPPORT +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#endif /* PAP_SUPPORT */ +/* FIXME: make LQR support optional, anyway, there is no LQR support at all in pppd */ +#define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#if CHAP_SUPPORT +#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ +#endif /* CHAP_SUPPORT */ +#if CBCP_SUPPORT +#define PPP_CBCP 0xc029 /* Callback Control Protocol */ +#endif /* CBCP_SUPPORT */ +#if EAP_SUPPORT +#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ +#endif /* EAP_SUPPORT */ + +/* + * Values for FCS calculations. + */ +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +/* + * A 32-bit unsigned integral type. + */ + +#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \ + && !defined(__FreeBSD__) && (NS_TARGET < 40) +#ifdef UINT32_T +typedef UINT32_T u_int32_t; +#else +typedef unsigned int u_int32_t; +typedef unsigned short u_int16_t; #endif +#endif + +/* + * Extended asyncmap - allows any character to be escaped. + */ +typedef u_int32_t ext_accm[8]; + +/* + * What to do with network protocol (NP) packets. + */ +enum NPmode { + NPMODE_PASS, /* pass the packet through */ + NPMODE_DROP, /* silently drop the packet */ + NPMODE_ERROR, /* return an error */ + NPMODE_QUEUE /* save it up for later. */ +}; + +/* + * Statistics. + */ +#if PPP_STATS_SUPPORT +struct pppstat { + unsigned int ppp_ibytes; /* bytes received */ + unsigned int ppp_ipackets; /* packets received */ + unsigned int ppp_ierrors; /* receive errors */ + unsigned int ppp_obytes; /* bytes sent */ + unsigned int ppp_opackets; /* packets sent */ + unsigned int ppp_oerrors; /* transmit errors */ +}; + +#if VJ_SUPPORT +struct vjstat { + unsigned int vjs_packets; /* outbound packets */ + unsigned int vjs_compressed; /* outbound compressed packets */ + unsigned int vjs_searches; /* searches for connection state */ + unsigned int vjs_misses; /* times couldn't find conn. state */ + unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ + unsigned int vjs_compressedin; /* inbound compressed packets */ + unsigned int vjs_errorin; /* inbound unknown type packets */ + unsigned int vjs_tossed; /* inbound packets tossed because of error */ +}; +#endif /* VJ_SUPPORT */ + +struct ppp_stats { + struct pppstat p; /* basic PPP statistics */ +#if VJ_SUPPORT + struct vjstat vj; /* VJ header compression statistics */ +#endif /* VJ_SUPPORT */ +}; + +#if CCP_SUPPORT +struct compstat { + unsigned int unc_bytes; /* total uncompressed bytes */ + unsigned int unc_packets; /* total uncompressed packets */ + unsigned int comp_bytes; /* compressed bytes */ + unsigned int comp_packets; /* compressed packets */ + unsigned int inc_bytes; /* incompressible bytes */ + unsigned int inc_packets; /* incompressible packets */ + unsigned int ratio; /* recent compression ratio << 8 */ +}; + +struct ppp_comp_stats { + struct compstat c; /* packet compression statistics */ + struct compstat d; /* packet decompression statistics */ +}; +#endif /* CCP_SUPPORT */ + +#endif /* PPP_STATS_SUPPORT */ + +/* + * The following structure records the time in seconds since + * the last NP packet was sent or received. + */ +/* FIXME: add idle time support and make it optional */ +struct ppp_idle { + time_t xmit_idle; /* time since last NP packet sent */ + time_t recv_idle; /* time since last NP packet received */ +}; /* FIXME: make endpoint discriminator optional */ diff --git a/src/netif/ppp/session.c b/src/netif/ppp/session.c deleted file mode 100644 index 3885a759..00000000 --- a/src/netif/ppp/session.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * session.c - PPP session control. - * - * Copyright (c) 2007 Diego Rivera. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Derived from auth.c, which is: - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if 0 /* UNUSED */ - -#include "lwip/opt.h" - -#include -#include -#include -#include -#include -#ifdef HAS_SHADOW -#include -#endif -#include -#include -#include -#include - -#include "ppp.h" - -#include "session.h" - -#ifdef USE_PAM -#include -#endif /* #ifdef USE_PAM */ - -#define SET_MSG(var, msg) if (var != NULL) { var[0] = msg; } -#define COPY_STRING(s) ((s) ? strdup(s) : NULL) - -#define SUCCESS_MSG "Session started successfully" -#define ABORT_MSG "Session can't be started without a username" -#define SERVICE_NAME "ppp" - -#define SESSION_FAILED 0 -#define SESSION_OK 1 - -/* We have successfully started a session */ -static bool logged_in = 0; - -#ifdef USE_PAM -/* - * Static variables used to communicate between the conversation function - * and the server_login function - */ -static const char *PAM_username; -static const char *PAM_password; -static int PAM_session = 0; -static pam_handle_t *pamh = NULL; - -/* PAM conversation function - * Here we assume (for now, at least) that echo on means login name, and - * echo off means password. - */ - -static int conversation (int num_msg, -#ifndef SOL2 - const -#endif - struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr) -{ - int replies = 0; - struct pam_response *reply = NULL; - - reply = malloc(sizeof(struct pam_response) * num_msg); - if (!reply) return PAM_CONV_ERR; - - for (replies = 0; replies < num_msg; replies++) { - switch (msg[replies]->msg_style) { - case PAM_PROMPT_ECHO_ON: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_username); - /* PAM frees resp */ - break; - case PAM_PROMPT_ECHO_OFF: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_password); - /* PAM frees resp */ - break; - case PAM_TEXT_INFO: - /* fall through */ - case PAM_ERROR_MSG: - /* ignore it, but pam still wants a NULL response... */ - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = NULL; - break; - default: - /* Must be an error of some sort... */ - free (reply); - return PAM_CONV_ERR; - } - } - *resp = reply; - return PAM_SUCCESS; -} - -static struct pam_conv pam_conv_data = { - &conversation, - NULL -}; -#endif /* #ifdef USE_PAM */ - -int -session_start(flags, user, passwd, ttyName, msg) - const int flags; - const char *user; - const char *passwd; - const char *ttyName; - char **msg; -{ -#ifdef USE_PAM - bool ok = 1; - const char *usr; - int pam_error; - bool try_session = 0; -#else /* #ifdef USE_PAM */ - struct passwd *pw; -#ifdef HAS_SHADOW - struct spwd *spwd; - struct spwd *getspnam(); - long now = 0; -#endif /* #ifdef HAS_SHADOW */ -#endif /* #ifdef USE_PAM */ - - SET_MSG(msg, SUCCESS_MSG); - - /* If no verification is requested, then simply return an OK */ - if (!(SESS_ALL & flags)) { - return SESSION_OK; - } - - if (user == NULL) { - SET_MSG(msg, ABORT_MSG); - return SESSION_FAILED; - } - -#ifdef USE_PAM - /* Find the '\\' in the username */ - /* This needs to be fixed to support different username schemes */ - if ((usr = strchr(user, '\\')) == NULL) - usr = user; - else - usr++; - - PAM_session = 0; - PAM_username = usr; - PAM_password = passwd; - - dbglog("Initializing PAM (%d) for user %s", flags, usr); - pam_error = pam_start (SERVICE_NAME, usr, &pam_conv_data, &pamh); - dbglog("---> PAM INIT Result = %d", pam_error); - ok = (pam_error == PAM_SUCCESS); - - if (ok) { - ok = (pam_set_item(pamh, PAM_TTY, ttyName) == PAM_SUCCESS) && - (pam_set_item(pamh, PAM_RHOST, ifname) == PAM_SUCCESS); - } - - if (ok && (SESS_AUTH & flags)) { - dbglog("Attempting PAM authentication"); - pam_error = pam_authenticate (pamh, PAM_SILENT); - if (pam_error == PAM_SUCCESS) { - /* PAM auth was OK */ - dbglog("PAM Authentication OK for %s", user); - } else { - /* No matter the reason, we fail because we're authenticating */ - ok = 0; - if (pam_error == PAM_USER_UNKNOWN) { - dbglog("User unknown, failing PAM authentication"); - SET_MSG(msg, "User unknown - cannot authenticate via PAM"); - } else { - /* Any other error means authentication was bad */ - dbglog("PAM Authentication failed: %d: %s", pam_error, - pam_strerror(pamh, pam_error)); - SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); - } - } - } - - if (ok && (SESS_ACCT & flags)) { - dbglog("Attempting PAM account checks"); - pam_error = pam_acct_mgmt (pamh, PAM_SILENT); - if (pam_error == PAM_SUCCESS) { - /* - * PAM account was OK, set the flag which indicates that we should - * try to perform the session checks. - */ - try_session = 1; - dbglog("PAM Account OK for %s", user); - } else { - /* - * If the account checks fail, then we should not try to perform - * the session check, because they don't make sense. - */ - try_session = 0; - if (pam_error == PAM_USER_UNKNOWN) { - /* - * We're checking the account, so it's ok to not have one - * because the user might come from the secrets files, or some - * other plugin. - */ - dbglog("User unknown, ignoring PAM restrictions"); - SET_MSG(msg, "User unknown - ignoring PAM restrictions"); - } else { - /* Any other error means session is rejected */ - ok = 0; - dbglog("PAM Account checks failed: %d: %s", pam_error, - pam_strerror(pamh, pam_error)); - SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); - } - } - } - - if (ok && try_session && (SESS_ACCT & flags)) { - /* Only open a session if the user's account was found */ - pam_error = pam_open_session (pamh, PAM_SILENT); - if (pam_error == PAM_SUCCESS) { - dbglog("PAM Session opened for user %s", user); - PAM_session = 1; - } else { - dbglog("PAM Session denied for user %s", user); - SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); - ok = 0; - } - } - - /* This is needed because apparently the PAM stuff closes the log */ - reopen_log(); - - /* If our PAM checks have already failed, then we must return a failure */ - if (!ok) return SESSION_FAILED; - -#else /* #ifdef USE_PAM */ - -/* - * Use the non-PAM methods directly. 'pw' will remain NULL if the user - * has not been authenticated using local UNIX system services. - */ - - pw = NULL; - if ((SESS_AUTH & flags)) { - pw = getpwnam(user); - - endpwent(); - /* - * Here, we bail if we have no user account, because there is nothing - * to verify against. - */ - if (pw == NULL) - return SESSION_FAILED; - -#ifdef HAS_SHADOW - - spwd = getspnam(user); - endspent(); - - /* - * If there is no shadow entry for the user, then we can't verify the - * account. - */ - if (spwd == NULL) - return SESSION_FAILED; - - /* - * We check validity all the time, because if the password has expired, - * then clearly we should not authenticate against it (if we're being - * called for authentication only). Thus, in this particular instance, - * there is no real difference between using the AUTH, SESS or ACCT - * flags, or combinations thereof. - */ - now = time(NULL) / 86400L; - if ((spwd->sp_expire > 0 && now >= spwd->sp_expire) - || ((spwd->sp_max >= 0 && spwd->sp_max < 10000) - && spwd->sp_lstchg >= 0 - && now >= spwd->sp_lstchg + spwd->sp_max)) { - warn("Password for %s has expired", user); - return SESSION_FAILED; - } - - /* We have a valid shadow entry, keep the password */ - pw->pw_passwd = spwd->sp_pwdp; - -#endif /* #ifdef HAS_SHADOW */ - -#if 0 - /* - * If no passwd, don't let them login if we're authenticating. - */ - if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2 - || strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0) - return SESSION_FAILED; -#endif - } - -#endif /* #ifdef USE_PAM */ - - /* - * Write a wtmp entry for this user. - */ - - if (SESS_ACCT & flags) { - if (strncmp(ttyName, "/dev/", 5) == 0) - ttyName += 5; - logwtmp(ttyName, user, ifname); /* Add wtmp login entry */ - logged_in = 1; - -#if defined(_PATH_LASTLOG) && !defined(USE_PAM) - /* - * Enter the user in lastlog only if he has been authenticated using - * local system services. If he has not, then we don't know what his - * UID might be, and lastlog is indexed by UID. - */ - if (pw != NULL) { - struct lastlog ll; - int fd; - time_t tnow; - - if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { - (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); - memset((void *)&ll, 0, sizeof(ll)); - (void)time(&tnow); - ll.ll_time = tnow; - (void)strncpy(ll.ll_line, ttyName, sizeof(ll.ll_line)); - (void)strncpy(ll.ll_host, ifname, sizeof(ll.ll_host)); - (void)write(fd, (char *)&ll, sizeof(ll)); - (void)close(fd); - } - } -#endif /* _PATH_LASTLOG and not USE_PAM */ - info("user %s logged in on tty %s intf %s", user, ttyName, ifname); - } - - return SESSION_OK; -} - -/* - * session_end - Logout the user. - */ -void -session_end(const char* ttyName) -{ -#ifdef USE_PAM - int pam_error = PAM_SUCCESS; - - if (pamh != NULL) { - if (PAM_session) pam_error = pam_close_session (pamh, PAM_SILENT); - PAM_session = 0; - pam_end (pamh, pam_error); - pamh = NULL; - /* Apparently the pam stuff does closelog(). */ - reopen_log(); - } -#endif - if (logged_in) { - if (strncmp(ttyName, "/dev/", 5) == 0) - ttyName += 5; - logwtmp(ttyName, "", ""); /* Wipe out utmp logout entry */ - logged_in = 0; - } -} - -#endif /* UNUSED */ diff --git a/src/netif/ppp/session.h b/src/netif/ppp/session.h deleted file mode 100644 index cfdbdfac..00000000 --- a/src/netif/ppp/session.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * session.c - PPP session control. - * - * Copyright (c) 2007 Diego Rivera. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if 0 /* UNUSED */ - -#ifndef __SESSION_H -#define __SESSION_H - -#define SESS_AUTH 1 /* Check User Authentication */ -#define SESS_ACCT 2 /* Check Account Validity */ - -/* Convenience parameter to do the whole enchilada */ -#define SESS_ALL (SESS_AUTH | SESS_ACCT) - -/* - * int session_start(...) - * - * Start a session, performing any necessary validations. - * - * Parameters: - * const int flags : - * Any combination of the SESS_XXX flags, to indicate what the function - * should do as part of its checks - * - * const char* user : - * The username to validate. May safely be null. - * - * const char* passwd : - * The password to validate the user with. May safely be null. - * - * const char* tty : - * The TTY the user is connected on. May safely be null. - * - * char** msg : - * A char* to return an error or success message. This message will be returned - * regardless of the result. May safely be null. - * - * Return Value: - * Zero value for failure, non-zero value for successful session verification. - */ -int -session_start(const int flags, const char* user, const char* passwd, const char* tty, char** msg); - -/* Added these macros for convenience... */ -#define session_auth(user, pass, tty, msg) \ - session_start(SESS_AUTH, user, pass, tty, msg) - -#define session_check(user, pass, tty, msg) \ - session_start(SESS_ACCT, user, pass, tty, msg) - -#define session_full(user, pass, tty, msg) \ - session_start(SESS_ALL, user, pass, tty, msg) - -/* - * void session_end(...) - * - * End a previously-started session. - * - * Parameters: - * const char* tty : - * The TTY the user is connected on. May safely be null. - */ -void -session_end(const char* tty); - -#endif - -#endif /* UNUSED */ diff --git a/src/netif/ppp/tty.c b/src/netif/ppp/tty.c deleted file mode 100644 index 53941c6e..00000000 --- a/src/netif/ppp/tty.c +++ /dev/null @@ -1,1290 +0,0 @@ -/* - * tty.c - code for handling serial ports in pppd. - * - * Copyright (C) 2000-2004 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Portions derived from main.c, which is: - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if 0 /* NEED OUR OWN PORT */ - -#define RCSID "$Id: tty.c,v 1.27 2008/07/01 12:27:56 paulus Exp $" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ppp.h" - -#include "fsm.h" -#include "lcp.h" - -void tty_process_extra_options __P((void)); -void tty_check_options __P((void)); -int connect_tty __P((void)); -void disconnect_tty __P((void)); -void tty_close_fds __P((void)); -void cleanup_tty __P((void)); -void tty_do_send_config __P((int, u_int32_t, int, int)); - -static int setdevname __P((char *, char **, int)); -static int setspeed __P((char *, char **, int)); -static int setxonxoff __P((char **)); -static int setescape __P((char **)); -#if 0 /* UNUSED */ -static void printescape __P((option_t *, void (*)(void *, char *,...),void *)); -#endif /* UNUSED */ -static void finish_tty __P((void)); -static int start_charshunt __P((int, int)); -static void stop_charshunt __P((void *, int)); -static void charshunt_done __P((void *)); -static void charshunt __P((int, int, char *)); -static int record_write __P((FILE *, int code, u_char *buf, int nb, - struct timeval *)); -static int open_socket __P((char *)); - -#if 0 -static void maybe_relock __P((void *, int)); -#endif - -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) */ -static int ttyfd; /* Serial port file descriptor */ -static char speed_str[16]; /* Serial port speed as string */ - -mode_t tty_mode = (mode_t)-1; /* Original access permissions to tty */ -int baud_rate; /* Actual bits/second for serial device */ -char *callback_script; /* script for doing callback */ -int charshunt_pid; /* Process ID for charshunt */ -int locked; /* lock() has succeeded */ -struct stat devstat; /* result of stat() on devnam */ - -/* option variables */ -int crtscts = 0; /* Use hardware flow control */ -bool modem = 1; /* Use modem control lines */ -int inspeed = 0; /* Input/Output speed requested */ -bool lockflag = 0; /* Create lock file to lock the serial dev */ -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 */ -bool notty = 0; /* Stdin/out is not a tty */ -char *record_file = NULL; /* File to record chars sent/received */ -int max_data_rate; /* max bytes/sec through charshunt */ -bool sync_serial = 0; /* Device is synchronous serial device */ -char *pty_socket = NULL; /* Socket to connect to pty */ -int using_pty = 0; /* we're allocating a pty as the device */ - -extern uid_t uid; -#if 0 /* UNUSED */ -extern int kill_link; -#endif /* UNUSED */ -extern int asked_to_quit; -extern int got_sigterm; - -/* XXX */ -extern int privopen; /* don't lock, open device as root */ - -u_int32_t xmit_accm[8]; /* extended transmit ACCM */ - -#if 0 /* UNUSED */ -/* option descriptors */ -option_t tty_options[] = { - /* device name must be first, or change connect_tty() below! */ - { "device name", o_wild, (void *) &setdevname, - "Serial port device name", - OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, - devnam}, - - { "tty speed", o_wild, (void *) &setspeed, - "Baud rate for serial port", - OPT_PRIO | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, speed_str }, - - { "lock", o_bool, &lockflag, - "Lock serial device with UUCP-style lock file", OPT_PRIO | 1 }, - { "nolock", o_bool, &lockflag, - "Don't lock serial device", OPT_PRIOSUB | OPT_PRIV }, - - { "init", o_string, &initializer, - "A program to initialize the device", OPT_PRIO | OPT_PRIVFIX }, - - { "connect", o_string, &connect_script, - "A program to set up a connection", OPT_PRIO | OPT_PRIVFIX }, - - { "disconnect", o_string, &disconnect_script, - "Program to disconnect serial device", OPT_PRIO | OPT_PRIVFIX }, - - { "welcome", o_string, &welcomer, - "Script to welcome client", OPT_PRIO | OPT_PRIVFIX }, - - { "pty", o_string, &ptycommand, - "Script to run on pseudo-tty master side", - OPT_PRIO | OPT_PRIVFIX | OPT_DEVNAM }, - - { "notty", o_bool, ¬ty, - "Input/output is not a tty", OPT_DEVNAM | 1 }, - - { "socket", o_string, &pty_socket, - "Send and receive over socket, arg is host:port", - OPT_PRIO | OPT_DEVNAM }, - - { "record", o_string, &record_file, - "Record characters sent/received to file", OPT_PRIO }, - - { "crtscts", o_int, &crtscts, - "Set hardware (RTS/CTS) flow control", - OPT_PRIO | OPT_NOARG | OPT_VAL(1) }, - { "cdtrcts", o_int, &crtscts, - "Set alternate hardware (DTR/CTS) flow control", - OPT_PRIOSUB | OPT_NOARG | OPT_VAL(2) }, - { "nocrtscts", o_int, &crtscts, - "Disable hardware flow control", - OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, - { "-crtscts", o_int, &crtscts, - "Disable hardware flow control", - OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, - { "nocdtrcts", o_int, &crtscts, - "Disable hardware flow control", - OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, - { "xonxoff", o_special_noarg, (void *)setxonxoff, - "Set software (XON/XOFF) flow control", OPT_PRIOSUB }, - - { "modem", o_bool, &modem, - "Use modem control lines", OPT_PRIO | 1 }, - { "local", o_bool, &modem, - "Don't use modem control lines", OPT_PRIOSUB | 0 }, - - { "sync", o_bool, &sync_serial, - "Use synchronous HDLC serial encoding", 1 }, - - { "datarate", o_int, &max_data_rate, - "Maximum data rate in bytes/sec (with pty, notty or record option)", - OPT_PRIO }, - - { "escape", o_special, (void *)setescape, - "List of character codes to escape on transmission", - OPT_A2PRINTER, (void *)printescape }, - - { NULL } -}; - -#endif /* UNUSED */ - -struct channel tty_channel = { -#if PPP_OPTIONS - tty_options, - &tty_process_extra_options, - &tty_check_options, - &connect_tty, -#endif /* UNUSED */ - &disconnect_tty, - &tty_establish_ppp, - &tty_disestablish_ppp, - &tty_do_send_config, - &tty_recv_config, - &cleanup_tty, - &tty_close_fds -}; - -/* - * setspeed - Set the serial port baud rate. - * If doit is 0, the call is to check whether this option is - * potentially a speed value. - */ -static int -setspeed(arg, argv, doit) - char *arg; - char **argv; - int doit; -{ - char *ptr; - int spd; - - spd = strtol(arg, &ptr, 0); - if (ptr == arg || *ptr != 0 || spd == 0) - return 0; - if (doit) { - inspeed = spd; - slprintf(speed_str, sizeof(speed_str), "%d", spd); - } - return 1; -} - - -/* - * setdevname - Set the device name. - * If doit is 0, the call is to check whether this option is - * potentially a device name. - */ -static int -setdevname(cp, argv, doit) - char *cp; - char **argv; - int doit; -{ - struct stat statbuf; - char dev[MAXPATHLEN]; - - if (*cp == 0) - return 0; - - if (*cp != '/') { - 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 (!doit) - return errno != ENOENT; - option_error("Couldn't stat %s: %m", cp); - return 0; - } - if (!S_ISCHR(statbuf.st_mode)) { - if (doit) - option_error("%s is not a character device", cp); - return 0; - } - - if (doit) { - strlcpy(devnam, cp, sizeof(devnam)); - devstat = statbuf; - default_device = 0; - } - - return 1; -} - -static int -setxonxoff(argv) - char **argv; -{ - lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ - lcp_wantoptions[0].neg_asyncmap = 1; - - crtscts = -2; - return 1; -} - -/* - * setescape - add chars to the set we escape on transmission. - */ -static int -setescape(argv) - 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[n >> 5] |= 1 << (n & 0x1F); - while (*p == ',' || *p == ' ') - ++p; - } - lcp_allowoptions[0].asyncmap = xmit_accm[0]; - return ret; -} - -#if 0 /* UNUSED */ -static void -printescape(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int n; - int first = 1; - - for (n = 0; n < 256; ++n) { - if (n == 0x7d) - n += 2; /* skip 7d, 7e */ - if (xmit_accm[n >> 5] & (1 << (n & 0x1f))) { - if (!first) - printer(arg, ","); - else - first = 0; - printer(arg, "%x", n); - } - } - if (first) - printer(arg, "oops # nothing escaped"); -} -#endif /* UNUSED */ - -#if 0 -/* - * tty_init - do various tty-related initializations. - */ -void tty_init() -{ - add_notifier(&pidchange, maybe_relock, 0); - the_channel = &tty_channel; - xmit_accm[3] = 0x60000000; -} -#endif - -/* - * tty_process_extra_options - work out which tty device we are using - * and read its options file. - */ -void tty_process_extra_options() -{ - using_pty = notty || ptycommand != NULL || pty_socket != NULL; - if (using_pty) - return; - if (default_device) { - char *p; - if (!isatty(0) || (p = ttyname(0)) == NULL) { - option_error("no device specified and stdin is not a tty"); - exit(EXIT_OPTION_ERROR); - } - strlcpy(devnam, p, sizeof(devnam)); - if (stat(devnam, &devstat) < 0) - fatal("Couldn't stat default device %s: %m", devnam); - } - -#if PPP_OPTIONS - /* - * Parse the tty options file. - * The per-tty options file should not change - * ptycommand, pty_socket, notty or devnam. - * options_for_tty doesn't override options set on the command line, - * except for some privileged options. - */ - if (!options_for_tty()) - exit(EXIT_OPTION_ERROR); -#endif /* PPP_OPTIONS */ -} - -#if 0 /* UNUSED */ -/* - * tty_check_options - do consistency checks on the options we were given. - */ -void -tty_check_options() -{ - struct stat statbuf; - int fdflags; - - if (demand && notty) { - option_error("demand-dialling is incompatible with notty"); - exit(EXIT_OPTION_ERROR); - } - if (demand && connect_script == 0 && ptycommand == NULL - && pty_socket == NULL) { - option_error("connect script is required for demand-dialling\n"); - exit(EXIT_OPTION_ERROR); - } - /* default holdoff to 0 if no connect script has been given */ - if (connect_script == 0 && !holdoff_specified) - holdoff = 0; - - if (using_pty) { - if (!default_device) { - option_error("%s option precludes specifying device name", - pty_socket? "socket": notty? "notty": "pty"); - exit(EXIT_OPTION_ERROR); - } - if (ptycommand != NULL && notty) { - option_error("pty option is incompatible with notty option"); - exit(EXIT_OPTION_ERROR); - } - if (pty_socket != NULL && (ptycommand != NULL || notty)) { - option_error("socket option is incompatible with pty and notty"); - exit(EXIT_OPTION_ERROR); - } - default_device = notty; - lockflag = 0; - modem = 0; - if (notty && log_to_fd <= 1) - log_to_fd = -1; - } else { - /* - * If the user has specified a device which is the same as - * the one on stdin, pretend they didn't specify any. - * If the device is already open read/write on stdin, - * we assume we don't need to lock it, and we can open it - * as root. - */ - if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode) - && statbuf.st_rdev == devstat.st_rdev) { - default_device = 1; - fdflags = fcntl(0, F_GETFL); - if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR) - privopen = 1; - } - } - if (default_device) - nodetach = 1; - - /* - * Don't send log messages to the serial port, it tends to - * confuse the peer. :-) - */ - if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0 - && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev) - log_to_fd = -1; -} -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* - * connect_tty - get the serial port ready to start doing PPP. - * That is, open the serial port, set its speed and mode, and run - * the connector and/or welcomer. - */ -int connect_tty() -{ - char *connector; - int fdflags; -#ifndef __linux__ - struct stat statbuf; -#endif - char numbuf[16]; - - /* - * Get a pty master/slave pair if the pty, notty, socket, - * or record options were specified. - */ - strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); - pty_master = -1; - pty_slave = -1; - real_ttyfd = -1; - if (using_pty || record_file != NULL) { - if (!get_pty(&pty_master, &pty_slave, ppp_devnam, uid)) { - error("Couldn't allocate pseudo-tty"); - status = EXIT_FATAL_ERROR; - return -1; - } - set_up_tty(pty_slave, 1); - } - - /* - * Lock the device if we've been asked to. - */ - status = EXIT_LOCK_FAILED; - if (lockflag && !privopen) { - if (lock(devnam) < 0) - goto errret; - locked = 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. - */ - got_sigterm = 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, prio; - - prio = privopen? OPRIO_ROOT: tty_options[0].priority; - if (prio < OPRIO_ROOT && seteuid(uid) == -1) { - error("Unable to drop privileges before opening %s: %m\n", - devnam); - status = EXIT_OPEN_FAILED; - goto errret; - } - real_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0); - err = errno; - if (prio < OPRIO_ROOT && seteuid(0) == -1) - fatal("Unable to regain privileges"); - if (real_ttyfd >= 0) - break; - errno = err; - if (err != EINTR) { - error("Failed to open %s: %m", devnam); - status = EXIT_OPEN_FAILED; - } - if (!persist || err != EINTR) - goto errret; - } - ttyfd = real_ttyfd; - if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 - || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) - warn("Couldn't reset non-blocking mode on device: %m"); - -#ifndef __linux__ - /* - * Linux 2.4 and above blocks normal writes to the tty - * when it is in PPP line discipline, so this isn't needed. - */ - /* - * Do the equivalent of `mesg n' to stop broadcast messages. - */ - if (fstat(ttyfd, &statbuf) < 0 - || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { - warn("Couldn't restrict write permissions to %s: %m", devnam); - } else - tty_mode = statbuf.st_mode; -#endif /* __linux__ */ - - /* - * 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(ttyfd, ((connector != NULL && connector[0] != 0) - || initializer != NULL)); - } - - /* - * If the pty, socket, notty and/or record option was specified, - * start up the character shunt now. - */ - status = EXIT_PTYCMD_FAILED; - if (ptycommand != NULL) { - if (record_file != NULL) { - int ipipe[2], opipe[2], ok; - - if (pipe(ipipe) < 0 || pipe(opipe) < 0) - fatal("Couldn't create pipes for record option: %m"); - - /* don't leak these to the ptycommand */ - (void) fcntl(ipipe[0], F_SETFD, FD_CLOEXEC); - (void) fcntl(opipe[1], F_SETFD, FD_CLOEXEC); - - ok = device_script(ptycommand, opipe[0], ipipe[1], 1) == 0 - && start_charshunt(ipipe[0], opipe[1]); - close(ipipe[0]); - close(ipipe[1]); - close(opipe[0]); - close(opipe[1]); - if (!ok) - goto errret; - } else { - if (device_script(ptycommand, pty_master, pty_master, 1) < 0) - goto errret; - } - } else if (pty_socket != NULL) { - int fd = open_socket(pty_socket); - if (fd < 0) - goto errret; - if (!start_charshunt(fd, fd)) - goto errret; - close(fd); - } else if (notty) { - if (!start_charshunt(0, 1)) - goto errret; - dup2(fd_devnull, 0); - dup2(fd_devnull, 1); - if (log_to_fd == 1) - log_to_fd = -1; - if (log_to_fd != 2) - dup2(fd_devnull, 2); - } else if (record_file != NULL) { - int fd = dup(ttyfd); - if (!start_charshunt(fd, fd)) - goto errret; - } - - if (using_pty || record_file != NULL) { - ttyfd = pty_slave; - close(pty_master); - pty_master = -1; - } - - /* 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(initializer, ttyfd, ttyfd, 0) < 0) { - error("Initializer script failed"); - status = EXIT_INIT_FAILED; - goto errretf; - } - if (got_sigterm) { - disconnect_tty(); - goto errretf; - } - info("Serial port initialized."); - } - - if (connector && connector[0]) { - if (device_script(connector, ttyfd, ttyfd, 0) < 0) { - error("Connect script failed"); - status = EXIT_CONNECT_FAILED; - goto errretf; - } - if (got_sigterm) { - disconnect_tty(); - goto errretf; - } - 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) { - int i; - for (;;) { - if ((i = open(devnam, O_RDWR)) >= 0) - break; - if (errno != EINTR) { - error("Failed to reopen %s: %m", devnam); - status = EXIT_OPEN_FAILED; - } - if (!persist || errno != EINTR || hungup || got_sigterm) - goto errret; - } - close(i); - } - - slprintf(numbuf, sizeof(numbuf), "%d", baud_rate); - script_setenv("SPEED", numbuf, 0); - - /* run welcome script, if any */ - if (welcomer && welcomer[0]) { - if (device_script(welcomer, ttyfd, ttyfd, 0) < 0) - warn("Welcome script failed"); - } - - /* - * If we are initiating this connection, wait for a short - * time for something from the peer. This can avoid bouncing - * our packets off his tty before he has it set up. - */ - if (connector != NULL || ptycommand != NULL || pty_socket != NULL) - listen_time = connect_delay; - - return ttyfd; - - errretf: - if (real_ttyfd >= 0) - tcflush(real_ttyfd, TCIOFLUSH); - errret: - if (pty_master >= 0) { - close(pty_master); - pty_master = -1; - } - ttyfd = -1; - if (got_sigterm) - asked_to_quit = 1; - return -1; -} -#endif /* UNUSED */ - -void disconnect_tty() -{ - if (disconnect_script == NULL || hungup) - return; - if (real_ttyfd >= 0) - set_up_tty(real_ttyfd, 1); - if (device_script(disconnect_script, ttyfd, ttyfd, 0) < 0) { - warn("disconnect script failed"); - } else { - info("Serial link disconnected."); - } - stop_charshunt(NULL, 0); -} - -void tty_close_fds() -{ - if (pty_slave >= 0) - close(pty_slave); - if (real_ttyfd >= 0) { - close(real_ttyfd); - real_ttyfd = -1; - } - /* N.B. ttyfd will == either pty_slave or real_ttyfd */ -} - -void cleanup_tty() -{ - if (real_ttyfd >= 0) - finish_tty(); - tty_close_fds(); -#if 0 - if (locked) { - unlock(); - locked = 0; - } -#endif -} - -/* - * tty_do_send_config - set transmit-side PPP configuration. - * We set the extended transmit ACCM here as well. - */ -void -tty_do_send_config(mtu, accm, pcomp, accomp) - int mtu; - u_int32_t accm; - int pcomp, accomp; -{ - tty_set_xaccm(xmit_accm); - tty_send_config(mtu, accm, pcomp, accomp); -} - -/* - * finish_tty - restore the terminal device to its original settings - */ -static void -finish_tty() -{ - /* 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); - -#ifndef __linux__ - if (tty_mode != (mode_t) -1) { - if (fchmod(real_ttyfd, tty_mode) != 0) - error("Couldn't restore tty permissions"); - } -#endif /* __linux__ */ - - close(real_ttyfd); - real_ttyfd = -1; -} - -#if 0 -/* - * maybe_relock - our PID has changed, maybe update the lock file. - */ -static void -maybe_relock(arg, pid) - void *arg; - int pid; -{ - if (locked) - relock(pid); -} -#endif - -/* - * open_socket - establish a stream socket connection to the nominated - * host and port. - */ -static int -open_socket(dest) - char *dest; -{ - char *sep, *endp = NULL; - int sock, port = -1; - u_int32_t host; - struct hostent *hent; - struct sockaddr_in sad; - - /* parse host:port and resolve host to an IP address */ - sep = strchr(dest, ':'); - if (sep != NULL) - port = strtol(sep+1, &endp, 10); - if (port < 0 || endp == sep+1 || sep == dest) { - error("Can't parse host:port for socket destination"); - return -1; - } - *sep = 0; - host = inet_addr(dest); - if (host == (u_int32_t) -1) { - hent = gethostbyname(dest); - if (hent == NULL) { - error("%s: unknown host in socket option", dest); - *sep = ':'; - return -1; - } - host = *(u_int32_t *)(hent->h_addr_list[0]); - } - *sep = ':'; - - /* get a socket and connect it to the other end */ - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock < 0) { - error("Can't create socket: %m"); - return -1; - } - memset(&sad, 0, sizeof(sad)); - sad.sin_family = AF_INET; - sad.sin_port = htons(port); - sad.sin_addr.s_addr = host; - if (connect(sock, (struct sockaddr *)&sad, sizeof(sad)) < 0) { - error("Can't connect to %s: %m", dest); - close(sock); - return -1; - } - - return sock; -} - - -/* - * start_charshunt - create a child process to run the character shunt. - */ -static int -start_charshunt(ifd, ofd) - int ifd, ofd; -{ - int cpid; - - cpid = -1; /* safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2)); */ - if (cpid == -1) { - error("Can't fork process for character shunt: %m"); - return 0; - } - if (cpid == 0) { - /* child */ - reopen_log(); - if (!nodetach) - log_to_fd = -1; - else if (log_to_fd >= 0) - log_to_fd = 2; - setgid(getgid()); - setuid(uid); - if (getuid() != uid) - fatal("setuid failed"); - charshunt(0, 1, record_file); - exit(0); - } - charshunt_pid = cpid; - record_child(cpid, "pppd (charshunt)", charshunt_done, NULL, 1); - return 1; -} - -static void -charshunt_done(arg) - void *arg; -{ - charshunt_pid = 0; -} - -static void -stop_charshunt(arg, sig) - void *arg; - int sig; -{ - if (charshunt_pid) - kill(charshunt_pid, (sig == SIGINT? sig: SIGTERM)); -} - -/* - * charshunt - the character shunt, which passes characters between - * the pty master side and the serial port (or stdin/stdout). - * This runs as the user (not as root). - * (We assume ofd >= ifd which is true the way this gets called. :-). - */ -static void -charshunt(ifd, ofd, record_file) - int ifd, ofd; - char *record_file; -{ - int n, nfds; - fd_set ready, writey; - u_char *ibufp, *obufp; - int nibuf, nobuf; - int flags; - int pty_readable, stdin_readable; - struct timeval lasttime; - FILE *recordf = NULL; - int ilevel, olevel, max_level; - struct timeval levelt, tout, *top; - extern u_char inpacket_buf[]; - - /* - * Reset signal handlers. - */ - signal(SIGHUP, SIG_IGN); /* Hangup */ - signal(SIGINT, SIG_DFL); /* Interrupt */ - signal(SIGTERM, SIG_DFL); /* Terminate */ - signal(SIGCHLD, SIG_DFL); - signal(SIGUSR1, SIG_DFL); - signal(SIGUSR2, SIG_DFL); - signal(SIGABRT, SIG_DFL); - signal(SIGALRM, SIG_DFL); - signal(SIGFPE, SIG_DFL); - signal(SIGILL, SIG_DFL); - signal(SIGPIPE, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGSEGV, SIG_DFL); -#ifdef SIGBUS - signal(SIGBUS, SIG_DFL); -#endif -#ifdef SIGEMT - signal(SIGEMT, SIG_DFL); -#endif -#ifdef SIGPOLL - signal(SIGPOLL, SIG_DFL); -#endif -#ifdef SIGPROF - signal(SIGPROF, SIG_DFL); -#endif -#ifdef SIGSYS - signal(SIGSYS, SIG_DFL); -#endif -#ifdef SIGTRAP - signal(SIGTRAP, SIG_DFL); -#endif -#ifdef SIGVTALRM - signal(SIGVTALRM, SIG_DFL); -#endif -#ifdef SIGXCPU - signal(SIGXCPU, SIG_DFL); -#endif -#ifdef SIGXFSZ - signal(SIGXFSZ, SIG_DFL); -#endif - - /* - * Check that the fds won't overrun the fd_sets - */ - if (ifd >= FD_SETSIZE || ofd >= FD_SETSIZE || pty_master >= FD_SETSIZE) - fatal("internal error: file descriptor too large (%d, %d, %d)", - ifd, ofd, pty_master); - - /* - * Open the record file if required. - */ - if (record_file != NULL) { - recordf = fopen(record_file, "a"); - if (recordf == NULL) - error("Couldn't create record file %s: %m", record_file); - } - - /* set all the fds to non-blocking mode */ - flags = fcntl(pty_master, F_GETFL); - if (flags == -1 - || fcntl(pty_master, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set pty master to nonblock: %m"); - flags = fcntl(ifd, F_GETFL); - if (flags == -1 - || fcntl(ifd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set %s to nonblock: %m", (ifd==0? "stdin": "tty")); - if (ofd != ifd) { - flags = fcntl(ofd, F_GETFL); - if (flags == -1 - || fcntl(ofd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set stdout to nonblock: %m"); - } - - nibuf = nobuf = 0; - ibufp = obufp = NULL; - pty_readable = stdin_readable = 1; - - ilevel = olevel = 0; - gettimeofday(&levelt, NULL); - if (max_data_rate) { - max_level = max_data_rate / 10; - if (max_level < 100) - max_level = 100; - } else - max_level = PPP_MRU + PPP_HDRLEN + 1; - - nfds = (ofd > pty_master? ofd: pty_master) + 1; - if (recordf != NULL) { - gettimeofday(&lasttime, NULL); - putc(7, recordf); /* put start marker */ - putc(lasttime.tv_sec >> 24, recordf); - putc(lasttime.tv_sec >> 16, recordf); - putc(lasttime.tv_sec >> 8, recordf); - putc(lasttime.tv_sec, recordf); - lasttime.tv_usec = 0; - } - - while (nibuf != 0 || nobuf != 0 || pty_readable || stdin_readable) { - top = 0; - tout.tv_sec = 0; - tout.tv_usec = 10000; - FD_ZERO(&ready); - FD_ZERO(&writey); - if (nibuf != 0) { - if (ilevel >= max_level) - top = &tout; - else - FD_SET(pty_master, &writey); - } else if (stdin_readable) - FD_SET(ifd, &ready); - if (nobuf != 0) { - if (olevel >= max_level) - top = &tout; - else - FD_SET(ofd, &writey); - } else if (pty_readable) - FD_SET(pty_master, &ready); - if (select(nfds, &ready, &writey, NULL, top) < 0) { - if (errno != EINTR) - fatal("select"); - continue; - } - if (max_data_rate) { - double dt; - int nbt; - struct timeval now; - - gettimeofday(&now, NULL); - dt = (now.tv_sec - levelt.tv_sec - + (now.tv_usec - levelt.tv_usec) / 1e6); - nbt = (int)(dt * max_data_rate); - ilevel = (nbt < 0 || nbt > ilevel)? 0: ilevel - nbt; - olevel = (nbt < 0 || nbt > olevel)? 0: olevel - nbt; - levelt = now; - } else - ilevel = olevel = 0; - if (FD_ISSET(ifd, &ready)) { - ibufp = inpacket_buf; - nibuf = read(ifd, ibufp, PPP_MRU + PPP_HDRLEN); - if (nibuf < 0 && errno == EIO) - nibuf = 0; - if (nibuf < 0) { - if (!(errno == EINTR || errno == EAGAIN)) { - error("Error reading standard input: %m"); - break; - } - nibuf = 0; - } else if (nibuf == 0) { - /* end of file from stdin */ - stdin_readable = 0; - if (recordf) - if (!record_write(recordf, 4, NULL, 0, &lasttime)) - recordf = NULL; - } else { - FD_SET(pty_master, &writey); - if (recordf) - if (!record_write(recordf, 2, ibufp, nibuf, &lasttime)) - recordf = NULL; - } - } - if (FD_ISSET(pty_master, &ready)) { - obufp = outpacket_buf; - nobuf = read(pty_master, obufp, PPP_MRU + PPP_HDRLEN); - if (nobuf < 0 && errno == EIO) - nobuf = 0; - if (nobuf < 0) { - if (!(errno == EINTR || errno == EAGAIN)) { - error("Error reading pseudo-tty master: %m"); - break; - } - nobuf = 0; - } else if (nobuf == 0) { - /* end of file from the pty - slave side has closed */ - pty_readable = 0; - stdin_readable = 0; /* pty is not writable now */ - nibuf = 0; - close(ofd); - if (recordf) - if (!record_write(recordf, 3, NULL, 0, &lasttime)) - recordf = NULL; - } else { - FD_SET(ofd, &writey); - if (recordf) - if (!record_write(recordf, 1, obufp, nobuf, &lasttime)) - recordf = NULL; - } - } else if (!stdin_readable) - pty_readable = 0; - if (FD_ISSET(ofd, &writey)) { - n = nobuf; - if (olevel + n > max_level) - n = max_level - olevel; - n = write(ofd, obufp, n); - if (n < 0) { - if (errno == EIO) { - pty_readable = 0; - nobuf = 0; - } else if (errno != EAGAIN && errno != EINTR) { - error("Error writing standard output: %m"); - break; - } - } else { - obufp += n; - nobuf -= n; - olevel += n; - } - } - if (FD_ISSET(pty_master, &writey)) { - n = nibuf; - if (ilevel + n > max_level) - n = max_level - ilevel; - n = write(pty_master, ibufp, n); - if (n < 0) { - if (errno == EIO) { - stdin_readable = 0; - nibuf = 0; - } else if (errno != EAGAIN && errno != EINTR) { - error("Error writing pseudo-tty master: %m"); - break; - } - } else { - ibufp += n; - nibuf -= n; - ilevel += n; - } - } - } - exit(0); -} - -static int -record_write(f, code, buf, nb, tp) - FILE *f; - int code; - u_char *buf; - int nb; - struct timeval *tp; -{ - struct timeval now; - int diff; - - gettimeofday(&now, NULL); - now.tv_usec /= 100000; /* actually 1/10 s, not usec now */ - diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec); - if (diff > 0) { - if (diff > 255) { - putc(5, f); - putc(diff >> 24, f); - putc(diff >> 16, f); - putc(diff >> 8, f); - putc(diff, f); - } else { - putc(6, f); - putc(diff, f); - } - *tp = now; - } - putc(code, f); - if (buf != NULL) { - putc(nb >> 8, f); - putc(nb, f); - fwrite(buf, nb, 1, f); - } - fflush(f); - if (ferror(f)) { - error("Error writing record file: %m"); - return 0; - } - return 1; -} - -#endif /* NEED OUR OWN PORT */ From 05817aa3b99e3a98539d7459d5957dd4ccbc25c5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 14:02:25 +0200 Subject: [PATCH 089/320] LQR (Link Quality Report) support is now optional --- src/include/lwip/opt.h | 7 +++++++ src/netif/ppp/lcp.c | 28 ++++++++++++++++++++++++++++ src/netif/ppp/lcp.h | 4 ++++ src/netif/ppp/ppp.c | 5 ++++- src/netif/ppp/ppp.h | 3 ++- 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index f0848d2e..c8b8cd29 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1748,6 +1748,13 @@ #define ECP_SUPPORT 0 #endif +/** + * LQR_SUPPORT==1: Support Link Quality Report. Do nothing except exchanging some LCP packets. + */ +#ifndef LQR_SUPPORT +#define LQR_SUPPORT 0 +#endif + /** * VJ_SUPPORT==1: Support VJ header compression. */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index b0aee641..a15665e0 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -313,7 +313,9 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL; #define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ #endif /* CHAP_SUPPORT */ #define CILEN_LONG 6 /* CILEN_VOID + 4 */ +#if LQR_SUPPORT #define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ +#endif /* LQR_SUPPORT */ #define CILEN_CBCP 3 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ @@ -721,7 +723,9 @@ lcp_cilen(f) #endif /* CHAP_SUPPORT */ #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) +#if LQR_SUPPORT #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) +#endif /* LQR_SUPPORT */ #define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) /* * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will @@ -755,7 +759,9 @@ lcp_cilen(f) LENCISHORT(go->neg_upap) + #endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ #endif /* PAP_SUPPORT */ +#if LQR_SUPPORT LENCILQR(go->neg_lqr) + +#endif /* LQR_SUPPORT */ LENCICBCP(go->neg_cbcp) + LENCILONG(go->neg_magicnumber) + LENCIVOID(go->neg_pcompression) + @@ -804,6 +810,7 @@ lcp_addci(f, ucp, lenp) PUTCHAR(CILEN_LONG, ucp); \ PUTLONG(val, ucp); \ } +#if LQR_SUPPORT #define ADDCILQR(opt, neg, val) \ if (neg) { \ PUTCHAR(opt, ucp); \ @@ -811,6 +818,7 @@ lcp_addci(f, ucp, lenp) PUTSHORT(PPP_LQR, ucp); \ PUTLONG(val, ucp); \ } +#endif /* LQR_SUPPORT */ #define ADDCICHAR(opt, neg, val) \ if (neg) { \ PUTCHAR(opt, ucp); \ @@ -855,7 +863,9 @@ lcp_addci(f, ucp, lenp) ADDCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); #endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ #endif /* PAP_SUPPORT */ +#if LQR_SUPPORT ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); +#endif /* LQR_SUPPORT */ ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); @@ -963,6 +973,7 @@ lcp_ackci(f, p, len) if (cilong != val) \ goto bad; \ } +#if LQR_SUPPORT #define ACKCILQR(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_LQR) < 0) \ @@ -979,6 +990,7 @@ lcp_ackci(f, p, len) if (cilong != val) \ goto bad; \ } +#endif /* LQR_SUPPORT */ #define ACKCIENDP(opt, neg, class, val, vlen) \ if (neg) { \ int i; \ @@ -1027,7 +1039,9 @@ lcp_ackci(f, p, len) ACKCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); #endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ #endif /* PAP_SUPPORT */ +#if LQR_SUPPORT ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); +#endif /* LQR_SUPPORT */ ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); @@ -1140,6 +1154,7 @@ lcp_nakci(f, p, len, treat_as_reject) no.neg = 1; \ code \ } +#if LQR_SUPPORT #define NAKCILQR(opt, neg, code) \ if (go->neg && \ len >= CILEN_LQR && \ @@ -1152,6 +1167,7 @@ lcp_nakci(f, p, len, treat_as_reject) no.neg = 1; \ code \ } +#endif /* LQR_SUPPORT */ #define NAKCIENDP(opt, neg) \ if (go->neg && \ len >= CILEN_CHAR && \ @@ -1328,6 +1344,7 @@ lcp_nakci(f, p, len, treat_as_reject) } } +#if LQR_SUPPORT /* * 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. @@ -1339,6 +1356,7 @@ lcp_nakci(f, p, len, treat_as_reject) else try.lqr_period = cilong; ); +#endif /* LQR_SUPPORT */ /* * Only implementing CBCP...not the rest of the callback options @@ -1456,10 +1474,12 @@ lcp_nakci(f, p, len, treat_as_reject) || cilen != CILEN_VOID) goto bad; break; +#if LQR_SUPPORT case CI_QUALITY: if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) goto bad; break; +#endif /* LQR_SUPPORT */ case CI_MRRU: if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) goto bad; @@ -1636,6 +1656,7 @@ lcp_rejci(f, p, len) goto bad; \ try.neg = 0; \ } +#if LQR_SUPPORT #define REJCILQR(opt, neg, val) \ if (go->neg && \ len >= CILEN_LQR && \ @@ -1650,6 +1671,7 @@ lcp_rejci(f, p, len) goto bad; \ try.neg = 0; \ } +#endif /* LQR_SUPPORT */ #define REJCICBCP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CBCP && \ @@ -1701,7 +1723,9 @@ lcp_rejci(f, p, len) #if EAP_SUPPORT } #endif /* EAP_SUPPORT */ +#if LQR_SUPPORT REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); +#endif /* LQR_SUPPORT */ REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); REJCIVOID(CI_PCOMPRESSION, neg_pcompression); @@ -2026,6 +2050,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) {} break; +#if LQR_SUPPORT case CI_QUALITY: if (!ao->neg_lqr || cilen != CILEN_LQR) { @@ -2049,6 +2074,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; } break; +#endif /* LQR_SUPPORT */ case CI_MAGICNUMBER: if (!(ao->neg_magicnumber || go->neg_magicnumber) || @@ -2394,6 +2420,7 @@ lcp_printpkt(p, plen, printer, arg) } } break; +#if LQR_SUPPORT case CI_QUALITY: if (olen >= CILEN_SHORT) { p += 2; @@ -2408,6 +2435,7 @@ lcp_printpkt(p, plen, printer, arg) } } break; +#endif /* LQR_SUPPORT */ case CI_CALLBACK: if (olen >= CILEN_CHAR) { p += 2; diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index a97b73a7..6f62d997 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -103,7 +103,9 @@ typedef struct lcp_options { bool neg_magicnumber; /* Ask for magic number? */ bool neg_pcompression; /* HDLC Protocol Field Compression? */ bool neg_accompression; /* HDLC Address/Control Field Compression? */ +#if LQR_SUPPORT bool neg_lqr; /* Negotiate use of Link Quality Reports */ +#endif /* LQR_SUPPORT */ bool neg_cbcp; /* Negotiate use of CBCP */ bool neg_mrru; /* negotiate multilink MRRU */ bool neg_ssnhf; /* negotiate short sequence numbers */ @@ -116,7 +118,9 @@ typedef struct lcp_options { u_int32_t asyncmap; /* Value of async map */ u_int32_t magicnumber; int numloops; /* Number of loops during magic number neg. */ +#if LQR_SUPPORT u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ +#endif /* LQR_SUPPORT */ struct epdisc endpoint; /* endpoint discriminator */ } lcp_options; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index a3331037..fc3b3dc9 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -491,7 +491,10 @@ static void ppp_input(void *arg) { * except LCP, LQR and authentication packets. */ if (phase <= PHASE_AUTHENTICATE - && !(protocol == PPP_LCP || protocol == PPP_LQR + && !(protocol == PPP_LCP +#if LQR_SUPPORT + || protocol == PPP_LQR +#endif /* LQR_SUPPORT */ #if PAP_SUPPORT || protocol == PPP_PAP #endif /* PAP_SUPPORT */ diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 5e18d6b7..0f20399b 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -109,8 +109,9 @@ typedef unsigned char bool; #if PAP_SUPPORT #define PPP_PAP 0xc023 /* Password Authentication Protocol */ #endif /* PAP_SUPPORT */ -/* FIXME: make LQR support optional, anyway, there is no LQR support at all in pppd */ +#if LQR_SUPPORT #define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#endif /* LQR_SUPPORT */ #if CHAP_SUPPORT #define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ #endif /* CHAP_SUPPORT */ From 89d2c2917fd3ea4b901ffdac9e64bb9f2cbe0463 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 16:24:33 +0200 Subject: [PATCH 090/320] more ppp.[ch] cleaning --- src/netif/ppp/ppp.c | 27 +++++++++++---------------- src/netif/ppp/ppp.h | 10 ++++++---- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index fc3b3dc9..3b0942fd 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -181,10 +181,6 @@ typedef struct PPPControl_s { /* Prototypes for procedures local to this file. */ -#if PPPOE_SUPPORT -static void pppOverEthernetLinkStatusCB(int pd, int up); -#endif /* PPPOE_SUPPORT */ - static void ppp_start(int pd); /** Initiate LCP open request */ static void ppp_input(void *arg); @@ -240,7 +236,7 @@ int ppp_init(void) { memset(&ppp_settings, 0, sizeof(ppp_settings)); ppp_settings.usepeerdns = 1; - pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL); + ppp_set_auth(PPPAUTHTYPE_NONE, NULL, NULL); /* * Initialize magic number generator now so that protocols may @@ -257,7 +253,7 @@ int ppp_init(void) { return 0; } -void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) { +void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passwd) { /* FIXME: the following may look stupid, but this is just an easy way * to check different auth by changing compile time option */ @@ -361,11 +357,10 @@ void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) } #if PPPOE_SUPPORT -static void pppOverEthernetLinkStatusCB(int pd, int up); +static void ppp_over_ethernet_link_status_cb(int pd, int up); -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, - pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) -{ +int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, + pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) { PPPControl *pc; int pd; @@ -401,7 +396,7 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha lcp_allowoptions[pd].neg_pcompression = 0; lcp_allowoptions[pd].neg_accompression = 0; - if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) { + if(pppoe_create(ethif, pd, ppp_over_ethernet_link_status_cb, &pc->pppoe_sc) != ERR_OK) { pc->openFlag = 0; return PPPERR_OPEN; } @@ -430,16 +425,15 @@ void pppOverEthernetInitFailed(int pd) { } } -static void pppOverEthernetLinkStatusCB(int pd, int up) { +static void ppp_over_ethernet_link_status_cb(int pd, int up) { if(up) { - PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: Connecting\n", pd)); ppp_start(pd); } else { pppOverEthernetInitFailed(pd); } } -#endif - +#endif /* PPPOE_SUPPORT */ /** Initiate LCP open request */ @@ -450,6 +444,7 @@ static void ppp_start(int pd) { PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); } + /* * Pass the processed input packet to the appropriate handler. * This function and all handlers run in the context of the tcpip_thread @@ -1093,7 +1088,7 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { #endif /* PPPOE_SUPPORT */ - +/* merge a pbuf chain into one pbuf */ struct pbuf * ppp_singlebuf(struct pbuf *p) { struct pbuf *q, *b; u_char *pl; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 0f20399b..e4c95b24 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -497,7 +497,7 @@ enum pppAuthType { /* Initialize the PPP subsystem. */ int ppp_init(void); -void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); +void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passwd); /* Link status callback function prototype */ typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); @@ -505,13 +505,14 @@ typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); /* * Open a new PPP Over Ethernet (PPPOE) connection. */ -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, +int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); - -/* --- EVERYTHING BELOW SHOULD BE CONSIDERED PRIVATE ---- */ +/* ------------------------------------------------------ * + * --- EVERYTHING BELOW SHOULD BE CONSIDERED PRIVATE ---- * + * ------------------------------------------------------ */ /* PPP flow functions */ @@ -527,6 +528,7 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb); /* function called by all PPP subsystems to send packets */ int ppp_write(int pd, const u_char *s, int n); +/* merge a pbuf chain into one pbuf */ struct pbuf * ppp_singlebuf(struct pbuf *p); From 2f5f86d6fcda53a0285639696fa877cf8d3b74b5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 16:38:26 +0200 Subject: [PATCH 091/320] don't build any PPP file if PPP support is disabled --- src/netif/ppp/auth.c | 3 +++ src/netif/ppp/ccp.c | 4 ---- src/netif/ppp/chap-new.c | 2 -- src/netif/ppp/demand.c | 2 -- src/netif/ppp/ecp.c | 4 ---- src/netif/ppp/fsm.c | 7 +++---- src/netif/ppp/fsm.h | 5 +++++ src/netif/ppp/ipcp.c | 7 +++---- src/netif/ppp/ipcp.h | 5 +++++ src/netif/ppp/lcp.c | 3 +++ src/netif/ppp/lcp.h | 5 +++++ src/netif/ppp/magic.h | 9 +++++---- src/netif/ppp/multilink.c | 5 ++--- src/netif/ppp/options.c | 7 +++---- src/netif/ppp/polarssl/des.h | 6 ++++++ src/netif/ppp/polarssl/md4.h | 6 ++++++ src/netif/ppp/polarssl/md5.h | 6 ++++++ src/netif/ppp/polarssl/sha1.h | 6 ++++++ src/netif/ppp/ppp.c | 3 +++ src/netif/ppp/ppp.h | 3 +++ src/netif/ppp/ppp_oe.c | 5 ++--- src/netif/ppp/pppdebug.h | 6 ++++++ src/netif/ppp/utils.c | 7 +++---- 23 files changed, 78 insertions(+), 38 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index d96ab99f..c7d232a1 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -69,6 +69,7 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #if 0 /* UNUSED */ #include @@ -2580,3 +2581,5 @@ free_wordlist(wp) } } #endif /* UNUSED */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 5c1cac58..47b1027b 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -31,8 +31,6 @@ #include "lwip/opt.h" #if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#define RCSID "$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $" - #include #include @@ -47,8 +45,6 @@ #include "lcp.h" /* lcp_close(), lcp_fsm */ #endif -static const char rcsid[] = RCSID; - /* * Unfortunately there is a bug in zlib which means that using a * size of 8 (window size = 256) for Deflate compression will cause diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index c92ab19d..7c0b1c1a 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -31,8 +31,6 @@ #include "lwip/opt.h" #if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#define RCSID "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $" - #if 0 /* UNUSED */ #include #include diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index 2b93b4ce..b2f146d6 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -58,8 +58,6 @@ #include "ipcp.h" #include "lcp.h" -static const char rcsid[] = RCSID; - char *frame; int framelen; int framemax; diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index 18b1d89f..a355c48a 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -60,10 +60,6 @@ #include "lwip/opt.h" #if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $" - -static const char rcsid[] = RCSID; - #include #include "ppp.h" diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 40c1f954..585ec8e7 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -41,8 +41,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: fsm.c,v 1.23 2004/11/13 02:28:15 paulus Exp $" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ /* * TODO: @@ -60,8 +59,6 @@ #include "fsm.h" -static const char rcsid[] = RCSID; - static void fsm_timeout __P((void *)); static void fsm_rconfreq __P((fsm *, int, u_char *, int)); static void fsm_rconfack __P((fsm *, int, u_char *, int)); @@ -820,3 +817,5 @@ fsm_sdata(f, code, id, data, datalen) PUTSHORT(outlen, outp); ppp_write(f->unit, outpacket_buf, outlen + PPP_HDRLEN); } + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index 87a78d38..4f202caa 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -42,6 +42,9 @@ * $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + /* * Packet header = Code, id, length. */ @@ -166,3 +169,5 @@ void fsm_sdata __P((fsm *, int, int, u_char *, int)); * Variables */ extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index f0ebea2e..8106ffa1 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -41,8 +41,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp $" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ /* * TODO: @@ -65,8 +64,6 @@ #include "fsm.h" #include "ipcp.h" -static const char rcsid[] = RCSID; - /* 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 */ @@ -2268,3 +2265,5 @@ ip_active_pkt(pkt, len) return 1; } #endif /* DEMAND_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index 332575e7..582d167b 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -42,6 +42,9 @@ * $Id: ipcp.h,v 1.14 2002/12/04 23:03:32 paulus Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + /* * Options. */ @@ -97,3 +100,5 @@ char *ip_ntoa __P((u_int32_t)); #endif /* UNUSED, already defined by lwIP */ extern struct protent ipcp_protent; + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index a15665e0..11f25bf8 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -41,6 +41,7 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ /* * TODO: @@ -2735,3 +2736,5 @@ lcp_echo_lowerdown (unit) lcp_echo_timer_running = 0; } } + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index 6f62d997..60d643d1 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -42,6 +42,9 @@ * $Id: lcp.h,v 1.20 2004/11/14 22:53:42 carlsonj Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + /* * Options. */ @@ -145,3 +148,5 @@ 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 + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/magic.h b/src/netif/ppp/magic.h index 75bab1ca..5dc34018 100644 --- a/src/netif/ppp/magic.h +++ b/src/netif/ppp/magic.h @@ -74,12 +74,12 @@ * Extracted from avos. *****************************************************************************/ -#ifndef MAGIC_H -#define MAGIC_H - #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#ifndef MAGIC_H +#define MAGIC_H + /*********************** *** PUBLIC FUNCTIONS *** ***********************/ @@ -114,5 +114,6 @@ u32_t magic(void); /* Returns the next magic number */ void random_bytes(unsigned char *buf, u32_t len); #endif /* PPP_MD5_RANDM */ -#endif /* PPP_SUPPORT */ #endif /* MAGIC_H */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 792da323..4c7ae95e 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -29,6 +29,7 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT && HAVE_MULTILINK /* don't build if not configured for use in lwipopts.h */ /* Multilink support * @@ -39,8 +40,6 @@ * or dropping multilink support at all. */ -#ifdef HAVE_MULTILINK - #include #include #include @@ -607,4 +606,4 @@ str_to_epdisc(ep, str) return 1; } -#endif /* HAVE_MULTILINK */ +#endif /* PPP_SUPPORT && HAVE_MULTILINK */ diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index fbe3404a..eb718f09 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -41,8 +41,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: options.c,v 1.102 2008/06/15 06:53:06 paulus Exp $" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include #include @@ -82,8 +81,6 @@ char *strdup __P((char *)); #endif -static const char rcsid[] = RCSID; - struct option_value { struct option_value *next; const char *source; @@ -1647,3 +1644,5 @@ loadplugin(argv) } #endif /* PLUGIN */ #endif /* PPP_OPTIONS */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/polarssl/des.h b/src/netif/ppp/polarssl/des.h index abe4652a..86417cd4 100644 --- a/src/netif/ppp/polarssl/des.h +++ b/src/netif/ppp/polarssl/des.h @@ -32,6 +32,10 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "lwip/opt.h" +#if LWIP_INCLUDED_POLARSSL_DES + #ifndef LWIP_INCLUDED_POLARSSL_DES_H #define LWIP_INCLUDED_POLARSSL_DES_H @@ -84,3 +88,5 @@ void des_crypt_ecb( des_context *ctx, #endif #endif /* LWIP_INCLUDED_POLARSSL_DES_H */ + +#endif /* LWIP_INCLUDED_POLARSSL_DES */ diff --git a/src/netif/ppp/polarssl/md4.h b/src/netif/ppp/polarssl/md4.h index 7fe5985f..46ebf5cb 100644 --- a/src/netif/ppp/polarssl/md4.h +++ b/src/netif/ppp/polarssl/md4.h @@ -32,6 +32,10 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "lwip/opt.h" +#if LWIP_INCLUDED_POLARSSL_MD4 + #ifndef LWIP_INCLUDED_POLARSSL_MD4_H #define LWIP_INCLUDED_POLARSSL_MD4_H @@ -89,3 +93,5 @@ void md4( unsigned char *input, int ilen, unsigned char output[16] ); #endif #endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ + +#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ diff --git a/src/netif/ppp/polarssl/md5.h b/src/netif/ppp/polarssl/md5.h index 2103f00e..3587b4c0 100644 --- a/src/netif/ppp/polarssl/md5.h +++ b/src/netif/ppp/polarssl/md5.h @@ -32,6 +32,10 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "lwip/opt.h" +#if LWIP_INCLUDED_POLARSSL_MD5 + #ifndef LWIP_INCLUDED_POLARSSL_MD5_H #define LWIP_INCLUDED_POLARSSL_MD5_H @@ -88,3 +92,5 @@ void md5( unsigned char *input, int ilen, unsigned char output[16] ); #endif #endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ + +#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ diff --git a/src/netif/ppp/polarssl/sha1.h b/src/netif/ppp/polarssl/sha1.h index 5f69aef7..9d331633 100644 --- a/src/netif/ppp/polarssl/sha1.h +++ b/src/netif/ppp/polarssl/sha1.h @@ -32,6 +32,10 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "lwip/opt.h" +#if LWIP_INCLUDED_POLARSSL_SHA1 + #ifndef LWIP_INCLUDED_POLARSSL_SHA1_H #define LWIP_INCLUDED_POLARSSL_SHA1_H @@ -88,3 +92,5 @@ void sha1( unsigned char *input, int ilen, unsigned char output[20] ); #endif #endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ + +#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 3b0942fd..df408505 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -6,6 +6,7 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include "lwip/pbuf.h" #include "lwip/stats.h" @@ -1571,3 +1572,5 @@ void print_link_stats() { } } #endif /* PPP_STATS_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index e4c95b24..c9de3032 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -6,6 +6,7 @@ */ #include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #ifndef PPPMY_H_ #define PPPMY_H_ @@ -744,3 +745,5 @@ void dump_packet __P((const char *, u_char *, int)); #endif /* PPPMY_H_ */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index b265c75b..caba219e 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -69,7 +69,7 @@ */ #include "lwip/opt.h" -#if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ #if 0 /* UNUSED */ #include @@ -1126,5 +1126,4 @@ pppoe_clear_softc(struct pppoe_softc *sc, const char *message) sc->sc_session = 0; } -#endif /* PPPOE_SUPPORT */ - +#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/src/netif/ppp/pppdebug.h b/src/netif/ppp/pppdebug.h index b8bae15f..e35c8e09 100644 --- a/src/netif/ppp/pppdebug.h +++ b/src/netif/ppp/pppdebug.h @@ -33,6 +33,10 @@ * ***************************************************************************** */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + #ifndef PPPDEBUG_H #define PPPDEBUG_H @@ -72,3 +76,5 @@ #endif /* PPP_DEBUG */ #endif /* PPPDEBUG_H */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 679d0ef8..4869c057 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -29,8 +29,7 @@ */ #include "lwip/opt.h" - -#define RCSID "$Id: utils.c,v 1.25 2008/06/03 12:06:37 paulus Exp $" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #if 0 /* UNUSED */ #include @@ -66,8 +65,6 @@ #include "fsm.h" #include "lcp.h" -static const char rcsid[] = RCSID; - #if defined(SUNOS4) extern char *strerror(); #endif @@ -1084,3 +1081,5 @@ unlock() } #endif /* Unused */ + +#endif /* PPP_SUPPORT */ From 103ad75c507fc88c39d3dadb752d071ae1751b6f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 16:51:03 +0200 Subject: [PATCH 092/320] automatically enable MD5 Random support if CHAP or EAP is enabled --- src/include/lwip/opt.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index c8b8cd29..fd810fec 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1763,7 +1763,7 @@ #endif /** - * PPP_MD5_RANDM==1: Use MD5 for better randomness. + * PPP_MD5_RANDM==1: Use MD5 for better randomness. Automatically enabled if CHAP or EAP support is enabled. */ #ifndef PPP_MD5_RANDM #define PPP_MD5_RANDM 0 @@ -1805,6 +1805,8 @@ #if CHAP_SUPPORT || EAP_SUPPORT || PPP_MD5_RANDM #ifndef LWIP_INCLUDED_POLARSSL_MD5 #define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP and EAP require MD5 support */ +#undef PPP_MD5_RANDM +#define PPP_MD5_RANDM 1 /* MD5 Random is required for CHAP and EAP */ #endif /* LWIP_INCLUDED_POLARSSL_MD5 */ #endif /* CHAP_SUPPORT || EAP_SUPPORT || PPP_MD5_RANDM */ From 10175caa384c4f9527794ca18974dd06dd6498a2 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 16:59:50 +0200 Subject: [PATCH 093/320] fixed MD5 Random enabling conditions --- src/include/lwip/opt.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index fd810fec..d4078520 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1763,11 +1763,15 @@ #endif /** - * PPP_MD5_RANDM==1: Use MD5 for better randomness. Automatically enabled if CHAP or EAP support is enabled. + * PPP_MD5_RANDM==1: Use MD5 for better randomness. Automatically enabled if CHAP support is enabled. */ #ifndef PPP_MD5_RANDM #define PPP_MD5_RANDM 0 #endif +#if CHAP_SUPPORT +#undef PPP_MD5_RANDM +#define PPP_MD5_RANDM 1 /* MD5 Random is required for CHAP */ +#endif /* CHAP_SUPPORT */ /** * PolarSSL library, used if necessary and not previously disabled @@ -1804,9 +1808,7 @@ #if CHAP_SUPPORT || EAP_SUPPORT || PPP_MD5_RANDM #ifndef LWIP_INCLUDED_POLARSSL_MD5 -#define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP and EAP require MD5 support */ -#undef PPP_MD5_RANDM -#define PPP_MD5_RANDM 1 /* MD5 Random is required for CHAP and EAP */ +#define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP, EAP and MD5 Random require MD5 support */ #endif /* LWIP_INCLUDED_POLARSSL_MD5 */ #endif /* CHAP_SUPPORT || EAP_SUPPORT || PPP_MD5_RANDM */ From 0663421d019005bc02b50b5dfcb77c4b4f04f0a3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 20:05:40 +0200 Subject: [PATCH 094/320] re-added PPPoS code from the previous port, it builds, maybe it works --- src/netif/ppp/auth.c | 12 +- src/netif/ppp/lcp.c | 36 ++ src/netif/ppp/lcp.h | 3 + src/netif/ppp/ppp.c | 1041 +++++++++++++++++++++++++++++++++++++++--- src/netif/ppp/ppp.h | 121 ++++- 5 files changed, 1130 insertions(+), 83 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index c7d232a1..cdb067df 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -661,7 +661,7 @@ link_terminated(unit) lcp_lowerdown(0); new_phase(PHASE_DEAD); - + pppLinkTerminated(unit); #if 0 /* * Delete pid files before disestablishing ppp. Otherwise it @@ -728,6 +728,8 @@ link_down(unit) } /* XXX if doing_multilink, should do something to stop network-layer traffic on the link */ + + pppLinkDown(unit); } void upper_layers_down(int unit) @@ -1109,6 +1111,7 @@ void auth_withpeer_fail(unit, protocol) int unit, protocol; { + int errcode = PPPERR_AUTHFAIL; /* * We've failed to authenticate ourselves to our peer. * Some servers keep sending CHAP challenges, but there @@ -1116,6 +1119,13 @@ auth_withpeer_fail(unit, protocol) * authentication secrets. */ status = EXIT_AUTH_TOPEER_FAILED; + + /* + * We've failed to authenticate ourselves to our peer. + * He'll probably take the link down, and there's not much + * we can do except wait for that. + */ + pppIOCtl(unit, PPPCTLS_ERRCODE, &errcode); lcp_close(unit, "Failed to authenticate ourselves to peer"); } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 11f25bf8..c8d12455 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -207,6 +207,9 @@ 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 */ +#if PPPOS_SUPPORT +ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */ +#endif /* PPPOS_SUPPORT */ static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */ static int lcp_echo_number = 0; /* ID number of next echo frame */ @@ -403,6 +406,24 @@ lcp_init(unit) ao->neg_pcompression = 1; ao->neg_accompression = 1; ao->neg_endpoint = 1; + +#if PPPOS_SUPPORT + /* + * Set transmit escape for the flag and escape characters plus anything + * set for the allowable options. + */ + memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); + xmit_accm[unit][15] = 0x60; + xmit_accm[unit][0] = (u_char)((ao->asyncmap & 0xFF)); + xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF); + xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF); + xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF); + LCPDEBUG(("lcp_init: xmit_accm=%X %X %X %X\n", + xmit_accm[unit][0], + xmit_accm[unit][1], + xmit_accm[unit][2], + xmit_accm[unit][3])); +#endif /* PPPOS_SUPPORT */ } @@ -475,12 +496,27 @@ lcp_lowerup(unit) * but accept A/C and protocol compressed packets * if we are going to ask for A/C and protocol compression. */ +#if PPPOS_SUPPORT + ppp_set_xaccm(unit, &xmit_accm[unit]); +#endif /* PPPOS_SUPPORT */ if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0 || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), wo->neg_pcompression, wo->neg_accompression) < 0) return; peer_mru[unit] = PPP_MRU; + #if PPPOS_SUPPORT + lcp_allowoptions[unit].asyncmap = (u_long)xmit_accm[unit][0] + | ((u_long)xmit_accm[unit][1] << 8) + | ((u_long)xmit_accm[unit][2] << 16) + | ((u_long)xmit_accm[unit][3] << 24); + LCPDEBUG(("lcp_lowerup: asyncmap=%X %X %X %X\n", + xmit_accm[unit][3], + xmit_accm[unit][2], + xmit_accm[unit][1], + xmit_accm[unit][0])); +#endif /* PPPOS_SUPPORT */ + if (listen_time != 0) { f->flags |= DELAYED_UP; TIMEOUTMS(lcp_delayed_up, f, listen_time); diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index 60d643d1..d701e9af 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -132,6 +132,9 @@ extern lcp_options lcp_wantoptions[]; extern lcp_options lcp_gotoptions[]; extern lcp_options lcp_allowoptions[]; extern lcp_options lcp_hisoptions[]; +#if PPPOS_SUPPORT +extern ext_accm xmit_accm[]; +#endif /* #if PPPOS_SUPPORT */ #define DEFMRU 1500 /* Try for this */ #define MINMRU 128 /* No MRUs below this */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index df408505..2be4388f 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1,8 +1,82 @@ +/***************************************************************************** +* ppp.c - Network Point to Point Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ + /* - * ppp.c + * ppp_defs.h - PPP definitions. * - * Created on: May 12, 2012 - * Author: gradator + * if_pppvar.h - private structures and declarations for PPP. + * + * 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. + */ + +/* + * if_ppp.h - Point-to-Point 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "lwip/opt.h" @@ -14,6 +88,8 @@ #include "lwip/tcpip.h" #include "lwip/api.h" #include "lwip/snmp.h" +#include "lwip/sio.h" +#include "lwip/ip.h" /* for ip_input() */ #include "ppp.h" @@ -42,6 +118,29 @@ #include "netif/ppp_oe.h" #endif /* PPPOE_SUPPORT */ +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + +/** PPP_INPROC_MULTITHREADED==1 call ppp_input using tcpip_callback(). + * Set this to 0 if pppInProc is called inside tcpip_thread or with NO_SYS==1. + * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). + */ +#ifndef PPP_INPROC_MULTITHREADED +#define PPP_INPROC_MULTITHREADED (NO_SYS==0) +#endif + +/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session. + * Default is 0: call pppos_input() for received raw characters, character + * reception is up to the port */ +#ifndef PPP_INPROC_OWNTHREAD +#define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED +#endif + +#if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED + #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1" +#endif + /* * Global variables. */ @@ -57,6 +156,11 @@ int need_holdoff; /* need holdoff period before restarting */ int ifunit; /* Interface unit number */ /* FIXME: outpacket_buf per PPP session */ + +/* + * Buffers for outgoing packets. This must be accessed only from the appropriate + * PPP task so that it doesn't need to be protected to avoid collisions. + */ u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ #if PPPOS_SUPPORT @@ -119,31 +223,35 @@ typedef enum { PDDATA /* Process data byte. */ } PPPDevStates; +#if PPPOS_SUPPORT +#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07]) + +/** RX buffer size: this may be configured smaller! */ +#ifndef PPPOS_RX_BUFSIZE +#define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN) +#endif +#endif /* PPPOS_SUPPORT */ + typedef struct PPPControlRx_s { /** unit number / ppp descriptor */ int pd; /** the rx file descriptor */ -#if PPPOS_SUPPORT /* FIXME: enable sio_fd_t back */ sio_fd_t fd; -#endif -#if PPPOE_SUPPORT - int fd; -#endif /** receive buffer - encoded data is stored here */ -#if PPP_INPROC_OWNTHREAD +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD u_char rxbuf[PPPOS_RX_BUFSIZE]; -#endif /* PPP_INPROC_OWNTHREAD */ +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ +#if PPPOS_SUPPORT /* The input packet. */ struct pbuf *inHead, *inTail; -#if PPPOS_SUPPORT u16_t inProtocol; /* The input protocol code. */ u16_t inFCS; /* Input Frame Check Sequence value. */ -#endif /* PPPOS_SUPPORT */ PPPDevStates inState; /* The input process state. */ char inEscaped; /* Escape next character. */ ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ +#endif /* PPPOS_SUPPORT */ } PPPControlRx; /* @@ -165,7 +273,9 @@ typedef struct PPPControl_s { int pcomp; /* Does peer accept protocol compression? */ int accomp; /* Does peer accept addr/ctl compression? */ u_long lastXMit; /* Time of last transmission. */ +#if PPPOS_SUPPORT ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ +#endif /* PPPOS_SUPPORT */ #if PPPOS_SUPPORT && VJ_SUPPORT int vjEnabled; /* Flag indicating VJ compression enabled. */ struct vjcompress vjComp; /* Van Jacobson compression header. */ @@ -185,14 +295,29 @@ typedef struct PPPControl_s { static void ppp_start(int pd); /** Initiate LCP open request */ static void ppp_input(void *arg); +#if PPPOS_SUPPORT +static void pppRecvWakeup(int pd); +#endif /* #if PPPOS_SUPPORT */ + +static void pppStop(int pd); +static void pppHup(int pd); + +#if PPPOS_SUPPORT +#if PPP_INPROC_OWNTHREAD +static void pppInputThread(void *arg); +#endif /* PPP_INPROC_OWNTHREAD */ +static void pppDrop(PPPControlRx *pcrx); +static void pppInProc(PPPControlRx *pcrx, u_char *s, int l); +static void pppFreeCurrentInputPacket(PPPControlRx *pcrx); +#endif /* PPPOS_SUPPORT */ + static err_t ppp_netif_init_cb(struct netif *netif); static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); -#if PPPOE_SUPPORT -static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p); -#endif /* PPPOE_SUPPORT */ #if PPPOE_SUPPORT +static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p); /* function called by ppp_write() */ +void pppOverEthernetClose(int pd); static int ppp_write_over_ethernet(int pd, const u_char *s, int n); #endif /* PPPOE_SUPPORT */ @@ -220,8 +345,8 @@ PACK_STRUCT_END /***********************************/ /*** PUBLIC FUNCTION DEFINITIONS ***/ /***********************************/ -/* Initialize the PPP subsystem. */ +/* Initialize the PPP subsystem. */ int ppp_init(void) { int i; struct protent *protp; @@ -357,6 +482,85 @@ void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passw } } +#if PPPOS_SUPPORT +/** Open a new PPP connection using the given I/O device. + * This initializes the PPP control block but does not + * attempt to negotiate the LCP session. If this port + * connects to a modem, the modem connection must be + * established before calling this. + * Return a new PPP connection descriptor on success or + * an error code (negative) on failure. + * + * pppOpen() is directly defined to this function. + */ +int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) { + PPPControl *pc; + int pd; + + if (linkStatusCB == NULL) { + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + return PPPERR_PARAM; + } + + /* Find a free PPP session descriptor. */ + for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + + if (pd >= NUM_PPP) { + pd = PPPERR_OPEN; + } else { + pc = &pppControl[pd]; + /* input pbuf left over from last session? */ + pppFreeCurrentInputPacket(&pc->rx); + /* @todo: is this correct or do I overwrite something? */ + memset(pc, 0, sizeof(PPPControl)); + pc->rx.pd = pd; + pc->rx.fd = fd; + + pc->openFlag = 1; + pc->fd = fd; + +#if VJ_SUPPORT + vj_compress_init(&pc->vjComp); +#endif /* VJ_SUPPORT */ + + /* + * Default the in and out accm so that escape and flag characters + * are always escaped. + */ + pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */ + pc->outACCM[15] = 0x60; + + pc->linkStatusCB = linkStatusCB; + pc->linkStatusCtx = linkStatusCtx; + + /* + * Start the connection and handle incoming events (packet or timeout). + */ + PPPDEBUG(LOG_INFO, ("pppOverSerialOpen: unit %d: Connecting\n", pd)); + ppp_start(pd); +#if PPP_INPROC_OWNTHREAD + sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); +#endif /* PPP_INPROC_OWNTHREAD */ + } + + return pd; +} + +/* + * ppp_set_xaccm - set the extended transmit ACCM for the interface. + */ +void ppp_set_xaccm(int unit, ext_accm *accm) { + SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm)); + PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n", + unit, + pppControl[unit].outACCM[0], + pppControl[unit].outACCM[1], + pppControl[unit].outACCM[2], + pppControl[unit].outACCM[3])); +} +#endif /* PPPOS_SUPPORT */ + #if PPPOE_SUPPORT static void ppp_over_ethernet_link_status_cb(int pd, int up); @@ -408,35 +612,63 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const return pd; } +void pppOverEthernetClose(int pd) { + PPPControl* pc = &pppControl[pd]; -void pppOverEthernetInitFailed(int pd) { - PPPControl* pc; + /* *TJL* There's no lcp_deinit */ + lcp_close(pd, NULL); - /* FIXME: re-enable that - * pppHup(pd); - * pppStop(pd); - */ - - pc = &pppControl[pd]; pppoe_destroy(&pc->netif); - pc->openFlag = 0; - - if(pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); - } -} - -static void ppp_over_ethernet_link_status_cb(int pd, int up) { - if(up) { - PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: Connecting\n", pd)); - ppp_start(pd); - } else { - pppOverEthernetInitFailed(pd); - } } #endif /* PPPOE_SUPPORT */ +/* Close a PPP connection and release the descriptor. + * Any outstanding packets in the queues are dropped. + * Return 0 on success, an error code on failure. */ +int +pppClose(int pd) +{ + PPPControl *pc = &pppControl[pd]; + int st = 0; + + PPPDEBUG(LOG_DEBUG, ("pppClose() called\n")); + + /* Disconnect */ +#if PPPOE_SUPPORT + if(pc->ethif) { + PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); + pc->errCode = PPPERR_USER; + /* This will leave us at PHASE_DEAD. */ + pppStop(pd); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT + PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); + pc->errCode = PPPERR_USER; + /* This will leave us at PHASE_DEAD. */ + pppStop(pd); +#if PPP_INPROC_OWNTHREAD + pppRecvWakeup(pd); +#endif /* PPP_INPROC_OWNTHREAD */ +#endif /* PPPOS_SUPPORT */ + } + + return st; +} + +/* This function is called when carrier is lost on the PPP channel. */ +void +pppSigHUP(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); + pppHup(pd); +} + + + + /** Initiate LCP open request */ static void ppp_start(int pd) { PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pd)); @@ -445,6 +677,22 @@ static void ppp_start(int pd) { PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); } +/** LCP close request */ +static void +pppStop(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppStop: unit %d\n", pd)); + lcp_close(pd, "User request"); +} + +/** Called when carrier/link is lost */ +static void +pppHup(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppHupCB: unit %d\n", pd)); + lcp_lowerdown(pd); + link_terminated(pd); +} /* * Pass the processed input packet to the appropriate handler. @@ -512,7 +760,7 @@ static void ppp_input(void *arg) { #if PPPOS_SUPPORT && VJ_SUPPORT case PPP_VJC_COMP: /* VJ compressed TCP */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); /* * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. @@ -522,11 +770,11 @@ static void ppp_input(void *arg) { return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pd)); break; case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); /* * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. @@ -536,12 +784,12 @@ static void ppp_input(void *arg) { return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pd)); break; #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pd, nb->len)); if (pppControl[pd].netif.input) { pppControl[pd].netif.input(nb, &pppControl[pd].netif); return; @@ -613,7 +861,7 @@ out: if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || (lcp_phase[pd] != PHASE_AUTHENTICATE)) { - PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); + PPPDEBUG(LOG_INFO, ("ppp_input: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); goto drop; } } @@ -621,7 +869,7 @@ out: switch(protocol) { case PPP_VJC_COMP: /* VJ compressed TCP */ #if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); /* * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. @@ -631,16 +879,16 @@ out: return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pd)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ #if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); /* * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. @@ -650,17 +898,17 @@ out: return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pd)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ /* No handler for this protocol so drop the packet. */ PPPDEBUG(LOG_INFO, - ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", + ("ppp_input[%d]: drop VJ UnComp in %d:.*H\n", pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pd, nb->len)); if (pppControl[pd].netif.input) { pppControl[pd].netif.input(nb, &pppControl[pd].netif); return; @@ -676,16 +924,16 @@ out: */ for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { - PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: %s len=%d\n", pd, protp->name, nb->len)); nb = ppp_singlebuf(nb); (*protp->input)(pd, nb->payload, nb->len); - PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); + PPPDEBUG(LOG_DETAIL, ("ppp_input[%d]: packet processed\n", pd)); goto out; } } /* No handler for this protocol so reject the packet. */ - PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); if (pbuf_header(nb, sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; @@ -703,6 +951,72 @@ out: } +#if PPPOS_SUPPORT +/* + * FCS lookup table as calculated by genfcstab. + * @todo: smaller, slower implementation for lower memory footprint? + */ +static const 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 +}; + +/* PPP's Asynchronous-Control-Character-Map. The mask array is used + * to select the specific bit for a character. */ +static u_char pppACCMMask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 +}; + +#if PPP_INPROC_OWNTHREAD +/** Wake up the task blocked in reading from serial line (if any) */ +static void +pppRecvWakeup(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd)); + if (pppControl[pd].openFlag != 0) { + sio_read_abort(pppControl[pd].fd); + } +} +#endif /* PPP_INPROC_OWNTHREAD */ +#endif /* PPPOS_SUPPORT */ + #if PPPOE_SUPPORT /* ppp_input_over_ethernet * @@ -763,6 +1077,96 @@ static err_t ppp_netif_init_cb(struct netif *netif) { return ERR_OK; } + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ + +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD +/* The main PPP process function. This implements the state machine according + * to section 4 of RFC 1661: The Point-To-Point Protocol. */ +static void +pppInputThread(void *arg) +{ + int count; + PPPControlRx *pcrx = arg; + + while (phase != PHASE_DEAD) { + count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); + if(count > 0) { + pppInProc(pcrx, pcrx->rxbuf, count); + } else { + /* nothing received, give other tasks a chance to run */ + sys_msleep(1); + } + } +} +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ + + +#if PPPOS_SUPPORT +static void +nPut(PPPControl *pc, struct pbuf *nb) +{ + struct pbuf *b; + int c; + + for(b = nb; b != NULL; b = b->next) { + if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) { + PPPDEBUG(LOG_WARNING, + ("PPP nPut: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); + LINK_STATS_INC(link.err); + pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */ + snmp_inc_ifoutdiscards(&pc->netif); + pbuf_free(nb); + return; + } + } + + snmp_add_ifoutoctets(&pc->netif, nb->tot_len); + snmp_inc_ifoutucastpkts(&pc->netif); + pbuf_free(nb); + LINK_STATS_INC(link.xmit); +} + +/* + * pppAppend - append given character to end of given pbuf. If outACCM + * is not NULL and the character needs to be escaped, do so. + * If pbuf is full, append another. + * Return the current pbuf. + */ +static struct pbuf * +pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM) +{ + struct pbuf *tb = nb; + + /* Make sure there is room for the character and an escape code. + * Sure we don't quite fill the buffer if the character doesn't + * get escaped but is one character worth complicating this? */ + /* Note: We assume no packet header. */ + if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) { + tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (tb) { + nb->next = tb; + } else { + LINK_STATS_INC(link.memerr); + } + nb = tb; + } + + if (nb) { + if (outACCM && ESCAPE_P(*outACCM, c)) { + *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE; + *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS; + } else { + *((u_char*)nb->payload + nb->len++) = c; + } + } + + return tb; +} +#endif /* PPPOS_SUPPORT */ + /* Send a packet on the given connection. * * This is the low level function that send the PPP packet. @@ -973,6 +1377,56 @@ u_short pppMTU(int pd) { return st; } +/* Get and set parameters for the given connection. + * Return 0 on success, an error code on failure. */ +int +pppIOCtl(int pd, int cmd, void *arg) +{ + PPPControl *pc = &pppControl[pd]; + int st = 0; + + if (pd < 0 || pd >= NUM_PPP) { + st = PPPERR_PARAM; + } else { + switch(cmd) { + case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ + if (arg) { + *(int *)arg = (int)(pc->if_up); + } else { + st = PPPERR_PARAM; + } + break; + case PPPCTLS_ERRCODE: /* Set the PPP error code. */ + if (arg) { + pc->errCode = *(int *)arg; + } else { + st = PPPERR_PARAM; + } + break; + case PPPCTLG_ERRCODE: /* Get the PPP error code. */ + if (arg) { + *(int *)arg = (int)(pc->errCode); + } else { + st = PPPERR_PARAM; + } + break; +#if PPPOS_SUPPORT + case PPPCTLG_FD: /* Get the fd associated with the ppp */ + if (arg) { + *(sio_fd_t *)arg = pc->fd; + } else { + st = PPPERR_PARAM; + } + break; +#endif /* PPPOS_SUPPORT */ + default: + st = PPPERR_PARAM; + break; + } + } + + return st; +} /* * Write n characters to a ppp link. @@ -1089,6 +1543,260 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { #endif /* PPPOE_SUPPORT */ +#if PPPOS_SUPPORT +/* + * Drop the input packet. + */ +static void +pppFreeCurrentInputPacket(PPPControlRx *pcrx) +{ + if (pcrx->inHead != NULL) { + if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) { + pbuf_free(pcrx->inTail); + } + pbuf_free(pcrx->inHead); + pcrx->inHead = NULL; + } + pcrx->inTail = NULL; +} + +/* + * Drop the input packet and increase error counters. + */ +static void +pppDrop(PPPControlRx *pcrx) +{ + if (pcrx->inHead != NULL) { +#if 0 + PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload)); +#endif + PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead)); + } + pppFreeCurrentInputPacket(pcrx); +#if VJ_SUPPORT + vj_uncompress_err(&pppControl[pcrx->pd].vjComp); +#endif /* VJ_SUPPORT */ + + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); +} + +#if !PPP_INPROC_OWNTHREAD +/** Pass received raw characters to PPPoS to be decoded. This function is + * thread-safe and can be called from a dedicated RX-thread or from a main-loop. + * + * @param pd PPP descriptor index, returned by pppOpen() + * @param data received data + * @param len length of received data + */ +void +pppos_input(int pd, u_char* data, int len) +{ + pppInProc(&pppControl[pd].rx, data, len); +} +#endif + +/** + * Process a received octet string. + */ +static void +pppInProc(PPPControlRx *pcrx, u_char *s, int l) +{ + struct pbuf *nextNBuf; + u_char curChar; + u_char escaped; + SYS_ARCH_DECL_PROTECT(lev); + + PPPDEBUG(LOG_DEBUG, ("pppInProc[%d]: got %d bytes\n", pcrx->pd, l)); + while (l-- > 0) { + curChar = *s++; + + SYS_ARCH_PROTECT(lev); + escaped = ESCAPE_P(pcrx->inACCM, curChar); + SYS_ARCH_UNPROTECT(lev); + /* Handle special characters. */ + if (escaped) { + /* Check for escape sequences. */ + /* XXX Note that this does not handle an escaped 0x5d character which + * would appear as an escape character. Since this is an ASCII ']' + * and there is no reason that I know of to escape it, I won't complicate + * the code to handle this case. GLL */ + if (curChar == PPP_ESCAPE) { + pcrx->inEscaped = 1; + /* Check for the flag character. */ + } else if (curChar == PPP_FLAG) { + /* If this is just an extra flag character, ignore it. */ + if (pcrx->inState <= PDADDRESS) { + /* ignore it */; + /* If we haven't received the packet header, drop what has come in. */ + } else if (pcrx->inState < PDDATA) { + PPPDEBUG(LOG_WARNING, + ("pppInProc[%d]: Dropping incomplete packet %d\n", + pcrx->pd, pcrx->inState)); + LINK_STATS_INC(link.lenerr); + pppDrop(pcrx); + /* If the fcs is invalid, drop the packet. */ + } else if (pcrx->inFCS != PPP_GOODFCS) { + PPPDEBUG(LOG_INFO, + ("pppInProc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", + pcrx->pd, pcrx->inFCS, pcrx->inProtocol)); + /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ + LINK_STATS_INC(link.chkerr); + pppDrop(pcrx); + /* Otherwise it's a good packet so pass it on. */ + } else { + struct pbuf *inp; + /* Trim off the checksum. */ + if(pcrx->inTail->len > 2) { + pcrx->inTail->len -= 2; + + pcrx->inTail->tot_len = pcrx->inTail->len; + if (pcrx->inTail != pcrx->inHead) { + pbuf_cat(pcrx->inHead, pcrx->inTail); + } + } else { + pcrx->inTail->tot_len = pcrx->inTail->len; + if (pcrx->inTail != pcrx->inHead) { + pbuf_cat(pcrx->inHead, pcrx->inTail); + } + + pbuf_realloc(pcrx->inHead, pcrx->inHead->tot_len - 2); + } + + /* Dispatch the packet thereby consuming it. */ + inp = pcrx->inHead; + /* Packet consumed, release our references. */ + pcrx->inHead = NULL; + pcrx->inTail = NULL; +#if PPP_INPROC_MULTITHREADED + if(tcpip_callback_with_block(ppp_input, inp, 0) != ERR_OK) { + PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); + pbuf_free(inp); + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); + } +#else /* PPP_INPROC_MULTITHREADED */ + ppp_input(inp); +#endif /* PPP_INPROC_MULTITHREADED */ + } + + /* Prepare for a new packet. */ + pcrx->inFCS = PPP_INITFCS; + pcrx->inState = PDADDRESS; + pcrx->inEscaped = 0; + /* Other characters are usually control characters that may have + * been inserted by the physical layer so here we just drop them. */ + } else { + PPPDEBUG(LOG_WARNING, + ("pppInProc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, curChar)); + } + /* Process other characters. */ + } else { + /* Unencode escaped characters. */ + if (pcrx->inEscaped) { + pcrx->inEscaped = 0; + curChar ^= PPP_TRANS; + } + + /* Process character relative to current state. */ + switch(pcrx->inState) { + case PDIDLE: /* Idle state - waiting. */ + /* Drop the character if it's not 0xff + * we would have processed a flag character above. */ + if (curChar != PPP_ALLSTATIONS) { + break; + } + + /* Fall through */ + case PDSTART: /* Process start flag. */ + /* Prepare for a new packet. */ + pcrx->inFCS = PPP_INITFCS; + + /* Fall through */ + case PDADDRESS: /* Process address field. */ + if (curChar == PPP_ALLSTATIONS) { + pcrx->inState = PDCONTROL; + break; + } + /* Else assume compressed address and control fields so + * fall through to get the protocol... */ + case PDCONTROL: /* Process control field. */ + /* If we don't get a valid control code, restart. */ + if (curChar == PPP_UI) { + pcrx->inState = PDPROTOCOL1; + break; + } +#if 0 + else { + PPPDEBUG(LOG_WARNING, + ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar)); + pcrx->inState = PDSTART; + } +#endif + case PDPROTOCOL1: /* Process protocol field 1. */ + /* If the lower bit is set, this is the end of the protocol + * field. */ + if (curChar & 1) { + pcrx->inProtocol = curChar; + pcrx->inState = PDDATA; + } else { + pcrx->inProtocol = (u_int)curChar << 8; + pcrx->inState = PDPROTOCOL2; + } + break; + case PDPROTOCOL2: /* Process protocol field 2. */ + pcrx->inProtocol |= curChar; + pcrx->inState = PDDATA; + break; + case PDDATA: /* Process data byte. */ + /* Make space to receive processed data. */ + if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) { + if (pcrx->inTail != NULL) { + pcrx->inTail->tot_len = pcrx->inTail->len; + if (pcrx->inTail != pcrx->inHead) { + pbuf_cat(pcrx->inHead, pcrx->inTail); + /* give up the inTail reference now */ + pcrx->inTail = NULL; + } + } + /* If we haven't started a packet, we need a packet header. */ + nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (nextNBuf == NULL) { + /* No free buffers. Drop the input packet and let the + * higher layers deal with it. Continue processing + * the received pbuf chain in case a new packet starts. */ + PPPDEBUG(LOG_ERR, ("pppInProc[%d]: NO FREE MBUFS!\n", pcrx->pd)); + LINK_STATS_INC(link.memerr); + pppDrop(pcrx); + pcrx->inState = PDSTART; /* Wait for flag sequence. */ + break; + } + if (pcrx->inHead == NULL) { + struct pppInputHeader *pih = nextNBuf->payload; + + pih->unit = pcrx->pd; + pih->proto = pcrx->inProtocol; + + nextNBuf->len += sizeof(*pih); + + pcrx->inHead = nextNBuf; + } + pcrx->inTail = nextNBuf; + } + /* Load character into buffer. */ + ((u_char*)pcrx->inTail->payload)[pcrx->inTail->len++] = curChar; + break; + } + + /* update the frame check sequence number. */ + pcrx->inFCS = PPP_FCS(pcrx->inFCS, curChar); + } + } /* while (l-- > 0), all bytes processed */ + + magic_randomize(); +} +#endif /* PPPOS_SUPPORT */ + /* merge a pbuf chain into one pbuf */ struct pbuf * ppp_singlebuf(struct pbuf *p) { struct pbuf *q, *b; @@ -1115,6 +1823,104 @@ struct pbuf * ppp_singlebuf(struct pbuf *p) { return q; } +#if PPPOE_SUPPORT +void pppOverEthernetInitFailed(int pd) { + PPPControl* pc; + + pppHup(pd); + pppStop(pd); + + pc = &pppControl[pd]; + pppoe_destroy(&pc->netif); + pc->openFlag = 0; + + if(pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + } +} + +static void ppp_over_ethernet_link_status_cb(int pd, int up) { + if(up) { + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: Connecting\n", pd)); + ppp_start(pd); + } else { + pppOverEthernetInitFailed(pd); + } +} +#endif /* PPPOE_SUPPORT */ + +void pppLinkDown(int pd) { + PPPDEBUG(LOG_DEBUG, ("pppLinkDown: unit %d\n", pd)); + +#if PPPOE_SUPPORT + if (pppControl[pd].ethif) { + pppoe_disconnect(pppControl[pd].pppoe_sc); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD + pppRecvWakeup(pd); +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ + } +} + +void pppLinkTerminated(int pd) { + PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d\n", pd)); + +#if PPPOE_SUPPORT + if (pppControl[pd].ethif) { + pppoe_disconnect(pppControl[pd].pppoe_sc); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT + PPPControl* pc; +#if PPP_INPROC_OWNTHREAD + pppRecvWakeup(pd); +#endif /* PPP_INPROC_OWNTHREAD */ + pc = &pppControl[pd]; + + PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); + if (pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + } + + pc->openFlag = 0;/**/ +#endif /* PPPOS_SUPPORT */ + } + PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: finished.\n")); +} + + +#if LWIP_NETIF_STATUS_CALLBACK +/** Set the status callback of a PPP's netif + * + * @param pd The PPP descriptor returned by pppOpen() + * @param status_callback pointer to the status callback function + * + * @see netif_set_status_callback + */ +void +ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback) +{ + netif_set_status_callback(&pppControl[pd].netif, status_callback); +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +/** Set the link callback of a PPP's netif + * + * @param pd The PPP descriptor returned by pppOpen() + * @param link_callback pointer to the link callback function + * + * @see netif_set_link_callback + */ +void +ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback) +{ + netif_set_link_callback(&pppControl[pd].netif, link_callback); +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ /************************************************************************ * Functions called by various PPP subsystems to configure @@ -1137,19 +1943,30 @@ void new_phase(int p) { */ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { PPPControl *pc = &pppControl[unit]; +#if PPPOS_SUPPORT int i; +#endif /* PPPOS_SUPPORT */ pc->mtu = mtu; pc->pcomp = pcomp; pc->accomp = accomp; +#if PPPOS_SUPPORT /* Load the ACCM bits for the 32 control codes. */ for (i = 0; i < 32/8; i++) { pc->outACCM[i] = (u_char)((accm >> (8 * i)) & 0xFF); } +#else + LWIP_UNUSED_ARG(accm); +#endif /* PPPOS_SUPPORT */ + +#if PPPOS_SUPPORT PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", unit, pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); +#else + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", unit) ); +#endif /* PPPOS_SUPPORT */ return 0; } @@ -1158,24 +1975,35 @@ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { * the ppp interface. */ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { +#if PPPOS_SUPPORT PPPControl *pc = &pppControl[unit]; int i; SYS_ARCH_DECL_PROTECT(lev); +#endif /* PPPOS_SUPPORT */ LWIP_UNUSED_ARG(accomp); LWIP_UNUSED_ARG(pcomp); LWIP_UNUSED_ARG(mru); /* Load the ACCM bits for the 32 control codes. */ +#if PPPOS_SUPPORT SYS_ARCH_PROTECT(lev); for (i = 0; i < 32 / 8; i++) { /* @todo: does this work? ext_accm has been modified from pppd! */ pc->rx.inACCM[i] = (u_char)(accm >> (i * 8)); } SYS_ARCH_UNPROTECT(lev); +#else + LWIP_UNUSED_ARG(accm); +#endif /* PPPOS_SUPPORT */ + +#if PPPOS_SUPPORT PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", unit, pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); +#else + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", unit) ); +#endif /* PPPOS_SUPPORT */ return 0; } @@ -1208,9 +2036,23 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */ -int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { - /* FIXME: do the code which clear a IP on a PPP interface */ - return 0; +int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr) { + PPPControl *pc = &pppControl[unit]; + int st = 1; + + LWIP_UNUSED_ARG(our_adr); + LWIP_UNUSED_ARG(his_adr); + if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad parms\n", unit)); + } else { + IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); + IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); + IP4_ADDR(&pc->addrs.netmask, 255,255,255,0); + IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); + IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); + } + return st; } /* @@ -1250,9 +2092,24 @@ int sifup(int u) * sifdown - Disable the indicated protocol and config the interface * down if there are no remaining protocols. */ -int sifdown (int u) { - /* FIXME: do the code which shutdown a PPP interface */ - return 1; +int sifdown(int unit) { + PPPControl *pc = &pppControl[unit]; + int st = 1; + + if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", unit)); + } else { + pc->if_up = 0; + /* make sure the netif status callback is called */ + netif_set_down(&pc->netif); + netif_remove(&pc->netif); + PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: linkStatusCB=%p errCode=%d\n", unit, pc->linkStatusCB, pc->errCode)); + if (pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL); + } + } + return st; } /* @@ -1291,20 +2148,46 @@ int netif_get_mtu(int mtu) { * and then changes the temporary addresses to the addresses for the real * ppp connection when it has come up. */ +int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { + PPPControl *pc = &pppControl[unit]; + int st = 1; -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { - /* FIXME: do the code which add the default route */ - return 0; + LWIP_UNUSED_ARG(ouraddr); + LWIP_UNUSED_ARG(gateway); + /* FIXME: handle replace condition */ + LWIP_UNUSED_ARG(replace); + + if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); + } else { + netif_set_default(&pc->netif); + } + + /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */ + + return st; } /******************************************************************** * * cifdefaultroute - delete a default route through the address given. */ +int cifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway) { + PPPControl *pc = &pppControl[unit]; + int st = 1; -int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { - /* FIXME: do the code which remove the default route */ - return 0; + LWIP_UNUSED_ARG(ouraddr); + LWIP_UNUSED_ARG(gateway); + + if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); + } else { + netif_set_default(NULL); + } + + return st; } /******************************************************************** @@ -1312,7 +2195,7 @@ int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { * sifproxyarp - Make a proxy ARP entry for the peer. */ -int sifproxyarp (int unit, u_int32_t his_adr) { +int sifproxyarp(int unit, u_int32_t his_adr) { /* FIXME: do we really need that in IPCP ? */ return 0; } @@ -1322,7 +2205,7 @@ int sifproxyarp (int unit, u_int32_t his_adr) { * cifproxyarp - Delete the proxy ARP entry for the peer. */ -int cifproxyarp (int unit, u_int32_t his_adr) { +int cifproxyarp(int unit, u_int32_t his_adr) { /* FIXME: do we really need that in IPCP ? */ return 0; } @@ -1331,9 +2214,23 @@ int cifproxyarp (int unit, u_int32_t his_adr) { * * sifvjcomp - config tcp header compression */ -int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) { - /* FIXME: add VJ support */ - return 1; +int sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid) { +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPControl *pc = &pppControl[u]; + + pc->vjEnabled = vjcomp; + pc->vjComp.compressSlot = cidcomp; + pc->vjComp.maxSlotIndex = maxcid; + PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", + vjcomp, cidcomp, maxcid)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(vjcomp); + LWIP_UNUSED_ARG(cidcomp); + LWIP_UNUSED_ARG(maxcid); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + return 0; } /******************************************************************** @@ -1342,6 +2239,8 @@ int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) { */ int get_idle_time(int u, struct ppp_idle *ip) { /* FIXME: add idle time support and make it optional */ + LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(ip); return 1; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index c9de3032..a84efbaa 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -1,9 +1,35 @@ -/* - * ppp.h - * - * Created on: May 12, 2012 - * Author: gradator - */ +/***************************************************************************** +* ppp.h - Network Point to Point Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ @@ -38,6 +64,7 @@ typedef unsigned char bool; #include "lwip/netif.h" #include "lwip/def.h" #include "lwip/timers.h" +#include "lwip/sio.h" #include "pppdebug.h" @@ -147,7 +174,7 @@ typedef unsigned short u_int16_t; /* * Extended asyncmap - allows any character to be escaped. */ -typedef u_int32_t ext_accm[8]; +typedef u_char ext_accm[32]; /* * What to do with network protocol (NP) packets. @@ -407,6 +434,18 @@ extern struct protent *protocols[]; #define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */ #define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */ +/* + * PPP IOCTL commands. + */ +/* + * Get the up status - 0 for down, non-zero for up. The argument must + * point to an int. + */ +#define PPPCTLG_UPSTATUS 100 /* Get the up status - 0 down else up */ +#define PPPCTLS_ERRCODE 101 /* Set the error code */ +#define PPPCTLG_ERRCODE 102 /* Get the error code */ +#define PPPCTLG_FD 103 /* Get the fd associated with the ppp */ + /************************ *** PUBLIC DATA TYPES *** ************************/ @@ -503,11 +542,62 @@ void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passw /* Link status callback function prototype */ typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); +#if PPPOS_SUPPORT + +/* + * Open a new PPP connection using the given serial I/O device. + * This initializes the PPP control block but does not + * attempt to negotiate the LCP session. + * + * If this port connects to a modem, the modem connection must be + * established before calling this. + * + * Return a new PPP connection descriptor on success or + * an error code (negative) on failure. + */ +int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); + +#if !PPP_INPROC_OWNTHREAD +/* + * PPP over Serial: this is the input function to be called for received data. + * If PPP_INPROC_OWNTHREAD==1, a separate input thread using the blocking + * sio_read() is used, so this is deactivated. + */ +void pppos_input(int pd, u_char* data, int len); +#endif /* !PPP_INPROC_OWNTHREAD */ + +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT /* * Open a new PPP Over Ethernet (PPPOE) connection. */ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); +#endif /* PPPOE_SUPPORT */ + +/* + * Close a PPP connection and release the descriptor. + * Any outstanding packets in the queues are dropped. + * Return 0 on success, an error code on failure. + */ +int pppClose(int pd); + +/* + * Indicate to the PPP process that the line has disconnected. + */ +void pppSigHUP(int pd); + +#if LWIP_NETIF_STATUS_CALLBACK +/* Set an lwIP-style status-callback for the selected PPP device */ +void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +/* Set an lwIP-style link-callback for the selected PPP device */ +void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + @@ -517,18 +607,24 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const /* PPP flow functions */ -void pppOverEthernetInitFailed(int pd); - -u_short pppMTU(int pd); - #if PPPOE_SUPPORT +void pppOverEthernetInitFailed(int pd); /* function called by pppoe.c */ void ppp_input_over_ethernet(int pd, struct pbuf *pb); #endif /* PPPOE_SUPPORT */ +int pppIOCtl(int pd, int cmd, void *arg); + +/* FIXME: demystify MTU support */ +u_short pppMTU(int pd); + /* function called by all PPP subsystems to send packets */ int ppp_write(int pd, const u_char *s, int n); +/* functions called by auth.c link_terminated() */ +void pppLinkDown(int pd); +void pppLinkTerminated(int pd); + /* merge a pbuf chain into one pbuf */ struct pbuf * ppp_singlebuf(struct pbuf *p); @@ -538,6 +634,9 @@ struct pbuf * ppp_singlebuf(struct pbuf *p); */ void new_phase(int p); +#if PPPOS_SUPPORT +void ppp_set_xaccm(int unit, ext_accm *accm); +#endif /* PPPOS_SUPPORT */ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp); int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp); From 3bad9ff50ad9ad982e37138fba76f0a388b87139 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 20:25:32 +0200 Subject: [PATCH 095/320] ppp_impl.h is back! --- src/netif/ppp/auth.c | 2 +- src/netif/ppp/ccp.c | 2 +- src/netif/ppp/chap-md5.c | 2 +- src/netif/ppp/chap-new.c | 2 +- src/netif/ppp/chap_ms.c | 2 +- src/netif/ppp/demand.c | 2 +- src/netif/ppp/eap.c | 2 +- src/netif/ppp/ecp.c | 2 +- src/netif/ppp/fsm.c | 2 +- src/netif/ppp/ipcp.c | 2 +- src/netif/ppp/lcp.c | 2 +- src/netif/ppp/magic.c | 2 +- src/netif/ppp/multilink.c | 2 +- src/netif/ppp/options.c | 2 +- src/netif/ppp/ppp.c | 2 +- src/netif/ppp/ppp.h | 741 +++----------------------------------- src/netif/ppp/ppp_impl.h | 706 ++++++++++++++++++++++++++++++++++++ src/netif/ppp/ppp_oe.c | 2 +- src/netif/ppp/pppcrypt.c | 2 +- src/netif/ppp/upap.c | 2 +- src/netif/ppp/utils.c | 2 +- 21 files changed, 776 insertions(+), 709 deletions(-) create mode 100644 src/netif/ppp/ppp_impl.h diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index cdb067df..df0d4de7 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -103,7 +103,7 @@ #include #endif /* UNUSED */ -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "lcp.h" diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 47b1027b..293c39e8 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -34,7 +34,7 @@ #include #include -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "ccp.h" diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 3f6734e1..45750308 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -36,7 +36,7 @@ #include #endif /* UNUSED */ -#include "ppp.h" +#include "ppp_impl.h" #include "chap-new.h" #include "chap-md5.h" diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 7c0b1c1a..fbeacabf 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -36,7 +36,7 @@ #include #endif /* UNUSED */ -#include "ppp.h" +#include "ppp_impl.h" #if 0 /* UNUSED */ #include "session.h" diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index e70c28fc..a5caa54b 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -87,7 +87,7 @@ #include #endif /* UNUSED */ -#include "ppp.h" +#include "ppp_impl.h" #include "chap-new.h" #include "chap_ms.h" diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index b2f146d6..5ef93755 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -52,7 +52,7 @@ #include #endif -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "ipcp.h" diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 737f5411..e1b4f103 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -46,7 +46,7 @@ #include "lwip/opt.h" #if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "polarssl/md5.h" #include "eap.h" diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index a355c48a..90f3ee20 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -62,7 +62,7 @@ #include -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "ecp.h" diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 585ec8e7..4a31a904 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -55,7 +55,7 @@ #include #endif /* UNUSED */ -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 8106ffa1..330de3f3 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -59,7 +59,7 @@ #include #endif /* UNUSED */ -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "ipcp.h" diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index c8d12455..5212d934 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -53,7 +53,7 @@ #include #endif /* UNUSED */ -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "lcp.h" diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 73377cf7..e945f26a 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -75,7 +75,7 @@ #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "polarssl/md5.h" #include "magic.h" diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 4c7ae95e..0ca3309c 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -49,7 +49,7 @@ #include #include -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "lcp.h" diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index eb718f09..b4d334f7 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -75,7 +75,7 @@ #endif #endif /* PPP_FILTER */ -#include "ppp.h" +#include "ppp_impl.h" #if defined(ultrix) || defined(NeXT) char *strdup __P((char *)); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 2be4388f..c5c35cf0 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -91,7 +91,7 @@ #include "lwip/sio.h" #include "lwip/ip.h" /* for ip_input() */ -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "lcp.h" diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index a84efbaa..17fd91ee 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -7,13 +7,13 @@ * The authors hereby grant permission to use, copy, modify, distribute, * and license this software and its documentation for any purpose, provided * that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any +* notice and the following disclaimer are included verbatim in any * distributions. No written agreement, license, or royalty fee is required * for any of the authorized uses. * * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, @@ -34,390 +34,28 @@ #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#ifndef PPPMY_H_ -#define PPPMY_H_ +#ifndef PPP_H +#define PPP_H -#include /* formats */ - -#if defined(__STDC__) -#include -#define __V(x) x -#else -#include -#define __V(x) (va_alist) va_dcl -#define const -#define volatile -#endif - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - -#ifndef bool -typedef unsigned char bool; -#endif - -#include "lwip/netif.h" #include "lwip/def.h" -#include "lwip/timers.h" #include "lwip/sio.h" +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/netif.h" +#include "lwip/sys.h" +#include "lwip/timers.h" -#include "pppdebug.h" -#ifdef INET6 -#include "eui64.h" +#ifndef __u_char_defined + +/* Type definitions for BSD code. */ +typedef unsigned long u_long; +typedef unsigned int u_int; +typedef unsigned short u_short; +typedef unsigned char u_char; + #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 */ - - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - -#define PPP_ADDRESS(p) (((u_char *)(p))[0]) -#define PPP_CONTROL(p) (((u_char *)(p))[1]) -#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#if 0 /* UNUSED */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_IPX 0x2b /* IPX protocol */ -#endif /* UNUSED */ -#if VJ_SUPPORT -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#endif /* VJ_SUPPORT */ -#ifdef INET6 -#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ -#endif /* INET6 */ -#if CCP_SUPPORT -#define PPP_COMP 0xfd /* compressed packet */ -#endif /* CCP_SUPPORT */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#if 0 /* UNUSED */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_IPXCP 0x802b /* IPX Control Protocol */ -#endif /* UNUSED */ -#ifdef INET6 -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#endif /* INET6 */ -#if CCP_SUPPORT -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT -#define PPP_ECP 0x8053 /* Encryption Control Protocol */ -#endif /* ECP_SUPPORT */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#if PAP_SUPPORT -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#endif /* LQR_SUPPORT */ -#if CHAP_SUPPORT -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#endif /* CHAP_SUPPORT */ -#if CBCP_SUPPORT -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ -#endif /* CBCP_SUPPORT */ -#if EAP_SUPPORT -#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ -#endif /* EAP_SUPPORT */ - -/* - * Values for FCS calculations. - */ -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) - -/* - * A 32-bit unsigned integral type. - */ - -#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \ - && !defined(__FreeBSD__) && (NS_TARGET < 40) -#ifdef UINT32_T -typedef UINT32_T u_int32_t; -#else -typedef unsigned int u_int32_t; -typedef unsigned short u_int16_t; -#endif -#endif - -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u_char ext_accm[32]; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Statistics. - */ -#if PPP_STATS_SUPPORT -struct pppstat { - unsigned int ppp_ibytes; /* bytes received */ - unsigned int ppp_ipackets; /* packets received */ - unsigned int ppp_ierrors; /* receive errors */ - unsigned int ppp_obytes; /* bytes sent */ - unsigned int ppp_opackets; /* packets sent */ - unsigned int ppp_oerrors; /* transmit errors */ -}; - -#if VJ_SUPPORT -struct vjstat { - unsigned int vjs_packets; /* outbound packets */ - unsigned int vjs_compressed; /* outbound compressed packets */ - unsigned int vjs_searches; /* searches for connection state */ - unsigned int vjs_misses; /* times couldn't find conn. state */ - unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ - unsigned int vjs_compressedin; /* inbound compressed packets */ - unsigned int vjs_errorin; /* inbound unknown type packets */ - unsigned int vjs_tossed; /* inbound packets tossed because of error */ -}; -#endif /* VJ_SUPPORT */ - -struct ppp_stats { - struct pppstat p; /* basic PPP statistics */ -#if VJ_SUPPORT - struct vjstat vj; /* VJ header compression statistics */ -#endif /* VJ_SUPPORT */ -}; - -#if CCP_SUPPORT -struct compstat { - unsigned int unc_bytes; /* total uncompressed bytes */ - unsigned int unc_packets; /* total uncompressed packets */ - unsigned int comp_bytes; /* compressed bytes */ - unsigned int comp_packets; /* compressed packets */ - unsigned int inc_bytes; /* incompressible bytes */ - unsigned int inc_packets; /* incompressible packets */ - unsigned int ratio; /* recent compression ratio << 8 */ -}; - -struct ppp_comp_stats { - struct compstat c; /* packet compression statistics */ - struct compstat d; /* packet decompression statistics */ -}; -#endif /* CCP_SUPPORT */ - -#endif /* PPP_STATS_SUPPORT */ - -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -/* FIXME: add idle time support and make it optional */ -struct ppp_idle { - time_t xmit_idle; /* time since last NP packet sent */ - time_t recv_idle; /* time since last NP packet received */ -}; - -/* FIXME: make endpoint discriminator optional */ - -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class; - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; - -/* values for epdisc.class */ -#define EPD_NULL 0 /* null discriminator, no data */ -#define EPD_LOCAL 1 -#define EPD_IP 2 -#define EPD_MAC 3 -#define EPD_MAGIC 4 -#define EPD_PHONENUM 5 - -/* FIXME: global variables per PPP session */ - -/* - * Global variables. - */ -/* FIXME: improve debug flag */ -extern int debug; /* Debug flag */ - -/* FIXME: is our_name really necessary ? */ -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 */ - -/* FIXME: make it a compile time option */ -extern int idle_time_limit;/* Shut down link if idle for this long */ - -extern int phase; /* Current state of link - see values below */ -extern int error_count; /* # of times error() has been called */ -extern int unsuccess; /* # unsuccessful connection attempts */ -extern int listen_time; /* time to listen first (ms) */ -extern int status; /* exit status for pppd */ -extern int need_holdoff; /* Need holdoff period after link terminates */ -/* FIXME: remove ifunit */ -extern int ifunit; /* Interface unit number */ -extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ - -/* FIXME: add more HAVE_MULTILINK */ -extern bool multilink; /* enable multilink operation */ - -/* FIXME: it is really necessary ? */ -extern int maxconnect; /* Maximum connect time (seconds) */ - -#ifdef HAVE_MULTILINK -extern bool doing_multilink; -extern bool multilink_master; -extern bool bundle_eof; -extern bool bundle_terminating; -#endif - -#ifdef MAXOCTETS -extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ -extern int maxoctets_dir; /* Direction : - 0 - in+out (default) - 1 - in - 2 - out - 3 - max(in,out) */ -extern int maxoctets_timeout; /* Timeout for check of octets limit */ -#define PPP_OCTETS_DIRECTION_SUM 0 -#define PPP_OCTETS_DIRECTION_IN 1 -#define PPP_OCTETS_DIRECTION_OUT 2 -#define PPP_OCTETS_DIRECTION_MAXOVERAL 3 -/* same as previos, but little different on RADIUS side */ -#define PPP_OCTETS_DIRECTION_MAXSESSION 4 -#endif - -/* - * 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) __P((int unit)); - /* Process a received packet */ - void (*input) __P((int unit, u_char *pkt, int len)); - /* Process a received protocol-reject */ - void (*protrej) __P((int unit)); - /* Lower layer has come up */ - void (*lowerup) __P((int unit)); - /* Lower layer has gone down */ - void (*lowerdown) __P((int unit)); - /* Open the protocol */ - void (*open) __P((int unit)); - /* Close the protocol */ - void (*close) __P((int unit, char *reason)); -#if PRINTPKT_SUPPORT - /* Print a packet in readable form */ - int (*printpkt) __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); -#endif /* PRINTPKT_SUPPORT */ - /* FIXME: data input is only used by CCP, which is not supported at this time, - * should we remove this entry and save some flash ? - */ - /* Process a received data packet */ - void (*datainput) __P((int unit, u_char *pkt, int len)); - bool enabled_flag; /* 0 iff protocol is disabled */ -#if PRINTPKT_SUPPORT - char *name; /* Text name of protocol */ - char *data_name; /* Text name of corresponding data protocol */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - option_t *options; /* List of command-line options */ - /* Check requested options, assign defaults */ - void (*check_options) __P((void)); -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - /* Configure interface for demand-dial */ - int (*demand_conf) __P((int unit)); - /* Say whether to bring up link for this pkt */ - int (*active_pkt) __P((u_char *pkt, int len)); -#endif /* DEMAND_SUPPORT */ -}; - -/* Table of pointers to supported protocols */ -extern struct protent *protocols[]; - - -/* Values for auth_pending, auth_done */ -#if PAP_SUPPORT -#define PAP_WITHPEER 0x1 -#define PAP_PEER 0x2 -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#define CHAP_WITHPEER 0x4 -#define CHAP_PEER 0x8 -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#define EAP_WITHPEER 0x10 -#define EAP_PEER 0x20 -#endif /* EAP_SUPPORT */ - -/* Values for auth_done only */ -#if CHAP_SUPPORT -#define CHAP_MD5_WITHPEER 0x40 -#define CHAP_MD5_PEER 0x80 -#if MSCHAP_SUPPORT -#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ -#define CHAP_MS_WITHPEER 0x100 -#define CHAP_MS_PEER 0x200 -#define CHAP_MS2_WITHPEER 0x400 -#define CHAP_MS2_PEER 0x800 -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ - -/* - * 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 -#define PHASE_MASTER 12 - /************************* *** PUBLIC DEFINITIONS *** @@ -454,58 +92,14 @@ struct ppp_addrs { ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; }; -#if PPP_STATS_SUPPORT -/* - * PPP statistics structure - */ -struct pppd_stats { - unsigned int bytes_in; - unsigned int bytes_out; - unsigned int pkts_in; - unsigned int pkts_out; -}; -#endif /* PPP_STATS_SUPPORT */ - -/* FIXME: use PPP option instead ? */ - -struct ppp_settings { - - u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ - u_int auth_required : 1; /* Peer is required to authenticate */ - u_int explicit_remote : 1; /* remote_name specified with remotename opt */ -#if PAP_SUPPORT - u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ -#endif /* CHAP_SUPPORT */ -#if MSCHAP_SUPPORT - u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ - u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ -#endif /* MSCHAP_SUPPORT */ -#if EAP_SUPPORT - u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ -#endif /* EAP_SUPPORT */ - u_int usehostname : 1; /* Use hostname for our_name */ - u_int usepeerdns : 1; /* Ask peer for DNS adds */ - - u_short idle_time_limit; /* Shut down link if idle for this long */ - int maxconnect; /* Maximum connect time (seconds) */ - - char user [MAXNAMELEN + 1]; /* Username for PAP */ - char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ - char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ - /* FIXME: re-enable that */ - /* char remote_name[MAXNAMELEN + 1]; */ /* Peer's name for authentication */ -}; - -struct ppp_settings ppp_settings; - /************************ *** PUBLIC FUNCTIONS *** ************************/ +/* Initialize the PPP subsystem. */ +int ppp_init(void); + /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. * RFC 1994 says: * @@ -529,21 +123,19 @@ enum pppAuthType { #if CHAP_SUPPORT PPPAUTHTYPE_CHAP, #endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT PPPAUTHTYPE_PAP, +#endif /* PAP_SUPPORT */ PPPAUTHTYPE_ANY, PPPAUTHTYPE_NONE }; -/* Initialize the PPP subsystem. */ -int ppp_init(void); - void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passwd); /* Link status callback function prototype */ typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); #if PPPOS_SUPPORT - /* * Open a new PPP connection using the given serial I/O device. * This initializes the PPP control block but does not @@ -556,30 +148,23 @@ typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); * an error code (negative) on failure. */ int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); - -#if !PPP_INPROC_OWNTHREAD -/* - * PPP over Serial: this is the input function to be called for received data. - * If PPP_INPROC_OWNTHREAD==1, a separate input thread using the blocking - * sio_read() is used, so this is deactivated. - */ -void pppos_input(int pd, u_char* data, int len); -#endif /* !PPP_INPROC_OWNTHREAD */ - #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT /* - * Open a new PPP Over Ethernet (PPPOE) connection. + * Open a new PPP Over Ethernet (PPPoE) connection. */ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); #endif /* PPPOE_SUPPORT */ +/* for source code compatibility */ +#define pppOpen(fd,cb,ls) pppOverSerialOpen(fd,cb,ls) + /* - * Close a PPP connection and release the descriptor. + * Close a PPP connection and release the descriptor. * Any outstanding packets in the queues are dropped. - * Return 0 on success, an error code on failure. + * Return 0 on success, an error code on failure. */ int pppClose(int pd); @@ -588,261 +173,37 @@ int pppClose(int pd); */ void pppSigHUP(int pd); +/* + * Get and set parameters for the given connection. + * Return 0 on success, an error code on failure. + */ +int pppIOCtl(int pd, int cmd, void *arg); + +/* + * Return the Maximum Transmission Unit for the given PPP connection. + */ +/* FIXME: demystify MTU support */ +u_short pppMTU(int pd); + +#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD +/* + * PPP over Serial: this is the input function to be called for received data. + * If PPP_INPROC_OWNTHREAD==1, a seperate input thread using the blocking + * sio_read() is used, so this is deactivated. + */ +void pppos_input(int pd, u_char* data, int len); +#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ + + #if LWIP_NETIF_STATUS_CALLBACK /* Set an lwIP-style status-callback for the selected PPP device */ void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback); #endif /* LWIP_NETIF_STATUS_CALLBACK */ - #if LWIP_NETIF_LINK_CALLBACK /* Set an lwIP-style link-callback for the selected PPP device */ void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback); #endif /* LWIP_NETIF_LINK_CALLBACK */ - - - -/* ------------------------------------------------------ * - * --- EVERYTHING BELOW SHOULD BE CONSIDERED PRIVATE ---- * - * ------------------------------------------------------ */ - -/* PPP flow functions - */ -#if PPPOE_SUPPORT -void pppOverEthernetInitFailed(int pd); -/* function called by pppoe.c */ -void ppp_input_over_ethernet(int pd, struct pbuf *pb); -#endif /* PPPOE_SUPPORT */ - -int pppIOCtl(int pd, int cmd, void *arg); - -/* FIXME: demystify MTU support */ -u_short pppMTU(int pd); - -/* function called by all PPP subsystems to send packets */ -int ppp_write(int pd, const u_char *s, int n); - -/* functions called by auth.c link_terminated() */ -void pppLinkDown(int pd); -void pppLinkTerminated(int pd); - -/* merge a pbuf chain into one pbuf */ -struct pbuf * ppp_singlebuf(struct pbuf *p); - - -/* Functions called by various PPP subsystems to configure - * the PPP interface or change the PPP phase. - */ -void new_phase(int p); - -#if PPPOS_SUPPORT -void ppp_set_xaccm(int unit, ext_accm *accm); -#endif /* PPPOS_SUPPORT */ -int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp); -int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp); - -int sifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); -int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr); - -int sifup(int u); -int sifdown (int u); - -int sifnpmode(int u, int proto, enum NPmode mode); - -void netif_set_mtu(int unit, int mtu); -int netif_get_mtu(int mtu); - -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace); -int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway); - -int sifproxyarp (int unit, u_int32_t his_adr); -int cifproxyarp (int unit, u_int32_t his_adr); - -int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid); - -int get_idle_time(int u, struct ppp_idle *ip); - -int get_loop_output(void); - -u_int32_t GetMask (u_int32_t addr); - - -/* Optional protocol names list, to make our messages a little more informative. */ -#if PPP_PROTOCOLNAME -const char * protocol_name(int proto); -#endif /* PPP_PROTOCOLNAME */ - - -/* Optional stats support, to get some statistics on the PPP interface */ -#if PPP_STATS_SUPPORT -void print_link_stats(void); /* Print stats, if available */ -void reset_link_stats(int u); /* Reset (init) stats when link goes up */ -void update_link_stats(int u); /* Get stats at link termination */ -#endif /* PPP_STATS_SUPPORT */ - - - -/* - * 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(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) -#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) -#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) - -#define BZERO(s, n) memset(s, 0, n) -#define BCMP(s1, s2, l) memcmp(s1, s2, l) - -#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 -#ifdef MAXOCTETS -#define EXIT_TRAFFIC_LIMIT 20 -#endif -#define EXIT_CNID_AUTH_FAILED 21 - -/* Procedures exported from auth.c */ -void link_required __P((int)); /* we are starting to use the link */ -void link_terminated __P((int)); /* we are finished with the link */ -void link_down __P((int)); /* the LCP layer has left the Opened state */ -void upper_layers_down __P((int));/* take all NCPs down */ -void link_established __P((int)); /* the link is up; authenticate now */ -void start_networks __P((int)); /* start all the network control protos */ -void continue_networks __P((int)); /* start network [ip, etc] control protos */ - -void auth_peer_fail __P((int, int)); - /* peer failed to authenticate itself */ -void auth_peer_success __P((int, int, int, char *, int)); - /* peer successfully authenticated itself */ -void auth_withpeer_fail __P((int, int)); - /* we failed to authenticate ourselves */ -void auth_withpeer_success __P((int, int, int)); - /* we successfully authenticated ourselves */ -void np_up __P((int, int)); /* a network protocol has come up */ -void np_down __P((int, int)); /* a network protocol has gone down */ -void np_finished __P((int, int)); /* a network protocol no longer needs link */ -void auth_reset __P((int)); /* check what secrets we have */ -int get_secret __P((int, char *, char *, char *, int *, int)); - /* get "secret" for chap */ - -/* Procedures exported from ipcp.c */ -/* int parse_dotted_ip __P((char *, u_int32_t *)); */ - -/* Procedures exported from demand.c */ -#if DEMAND_SUPPORT -void demand_conf __P((void)); /* config interface(s) for demand-dial */ -void demand_block __P((void)); /* set all NPs to queue up packets */ -void demand_unblock __P((void)); /* set all NPs to pass packets */ -void demand_discard __P((void)); /* set all NPs to discard packets */ -void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ -int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ -int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ -#endif /* DEMAND_SUPPORT */ - -/* Procedures exported from multilink.c */ -#ifdef HAVE_MULTILINK -void mp_check_options __P((void)); /* Check multilink-related options */ -int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ -void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */ -void mp_bundle_terminated __P((void)); -char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ -int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ -#else -#define mp_bundle_terminated() /* nothing */ -#define mp_exit_bundle() /* nothing */ -#define doing_multilink 0 -#define multilink_master 0 -#endif - -/* Procedures exported from utils.c. */ -void print_string __P((char *, int, void (*) (void *, char *, ...), - void *)); /* Format a string for output */ -int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ -int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ -size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ -size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ -void dbglog __P((char *, ...)); /* log a debug message */ -void info __P((char *, ...)); /* log an informational message */ -void notice __P((char *, ...)); /* log a notice-level message */ -void warn __P((char *, ...)); /* log a warning message */ -void error __P((char *, ...)); /* log an error message */ -void fatal __P((char *, ...)); /* log an error message and die(1) */ -void init_pr_log __P((const char *, int)); /* initialize for using pr_log */ -void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ -void end_pr_log __P((void)); /* finish up after using pr_log */ -#if PRINTPKT_SUPPORT -void dump_packet __P((const char *, u_char *, int)); - /* dump packet to debug log if interesting */ -#endif /* PRINTPKT_SUPPORT */ - - -#endif /* PPPMY_H_ */ +#endif /* PPP_H */ #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h new file mode 100644 index 00000000..da846727 --- /dev/null +++ b/src/netif/ppp/ppp_impl.h @@ -0,0 +1,706 @@ +/***************************************************************************** +* ppp.h - Network Point to Point Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPP_IMP_H_ +#define PPP_IMP_H_ + +#include /* formats */ + +#if defined(__STDC__) +#include +#define __V(x) x +#else +#include +#define __V(x) (va_alist) va_dcl +#define const +#define volatile +#endif + +#ifndef __P +#ifdef __STDC__ +#define __P(x) x +#else +#define __P(x) () +#endif +#endif + +#ifndef bool +typedef unsigned char bool; +#endif + +#include "lwip/netif.h" +#include "lwip/def.h" +#include "lwip/timers.h" +#include "lwip/sio.h" + +#include "ppp.h" +#include "pppdebug.h" + +#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 */ + + +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ + +#define PPP_ADDRESS(p) (((u_char *)(p))[0]) +#define PPP_CONTROL(p) (((u_char *)(p))[1]) +#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) + +/* + * Significant octet values. + */ +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_FLAG 0x7e /* Flag Sequence */ +#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ +#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* + * Protocol field values. + */ +#define PPP_IP 0x21 /* Internet Protocol */ +#if 0 /* UNUSED */ +#define PPP_AT 0x29 /* AppleTalk Protocol */ +#define PPP_IPX 0x2b /* IPX protocol */ +#endif /* UNUSED */ +#if VJ_SUPPORT +#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ +#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ +#endif /* VJ_SUPPORT */ +#ifdef INET6 +#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ +#endif /* INET6 */ +#if CCP_SUPPORT +#define PPP_COMP 0xfd /* compressed packet */ +#endif /* CCP_SUPPORT */ +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#if 0 /* UNUSED */ +#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ +#define PPP_IPXCP 0x802b /* IPX Control Protocol */ +#endif /* UNUSED */ +#ifdef INET6 +#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#endif /* INET6 */ +#if CCP_SUPPORT +#define PPP_CCP 0x80fd /* Compression Control Protocol */ +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT +#define PPP_ECP 0x8053 /* Encryption Control Protocol */ +#endif /* ECP_SUPPORT */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#if PAP_SUPPORT +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#endif /* PAP_SUPPORT */ +#if LQR_SUPPORT +#define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#endif /* LQR_SUPPORT */ +#if CHAP_SUPPORT +#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ +#endif /* CHAP_SUPPORT */ +#if CBCP_SUPPORT +#define PPP_CBCP 0xc029 /* Callback Control Protocol */ +#endif /* CBCP_SUPPORT */ +#if EAP_SUPPORT +#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ +#endif /* EAP_SUPPORT */ + +/* + * Values for FCS calculations. + */ +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +/* + * A 32-bit unsigned integral type. + */ + +#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \ + && !defined(__FreeBSD__) && (NS_TARGET < 40) +#ifdef UINT32_T +typedef UINT32_T u_int32_t; +#else +typedef unsigned int u_int32_t; +typedef unsigned short u_int16_t; +#endif +#endif + +/* + * Extended asyncmap - allows any character to be escaped. + */ +typedef u_char ext_accm[32]; + +/* + * What to do with network protocol (NP) packets. + */ +enum NPmode { + NPMODE_PASS, /* pass the packet through */ + NPMODE_DROP, /* silently drop the packet */ + NPMODE_ERROR, /* return an error */ + NPMODE_QUEUE /* save it up for later. */ +}; + +/* + * Statistics. + */ +#if PPP_STATS_SUPPORT +struct pppstat { + unsigned int ppp_ibytes; /* bytes received */ + unsigned int ppp_ipackets; /* packets received */ + unsigned int ppp_ierrors; /* receive errors */ + unsigned int ppp_obytes; /* bytes sent */ + unsigned int ppp_opackets; /* packets sent */ + unsigned int ppp_oerrors; /* transmit errors */ +}; + +#if VJ_SUPPORT +struct vjstat { + unsigned int vjs_packets; /* outbound packets */ + unsigned int vjs_compressed; /* outbound compressed packets */ + unsigned int vjs_searches; /* searches for connection state */ + unsigned int vjs_misses; /* times couldn't find conn. state */ + unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ + unsigned int vjs_compressedin; /* inbound compressed packets */ + unsigned int vjs_errorin; /* inbound unknown type packets */ + unsigned int vjs_tossed; /* inbound packets tossed because of error */ +}; +#endif /* VJ_SUPPORT */ + +struct ppp_stats { + struct pppstat p; /* basic PPP statistics */ +#if VJ_SUPPORT + struct vjstat vj; /* VJ header compression statistics */ +#endif /* VJ_SUPPORT */ +}; + +#if CCP_SUPPORT +struct compstat { + unsigned int unc_bytes; /* total uncompressed bytes */ + unsigned int unc_packets; /* total uncompressed packets */ + unsigned int comp_bytes; /* compressed bytes */ + unsigned int comp_packets; /* compressed packets */ + unsigned int inc_bytes; /* incompressible bytes */ + unsigned int inc_packets; /* incompressible packets */ + unsigned int ratio; /* recent compression ratio << 8 */ +}; + +struct ppp_comp_stats { + struct compstat c; /* packet compression statistics */ + struct compstat d; /* packet decompression statistics */ +}; +#endif /* CCP_SUPPORT */ + +#endif /* PPP_STATS_SUPPORT */ + +/* + * The following structure records the time in seconds since + * the last NP packet was sent or received. + */ +/* FIXME: add idle time support and make it optional */ +struct ppp_idle { + time_t xmit_idle; /* time since last NP packet sent */ + time_t recv_idle; /* time since last NP packet received */ +}; + +/* FIXME: make endpoint discriminator optional */ + +/* An endpoint discriminator, used with multilink. */ +#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ +struct epdisc { + unsigned char class; + unsigned char length; + unsigned char value[MAX_ENDP_LEN]; +}; + +/* values for epdisc.class */ +#define EPD_NULL 0 /* null discriminator, no data */ +#define EPD_LOCAL 1 +#define EPD_IP 2 +#define EPD_MAC 3 +#define EPD_MAGIC 4 +#define EPD_PHONENUM 5 + +/* FIXME: global variables per PPP session */ + +/* + * Global variables. + */ +/* FIXME: improve debug flag */ +extern int debug; /* Debug flag */ + +/* FIXME: is our_name really necessary ? */ +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 */ + +/* FIXME: make it a compile time option */ +extern int idle_time_limit;/* Shut down link if idle for this long */ + +extern int phase; /* Current state of link - see values below */ +extern int error_count; /* # of times error() has been called */ +extern int unsuccess; /* # unsuccessful connection attempts */ +extern int listen_time; /* time to listen first (ms) */ +extern int status; /* exit status for pppd */ +extern int need_holdoff; /* Need holdoff period after link terminates */ +/* FIXME: remove ifunit */ +extern int ifunit; /* Interface unit number */ +extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ + +/* FIXME: add more HAVE_MULTILINK */ +extern bool multilink; /* enable multilink operation */ + +/* FIXME: it is really necessary ? */ +extern int maxconnect; /* Maximum connect time (seconds) */ + +#ifdef HAVE_MULTILINK +extern bool doing_multilink; +extern bool multilink_master; +extern bool bundle_eof; +extern bool bundle_terminating; +#endif + +#ifdef MAXOCTETS +extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ +extern int maxoctets_dir; /* Direction : + 0 - in+out (default) + 1 - in + 2 - out + 3 - max(in,out) */ +extern int maxoctets_timeout; /* Timeout for check of octets limit */ +#define PPP_OCTETS_DIRECTION_SUM 0 +#define PPP_OCTETS_DIRECTION_IN 1 +#define PPP_OCTETS_DIRECTION_OUT 2 +#define PPP_OCTETS_DIRECTION_MAXOVERAL 3 +/* same as previos, but little different on RADIUS side */ +#define PPP_OCTETS_DIRECTION_MAXSESSION 4 +#endif + +/* + * 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) __P((int unit)); + /* Process a received packet */ + void (*input) __P((int unit, u_char *pkt, int len)); + /* Process a received protocol-reject */ + void (*protrej) __P((int unit)); + /* Lower layer has come up */ + void (*lowerup) __P((int unit)); + /* Lower layer has gone down */ + void (*lowerdown) __P((int unit)); + /* Open the protocol */ + void (*open) __P((int unit)); + /* Close the protocol */ + void (*close) __P((int unit, char *reason)); +#if PRINTPKT_SUPPORT + /* Print a packet in readable form */ + int (*printpkt) __P((u_char *pkt, int len, + void (*printer) __P((void *, char *, ...)), + void *arg)); +#endif /* PRINTPKT_SUPPORT */ + /* FIXME: data input is only used by CCP, which is not supported at this time, + * should we remove this entry and save some flash ? + */ + /* Process a received data packet */ + void (*datainput) __P((int unit, u_char *pkt, int len)); + bool enabled_flag; /* 0 iff protocol is disabled */ +#if PRINTPKT_SUPPORT + char *name; /* Text name of protocol */ + char *data_name; /* Text name of corresponding data protocol */ +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + option_t *options; /* List of command-line options */ + /* Check requested options, assign defaults */ + void (*check_options) __P((void)); +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + /* Configure interface for demand-dial */ + int (*demand_conf) __P((int unit)); + /* Say whether to bring up link for this pkt */ + int (*active_pkt) __P((u_char *pkt, int len)); +#endif /* DEMAND_SUPPORT */ +}; + +/* Table of pointers to supported protocols */ +extern struct protent *protocols[]; + + +/* Values for auth_pending, auth_done */ +#if PAP_SUPPORT +#define PAP_WITHPEER 0x1 +#define PAP_PEER 0x2 +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#define CHAP_WITHPEER 0x4 +#define CHAP_PEER 0x8 +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +#define EAP_WITHPEER 0x10 +#define EAP_PEER 0x20 +#endif /* EAP_SUPPORT */ + +/* Values for auth_done only */ +#if CHAP_SUPPORT +#define CHAP_MD5_WITHPEER 0x40 +#define CHAP_MD5_PEER 0x80 +#if MSCHAP_SUPPORT +#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ +#define CHAP_MS_WITHPEER 0x100 +#define CHAP_MS_PEER 0x200 +#define CHAP_MS2_WITHPEER 0x400 +#define CHAP_MS2_PEER 0x800 +#endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ + +/* + * 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 +#define PHASE_MASTER 12 + + +#if PPP_STATS_SUPPORT +/* + * PPP statistics structure + */ +struct pppd_stats { + unsigned int bytes_in; + unsigned int bytes_out; + unsigned int pkts_in; + unsigned int pkts_out; +}; +#endif /* PPP_STATS_SUPPORT */ + +/* FIXME: fill the struct below with option.c global variables */ + +struct ppp_settings { + + u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ + u_int auth_required : 1; /* Peer is required to authenticate */ + u_int explicit_remote : 1; /* remote_name specified with remotename opt */ +#if PAP_SUPPORT + u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ +#endif /* CHAP_SUPPORT */ +#if MSCHAP_SUPPORT + u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ + u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#endif /* MSCHAP_SUPPORT */ +#if EAP_SUPPORT + u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ +#endif /* EAP_SUPPORT */ + u_int usehostname : 1; /* Use hostname for our_name */ + u_int usepeerdns : 1; /* Ask peer for DNS adds */ + + u_short idle_time_limit; /* Shut down link if idle for this long */ + int maxconnect; /* Maximum connect time (seconds) */ + + char user [MAXNAMELEN + 1]; /* Username for PAP */ + char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ + char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ + /* FIXME: re-enable that */ + /* char remote_name[MAXNAMELEN + 1]; */ /* Peer's name for authentication */ +}; + +struct ppp_settings ppp_settings; + + +/* PPP flow functions + */ +#if PPPOE_SUPPORT +void pppOverEthernetInitFailed(int pd); +/* function called by pppoe.c */ +void ppp_input_over_ethernet(int pd, struct pbuf *pb); +#endif /* PPPOE_SUPPORT */ + +/* function called by all PPP subsystems to send packets */ +int ppp_write(int pd, const u_char *s, int n); + +/* functions called by auth.c link_terminated() */ +void pppLinkDown(int pd); +void pppLinkTerminated(int pd); + +/* merge a pbuf chain into one pbuf */ +struct pbuf * ppp_singlebuf(struct pbuf *p); + + +/* Functions called by various PPP subsystems to configure + * the PPP interface or change the PPP phase. + */ +void new_phase(int p); + +#if PPPOS_SUPPORT +void ppp_set_xaccm(int unit, ext_accm *accm); +#endif /* PPPOS_SUPPORT */ +int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp); +int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp); + +int sifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); +int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr); + +int sifup(int u); +int sifdown (int u); + +int sifnpmode(int u, int proto, enum NPmode mode); + +void netif_set_mtu(int unit, int mtu); +int netif_get_mtu(int mtu); + +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace); +int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway); + +int sifproxyarp (int unit, u_int32_t his_adr); +int cifproxyarp (int unit, u_int32_t his_adr); + +int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid); + +int get_idle_time(int u, struct ppp_idle *ip); + +int get_loop_output(void); + +u_int32_t GetMask (u_int32_t addr); + + +/* Optional protocol names list, to make our messages a little more informative. */ +#if PPP_PROTOCOLNAME +const char * protocol_name(int proto); +#endif /* PPP_PROTOCOLNAME */ + + +/* Optional stats support, to get some statistics on the PPP interface */ +#if PPP_STATS_SUPPORT +void print_link_stats(void); /* Print stats, if available */ +void reset_link_stats(int u); /* Reset (init) stats when link goes up */ +void update_link_stats(int u); /* Get stats at link termination */ +#endif /* PPP_STATS_SUPPORT */ + + + +/* + * 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(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) +#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) +#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) + +#define BZERO(s, n) memset(s, 0, n) +#define BCMP(s1, s2, l) memcmp(s1, s2, l) + +#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 +#ifdef MAXOCTETS +#define EXIT_TRAFFIC_LIMIT 20 +#endif +#define EXIT_CNID_AUTH_FAILED 21 + +/* Procedures exported from auth.c */ +void link_required __P((int)); /* we are starting to use the link */ +void link_terminated __P((int)); /* we are finished with the link */ +void link_down __P((int)); /* the LCP layer has left the Opened state */ +void upper_layers_down __P((int));/* take all NCPs down */ +void link_established __P((int)); /* the link is up; authenticate now */ +void start_networks __P((int)); /* start all the network control protos */ +void continue_networks __P((int)); /* start network [ip, etc] control protos */ + +void auth_peer_fail __P((int, int)); + /* peer failed to authenticate itself */ +void auth_peer_success __P((int, int, int, char *, int)); + /* peer successfully authenticated itself */ +void auth_withpeer_fail __P((int, int)); + /* we failed to authenticate ourselves */ +void auth_withpeer_success __P((int, int, int)); + /* we successfully authenticated ourselves */ +void np_up __P((int, int)); /* a network protocol has come up */ +void np_down __P((int, int)); /* a network protocol has gone down */ +void np_finished __P((int, int)); /* a network protocol no longer needs link */ +void auth_reset __P((int)); /* check what secrets we have */ +int get_secret __P((int, char *, char *, char *, int *, int)); + /* get "secret" for chap */ + +/* Procedures exported from ipcp.c */ +/* int parse_dotted_ip __P((char *, u_int32_t *)); */ + +/* Procedures exported from demand.c */ +#if DEMAND_SUPPORT +void demand_conf __P((void)); /* config interface(s) for demand-dial */ +void demand_block __P((void)); /* set all NPs to queue up packets */ +void demand_unblock __P((void)); /* set all NPs to pass packets */ +void demand_discard __P((void)); /* set all NPs to discard packets */ +void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ +int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ +int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ +#endif /* DEMAND_SUPPORT */ + +/* Procedures exported from multilink.c */ +#ifdef HAVE_MULTILINK +void mp_check_options __P((void)); /* Check multilink-related options */ +int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ +void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */ +void mp_bundle_terminated __P((void)); +char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ +int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ +#else +#define mp_bundle_terminated() /* nothing */ +#define mp_exit_bundle() /* nothing */ +#define doing_multilink 0 +#define multilink_master 0 +#endif + +/* Procedures exported from utils.c. */ +void print_string __P((char *, int, void (*) (void *, char *, ...), + void *)); /* Format a string for output */ +int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ +int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ +size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ +size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ +void dbglog __P((char *, ...)); /* log a debug message */ +void info __P((char *, ...)); /* log an informational message */ +void notice __P((char *, ...)); /* log a notice-level message */ +void warn __P((char *, ...)); /* log a warning message */ +void error __P((char *, ...)); /* log an error message */ +void fatal __P((char *, ...)); /* log an error message and die(1) */ +void init_pr_log __P((const char *, int)); /* initialize for using pr_log */ +void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ +void end_pr_log __P((void)); /* finish up after using pr_log */ +#if PRINTPKT_SUPPORT +void dump_packet __P((const char *, u_char *, int)); + /* dump packet to debug log if interesting */ +#endif /* PRINTPKT_SUPPORT */ + + +#endif /* PPP_IMP_H_ */ + +#endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index caba219e..50a966d8 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -80,7 +80,7 @@ #include "lwip/memp.h" #include "lwip/stats.h" -#include "ppp.h" +#include "ppp_impl.h" #include "netif/ppp_oe.h" diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index 6a3a4ab6..dd6963e8 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -33,7 +33,7 @@ #include "lwip/opt.h" #if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppcrypt.h" diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 8eae19d5..07ea3853 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -52,7 +52,7 @@ #include #endif /* UNUSED */ -#include "ppp.h" +#include "ppp_impl.h" #include "upap.h" diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 4869c057..e1340388 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -60,7 +60,7 @@ #include /* isdigit() */ -#include "ppp.h" +#include "ppp_impl.h" #include "fsm.h" #include "lcp.h" From c09f03f6e883c3a5c0026e5f2f2f4883f1de0022 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 20:44:47 +0200 Subject: [PATCH 096/320] VJ support is back! --- src/include/lwip/opt.h | 6 +- src/netif/ppp/ppp.c | 4 + src/netif/ppp/vj.c | 647 +++++++++++++++++++++++++++++++++++++++++ src/netif/ppp/vj.h | 161 ++++++++++ 4 files changed, 817 insertions(+), 1 deletion(-) create mode 100644 src/netif/ppp/vj.c create mode 100644 src/netif/ppp/vj.h diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index d4078520..fcda2e3e 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1759,8 +1759,12 @@ * VJ_SUPPORT==1: Support VJ header compression. */ #ifndef VJ_SUPPORT -#define VJ_SUPPORT 0 +#define VJ_SUPPORT 1 #endif +#if !PPPOS_SUPPORT +#undef VJ_SUPPORT +#define VJ_SUPPORT 0 /* Only PPPoS may need VJ compression */ +#endif /* !PPPOS_SUPPORT */ /** * PPP_MD5_RANDM==1: Use MD5 for better randomness. Automatically enabled if CHAP support is enabled. diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index c5c35cf0..af706987 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -89,6 +89,7 @@ #include "lwip/api.h" #include "lwip/snmp.h" #include "lwip/sio.h" +#include "lwip/sys.h" #include "lwip/ip.h" /* for ip_input() */ #include "ppp_impl.h" @@ -113,6 +114,9 @@ #if ECP_SUPPORT #include "ecp.h" #endif /* EAP_SUPPORT */ +#if VJ_SUPPORT +#include "vj.h" +#endif /* VJ_SUPPORT */ #if PPPOE_SUPPORT #include "netif/ppp_oe.h" diff --git a/src/netif/ppp/vj.c b/src/netif/ppp/vj.c new file mode 100644 index 00000000..0fed7aab --- /dev/null +++ b/src/netif/ppp/vj.c @@ -0,0 +1,647 @@ +/* + * Routines to compress and uncompess tcp packets (for transmission + * over low speed serial lines. + * + * Copyright (c) 1989 Regents of the University of California. + * 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 University of California, Berkeley. 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. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * Initial distribution. + * + * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, + * so that the entire packet being decompressed doesn't have + * to be in contiguous memory (just the compressed header). + * + * Modified March 1998 by Guy Lancaster, glanca@gesn.com, + * for a 16 bit processor. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "vj.h" + +#include + +#if LINK_STATS +#define INCR(counter) ++comp->stats.counter +#else +#define INCR(counter) +#endif + +void +vj_compress_init(struct vjcompress *comp) +{ + register u_char i; + register struct cstate *tstate = comp->tstate; + +#if MAX_SLOTS == 0 + memset((char *)comp, 0, sizeof(*comp)); +#endif + comp->maxSlotIndex = MAX_SLOTS - 1; + comp->compressSlot = 0; /* Disable slot ID compression by default. */ + for (i = MAX_SLOTS - 1; i > 0; --i) { + tstate[i].cs_id = i; + tstate[i].cs_next = &tstate[i - 1]; + } + tstate[0].cs_next = &tstate[MAX_SLOTS - 1]; + tstate[0].cs_id = 0; + comp->last_cs = &tstate[0]; + comp->last_recv = 255; + comp->last_xmit = 255; + comp->flags = VJF_TOSS; +} + + +/* ENCODE encodes a number that is known to be non-zero. ENCODEZ + * checks for zero (since zero has to be encoded in the long, 3 byte + * form). + */ +#define ENCODE(n) { \ + if ((u_short)(n) >= 256) { \ + *cp++ = 0; \ + cp[1] = (u_char)(n); \ + cp[0] = (u_char)((n) >> 8); \ + cp += 2; \ + } else { \ + *cp++ = (u_char)(n); \ + } \ +} +#define ENCODEZ(n) { \ + if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ + *cp++ = 0; \ + cp[1] = (u_char)(n); \ + cp[0] = (u_char)((n) >> 8); \ + cp += 2; \ + } else { \ + *cp++ = (u_char)(n); \ + } \ +} + +#define DECODEL(f) { \ + if (*cp == 0) {\ + u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \ + (f) = htonl(tmp); \ + cp += 3; \ + } else { \ + u32_t tmp = ntohl(f) + (u32_t)*cp++; \ + (f) = htonl(tmp); \ + } \ +} + +#define DECODES(f) { \ + if (*cp == 0) {\ + u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \ + (f) = htons(tmp); \ + cp += 3; \ + } else { \ + u_short tmp = ntohs(f) + (u_short)*cp++; \ + (f) = htons(tmp); \ + } \ +} + +#define DECODEU(f) { \ + if (*cp == 0) {\ + (f) = htons(((u_short)cp[1] << 8) | cp[2]); \ + cp += 3; \ + } else { \ + (f) = htons((u_short)*cp++); \ + } \ +} + +/* + * vj_compress_tcp - Attempt to do Van Jacobson header compression on a + * packet. This assumes that nb and comp are not null and that the first + * buffer of the chain contains a valid IP header. + * Return the VJ type code indicating whether or not the packet was + * compressed. + */ +u_int +vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) +{ + register struct ip_hdr *ip = (struct ip_hdr *)pb->payload; + register struct cstate *cs = comp->last_cs->cs_next; + register u_short hlen = IPH_HL(ip); + register struct tcp_hdr *oth; + register struct tcp_hdr *th; + register u_short deltaS, deltaA = 0; + register u_long deltaL; + register u_int changes = 0; + u_char new_seq[16]; + register u_char *cp = new_seq; + + /* + * Check that the packet is IP proto TCP. + */ + if (IPH_PROTO(ip) != IP_PROTO_TCP) { + return (TYPE_IP); + } + + /* + * Bail if this is an IP fragment or if the TCP packet isn't + * `compressible' (i.e., ACK isn't set or some other control bit is + * set). + */ + if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) { + return (TYPE_IP); + } + th = (struct tcp_hdr *)&((long *)ip)[hlen]; + if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) { + return (TYPE_IP); + } + /* + * Packet is compressible -- we're going to send either a + * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need + * to locate (or create) the connection state. Special case the + * most recently used connection since it's most likely to be used + * again & we don't have to do any reordering if it's used. + */ + INCR(vjs_packets); + if (!ip_addr_cmp(&ip->src, &cs->cs_ip.src) + || !ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) + || *(long *)th != ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { + /* + * Wasn't the first -- search for it. + * + * States are kept in a circularly linked list with + * last_cs pointing to the end of the list. The + * list is kept in lru order by moving a state to the + * head of the list whenever it is referenced. Since + * the list is short and, empirically, the connection + * we want is almost always near the front, we locate + * states via linear search. If we don't find a state + * for the datagram, the oldest state is (re-)used. + */ + register struct cstate *lcs; + register struct cstate *lastcs = comp->last_cs; + + do { + lcs = cs; cs = cs->cs_next; + INCR(vjs_searches); + if (ip_addr_cmp(&ip->src, &cs->cs_ip.src) + && ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) + && *(long *)th == ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { + goto found; + } + } while (cs != lastcs); + + /* + * Didn't find it -- re-use oldest cstate. Send an + * uncompressed packet that tells the other side what + * connection number we're using for this conversation. + * Note that since the state list is circular, the oldest + * state points to the newest and we only need to set + * last_cs to update the lru linkage. + */ + INCR(vjs_misses); + comp->last_cs = lcs; + hlen += TCPH_HDRLEN(th); + hlen <<= 2; + /* Check that the IP/TCP headers are contained in the first buffer. */ + if (hlen > pb->len) { + return (TYPE_IP); + } + goto uncompressed; + + found: + /* + * Found it -- move to the front on the connection list. + */ + if (cs == lastcs) { + comp->last_cs = lcs; + } else { + lcs->cs_next = cs->cs_next; + cs->cs_next = lastcs->cs_next; + lastcs->cs_next = cs; + } + } + + oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen]; + deltaS = hlen; + hlen += TCPH_HDRLEN(th); + hlen <<= 2; + /* Check that the IP/TCP headers are contained in the first buffer. */ + if (hlen > pb->len) { + PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen)); + return (TYPE_IP); + } + + /* + * Make sure that only what we expect to change changed. The first + * line of the `if' checks the IP protocol version, header length & + * type of service. The 2nd line checks the "Don't fragment" bit. + * The 3rd line checks the time-to-live and protocol (the protocol + * check is unnecessary but costless). The 4th line checks the TCP + * header length. The 5th line checks IP options, if any. The 6th + * line checks TCP options, if any. If any of these things are + * different between the previous & current datagram, we send the + * current datagram `uncompressed'. + */ + if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] + || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] + || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] + || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) + || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) + || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) { + goto uncompressed; + } + + /* + * Figure out which of the changing fields changed. The + * receiver expects changes in the order: urgent, window, + * ack, seq (the order minimizes the number of temporaries + * needed in this section of code). + */ + if (TCPH_FLAGS(th) & TCP_URG) { + deltaS = ntohs(th->urgp); + ENCODEZ(deltaS); + changes |= NEW_U; + } else if (th->urgp != oth->urgp) { + /* argh! URG not set but urp changed -- a sensible + * implementation should never do this but RFC793 + * doesn't prohibit the change so we have to deal + * with it. */ + goto uncompressed; + } + + if ((deltaS = (u_short)(ntohs(th->wnd) - ntohs(oth->wnd))) != 0) { + ENCODE(deltaS); + changes |= NEW_W; + } + + if ((deltaL = ntohl(th->ackno) - ntohl(oth->ackno)) != 0) { + if (deltaL > 0xffff) { + goto uncompressed; + } + deltaA = (u_short)deltaL; + ENCODE(deltaA); + changes |= NEW_A; + } + + if ((deltaL = ntohl(th->seqno) - ntohl(oth->seqno)) != 0) { + if (deltaL > 0xffff) { + goto uncompressed; + } + deltaS = (u_short)deltaL; + ENCODE(deltaS); + changes |= NEW_S; + } + + switch(changes) { + case 0: + /* + * Nothing changed. If this packet contains data and the + * last one didn't, this is probably a data packet following + * an ack (normal on an interactive connection) and we send + * it compressed. Otherwise it's probably a retransmit, + * retransmitted ack or window probe. Send it uncompressed + * in case the other side missed the compressed version. + */ + if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) && + ntohs(IPH_LEN(&cs->cs_ip)) == hlen) { + break; + } + + /* (fall through) */ + + case SPECIAL_I: + case SPECIAL_D: + /* + * actual changes match one of our special case encodings -- + * send packet uncompressed. + */ + goto uncompressed; + + case NEW_S|NEW_A: + if (deltaS == deltaA && deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { + /* special case for echoed terminal traffic */ + changes = SPECIAL_I; + cp = new_seq; + } + break; + + case NEW_S: + if (deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { + /* special case for data xfer */ + changes = SPECIAL_D; + cp = new_seq; + } + break; + } + + deltaS = (u_short)(ntohs(IPH_ID(ip)) - ntohs(IPH_ID(&cs->cs_ip))); + if (deltaS != 1) { + ENCODEZ(deltaS); + changes |= NEW_I; + } + if (TCPH_FLAGS(th) & TCP_PSH) { + changes |= TCP_PUSH_BIT; + } + /* + * Grab the cksum before we overwrite it below. Then update our + * state with this packet's header. + */ + deltaA = ntohs(th->chksum); + MEMCPY(&cs->cs_ip, ip, hlen); + + /* + * We want to use the original packet as our compressed packet. + * (cp - new_seq) is the number of bytes we need for compressed + * sequence numbers. In addition we need one byte for the change + * mask, one for the connection id and two for the tcp checksum. + * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how + * many bytes of the original packet to toss so subtract the two to + * get the new packet size. + */ + deltaS = (u_short)(cp - new_seq); + if (!comp->compressSlot || comp->last_xmit != cs->cs_id) { + comp->last_xmit = cs->cs_id; + hlen -= deltaS + 4; + if(pbuf_header(pb, -hlen)){ + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + } + cp = (u_char *)pb->payload; + *cp++ = (u_char)(changes | NEW_C); + *cp++ = cs->cs_id; + } else { + hlen -= deltaS + 3; + if(pbuf_header(pb, -hlen)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + } + cp = (u_char *)pb->payload; + *cp++ = (u_char)changes; + } + *cp++ = (u_char)(deltaA >> 8); + *cp++ = (u_char)deltaA; + MEMCPY(cp, new_seq, deltaS); + INCR(vjs_compressed); + return (TYPE_COMPRESSED_TCP); + + /* + * Update connection state cs & send uncompressed packet (that is, + * a regular ip/tcp packet but with the 'conversation id' we hope + * to use on future compressed packets in the protocol field). + */ +uncompressed: + MEMCPY(&cs->cs_ip, ip, hlen); + IPH_PROTO_SET(ip, cs->cs_id); + comp->last_xmit = cs->cs_id; + return (TYPE_UNCOMPRESSED_TCP); +} + +/* + * Called when we may have missed a packet. + */ +void +vj_uncompress_err(struct vjcompress *comp) +{ + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); +} + +/* + * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. + * Return 0 on success, -1 on failure. + */ +int +vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) +{ + register u_int hlen; + register struct cstate *cs; + register struct ip_hdr *ip; + + ip = (struct ip_hdr *)nb->payload; + hlen = IPH_HL(ip) << 2; + if (IPH_PROTO(ip) >= MAX_SLOTS + || hlen + sizeof(struct tcp_hdr) > nb->len + || (hlen += TCPH_HDRLEN(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2) + > nb->len + || hlen > MAX_HDR) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", + IPH_PROTO(ip), hlen, nb->len)); + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); + return -1; + } + cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)]; + comp->flags &=~ VJF_TOSS; + IPH_PROTO_SET(ip, IP_PROTO_TCP); + MEMCPY(&cs->cs_ip, ip, hlen); + cs->cs_hlen = (u_short)hlen; + INCR(vjs_uncompressedin); + return 0; +} + +/* + * Uncompress a packet of type TYPE_COMPRESSED_TCP. + * The packet is composed of a buffer chain and the first buffer + * must contain an accurate chain length. + * The first buffer must include the entire compressed TCP/IP header. + * This procedure replaces the compressed header with the uncompressed + * header and returns the length of the VJ header. + */ +int +vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) +{ + u_char *cp; + struct tcp_hdr *th; + struct cstate *cs; + u_short *bp; + struct pbuf *n0 = *nb; + u32_t tmp; + u_int vjlen, hlen, changes; + + INCR(vjs_compressedin); + cp = (u_char *)n0->payload; + changes = *cp++; + if (changes & NEW_C) { + /* + * Make sure the state index is in range, then grab the state. + * If we have a good state index, clear the 'discard' flag. + */ + if (*cp >= MAX_SLOTS) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp)); + goto bad; + } + + comp->flags &=~ VJF_TOSS; + comp->last_recv = *cp++; + } else { + /* + * this packet has an implicit state index. If we've + * had a line error since the last time we got an + * explicit state index, we have to toss the packet. + */ + if (comp->flags & VJF_TOSS) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n")); + INCR(vjs_tossed); + return (-1); + } + } + cs = &comp->rstate[comp->last_recv]; + hlen = IPH_HL(&cs->cs_ip) << 2; + th = (struct tcp_hdr *)&((u_char *)&cs->cs_ip)[hlen]; + th->chksum = htons((*cp << 8) | cp[1]); + cp += 2; + if (changes & TCP_PUSH_BIT) { + TCPH_SET_FLAG(th, TCP_PSH); + } else { + TCPH_UNSET_FLAG(th, TCP_PSH); + } + + switch (changes & SPECIALS_MASK) { + case SPECIAL_I: + { + register u32_t i = ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; + /* some compilers can't nest inline assembler.. */ + tmp = ntohl(th->ackno) + i; + th->ackno = htonl(tmp); + tmp = ntohl(th->seqno) + i; + th->seqno = htonl(tmp); + } + break; + + case SPECIAL_D: + /* some compilers can't nest inline assembler.. */ + tmp = ntohl(th->seqno) + ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; + th->seqno = htonl(tmp); + break; + + default: + if (changes & NEW_U) { + TCPH_SET_FLAG(th, TCP_URG); + DECODEU(th->urgp); + } else { + TCPH_UNSET_FLAG(th, TCP_URG); + } + if (changes & NEW_W) { + DECODES(th->wnd); + } + if (changes & NEW_A) { + DECODEL(th->ackno); + } + if (changes & NEW_S) { + DECODEL(th->seqno); + } + break; + } + if (changes & NEW_I) { + DECODES(cs->cs_ip._id); + } else { + IPH_ID_SET(&cs->cs_ip, ntohs(IPH_ID(&cs->cs_ip)) + 1); + IPH_ID_SET(&cs->cs_ip, htons(IPH_ID(&cs->cs_ip))); + } + + /* + * At this point, cp points to the first byte of data in the + * packet. Fill in the IP total length and update the IP + * header checksum. + */ + vjlen = (u_short)(cp - (u_char*)n0->payload); + if (n0->len < vjlen) { + /* + * We must have dropped some characters (crc should detect + * this but the old slip framing won't) + */ + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n", + n0->len, vjlen)); + goto bad; + } + +#if BYTE_ORDER == LITTLE_ENDIAN + tmp = n0->tot_len - vjlen + cs->cs_hlen; + IPH_LEN_SET(&cs->cs_ip, htons((u_short)tmp)); +#else + IPH_LEN_SET(&cs->cs_ip, htons(n0->tot_len - vjlen + cs->cs_hlen)); +#endif + + /* recompute the ip header checksum */ + bp = (u_short *) &cs->cs_ip; + IPH_CHKSUM_SET(&cs->cs_ip, 0); + for (tmp = 0; hlen > 0; hlen -= 2) { + tmp += *bp++; + } + tmp = (tmp & 0xffff) + (tmp >> 16); + tmp = (tmp & 0xffff) + (tmp >> 16); + IPH_CHKSUM_SET(&cs->cs_ip, (u_short)(~tmp)); + + /* Remove the compressed header and prepend the uncompressed header. */ + if(pbuf_header(n0, -((s16_t)(vjlen)))) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + goto bad; + } + + if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) { + struct pbuf *np, *q; + u8_t *bufptr; + + np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); + if(!np) { + PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n")); + goto bad; + } + + if(pbuf_header(np, -cs->cs_hlen)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + goto bad; + } + + bufptr = n0->payload; + for(q = np; q != NULL; q = q->next) { + MEMCPY(q->payload, bufptr, q->len); + bufptr += q->len; + } + + if(n0->next) { + pbuf_chain(np, n0->next); + pbuf_dechain(n0); + } + pbuf_free(n0); + n0 = np; + } + + if(pbuf_header(n0, cs->cs_hlen)) { + struct pbuf *np; + + LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE); + np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL); + if(!np) { + PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n")); + goto bad; + } + pbuf_cat(np, n0); + n0 = np; + } + LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); + MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen); + + *nb = n0; + + return vjlen; + +bad: + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); + return (-1); +} + +#endif /* PPP_SUPPORT && VJ_SUPPORT */ diff --git a/src/netif/ppp/vj.h b/src/netif/ppp/vj.h new file mode 100644 index 00000000..3780667b --- /dev/null +++ b/src/netif/ppp/vj.h @@ -0,0 +1,161 @@ +/* + * Definitions for tcp compression routines. + * + * $Id: vj.h,v 1.7 2010/02/22 17:52:09 goldsimon Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * 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 University of California, Berkeley. 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. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef VJ_H +#define VJ_H + +#include "lwip/ip.h" +#include "lwip/tcp_impl.h" + +#define MAX_SLOTS 16 /* must be > 2 and < 256 */ +#define MAX_HDR 128 + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowlegement, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + +/* packet types */ +#define TYPE_IP 0x40 +#define TYPE_UNCOMPRESSED_TCP 0x70 +#define TYPE_COMPRESSED_TCP 0x80 +#define TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + struct cstate *cs_next; /* next most recently used state (xmit only) */ + u_short cs_hlen; /* size of hdr (receive only) */ + u_char cs_id; /* connection # associated with this state */ + u_char cs_filler; + union { + char csu_hdr[MAX_HDR]; + struct ip_hdr csu_ip; /* ip/tcp hdr from most recent packet */ + } vjcs_u; +}; +#define cs_ip vjcs_u.csu_ip +#define cs_hdr vjcs_u.csu_hdr + + +struct vjstat { + unsigned long vjs_packets; /* outbound packets */ + unsigned long vjs_compressed; /* outbound compressed packets */ + unsigned long vjs_searches; /* searches for connection state */ + unsigned long vjs_misses; /* times couldn't find conn. state */ + unsigned long vjs_uncompressedin; /* inbound uncompressed packets */ + unsigned long vjs_compressedin; /* inbound compressed packets */ + unsigned long vjs_errorin; /* inbound unknown type packets */ + unsigned long vjs_tossed; /* inbound packets tossed because of error */ +}; + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct vjcompress { + struct cstate *last_cs; /* most recently used tstate */ + u_char last_recv; /* last rcvd conn. id */ + u_char last_xmit; /* last sent conn. id */ + u_short flags; + u_char maxSlotIndex; + u_char compressSlot; /* Flag indicating OK to compress slot ID. */ +#if LINK_STATS + struct vjstat stats; +#endif + struct cstate tstate[MAX_SLOTS]; /* xmit connection states */ + struct cstate rstate[MAX_SLOTS]; /* receive connection states */ +}; + +/* flag values */ +#define VJF_TOSS 1U /* tossing rcvd frames because of input err */ + +extern void vj_compress_init (struct vjcompress *comp); +extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb); +extern void vj_uncompress_err (struct vjcompress *comp); +extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp); +extern int vj_uncompress_tcp (struct pbuf **nb, struct vjcompress *comp); + +#endif /* VJ_H */ + +#endif /* PPP_SUPPORT && VJ_SUPPORT */ From 03fda0f803132316d97ff02e1284ec226c7487fc Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 21:48:10 +0200 Subject: [PATCH 097/320] removed CamelCase for all ppp.h declared functions --- src/netif/ppp/auth.c | 2 +- src/netif/ppp/ppp.c | 68 +++++++++++++++++++++++--------------------- src/netif/ppp/ppp.h | 38 ++++++++++++++++--------- 3 files changed, 61 insertions(+), 47 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index df0d4de7..820d0f64 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1125,7 +1125,7 @@ auth_withpeer_fail(unit, protocol) * He'll probably take the link down, and there's not much * we can do except wait for that. */ - pppIOCtl(unit, PPPCTLS_ERRCODE, &errcode); + ppp_ioctl(unit, PPPCTLS_ERRCODE, &errcode); lcp_close(unit, "Failed to authenticate ourselves to peer"); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index af706987..0f96a64f 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -289,8 +289,8 @@ typedef struct PPPControl_s { struct ppp_addrs addrs; - void (*linkStatusCB)(void *ctx, int errCode, void *arg); - void *linkStatusCtx; + void (*link_status_cb)(void *ctx, int errCode, void *arg); + void *link_status_ctx; } PPPControl; @@ -383,7 +383,7 @@ int ppp_init(void) { return 0; } -void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passwd) { +void ppp_set_auth(enum ppp_auth_type authtype, const char *user, const char *passwd) { /* FIXME: the following may look stupid, but this is just an easy way * to check different auth by changing compile time option */ @@ -423,7 +423,7 @@ void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passw /* FIXME: re-enable that */ #if 0 - switch(authType) { + switch(authtype) { case PPPAUTHTYPE_NONE: default: #ifdef LWIP_PPP_STRICT_PAP_REJECT @@ -497,11 +497,11 @@ void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passw * * pppOpen() is directly defined to this function. */ -int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) { +int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { PPPControl *pc; int pd; - if (linkStatusCB == NULL) { + if (link_status_cb == NULL) { /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ return PPPERR_PARAM; @@ -535,13 +535,13 @@ int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkSt pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */ pc->outACCM[15] = 0x60; - pc->linkStatusCB = linkStatusCB; - pc->linkStatusCtx = linkStatusCtx; + pc->link_status_cb = link_status_cb; + pc->link_status_ctx = link_status_ctx; /* * Start the connection and handle incoming events (packet or timeout). */ - PPPDEBUG(LOG_INFO, ("pppOverSerialOpen: unit %d: Connecting\n", pd)); + PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pd)); ppp_start(pd); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); @@ -569,14 +569,14 @@ void ppp_set_xaccm(int unit, ext_accm *accm) { static void ppp_over_ethernet_link_status_cb(int pd, int up); int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, - pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) { + ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { PPPControl *pc; int pd; LWIP_UNUSED_ARG(service_name); LWIP_UNUSED_ARG(concentrator_name); - if (linkStatusCB == NULL) { + if (link_status_cb == NULL) { /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ return PPPERR_PARAM; @@ -592,8 +592,8 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const pc->openFlag = 1; pc->ethif = ethif; - pc->linkStatusCB = linkStatusCB; - pc->linkStatusCtx = linkStatusCtx; + pc->link_status_cb = link_status_cb; + pc->link_status_ctx = link_status_ctx; lcp_wantoptions[pd].mru = PPPOE_MAXMTU; lcp_wantoptions[pd].neg_asyncmap = 0; @@ -631,17 +631,17 @@ void pppOverEthernetClose(int pd) { * Any outstanding packets in the queues are dropped. * Return 0 on success, an error code on failure. */ int -pppClose(int pd) +ppp_close(int pd) { PPPControl *pc = &pppControl[pd]; int st = 0; - PPPDEBUG(LOG_DEBUG, ("pppClose() called\n")); + PPPDEBUG(LOG_DEBUG, ("ppp_close() called\n")); /* Disconnect */ #if PPPOE_SUPPORT if(pc->ethif) { - PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> pppStop\n", pd)); pc->errCode = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ pppStop(pd); @@ -649,7 +649,7 @@ pppClose(int pd) #endif /* PPPOE_SUPPORT */ { #if PPPOS_SUPPORT - PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> pppStop\n", pd)); pc->errCode = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ pppStop(pd); @@ -664,9 +664,9 @@ pppClose(int pd) /* This function is called when carrier is lost on the PPP channel. */ void -pppSigHUP(int pd) +ppp_sighup(int pd) { - PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); + PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> pppHupCB\n", pd)); pppHup(pd); } @@ -1072,7 +1072,7 @@ static err_t ppp_netif_init_cb(struct netif *netif) { netif->name[0] = 'p'; netif->name[1] = 'p'; netif->output = ppp_netif_output; - netif->mtu = pppMTU((int)(size_t)netif->state); + netif->mtu = ppp_mtu((int)(size_t)netif->state); netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; #if LWIP_NETIF_HOSTNAME /* @todo: Initialize interface hostname */ @@ -1368,7 +1368,7 @@ static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { /* * Return the Maximum Transmission Unit for the given PPP connection. */ -u_short pppMTU(int pd) { +u_short ppp_mtu(int pd) { PPPControl *pc = &pppControl[pd]; u_short st; @@ -1381,10 +1381,12 @@ u_short pppMTU(int pd) { return st; } + + /* Get and set parameters for the given connection. * Return 0 on success, an error code on failure. */ int -pppIOCtl(int pd, int cmd, void *arg) +ppp_ioctl(int pd, int cmd, void *arg) { PPPControl *pc = &pppControl[pd]; int st = 0; @@ -1838,8 +1840,8 @@ void pppOverEthernetInitFailed(int pd) { pppoe_destroy(&pc->netif); pc->openFlag = 0; - if(pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + if(pc->link_status_cb) { + pc->link_status_cb(pc->link_status_ctx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); } } @@ -1884,9 +1886,9 @@ void pppLinkTerminated(int pd) { #endif /* PPP_INPROC_OWNTHREAD */ pc = &pppControl[pd]; - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: link_status_cb=%p errCode=%d\n", pd, pc->link_status_cb, pc->errCode)); + if (pc->link_status_cb) { + pc->link_status_cb(pc->link_status_ctx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); } pc->openFlag = 0;/**/ @@ -2078,9 +2080,9 @@ int sifup(int u) pc->if_up = 1; pc->errCode = PPPERR_NONE; - PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", u, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p errCode=%d\n", u, pc->link_status_cb, pc->errCode)); + if (pc->link_status_cb) { + pc->link_status_cb(pc->link_status_ctx, pc->errCode, &pc->addrs); } } else { st = 0; @@ -2108,9 +2110,9 @@ int sifdown(int unit) { /* make sure the netif status callback is called */ netif_set_down(&pc->netif); netif_remove(&pc->netif); - PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: linkStatusCB=%p errCode=%d\n", unit, pc->linkStatusCB, pc->errCode)); - if (pc->linkStatusCB) { - pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL); + PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p errCode=%d\n", unit, pc->link_status_cb, pc->errCode)); + if (pc->link_status_cb) { + pc->link_status_cb(pc->link_status_ctx, PPPERR_CONNECT, NULL); } } return st; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 17fd91ee..57d29485 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -100,7 +100,7 @@ struct ppp_addrs { /* Initialize the PPP subsystem. */ int ppp_init(void); -/* Warning: Using PPPAUTHTYPE_ANY might have security consequences. +/* Warning: Using ppp_auth_type_ANY might have security consequences. * RFC 1994 says: * * In practice, within or associated with each PPP server, there is a @@ -119,7 +119,7 @@ int ppp_init(void); * which identifies exactly one authentication method. * */ -enum pppAuthType { +enum ppp_auth_type { #if CHAP_SUPPORT PPPAUTHTYPE_CHAP, #endif /* CHAP_SUPPORT */ @@ -130,10 +130,10 @@ enum pppAuthType { PPPAUTHTYPE_NONE }; -void ppp_set_auth(enum pppAuthType authType, const char *user, const char *passwd); +void ppp_set_auth(enum ppp_auth_type authtype, const char *user, const char *passwd); /* Link status callback function prototype */ -typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); +typedef void (*ppp_link_status_cb_fn)(void *ctx, int errcode, void *arg); #if PPPOS_SUPPORT /* @@ -147,7 +147,7 @@ typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); * Return a new PPP connection descriptor on success or * an error code (negative) on failure. */ -int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); +int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT @@ -155,35 +155,32 @@ int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkSt * Open a new PPP Over Ethernet (PPPoE) connection. */ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, - pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); + ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOE_SUPPORT */ -/* for source code compatibility */ -#define pppOpen(fd,cb,ls) pppOverSerialOpen(fd,cb,ls) - /* * Close a PPP connection and release the descriptor. * Any outstanding packets in the queues are dropped. * Return 0 on success, an error code on failure. */ -int pppClose(int pd); +int ppp_close(int pd); /* * Indicate to the PPP process that the line has disconnected. */ -void pppSigHUP(int pd); +void ppp_sighup(int pd); /* * Get and set parameters for the given connection. * Return 0 on success, an error code on failure. */ -int pppIOCtl(int pd, int cmd, void *arg); +int ppp_ioctl(int pd, int cmd, void *arg); /* * Return the Maximum Transmission Unit for the given PPP connection. */ /* FIXME: demystify MTU support */ -u_short pppMTU(int pd); +u_short ppp_mtu(int pd); #if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD /* @@ -204,6 +201,21 @@ void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callba void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback); #endif /* LWIP_NETIF_LINK_CALLBACK */ + +/* Source code compatibility */ +#if 0 +#define pppAuthType ppp_auth_type +#define pppInit() ppp_init() +#define pppSetAuth(authtype,user,passwd) ppp_set_auth(authtype,user,passwd) +#define pppOpen(fd,cb,ls) ppp_over_serial_open(fd,cb,ls) +#define pppOverSerialOpen(fd,cb,ls) ppp_over_serial_open(fd,cb,ls) +#define pppOverEthernetOpen(ethif,sn,cn,lscb,lsctx) ppp_over_ethernet_open(ethif,sn,cn,lscb,lsctx) +#define pppClose(unit) ppp_close(unit) +#define pppSigHUP(unit) ppp_sigup(unit) +#define pppIOCtl(pd,cmd,arg) ppp_ioctl(pd,cmd,arg) +#define pppMTU(unit) ppp_mtu(unit) +#endif + #endif /* PPP_H */ #endif /* PPP_SUPPORT */ From 31456a6dfe8b6b5c6c4c274b6e592111be608638 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 3 Jun 2012 23:56:56 +0200 Subject: [PATCH 098/320] removed CamelCase in ppp.c and ppp_impl.h, added compat macro in ppp.h (but disabled for now) --- src/netif/ppp/auth.c | 4 +- src/netif/ppp/ipcp.c | 6 +- src/netif/ppp/ppp.c | 636 +++++++++++++++++++-------------------- src/netif/ppp/ppp_impl.h | 8 +- 4 files changed, 327 insertions(+), 327 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 820d0f64..f8ba2668 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -661,7 +661,7 @@ link_terminated(unit) lcp_lowerdown(0); new_phase(PHASE_DEAD); - pppLinkTerminated(unit); + ppp_link_terminated(unit); #if 0 /* * Delete pid files before disestablishing ppp. Otherwise it @@ -729,7 +729,7 @@ link_down(unit) /* XXX if doing_multilink, should do something to stop network-layer traffic on the link */ - pppLinkDown(unit); + ppp_link_down(unit); } void upper_layers_down(int unit) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 330de3f3..27fb5040 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1762,7 +1762,7 @@ ip_demand_conf(u) wo->accept_local = 1; ask_for_local = 0; /* don't tell the peer this address */ } - if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) + if (!sifaddr(u, wo->ouraddr, wo->hisaddr, get_mask(wo->ouraddr))) return 0; if (!sifup(u)) return 0; @@ -1885,7 +1885,7 @@ ipcp_up(f) script_unsetenv("OLDIPREMOTE"); /* Set the interface to the new addresses */ - mask = GetMask(go->ouraddr); + mask = get_mask(go->ouraddr); if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { if (debug) warn("Interface configuration failed"); @@ -1914,7 +1914,7 @@ ipcp_up(f) /* * Set IP addresses and (if specified) netmask. */ - mask = GetMask(go->ouraddr); + mask = get_mask(go->ouraddr); #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0f96a64f..3be7ec47 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -127,7 +127,7 @@ /*************************/ /** PPP_INPROC_MULTITHREADED==1 call ppp_input using tcpip_callback(). - * Set this to 0 if pppInProc is called inside tcpip_thread or with NO_SYS==1. + * Set this to 0 if pppos_input_proc is called inside tcpip_thread or with NO_SYS==1. * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). */ #ifndef PPP_INPROC_MULTITHREADED @@ -225,10 +225,10 @@ typedef enum { PDPROTOCOL1, /* Process protocol field 1. */ PDPROTOCOL2, /* Process protocol field 2. */ PDDATA /* Process data byte. */ -} PPPDevStates; +} ppp_dev_states; #if PPPOS_SUPPORT -#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07]) +#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & ppp_accm_mask[c & 0x07]) /** RX buffer size: this may be configured smaller! */ #ifndef PPPOS_RX_BUFSIZE @@ -236,7 +236,7 @@ typedef enum { #endif #endif /* PPPOS_SUPPORT */ -typedef struct PPPControlRx_s { +typedef struct ppp_control_rx_s { /** unit number / ppp descriptor */ int pd; /** the rx file descriptor */ @@ -248,51 +248,51 @@ typedef struct PPPControlRx_s { #if PPPOS_SUPPORT /* The input packet. */ - struct pbuf *inHead, *inTail; + struct pbuf *in_head, *in_tail; - u16_t inProtocol; /* The input protocol code. */ - u16_t inFCS; /* Input Frame Check Sequence value. */ - PPPDevStates inState; /* The input process state. */ - char inEscaped; /* Escape next character. */ - ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ + u16_t in_protocol; /* The input protocol code. */ + u16_t in_fcs; /* Input Frame Check Sequence value. */ + ppp_dev_states in_state; /* The input process state. */ + char in_escaped; /* Escape next character. */ + ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ #endif /* PPPOS_SUPPORT */ -} PPPControlRx; +} ppp_control_rx; /* * PPP interface control block. */ -typedef struct PPPControl_s { - PPPControlRx rx; - char openFlag; /* True when in use. */ +typedef struct ppp_control_s { + ppp_control_rx rx; + char open_flag; /* True when in use. */ #if PPPOE_SUPPORT struct netif *ethif; struct pppoe_softc *pppoe_sc; #endif /* PPPOE_SUPPORT */ int if_up; /* True when the interface is up. */ - int errCode; /* Code indicating why interface is down. */ + int err_code; /* Code indicating why interface is down. */ #if PPPOS_SUPPORT sio_fd_t fd; /* File device ID of port. */ #endif /* PPPOS_SUPPORT */ u16_t mtu; /* Peer's mru */ int pcomp; /* Does peer accept protocol compression? */ int accomp; /* Does peer accept addr/ctl compression? */ - u_long lastXMit; /* Time of last transmission. */ + u_long last_xmit; /* Time of last transmission. */ #if PPPOS_SUPPORT - ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ + ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ #endif /* PPPOS_SUPPORT */ #if PPPOS_SUPPORT && VJ_SUPPORT - int vjEnabled; /* Flag indicating VJ compression enabled. */ - struct vjcompress vjComp; /* Van Jacobson compression header. */ + int vj_enabled; /* Flag indicating VJ compression enabled. */ + struct vjcompress vj_comp; /* Van Jacobson compression header. */ #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ struct netif netif; struct ppp_addrs addrs; - void (*link_status_cb)(void *ctx, int errCode, void *arg); + void (*link_status_cb)(void *ctx, int err_code, void *arg); void *link_status_ctx; -} PPPControl; +} ppp_control; /* Prototypes for procedures local to this file. */ @@ -300,19 +300,19 @@ static void ppp_start(int pd); /** Initiate LCP open request */ static void ppp_input(void *arg); #if PPPOS_SUPPORT -static void pppRecvWakeup(int pd); +static void ppp_receive_wakeup(int pd); #endif /* #if PPPOS_SUPPORT */ -static void pppStop(int pd); -static void pppHup(int pd); +static void ppp_stop(int pd); +static void ppp_hup(int pd); #if PPPOS_SUPPORT #if PPP_INPROC_OWNTHREAD -static void pppInputThread(void *arg); +static void ppp_input_thread(void *arg); #endif /* PPP_INPROC_OWNTHREAD */ -static void pppDrop(PPPControlRx *pcrx); -static void pppInProc(PPPControlRx *pcrx, u_char *s, int l); -static void pppFreeCurrentInputPacket(PPPControlRx *pcrx); +static void ppp_drop(ppp_control_rx *pcrx); +static void pppos_input_proc(ppp_control_rx *pcrx, u_char *s, int l); +static void ppp_free_current_input_packet(ppp_control_rx *pcrx); #endif /* PPPOS_SUPPORT */ static err_t ppp_netif_init_cb(struct netif *netif); @@ -328,7 +328,7 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n); /******************************/ /*** PUBLIC DATA STRUCTURES ***/ /******************************/ -static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ +static ppp_control ppp_control_list[NUM_PPP]; /* The PPP interface control blocks. */ /** Input helper struct, must be packed since it is stored to pbuf->payload, * which might be unaligned. @@ -337,7 +337,7 @@ static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ # include "arch/bpstruct.h" #endif PACK_STRUCT_BEGIN -struct pppInputHeader { +struct ppp_input_header { PACK_STRUCT_FIELD(int unit); PACK_STRUCT_FIELD(u16_t proto); } PACK_STRUCT_STRUCT; @@ -498,7 +498,7 @@ void ppp_set_auth(enum ppp_auth_type authtype, const char *user, const char *pas * pppOpen() is directly defined to this function. */ int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { - PPPControl *pc; + ppp_control *pc; int pd; if (link_status_cb == NULL) { @@ -508,32 +508,32 @@ int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void } /* Find a free PPP session descriptor. */ - for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + for (pd = 0; pd < NUM_PPP && ppp_control_list[pd].open_flag != 0; pd++); if (pd >= NUM_PPP) { pd = PPPERR_OPEN; } else { - pc = &pppControl[pd]; + pc = &ppp_control_list[pd]; /* input pbuf left over from last session? */ - pppFreeCurrentInputPacket(&pc->rx); + ppp_free_current_input_packet(&pc->rx); /* @todo: is this correct or do I overwrite something? */ - memset(pc, 0, sizeof(PPPControl)); + memset(pc, 0, sizeof(ppp_control)); pc->rx.pd = pd; pc->rx.fd = fd; - pc->openFlag = 1; + pc->open_flag = 1; pc->fd = fd; #if VJ_SUPPORT - vj_compress_init(&pc->vjComp); + vj_compress_init(&pc->vj_comp); #endif /* VJ_SUPPORT */ /* * Default the in and out accm so that escape and flag characters * are always escaped. */ - pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */ - pc->outACCM[15] = 0x60; + pc->rx.in_accm[15] = 0x60; /* no need to protect since RX is not running */ + pc->out_accm[15] = 0x60; pc->link_status_cb = link_status_cb; pc->link_status_ctx = link_status_ctx; @@ -544,7 +544,7 @@ int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pd)); ppp_start(pd); #if PPP_INPROC_OWNTHREAD - sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); + sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); #endif /* PPP_INPROC_OWNTHREAD */ } @@ -555,13 +555,13 @@ int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void * ppp_set_xaccm - set the extended transmit ACCM for the interface. */ void ppp_set_xaccm(int unit, ext_accm *accm) { - SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm)); - PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n", + SMEMCPY(ppp_control_list[unit].out_accm, accm, sizeof(ext_accm)); + PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: out_accm=%X %X %X %X\n", unit, - pppControl[unit].outACCM[0], - pppControl[unit].outACCM[1], - pppControl[unit].outACCM[2], - pppControl[unit].outACCM[3])); + ppp_control_list[unit].out_accm[0], + ppp_control_list[unit].out_accm[1], + ppp_control_list[unit].out_accm[2], + ppp_control_list[unit].out_accm[3])); } #endif /* PPPOS_SUPPORT */ @@ -570,7 +570,7 @@ static void ppp_over_ethernet_link_status_cb(int pd, int up); int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { - PPPControl *pc; + ppp_control *pc; int pd; LWIP_UNUSED_ARG(service_name); @@ -583,13 +583,13 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const } /* Find a free PPP session descriptor. Critical region? */ - for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + for (pd = 0; pd < NUM_PPP && ppp_control_list[pd].open_flag != 0; pd++); if (pd >= NUM_PPP) { pd = PPPERR_OPEN; } else { - pc = &pppControl[pd]; - memset(pc, 0, sizeof(PPPControl)); - pc->openFlag = 1; + pc = &ppp_control_list[pd]; + memset(pc, 0, sizeof(ppp_control)); + pc->open_flag = 1; pc->ethif = ethif; pc->link_status_cb = link_status_cb; @@ -606,7 +606,7 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const lcp_allowoptions[pd].neg_accompression = 0; if(pppoe_create(ethif, pd, ppp_over_ethernet_link_status_cb, &pc->pppoe_sc) != ERR_OK) { - pc->openFlag = 0; + pc->open_flag = 0; return PPPERR_OPEN; } @@ -617,7 +617,7 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const } void pppOverEthernetClose(int pd) { - PPPControl* pc = &pppControl[pd]; + ppp_control* pc = &ppp_control_list[pd]; /* *TJL* There's no lcp_deinit */ lcp_close(pd, NULL); @@ -633,7 +633,7 @@ void pppOverEthernetClose(int pd) { int ppp_close(int pd) { - PPPControl *pc = &pppControl[pd]; + ppp_control *pc = &ppp_control_list[pd]; int st = 0; PPPDEBUG(LOG_DEBUG, ("ppp_close() called\n")); @@ -641,20 +641,20 @@ ppp_close(int pd) /* Disconnect */ #if PPPOE_SUPPORT if(pc->ethif) { - PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> pppStop\n", pd)); - pc->errCode = PPPERR_USER; + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pd)); + pc->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ - pppStop(pd); + ppp_stop(pd); } else #endif /* PPPOE_SUPPORT */ { #if PPPOS_SUPPORT - PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> pppStop\n", pd)); - pc->errCode = PPPERR_USER; + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pd)); + pc->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ - pppStop(pd); + ppp_stop(pd); #if PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); + ppp_receive_wakeup(pd); #endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ } @@ -666,8 +666,8 @@ ppp_close(int pd) void ppp_sighup(int pd) { - PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> pppHupCB\n", pd)); - pppHup(pd); + PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hupCB\n", pd)); + ppp_hup(pd); } @@ -683,17 +683,17 @@ static void ppp_start(int pd) { /** LCP close request */ static void -pppStop(int pd) +ppp_stop(int pd) { - PPPDEBUG(LOG_DEBUG, ("pppStop: unit %d\n", pd)); + PPPDEBUG(LOG_DEBUG, ("ppp_stop: unit %d\n", pd)); lcp_close(pd, "User request"); } /** Called when carrier/link is lost */ static void -pppHup(int pd) +ppp_hup(int pd) { - PPPDEBUG(LOG_DEBUG, ("pppHupCB: unit %d\n", pd)); + PPPDEBUG(LOG_DEBUG, ("ppp_hupCB: unit %d\n", pd)); lcp_lowerdown(pd); link_terminated(pd); } @@ -703,7 +703,7 @@ pppHup(int pd) * This function and all handlers run in the context of the tcpip_thread */ -/* FIXME: maybe we should pass in two arguments pppInputHeader and payload +/* FIXME: maybe we should pass in two arguments ppp_input_header and payload * this is totally stupid to make room for it and then modify the packet directly * or it is used in output ? have to find out... */ @@ -712,17 +712,17 @@ static void ppp_input(void *arg) { u16_t protocol; int pd; - pd = ((struct pppInputHeader *)nb->payload)->unit; - protocol = ((struct pppInputHeader *)nb->payload)->proto; + pd = ((struct ppp_input_header *)nb->payload)->unit; + protocol = ((struct ppp_input_header *)nb->payload)->proto; - if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { + if(pbuf_header(nb, -(int)sizeof(struct ppp_input_header))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } LINK_STATS_INC(link.recv); - snmp_inc_ifinucastpkts(&pppControl[pd].netif); - snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); + snmp_inc_ifinucastpkts(&ppp_control_list[pd].netif); + snmp_add_ifinoctets(&ppp_control_list[pd].netif, nb->tot_len); /* * Toss all non-LCP packets unless LCP is OPEN. @@ -769,8 +769,8 @@ static void ppp_input(void *arg) { * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); + if ((vj_uncompress_tcp(&nb, &ppp_control_list[pd].vj_comp) >= 0) && (ppp_control_list[pd].netif.input)) { + ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); return; } /* Something's wrong so drop it. */ @@ -783,8 +783,8 @@ static void ppp_input(void *arg) { * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); + if ((vj_uncompress_uncomp(nb, &ppp_control_list[pd].vj_comp) >= 0) && ppp_control_list[pd].netif.input) { + ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); return; } /* Something's wrong so drop it. */ @@ -794,8 +794,8 @@ static void ppp_input(void *arg) { case PPP_IP: /* Internet Protocol */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); + if (ppp_control_list[pd].netif.input) { + ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); return; } break; @@ -850,7 +850,7 @@ static void ppp_input(void *arg) { drop: LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); + snmp_inc_ifindiscards(&ppp_control_list[pd].netif); out: pbuf_free(nb); @@ -878,8 +878,8 @@ out: * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); + if ((vj_uncompress_tcp(&nb, &ppp_control_list[pd].vj_comp) >= 0) && (ppp_control_list[pd].netif.input)) { + ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); return; } /* Something's wrong so drop it. */ @@ -897,8 +897,8 @@ out: * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); + if ((vj_uncompress_uncomp(nb, &ppp_control_list[pd].vj_comp) >= 0) && ppp_control_list[pd].netif.input) { + ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); return; } /* Something's wrong so drop it. */ @@ -913,8 +913,8 @@ out: case PPP_IP: /* Internet Protocol */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (pppControl[pd].netif.input) { - pppControl[pd].netif.input(nb, &pppControl[pd].netif); + if (ppp_control_list[pd].netif.input) { + ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); return; } break; @@ -997,7 +997,7 @@ static const u_short fcstab[256] = { /* PPP's Asynchronous-Control-Character-Map. The mask array is used * to select the specific bit for a character. */ -static u_char pppACCMMask[] = { +static u_char ppp_accm_mask[] = { 0x01, 0x02, 0x04, @@ -1011,11 +1011,11 @@ static u_char pppACCMMask[] = { #if PPP_INPROC_OWNTHREAD /** Wake up the task blocked in reading from serial line (if any) */ static void -pppRecvWakeup(int pd) +ppp_receive_wakeup(int pd) { - PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd)); - if (pppControl[pd].openFlag != 0) { - sio_read_abort(pppControl[pd].fd); + PPPDEBUG(LOG_DEBUG, ("ppp_receive_wakeup: unit %d\n", pd)); + if (ppp_control_list[pd].open_flag != 0) { + sio_read_abort(ppp_control_list[pd].fd); } } #endif /* PPP_INPROC_OWNTHREAD */ @@ -1027,23 +1027,23 @@ pppRecvWakeup(int pd) * take a packet from PPPoE subsystem and pass it to the PPP stack through ppp_input() */ -/* FIXME: maybe we should pass in two arguments pppInputHeader and payload +/* FIXME: maybe we should pass in two arguments ppp_input_header and payload * this is totally stupid to make room for it and then modify the packet directly * or it is used in output ? have to find out... */ void ppp_input_over_ethernet(int pd, struct pbuf *pb) { - struct pppInputHeader *pih; - u16_t inProtocol; + struct ppp_input_header *pih; + u16_t in_protocol; - if(pb->len < sizeof(inProtocol)) { + if(pb->len < sizeof(in_protocol)) { PPPDEBUG(LOG_ERR, ("ppp_input_over_ethernet: too small for protocol field\n")); goto drop; } - inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; + in_protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - /* make room for pppInputHeader - should not fail */ - if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { + /* make room for ppp_input_header - should not fail */ + if (pbuf_header(pb, sizeof(*pih) - sizeof(in_protocol)) != 0) { PPPDEBUG(LOG_ERR, ("ppp_input_over_ethernet: could not allocate room for header\n")); goto drop; } @@ -1051,7 +1051,7 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb) { pih = pb->payload; pih->unit = pd; - pih->proto = inProtocol; + pih->proto = in_protocol; /* Dispatch the packet thereby consuming it. */ ppp_input(pb); @@ -1059,7 +1059,7 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb) { drop: LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pd].netif); + snmp_inc_ifindiscards(&ppp_control_list[pd].netif); pbuf_free(pb); return; } @@ -1090,15 +1090,15 @@ static err_t ppp_netif_init_cb(struct netif *netif) { /* The main PPP process function. This implements the state machine according * to section 4 of RFC 1661: The Point-To-Point Protocol. */ static void -pppInputThread(void *arg) +ppp_input_thread(void *arg) { int count; - PPPControlRx *pcrx = arg; + ppp_control_rx *pcrx = arg; while (phase != PHASE_DEAD) { count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); if(count > 0) { - pppInProc(pcrx, pcrx->rxbuf, count); + pppos_input_proc(pcrx, pcrx->rxbuf, count); } else { /* nothing received, give other tasks a chance to run */ sys_msleep(1); @@ -1110,7 +1110,7 @@ pppInputThread(void *arg) #if PPPOS_SUPPORT static void -nPut(PPPControl *pc, struct pbuf *nb) +pppos_put(ppp_control *pc, struct pbuf *nb) { struct pbuf *b; int c; @@ -1118,9 +1118,9 @@ nPut(PPPControl *pc, struct pbuf *nb) for(b = nb; b != NULL; b = b->next) { if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) { PPPDEBUG(LOG_WARNING, - ("PPP nPut: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); + ("PPP pppos_put: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); LINK_STATS_INC(link.err); - pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */ + pc->last_xmit = 0; /* prepend PPP_FLAG to next packet */ snmp_inc_ifoutdiscards(&pc->netif); pbuf_free(nb); return; @@ -1134,13 +1134,13 @@ nPut(PPPControl *pc, struct pbuf *nb) } /* - * pppAppend - append given character to end of given pbuf. If outACCM + * ppp_append - append given character to end of given pbuf. If out_accm * is not NULL and the character needs to be escaped, do so. * If pbuf is full, append another. * Return the current pbuf. */ static struct pbuf * -pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM) +ppp_append(u_char c, struct pbuf *nb, ext_accm *out_accm) { struct pbuf *tb = nb; @@ -1159,7 +1159,7 @@ pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM) } if (nb) { - if (outACCM && ESCAPE_P(*outACCM, c)) { + if (out_accm && ESCAPE_P(*out_accm, c)) { *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE; *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS; } else { @@ -1177,11 +1177,11 @@ pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM) */ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { int pd = (int)(size_t)netif->state; - PPPControl *pc = &pppControl[pd]; + ppp_control *pc = &ppp_control_list[pd]; #if PPPOS_SUPPORT u_short protocol = PPP_IP; - u_int fcsOut = PPP_INITFCS; - struct pbuf *headMB = NULL, *tailMB = NULL, *p; + u_int fcs_out = PPP_INITFCS; + struct pbuf *head = NULL, *tail = NULL, *p; u_char c; #endif /* PPPOS_SUPPORT */ @@ -1190,7 +1190,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i /* Validate parameters. */ /* We let any protocol value go through - it can't hurt us * and the peer will just drop it if it's not accepting it. */ - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { + if (pd < 0 || pd >= NUM_PPP || !pc->open_flag || !pb) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad parms prot=%d pb=%p\n", pd, PPP_IP, (void*)pb)); LINK_STATS_INC(link.opterr); @@ -1216,8 +1216,8 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i #if PPPOS_SUPPORT /* Grab an output buffer. */ - headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (headMB == NULL) { + head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (head == NULL) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: first alloc fail\n", pd)); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); @@ -1230,8 +1230,8 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i * Attempt Van Jacobson header compression if VJ is configured and * this is an IP packet. */ - if (protocol == PPP_IP && pc->vjEnabled) { - switch (vj_compress_tcp(&pc->vjComp, pb)) { + if (protocol == PPP_IP && pc->vj_enabled) { + switch (vj_compress_tcp(&pc->vj_comp, pb)) { case TYPE_IP: /* No change... protocol = PPP_IP_PROTOCOL; */ @@ -1247,34 +1247,34 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i LINK_STATS_INC(link.proterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); - pbuf_free(headMB); + pbuf_free(head); return ERR_VAL; } } #endif /* VJ_SUPPORT */ - tailMB = headMB; + tail = head; /* Build the PPP header. */ - if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + if ((sys_jiffies() - pc->last_xmit) >= PPP_MAXIDLEFLAG) { + tail = ppp_append(PPP_FLAG, tail, NULL); } - pc->lastXMit = sys_jiffies(); + pc->last_xmit = sys_jiffies(); if (!pc->accomp) { - fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS); - tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM); - fcsOut = PPP_FCS(fcsOut, PPP_UI); - tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM); + fcs_out = PPP_FCS(fcs_out, PPP_ALLSTATIONS); + tail = ppp_append(PPP_ALLSTATIONS, tail, &pc->out_accm); + fcs_out = PPP_FCS(fcs_out, PPP_UI); + tail = ppp_append(PPP_UI, tail, &pc->out_accm); } if (!pc->pcomp || protocol > 0xFF) { c = (protocol >> 8) & 0xFF; - fcsOut = PPP_FCS(fcsOut, c); - tailMB = pppAppend(c, tailMB, &pc->outACCM); + fcs_out = PPP_FCS(fcs_out, c); + tail = ppp_append(c, tail, &pc->out_accm); } c = protocol & 0xFF; - fcsOut = PPP_FCS(fcsOut, c); - tailMB = pppAppend(c, tailMB, &pc->outACCM); + fcs_out = PPP_FCS(fcs_out, c); + tail = ppp_append(c, tail, &pc->out_accm); /* Load packet. */ for(p = pb; p; p = p->next) { @@ -1287,26 +1287,26 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i c = *sPtr++; /* Update FCS before checking for special characters. */ - fcsOut = PPP_FCS(fcsOut, c); + fcs_out = PPP_FCS(fcs_out, c); /* Copy to output buffer escaping special characters. */ - tailMB = pppAppend(c, tailMB, &pc->outACCM); + tail = ppp_append(c, tail, &pc->out_accm); } } /* Add FCS and trailing flag. */ - c = ~fcsOut & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - c = (~fcsOut >> 8) & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + c = ~fcs_out & 0xFF; + tail = ppp_append(c, tail, &pc->out_accm); + c = (~fcs_out >> 8) & 0xFF; + tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(PPP_FLAG, tail, NULL); /* If we failed to complete the packet, throw it away. */ - if (!tailMB) { + if (!tail) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: Alloc err - dropping proto=%d\n", pd, protocol)); - pbuf_free(headMB); + pbuf_free(head); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -1316,7 +1316,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i /* Send it. */ PPPDEBUG(LOG_INFO, ("ppp_netif_output[%d]: proto=0x%"X16_F"\n", pd, protocol)); - nPut(pc, headMB); + pppos_put(pc, head); #endif /* PPPOS_SUPPORT */ return ERR_OK; @@ -1324,7 +1324,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i #if PPPOE_SUPPORT static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { - PPPControl *pc = &pppControl[pd]; + ppp_control *pc = &ppp_control_list[pd]; struct pbuf *pb; u_short protocol = PPP_IP; int i=0; @@ -1341,7 +1341,7 @@ static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - pc->lastXMit = sys_jiffies(); + pc->last_xmit = sys_jiffies(); if (!pc->pcomp || protocol > 0xFF) { *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; @@ -1369,11 +1369,11 @@ static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { * Return the Maximum Transmission Unit for the given PPP connection. */ u_short ppp_mtu(int pd) { - PPPControl *pc = &pppControl[pd]; + ppp_control *pc = &ppp_control_list[pd]; u_short st; /* Validate parameters. */ - if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + if (pd < 0 || pd >= NUM_PPP || !pc->open_flag) { st = 0; } else { st = pc->mtu; @@ -1388,7 +1388,7 @@ u_short ppp_mtu(int pd) { int ppp_ioctl(int pd, int cmd, void *arg) { - PPPControl *pc = &pppControl[pd]; + ppp_control *pc = &ppp_control_list[pd]; int st = 0; if (pd < 0 || pd >= NUM_PPP) { @@ -1404,14 +1404,14 @@ ppp_ioctl(int pd, int cmd, void *arg) break; case PPPCTLS_ERRCODE: /* Set the PPP error code. */ if (arg) { - pc->errCode = *(int *)arg; + pc->err_code = *(int *)arg; } else { st = PPPERR_PARAM; } break; case PPPCTLG_ERRCODE: /* Get the PPP error code. */ if (arg) { - *(int *)arg = (int)(pc->errCode); + *(int *)arg = (int)(pc->err_code); } else { st = PPPERR_PARAM; } @@ -1440,11 +1440,11 @@ ppp_ioctl(int pd, int cmd, void *arg) * -1 Failed to write to device */ int ppp_write(int pd, const u_char *s, int n) { - PPPControl *pc = &pppControl[pd]; + ppp_control *pc = &ppp_control_list[pd]; #if PPPOS_SUPPORT u_char c; - u_int fcsOut; - struct pbuf *headMB, *tailMB; + u_int fcs_out; + struct pbuf *head, *tail; #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT @@ -1454,58 +1454,58 @@ int ppp_write(int pd, const u_char *s, int n) { #endif /* PPPOE_SUPPORT */ #if PPPOS_SUPPORT - headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (headMB == NULL) { + head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (head == NULL) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pc->netif); return PPPERR_ALLOC; } - tailMB = headMB; + tail = head; /* If the link has been idle, we'll send a fresh flag character to * flush any noise. */ - if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + if ((sys_jiffies() - pc->last_xmit) >= PPP_MAXIDLEFLAG) { + tail = ppp_append(PPP_FLAG, tail, NULL); } - pc->lastXMit = sys_jiffies(); + pc->last_xmit = sys_jiffies(); - fcsOut = PPP_INITFCS; + fcs_out = PPP_INITFCS; /* Load output buffer. */ while (n-- > 0) { c = *s++; /* Update FCS before checking for special characters. */ - fcsOut = PPP_FCS(fcsOut, c); + fcs_out = PPP_FCS(fcs_out, c); /* Copy to output buffer escaping special characters. */ - tailMB = pppAppend(c, tailMB, &pc->outACCM); + tail = ppp_append(c, tail, &pc->out_accm); } /* Add FCS and trailing flag. */ - c = ~fcsOut & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - c = (~fcsOut >> 8) & 0xFF; - tailMB = pppAppend(c, tailMB, &pc->outACCM); - tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + c = ~fcs_out & 0xFF; + tail = ppp_append(c, tail, &pc->out_accm); + c = (~fcs_out >> 8) & 0xFF; + tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(PPP_FLAG, tail, NULL); /* If we failed to complete the packet, throw it away. * Otherwise send it. */ - if (!tailMB) { + if (!tail) { PPPDEBUG(LOG_WARNING, - ("ppp_write[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); - /*"ppp_write[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ - pbuf_free(headMB); + ("ppp_write[%d]: Alloc err - dropping pbuf len=%d\n", pd, head->len)); + /*"ppp_write[%d]: Alloc err - dropping %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ + pbuf_free(head); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pc->netif); return PPPERR_ALLOC; } - PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pd, headMB->len)); - /* "ppp_write[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ - nPut(pc, headMB); + PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pd, head->len)); + /* "ppp_write[%d]: %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ + pppos_put(pc, head); #endif /* PPPOS_SUPPORT */ return PPPERR_NONE; @@ -1513,7 +1513,7 @@ int ppp_write(int pd, const u_char *s, int n) { #if PPPOE_SUPPORT static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { - PPPControl *pc = &pppControl[pd]; + ppp_control *pc = &ppp_control_list[pd]; struct pbuf *pb; /* skip address & flags */ @@ -1531,7 +1531,7 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - pc->lastXMit = sys_jiffies(); + pc->last_xmit = sys_jiffies(); MEMCPY(pb->payload, s, n); @@ -1554,37 +1554,37 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { * Drop the input packet. */ static void -pppFreeCurrentInputPacket(PPPControlRx *pcrx) +ppp_free_current_input_packet(ppp_control_rx *pcrx) { - if (pcrx->inHead != NULL) { - if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) { - pbuf_free(pcrx->inTail); + if (pcrx->in_head != NULL) { + if (pcrx->in_tail && (pcrx->in_tail != pcrx->in_head)) { + pbuf_free(pcrx->in_tail); } - pbuf_free(pcrx->inHead); - pcrx->inHead = NULL; + pbuf_free(pcrx->in_head); + pcrx->in_head = NULL; } - pcrx->inTail = NULL; + pcrx->in_tail = NULL; } /* * Drop the input packet and increase error counters. */ static void -pppDrop(PPPControlRx *pcrx) +ppp_drop(ppp_control_rx *pcrx) { - if (pcrx->inHead != NULL) { + if (pcrx->in_head != NULL) { #if 0 - PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload)); + PPPDEBUG(LOG_INFO, ("ppp_drop: %d:%.*H\n", pcrx->in_head->len, min(60, pcrx->in_head->len * 2), pcrx->in_head->payload)); #endif - PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead)); + PPPDEBUG(LOG_INFO, ("ppp_drop: pbuf len=%d, addr %p\n", pcrx->in_head->len, (void*)pcrx->in_head)); } - pppFreeCurrentInputPacket(pcrx); + ppp_free_current_input_packet(pcrx); #if VJ_SUPPORT - vj_uncompress_err(&pppControl[pcrx->pd].vjComp); + vj_uncompress_err(&ppp_control_list[pcrx->pd].vj_comp); #endif /* VJ_SUPPORT */ LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); + snmp_inc_ifindiscards(&ppp_control_list[pcrx->pd].netif); } #if !PPP_INPROC_OWNTHREAD @@ -1598,7 +1598,7 @@ pppDrop(PPPControlRx *pcrx) void pppos_input(int pd, u_char* data, int len) { - pppInProc(&pppControl[pd].rx, data, len); + pppos_input_proc(&ppp_control_list[pd].rx, data, len); } #endif @@ -1606,19 +1606,19 @@ pppos_input(int pd, u_char* data, int len) * Process a received octet string. */ static void -pppInProc(PPPControlRx *pcrx, u_char *s, int l) +pppos_input_proc(ppp_control_rx *pcrx, u_char *s, int l) { - struct pbuf *nextNBuf; - u_char curChar; + struct pbuf *next_pbuf; + u_char cur_char; u_char escaped; SYS_ARCH_DECL_PROTECT(lev); - PPPDEBUG(LOG_DEBUG, ("pppInProc[%d]: got %d bytes\n", pcrx->pd, l)); + PPPDEBUG(LOG_DEBUG, ("pppos_input_proc[%d]: got %d bytes\n", pcrx->pd, l)); while (l-- > 0) { - curChar = *s++; + cur_char = *s++; SYS_ARCH_PROTECT(lev); - escaped = ESCAPE_P(pcrx->inACCM, curChar); + escaped = ESCAPE_P(pcrx->in_accm, cur_char); SYS_ARCH_UNPROTECT(lev); /* Handle special characters. */ if (escaped) { @@ -1627,59 +1627,59 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l) * would appear as an escape character. Since this is an ASCII ']' * and there is no reason that I know of to escape it, I won't complicate * the code to handle this case. GLL */ - if (curChar == PPP_ESCAPE) { - pcrx->inEscaped = 1; + if (cur_char == PPP_ESCAPE) { + pcrx->in_escaped = 1; /* Check for the flag character. */ - } else if (curChar == PPP_FLAG) { + } else if (cur_char == PPP_FLAG) { /* If this is just an extra flag character, ignore it. */ - if (pcrx->inState <= PDADDRESS) { + if (pcrx->in_state <= PDADDRESS) { /* ignore it */; /* If we haven't received the packet header, drop what has come in. */ - } else if (pcrx->inState < PDDATA) { + } else if (pcrx->in_state < PDDATA) { PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Dropping incomplete packet %d\n", - pcrx->pd, pcrx->inState)); + ("pppos_input_proc[%d]: Dropping incomplete packet %d\n", + pcrx->pd, pcrx->in_state)); LINK_STATS_INC(link.lenerr); - pppDrop(pcrx); + ppp_drop(pcrx); /* If the fcs is invalid, drop the packet. */ - } else if (pcrx->inFCS != PPP_GOODFCS) { + } else if (pcrx->in_fcs != PPP_GOODFCS) { PPPDEBUG(LOG_INFO, - ("pppInProc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", - pcrx->pd, pcrx->inFCS, pcrx->inProtocol)); + ("pppos_input_proc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", + pcrx->pd, pcrx->in_fcs, pcrx->in_protocol)); /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ LINK_STATS_INC(link.chkerr); - pppDrop(pcrx); + ppp_drop(pcrx); /* Otherwise it's a good packet so pass it on. */ } else { struct pbuf *inp; /* Trim off the checksum. */ - if(pcrx->inTail->len > 2) { - pcrx->inTail->len -= 2; + if(pcrx->in_tail->len > 2) { + pcrx->in_tail->len -= 2; - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); + pcrx->in_tail->tot_len = pcrx->in_tail->len; + if (pcrx->in_tail != pcrx->in_head) { + pbuf_cat(pcrx->in_head, pcrx->in_tail); } } else { - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); + pcrx->in_tail->tot_len = pcrx->in_tail->len; + if (pcrx->in_tail != pcrx->in_head) { + pbuf_cat(pcrx->in_head, pcrx->in_tail); } - pbuf_realloc(pcrx->inHead, pcrx->inHead->tot_len - 2); + pbuf_realloc(pcrx->in_head, pcrx->in_head->tot_len - 2); } /* Dispatch the packet thereby consuming it. */ - inp = pcrx->inHead; + inp = pcrx->in_head; /* Packet consumed, release our references. */ - pcrx->inHead = NULL; - pcrx->inTail = NULL; + pcrx->in_head = NULL; + pcrx->in_tail = NULL; #if PPP_INPROC_MULTITHREADED if(tcpip_callback_with_block(ppp_input, inp, 0) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); + PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); pbuf_free(inp); LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); + snmp_inc_ifindiscards(&ppp_control_list[pcrx->pd].netif); } #else /* PPP_INPROC_MULTITHREADED */ ppp_input(inp); @@ -1687,115 +1687,115 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l) } /* Prepare for a new packet. */ - pcrx->inFCS = PPP_INITFCS; - pcrx->inState = PDADDRESS; - pcrx->inEscaped = 0; + pcrx->in_fcs = PPP_INITFCS; + pcrx->in_state = PDADDRESS; + pcrx->in_escaped = 0; /* Other characters are usually control characters that may have * been inserted by the physical layer so here we just drop them. */ } else { PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, curChar)); + ("pppos_input_proc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, cur_char)); } /* Process other characters. */ } else { /* Unencode escaped characters. */ - if (pcrx->inEscaped) { - pcrx->inEscaped = 0; - curChar ^= PPP_TRANS; + if (pcrx->in_escaped) { + pcrx->in_escaped = 0; + cur_char ^= PPP_TRANS; } /* Process character relative to current state. */ - switch(pcrx->inState) { + switch(pcrx->in_state) { case PDIDLE: /* Idle state - waiting. */ /* Drop the character if it's not 0xff * we would have processed a flag character above. */ - if (curChar != PPP_ALLSTATIONS) { + if (cur_char != PPP_ALLSTATIONS) { break; } /* Fall through */ case PDSTART: /* Process start flag. */ /* Prepare for a new packet. */ - pcrx->inFCS = PPP_INITFCS; + pcrx->in_fcs = PPP_INITFCS; /* Fall through */ case PDADDRESS: /* Process address field. */ - if (curChar == PPP_ALLSTATIONS) { - pcrx->inState = PDCONTROL; + if (cur_char == PPP_ALLSTATIONS) { + pcrx->in_state = PDCONTROL; break; } /* Else assume compressed address and control fields so * fall through to get the protocol... */ case PDCONTROL: /* Process control field. */ /* If we don't get a valid control code, restart. */ - if (curChar == PPP_UI) { - pcrx->inState = PDPROTOCOL1; + if (cur_char == PPP_UI) { + pcrx->in_state = PDPROTOCOL1; break; } #if 0 else { PPPDEBUG(LOG_WARNING, - ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar)); - pcrx->inState = PDSTART; + ("pppos_input_proc[%d]: Invalid control <%d>\n", pcrx->pd, cur_char)); + pcrx->in_state = PDSTART; } #endif case PDPROTOCOL1: /* Process protocol field 1. */ /* If the lower bit is set, this is the end of the protocol * field. */ - if (curChar & 1) { - pcrx->inProtocol = curChar; - pcrx->inState = PDDATA; + if (cur_char & 1) { + pcrx->in_protocol = cur_char; + pcrx->in_state = PDDATA; } else { - pcrx->inProtocol = (u_int)curChar << 8; - pcrx->inState = PDPROTOCOL2; + pcrx->in_protocol = (u_int)cur_char << 8; + pcrx->in_state = PDPROTOCOL2; } break; case PDPROTOCOL2: /* Process protocol field 2. */ - pcrx->inProtocol |= curChar; - pcrx->inState = PDDATA; + pcrx->in_protocol |= cur_char; + pcrx->in_state = PDDATA; break; case PDDATA: /* Process data byte. */ /* Make space to receive processed data. */ - if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) { - if (pcrx->inTail != NULL) { - pcrx->inTail->tot_len = pcrx->inTail->len; - if (pcrx->inTail != pcrx->inHead) { - pbuf_cat(pcrx->inHead, pcrx->inTail); - /* give up the inTail reference now */ - pcrx->inTail = NULL; + if (pcrx->in_tail == NULL || pcrx->in_tail->len == PBUF_POOL_BUFSIZE) { + if (pcrx->in_tail != NULL) { + pcrx->in_tail->tot_len = pcrx->in_tail->len; + if (pcrx->in_tail != pcrx->in_head) { + pbuf_cat(pcrx->in_head, pcrx->in_tail); + /* give up the in_tail reference now */ + pcrx->in_tail = NULL; } } /* If we haven't started a packet, we need a packet header. */ - nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (nextNBuf == NULL) { + next_pbuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (next_pbuf == NULL) { /* No free buffers. Drop the input packet and let the * higher layers deal with it. Continue processing * the received pbuf chain in case a new packet starts. */ - PPPDEBUG(LOG_ERR, ("pppInProc[%d]: NO FREE MBUFS!\n", pcrx->pd)); + PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: NO FREE MBUFS!\n", pcrx->pd)); LINK_STATS_INC(link.memerr); - pppDrop(pcrx); - pcrx->inState = PDSTART; /* Wait for flag sequence. */ + ppp_drop(pcrx); + pcrx->in_state = PDSTART; /* Wait for flag sequence. */ break; } - if (pcrx->inHead == NULL) { - struct pppInputHeader *pih = nextNBuf->payload; + if (pcrx->in_head == NULL) { + struct ppp_input_header *pih = next_pbuf->payload; pih->unit = pcrx->pd; - pih->proto = pcrx->inProtocol; + pih->proto = pcrx->in_protocol; - nextNBuf->len += sizeof(*pih); + next_pbuf->len += sizeof(*pih); - pcrx->inHead = nextNBuf; + pcrx->in_head = next_pbuf; } - pcrx->inTail = nextNBuf; + pcrx->in_tail = next_pbuf; } /* Load character into buffer. */ - ((u_char*)pcrx->inTail->payload)[pcrx->inTail->len++] = curChar; + ((u_char*)pcrx->in_tail->payload)[pcrx->in_tail->len++] = cur_char; break; } /* update the frame check sequence number. */ - pcrx->inFCS = PPP_FCS(pcrx->inFCS, curChar); + pcrx->in_fcs = PPP_FCS(pcrx->in_fcs, cur_char); } } /* while (l-- > 0), all bytes processed */ @@ -1830,18 +1830,18 @@ struct pbuf * ppp_singlebuf(struct pbuf *p) { } #if PPPOE_SUPPORT -void pppOverEthernetInitFailed(int pd) { - PPPControl* pc; +void ppp_over_ethernet_init_failed(int pd) { + ppp_control* pc; - pppHup(pd); - pppStop(pd); + ppp_hup(pd); + ppp_stop(pd); - pc = &pppControl[pd]; + pc = &ppp_control_list[pd]; pppoe_destroy(&pc->netif); - pc->openFlag = 0; + pc->open_flag = 0; if(pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_PROTOCOL, NULL); } } @@ -1850,51 +1850,51 @@ static void ppp_over_ethernet_link_status_cb(int pd, int up) { PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: Connecting\n", pd)); ppp_start(pd); } else { - pppOverEthernetInitFailed(pd); + ppp_over_ethernet_init_failed(pd); } } #endif /* PPPOE_SUPPORT */ -void pppLinkDown(int pd) { - PPPDEBUG(LOG_DEBUG, ("pppLinkDown: unit %d\n", pd)); +void ppp_link_down(int pd) { + PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pd)); #if PPPOE_SUPPORT - if (pppControl[pd].ethif) { - pppoe_disconnect(pppControl[pd].pppoe_sc); + if (ppp_control_list[pd].ethif) { + pppoe_disconnect(ppp_control_list[pd].pppoe_sc); } else #endif /* PPPOE_SUPPORT */ { #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); + ppp_receive_wakeup(pd); #endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ } } -void pppLinkTerminated(int pd) { - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d\n", pd)); +void ppp_link_terminated(int pd) { + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d\n", pd)); #if PPPOE_SUPPORT - if (pppControl[pd].ethif) { - pppoe_disconnect(pppControl[pd].pppoe_sc); + if (ppp_control_list[pd].ethif) { + pppoe_disconnect(ppp_control_list[pd].pppoe_sc); } else #endif /* PPPOE_SUPPORT */ { #if PPPOS_SUPPORT - PPPControl* pc; + ppp_control* pc; #if PPP_INPROC_OWNTHREAD - pppRecvWakeup(pd); + ppp_receive_wakeup(pd); #endif /* PPP_INPROC_OWNTHREAD */ - pc = &pppControl[pd]; + pc = &ppp_control_list[pd]; - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: link_status_cb=%p errCode=%d\n", pd, pc->link_status_cb, pc->errCode)); + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pd, pc->link_status_cb, pc->err_code)); if (pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_PROTOCOL, NULL); } - pc->openFlag = 0;/**/ + pc->open_flag = 0;/**/ #endif /* PPPOS_SUPPORT */ } - PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: finished.\n")); + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: finished.\n")); } @@ -1909,7 +1909,7 @@ void pppLinkTerminated(int pd) { void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback) { - netif_set_status_callback(&pppControl[pd].netif, status_callback); + netif_set_status_callback(&ppp_control_list[pd].netif, status_callback); } #endif /* LWIP_NETIF_STATUS_CALLBACK */ @@ -1924,7 +1924,7 @@ ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback) void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback) { - netif_set_link_callback(&pppControl[pd].netif, link_callback); + netif_set_link_callback(&ppp_control_list[pd].netif, link_callback); } #endif /* LWIP_NETIF_LINK_CALLBACK */ @@ -1948,7 +1948,7 @@ void new_phase(int p) { * the ppp interface. */ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { - PPPControl *pc = &pppControl[unit]; + ppp_control *pc = &ppp_control_list[unit]; #if PPPOS_SUPPORT int i; #endif /* PPPOS_SUPPORT */ @@ -1960,16 +1960,16 @@ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT /* Load the ACCM bits for the 32 control codes. */ for (i = 0; i < 32/8; i++) { - pc->outACCM[i] = (u_char)((accm >> (8 * i)) & 0xFF); + pc->out_accm[i] = (u_char)((accm >> (8 * i)) & 0xFF); } #else LWIP_UNUSED_ARG(accm); #endif /* PPPOS_SUPPORT */ #if PPPOS_SUPPORT - PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: out_accm=%X %X %X %X\n", unit, - pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); + pc->out_accm[0], pc->out_accm[1], pc->out_accm[2], pc->out_accm[3])); #else PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", unit) ); #endif /* PPPOS_SUPPORT */ @@ -1982,7 +1982,7 @@ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { */ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT - PPPControl *pc = &pppControl[unit]; + ppp_control *pc = &ppp_control_list[unit]; int i; SYS_ARCH_DECL_PROTECT(lev); #endif /* PPPOS_SUPPORT */ @@ -1996,7 +1996,7 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { SYS_ARCH_PROTECT(lev); for (i = 0; i < 32 / 8; i++) { /* @todo: does this work? ext_accm has been modified from pppd! */ - pc->rx.inACCM[i] = (u_char)(accm >> (i * 8)); + pc->rx.in_accm[i] = (u_char)(accm >> (i * 8)); } SYS_ARCH_UNPROTECT(lev); #else @@ -2004,9 +2004,9 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { #endif /* PPPOS_SUPPORT */ #if PPPOS_SUPPORT - PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: in_accm=%X %X %X %X\n", unit, - pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); + pc->rx.in_accm[0], pc->rx.in_accm[1], pc->rx.in_accm[2], pc->rx.in_accm[3])); #else PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", unit) ); #endif /* PPPOS_SUPPORT */ @@ -2019,10 +2019,10 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { */ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask) { - PPPControl *pc = &pppControl[unit]; + ppp_control *pc = &ppp_control_list[unit]; int st = 1; - if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); } else { @@ -2043,12 +2043,12 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, * through the interface if possible. */ int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr) { - PPPControl *pc = &pppControl[unit]; + ppp_control *pc = &ppp_control_list[unit]; int st = 1; LWIP_UNUSED_ARG(our_adr); LWIP_UNUSED_ARG(his_adr); - if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad parms\n", unit)); } else { @@ -2066,10 +2066,10 @@ int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr) { */ int sifup(int u) { - PPPControl *pc = &pppControl[u]; + ppp_control *pc = &ppp_control_list[u]; int st = 1; - if (u < 0 || u >= NUM_PPP || !pc->openFlag) { + if (u < 0 || u >= NUM_PPP || !pc->open_flag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", u)); } else { @@ -2078,11 +2078,11 @@ int sifup(int u) &pc->addrs.his_ipaddr, (void *)(size_t)u, ppp_netif_init_cb, ip_input)) { netif_set_up(&pc->netif); pc->if_up = 1; - pc->errCode = PPPERR_NONE; + pc->err_code = PPPERR_NONE; - PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p errCode=%d\n", u, pc->link_status_cb, pc->errCode)); + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p err_code=%d\n", u, pc->link_status_cb, pc->err_code)); if (pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, pc->errCode, &pc->addrs); + pc->link_status_cb(pc->link_status_ctx, pc->err_code, &pc->addrs); } } else { st = 0; @@ -2099,10 +2099,10 @@ int sifup(int u) * down if there are no remaining protocols. */ int sifdown(int unit) { - PPPControl *pc = &pppControl[unit]; + ppp_control *pc = &ppp_control_list[unit]; int st = 1; - if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", unit)); } else { @@ -2110,7 +2110,7 @@ int sifdown(int unit) { /* make sure the netif status callback is called */ netif_set_down(&pc->netif); netif_remove(&pc->netif); - PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p errCode=%d\n", unit, pc->link_status_cb, pc->errCode)); + PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p err_code=%d\n", unit, pc->link_status_cb, pc->err_code)); if (pc->link_status_cb) { pc->link_status_cb(pc->link_status_ctx, PPPERR_CONNECT, NULL); } @@ -2155,7 +2155,7 @@ int netif_get_mtu(int mtu) { * ppp connection when it has come up. */ int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { - PPPControl *pc = &pppControl[unit]; + ppp_control *pc = &ppp_control_list[unit]; int st = 1; LWIP_UNUSED_ARG(ouraddr); @@ -2163,7 +2163,7 @@ int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace /* FIXME: handle replace condition */ LWIP_UNUSED_ARG(replace); - if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); } else { @@ -2180,13 +2180,13 @@ int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace * cifdefaultroute - delete a default route through the address given. */ int cifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway) { - PPPControl *pc = &pppControl[unit]; + ppp_control *pc = &ppp_control_list[unit]; int st = 1; LWIP_UNUSED_ARG(ouraddr); LWIP_UNUSED_ARG(gateway); - if (unit < 0 || unit >= NUM_PPP || !pc->openFlag) { + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); } else { @@ -2222,11 +2222,11 @@ int cifproxyarp(int unit, u_int32_t his_adr) { */ int sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid) { #if PPPOS_SUPPORT && VJ_SUPPORT - PPPControl *pc = &pppControl[u]; + ppp_control *pc = &ppp_control_list[u]; - pc->vjEnabled = vjcomp; - pc->vjComp.compressSlot = cidcomp; - pc->vjComp.maxSlotIndex = maxcid; + pc->vj_enabled = vjcomp; + pc->vj_comp.compressSlot = cidcomp; + pc->vj_comp.maxSlotIndex = maxcid; PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", vjcomp, cidcomp, maxcid)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ @@ -2272,7 +2272,7 @@ int get_loop_output(void) { * user-specified netmask. */ -u_int32_t GetMask (u_int32_t addr) { +u_int32_t get_mask (u_int32_t addr) { /* FIXME: do we really need that in IPCP ? */ return 0; } diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index da846727..0b3c18e7 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -471,7 +471,7 @@ struct ppp_settings ppp_settings; /* PPP flow functions */ #if PPPOE_SUPPORT -void pppOverEthernetInitFailed(int pd); +void ppp_over_ethernet_init_failed(int pd); /* function called by pppoe.c */ void ppp_input_over_ethernet(int pd, struct pbuf *pb); #endif /* PPPOE_SUPPORT */ @@ -480,8 +480,8 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb); int ppp_write(int pd, const u_char *s, int n); /* functions called by auth.c link_terminated() */ -void pppLinkDown(int pd); -void pppLinkTerminated(int pd); +void ppp_link_down(int pd); +void ppp_link_terminated(int pd); /* merge a pbuf chain into one pbuf */ struct pbuf * ppp_singlebuf(struct pbuf *p); @@ -521,7 +521,7 @@ int get_idle_time(int u, struct ppp_idle *ip); int get_loop_output(void); -u_int32_t GetMask (u_int32_t addr); +u_int32_t get_mask (u_int32_t addr); /* Optional protocol names list, to make our messages a little more informative. */ From eb020656d2e5d9b935df6876ffb0918518602b9d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 00:12:17 +0200 Subject: [PATCH 099/320] disabled all plugins hooks --- src/netif/ppp/ipcp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 27fb5040..69427357 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -75,6 +75,7 @@ u_int32_t netmask = 0; /* IP netmask to set on interface */ bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ bool noremoteip = 0; /* Let him have no IP address */ +#if 0 /* UNUSED */ /* Hook for a plugin to know when IP protocol has come up */ void (*ip_up_hook) __P((void)) = NULL; @@ -83,6 +84,7 @@ void (*ip_down_hook) __P((void)) = NULL; /* Hook for a plugin to choose the remote IP address */ void (*ip_choose_hook) __P((u_int32_t *)) = NULL; +#endif /* UNUSED */ #if PPP_NOTIFY /* Notifiers for when IPCP goes up and down */ @@ -732,12 +734,14 @@ ipcp_resetci(f) *go = *wo; if (!ask_for_local) go->ouraddr = 0; +#if 0 /* UNUSED */ if (ip_choose_hook) { ip_choose_hook(&wo->hisaddr); if (wo->hisaddr) { wo->accept_remote = 0; } } +#endif /* UNUSED */ BZERO(&ipcp_hisoptions[f->unit], sizeof(ipcp_options)); } @@ -1975,8 +1979,10 @@ ipcp_up(f) #if PPP_NOTIFY notify(ip_up_notifier, 0); #endif /* PPP_NOTIFY */ +#if 0 /* UNUSED */ if (ip_up_hook) ip_up_hook(); +#endif /* UNUSED */ } @@ -2001,8 +2007,10 @@ ipcp_down(f) #if PPP_NOTIFY notify(ip_down_notifier, 0); #endif /* PPP_NOTIFY */ +#if 0 /* UNUSED */ if (ip_down_hook) ip_down_hook(); +#endif /* UNUSED */ if (ipcp_is_up) { ipcp_is_up = 0; np_down(f->unit, PPP_IP); From 8332a5aa53a7e87bbd126791dcabdc84d6b26ec7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 00:12:45 +0200 Subject: [PATCH 100/320] disabled all plugins hooks --- src/netif/ppp/chap-new.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h index bb21fe22..3bb9efc0 100644 --- a/src/netif/ppp/chap-new.h +++ b/src/netif/ppp/chap-new.h @@ -136,11 +136,13 @@ struct chap_digest_type { struct chap_digest_type *next; }; +#if 0 /* UNUSED */ /* Hook for a plugin to validate CHAP challenge */ extern int (*chap_verify_hook)(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space); +#endif /* UNUSED */ /* Called by digest code to register a digest type */ extern void chap_register_digest(struct chap_digest_type *); From 093c7b438681f6b847567ae7d829ae365391f96a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 00:34:28 +0200 Subject: [PATCH 101/320] cleaned depreacted __P() and __V() macros, removed the legacy varargs.h header --- src/netif/ppp/auth.c | 70 +++++++++---------- src/netif/ppp/ccp.c | 54 +++++++-------- src/netif/ppp/chap-new.c | 4 +- src/netif/ppp/chap_ms.c | 22 +++--- src/netif/ppp/chap_ms.h | 10 +-- src/netif/ppp/demand.c | 2 +- src/netif/ppp/eap.c | 18 ++--- src/netif/ppp/eap.h | 4 +- src/netif/ppp/ecp.c | 24 +++---- src/netif/ppp/fsm.c | 16 ++--- src/netif/ppp/fsm.h | 44 ++++++------ src/netif/ppp/ipcp.c | 68 +++++++++---------- src/netif/ppp/ipcp.h | 2 +- src/netif/ppp/lcp.c | 64 +++++++++--------- src/netif/ppp/lcp.h | 10 +-- src/netif/ppp/multilink.c | 12 ++-- src/netif/ppp/options.c | 66 +++++++++--------- src/netif/ppp/ppp_impl.h | 137 +++++++++++++++++--------------------- src/netif/ppp/upap.c | 30 ++++----- src/netif/ppp/upap.h | 4 +- src/netif/ppp/utils.c | 32 ++++----- 21 files changed, 338 insertions(+), 355 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index f8ba2668..a51007f2 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -177,39 +177,39 @@ static int num_np_up; static bool default_auth; /* Hook to enable a plugin to control the idle time limit */ -int (*idle_time_hook) __P((struct ppp_idle *)) = NULL; +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) __P((void)) = NULL; +int (*pap_check_hook) (void) = NULL; /* Hook for a plugin to check the PAP user and password */ -int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, +int (*pap_auth_hook) (char *user, char *passwd, char **msgp, struct wordlist **paddrs, - struct wordlist **popts)) = NULL; + struct wordlist **popts) = NULL; /* Hook for a plugin to know about the PAP user logout */ -void (*pap_logout_hook) __P((void)) = NULL; +void (*pap_logout_hook) (void) = NULL; /* Hook for a plugin to get the PAP password for authenticating us */ -int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; +int (*pap_passwd_hook) (char *user, char *passwd) = NULL; /* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ -int (*chap_check_hook) __P((void)) = NULL; +int (*chap_check_hook) (void) = NULL; /* Hook for a plugin to get the CHAP password for authenticating us */ -int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL; +int (*chap_passwd_hook) (char *user, char *passwd) = NULL; /* Hook for a plugin to say whether it is OK if the peer refuses to authenticate. */ -int (*null_auth_hook) __P((struct wordlist **paddrs, - struct wordlist **popts)) = NULL; +int (*null_auth_hook) (struct wordlist **paddrs, + struct wordlist **popts) = NULL; -int (*allowed_address_hook) __P((u_int32_t addr)) = NULL; +int (*allowed_address_hook) (u_int32_t addr) = NULL; #endif /* UNUSED */ #ifdef HAVE_MULTILINK /* Hook for plugin to hear when an interface joins a multilink bundle */ -void (*multilink_join_hook) __P((void)) = NULL; +void (*multilink_join_hook) (void) = NULL; #endif #if PPP_NOTIFY @@ -253,37 +253,37 @@ char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ #if 0 /* UNUSED */ static char *uafname; /* name of most recent +ua file */ -extern char *crypt __P((const char *, const char *)); +extern char *crypt (const char *, const char *); #endif /* UNUSED */ /* Prototypes for procedures local to this file. */ -static void network_phase __P((int)); -static void check_idle __P((void *)); -static void connect_time_expired __P((void *)); +static void network_phase (int); +static void check_idle (void *); +static void connect_time_expired (void *); #if 0 /* UNUSED */ -static int null_login __P((int)); -/* static int get_pap_passwd __P((char *)); */ -static int have_pap_secret __P((int *)); -static int have_chap_secret __P((char *, char *, int, int *)); -static int have_srp_secret __P((char *client, char *server, int need_ip, - int *lacks_ipp)); -static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); -static int scan_authfile __P((FILE *, char *, char *, char *, +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 *); +static int have_srp_secret (char *client, char *server, int need_ip, + int *lacks_ipp); +static int ip_addr_check (u_int32_t, struct permitted_ip *); +static int scan_authfile (FILE *, char *, char *, char *, struct wordlist **, struct wordlist **, - char *, int)); -static void free_wordlist __P((struct wordlist *)); -static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *)); -static int some_ip_ok __P((struct wordlist *)); -static int setupapfile __P((char **)); -static int privgroup __P((char **)); -static int set_noauth_addr __P((char **)); -static int set_permitted_number __P((char **)); -static void check_access __P((FILE *, char *)); -static int wordlist_count __P((struct wordlist *)); + char *, int); +static void free_wordlist (struct wordlist *); +static void set_allowed_addrs (int, struct wordlist *, struct wordlist *); +static int some_ip_ok (struct wordlist *); +static int setupapfile (char **); +static int privgroup (char **); +static int set_noauth_addr (char **); +static int set_permitted_number (char **); +static void check_access (FILE *, char *); +static int wordlist_count (struct wordlist *); #endif /* UNUSED */ #ifdef MAXOCTETS -static void check_maxoctets __P((void *)); +static void check_maxoctets (void *); #endif #if PPP_OPTIONS diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 293c39e8..d2e04569 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -57,8 +57,8 @@ /* * Command-line options. */ -static int setbsdcomp __P((char **)); -static int setdeflate __P((char **)); +static int setbsdcomp (char **); +static int setdeflate (char **); static char bsd_value[8]; static char deflate_value[8]; @@ -166,19 +166,19 @@ static option_t ccp_option_list[] = { /* * Protocol entry points from main code. */ -static void ccp_init __P((int unit)); -static void ccp_open __P((int unit)); -static void ccp_close __P((int unit, char *)); -static void ccp_lowerup __P((int unit)); -static void ccp_lowerdown __P((int)); -static void ccp_input __P((int unit, u_char *pkt, int len)); -static void ccp_protrej __P((int unit)); +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); #if PRINTPKT_SUPPORT -static int ccp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); +static int ccp_printpkt (u_char *pkt, int len, + void (*printer) (void *, char *, ...), + void *arg); #endif /* PRINTPKT_SUPPORT */ -static void ccp_datainput __P((int unit, u_char *pkt, int len)); +static void ccp_datainput (int unit, u_char *pkt, int len); struct protent ccp_protent = { PPP_CCP, @@ -217,18 +217,18 @@ ccp_options ccp_hisoptions[NUM_PPP]; /* what we agreed to do */ /* * Callbacks for fsm code. */ -static void ccp_resetci __P((fsm *)); -static int ccp_cilen __P((fsm *)); -static void ccp_addci __P((fsm *, u_char *, int *)); -static int ccp_ackci __P((fsm *, u_char *, int)); -static int ccp_nakci __P((fsm *, u_char *, int, int)); -static int ccp_rejci __P((fsm *, u_char *, int)); -static int ccp_reqci __P((fsm *, u_char *, int *, int)); -static void ccp_up __P((fsm *)); -static void ccp_down __P((fsm *)); -static int ccp_extcode __P((fsm *, int, int, u_char *, int)); -static void ccp_rack_timeout __P((void *)); -static char *method_name __P((ccp_options *, ccp_options *)); +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, 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, @@ -267,7 +267,7 @@ static int ccp_localstate[NUM_PPP]; static int all_rejected[NUM_PPP]; /* we rejected all peer's options */ /* - * Option parsing. + * Option parsing */ static int setbsdcomp(argv) @@ -1502,7 +1502,7 @@ static int ccp_printpkt(p, plen, printer, arg) u_char *p; int plen; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { u_char *p0, *optend; diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index fbeacabf..6a7fc29e 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -140,7 +140,7 @@ static void chap_protrej(int unit); static void chap_input(int unit, unsigned char *pkt, int pktlen); #if PRINTPKT_SUPPORT static int chap_print_pkt(unsigned char *p, int plen, - void (*printer) __P((void *, char *, ...)), void *arg); + void (*printer) (void *, char *, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ /* List of digest types that we know about */ @@ -604,7 +604,7 @@ static char *chap_code_names[] = { static int chap_print_pkt(unsigned char *p, int plen, - void (*printer) __P((void *, char *, ...)), void *arg) + void (*printer) (void *, char *, ...), void *arg) { int code, id, len; int clen, nlen; diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index a5caa54b..11a8258f 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -99,22 +99,22 @@ #define SHA1_SIGNATURE_SIZE 20 -static void ascii2unicode __P((char[], int, u_char[])); -static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); -static void ChallengeResponse __P((u_char *, u_char *, u_char[24])); -static void ChapMS_NT __P((u_char *, char *, int, u_char[24])); -static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int, - u_char[24])); +static void ascii2unicode (char[], int, u_char[]); +static void NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]); +static void ChallengeResponse (u_char *, u_char *, u_char[24]); +static void ChapMS_NT (u_char *, char *, int, u_char[24]); +static void ChapMS2_NT (u_char *, u_char[16], char *, char *, int, + u_char[24]); static void GenerateAuthenticatorResponsePlain - __P((char*, int, u_char[24], u_char[16], u_char *, - char *, u_char[41])); + (char*, int, u_char[24], u_char[16], u_char *, + char *, u_char[41]); #ifdef MSLANMAN -static void ChapMS_LANMan __P((u_char *, char *, int, u_char *)); +static void ChapMS_LANMan (u_char *, char *, int, u_char *); #endif #ifdef MPPE -static void Set_Start_Key __P((u_char *, char *, int)); -static void SetMasterKeys __P((char *, int, u_char[24], int)); +static void Set_Start_Key (u_char *, char *, int); +static void SetMasterKeys (char *, int, u_char[24], int); #endif #ifdef MSLANMAN diff --git a/src/netif/ppp/chap_ms.h b/src/netif/ppp/chap_ms.h index ffff9b66..70211d3d 100644 --- a/src/netif/ppp/chap_ms.h +++ b/src/netif/ppp/chap_ms.h @@ -90,16 +90,16 @@ extern void set_mppe_enc_types(int, int); #define MS_CHAP2_AUTHENTICATEE 0 #define MS_CHAP2_AUTHENTICATOR 1 -void ChapMS __P((u_char *, char *, int, u_char *)); -void ChapMS2 __P((u_char *, u_char *, char *, char *, int, - u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int)); +void ChapMS (u_char *, char *, int, u_char *); +void ChapMS2 (u_char *, u_char *, char *, char *, int, + u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int); #ifdef MPPE -void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE])); +void mppe_set_keys (u_char *, u_char[MD4_SIGNATURE_SIZE]); void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], int IsServer); #endif -void ChallengeHash __P((u_char[16], u_char *, char *, u_char[8])); +void ChallengeHash (u_char[16], u_char *, char *, u_char[8]); void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], u_char PeerChallenge[16], diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index 5ef93755..b7c33e0f 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -74,7 +74,7 @@ struct packet { struct packet *pend_q; struct packet *pend_qtail; -static int active_packet __P((unsigned char *, int)); +static int active_packet (unsigned char *, int); /* * demand_conf - configure the interface for doing dial-on-demand. diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index e1b4f103..305e795d 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -97,14 +97,14 @@ static option_t eap_option_list[] = { /* * Protocol entry points. */ -static void eap_init __P((int unit)); -static void eap_input __P((int unit, u_char *inp, int inlen)); -static void eap_protrej __P((int unit)); -static void eap_lowerup __P((int unit)); -static void eap_lowerdown __P((int unit)); +static void eap_init (int unit); +static void eap_input (int unit, u_char *inp, int inlen); +static void eap_protrej (int unit); +static void eap_lowerup (int unit); +static void eap_lowerdown (int unit); #if PRINTPKT_SUPPORT -static int eap_printpkt __P((u_char *inp, int inlen, - void (*)(void *arg, char *fmt, ...), void *arg)); +static int eap_printpkt (u_char *inp, int inlen, + void (*)(void *arg, char *fmt, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ struct protent eap_protent = { @@ -176,7 +176,7 @@ static const u_char wkmodulus[] = { #endif /* Local forward declarations. */ -static void eap_server_timeout __P((void *arg)); +static void eap_server_timeout (void *arg); /* * Convert EAP state code to printable string for debug. @@ -2149,7 +2149,7 @@ static int eap_printpkt(inp, inlen, printer, arg) u_char *inp; int inlen; -void (*printer) __P((void *, char *, ...)); +void (*printer) (void *, char *, ...); void *arg; { int code, id, len, rtype, vallen; diff --git a/src/netif/ppp/eap.h b/src/netif/ppp/eap.h index ea0147ec..632df5f9 100644 --- a/src/netif/ppp/eap.h +++ b/src/netif/ppp/eap.h @@ -148,8 +148,8 @@ typedef struct eap_state { extern eap_state eap_states[]; -void eap_authwithpeer __P((int unit, char *localname)); -void eap_authpeer __P((int unit, char *localname)); +void eap_authwithpeer (int unit, char *localname); +void eap_authpeer (int unit, char *localname); extern struct protent eap_protent; diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index 90f3ee20..4c469b9a 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -81,22 +81,22 @@ static option_t ecp_option_list[] = { /* * Protocol entry points from main code. */ -static void ecp_init __P((int unit)); +static void ecp_init (int unit); /* -static void ecp_open __P((int unit)); -static void ecp_close __P((int unit, char *)); -static void ecp_lowerup __P((int unit)); -static void ecp_lowerdown __P((int)); -static void ecp_input __P((int unit, u_char *pkt, int len)); -static void ecp_protrej __P((int unit)); +static void ecp_open (int unit); +static void ecp_close (int unit, char *); +static void ecp_lowerup (int unit); +static void ecp_lowerdown (int); +static void ecp_input (int unit, u_char *pkt, int len); +static void ecp_protrej (int unit); */ #if PRINTPKT_SUPPORT -static int ecp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); +static int ecp_printpkt (u_char *pkt, int len, + void (*printer) (void *, char *, ...), + void *arg); #endif /* PRINTPKT_SUPPORT */ /* -static void ecp_datainput __P((int unit, u_char *pkt, int len)); +static void ecp_datainput (int unit, u_char *pkt, int len); */ struct protent ecp_protent = { @@ -178,7 +178,7 @@ static int ecp_printpkt(p, plen, printer, arg) u_char *p; int plen; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { return 0; diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 4a31a904..3edf8b2b 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -59,14 +59,14 @@ #include "fsm.h" -static void fsm_timeout __P((void *)); -static void fsm_rconfreq __P((fsm *, int, u_char *, int)); -static void fsm_rconfack __P((fsm *, int, u_char *, int)); -static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int)); -static void fsm_rtermreq __P((fsm *, int, u_char *, int)); -static void fsm_rtermack __P((fsm *)); -static void fsm_rcoderej __P((fsm *, u_char *, int)); -static void fsm_sconfreq __P((fsm *, int)); +static void fsm_timeout (void *); +static void fsm_rconfreq (fsm *, int, 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) diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index 4f202caa..679dc187 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -89,33 +89,33 @@ typedef struct fsm { typedef struct fsm_callbacks { void (*resetci) /* Reset our Configuration Information */ - __P((fsm *)); + (fsm *); int (*cilen) /* Length of our Configuration Information */ - __P((fsm *)); + (fsm *); void (*addci) /* Add our Configuration Information */ - __P((fsm *, u_char *, int *)); + (fsm *, u_char *, int *); int (*ackci) /* ACK our Configuration Information */ - __P((fsm *, u_char *, int)); + (fsm *, u_char *, int); int (*nakci) /* NAK our Configuration Information */ - __P((fsm *, u_char *, int, int)); + (fsm *, u_char *, int, int); int (*rejci) /* Reject our Configuration Information */ - __P((fsm *, u_char *, int)); + (fsm *, u_char *, int); int (*reqci) /* Request peer's Configuration Information */ - __P((fsm *, u_char *, int *, int)); + (fsm *, u_char *, int *, int); void (*up) /* Called when fsm reaches OPENED state */ - __P((fsm *)); + (fsm *); void (*down) /* Called when fsm leaves OPENED state */ - __P((fsm *)); + (fsm *); void (*starting) /* Called when we want the lower layer */ - __P((fsm *)); + (fsm *); void (*finished) /* Called when we don't want the lower layer */ - __P((fsm *)); + (fsm *); void (*protreject) /* Called when Protocol-Reject received */ - __P((int)); + (int); void (*retransmit) /* Retransmission is necessary */ - __P((fsm *)); + (fsm *); int (*extcode) /* Called when unknown code received */ - __P((fsm *, int, int, u_char *, int)); + (fsm *, int, int, u_char *, int); char *proto_name; /* String name for protocol (for messages) */ } fsm_callbacks; @@ -155,14 +155,14 @@ typedef struct fsm_callbacks { /* * Prototypes */ -void fsm_init __P((fsm *)); -void fsm_lowerup __P((fsm *)); -void fsm_lowerdown __P((fsm *)); -void fsm_open __P((fsm *)); -void fsm_close __P((fsm *, char *)); -void fsm_input __P((fsm *, u_char *, int)); -void fsm_protreject __P((fsm *)); -void fsm_sdata __P((fsm *, int, int, u_char *, int)); +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 *, int, int, u_char *, int); /* diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 69427357..0c007b58 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -77,13 +77,13 @@ bool noremoteip = 0; /* Let him have no IP address */ #if 0 /* UNUSED */ /* Hook for a plugin to know when IP protocol has come up */ -void (*ip_up_hook) __P((void)) = NULL; +void (*ip_up_hook) (void) = NULL; /* Hook for a plugin to know when IP protocol has come down */ -void (*ip_down_hook) __P((void)) = NULL; +void (*ip_down_hook) (void) = NULL; /* Hook for a plugin to choose the remote IP address */ -void (*ip_choose_hook) __P((u_int32_t *)) = NULL; +void (*ip_choose_hook) (u_int32_t *) = NULL; #endif /* UNUSED */ #if PPP_NOTIFY @@ -107,16 +107,16 @@ static char netmask_str[20]; /* string form of netmask value */ /* * Callbacks for fsm code. (CI = Configuration Information) */ -static void ipcp_resetci __P((fsm *)); /* Reset our CI */ -static int ipcp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ -static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipcp_up __P((fsm *)); /* We're UP */ -static void ipcp_down __P((fsm *)); /* We're DOWN */ -static void ipcp_finished __P((fsm *)); /* Don't need lower layer */ +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, 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 */ @@ -142,13 +142,13 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ * Command-line options. */ #if PPP_OPTIONS -static int setvjslots __P((char **)); -static int setdnsaddr __P((char **)); -static int setwinsaddr __P((char **)); -static int setnetmask __P((char **)); -int setipaddr __P((char *, char **, int)); +static int setvjslots (char **); +static int setdnsaddr (char **); +static int setwinsaddr (char **); +static int setnetmask (char **); +int setipaddr (char *, char **, int); -static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); +static void printipaddr (option_t *, void (*)(void *, char *,...),void *); static option_t ipcp_option_list[] = { { "noip", o_bool, &ipcp_protent.enabled_flag, @@ -255,26 +255,26 @@ static option_t ipcp_option_list[] = { /* * Protocol entry points from main code. */ -static void ipcp_init __P((int)); -static void ipcp_open __P((int)); -static void ipcp_close __P((int, char *)); -static void ipcp_lowerup __P((int)); -static void ipcp_lowerdown __P((int)); -static void ipcp_input __P((int, u_char *, int)); -static void ipcp_protrej __P((int)); +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); #if PRINTPKT_SUPPORT -static int ipcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); +static int ipcp_printpkt (u_char *, int, + void (*) (void *, char *, ...), void *); #endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS -static void ip_check_options __P((void)); +static void ip_check_options (void); #endif /* PPP_OPTIONS */ #if DEMAND_SUPPORT -static int ip_demand_conf __P((int)); -static int ip_active_pkt __P((u_char *, int)); +static int ip_demand_conf (int); +static int ip_active_pkt (u_char *, int); #endif /* DEMAND_SUPPORT */ #if 0 /* UNUSED */ -static void create_resolv __P((u_int32_t, u_int32_t)); +static void create_resolv (u_int32_t, u_int32_t); #endif /* UNUSED */ struct protent ipcp_protent = { @@ -510,7 +510,7 @@ setipaddr(arg, argv, doit) static void printipaddr(opt, printer, arg) option_t *opt; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { ipcp_options *wo = &ipcp_wantoptions[0]; @@ -2106,7 +2106,7 @@ static int ipcp_printpkt(p, plen, printer, arg) u_char *p; int plen; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { int code, id, len, olen; diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index 582d167b..fbd0214c 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -96,7 +96,7 @@ extern ipcp_options ipcp_allowoptions[]; extern ipcp_options ipcp_hisoptions[]; #if 0 /* UNUSED, already defined by lwIP */ -char *ip_ntoa __P((u_int32_t)); +char *ip_ntoa (u_int32_t); #endif /* UNUSED, already defined by lwIP */ extern struct protent ipcp_protent; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 5212d934..8613559a 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -70,7 +70,7 @@ /* steal a bit in fsm flags word */ #define DELAYED_UP 0x100 -static void lcp_delayed_up __P((void *)); +static void lcp_delayed_up (void *); /* * LCP-related command-line options. @@ -84,13 +84,13 @@ bool lax_recv = 0; /* accept control chars in asyncmap */ bool noendpoint = 0; /* don't send/accept endpoint discriminator */ #if PPP_OPTIONS -static int noopt __P((char **)); +static int noopt (char **); #endif /* PPP_OPTIONS */ #ifdef HAVE_MULTILINK -static int setendpoint __P((char **)); -static void printendpoint __P((option_t *, void (*)(void *, char *, ...), - void *)); +static int setendpoint (char **); +static void printendpoint (option_t *, void (*)(void *, char *, ...), + void *); #endif /* HAVE_MULTILINK */ #if PPP_OPTIONS @@ -220,31 +220,31 @@ static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ /* * Callbacks for fsm code. (CI = Configuration Information) */ -static void lcp_resetci __P((fsm *)); /* Reset our CI */ -static int lcp_cilen __P((fsm *)); /* Return length of our CI */ -static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */ -static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int lcp_nakci __P((fsm *, u_char *, int, int)); /* Peer nak'd our CI */ -static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */ -static void lcp_up __P((fsm *)); /* We're UP */ -static void lcp_down __P((fsm *)); /* We're DOWN */ -static void lcp_starting __P((fsm *)); /* We need lower layer up */ -static void lcp_finished __P((fsm *)); /* We need lower layer down */ -static int lcp_extcode __P((fsm *, int, int, u_char *, int)); -static void lcp_rprotrej __P((fsm *, u_char *, int)); +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, 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 __P((int)); -static void lcp_echo_lowerdown __P((int)); -static void LcpEchoTimeout __P((void *)); -static void lcp_received_echo_reply __P((fsm *, int, u_char *, int)); -static void LcpSendEchoRequest __P((fsm *)); -static void LcpLinkFailure __P((fsm *)); -static void LcpEchoCheck __P((fsm *)); +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 */ @@ -269,12 +269,12 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ * Some of these are called directly. */ -static void lcp_init __P((int)); -static void lcp_input __P((int, u_char *, int)); -static void lcp_protrej __P((int)); +static void lcp_init (int); +static void lcp_input (int, u_char *, int); +static void lcp_protrej (int); #if PRINTPKT_SUPPORT -static int lcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); +static int lcp_printpkt (u_char *, int, + void (*) (void *, char *, ...), void *); #endif /* PRINTPKT_SUPPORT */ struct protent lcp_protent = { @@ -356,7 +356,7 @@ setendpoint(argv) static void printendpoint(opt, printer, arg) option_t *opt; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint)); @@ -2360,7 +2360,7 @@ static int lcp_printpkt(p, plen, printer, arg) u_char *p; int plen; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { int code, id, len, olen, i; diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index d701e9af..eb1e33f8 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -140,11 +140,11 @@ extern ext_accm xmit_accm[]; #define MINMRU 128 /* No MRUs below this */ #define MAXMRU 16384 /* Normally limit MRU to this */ -void lcp_open __P((int)); -void lcp_close __P((int, char *)); -void lcp_lowerup __P((int)); -void lcp_lowerdown __P((int)); -void lcp_sprotrej __P((int, u_char *, int)); /* send protocol reject */ +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; diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 0ca3309c..5648d26c 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -64,13 +64,13 @@ bool multilink_master; /* we own the multilink bundle */ extern TDB_CONTEXT *pppdb; extern char db_key[]; -static void make_bundle_links __P((int append)); -static void remove_bundle_link __P((void)); -static void iterate_bundle_links __P((void (*func) __P((char *)))); +static void make_bundle_links (int append); +static void remove_bundle_link (void); +static void iterate_bundle_links (void (*func) (char *)); -static int get_default_epdisc __P((struct epdisc *)); -static int parse_num __P((char *str, const char *key, int *valp)); -static int owns_unit __P((TDB_DATA pid, int unit)); +static int get_default_epdisc (struct epdisc *); +static int parse_num (char *str, const char *key, int *valp); +static int owns_unit (TDB_DATA pid, int unit); #define set_ip_epdisc(ep, addr) do { \ ep->length = 4; \ diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index b4d334f7..1c39c6a7 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -78,7 +78,7 @@ #include "ppp_impl.h" #if defined(ultrix) || defined(NeXT) -char *strdup __P((char *)); +char *strdup (char *); #endif struct option_value { @@ -165,32 +165,32 @@ static char logfile_name[MAXPATHLEN]; /* name of log file */ * Prototypes */ #if 0 /* UNUSED */ -static int setdomain __P((char **)); -static int readfile __P((char **)); -static int callfile __P((char **)); -static int showversion __P((char **)); -static int showhelp __P((char **)); -static void usage __P((void)); -static int setlogfile __P((char **)); +static int setdomain (char **); +static int readfile (char **); +static int callfile (char **); +static int showversion (char **); +static int showhelp (char **); +static void usage (void); +static int setlogfile (char **); #endif /* UNUSED */ #ifdef PLUGIN -static int loadplugin __P((char **)); +static int loadplugin (char **); #endif #ifdef PPP_FILTER -static int setpassfilter __P((char **)); -static int setactivefilter __P((char **)); +static int setpassfilter (char **); +static int setactivefilter (char **); #endif #ifdef MAXOCTETS -static int setmodir __P((char **)); +static int setmodir (char **); #endif #if 0 /* UNUSED */ -static option_t *find_option __P((const char *name)); -static int process_option __P((option_t *, char *, char **)); -static int n_arguments __P((option_t *)); -static int number_option __P((char *, u_int32_t *, int)); +static option_t *find_option (const char *name); +static int process_option (option_t *, char *, char **); +static int n_arguments (option_t *); +static int number_option (char *, u_int32_t *, int); /* * Structure to store extra lists of options. @@ -597,13 +597,13 @@ match_option(name, opt, dowild) option_t *opt; int dowild; { - int (*match) __P((char *, char **, int)); + int (*match) (char *, char **, int); if (dowild != (opt->type == o_wild)) return 0; if (!dowild) return strcmp(name, opt->name) == 0; - match = (int (*) __P((char *, char **, int))) opt->addr; + match = (int (*) (char *, char **, int)) opt->addr; return (*match)(name, NULL, 0); } @@ -655,8 +655,8 @@ process_option(opt, cmd, argv) u_int32_t v; int iv, a; char *sv; - int (*parser) __P((char **)); - int (*wildp) __P((char *, char **, int)); + int (*parser) (char **); + int (*wildp) (char *, char **, int); char *optopt = (opt->type == o_wild)? "": " option"; int prio = option_priority; option_t *mainopt = opt; @@ -787,7 +787,7 @@ process_option(opt, cmd, argv) case o_special_noarg: case o_special: - parser = (int (*) __P((char **))) opt->addr; + parser = (int (*) (char **)) opt->addr; if (!(*parser)(argv)) return 0; if (opt->flags & OPT_A2LIST) { @@ -810,7 +810,7 @@ process_option(opt, cmd, argv) break; case o_wild: - wildp = (int (*) __P((char *, char **, int))) opt->addr; + wildp = (int (*) (char *, char **, int)) opt->addr; if (!(*wildp)(cmd, argv, 1)) return 0; break; @@ -901,7 +901,7 @@ check_options() static void print_option(opt, mainopt, printer, arg) option_t *opt, *mainopt; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { int i, v; @@ -964,12 +964,12 @@ print_option(opt, mainopt, printer, arg) printer(arg, " "); } if (opt->flags & OPT_A2PRINTER) { - void (*oprt) __P((option_t *, - void ((*)__P((void *, char *, ...))), - void *)); - oprt = (void (*) __P((option_t *, - void ((*)__P((void *, char *, ...))), - void *)))opt->addr2; + void (*oprt) (option_t *, + void ((*)(void *, char *, ...)), + void *); + oprt = (void (*) (option_t *, + void ((*)(void *, char *, ...)), + void *))opt->addr2; (*oprt)(opt, printer, arg); } else if (opt->flags & OPT_A2STRVAL) { p = (char *) opt->addr2; @@ -1006,7 +1006,7 @@ print_option(opt, mainopt, printer, arg) static void print_option_list(opt, printer, arg) option_t *opt; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { while (opt->name != NULL) { @@ -1024,7 +1024,7 @@ print_option_list(opt, printer, arg) */ void print_options(printer, arg) - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { struct option_list *list; @@ -1084,7 +1084,7 @@ showversion(argv) * stderr if phase == PHASE_INITIALIZE. */ void -option_error __V((char *fmt, ...)) +option_error (char *fmt, ...) { va_list args; char buf[1024]; @@ -1596,7 +1596,7 @@ loadplugin(argv) char *arg = *argv; void *handle; const char *err; - void (*init) __P((void)); + void (*init) (void); char *path = arg; const char *vers; diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 0b3c18e7..5f3c5a78 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -38,24 +38,7 @@ #define PPP_IMP_H_ #include /* formats */ - -#if defined(__STDC__) #include -#define __V(x) x -#else -#include -#define __V(x) (va_alist) va_dcl -#define const -#define volatile -#endif - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif #ifndef bool typedef unsigned char bool; @@ -329,30 +312,30 @@ extern int maxoctets_timeout; /* Timeout for check of octets limit */ struct protent { u_short protocol; /* PPP protocol number */ /* Initialization procedure */ - void (*init) __P((int unit)); + void (*init) (int unit); /* Process a received packet */ - void (*input) __P((int unit, u_char *pkt, int len)); + void (*input) (int unit, u_char *pkt, int len); /* Process a received protocol-reject */ - void (*protrej) __P((int unit)); + void (*protrej) (int unit); /* Lower layer has come up */ - void (*lowerup) __P((int unit)); + void (*lowerup) (int unit); /* Lower layer has gone down */ - void (*lowerdown) __P((int unit)); + void (*lowerdown) (int unit); /* Open the protocol */ - void (*open) __P((int unit)); + void (*open) (int unit); /* Close the protocol */ - void (*close) __P((int unit, char *reason)); + void (*close) (int unit, char *reason); #if PRINTPKT_SUPPORT /* Print a packet in readable form */ - int (*printpkt) __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); + int (*printpkt) (u_char *pkt, int len, + void (*printer) (void *, char *, ...), + void *arg); #endif /* PRINTPKT_SUPPORT */ /* FIXME: data input is only used by CCP, which is not supported at this time, * should we remove this entry and save some flash ? */ /* Process a received data packet */ - void (*datainput) __P((int unit, u_char *pkt, int len)); + void (*datainput) (int unit, u_char *pkt, int len); bool enabled_flag; /* 0 iff protocol is disabled */ #if PRINTPKT_SUPPORT char *name; /* Text name of protocol */ @@ -361,13 +344,13 @@ struct protent { #if PPP_OPTIONS option_t *options; /* List of command-line options */ /* Check requested options, assign defaults */ - void (*check_options) __P((void)); + void (*check_options) (void); #endif /* PPP_OPTIONS */ #if DEMAND_SUPPORT /* Configure interface for demand-dial */ - int (*demand_conf) __P((int unit)); + int (*demand_conf) (int unit); /* Say whether to bring up link for this pkt */ - int (*active_pkt) __P((u_char *pkt, int len)); + int (*active_pkt) (u_char *pkt, int len); #endif /* DEMAND_SUPPORT */ }; @@ -627,51 +610,51 @@ void update_link_stats(int u); /* Get stats at link termination */ #define EXIT_CNID_AUTH_FAILED 21 /* Procedures exported from auth.c */ -void link_required __P((int)); /* we are starting to use the link */ -void link_terminated __P((int)); /* we are finished with the link */ -void link_down __P((int)); /* the LCP layer has left the Opened state */ -void upper_layers_down __P((int));/* take all NCPs down */ -void link_established __P((int)); /* the link is up; authenticate now */ -void start_networks __P((int)); /* start all the network control protos */ -void continue_networks __P((int)); /* start network [ip, etc] control protos */ +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 upper_layers_down (int);/* take all NCPs down */ +void link_established (int); /* the link is up; authenticate now */ +void start_networks (int); /* start all the network control protos */ +void continue_networks (int); /* start network [ip, etc] control protos */ -void auth_peer_fail __P((int, int)); +void auth_peer_fail (int, int); /* peer failed to authenticate itself */ -void auth_peer_success __P((int, int, int, char *, int)); +void auth_peer_success (int, int, int, char *, int); /* peer successfully authenticated itself */ -void auth_withpeer_fail __P((int, int)); +void auth_withpeer_fail (int, int); /* we failed to authenticate ourselves */ -void auth_withpeer_success __P((int, int, int)); +void auth_withpeer_success (int, int, int); /* we successfully authenticated ourselves */ -void np_up __P((int, int)); /* a network protocol has come up */ -void np_down __P((int, int)); /* a network protocol has gone down */ -void np_finished __P((int, int)); /* a network protocol no longer needs link */ -void auth_reset __P((int)); /* check what secrets we have */ -int get_secret __P((int, char *, char *, char *, int *, int)); +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_reset (int); /* check what secrets we have */ +int get_secret (int, char *, char *, char *, int *, int); /* get "secret" for chap */ /* Procedures exported from ipcp.c */ -/* int parse_dotted_ip __P((char *, u_int32_t *)); */ +/* int parse_dotted_ip (char *, u_int32_t *); */ /* Procedures exported from demand.c */ #if DEMAND_SUPPORT -void demand_conf __P((void)); /* config interface(s) for demand-dial */ -void demand_block __P((void)); /* set all NPs to queue up packets */ -void demand_unblock __P((void)); /* set all NPs to pass packets */ -void demand_discard __P((void)); /* set all NPs to discard packets */ -void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ -int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ -int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ +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, u_int32_t); /* 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? */ #endif /* DEMAND_SUPPORT */ /* Procedures exported from multilink.c */ #ifdef HAVE_MULTILINK -void mp_check_options __P((void)); /* Check multilink-related options */ -int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ -void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */ -void mp_bundle_terminated __P((void)); -char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ -int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ +void mp_check_options (void); /* Check multilink-related options */ +int mp_join_bundle (void); /* join our link to an appropriate bundle */ +void mp_exit_bundle (void); /* have disconnected our link from bundle */ +void mp_bundle_terminated (void); +char *epdisc_to_str (struct epdisc *); /* string from endpoint discrim. */ +int str_to_epdisc (struct epdisc *, char *); /* endpt disc. from str */ #else #define mp_bundle_terminated() /* nothing */ #define mp_exit_bundle() /* nothing */ @@ -680,23 +663,23 @@ int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ #endif /* Procedures exported from utils.c. */ -void print_string __P((char *, int, void (*) (void *, char *, ...), - void *)); /* Format a string for output */ -int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ -int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ -size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ -size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ -void dbglog __P((char *, ...)); /* log a debug message */ -void info __P((char *, ...)); /* log an informational message */ -void notice __P((char *, ...)); /* log a notice-level message */ -void warn __P((char *, ...)); /* log a warning message */ -void error __P((char *, ...)); /* log an error message */ -void fatal __P((char *, ...)); /* log an error message and die(1) */ -void init_pr_log __P((const char *, int)); /* initialize for using pr_log */ -void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ -void end_pr_log __P((void)); /* finish up after using pr_log */ +void print_string (char *, 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 dbglog (char *, ...); /* log a debug message */ +void info (char *, ...); /* log an informational message */ +void notice (char *, ...); /* log a notice-level message */ +void warn (char *, ...); /* log a warning message */ +void error (char *, ...); /* log an error message */ +void fatal (char *, ...); /* log an error message and die(1) */ +void init_pr_log (const char *, int); /* initialize for using pr_log */ +void pr_log (void *, char *, ...); /* printer fn, output to syslog */ +void end_pr_log (void); /* finish up after using pr_log */ #if PRINTPKT_SUPPORT -void dump_packet __P((const char *, u_char *, int)); +void dump_packet (const char *, u_char *, int); /* dump packet to debug log if interesting */ #endif /* PRINTPKT_SUPPORT */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 07ea3853..eddba238 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -84,14 +84,14 @@ static option_t pap_option_list[] = { /* * Protocol entry points. */ -static void upap_init __P((int)); -static void upap_lowerup __P((int)); -static void upap_lowerdown __P((int)); -static void upap_input __P((int, u_char *, int)); -static void upap_protrej __P((int)); +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); #if PRINTPKT_SUPPORT -static int upap_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); +static int upap_printpkt (u_char *, int, + void (*) (void *, char *, ...), void *); #endif /* PRINTPKT_SUPPORT */ struct protent pap_protent = { @@ -124,16 +124,16 @@ struct protent pap_protent = { upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ -static void upap_timeout __P((void *)); -static void upap_reqtimeout __P((void *)); +static void upap_timeout (void *); +static void upap_reqtimeout (void *); #if 0 /* UNUSED */ -static void upap_rauthreq __P((upap_state *, u_char *, int, int)); +static void upap_rauthreq (upap_state *, u_char *, int, int); #endif /* UNUSED */ -static void upap_rauthack __P((upap_state *, u_char *, int, int)); -static void upap_rauthnak __P((upap_state *, u_char *, int, int)); -static void upap_sauthreq __P((upap_state *)); +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 *); #if 0 /* UNUSED */ -static void upap_sresp __P((upap_state *, int, int, char *, int)); +static void upap_sresp (upap_state *, int, int, char *, int); #endif /* UNUSED */ @@ -638,7 +638,7 @@ static int upap_printpkt(p, plen, printer, arg) u_char *p; int plen; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { int code, id, len; diff --git a/src/netif/ppp/upap.h b/src/netif/ppp/upap.h index 7e51b351..189e858e 100644 --- a/src/netif/ppp/upap.h +++ b/src/netif/ppp/upap.h @@ -109,8 +109,8 @@ typedef struct upap_state { extern upap_state upap[]; -void upap_authwithpeer __P((int, char *, char *)); -void upap_authpeer __P((int)); +void upap_authwithpeer (int, char *, char *); +void upap_authpeer (int); extern struct protent pap_protent; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index e1340388..b2e2a8a3 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -69,12 +69,12 @@ extern char *strerror(); #endif -static void logit __P((int, char *, va_list)); -static void log_write __P((int, char *)); +static void logit (int, char *, va_list); +static void log_write (int, char *); #if PRINTPKT_SUPPORT -static void vslp_printer __P((void *, char *, ...)); -static void format_packet __P((u_char *, int, void (*) (void *, char *, ...), - void *)); +static void vslp_printer (void *, char *, ...); +static void format_packet (u_char *, int, void (*) (void *, char *, ...), + void *); #endif /* PRINTPKT_SUPPORT */ struct buffer_info { @@ -130,7 +130,7 @@ strlcat(dest, src, len) * Returns the number of chars put into buf. */ int -slprintf __V((char *buf, int buflen, char *fmt, ...)) +slprintf (char *buf, int buflen, char *fmt, ...) { va_list args; int n; @@ -440,7 +440,7 @@ vslprintf(buf, buflen, fmt, args) * vslp_printer - used in processing a %P format */ static void -vslp_printer __V((void *arg, char *fmt, ...)) +vslp_printer (void *arg, char *fmt, ...) { int n; va_list pvar; @@ -492,7 +492,7 @@ static void format_packet(p, len, printer, arg) u_char *p; int len; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { int i, n; @@ -569,7 +569,7 @@ end_pr_log() * pr_log - printer routine for outputting to log */ void -pr_log __V((void *arg, char *fmt, ...)) +pr_log (void *arg, char *fmt, ...) { int l, n; va_list pvar; @@ -631,7 +631,7 @@ void print_string(p, len, printer, arg) char *p; int len; - void (*printer) __P((void *, char *, ...)); + void (*printer) (void *, char *, ...); void *arg; { int c; @@ -702,7 +702,7 @@ log_write(level, buf) * fatal - log an error message and die horribly. */ void -fatal __V((char *fmt, ...)) +fatal (char *fmt, ...) { va_list pvar; @@ -727,7 +727,7 @@ fatal __V((char *fmt, ...)) * error - log an error message. */ void -error __V((char *fmt, ...)) +error (char *fmt, ...) { va_list pvar; @@ -748,7 +748,7 @@ error __V((char *fmt, ...)) * warn - log a warning message. */ void -warn __V((char *fmt, ...)) +warn (char *fmt, ...) { va_list pvar; @@ -768,7 +768,7 @@ warn __V((char *fmt, ...)) * notice - log a notice-level message. */ void -notice __V((char *fmt, ...)) +notice (char *fmt, ...) { va_list pvar; @@ -788,7 +788,7 @@ notice __V((char *fmt, ...)) * info - log an informational message. */ void -info __V((char *fmt, ...)) +info (char *fmt, ...) { va_list pvar; @@ -808,7 +808,7 @@ info __V((char *fmt, ...)) * dbglog - log a debug message. */ void -dbglog __V((char *fmt, ...)) +dbglog (char *fmt, ...) { va_list pvar; From bea45b3c30b50b1e36d49108813cc5cdfc8270a7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 00:59:24 +0200 Subject: [PATCH 102/320] cleared IDE warnings --- src/netif/ppp/auth.c | 1 + src/netif/ppp/fsm.c | 7 ++++ src/netif/ppp/lcp.c | 2 +- src/netif/ppp/options.c | 6 --- src/netif/ppp/ppp.c | 10 ++++- src/netif/ppp/utils.c | 81 ++--------------------------------------- src/netif/ppp/vj.c | 4 +- 7 files changed, 23 insertions(+), 88 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index a51007f2..3529b392 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1174,6 +1174,7 @@ auth_withpeer_success(unit, protocol, prot_flavor) default: warn("auth_withpeer_success: unknown protocol %x", protocol); bit = 0; + /* no break */ } notice("%s authentication succeeded", prot); diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 3edf8b2b..57b366b2 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -117,6 +117,7 @@ fsm_lowerup(f) default: FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); + /* no break */ } } @@ -162,6 +163,7 @@ fsm_lowerdown(f) default: FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); + /* no break */ } } @@ -193,6 +195,7 @@ fsm_open(f) case CLOSING: f->state = STOPPING; /* fall through */ + /* no break */ case STOPPED: case OPENED: if( f->flags & OPT_RESTART ){ @@ -325,6 +328,7 @@ fsm_timeout(arg) default: FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); + /* no break */ } } @@ -711,6 +715,7 @@ fsm_protreject(f) case CLOSING: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ /* fall through */ + /* no break */ case CLOSED: f->state = CLOSED; if( f->callbacks->finished ) @@ -723,6 +728,7 @@ fsm_protreject(f) case ACKSENT: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ /* fall through */ + /* no break */ case STOPPED: f->state = STOPPED; if( f->callbacks->finished ) @@ -736,6 +742,7 @@ fsm_protreject(f) default: FSMDEBUG(("%s: Protocol-reject event in state %d!", PROTO_NAME(f), f->state)); + /* no break */ } } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 8613559a..533b0824 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -467,7 +467,7 @@ lcp_close(unit, reason) oldstate = f->state; fsm_close(f, reason); - if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) { + if (oldstate == STOPPED && (f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP))) { /* * This action is not strictly according to the FSM in RFC1548, * but it does mean that the program terminates if you do a diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 1c39c6a7..0cbe1de7 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -1089,13 +1089,7 @@ option_error (char *fmt, ...) va_list args; char buf[1024]; -#if defined(__STDC__) va_start(args, fmt); -#else - char *fmt; - va_start(args); - fmt = va_arg(args, char *); -#endif vslprintf(buf, sizeof(buf), fmt, args); va_end(args); if (phase == PHASE_INITIALIZE) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 3be7ec47..994ae4d2 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1712,18 +1712,22 @@ pppos_input_proc(ppp_control_rx *pcrx, u_char *s, int l) if (cur_char != PPP_ALLSTATIONS) { break; } + /* no break */ + /* Fall through */ - /* Fall through */ case PDSTART: /* Process start flag. */ /* Prepare for a new packet. */ pcrx->in_fcs = PPP_INITFCS; + /* no break */ + /* Fall through */ - /* Fall through */ case PDADDRESS: /* Process address field. */ if (cur_char == PPP_ALLSTATIONS) { pcrx->in_state = PDCONTROL; break; } + /* no break */ + /* Else assume compressed address and control fields so * fall through to get the protocol... */ case PDCONTROL: /* Process control field. */ @@ -1732,6 +1736,8 @@ pppos_input_proc(ppp_control_rx *pcrx, u_char *s, int l) pcrx->in_state = PDPROTOCOL1; break; } + /* no break */ + #if 0 else { PPPDEBUG(LOG_WARNING, diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index b2e2a8a3..b7cf10cc 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -135,17 +135,7 @@ slprintf (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; @@ -287,9 +277,11 @@ vslprintf(buf, buflen, fmt, args) num[1] = 0; str = num; break; +#if 0 /* do we always have strerror() in embedded ? */ case 'm': str = strerror(errno); break; +#endif /* do we always have strerror() in embedded ? */ case 'I': ip = va_arg(args, u_int32_t); ip = ntohl(ip); @@ -446,16 +438,7 @@ vslp_printer (void *arg, char *fmt, ...) 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); @@ -576,16 +559,7 @@ pr_log (void *arg, char *fmt, ...) char *p, *eol; 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); @@ -627,13 +601,7 @@ pr_log (void *arg, char *fmt, ...) * print_string - print a readable representation of a string using * printer. */ -void -print_string(p, len, printer, arg) - char *p; - int len; - void (*printer) (void *, char *, ...); - void *arg; -{ +void print_string(char *p, int len, void (*printer) (void *, char *, ...), void arg) { int c; printer(arg, "\""); @@ -656,6 +624,7 @@ print_string(p, len, printer, arg) break; default: printer(arg, "\\%.3o", c); + /* no break */ } } } @@ -706,14 +675,7 @@ fatal (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); @@ -731,14 +693,7 @@ error (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); ++error_count; @@ -752,14 +707,7 @@ warn (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); } @@ -772,14 +720,7 @@ notice (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); } @@ -792,14 +733,7 @@ info (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); } @@ -812,14 +746,7 @@ dbglog (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); } diff --git a/src/netif/ppp/vj.c b/src/netif/ppp/vj.c index 0fed7aab..79752512 100644 --- a/src/netif/ppp/vj.c +++ b/src/netif/ppp/vj.c @@ -316,8 +316,8 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) ntohs(IPH_LEN(&cs->cs_ip)) == hlen) { break; } - - /* (fall through) */ + /* no break */ + /* fall through */ case SPECIAL_I: case SPECIAL_D: From 2c7bd7e591c53289eb1858ce924f222bc677e002 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 01:45:33 +0200 Subject: [PATCH 103/320] fixed print_string() prototype --- src/netif/ppp/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index b7cf10cc..074d7a34 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -601,7 +601,7 @@ pr_log (void *arg, char *fmt, ...) * print_string - print a readable representation of a string using * printer. */ -void print_string(char *p, int len, void (*printer) (void *, char *, ...), void arg) { +void print_string(char *p, int len, void (*printer) (void *, char *, ...), void *arg) { int c; printer(arg, "\""); From ca1ad99bea13e8a90c6050a1a1de84677ae015a8 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 15:31:29 +0200 Subject: [PATCH 104/320] PPPoE reauth bug fixed --- src/netif/ppp/ppp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 994ae4d2..928a53e6 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1866,7 +1866,8 @@ void ppp_link_down(int pd) { #if PPPOE_SUPPORT if (ppp_control_list[pd].ethif) { - pppoe_disconnect(ppp_control_list[pd].pppoe_sc); +/* FIXME: find a way to set PPPoE down without disconnecting and freeing PPPoE structures */ +/* pppoe_disconnect(ppp_control_list[pd].pppoe_sc); */ } else #endif /* PPPOE_SUPPORT */ { From c549dba7258bc37df1ef142f391aeb19ca40249b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 16:25:16 +0200 Subject: [PATCH 105/320] re-enabled LCP echo interval / echo fail --- src/netif/ppp/lcp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 533b0824..a0d9d669 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -75,8 +75,15 @@ static void lcp_delayed_up (void *); /* * LCP-related command-line options. */ +#if 0 /* UNUSED */ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +#endif /* UNUSED */ + +/* options */ +static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ +static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ + #if PPP_LCP_ADAPTIVE bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ #endif From cd3ba004795dc24b06faa543667db2109a3be3d3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 18:58:05 +0200 Subject: [PATCH 106/320] get_mask now returns "255.255.255.255" by default, which is what we want in almost all cases on a PPP link --- src/netif/ppp/ppp.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 928a53e6..156c8f35 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -2278,10 +2278,31 @@ int get_loop_output(void) { * network as `addr'. If we find any, we OR in their netmask to the * user-specified netmask. */ +u_int32_t get_mask(u_int32_t addr) { +#if 0 + u32_t mask, nmask; -u_int32_t get_mask (u_int32_t addr) { - /* FIXME: do we really need that in IPCP ? */ - return 0; + addr = htonl(addr); + if (IP_CLASSA(addr)) { /* determine network mask for address class */ + nmask = IP_CLASSA_NET; + } else if (IP_CLASSB(addr)) { + nmask = IP_CLASSB_NET; + } else { + nmask = IP_CLASSC_NET; + } + + /* class D nets are disallowed by bad_ip_adrs */ + mask = PP_HTONL(0xffffff00UL) | htonl(nmask); + + /* XXX + * Scan through the system's network interfaces. + * Get each netmask and OR them into our mask. + */ + /* return mask; */ + return mask; +#endif + LWIP_UNUSED_ARG(addr); + return 0xFFFFFFFF; } From d6e5ca722f133121e857bb61542d08bf7628a884 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 19:00:36 +0200 Subject: [PATCH 107/320] setting default route by default --- src/netif/ppp/ipcp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 0c007b58..e7e8f03b 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -620,6 +620,9 @@ ipcp_init(unit) wo->maxslotindex = MAX_STATES - 1; /* really max index */ wo->cflag = 1; + /* wanting default route by default */ + /* FIXME: should be configurable */ + wo->default_route = 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 */ From dc0e15a74ed093aab28a91590375e48b189fecad Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 22:22:37 +0200 Subject: [PATCH 108/320] we should reduce nak_buffer[] size --- src/netif/ppp/lcp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index a0d9d669..495ea1f5 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -222,6 +222,7 @@ 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 */ +/* FIXME: do we really need such a large buffer? The typical 1500 bytes seem too much. */ static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ /* From 1013b49ab7510cd88fb3fd99bc6aaa50405dede5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 22:23:10 +0200 Subject: [PATCH 109/320] disabled ppp_over_ethernet_close(), which is not exported and probably bogus, until we fix it --- src/netif/ppp/ppp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 156c8f35..0f7a0119 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -296,6 +296,11 @@ typedef struct ppp_control_s { /* Prototypes for procedures local to this file. */ +/* FIXME: PPPoE close seem bogus, it was actually not exported at all in the previous port */ +#if 0 /* UNUSED */ +void ppp_over_ethernet_close(int pd); +#endif /* UNUSED */ + static void ppp_start(int pd); /** Initiate LCP open request */ static void ppp_input(void *arg); @@ -321,7 +326,6 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i #if PPPOE_SUPPORT static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p); /* function called by ppp_write() */ -void pppOverEthernetClose(int pd); static int ppp_write_over_ethernet(int pd, const u_char *s, int n); #endif /* PPPOE_SUPPORT */ @@ -616,7 +620,8 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const return pd; } -void pppOverEthernetClose(int pd) { +#if 0 /* UNUSED */ +void ppp_over_ethernet_close(int pd) { ppp_control* pc = &ppp_control_list[pd]; /* *TJL* There's no lcp_deinit */ @@ -624,6 +629,7 @@ void pppOverEthernetClose(int pd) { pppoe_destroy(&pc->netif); } +#endif /* UNUSED */ #endif /* PPPOE_SUPPORT */ From d95f1e99131c30528587f126332cbec64afdfadb Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 22:48:12 +0200 Subject: [PATCH 110/320] added missing initialisation in ppp_init.c --- src/netif/ppp/ppp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0f7a0119..892871ea 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -360,7 +360,17 @@ int ppp_init(void) { struct protent *protp; debug = 1; + + new_phase(PHASE_INITIALIZE); + error_count = 0; + unsuccess = 0; + listen_time = 0; + status = EXIT_OK; + need_holdoff = 1; ifunit = 1; /* FIXME: remove ifunit */ +#if PPP_STATS_SUPPORT + link_stats_valid = 0; +#endif /* PPP_STATS_SUPPORT */ /* openlog("LWIP-PPP", LOG_PID | LOG_NDELAY, LOG_DAEMON); From 7d7513c71c9255f717585ee695962d9d818e4935 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 4 Jun 2012 23:19:23 +0200 Subject: [PATCH 111/320] re-enabled DNS support --- src/netif/ppp/ipcp.c | 9 ++++---- src/netif/ppp/ppp.c | 47 +++++++++++++++++++++++++++++++++++----- src/netif/ppp/ppp_impl.h | 3 +++ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index e7e8f03b..66171bb3 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -95,7 +95,6 @@ struct notifier *ip_down_notifier = 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() */ static int ipcp_is_open; /* haven't called np_finished() */ static bool ask_for_local; /* request our address from peer */ @@ -732,8 +731,8 @@ ipcp_resetci(f) 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; + wo->req_dns1 = ppp_settings.usepeerdns; /* Request DNS addresses from the peer */ + wo->req_dns2 = ppp_settings.usepeerdns; *go = *wo; if (!ask_for_local) go->ouraddr = 0; @@ -1845,7 +1844,8 @@ ipcp_up(f) if (go->dnsaddr[1]) script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); #endif /* UNUSED */ - if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + sdns(f->unit, go->dnsaddr[0], go->dnsaddr[1]); /* FIXME: set here the DNS servers ? */ #if 0 /* UNUSED */ script_setenv("USEPEERDNS", "1", 0); @@ -2040,6 +2040,7 @@ ipcp_down(f) sifdown(f->unit); ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, ipcp_hisoptions[f->unit].hisaddr, 0); + cdns(f->unit, ipcp_gotoptions[f->unit].dnsaddr[0], ipcp_gotoptions[f->unit].dnsaddr[1]); } } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 892871ea..be6d61c3 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -2052,20 +2052,17 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, SMEMCPY(&pc->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); SMEMCPY(&pc->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); SMEMCPY(&pc->addrs.netmask, &net_mask, sizeof(net_mask)); -/* FIXME: re-enable DNS - * SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); - * SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); - */ } return st; } + /******************************************************************** * * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */ -int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr) { +int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { ppp_control *pc = &ppp_control_list[unit]; int st = 1; @@ -2077,13 +2074,51 @@ int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr) { } else { IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); - IP4_ADDR(&pc->addrs.netmask, 255,255,255,0); + IP4_ADDR(&pc->addrs.netmask, 255,255,255,255); + } + return st; +} + + +/* + * sdns - Config the DNS servers + */ +int sdns (int unit, u_int32_t ns1, u_int32_t ns2) { + ppp_control *pc = &ppp_control_list[unit]; + int st = 1; + + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sdns[%d]: bad parms\n", unit)); + } else { + SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); + SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); + } + return st; +} + + +/******************************************************************** + * + * cdns - Clear the DNS servers + */ +int cdns (int unit, u_int32_t ns1, u_int32_t ns2) { + ppp_control *pc = &ppp_control_list[unit]; + int st = 1; + + LWIP_UNUSED_ARG(ns1); + LWIP_UNUSED_ARG(ns2); + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad parms\n", unit)); + } else { IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); } return st; } + /* * sifup - Config the interface up and enable IP packets to pass. */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 5f3c5a78..a05ce7c2 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -484,6 +484,9 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp); int sifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr); +int sdns(int unit, u_int32_t ns1, u_int32_t ns2); +int cdns(int unit, u_int32_t ns1, u_int32_t ns2); + int sifup(int u); int sifdown (int u); From 2e227f868bbef1994a2e62a1e76afbb88c976dfd Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 5 Jun 2012 22:22:35 +0200 Subject: [PATCH 112/320] PPPoE is now guessing its MTU from the underlying netif MTU (in most cases 1500 minus 8 = 1492, which is the most common PPPoE MTU) --- src/include/netif/ppp_oe.h | 7 ------- src/netif/ppp/ppp.c | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index e1cdfa51..c8b15d46 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -133,13 +133,6 @@ PACK_STRUCT_END #define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ #define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ -#ifndef ETHERMTU -#define ETHERMTU 1500 -#endif - -/* two byte PPP protocol discriminator, then IP data */ -#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) - #ifndef PPPOE_MAX_AC_COOKIE_LEN #define PPPOE_MAX_AC_COOKIE_LEN 64 #endif diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index be6d61c3..ea8fabaa 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -609,12 +609,12 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const pc->link_status_cb = link_status_cb; pc->link_status_ctx = link_status_ctx; - lcp_wantoptions[pd].mru = PPPOE_MAXMTU; + lcp_wantoptions[pd].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ lcp_wantoptions[pd].neg_asyncmap = 0; lcp_wantoptions[pd].neg_pcompression = 0; lcp_wantoptions[pd].neg_accompression = 0; - lcp_allowoptions[pd].mru = PPPOE_MAXMTU; + lcp_allowoptions[pd].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ lcp_allowoptions[pd].neg_asyncmap = 0; lcp_allowoptions[pd].neg_pcompression = 0; lcp_allowoptions[pd].neg_accompression = 0; From 6f21f489377a0830cb790a35a1eb21f9e63268de Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 5 Jun 2012 23:10:38 +0200 Subject: [PATCH 113/320] added MTU support (using MRU from the peer) --- src/netif/ppp/ppp.c | 42 +++++++++++++++++----------------------- src/netif/ppp/ppp.h | 6 ------ src/netif/ppp/ppp_impl.h | 2 +- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index ea8fabaa..937a46a7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1088,7 +1088,7 @@ static err_t ppp_netif_init_cb(struct netif *netif) { netif->name[0] = 'p'; netif->name[1] = 'p'; netif->output = ppp_netif_output; - netif->mtu = ppp_mtu((int)(size_t)netif->state); + netif->mtu = netif_get_mtu((int)(size_t)netif->state); netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; #if LWIP_NETIF_HOSTNAME /* @todo: Initialize interface hostname */ @@ -1381,24 +1381,6 @@ static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { #endif /* PPPOE_SUPPORT */ -/* - * Return the Maximum Transmission Unit for the given PPP connection. - */ -u_short ppp_mtu(int pd) { - ppp_control *pc = &ppp_control_list[pd]; - u_short st; - - /* Validate parameters. */ - if (pd < 0 || pd >= NUM_PPP || !pc->open_flag) { - st = 0; - } else { - st = pc->mtu; - } - - return st; -} - - /* Get and set parameters for the given connection. * Return 0 on success, an error code on failure. */ int @@ -1976,7 +1958,7 @@ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { int i; #endif /* PPPOS_SUPPORT */ - pc->mtu = mtu; + /* pc->mtu = mtu; -- set correctly with netif_set_mtu */ pc->pcomp = pcomp; pc->accomp = accomp; @@ -2190,14 +2172,26 @@ int sifnpmode(int u, int proto, enum NPmode mode) { * netif_set_mtu - set the MTU on the PPP network interface. */ void netif_set_mtu(int unit, int mtu) { - /* FIXME: set lwIP MTU */ + ppp_control *pc = &ppp_control_list[unit]; + + /* Validate parameters. */ + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) + return; + + pc->mtu = mtu; } + /* * netif_get_mtu - get PPP interface MTU */ -int netif_get_mtu(int mtu) { - /* FIXME: get lwIP MTU */ - return 1492; +int netif_get_mtu(int unit) { + ppp_control *pc = &ppp_control_list[unit]; + + /* Validate parameters. */ + if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) + return 0; + + return pc->mtu; } /******************************************************************** diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 57d29485..06c425a9 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -176,12 +176,6 @@ void ppp_sighup(int pd); */ int ppp_ioctl(int pd, int cmd, void *arg); -/* - * Return the Maximum Transmission Unit for the given PPP connection. - */ -/* FIXME: demystify MTU support */ -u_short ppp_mtu(int pd); - #if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD /* * PPP over Serial: this is the input function to be called for received data. diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index a05ce7c2..cfb4cd72 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -493,7 +493,7 @@ int sifdown (int u); int sifnpmode(int u, int proto, enum NPmode mode); void netif_set_mtu(int unit, int mtu); -int netif_get_mtu(int mtu); +int netif_get_mtu(int unit); int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace); int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway); From 3c3331d5edb6bc60c433822ef4ec0677c9084389 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 6 Jun 2012 22:34:16 +0200 Subject: [PATCH 114/320] fixed some debug strings --- src/netif/ppp/ppp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 937a46a7..777dce59 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -2029,7 +2029,7 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("sifaddr[%d]: bad parms\n", unit)); } else { SMEMCPY(&pc->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); SMEMCPY(&pc->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); @@ -2092,7 +2092,7 @@ int cdns (int unit, u_int32_t ns1, u_int32_t ns2) { LWIP_UNUSED_ARG(ns2); if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("cdns[%d]: bad parms\n", unit)); } else { IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); @@ -2217,7 +2217,7 @@ int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("sifdefaultroute[%d]: bad parms\n", unit)); } else { netif_set_default(&pc->netif); } @@ -2240,7 +2240,7 @@ int cifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway) { if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("cifdefaultroute[%d]: bad parms\n", unit)); } else { netif_set_default(NULL); } From ac0a864e14c4c27fd3b5516f7882bf7d7ef0b166 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 6 Jun 2012 22:36:23 +0200 Subject: [PATCH 115/320] fixed typos s/parms/params/g --- src/netif/ppp/ppp.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 777dce59..ed849739 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1207,7 +1207,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i /* We let any protocol value go through - it can't hurt us * and the peer will just drop it if it's not accepting it. */ if (pd < 0 || pd >= NUM_PPP || !pc->open_flag || !pb) { - PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad parms prot=%d pb=%p\n", + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad params prot=%d pb=%p\n", pd, PPP_IP, (void*)pb)); LINK_STATS_INC(link.opterr); LINK_STATS_INC(link.drop); @@ -2029,7 +2029,7 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("sifaddr[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("sifaddr[%d]: bad params\n", unit)); } else { SMEMCPY(&pc->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); SMEMCPY(&pc->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); @@ -2052,7 +2052,7 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { LWIP_UNUSED_ARG(his_adr); if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad params\n", unit)); } else { IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); @@ -2071,7 +2071,7 @@ int sdns (int unit, u_int32_t ns1, u_int32_t ns2) { if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("sdns[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("sdns[%d]: bad params\n", unit)); } else { SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); @@ -2092,7 +2092,7 @@ int cdns (int unit, u_int32_t ns1, u_int32_t ns2) { LWIP_UNUSED_ARG(ns2); if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("cdns[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("cdns[%d]: bad params\n", unit)); } else { IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); @@ -2111,7 +2111,7 @@ int sifup(int u) if (u < 0 || u >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", u)); + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad params\n", u)); } else { netif_remove(&pc->netif); if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, @@ -2144,7 +2144,7 @@ int sifdown(int unit) { if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad params\n", unit)); } else { pc->if_up = 0; /* make sure the netif status callback is called */ @@ -2217,7 +2217,7 @@ int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("sifdefaultroute[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("sifdefaultroute[%d]: bad params\n", unit)); } else { netif_set_default(&pc->netif); } @@ -2240,7 +2240,7 @@ int cifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway) { if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { st = 0; - PPPDEBUG(LOG_WARNING, ("cifdefaultroute[%d]: bad parms\n", unit)); + PPPDEBUG(LOG_WARNING, ("cifdefaultroute[%d]: bad params\n", unit)); } else { netif_set_default(NULL); } From e44aada634d39027fe306af74a954528be629ea3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 6 Jun 2012 23:42:20 +0200 Subject: [PATCH 116/320] improved PPPoE callback with state values, so that PPP know exactly what is happening on the PPPoE side --- src/include/netif/ppp_oe.h | 4 +++ src/netif/ppp/ppp.c | 54 +++++++++++++++++++++++--------------- src/netif/ppp/ppp_oe.c | 9 +++---- 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index c8b15d46..8929a616 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -113,6 +113,10 @@ PACK_STRUCT_END /* passive */ #define PPPOE_STATE_PADO_SENT 1 +#define PPPOE_CB_STATE_UP 0 /* PPPoE link is UP */ +#define PPPOE_CB_STATE_DOWN 1 /* PPPoE link is DOWN - normal condition */ +#define PPPOE_CB_STATE_FAILED 2 /* Failed to setup PPPoE link */ + #define PPPOE_HEADERLEN sizeof(struct pppoehdr) #define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index ed849739..bfd20a83 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -580,7 +580,7 @@ void ppp_set_xaccm(int unit, ext_accm *accm) { #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT -static void ppp_over_ethernet_link_status_cb(int pd, int up); +static void ppp_over_ethernet_link_status_cb(int pd, int state); int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { @@ -682,7 +682,7 @@ ppp_close(int pd) void ppp_sighup(int pd) { - PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hupCB\n", pd)); + PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hup\n", pd)); ppp_hup(pd); } @@ -709,7 +709,7 @@ ppp_stop(int pd) static void ppp_hup(int pd) { - PPPDEBUG(LOG_DEBUG, ("ppp_hupCB: unit %d\n", pd)); + PPPDEBUG(LOG_DEBUG, ("ppp_hup: unit %d\n", pd)); lcp_lowerdown(pd); link_terminated(pd); } @@ -1834,27 +1834,39 @@ struct pbuf * ppp_singlebuf(struct pbuf *p) { } #if PPPOE_SUPPORT -void ppp_over_ethernet_init_failed(int pd) { - ppp_control* pc; +static void ppp_over_ethernet_link_status_cb(int pd, int state) { + ppp_control *pc = &ppp_control_list[pd]; - ppp_hup(pd); - ppp_stop(pd); + switch(state) { + case PPPOE_CB_STATE_UP: + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pd)); + ppp_start(pd); + break; - pc = &ppp_control_list[pd]; - pppoe_destroy(&pc->netif); - pc->open_flag = 0; + /* FIXME: here we can handle the PPPoE persist, in case of DOWN or FAILED, we just have to + * call pppoe_connect(sc); without setting pc->open_flag to 0. + */ + case PPPOE_CB_STATE_DOWN: + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pd)); + ppp_hup(pd); + ppp_stop(pd); + pppoe_destroy(&pc->netif); + pc->open_flag = 0; + if(pc->link_status_cb) { + pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_CONNECT, NULL); + } + break; - if(pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_PROTOCOL, NULL); - } -} - -static void ppp_over_ethernet_link_status_cb(int pd, int up) { - if(up) { - PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: Connecting\n", pd)); - ppp_start(pd); - } else { - ppp_over_ethernet_init_failed(pd); + case PPPOE_CB_STATE_FAILED: + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pd)); + ppp_hup(pd); + ppp_stop(pd); + pppoe_destroy(&pc->netif); + pc->open_flag = 0; + if(pc->link_status_cb) { + pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_PROTOCOL, NULL); + } + break; } } #endif /* PPPOE_SUPPORT */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 50a966d8..eef9e7a6 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -277,7 +277,7 @@ pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) static void pppoe_linkstatus_up(struct pppoe_softc *sc) { - sc->sc_linkStatusCB(sc->sc_pd, 1); + sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_UP); } /* analyze and handle a single received packet while not in session state */ @@ -863,8 +863,7 @@ pppoe_do_disconnect(struct pppoe_softc *sc) #endif sc->sc_session = 0; - sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ - + sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_DOWN); /* notify upper layers */ return err; } @@ -875,7 +874,7 @@ pppoe_abort_connect(struct pppoe_softc *sc) PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); sc->sc_state = PPPOE_STATE_CLOSING; - sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ + sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_FAILED); /* notify upper layers */ /* clear connection state */ MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); @@ -1118,7 +1117,7 @@ pppoe_clear_softc(struct pppoe_softc *sc, const char *message) sc->sc_state = PPPOE_STATE_INITIAL; /* notify upper layers */ - sc->sc_linkStatusCB(sc->sc_pd, 0); + sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_DOWN); /* clean up softc */ MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); From 7ef99ee6f3f1b2e639b363e5e474ad4a379c11f1 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 7 Jun 2012 00:46:19 +0200 Subject: [PATCH 117/320] added a persist option (enabled by default for now until we add a way for users to pass a ppp_settings structure) improved PPPoE state machine and added persist mode support --- src/include/netif/ppp_oe.h | 4 ++-- src/netif/ppp/ppp.c | 46 ++++++++++++++++++++++---------------- src/netif/ppp/ppp_impl.h | 1 + src/netif/ppp/ppp_oe.c | 34 ++++++++++++++++++---------- 4 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index 8929a616..ada32934 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -145,7 +145,7 @@ struct pppoe_softc { struct pppoe_softc *next; struct netif *sc_ethif; /* ethernet interface we are using */ int sc_pd; /* ppp unit number */ - void (*sc_linkStatusCB)(int pd, int up); + void (*sc_link_status_cb)(int pd, int up); int sc_state; /* discovery phase or session connected */ struct eth_addr sc_dest; /* hardware address of concentrator */ @@ -168,7 +168,7 @@ struct pppoe_softc { #define pppoe_init() /* compatibility define, no initialization needed */ -err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr); +err_t pppoe_create(struct netif *ethif, int pd, void (*link_status_cb)(int pd, int up), struct pppoe_softc **scptr); err_t pppoe_destroy(struct netif *ifp); int pppoe_connect(struct pppoe_softc *sc); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index bfd20a83..4400078a 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -380,6 +380,7 @@ int ppp_init(void) { memset(&ppp_settings, 0, sizeof(ppp_settings)); ppp_settings.usepeerdns = 1; + ppp_settings.persist = 1; ppp_set_auth(PPPAUTHTYPE_NONE, NULL, NULL); /* @@ -1835,39 +1836,46 @@ struct pbuf * ppp_singlebuf(struct pbuf *p) { #if PPPOE_SUPPORT static void ppp_over_ethernet_link_status_cb(int pd, int state) { - ppp_control *pc = &ppp_control_list[pd]; + int pppoe_err_code = PPPERR_NONE; + ppp_control *pc; switch(state) { + + /* PPPoE link is established, starting PPP negotiation */ case PPPOE_CB_STATE_UP: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pd)); ppp_start(pd); - break; + return; - /* FIXME: here we can handle the PPPoE persist, in case of DOWN or FAILED, we just have to - * call pppoe_connect(sc); without setting pc->open_flag to 0. - */ + /* PPPoE link normally down (i.e. asked to do so) */ case PPPOE_CB_STATE_DOWN: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pd)); - ppp_hup(pd); - ppp_stop(pd); - pppoe_destroy(&pc->netif); - pc->open_flag = 0; - if(pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_CONNECT, NULL); - } + pppoe_err_code = PPPERR_CONNECT; break; + /* PPPoE link failed to setup (i.e. PADI/PADO timeout */ case PPPOE_CB_STATE_FAILED: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pd)); - ppp_hup(pd); - ppp_stop(pd); - pppoe_destroy(&pc->netif); - pc->open_flag = 0; - if(pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_PROTOCOL, NULL); - } + pppoe_err_code = PPPERR_OPEN; break; } + + pc = &ppp_control_list[pd]; + + /* Reconnect if persist mode is enabled */ + if(ppp_settings.persist) { + if(pc->link_status_cb) + pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : pppoe_err_code, NULL); + pppoe_connect(pc->pppoe_sc); + return; + } + + ppp_hup(pd); + ppp_stop(pd); + pppoe_destroy(&pc->netif); + pc->open_flag = 0; + if(pc->link_status_cb) + pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : pppoe_err_code, NULL); } #endif /* PPPOE_SUPPORT */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index cfb4cd72..dfdacb64 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -437,6 +437,7 @@ struct ppp_settings { #endif /* EAP_SUPPORT */ u_int usehostname : 1; /* Use hostname for our_name */ u_int usepeerdns : 1; /* Ask peer for DNS adds */ + u_int persist : 1; /* Persist mode, always try to reopen the connection */ u_short idle_time_limit; /* Shut down link if idle for this long */ int maxconnect; /* Maximum connect time (seconds) */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index eef9e7a6..ab71d163 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -141,7 +141,7 @@ static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct n static struct pppoe_softc *pppoe_softc_list; err_t -pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr) +pppoe_create(struct netif *ethif, int pd, void (*link_status_cb)(int pd, int up), struct pppoe_softc **scptr) { struct pppoe_softc *sc; @@ -156,7 +156,7 @@ pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); sc->sc_pd = pd; - sc->sc_linkStatusCB = linkStatusCB; + sc->sc_link_status_cb = link_status_cb; sc->sc_ethif = ethif; /* put the new interface at the head of the list */ @@ -277,7 +277,7 @@ pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) static void pppoe_linkstatus_up(struct pppoe_softc *sc) { - sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_UP); + sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_UP); } /* analyze and handle a single received packet while not in session state */ @@ -806,6 +806,12 @@ pppoe_connect(struct pppoe_softc *sc) return EBUSY; } + /* stop any timer */ + sys_untimeout(pppoe_timeout, sc); + sc->sc_session = 0; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; + #ifdef PPPOE_SERVER /* wait PADI if IFF_PASSIVE */ if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { @@ -814,7 +820,6 @@ pppoe_connect(struct pppoe_softc *sc) #endif /* save state, in case we fail to send PADI */ sc->sc_state = PPPOE_STATE_PADI_SENT; - sc->sc_padr_retried = 0; if ((err = pppoe_send_padi(sc)) != 0) { PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); } @@ -862,8 +867,10 @@ pppoe_do_disconnect(struct pppoe_softc *sc) sc->sc_hunique_len = 0; #endif sc->sc_session = 0; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; - sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_DOWN); /* notify upper layers */ + sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_DOWN); /* notify upper layers */ return err; } @@ -872,13 +879,16 @@ static void pppoe_abort_connect(struct pppoe_softc *sc) { PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - sc->sc_state = PPPOE_STATE_CLOSING; - - sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_FAILED); /* notify upper layers */ /* clear connection state */ - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); sc->sc_state = PPPOE_STATE_INITIAL; + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_ac_cookie_len = 0; + sc->sc_session = 0; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; + + sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_FAILED); /* notify upper layers */ } /* Send a PADR packet */ @@ -1112,17 +1122,17 @@ pppoe_clear_softc(struct pppoe_softc *sc, const char *message) /* stop timer */ sys_untimeout(pppoe_timeout, sc); PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message)); - /* fix our state */ sc->sc_state = PPPOE_STATE_INITIAL; /* notify upper layers */ - sc->sc_linkStatusCB(sc->sc_pd, PPPOE_CB_STATE_DOWN); + sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_DOWN); /* clean up softc */ MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); sc->sc_ac_cookie_len = 0; sc->sc_session = 0; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; } - #endif /* PPP_SUPPORT && PPPOE_SUPPORT */ From a9ac45c5f063586002ac68c6c0ad5479db20bcac Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 7 Jun 2012 01:48:12 +0200 Subject: [PATCH 118/320] added PPPoE persist support (don't timeout sending PADI packets) --- src/include/netif/ppp_oe.h | 15 +++++++++------ src/netif/ppp/ppp.c | 4 ++-- src/netif/ppp/ppp_oe.c | 14 +++++++++----- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index ada32934..c098f583 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -67,12 +67,13 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include "lwip/opt.h" +#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ + #ifndef PPP_OE_H #define PPP_OE_H -#include "lwip/opt.h" - -#if PPPOE_SUPPORT > 0 +#include "ppp_impl.h" #include "netif/etharp.h" @@ -163,6 +164,8 @@ struct pppoe_softc { #endif int sc_padi_retried; /* number of PADI retries already done */ int sc_padr_retried; /* number of PADR retries already done */ + + u_int persist : 1; /* Persist mode, don't timeout sending PADI packets */ }; @@ -171,7 +174,7 @@ struct pppoe_softc { err_t pppoe_create(struct netif *ethif, int pd, void (*link_status_cb)(int pd, int up), struct pppoe_softc **scptr); err_t pppoe_destroy(struct netif *ifp); -int pppoe_connect(struct pppoe_softc *sc); +int pppoe_connect(struct pppoe_softc *sc, bool persist); void pppoe_disconnect(struct pppoe_softc *sc); void pppoe_disc_input(struct netif *netif, struct pbuf *p); @@ -182,6 +185,6 @@ err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); /** used in ppp.c */ #define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN) -#endif /* PPPOE_SUPPORT */ - #endif /* PPP_OE_H */ + +#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 4400078a..9df70260 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -625,7 +625,7 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const return PPPERR_OPEN; } - pppoe_connect(pc->pppoe_sc); + pppoe_connect(pc->pppoe_sc, ppp_settings.persist); } return pd; @@ -1866,7 +1866,7 @@ static void ppp_over_ethernet_link_status_cb(int pd, int state) { if(ppp_settings.persist) { if(pc->link_status_cb) pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : pppoe_err_code, NULL); - pppoe_connect(pc->pppoe_sc); + pppoe_connect(pc->pppoe_sc, ppp_settings.persist); return; } diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index ab71d163..04f76987 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -748,10 +748,14 @@ pppoe_timeout(void *arg) */ /* initialize for quick retry mode */ - retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); + retry_wait = LWIP_MIN(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), PPPOE_SLOW_RETRY); - sc->sc_padi_retried++; - if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { + /* prevent sc_padi_retried integer overflow << ~2^31/PPPOE_DISC_TIMEOUT + * FIXME: can be improved + */ + if(sc->sc_padi_retried < 100000) + sc->sc_padi_retried++; + if (!sc->persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { #if 0 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { /* slow retry mode */ @@ -798,7 +802,7 @@ pppoe_timeout(void *arg) /* Start a connection (i.e. initiate discovery phase) */ int -pppoe_connect(struct pppoe_softc *sc) +pppoe_connect(struct pppoe_softc *sc, bool persist) { int err; @@ -811,7 +815,7 @@ pppoe_connect(struct pppoe_softc *sc) sc->sc_session = 0; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; - + sc->persist = persist; #ifdef PPPOE_SERVER /* wait PADI if IFF_PASSIVE */ if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { From 4077422ae2d7e3214f85c1f276f098e4822a6185 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 7 Jun 2012 20:41:21 +0200 Subject: [PATCH 119/320] fixed pbuf leaks in ppp_input() in case of packets not expected --- src/netif/ppp/ppp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 9df70260..0482e845 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -746,7 +746,7 @@ static void ppp_input(void *arg) { */ if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { dbglog("Discarded non-LCP packet when LCP not open"); - return; + goto drop; } /* FIXME: add a phase per connection */ @@ -772,7 +772,7 @@ static void ppp_input(void *arg) { )) { dbglog("discarding proto 0x%x in phase %d", protocol, phase); - return; + goto drop; } /* FIXME: should we write protent to do that ? */ From 2fe778507aa987673ac7e29a717ffebec28f6a72 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 7 Jun 2012 22:19:25 +0200 Subject: [PATCH 120/320] fixed randm if random MD5 support is not enabled --- src/netif/ppp/magic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index e945f26a..45237b0a 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -235,7 +235,7 @@ void magic_randomize(void) { if (!magic_randomized) { magic_randomized = !0; - magic_randominit(); + magic_init(); /* The initialization function also updates the seed. */ } else { /* magic_randomseed += (magic_randomseed << 16) + TM1; */ From e5355cc45fc6396b95a5554ff7dae645e0e4027c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 7 Jun 2012 22:22:57 +0200 Subject: [PATCH 121/320] PPP server support is now optional (disabled by default, not working until PPP have a "listen" support) --- src/netif/ppp/auth.c | 6 ++++++ src/netif/ppp/chap-md5.c | 4 ++++ src/netif/ppp/chap-new.c | 27 +++++++++++++++++++++++++++ src/netif/ppp/chap-new.h | 4 ++++ src/netif/ppp/chap_ms.c | 6 ++++++ src/netif/ppp/eap.c | 21 +++++++++++++++++++++ src/netif/ppp/eap.h | 4 ++++ src/netif/ppp/upap.c | 18 ++++++++++++++++-- src/netif/ppp/upap.h | 2 ++ 9 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 3529b392..37c4df3c 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -761,7 +761,9 @@ link_established(unit) #if 0 /* UNUSED */ lcp_options *wo = &lcp_wantoptions[unit]; #endif /* UNUSED */ +#if PPP_SERVER lcp_options *go = &lcp_gotoptions[unit]; +#endif /* #if PPP_SERVER */ lcp_options *ho = &lcp_hisoptions[unit]; int i; struct protent *protp; @@ -817,6 +819,7 @@ link_established(unit) new_phase(PHASE_AUTHENTICATE); auth = 0; +#if PPP_SERVER #if EAP_SUPPORT if (go->neg_eap) { eap_authpeer(unit, our_name); @@ -836,6 +839,7 @@ link_established(unit) } else #endif /* PAP_SUPPORT */ {} +#endif /* PPP_SERVER */ #if EAP_SUPPORT if (ho->neg_eap) { @@ -1022,6 +1026,7 @@ continue_networks(unit) lcp_close(0, "No network protocols running"); } +#if PPP_SERVER /* * The peer has failed to authenticate himself using `protocol'. */ @@ -1103,6 +1108,7 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) if ((auth_pending[unit] &= ~bit) == 0) network_phase(unit); } +#endif /* PPP_SERVER */ /* * We have failed to authenticate ourselves to the peer using `protocol'. diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 45750308..d3866e4b 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -47,6 +47,7 @@ #define MD5_MIN_CHALLENGE 16 #define MD5_MAX_CHALLENGE 24 +#if PPP_SERVER static void chap_md5_generate_challenge(unsigned char *cp) { @@ -88,6 +89,7 @@ chap_md5_verify_response(int id, char *name, slprintf(message, message_space, "Access denied"); return 0; } +#endif /* PPP_SERVER */ static void chap_md5_make_response(unsigned char *response, int id, char *our_name, @@ -108,8 +110,10 @@ chap_md5_make_response(unsigned char *response, int id, char *our_name, static struct chap_digest_type md5_digest = { CHAP_MD5, /* code */ +#if PPP_SERVER chap_md5_generate_challenge, chap_md5_verify_response, +#endif /* PPP_SERVER */ chap_md5_make_response, NULL, /* check_success */ NULL, /* handle_failure */ diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 6a7fc29e..05cf6943 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -85,6 +85,7 @@ static option_t chap_option_list[] = { /* * Internal state. */ +/* FIXME: one client struct per ppp session */ static struct chap_client_state { int flags; char *name; @@ -99,6 +100,8 @@ static struct chap_client_state { #define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) #define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) +#if PPP_SERVER +/* FIXME: one server struct per ppp session */ static struct chap_server_state { int flags; int id; @@ -109,6 +112,7 @@ static struct chap_server_state { unsigned char challenge[CHAL_MAX_PKTLEN]; char message[256]; } server; +#endif /* PPP_SERVER */ /* Values for flags in chap_client_state and chap_server_state */ #define LOWERUP 1 @@ -124,6 +128,7 @@ static struct chap_server_state { static void chap_init(int unit); static void chap_lowerup(int unit); static void chap_lowerdown(int unit); +#if PPP_SERVER static void chap_timeout(void *arg); static void chap_generate_challenge(struct chap_server_state *ss); static void chap_handle_response(struct chap_server_state *ss, int code, @@ -132,6 +137,7 @@ static int chap_verify_response(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space); +#endif /* PPP_SERVER */ static void chap_respond(struct chap_client_state *cs, int id, unsigned char *pkt, int len); static void chap_handle_status(struct chap_client_state *cs, int code, int id, @@ -153,7 +159,9 @@ static void chap_init(int unit) { memset(&client, 0, sizeof(client)); +#if PPP_SERVER memset(&server, 0, sizeof(server)); +#endif /* PPP_SERVER */ chap_md5_init(); #if MSCHAP_SUPPORT @@ -178,26 +186,35 @@ static void chap_lowerup(int unit) { struct chap_client_state *cs = &client; +#if PPP_SERVER struct chap_server_state *ss = &server; +#endif /* PPP_SERVER */ cs->flags |= LOWERUP; +#if PPP_SERVER ss->flags |= LOWERUP; if (ss->flags & AUTH_STARTED) chap_timeout(ss); +#endif /* PPP_SERVER */ } static void chap_lowerdown(int unit) { struct chap_client_state *cs = &client; +#if PPP_SERVER struct chap_server_state *ss = &server; +#endif /* PPP_SERVER */ cs->flags = 0; +#if PPP_SERVER if (ss->flags & TIMEOUT_PENDING) UNTIMEOUT(chap_timeout, ss); ss->flags = 0; +#endif /* PPP_SERVER */ } +#if PPP_SERVER /* * chap_auth_peer - Start authenticating the peer. * If the lower layer is already up, we start sending challenges, @@ -228,6 +245,7 @@ chap_auth_peer(int unit, char *our_name, int digest_code) if (ss->flags & LOWERUP) chap_timeout(ss); } +#endif /* PPP_SERVER */ /* * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. @@ -255,6 +273,7 @@ chap_auth_with_peer(int unit, char *our_name, int digest_code) cs->flags |= AUTH_STARTED; } +# if PPP_SERVER /* * chap_timeout - It's time to send another challenge to the peer. * This could be either a retransmission of a previous challenge, @@ -446,6 +465,7 @@ chap_verify_response(char *name, char *ourname, int id, return ok; } +#endif /* PPP_SERVER */ /* * chap_respond - Generate and send a response to a challenge. @@ -546,7 +566,10 @@ static void chap_input(int unit, unsigned char *pkt, int pktlen) { struct chap_client_state *cs = &client; +#if PPP_SERVER struct chap_server_state *ss = &server; +#endif /* PPP_SERVER */ + unsigned char code, id; int len; @@ -563,9 +586,11 @@ chap_input(int unit, unsigned char *pkt, int pktlen) case CHAP_CHALLENGE: chap_respond(cs, id, pkt, len); break; +#if PPP_SERVER case CHAP_RESPONSE: chap_handle_response(ss, id, pkt, len); break; +#endif /* PPP_SERVER */ case CHAP_FAILURE: case CHAP_SUCCESS: chap_handle_status(cs, code, id, pkt, len); @@ -577,6 +602,7 @@ static void chap_protrej(int unit) { struct chap_client_state *cs = &client; +#if PPP_SERVER struct chap_server_state *ss = &server; if (ss->flags & TIMEOUT_PENDING) { @@ -587,6 +613,7 @@ chap_protrej(int unit) ss->flags = 0; auth_peer_fail(0, PPP_CHAP); } +#endif /* PPP_SERVER */ if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { cs->flags &= ~AUTH_STARTED; error("CHAP authentication failed due to protocol-reject"); diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h index 3bb9efc0..0713dca8 100644 --- a/src/netif/ppp/chap-new.h +++ b/src/netif/ppp/chap-new.h @@ -118,6 +118,7 @@ extern int chap_mdtype_all; struct chap_digest_type { int code; +#if PPP_SERVER /* * Note: challenge and response arguments below are formatted as * a length byte followed by the actual challenge/response data. @@ -127,6 +128,7 @@ struct chap_digest_type { unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, char *message, int message_space); +#endif /* PPP_SERVER */ void (*make_response)(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *priv); @@ -147,8 +149,10 @@ extern int (*chap_verify_hook)(char *name, char *ourname, int id, /* Called by digest code to register a digest type */ extern void chap_register_digest(struct chap_digest_type *); +#if PPP_SERVER /* Called by authentication code to start authenticating the peer. */ extern void chap_auth_peer(int unit, char *our_name, int digest_code); +#endif /* PPP_SERVER */ /* Called by auth. code to start authenticating us to the peer. */ extern void chap_auth_with_peer(int unit, char *our_name, int digest_code); diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 11a8258f..3e1d9af9 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -159,6 +159,7 @@ static option_t chapms_option_list[] = { }; #endif /* PPP_OPTIONS */ +#if PPP_SERVER /* * chapms_generate_challenge - generate a challenge for MS-CHAP. * For MS-CHAP the challenge length is fixed at 8 bytes. @@ -313,6 +314,7 @@ chapms2_verify_response(int id, char *name, challenge_len, challenge, "Access denied"); return 0; } +#endif /* PPP_SERVER */ static void chapms_make_response(unsigned char *response, int id, char *our_name, @@ -919,8 +921,10 @@ set_mppe_enc_types(int policy, int types) static struct chap_digest_type chapms_digest = { CHAP_MICROSOFT, /* code */ +#if PPP_SERVER chapms_generate_challenge, chapms_verify_response, +#endif /* PPP_SERVER */ chapms_make_response, NULL, /* check_success */ chapms_handle_failure, @@ -928,8 +932,10 @@ static struct chap_digest_type chapms_digest = { static struct chap_digest_type chapms2_digest = { CHAP_MICROSOFT_V2, /* code */ +#if PPP_SERVER chapms2_generate_challenge, chapms2_verify_response, +#endif /* PPP_SERVER */ chapms2_make_response, chapms2_check_success, chapms_handle_failure, diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 305e795d..9c2337ea 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -175,8 +175,10 @@ static const u_char wkmodulus[] = { }; #endif +#if PPP_SERVER /* Local forward declarations. */ static void eap_server_timeout (void *arg); +#endif /* PPP_SERVER */ /* * Convert EAP state code to printable string for debug. @@ -202,9 +204,11 @@ int unit; BZERO(esp, sizeof (*esp)); esp->es_unit = unit; +#if PPP_SERVER esp->es_server.ea_timeout = EAP_DEFTIMEOUT; esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS; esp->es_server.ea_id = (u_char)(drand48() * 0x100); +#endif /* PPP_SERVER */ esp->es_client.ea_timeout = EAP_DEFREQTIME; esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; } @@ -255,6 +259,7 @@ char *localname; esp->es_client.ea_timeout); } +#if PPP_SERVER /* * Format a standard EAP Failure message and send it to the peer. * (Server operation) @@ -304,6 +309,7 @@ eap_state *esp; auth_peer_success(esp->es_unit, PPP_EAP, 0, esp->es_server.ea_peer, esp->es_server.ea_peerlen); } +#endif /* PPP_SERVER */ #ifdef USE_SRP /* @@ -414,6 +420,7 @@ u_char *outp; } #endif /* USE_SRP */ +#if PPP_SERVER /* * Assume that current waiting server state is complete and figure * next state to use based on available authentication data. 'status' @@ -954,6 +961,7 @@ void *arg; esp->es_server.ea_id++; eap_send_request(esp); } +#endif /* PPP_SERVER */ /* * eap_lowerup - The lower layer is now up. @@ -970,16 +978,20 @@ int unit; eap_state *esp = &eap_states[unit]; /* Discard any (possibly authenticated) peer name. */ +#if PPP_SERVER if (esp->es_server.ea_peer != NULL && esp->es_server.ea_peer != remote_name) free(esp->es_server.ea_peer); esp->es_server.ea_peer = NULL; +#endif /* PPP_SERVER */ if (esp->es_client.ea_peer != NULL) free(esp->es_client.ea_peer); esp->es_client.ea_peer = NULL; esp->es_client.ea_state = eapClosed; +#if PPP_SERVER esp->es_server.ea_state = eapClosed; +#endif /* PPP_SERVER */ } /* @@ -996,6 +1008,7 @@ int unit; if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } +#if PPP_SERVER if (eap_server_active(esp)) { if (esp->es_server.ea_timeout > 0) { UNTIMEOUT(eap_server_timeout, (void *)esp); @@ -1014,6 +1027,7 @@ int unit; esp->es_client.ea_state = esp->es_server.ea_state = eapInitial; esp->es_client.ea_requests = esp->es_server.ea_requests = 0; +#endif /* PPP_SERVER */ } /* @@ -1032,10 +1046,12 @@ int unit; error("EAP authentication failed due to Protocol-Reject"); auth_withpeer_fail(unit, PPP_EAP); } +#if PPP_SERVER if (eap_server_active(esp)) { error("EAP authentication of peer failed on Protocol-Reject"); auth_peer_fail(unit, PPP_EAP); } +#endif /* PPP_SERVER */ eap_lowerdown(unit); } @@ -1717,6 +1733,8 @@ client_failure: #endif /* USE_SRP */ } +#if PPP_SERVER +/* FIXME: remove malloc() and free() */ /* * eap_response - Receive EAP Response message (server mode). */ @@ -2011,6 +2029,7 @@ int len; eap_send_request(esp); } } +#endif /* PPP_SERVER */ /* * eap_success - Receive EAP Success message (client mode). @@ -2110,9 +2129,11 @@ int inlen; eap_request(esp, inp, id, len); break; +#if PPP_SERVER case EAP_RESPONSE: eap_response(esp, inp, id, len); break; +#endif /* PPP_SERVER */ case EAP_SUCCESS: eap_success(esp, inp, id, len); diff --git a/src/netif/ppp/eap.h b/src/netif/ppp/eap.h index 632df5f9..2a7eed47 100644 --- a/src/netif/ppp/eap.h +++ b/src/netif/ppp/eap.h @@ -101,9 +101,11 @@ enum eap_state_code { "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" #define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) +#if PPP_SERVER #define eap_server_active(esp) \ ((esp)->es_server.ea_state >= eapIdentify && \ (esp)->es_server.ea_state <= eapMD5Chall) +#endif /* PPP_SERVER */ struct eap_auth { char *ea_name; /* Our name */ @@ -128,7 +130,9 @@ struct eap_auth { typedef struct eap_state { int es_unit; /* Interface unit number */ struct eap_auth es_client; /* Client (authenticatee) data */ +#if PPP_SERVER struct eap_auth es_server; /* Server (authenticator) data */ +#endif /* PPP_SERVER */ int es_savedtime; /* Saved timeout */ int es_rechallenge; /* EAP rechallenge interval */ int es_lwrechallenge; /* SRP lightweight rechallenge inter */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index eddba238..68936e89 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -125,7 +125,9 @@ struct protent pap_protent = { upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ static void upap_timeout (void *); +#if PPP_SERVER static void upap_reqtimeout (void *); +#endif /* PPP_SERVER */ #if 0 /* UNUSED */ static void upap_rauthreq (upap_state *, u_char *, int, int); #endif /* UNUSED */ @@ -152,7 +154,9 @@ upap_init(unit) u->us_passwd = NULL; u->us_passwdlen = 0; u->us_clientstate = UPAPCS_INITIAL; +#if PPP_SERVER u->us_serverstate = UPAPSS_INITIAL; +#endif /* PPP_SERVER */ u->us_id = 0; u->us_timeouttime = UPAP_DEFTIMEOUT; u->us_maxtransmits = 10; @@ -189,7 +193,7 @@ upap_authwithpeer(unit, user, password) upap_sauthreq(u); /* Start protocol */ } - +#if PPP_SERVER /* * upap_authpeer - Authenticate our peer (start server). * @@ -212,7 +216,7 @@ upap_authpeer(unit) if (u->us_reqtimeout > 0) TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); } - +#endif /* PPP_SERVER */ /* * upap_timeout - Retransmission timer for sending auth-reqs expired. @@ -238,6 +242,7 @@ upap_timeout(arg) } +#if PPP_SERVER /* * upap_reqtimeout - Give up waiting for the peer to send an auth-req. */ @@ -253,6 +258,7 @@ upap_reqtimeout(arg) auth_peer_fail(u->us_unit, PPP_PAP); u->us_serverstate = UPAPSS_BADAUTH; } +#endif /* PPP_SERVER */ /* @@ -272,6 +278,7 @@ upap_lowerup(unit) upap_sauthreq(u); /* send an auth-request */ } +#if PPP_SERVER if (u->us_serverstate == UPAPSS_INITIAL) u->us_serverstate = UPAPSS_CLOSED; else if (u->us_serverstate == UPAPSS_PENDING) { @@ -279,6 +286,7 @@ upap_lowerup(unit) if (u->us_reqtimeout > 0) TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); } +#endif /* PPP_SERVER */ } @@ -295,11 +303,15 @@ upap_lowerdown(unit) if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ +#if PPP_SERVER if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) UNTIMEOUT(upap_reqtimeout, u); +#endif /* PPP_SERVER */ u->us_clientstate = UPAPCS_INITIAL; +#if PPP_SERVER u->us_serverstate = UPAPSS_INITIAL; +#endif /* PPP_SERVER */ } @@ -318,10 +330,12 @@ upap_protrej(unit) error("PAP authentication failed due to protocol-reject"); auth_withpeer_fail(unit, PPP_PAP); } +#if PPP_SERVER if (u->us_serverstate == UPAPSS_LISTEN) { error("PAP authentication of peer failed (protocol-reject)"); auth_peer_fail(unit, PPP_PAP); } +#endif /* PPP_SERVER */ upap_lowerdown(unit); } diff --git a/src/netif/ppp/upap.h b/src/netif/ppp/upap.h index 189e858e..c0bdae99 100644 --- a/src/netif/ppp/upap.h +++ b/src/netif/ppp/upap.h @@ -69,7 +69,9 @@ typedef struct upap_state { char *us_passwd; /* Password */ int us_passwdlen; /* Password length */ int us_clientstate; /* Client state */ +#if PPP_SERVER int us_serverstate; /* Server state */ +#endif /* PPP_SERVER */ u_char us_id; /* Current id */ int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ int us_transmits; /* Number of auth-reqs sent */ From 302184938a004717dd7956214ee5ce177416861b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 7 Jun 2012 23:02:08 +0200 Subject: [PATCH 122/320] removed malloc() from ms chap --- src/netif/ppp/chap_ms.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 3e1d9af9..8dde4827 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -377,14 +377,10 @@ static void chapms_handle_failure(unsigned char *inp, int len) { int err; - char *p, *msg; + char *p, msg[64]; /* We want a null-terminated string for strxxx(). */ - msg = malloc(len + 1); - if (!msg) { - notice("Out of memory in chapms_handle_failure"); - return; - } + len = LWIP_MIN(len, 63); MEMCPY(msg, inp, len); msg[len] = 0; p = msg; @@ -432,7 +428,6 @@ chapms_handle_failure(unsigned char *inp, int len) break; default: - free(msg); error("Unknown MS-CHAP authentication failure: %.*v", len, inp); return; @@ -441,7 +436,6 @@ chapms_handle_failure(unsigned char *inp, int len) print_msg: if (p != NULL) error("MS-CHAP authentication failed: %v", p); - free(msg); } static void From 2e6fa7f8a387d10b869807a04eb0a7ae015ffdf9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 7 Jun 2012 23:05:19 +0200 Subject: [PATCH 123/320] dns server support is done, clearing FIXME entries --- src/netif/ppp/ipcp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 66171bb3..2d9913c9 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1846,7 +1846,6 @@ ipcp_up(f) #endif /* UNUSED */ if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { sdns(f->unit, go->dnsaddr[0], go->dnsaddr[1]); - /* FIXME: set here the DNS servers ? */ #if 0 /* UNUSED */ script_setenv("USEPEERDNS", "1", 0); create_resolv(go->dnsaddr[0], go->dnsaddr[1]); From d27da93c33db0d1286a245de46ac6075f469f0d5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 7 Jun 2012 23:34:06 +0200 Subject: [PATCH 124/320] now using maxconnect from ppp_settings --- src/netif/ppp/auth.c | 4 ++-- src/netif/ppp/options.c | 2 +- src/netif/ppp/ppp_impl.h | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 37c4df3c..3ac8405c 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1227,8 +1227,8 @@ np_up(unit, proto) * Set a timeout to close the connection once the maximum * connect time has expired. */ - if (maxconnect > 0) - TIMEOUT(connect_time_expired, 0, maxconnect); + if (ppp_settings.maxconnect > 0) + TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect); #ifdef MAXOCTETS if (maxoctets > 0) diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 0cbe1de7..d2707d75 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -98,8 +98,8 @@ char devnam[MAXPATHLEN]; /* Device name */ #endif bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ -int maxconnect = 0; /* Maximum connect time */ #if 0 +int maxconnect = 0; /* Maximum connect time */ char user[MAXNAMELEN]; /* Username for PAP */ char passwd[MAXSECRETLEN]; /* Password for PAP */ #endif diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index dfdacb64..184dfdd5 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -279,9 +279,6 @@ extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ /* FIXME: add more HAVE_MULTILINK */ extern bool multilink; /* enable multilink operation */ -/* FIXME: it is really necessary ? */ -extern int maxconnect; /* Maximum connect time (seconds) */ - #ifdef HAVE_MULTILINK extern bool doing_multilink; extern bool multilink_master; From b922eaa7540bb12c37ab665f78a34249c935a66b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 00:52:20 +0200 Subject: [PATCH 125/320] print packet is working back, at least for PPPoE --- src/netif/ppp/options.c | 6 ++---- src/netif/ppp/ppp.c | 10 +++++++++- src/netif/ppp/upap.c | 5 +++-- src/netif/ppp/utils.c | 29 ++++++++++++++++++----------- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index d2707d75..5dd15894 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -91,19 +91,17 @@ struct option_value { * Option variables and default values. */ int debug = 0; /* Debug flag */ +#if 0 int kdebugflag = 0; /* Tell kernel to print debug messages */ int default_device = 1; /* Using /dev/tty or equivalent */ -#if 0 char devnam[MAXPATHLEN]; /* Device name */ -#endif bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ -#if 0 int maxconnect = 0; /* Maximum connect time */ char user[MAXNAMELEN]; /* Username for PAP */ char passwd[MAXSECRETLEN]; /* Password for PAP */ -#endif bool persist = 0; /* Reopen link after it goes down */ +#endif char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ #if DEMAND_SUPPORT bool demand = 0; /* do dial-on-demand */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0482e845..b5f91058 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1057,6 +1057,10 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb) { goto drop; } +#if PRINTPKT_SUPPORT + dump_packet("rcvd", pb->payload, pb->len); +#endif /* PRINTPKT_SUPPORT */ + in_protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; /* make room for ppp_input_header - should not fail */ @@ -1068,7 +1072,7 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb) { pih = pb->payload; pih->unit = pd; - pih->proto = in_protocol; + pih->proto = in_protocol; /* pih->proto is now in host byte order */ /* Dispatch the packet thereby consuming it. */ ppp_input(pb); @@ -1540,6 +1544,10 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { return PPPERR_DEVICE; } +#if PRINTPKT_SUPPORT + dump_packet("sent", (unsigned char *)s, n); +#endif /* PRINTPKT_SUPPORT */ + snmp_add_ifoutoctets(&pc->netif, (u16_t)n); snmp_inc_ifoutucastpkts(&pc->netif); LINK_STATS_INC(link.xmit); diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 68936e89..2e49854d 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -56,9 +56,10 @@ #include "upap.h" -#if 0 /* UNUSED */ +/* FIXME: move that to ppp_options */ +#if PRINTPKT_SUPPORT static bool hide_password = 1; -#endif /* UNUSED */ +#endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS /* diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 074d7a34..5720bd17 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -75,12 +75,12 @@ static void log_write (int, char *); static void vslp_printer (void *, char *, ...); static void format_packet (u_char *, int, void (*) (void *, char *, ...), void *); -#endif /* PRINTPKT_SUPPORT */ struct buffer_info { char *ptr; int len; }; +#endif /* PRINTPKT_SUPPORT */ /* * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, @@ -482,10 +482,9 @@ format_packet(p, len, printer, arg) u_short proto; struct protent *protp; - if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { - p += 2; + if (len >= 2) { GETSHORT(proto, p); - len -= PPP_HDRLEN; + len -= 2; for (i = 0; (protp = protocols[i]) != NULL; ++i) if (proto == protp->protocol) break; @@ -651,9 +650,7 @@ log_write(level, buf) int level; char *buf; { -/* FIXME: replace this with a log callback */ - /* if(level >= min_log_level) */ /* FIXME: add a minimum log level */ - PPPDEBUG(LOG_DEBUG, ("LOG: %s\n", buf) ); + PPPDEBUG(level, ("%s\n", buf) ); #if 0 if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { int n = strlen(buf); @@ -764,18 +761,28 @@ dump_packet(const char *tag, unsigned char *p, int len) if (!debug) return; + /* + * don't print IPv4 and IPv6 packets. + */ + proto = (p[0] << 8) + p[1]; + if (proto == PPP_IP) + return; +#ifdef INET6 + if (proto == PPP_IPV6 || proto == PPP_IPV6CP) + return; +#endif + /* * don't print LCP echo request/reply packets if debug <= 1 * and the link is up. */ - proto = (p[2] << 8) + p[3]; if (debug <= 1 && unsuccess == 0 && proto == PPP_LCP - && len >= PPP_HDRLEN + HEADERLEN) { - unsigned char *lcp = p + PPP_HDRLEN; + && len >= 2 + HEADERLEN) { + unsigned char *lcp = p + 2; int l = (lcp[2] << 8) + lcp[3]; if ((lcp[0] == ECHOREQ || lcp[0] == ECHOREP) - && l >= HEADERLEN && l <= len - PPP_HDRLEN) + && l >= HEADERLEN && l <= len - 2) return; } From 21653f0f91f4784764a8c6364d43dcaf41df2e32 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 01:20:01 +0200 Subject: [PATCH 126/320] pr_log is unused, don't even try to build it --- src/netif/ppp/utils.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 5720bd17..fe07e4fb 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -448,7 +448,7 @@ vslp_printer (void *arg, char *fmt, ...) } #endif /* PRINTPKT_SUPPORT */ -#ifdef unused +#if 0 /* UNUSED */ /* * log_packet - format a packet and log it. */ @@ -464,7 +464,7 @@ log_packet(p, len, prefix, level) format_packet(p, len, pr_log, &level); end_pr_log(); } -#endif /* unused */ +#endif /* UNUSED */ #if PRINTPKT_SUPPORT /* @@ -517,6 +517,7 @@ format_packet(p, len, printer, arg) } #endif /* PRINTPKT_SUPPORT */ +#if 0 /* UNUSED */ /* * init_pr_log, end_pr_log - initialize and finish use of pr_log. */ @@ -595,6 +596,7 @@ pr_log (void *arg, char *fmt, ...) linep = line + l; } } +#endif /* UNUSED */ /* * print_string - print a readable representation of a string using From 2ec79c03a08a1aa3bbd41784aa4061fbbb98de66 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 01:26:21 +0200 Subject: [PATCH 127/320] unused ifunit global variable removed --- src/netif/ppp/ipcp.c | 2 +- src/netif/ppp/ppp.c | 3 --- src/netif/ppp/ppp_impl.h | 2 -- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 2d9913c9..29cbccff 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1824,7 +1824,7 @@ ipcp_up(f) return; } if (ho->hisaddr == 0 && !noremoteip) { - ho->hisaddr = htonl(0x0a404040 + ifunit); + ho->hisaddr = htonl(0x0a404040); warn("Could not determine remote IP address: defaulting to %I", ho->hisaddr); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index b5f91058..25333554 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -156,8 +156,6 @@ int unsuccess; /* # unsuccessful connection attempts */ int listen_time; /* time to listen first (ms) */ int status; /* exit status for pppd */ int need_holdoff; /* need holdoff period before restarting */ -/* FIXME: remove ifunit */ -int ifunit; /* Interface unit number */ /* FIXME: outpacket_buf per PPP session */ @@ -367,7 +365,6 @@ int ppp_init(void) { listen_time = 0; status = EXIT_OK; need_holdoff = 1; - ifunit = 1; /* FIXME: remove ifunit */ #if PPP_STATS_SUPPORT link_stats_valid = 0; #endif /* PPP_STATS_SUPPORT */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 184dfdd5..d35b5f33 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -272,8 +272,6 @@ extern int unsuccess; /* # unsuccessful connection attempts */ extern int listen_time; /* time to listen first (ms) */ extern int status; /* exit status for pppd */ extern int need_holdoff; /* Need holdoff period after link terminates */ -/* FIXME: remove ifunit */ -extern int ifunit; /* Interface unit number */ extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ /* FIXME: add more HAVE_MULTILINK */ From 552589f098887e2b8e0bda4fee68e8556903e092 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 14:14:06 +0200 Subject: [PATCH 128/320] removed multilink option when multilink support is not compiled --- src/netif/ppp/lcp.c | 18 ++++++++++++++---- src/netif/ppp/options.c | 2 ++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 495ea1f5..241b3999 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -741,11 +741,15 @@ lcp_resetci(f) wo->magicnumber = magic(); wo->numloops = 0; *go = *wo; +#ifdef HAVE_MULTILINK if (!multilink) { +#endif /* HAVE_MULTILINK */ go->neg_mrru = 0; go->neg_ssnhf = 0; go->neg_endpoint = 0; +#ifdef HAVE_MULTILINK } +#endif /* HAVE_MULTILINK */ if (noendpoint) ao->neg_endpoint = 0; peer_mru[f->unit] = PPP_MRU; @@ -2165,8 +2169,11 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; case CI_MRRU: - if (!ao->neg_mrru || !multilink || - cilen != CILEN_SHORT) { + if (!ao->neg_mrru +#ifdef HAVE_MULTILINK + || !multilink +#endif /* HAVE_MULTILINK */ + || cilen != CILEN_SHORT) { orc = CONFREJ; break; } @@ -2178,8 +2185,11 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) break; case CI_SSNHF: - if (!ao->neg_ssnhf || !multilink || - cilen != CILEN_VOID) { + if (!ao->neg_ssnhf +#ifdef HAVE_MULTILINK + || !multilink +#endif /* HAVE_MULTILINK */ + || cilen != CILEN_VOID) { orc = CONFREJ; break; } diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 5dd15894..17cd6442 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -121,7 +121,9 @@ 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 */ int req_unit = -1; /* requested interface unit */ +#if 0 bool multilink = 0; /* Enable multilink operation */ +#endif char *bundle_name = NULL; /* bundle name for multilink */ bool dump_options; /* print out option values */ #if 0 From 6589cf9d8e32fcaf3c065d4011a5f0089343cdb4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 14:16:59 +0200 Subject: [PATCH 129/320] removed useless options --- src/netif/ppp/options.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 17cd6442..d4017f06 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -106,31 +106,27 @@ char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ #if DEMAND_SUPPORT bool demand = 0; /* do dial-on-demand */ #endif /* DEMAND_SUPPORT */ +#if 0 char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ +#endif 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 */ #if 0 int log_to_fd = 1; /* send log messages to this fd too */ -#endif bool log_default = 1; /* log_to_fd is default (stdout) */ int maxfail = 10; /* max # of unsuccessful connection attempts */ -#if 0 char linkname[MAXPATHLEN]; /* logical name for link */ -#endif bool tune_kernel; /* may alter kernel settings */ int connect_delay = 1000; /* wait this many ms after connect script */ int req_unit = -1; /* requested interface unit */ -#if 0 bool multilink = 0; /* Enable multilink operation */ -#endif char *bundle_name = NULL; /* bundle name for multilink */ bool dump_options; /* print out option values */ -#if 0 bool dryrun; /* print out option values and exit */ -#endif char *domain; /* domain name set by domain option */ int child_wait = 5; /* # seconds to wait for children at exit */ +#endif #ifdef MAXOCTETS unsigned int maxoctets = 0; /* default - no limit */ From 4e7ce1168475d913b7a22a90c1ae4955b79cc1cd Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 14:31:45 +0200 Subject: [PATCH 130/320] removed holdoff support, can be handled without persist mode outside lwIP --- src/netif/ppp/auth.c | 4 ++++ src/netif/ppp/options.c | 2 +- src/netif/ppp/ppp.c | 2 -- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 3ac8405c..449a0778 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1306,7 +1306,9 @@ check_maxoctets(arg) notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); status = EXIT_TRAFFIC_LIMIT; lcp_close(0, "Traffic limit"); +#if 0 /* UNUSED */ need_holdoff = 0; +#endif /* UNUSED */ } else { TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); } @@ -1343,7 +1345,9 @@ check_idle(arg) notice("Terminating connection due to lack of activity."); status = EXIT_IDLE_TIMEOUT; lcp_close(0, "Link inactive"); +#if 0 /* UNUSED */ need_holdoff = 0; +#endif /* UNUSED */ } else { TIMEOUT(check_idle, NULL, tlim); } diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index d4017f06..b5964d17 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -110,9 +110,9 @@ bool demand = 0; /* do dial-on-demand */ char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ #endif int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ +#if 0 int holdoff = 30; /* # seconds to pause before reconnecting */ bool holdoff_specified; /* true if a holdoff value has been given */ -#if 0 int log_to_fd = 1; /* send log messages to this fd too */ bool log_default = 1; /* log_to_fd is default (stdout) */ int maxfail = 10; /* max # of unsuccessful connection attempts */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 25333554..12ee1065 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -155,7 +155,6 @@ int error_count; /* # of times error() has been called */ int unsuccess; /* # unsuccessful connection attempts */ int listen_time; /* time to listen first (ms) */ int status; /* exit status for pppd */ -int need_holdoff; /* need holdoff period before restarting */ /* FIXME: outpacket_buf per PPP session */ @@ -364,7 +363,6 @@ int ppp_init(void) { unsuccess = 0; listen_time = 0; status = EXIT_OK; - need_holdoff = 1; #if PPP_STATS_SUPPORT link_stats_valid = 0; #endif /* PPP_STATS_SUPPORT */ From becc30630025e4b17b50c64b91cf1b973c4ae0a9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 14:35:06 +0200 Subject: [PATCH 131/320] using idle_time_limit from ppp_settings --- src/netif/ppp/auth.c | 4 ++-- src/netif/ppp/options.c | 2 -- src/netif/ppp/ppp_impl.h | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 449a0778..04f96dc2 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1219,7 +1219,7 @@ np_up(unit, proto) tlim = (*idle_time_hook)(NULL); else #endif /* UNUSED */ - tlim = idle_time_limit; + tlim = ppp_settings.idle_time_limit; if (tlim > 0) TIMEOUT(check_idle, NULL, tlim); @@ -1336,7 +1336,7 @@ check_idle(arg) } else { #endif /* UNUSED */ itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); - tlim = idle_time_limit - itime; + tlim = ppp_settings.idle_time_limit - itime; #if 0 /* UNUSED */ } #endif /* UNUSED */ diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index b5964d17..8a766fdc 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -108,9 +108,7 @@ bool demand = 0; /* do dial-on-demand */ #endif /* DEMAND_SUPPORT */ #if 0 char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ -#endif int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ -#if 0 int holdoff = 30; /* # seconds to pause before reconnecting */ bool holdoff_specified; /* true if a holdoff value has been given */ int log_to_fd = 1; /* send log messages to this fd too */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index d35b5f33..1da3d78a 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -434,7 +434,7 @@ struct ppp_settings { u_int usepeerdns : 1; /* Ask peer for DNS adds */ u_int persist : 1; /* Persist mode, always try to reopen the connection */ - u_short idle_time_limit; /* Shut down link if idle for this long */ + u_short idle_time_limit; /* Disconnect if idle for this many seconds */ int maxconnect; /* Maximum connect time (seconds) */ char user [MAXNAMELEN + 1]; /* Username for PAP */ From 6db3026d475e2768373cf94f175f2a484b853388 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 14:39:44 +0200 Subject: [PATCH 132/320] using our_name from ppp_settings (only used in server mode and disabled by default) --- src/netif/ppp/auth.c | 4 ++-- src/netif/ppp/options.c | 2 +- src/netif/ppp/ppp_impl.h | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 04f96dc2..440fae0c 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -822,13 +822,13 @@ link_established(unit) #if PPP_SERVER #if EAP_SUPPORT if (go->neg_eap) { - eap_authpeer(unit, our_name); + eap_authpeer(unit, ppp_settings.our_name); auth |= EAP_PEER; } else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (go->neg_chap) { - chap_auth_peer(unit, our_name, CHAP_DIGEST(go->chap_mdtype)); + chap_auth_peer(unit, ppp_settings.our_name, CHAP_DIGEST(go->chap_mdtype)); auth |= CHAP_PEER; } else #endif /* CHAP_SUPPORT */ diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index 8a766fdc..b0f3fdc3 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -101,8 +101,8 @@ 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 */ -#endif char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ +#endif #if DEMAND_SUPPORT bool demand = 0; /* do dial-on-demand */ #endif /* DEMAND_SUPPORT */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 1da3d78a..6b19cd0a 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -439,7 +439,9 @@ struct ppp_settings { char user [MAXNAMELEN + 1]; /* Username for PAP */ char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ +#if PPP_SERVER char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ +#endif /* PPP_SERVER */ /* FIXME: re-enable that */ /* char remote_name[MAXNAMELEN + 1]; */ /* Peer's name for authentication */ }; From fb396b8fac3865ff2189bf2a6e8a3116d14433d7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 14:42:31 +0200 Subject: [PATCH 133/320] moved debug option from options.c to ppp.c --- src/netif/ppp/options.c | 6 ++++++ src/netif/ppp/ppp.c | 1 + 2 files changed, 7 insertions(+) diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c index b0f3fdc3..29f64800 100644 --- a/src/netif/ppp/options.c +++ b/src/netif/ppp/options.c @@ -81,11 +81,13 @@ char *strdup (char *); #endif +#if 0 struct option_value { struct option_value *next; const char *source; char value[1]; }; +#endif /* * Option variables and default values. @@ -142,13 +144,17 @@ struct bpf_program pass_filter;/* Filter program for packets to pass */ struct bpf_program active_filter; /* Filter program for link-active pkts */ #endif +#if 0 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 */ +#endif #if 0 /* UNUSED */ int option_priority = OPRIO_CFGFILE; /* priority of the current options */ #endif /* UNUSED */ +#if 0 bool devnam_fixed; /* can no longer change device name */ +#endif #if 0 /* UNUSED */ static int logfile_fd = -1; /* fd opened for log file */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 12ee1065..bae0784d 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -150,6 +150,7 @@ */ /* FIXME: global variables per PPP session */ /* FIXME: clean global variables */ +int debug = 0; /* Debug flag */ int phase; /* where the link is at */ int error_count; /* # of times error() has been called */ int unsuccess; /* # unsuccessful connection attempts */ From 1ccf516c5ed0281478a0b7e275e6ea81084c39b6 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 14:43:56 +0200 Subject: [PATCH 134/320] options.c is now empty, removed --- src/netif/ppp/options.c | 1642 --------------------------------------- 1 file changed, 1642 deletions(-) delete mode 100644 src/netif/ppp/options.c diff --git a/src/netif/ppp/options.c b/src/netif/ppp/options.c deleted file mode 100644 index 29f64800..00000000 --- a/src/netif/ppp/options.c +++ /dev/null @@ -1,1642 +0,0 @@ -/* - * options.c - handles option processing for PPP. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "lwip/opt.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include -#include -#include -#include -#include -#include -#if 0 -#include -#endif -#include -#include -#ifdef PLUGIN -#include -#endif - -#ifdef PPP_FILTER -#include -/* - * There have been 3 or 4 different names for this in libpcap CVS, but - * this seems to be what they have settled on... - * For older versions of libpcap, use DLT_PPP - but that means - * we lose the inbound and outbound qualifiers. - */ -#ifndef DLT_PPP_PPPD -#ifdef DLT_PPP_WITHDIRECTION -#define DLT_PPP_PPPD DLT_PPP_WITHDIRECTION -#else -#define DLT_PPP_PPPD DLT_PPP -#endif -#endif -#endif /* PPP_FILTER */ - -#include "ppp_impl.h" - -#if defined(ultrix) || defined(NeXT) -char *strdup (char *); -#endif - -#if 0 -struct option_value { - struct option_value *next; - const char *source; - char value[1]; -}; -#endif - -/* - * Option variables and default values. - */ -int debug = 0; /* Debug flag */ -#if 0 -int kdebugflag = 0; /* Tell kernel to print debug messages */ -int default_device = 1; /* Using /dev/tty or equivalent */ -char devnam[MAXPATHLEN]; /* Device name */ -bool nodetach = 0; /* Don't detach from controlling tty */ -bool updetach = 0; /* Detach once link is up */ -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 */ -#endif -#if DEMAND_SUPPORT -bool demand = 0; /* do dial-on-demand */ -#endif /* DEMAND_SUPPORT */ -#if 0 -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 */ -int log_to_fd = 1; /* send log messages to this fd too */ -bool log_default = 1; /* log_to_fd is default (stdout) */ -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 */ -int req_unit = -1; /* requested interface unit */ -bool multilink = 0; /* Enable multilink operation */ -char *bundle_name = NULL; /* bundle name for multilink */ -bool dump_options; /* print out option values */ -bool dryrun; /* print out option values and exit */ -char *domain; /* domain name set by domain option */ -int child_wait = 5; /* # seconds to wait for children at exit */ -#endif - -#ifdef MAXOCTETS -unsigned int maxoctets = 0; /* default - no limit */ -int maxoctets_dir = 0; /* default - sum of traffic */ -int maxoctets_timeout = 1; /* default 1 second */ -#endif - -#if 0 /* UNUSED */ -extern option_t auth_options[]; -extern struct stat devstat; -#endif /* UNUSED */ - -#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 */ -#endif - -#if 0 -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 */ -#endif -#if 0 /* UNUSED */ -int option_priority = OPRIO_CFGFILE; /* priority of the current options */ -#endif /* UNUSED */ -#if 0 -bool devnam_fixed; /* can no longer change device name */ -#endif - -#if 0 /* UNUSED */ -static int logfile_fd = -1; /* fd opened for log file */ -static char logfile_name[MAXPATHLEN]; /* name of log file */ -#endif /* UNUSED */ - -/* - * Prototypes - */ -#if 0 /* UNUSED */ -static int setdomain (char **); -static int readfile (char **); -static int callfile (char **); -static int showversion (char **); -static int showhelp (char **); -static void usage (void); -static int setlogfile (char **); -#endif /* UNUSED */ -#ifdef PLUGIN -static int loadplugin (char **); -#endif - -#ifdef PPP_FILTER -static int setpassfilter (char **); -static int setactivefilter (char **); -#endif - -#ifdef MAXOCTETS -static int setmodir (char **); -#endif - -#if 0 /* UNUSED */ -static option_t *find_option (const char *name); -static int process_option (option_t *, char *, char **); -static int n_arguments (option_t *); -static int number_option (char *, u_int32_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 }, - { "-d", o_int, &debug, - "Increase debugging level", - OPT_ALIAS | OPT_INC | OPT_NOARG | 1 }, - - { "kdebug", o_int, &kdebugflag, - "Set kernel driver debug level", OPT_PRIO }, - - { "nodetach", o_bool, &nodetach, - "Don't detach from controlling tty", OPT_PRIO | 1 }, - { "-detach", o_bool, &nodetach, - "Don't detach from controlling tty", OPT_ALIAS | OPT_PRIOSUB | 1 }, - { "updetach", o_bool, &updetach, - "Detach from controlling tty once link is up", - OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach }, - - { "holdoff", o_int, &holdoff, - "Set time in seconds before retrying connection", - OPT_PRIO, &holdoff_specified }, - - { "idle", o_int, &idle_time_limit, - "Set time in seconds before disconnecting idle link", OPT_PRIO }, - - { "maxconnect", o_int, &maxconnect, - "Set connection time limit", - OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, - - { "domain", o_special, (void *)setdomain, - "Add given domain name to hostname", - OPT_PRIO | OPT_PRIV | OPT_A2STRVAL, &domain }, - - { "file", o_special, (void *)readfile, - "Take options from a file", OPT_NOPRINT }, - { "call", o_special, (void *)callfile, - "Take options from a privileged file", OPT_NOPRINT }, - - { "persist", o_bool, &persist, - "Keep on reopening connection after close", OPT_PRIO | 1 }, - { "nopersist", o_bool, &persist, - "Turn off persist option", OPT_PRIOSUB }, - - { "demand", o_bool, &demand, - "Dial on demand", OPT_INITONLY | 1, &persist }, - - { "--version", o_special_noarg, (void *)showversion, - "Show version number" }, - { "--help", o_special_noarg, (void *)showhelp, - "Show brief listing of options" }, - { "-h", o_special_noarg, (void *)showhelp, - "Show brief listing of options", OPT_ALIAS }, - - { "logfile", o_special, (void *)setlogfile, - "Append log messages to this file", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, &logfile_name }, - { "logfd", o_int, &log_to_fd, - "Send log messages to this file descriptor", - OPT_PRIOSUB | OPT_A2CLR, &log_default }, - { "nolog", o_int, &log_to_fd, - "Don't send log messages to any file", - OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, - { "nologfd", o_int, &log_to_fd, - "Don't send log messages to any file descriptor", - OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, - - { "linkname", o_string, linkname, - "Set logical name for link", - OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXPATHLEN }, - - { "maxfail", o_int, &maxfail, - "Maximum number of unsuccessful connection attempts to allow", - OPT_PRIO }, - - { "ktune", o_bool, &tune_kernel, - "Alter kernel settings as necessary", OPT_PRIO | 1 }, - { "noktune", o_bool, &tune_kernel, - "Don't alter kernel settings", OPT_PRIOSUB }, - - { "connect-delay", o_int, &connect_delay, - "Maximum time (in ms) to wait after connect script finishes", - OPT_PRIO }, - - { "unit", o_int, &req_unit, - "PPP interface unit number to use if possible", - OPT_PRIO | OPT_LLIMIT, 0, 0 }, - - { "dump", o_bool, &dump_options, - "Print out option values after parsing all options", 1 }, - { "dryrun", o_bool, &dryrun, - "Stop after parsing, printing, and checking options", 1 }, - - { "child-timeout", o_int, &child_wait, - "Number of seconds to wait for child processes at exit", - OPT_PRIO }, - -#ifdef HAVE_MULTILINK - { "multilink", o_bool, &multilink, - "Enable multilink operation", OPT_PRIO | 1 }, - { "mp", o_bool, &multilink, - "Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 }, - { "nomultilink", o_bool, &multilink, - "Disable multilink operation", OPT_PRIOSUB | 0 }, - { "nomp", o_bool, &multilink, - "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 }, - - { "bundle", o_string, &bundle_name, - "Bundle name for multilink", OPT_PRIO }, -#endif /* HAVE_MULTILINK */ - -#ifdef PLUGIN - { "plugin", o_special, (void *)loadplugin, - "Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST }, -#endif - -#ifdef PPP_FILTER - { "pass-filter", o_special, setpassfilter, - "set filter for packets to pass", OPT_PRIO }, - - { "active-filter", o_special, setactivefilter, - "set filter for active pkts", OPT_PRIO }, -#endif - -#ifdef MAXOCTETS - { "maxoctets", o_int, &maxoctets, - "Set connection traffic limit", - OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, - { "mo", o_int, &maxoctets, - "Set connection traffic limit", - OPT_ALIAS | OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, - { "mo-direction", o_special, setmodir, - "Set direction for limit traffic (sum,in,out,max)" }, - { "mo-timeout", o_int, &maxoctets_timeout, - "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 }, -#endif - - { NULL } -}; - -#ifndef IMPLEMENTATION -#define IMPLEMENTATION "" -#endif - -static char *usage_string = "\ -pppd version %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. - */ -int -parse_args(argc, argv) - int argc; - char **argv; -{ - char *arg; - option_t *opt; - int n; - - privileged_option = privileged; - option_source = "command line"; - option_priority = OPRIO_CMDLINE; - while (argc > 0) { - arg = *argv++; - --argc; - opt = find_option(arg); - if (opt == NULL) { - option_error("unrecognized option '%s'", arg); - usage(); - return 0; - } - n = n_arguments(opt); - if (argc < n) { - option_error("too few parameters for option %s", arg); - return 0; - } - if (!process_option(opt, arg, argv)) - return 0; - argc -= n; - argv += n; - } - return 1; -} - -/* - * options_from_file - Read a string of options from a file, - * and interpret them. - */ -int -options_from_file(filename, must_exist, check_prot, priv) - char *filename; - int must_exist; - int check_prot; - int priv; -{ - FILE *f; - int i, newline, ret, err; - option_t *opt; - int oldpriv, n; - char *oldsource; - uid_t euid; - char *argv[MAXARGS]; - char args[MAXARGS][MAXWORDLEN]; - char cmd[MAXWORDLEN]; - - euid = geteuid(); - if (check_prot && seteuid(getuid()) == -1) { - option_error("unable to drop privileges to open %s: %m", filename); - return 0; - } - f = fopen(filename, "r"); - err = errno; - if (check_prot && seteuid(euid) == -1) - fatal("unable to regain privileges"); - if (f == NULL) { - errno = err; - if (!must_exist) { - if (err != ENOENT && err != ENOTDIR) - warn("Warning: can't open options file %s: %m", filename); - return 1; - } - 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)) { - opt = find_option(cmd); - if (opt == NULL) { - option_error("In file %s: unrecognized option '%s'", - filename, cmd); - goto err; - } - 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]; - } - if (!process_option(opt, cmd, argv)) - 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() -{ - char *user, *path, *file; - int ret; - struct passwd *pw; - size_t pl; - - pw = getpwuid(getuid()); - if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) - return 1; - file = _PATH_USEROPT; - pl = strlen(user) + strlen(file) + 2; - path = malloc(pl); - if (path == NULL) - novm("init file name"); - slprintf(path, pl, "%s/%s", user, file); - option_priority = OPRIO_CFGFILE; - ret = options_from_file(path, 0, 1, privileged); - free(path); - return ret; -} - -/* - * options_for_tty - See if an options file exists for the serial - * device, and if so, interpret options from it. - * We only allow the per-tty options file to override anything from - * the command line if it is something that the user can't override - * once it has been set by root; this is done by giving configuration - * files a lower priority than the command line. - */ -int -options_for_tty() -{ - char *dev, *path, *p; - int ret; - size_t pl; - - dev = devnam; - if ((p = strstr(dev, "/dev/")) != NULL) - dev = p + 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 = '.'; - option_priority = OPRIO_CFGFILE; - 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(w, priv) - struct wordlist *w; - int priv; -{ - char *argv[MAXARGS]; - option_t *opt; - int i, n, ret = 0; - struct wordlist *w0; - - privileged_option = priv; - option_source = "secrets file"; - option_priority = OPRIO_SECFILE; - - while (w != NULL) { - opt = find_option(w->word); - if (opt == NULL) { - option_error("In secrets file: unrecognized option '%s'", - w->word); - goto err; - } - n = n_arguments(opt); - 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; - } - if (!process_option(opt, w0->word, argv)) - goto err; - w = w->next; - } - ret = 1; - -err: - return ret; -} - -/* - * match_option - see if this option matches an option_t structure. - */ -static int -match_option(name, opt, dowild) - char *name; - option_t *opt; - int dowild; -{ - int (*match) (char *, char **, int); - - if (dowild != (opt->type == o_wild)) - return 0; - if (!dowild) - return strcmp(name, opt->name) == 0; - match = (int (*) (char *, char **, int)) opt->addr; - return (*match)(name, NULL, 0); -} - -/* - * 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(name) - const char *name; -{ - option_t *opt; - struct option_list *list; - int i, dowild; - - for (dowild = 0; dowild <= 1; ++dowild) { - for (opt = general_options; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - for (opt = auth_options; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - for (list = extra_options; list != NULL; list = list->next) - for (opt = list->options; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - for (opt = the_channel->options; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - for (i = 0; protocols[i] != NULL; ++i) - if ((opt = protocols[i]->options) != NULL) - for (; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - } - return NULL; -} - -/* - * process_option - process one new-style option. - */ -static int -process_option(opt, cmd, argv) - option_t *opt; - char *cmd; - char **argv; -{ - u_int32_t v; - int iv, a; - char *sv; - int (*parser) (char **); - int (*wildp) (char *, char **, int); - char *optopt = (opt->type == o_wild)? "": " option"; - int prio = option_priority; - option_t *mainopt = opt; - - current_option = opt->name; - if ((opt->flags & OPT_PRIVFIX) && privileged_option) - prio += OPRIO_ROOT; - while (mainopt->flags & OPT_PRIOSUB) - --mainopt; - if (mainopt->flags & OPT_PRIO) { - if (prio < mainopt->priority) { - /* new value doesn't override old */ - if (prio == OPRIO_CMDLINE && mainopt->priority > OPRIO_ROOT) { - option_error("%s%s set in %s cannot be overridden\n", - opt->name, optopt, mainopt->source); - return 0; - } - return 1; - } - if (prio > OPRIO_ROOT && mainopt->priority == OPRIO_CMDLINE) - warn("%s%s from %s overrides command line", - opt->name, optopt, option_source); - } - - if ((opt->flags & OPT_INITONLY) && phase != PHASE_INITIALIZE) { - option_error("%s%s cannot be changed after initialization", - opt->name, optopt); - return 0; - } - if ((opt->flags & OPT_PRIV) && !privileged_option) { - option_error("using the %s%s requires root privilege", - opt->name, optopt); - return 0; - } - if ((opt->flags & OPT_ENABLE) && *(bool *)(opt->addr2) == 0) { - option_error("%s%s is disabled", opt->name, optopt); - return 0; - } - if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) { - option_error("the %s%s may not be changed in %s", - opt->name, optopt, option_source); - 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; - else if (opt->addr2 && (opt->flags & OPT_A2CLR)) - *(bool *)(opt->addr2) = 0; - else if (opt->addr2 && (opt->flags & OPT_A2CLRB)) - *(u_char *)(opt->addr2) &= ~v; - else if (opt->addr2 && (opt->flags & OPT_A2OR)) - *(u_char *)(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, zok, 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; - if (v & 0x80) - v |= 0xffffff00U; - } else if (!number_option(*argv, &v, 16)) - return 0; - if (opt->flags & OPT_OR) - v |= *(u_int32_t *)(opt->addr); - *(u_int32_t *)(opt->addr) = v; - if (opt->addr2 && (opt->flags & OPT_A2COPY)) - *(u_int32_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"); - *(char **)(opt->addr) = sv; - } - break; - - case o_special_noarg: - case o_special: - parser = (int (*) (char **)) opt->addr; - if (!(*parser)(argv)) - return 0; - if (opt->flags & OPT_A2LIST) { - struct option_value *ovp, *pp; - - ovp = malloc(sizeof(*ovp) + strlen(*argv)); - if (ovp != 0) { - strcpy(ovp->value, *argv); - ovp->source = option_source; - ovp->next = NULL; - if (opt->addr2 == NULL) { - opt->addr2 = ovp; - } else { - for (pp = opt->addr2; pp->next != NULL; pp = pp->next) - ; - pp->next = ovp; - } - } - } - break; - - case o_wild: - wildp = (int (*) (char *, char **, int)) opt->addr; - if (!(*wildp)(cmd, argv, 1)) - return 0; - break; - } - - /* - * If addr2 wasn't used by any flag (OPT_A2COPY, etc.) but is set, - * treat it as a bool and set/clear it based on the OPT_A2CLR bit. - */ - if (opt->addr2 && (opt->flags & (OPT_A2COPY|OPT_ENABLE - |OPT_A2PRINTER|OPT_A2STRVAL|OPT_A2LIST|OPT_A2OR)) == 0) - *(bool *)(opt->addr2) = !(opt->flags & OPT_A2CLR); - - mainopt->source = option_source; - mainopt->priority = prio; - mainopt->winner = opt - mainopt; - - return 1; -} - -/* - * override_value - if the option priorities would permit us to - * override the value of option, return 1 and update the priority - * and source of the option value. Otherwise returns 0. - */ -int -override_value(option, priority, source) - const char *option; - int priority; - const char *source; -{ - option_t *opt; - - opt = find_option(option); - if (opt == NULL) - return 0; - while (opt->flags & OPT_PRIOSUB) - --opt; - if ((opt->flags & OPT_PRIO) && priority < opt->priority) - return 0; - opt->priority = priority; - opt->source = source; - opt->winner = -1; - return 1; -} - -/* - * n_arguments - tell how many arguments an option takes - */ -static int -n_arguments(opt) - 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(opt) - 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; -} - -/* - * check_options - check that options are valid and consistent. - */ -void -check_options() -{ - if (logfile_fd >= 0 && logfile_fd != log_to_fd) - close(logfile_fd); -} - -/* - * print_option - print out an option and its value - */ -static void -print_option(opt, mainopt, printer, arg) - option_t *opt, *mainopt; - void (*printer) (void *, char *, ...); - void *arg; -{ - int i, v; - char *p; - - if (opt->flags & OPT_NOPRINT) - return; - switch (opt->type) { - case o_bool: - v = opt->flags & OPT_VALUE; - if (*(bool *)opt->addr != v) - /* this can happen legitimately, e.g. lock - option turned off for default device */ - break; - printer(arg, "%s", opt->name); - break; - case o_int: - v = opt->flags & OPT_VALUE; - if (v >= 128) - v -= 256; - i = *(int *)opt->addr; - if (opt->flags & OPT_NOARG) { - printer(arg, "%s", opt->name); - if (i != v) { - if (opt->flags & OPT_INC) { - for (; i > v; i -= v) - printer(arg, " %s", opt->name); - } else - printer(arg, " # oops: %d not %d\n", - i, v); - } - } else { - printer(arg, "%s %d", opt->name, i); - } - break; - case o_uint32: - printer(arg, "%s", opt->name); - if ((opt->flags & OPT_NOARG) == 0) - printer(arg, " %x", *(u_int32_t *)opt->addr); - break; - - case o_string: - if (opt->flags & OPT_HIDE) { - p = "??????"; - } else { - p = (char *) opt->addr; - if ((opt->flags & OPT_STATIC) == 0) - p = *(char **)p; - } - printer(arg, "%s %q", opt->name, p); - break; - - case o_special: - case o_special_noarg: - case o_wild: - if (opt->type != o_wild) { - printer(arg, "%s", opt->name); - if (n_arguments(opt) == 0) - break; - printer(arg, " "); - } - if (opt->flags & OPT_A2PRINTER) { - void (*oprt) (option_t *, - void ((*)(void *, char *, ...)), - void *); - oprt = (void (*) (option_t *, - void ((*)(void *, char *, ...)), - void *))opt->addr2; - (*oprt)(opt, printer, arg); - } else if (opt->flags & OPT_A2STRVAL) { - p = (char *) opt->addr2; - if ((opt->flags & OPT_STATIC) == 0) - p = *(char **)p; - printer("%q", p); - } else if (opt->flags & OPT_A2LIST) { - struct option_value *ovp; - - ovp = (struct option_value *) opt->addr2; - for (;;) { - printer(arg, "%q", ovp->value); - if ((ovp = ovp->next) == NULL) - break; - printer(arg, "\t\t# (from %s)\n%s ", - ovp->source, opt->name); - } - } else { - printer(arg, "xxx # [don't know how to print value]"); - } - break; - - default: - printer(arg, "# %s value (type %d\?\?)", opt->name, opt->type); - break; - } - printer(arg, "\t\t# (from %s)\n", mainopt->source); -} - -/* - * print_option_list - print out options in effect from an - * array of options. - */ -static void -print_option_list(opt, printer, arg) - option_t *opt; - void (*printer) (void *, char *, ...); - void *arg; -{ - while (opt->name != NULL) { - if (opt->priority != OPRIO_DEFAULT - && opt->winner != (short int) -1) - print_option(opt + opt->winner, opt, printer, arg); - do { - ++opt; - } while (opt->flags & OPT_PRIOSUB); - } -} - -/* - * print_options - print out what options are in effect. - */ -void -print_options(printer, arg) - void (*printer) (void *, char *, ...); - void *arg; -{ - struct option_list *list; - int i; - - printer(arg, "pppd options in effect:\n"); - print_option_list(general_options, printer, arg); - print_option_list(auth_options, printer, arg); - for (list = extra_options; list != NULL; list = list->next) - print_option_list(list->options, printer, arg); - print_option_list(the_channel->options, printer, arg); - for (i = 0; protocols[i] != NULL; ++i) - print_option_list(protocols[i]->options, printer, arg); -} - -/* - * usage - print out a message telling how to use the program. - */ -static void -usage() -{ - if (phase == PHASE_INITIALIZE) - fprintf(stderr, usage_string, VERSION, progname); -} - -/* - * showhelp - print out usage message and exit. - */ -static int -showhelp(argv) - char **argv; -{ - if (phase == PHASE_INITIALIZE) { - usage(); - exit(0); - } - return 0; -} - -/* - * showversion - print out the version number and exit. - */ -static int -showversion(argv) - char **argv; -{ - if (phase == PHASE_INITIALIZE) { - fprintf(stderr, "pppd version %s\n", VERSION); - exit(0); - } - return 0; -} - -/* - * option_error - print a message about an error in an option. - * The message is logged, and also sent to - * stderr if phase == PHASE_INITIALIZE. - */ -void -option_error (char *fmt, ...) -{ - va_list args; - char buf[1024]; - - va_start(args, fmt); - vslprintf(buf, sizeof(buf), fmt, args); - va_end(args); - if (phase == PHASE_INITIALIZE) - fprintf(stderr, "%s: %s\n", progname, buf); - syslog(LOG_ERR, "%s", buf); -} - -#if 0 -/* - * readable - check if a file is readable by the real user. - */ -int -readable(fd) - int fd; -{ - uid_t uid; - int i; - struct stat sbuf; - - uid = getuid(); - if (uid == 0) - return 1; - if (fstat(fd, &sbuf) != 0) - return 0; - if (sbuf.st_uid == uid) - return sbuf.st_mode & S_IRUSR; - if (sbuf.st_gid == getgid()) - return sbuf.st_mode & S_IRGRP; - for (i = 0; i < ngroups; ++i) - if (sbuf.st_gid == groups[i]) - return sbuf.st_mode & S_IRGRP; - return sbuf.st_mode & S_IROTH; -} -#endif - -/* - * 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(f, word, newlinep, filename) - 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(str, valp, base) - char *str; - u_int32_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(str, valp) - char *str; - int *valp; -{ - u_int32_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(argv) - 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(argv) - 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 -/* - * setpassfilter - Set the pass filter for packets - */ -static int -setpassfilter(argv) - char **argv; -{ - pcap_t *pc; - int ret = 1; - - pc = pcap_open_dead(DLT_PPP_PPPD, 65535); - if (pcap_compile(pc, &pass_filter, *argv, 1, netmask) == -1) { - option_error("error in pass-filter expression: %s\n", - pcap_geterr(pc)); - ret = 0; - } - pcap_close(pc); - - return ret; -} - -/* - * setactivefilter - Set the active filter for packets - */ -static int -setactivefilter(argv) - char **argv; -{ - pcap_t *pc; - int ret = 1; - - pc = pcap_open_dead(DLT_PPP_PPPD, 65535); - if (pcap_compile(pc, &active_filter, *argv, 1, netmask) == -1) { - option_error("error in active-filter expression: %s\n", - pcap_geterr(pc)); - ret = 0; - } - pcap_close(pc); - - return ret; -} -#endif - -/* - * setdomain - Set domain name to append to hostname - */ -static int -setdomain(argv) - char **argv; -{ - gethostname(hostname, MAXNAMELEN); - if (**argv != 0) { - if (**argv != '.') - strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); - domain = hostname + strlen(hostname); - strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); - } - hostname[MAXNAMELEN-1] = 0; - return (1); -} - -static int -setlogfile(argv) - char **argv; -{ - int fd, err; - uid_t euid; - - euid = geteuid(); - if (!privileged_option && seteuid(getuid()) == -1) { - option_error("unable to drop permissions to open %s: %m", *argv); - return 0; - } - 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 (!privileged_option && seteuid(euid) == -1) - fatal("unable to regain privileges: %m"); - if (fd < 0) { - errno = err; - option_error("Can't open log file %s: %m", *argv); - return 0; - } - strlcpy(logfile_name, *argv, sizeof(logfile_name)); - if (logfile_fd >= 0) - close(logfile_fd); - logfile_fd = fd; - log_to_fd = fd; - log_default = 0; - return 1; -} - -#ifdef MAXOCTETS -static int -setmodir(argv) - char **argv; -{ - if(*argv == NULL) - return 0; - if(!strcmp(*argv,"in")) { - maxoctets_dir = PPP_OCTETS_DIRECTION_IN; - } else if (!strcmp(*argv,"out")) { - maxoctets_dir = PPP_OCTETS_DIRECTION_OUT; - } else if (!strcmp(*argv,"max")) { - maxoctets_dir = PPP_OCTETS_DIRECTION_MAXOVERAL; - } else { - maxoctets_dir = PPP_OCTETS_DIRECTION_SUM; - } - return 1; -} -#endif - -#ifdef PLUGIN -static int -loadplugin(argv) - char **argv; -{ - char *arg = *argv; - void *handle; - const char *err; - void (*init) (void); - char *path = arg; - const char *vers; - - if (strchr(arg, '/') == 0) { - const char *base = ""; - int l = strlen(base) + strlen(arg) + 2; - path = malloc(l); - if (path == 0) - novm("plugin file path"); - strlcpy(path, base, l); - strlcat(path, "/", l); - strlcat(path, arg, l); - } - handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); - if (handle == 0) { - err = dlerror(); - if (err != 0) - option_error("%s", err); - option_error("Couldn't load plugin %s", arg); - goto err; - } - init = (void (*)(void))dlsym(handle, "plugin_init"); - if (init == 0) { - option_error("%s has no initialization entry point", arg); - goto errclose; - } - vers = (const char *) dlsym(handle, "pppd_version"); - if (vers == 0) { - warn("Warning: plugin %s has no version information", arg); - } else if (strcmp(vers, VERSION) != 0) { - option_error("Plugin %s is for pppd version %s, this is %s", - arg, vers, VERSION); - goto errclose; - } - info("Plugin %s loaded.", arg); - (*init)(); - return 1; - - errclose: - dlclose(handle); - err: - if (path != arg) - free(path); - return 0; -} -#endif /* PLUGIN */ -#endif /* PPP_OPTIONS */ - -#endif /* PPP_SUPPORT */ From 945f2912a7dd12e15a15f0c90b9f8f7c0a3fe388 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 15:09:00 +0200 Subject: [PATCH 135/320] using PPP_DEBUG instead of debug global variable --- src/netif/ppp/ipcp.c | 20 ++++++++++++-------- src/netif/ppp/ppp.c | 27 ++++++++++++--------------- src/netif/ppp/utils.c | 8 ++------ 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 29cbccff..bb7eaf58 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1893,8 +1893,9 @@ ipcp_up(f) /* Set the interface to the new addresses */ mask = get_mask(go->ouraddr); if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - if (debug) - warn("Interface configuration failed"); +#if PPP_DEBUG + warn("Interface configuration failed"); +#endif /* PPP_DEBUG */ ipcp_close(f->unit, "Interface configuration failed"); return; } @@ -1924,8 +1925,9 @@ ipcp_up(f) #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - if (debug) - warn("Interface configuration failed"); +#if PPP_DEBUG + warn("Interface configuration failed"); +#endif /* PPP_DEBUG */ ipcp_close(f->unit, "Interface configuration failed"); return; } @@ -1933,16 +1935,18 @@ ipcp_up(f) /* bring the interface up for IP */ if (!sifup(f->unit)) { - if (debug) - warn("Interface failed to come up"); +#if PPP_DEBUG + warn("Interface failed to come up"); +#endif /* PPP_DEBUG */ 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"); +#if PPP_DEBUG + warn("Interface configuration failed"); +#endif /* PPP_DEBUG */ ipcp_close(f->unit, "Interface configuration failed"); return; } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index bae0784d..1d5c501a 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -150,7 +150,6 @@ */ /* FIXME: global variables per PPP session */ /* FIXME: clean global variables */ -int debug = 0; /* Debug flag */ int phase; /* where the link is at */ int error_count; /* # of times error() has been called */ int unsuccess; /* # unsuccessful connection attempts */ @@ -266,14 +265,14 @@ typedef struct ppp_control_s { struct netif *ethif; struct pppoe_softc *pppoe_sc; #endif /* PPPOE_SUPPORT */ - int if_up; /* True when the interface is up. */ + int if_up; /* True when the interface is up. */ int err_code; /* Code indicating why interface is down. */ #if PPPOS_SUPPORT - sio_fd_t fd; /* File device ID of port. */ + sio_fd_t fd; /* File device ID of port. */ #endif /* PPPOS_SUPPORT */ - u16_t mtu; /* Peer's mru */ - int pcomp; /* Does peer accept protocol compression? */ - int accomp; /* Does peer accept addr/ctl compression? */ + u16_t mtu; /* Peer's mru */ + int pcomp; /* Does peer accept protocol compression? */ + int accomp; /* Does peer accept addr/ctl compression? */ u_long last_xmit; /* Time of last transmission. */ #if PPPOS_SUPPORT ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ @@ -357,8 +356,6 @@ int ppp_init(void) { int i; struct protent *protp; - debug = 1; - new_phase(PHASE_INITIALIZE); error_count = 0; unsuccess = 0; @@ -843,15 +840,15 @@ static void ppp_input(void *arg) { #endif /* UNUSED */ } - if (debug) { +#if PPP_DEBUG #if PPP_PROTOCOLNAME - const char *pname = protocol_name(protocol); - if (pname != NULL) - warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); - else + const char *pname = protocol_name(protocol); + if (pname != NULL) + warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); + else #endif /* PPP_PROTOCOLNAME */ - warn("Unsupported protocol 0x%x received", protocol); - } + warn("Unsupported protocol 0x%x received", protocol); +#endif /* PPP_DEBUG */ if (pbuf_header(nb, sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index fe07e4fb..1bdae379 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -760,9 +760,6 @@ dump_packet(const char *tag, unsigned char *p, int len) { int proto; - if (!debug) - return; - /* * don't print IPv4 and IPv6 packets. */ @@ -775,10 +772,9 @@ dump_packet(const char *tag, unsigned char *p, int len) #endif /* - * don't print LCP echo request/reply packets if debug <= 1 - * and the link is up. + * don't print LCP echo request/reply packets if the link is up. */ - if (debug <= 1 && unsuccess == 0 && proto == PPP_LCP + if (unsuccess == 0 && proto == PPP_LCP && len >= 2 + HEADERLEN) { unsigned char *lcp = p + 2; int l = (lcp[2] << 8) + lcp[3]; From 42f672d85db047a0b39ba5423695a78de4d79bed Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 15:39:16 +0200 Subject: [PATCH 136/320] phase global variable moved to ppp_control structure --- src/netif/ppp/auth.c | 34 +++---- src/netif/ppp/lcp.c | 5 +- src/netif/ppp/ppp.c | 198 +++++++++++++-------------------------- src/netif/ppp/ppp_impl.h | 65 ++++++++++++- 4 files changed, 151 insertions(+), 151 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 440fae0c..9209f0ca 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -578,7 +578,7 @@ void start_link(unit) char *msg; status = EXIT_NEGOTIATION_FAILED; - new_phase(PHASE_SERIALCONN); + new_phase(unit, PHASE_SERIALCONN); hungup = 0; devfd = the_channel->connect(); @@ -614,18 +614,18 @@ void start_link(unit) notice("Starting negotiation on %s", ppp_devnam); add_fd(fd_ppp); - new_phase(PHASE_ESTABLISH); + new_phase(unit, PHASE_ESTABLISH); lcp_lowerup(0); return; disconnect: - new_phase(PHASE_DISCONNECT); + new_phase(unit, PHASE_DISCONNECT); if (the_channel->disconnect) the_channel->disconnect(); fail: - new_phase(PHASE_DEAD); + new_phase(unit, PHASE_DEAD); if (the_channel->cleanup) (*the_channel->cleanup)(); } @@ -639,9 +639,10 @@ void link_terminated(unit) int unit; { - if (phase == PHASE_DEAD || phase == PHASE_MASTER) + ppp_control *pc = &ppp_control_list[unit]; + if (pc->phase == PHASE_DEAD || pc->phase == PHASE_MASTER) return; - new_phase(PHASE_DISCONNECT); + new_phase(unit, PHASE_DISCONNECT); #if 0 /* UNUSED */ if (pap_logout_hook) { @@ -660,7 +661,7 @@ link_terminated(unit) lcp_lowerdown(0); - new_phase(PHASE_DEAD); + new_phase(unit, PHASE_DEAD); ppp_link_terminated(unit); #if 0 /* @@ -702,11 +703,11 @@ link_terminated(unit) if (doing_multilink && multilink_master) { if (!bundle_terminating) - new_phase(PHASE_MASTER); + new_phase(unit, PHASE_MASTER); else mp_bundle_terminated(); } else - new_phase(PHASE_DEAD); + new_phase(unit, PHASE_DEAD); #endif } @@ -717,14 +718,15 @@ void link_down(unit) int unit; { + ppp_control *pc = &ppp_control_list[unit]; #if PPP_NOTIFY notify(link_down_notifier, 0); #endif /* #if PPP_NOTIFY */ if (!doing_multilink) { upper_layers_down(unit); - if (phase != PHASE_DEAD && phase != PHASE_MASTER) - new_phase(PHASE_ESTABLISH); + if (pc->phase != PHASE_DEAD && pc->phase != PHASE_MASTER) + new_phase(unit, PHASE_ESTABLISH); } /* XXX if doing_multilink, should do something to stop network-layer traffic on the link */ @@ -817,7 +819,7 @@ link_established(unit) } #endif /* UNUSED */ - new_phase(PHASE_AUTHENTICATE); + new_phase(unit, PHASE_AUTHENTICATE); auth = 0; #if PPP_SERVER #if EAP_SUPPORT @@ -909,7 +911,7 @@ network_phase(unit) * If we negotiated callback, do it now. */ if (go->neg_cbcp) { - new_phase(PHASE_CALLBACK); + new_phase(unit, PHASE_CALLBACK); (*cbcp_protent.open)(unit); return; } @@ -943,7 +945,7 @@ start_networks(unit) int mppe_required; #endif /* MPPE */ - new_phase(PHASE_NETWORK); + new_phase(unit, PHASE_NETWORK); #ifdef HAVE_MULTILINK if (multilink) { @@ -1212,7 +1214,7 @@ np_up(unit, proto) */ status = EXIT_OK; unsuccess = 0; - new_phase(PHASE_RUNNING); + new_phase(unit, PHASE_RUNNING); #if 0 /* UNUSED */ if (idle_time_hook != 0) @@ -1259,7 +1261,7 @@ np_down(unit, proto) #ifdef MAXOCTETS UNTIMEOUT(check_maxoctets, NULL); #endif - new_phase(PHASE_NETWORK); + new_phase(unit, PHASE_NETWORK); } } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 241b3999..c8dcbf43 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -462,11 +462,12 @@ lcp_close(unit, reason) int unit; char *reason; { + ppp_control *pc = &ppp_control_list[unit]; fsm *f = &lcp_fsm[unit]; int oldstate; - if (phase != PHASE_DEAD && phase != PHASE_MASTER) - new_phase(PHASE_TERMINATE); + if (pc->phase != PHASE_DEAD && pc->phase != PHASE_MASTER) + new_phase(unit, PHASE_TERMINATE); if (f->flags & DELAYED_UP) { UNTIMEOUT(lcp_delayed_up, f); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 1d5c501a..4ec39fc5 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -150,7 +150,6 @@ */ /* FIXME: global variables per PPP session */ /* FIXME: clean global variables */ -int phase; /* where the link is at */ int error_count; /* # of times error() has been called */ int unsuccess; /* # unsuccessful connection attempts */ int listen_time; /* time to listen first (ms) */ @@ -233,64 +232,6 @@ typedef enum { #endif #endif /* PPPOS_SUPPORT */ -typedef struct ppp_control_rx_s { - /** unit number / ppp descriptor */ - int pd; - /** the rx file descriptor */ - sio_fd_t fd; - /** receive buffer - encoded data is stored here */ -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD - u_char rxbuf[PPPOS_RX_BUFSIZE]; -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ - -#if PPPOS_SUPPORT - /* The input packet. */ - struct pbuf *in_head, *in_tail; - - u16_t in_protocol; /* The input protocol code. */ - u16_t in_fcs; /* Input Frame Check Sequence value. */ - ppp_dev_states in_state; /* The input process state. */ - char in_escaped; /* Escape next character. */ - ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ -#endif /* PPPOS_SUPPORT */ -} ppp_control_rx; - -/* - * PPP interface control block. - */ -typedef struct ppp_control_s { - ppp_control_rx rx; - char open_flag; /* True when in use. */ -#if PPPOE_SUPPORT - struct netif *ethif; - struct pppoe_softc *pppoe_sc; -#endif /* PPPOE_SUPPORT */ - int if_up; /* True when the interface is up. */ - int err_code; /* Code indicating why interface is down. */ -#if PPPOS_SUPPORT - sio_fd_t fd; /* File device ID of port. */ -#endif /* PPPOS_SUPPORT */ - u16_t mtu; /* Peer's mru */ - int pcomp; /* Does peer accept protocol compression? */ - int accomp; /* Does peer accept addr/ctl compression? */ - u_long last_xmit; /* Time of last transmission. */ -#if PPPOS_SUPPORT - ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ -#endif /* PPPOS_SUPPORT */ -#if PPPOS_SUPPORT && VJ_SUPPORT - int vj_enabled; /* Flag indicating VJ compression enabled. */ - struct vjcompress vj_comp; /* Van Jacobson compression header. */ -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - - struct netif netif; - - struct ppp_addrs addrs; - - void (*link_status_cb)(void *ctx, int err_code, void *arg); - void *link_status_ctx; - -} ppp_control; - /* Prototypes for procedures local to this file. */ /* FIXME: PPPoE close seem bogus, it was actually not exported at all in the previous port */ @@ -299,7 +240,7 @@ void ppp_over_ethernet_close(int pd); #endif /* UNUSED */ static void ppp_start(int pd); /** Initiate LCP open request */ -static void ppp_input(void *arg); +static void ppp_input(int unit, void *arg); #if PPPOS_SUPPORT static void ppp_receive_wakeup(int pd); @@ -329,7 +270,6 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n); /******************************/ /*** PUBLIC DATA STRUCTURES ***/ /******************************/ -static ppp_control ppp_control_list[NUM_PPP]; /* The PPP interface control blocks. */ /** Input helper struct, must be packed since it is stored to pbuf->payload, * which might be unaligned. @@ -356,7 +296,6 @@ int ppp_init(void) { int i; struct protent *protp; - new_phase(PHASE_INITIALIZE); error_count = 0; unsuccess = 0; listen_time = 0; @@ -365,12 +304,7 @@ int ppp_init(void) { link_stats_valid = 0; #endif /* PPP_STATS_SUPPORT */ - /* - openlog("LWIP-PPP", LOG_PID | LOG_NDELAY, LOG_DAEMON); - setlogmask(LOG_UPTO(LOG_DEBUG)); - syslog(LOG_DEBUG, "hello, this is gradator lwIP PPP!"); - */ - + /* FIXME: Remove that, do a user provided ppp_settings with a ppp_settings init function */ memset(&ppp_settings, 0, sizeof(ppp_settings)); ppp_settings.usepeerdns = 1; ppp_settings.persist = 1; @@ -509,52 +443,51 @@ int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void ppp_control *pc; int pd; - if (link_status_cb == NULL) { - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + if (link_status_cb == NULL) return PPPERR_PARAM; - } /* Find a free PPP session descriptor. */ for (pd = 0; pd < NUM_PPP && ppp_control_list[pd].open_flag != 0; pd++); + if (pd >= NUM_PPP) + return PPPERR_OPEN; - if (pd >= NUM_PPP) { - pd = PPPERR_OPEN; - } else { - pc = &ppp_control_list[pd]; - /* input pbuf left over from last session? */ - ppp_free_current_input_packet(&pc->rx); - /* @todo: is this correct or do I overwrite something? */ - memset(pc, 0, sizeof(ppp_control)); - pc->rx.pd = pd; - pc->rx.fd = fd; + pc = &ppp_control_list[pd]; + /* input pbuf left over from last session? */ + ppp_free_current_input_packet(&pc->rx); + /* @todo: is this correct or do I overwrite something? */ + memset(pc, 0, sizeof(ppp_control)); + pc->rx.pd = pd; + pc->rx.fd = fd; - pc->open_flag = 1; - pc->fd = fd; + pc->open_flag = 1; + pc->fd = fd; + + new_phase(pd, PHASE_INITIALIZE); #if VJ_SUPPORT - vj_compress_init(&pc->vj_comp); + vj_compress_init(&pc->vj_comp); #endif /* VJ_SUPPORT */ - /* - * Default the in and out accm so that escape and flag characters - * are always escaped. - */ - pc->rx.in_accm[15] = 0x60; /* no need to protect since RX is not running */ - pc->out_accm[15] = 0x60; + /* + * Default the in and out accm so that escape and flag characters + * are always escaped. + */ + pc->rx.in_accm[15] = 0x60; /* no need to protect since RX is not running */ + pc->out_accm[15] = 0x60; - pc->link_status_cb = link_status_cb; - pc->link_status_ctx = link_status_ctx; + pc->link_status_cb = link_status_cb; + pc->link_status_ctx = link_status_ctx; - /* - * Start the connection and handle incoming events (packet or timeout). - */ - PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pd)); - ppp_start(pd); + /* + * Start the connection and handle incoming events (packet or timeout). + */ + PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pd)); + ppp_start(pd); #if PPP_INPROC_OWNTHREAD - sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); + sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); #endif /* PPP_INPROC_OWNTHREAD */ - } return pd; } @@ -584,43 +517,42 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const LWIP_UNUSED_ARG(service_name); LWIP_UNUSED_ARG(concentrator_name); - if (link_status_cb == NULL) { - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + if (link_status_cb == NULL) return PPPERR_PARAM; - } /* Find a free PPP session descriptor. Critical region? */ for (pd = 0; pd < NUM_PPP && ppp_control_list[pd].open_flag != 0; pd++); - if (pd >= NUM_PPP) { + if (pd >= NUM_PPP) pd = PPPERR_OPEN; - } else { - pc = &ppp_control_list[pd]; - memset(pc, 0, sizeof(ppp_control)); - pc->open_flag = 1; - pc->ethif = ethif; - pc->link_status_cb = link_status_cb; - pc->link_status_ctx = link_status_ctx; + pc = &ppp_control_list[pd]; + memset(pc, 0, sizeof(ppp_control)); + pc->open_flag = 1; + pc->ethif = ethif; - lcp_wantoptions[pd].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_wantoptions[pd].neg_asyncmap = 0; - lcp_wantoptions[pd].neg_pcompression = 0; - lcp_wantoptions[pd].neg_accompression = 0; + new_phase(pd, PHASE_INITIALIZE); - lcp_allowoptions[pd].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_allowoptions[pd].neg_asyncmap = 0; - lcp_allowoptions[pd].neg_pcompression = 0; - lcp_allowoptions[pd].neg_accompression = 0; + pc->link_status_cb = link_status_cb; + pc->link_status_ctx = link_status_ctx; - if(pppoe_create(ethif, pd, ppp_over_ethernet_link_status_cb, &pc->pppoe_sc) != ERR_OK) { - pc->open_flag = 0; - return PPPERR_OPEN; - } + lcp_wantoptions[pd].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + lcp_wantoptions[pd].neg_asyncmap = 0; + lcp_wantoptions[pd].neg_pcompression = 0; + lcp_wantoptions[pd].neg_accompression = 0; - pppoe_connect(pc->pppoe_sc, ppp_settings.persist); + lcp_allowoptions[pd].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + lcp_allowoptions[pd].neg_asyncmap = 0; + lcp_allowoptions[pd].neg_pcompression = 0; + lcp_allowoptions[pd].neg_accompression = 0; + + if(pppoe_create(ethif, pd, ppp_over_ethernet_link_status_cb, &pc->pppoe_sc) != ERR_OK) { + pc->open_flag = 0; + return PPPERR_OPEN; } + pppoe_connect(pc->pppoe_sc, ppp_settings.persist); return pd; } @@ -717,7 +649,8 @@ ppp_hup(int pd) * this is totally stupid to make room for it and then modify the packet directly * or it is used in output ? have to find out... */ -static void ppp_input(void *arg) { +static void ppp_input(int unit, void *arg) { + ppp_control *pc = &ppp_control_list[unit]; struct pbuf *nb = (struct pbuf *)arg; u16_t protocol; int pd; @@ -748,7 +681,7 @@ static void ppp_input(void *arg) { * Until we get past the authentication phase, toss all packets * except LCP, LQR and authentication packets. */ - if (phase <= PHASE_AUTHENTICATE + if (pc->phase <= PHASE_AUTHENTICATE && !(protocol == PPP_LCP #if LQR_SUPPORT || protocol == PPP_LQR @@ -764,7 +697,7 @@ static void ppp_input(void *arg) { #endif /* EAP_SUPPORT */ )) { dbglog("discarding proto 0x%x in phase %d", - protocol, phase); + protocol, pc->phase); goto drop; } @@ -1068,7 +1001,7 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb) { pih->proto = in_protocol; /* pih->proto is now in host byte order */ /* Dispatch the packet thereby consuming it. */ - ppp_input(pb); + ppp_input(pd, pb); return; drop: @@ -1214,7 +1147,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i } /* Check that the link is up. */ - if (phase == PHASE_DEAD) { + if (pc->phase == PHASE_DEAD) { PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pd)); LINK_STATS_INC(link.rterr); LINK_STATS_INC(link.drop); @@ -1962,8 +1895,9 @@ ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback) /* * new_phase - signal the start of a new phase of pppd's operation. */ -void new_phase(int p) { - phase = p; +void new_phase(int unit, int p) { + ppp_control *pc = &ppp_control_list[unit]; + pc->phase = p; #if PPP_NOTIFY /* The one willing notify support should add here the code to be notified of phase changes */ #endif /* PPP_NOTIFY */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 6b19cd0a..dc0ddef2 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -448,6 +448,69 @@ struct ppp_settings { struct ppp_settings ppp_settings; +/* + * PPP interface RX control block. + */ +typedef struct ppp_control_rx_s { + /** unit number / ppp descriptor */ + int pd; + /** the rx file descriptor */ + sio_fd_t fd; + /** receive buffer - encoded data is stored here */ +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD + u_char rxbuf[PPPOS_RX_BUFSIZE]; +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ + +#if PPPOS_SUPPORT + /* The input packet. */ + struct pbuf *in_head, *in_tail; + + u16_t in_protocol; /* The input protocol code. */ + u16_t in_fcs; /* Input Frame Check Sequence value. */ + ppp_dev_states in_state; /* The input process state. */ + char in_escaped; /* Escape next character. */ + ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ +#endif /* PPPOS_SUPPORT */ +} ppp_control_rx; + +/* + * PPP interface control block. + */ +typedef struct ppp_control_s { + ppp_control_rx rx; + char open_flag; /* True when in use. */ + u8_t phase; /* where the link is at */ +#if PPPOE_SUPPORT + struct netif *ethif; + struct pppoe_softc *pppoe_sc; +#endif /* PPPOE_SUPPORT */ + int if_up; /* True when the interface is up. */ + int err_code; /* Code indicating why interface is down. */ +#if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ +#endif /* PPPOS_SUPPORT */ + u16_t mtu; /* Peer's mru */ + int pcomp; /* Does peer accept protocol compression? */ + int accomp; /* Does peer accept addr/ctl compression? */ + u_long last_xmit; /* Time of last transmission. */ +#if PPPOS_SUPPORT + ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ +#endif /* PPPOS_SUPPORT */ +#if PPPOS_SUPPORT && VJ_SUPPORT + int vj_enabled; /* Flag indicating VJ compression enabled. */ + struct vjcompress vj_comp; /* Van Jacobson compression header. */ +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + struct netif netif; + + struct ppp_addrs addrs; + + void (*link_status_cb)(void *ctx, int err_code, void *arg); + void *link_status_ctx; + +} ppp_control; + +ppp_control ppp_control_list[NUM_PPP]; /* The PPP interface control blocks. */ /* PPP flow functions */ @@ -471,7 +534,7 @@ struct pbuf * ppp_singlebuf(struct pbuf *p); /* Functions called by various PPP subsystems to configure * the PPP interface or change the PPP phase. */ -void new_phase(int p); +void new_phase(int unit, int p); #if PPPOS_SUPPORT void ppp_set_xaccm(int unit, ext_accm *accm); From 772cac794605c6c4955f70fd9db6e9e4a6c73e09 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 15:42:57 +0200 Subject: [PATCH 137/320] removed useless error_count global variable --- src/netif/ppp/ppp_impl.h | 6 +----- src/netif/ppp/utils.c | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index dc0ddef2..fe160150 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -266,18 +266,14 @@ extern bool explicit_remote;/* remote_name specified with remotename opt */ /* FIXME: make it a compile time option */ extern int idle_time_limit;/* Shut down link if idle for this long */ -extern int phase; /* Current state of link - see values below */ -extern int error_count; /* # of times error() has been called */ extern int unsuccess; /* # unsuccessful connection attempts */ extern int listen_time; /* time to listen first (ms) */ extern int status; /* exit status for pppd */ extern int need_holdoff; /* Need holdoff period after link terminates */ extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ -/* FIXME: add more HAVE_MULTILINK */ -extern bool multilink; /* enable multilink operation */ - #ifdef HAVE_MULTILINK +extern bool multilink; /* enable multilink operation */ extern bool doing_multilink; extern bool multilink_master; extern bool bundle_eof; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 1bdae379..bc49d886 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -695,7 +695,9 @@ error (char *fmt, ...) va_start(pvar, fmt); logit(LOG_ERR, fmt, pvar); va_end(pvar); +#if 0 /* UNUSED */ ++error_count; +#endif /* UNUSED */ } /* From 2da930ba4cc4cf97bfce08c084156b22de7ece03 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 15:45:52 +0200 Subject: [PATCH 138/320] removed some useless extern --- src/netif/ppp/ppp_impl.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index fe160150..59971801 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -255,17 +255,9 @@ struct epdisc { /* * Global variables. */ -/* FIXME: improve debug flag */ -extern int debug; /* Debug flag */ - -/* FIXME: is our_name really necessary ? */ -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 */ -/* FIXME: make it a compile time option */ -extern int idle_time_limit;/* Shut down link if idle for this long */ - extern int unsuccess; /* # unsuccessful connection attempts */ extern int listen_time; /* time to listen first (ms) */ extern int status; /* exit status for pppd */ @@ -430,6 +422,7 @@ struct ppp_settings { u_int usepeerdns : 1; /* Ask peer for DNS adds */ u_int persist : 1; /* Persist mode, always try to reopen the connection */ + /* FIXME: make it a compile time option */ u_short idle_time_limit; /* Disconnect if idle for this many seconds */ int maxconnect; /* Maximum connect time (seconds) */ From 6b8c78bacce7894943353808038c52042d4b4715 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 15:55:01 +0200 Subject: [PATCH 139/320] moved remote_name and explicit_remote global variable to ppp_settings --- src/netif/ppp/auth.c | 6 ------ src/netif/ppp/chap-new.c | 4 ++-- src/netif/ppp/eap.c | 6 +++--- src/netif/ppp/ppp_impl.h | 7 ++----- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 9209f0ca..7273859a 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -238,19 +238,13 @@ bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #endif /* MSCHAP_SUPPORT */ -#endif /* MOVED TO ppp_settings */ -#if 0 /* UNUSED */ 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 */ -#endif /* UNUSED */ bool explicit_remote = 0; /* User specified explicit remote name */ -#if 0 /* UNUSED */ bool explicit_user = 0; /* Set if "user" option supplied */ bool explicit_passwd = 0; /* Set if "password" option supplied */ -#endif /* UNUSED */ char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -#if 0 /* UNUSED */ static char *uafname; /* name of most recent +ua file */ extern char *crypt (const char *, const char *); diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 05cf6943..d9ecd1e0 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -492,8 +492,8 @@ chap_respond(struct chap_client_state *cs, int id, slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); /* Microsoft doesn't send their name back in the PPP packet */ - if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) - strlcpy(rname, remote_name, sizeof(rname)); + if (ppp_settings.explicit_remote || (ppp_settings.remote_name[0] != 0 && rname[0] == 0)) + strlcpy(rname, ppp_settings.remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 9c2337ea..af50d789 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -1451,9 +1451,9 @@ int len; } /* In case the remote doesn't give us his name. */ - if (explicit_remote || - (remote_name[0] != '\0' && vallen == len)) - strlcpy(rhostname, remote_name, sizeof (rhostname)); + if (ppp_settings.explicit_remote || + (ppp_settings.remote_name[0] != '\0' && vallen == len)) + strlcpy(rhostname, ppp_settings.remote_name, sizeof (rhostname)); /* * Get the secret for authenticating ourselves with diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 59971801..f2711e3e 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -255,9 +255,6 @@ struct epdisc { /* * Global variables. */ -extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -extern bool explicit_remote;/* remote_name specified with remotename opt */ - extern int unsuccess; /* # unsuccessful connection attempts */ extern int listen_time; /* time to listen first (ms) */ extern int status; /* exit status for pppd */ @@ -431,8 +428,8 @@ struct ppp_settings { #if PPP_SERVER char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ #endif /* PPP_SERVER */ - /* FIXME: re-enable that */ - /* char remote_name[MAXNAMELEN + 1]; */ /* Peer's name for authentication */ + /* FIXME: make it a compile time option */ + char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ }; struct ppp_settings ppp_settings; From a7d7158b05a692a86a3b45fe3b07c3aa291a7b11 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 15:58:51 +0200 Subject: [PATCH 140/320] removed useless error_count global variable from ppp.c --- src/netif/ppp/ppp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 4ec39fc5..bb7a28f0 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -150,7 +150,6 @@ */ /* FIXME: global variables per PPP session */ /* FIXME: clean global variables */ -int error_count; /* # of times error() has been called */ int unsuccess; /* # unsuccessful connection attempts */ int listen_time; /* time to listen first (ms) */ int status; /* exit status for pppd */ @@ -296,7 +295,6 @@ int ppp_init(void) { int i; struct protent *protp; - error_count = 0; unsuccess = 0; listen_time = 0; status = EXIT_OK; From ce5121e659ab397ed7b6c37f32b5f2fd929b1b04 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 16:00:22 +0200 Subject: [PATCH 141/320] removed unused "unsuccess" global variable --- src/netif/ppp/auth.c | 1 - src/netif/ppp/ppp.c | 2 -- src/netif/ppp/ppp_impl.h | 1 - src/netif/ppp/utils.c | 3 +-- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 7273859a..cfd23b19 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1207,7 +1207,6 @@ np_up(unit, proto) * At this point we consider that the link has come up successfully. */ status = EXIT_OK; - unsuccess = 0; new_phase(unit, PHASE_RUNNING); #if 0 /* UNUSED */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index bb7a28f0..65ae4eb7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -150,7 +150,6 @@ */ /* FIXME: global variables per PPP session */ /* FIXME: clean global variables */ -int unsuccess; /* # unsuccessful connection attempts */ int listen_time; /* time to listen first (ms) */ int status; /* exit status for pppd */ @@ -295,7 +294,6 @@ int ppp_init(void) { int i; struct protent *protp; - unsuccess = 0; listen_time = 0; status = EXIT_OK; #if PPP_STATS_SUPPORT diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index f2711e3e..0cfab303 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -255,7 +255,6 @@ struct epdisc { /* * Global variables. */ -extern int unsuccess; /* # unsuccessful connection attempts */ extern int listen_time; /* time to listen first (ms) */ extern int status; /* exit status for pppd */ extern int need_holdoff; /* Need holdoff period after link terminates */ diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index bc49d886..c0eee4be 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -776,8 +776,7 @@ dump_packet(const char *tag, unsigned char *p, int len) /* * don't print LCP echo request/reply packets if the link is up. */ - if (unsuccess == 0 && proto == PPP_LCP - && len >= 2 + HEADERLEN) { + if (proto == PPP_LCP && len >= 2 + HEADERLEN) { unsigned char *lcp = p + 2; int l = (lcp[2] << 8) + lcp[3]; From 7a57d28db4f92cc51c05d1e968d11147c2e6a17b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 16:18:01 +0200 Subject: [PATCH 142/320] moved listen_time global variable to ppp_settings --- src/netif/ppp/lcp.c | 4 ++-- src/netif/ppp/ppp.c | 2 -- src/netif/ppp/ppp_impl.h | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index c8dcbf43..bbd5a41f 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -526,9 +526,9 @@ lcp_lowerup(unit) xmit_accm[unit][0])); #endif /* PPPOS_SUPPORT */ - if (listen_time != 0) { + if (ppp_settings.listen_time != 0) { f->flags |= DELAYED_UP; - TIMEOUTMS(lcp_delayed_up, f, listen_time); + TIMEOUTMS(lcp_delayed_up, f, ppp_settings.listen_time); } else fsm_lowerup(f); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 65ae4eb7..e271bc99 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -150,7 +150,6 @@ */ /* FIXME: global variables per PPP session */ /* FIXME: clean global variables */ -int listen_time; /* time to listen first (ms) */ int status; /* exit status for pppd */ /* FIXME: outpacket_buf per PPP session */ @@ -294,7 +293,6 @@ int ppp_init(void) { int i; struct protent *protp; - listen_time = 0; status = EXIT_OK; #if PPP_STATS_SUPPORT link_stats_valid = 0; diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 0cfab303..3a2901ec 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -255,9 +255,7 @@ struct epdisc { /* * Global variables. */ -extern int listen_time; /* time to listen first (ms) */ extern int status; /* exit status for pppd */ -extern int need_holdoff; /* Need holdoff period after link terminates */ extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ #ifdef HAVE_MULTILINK @@ -418,8 +416,10 @@ struct ppp_settings { u_int usepeerdns : 1; /* Ask peer for DNS adds */ u_int persist : 1; /* Persist mode, always try to reopen the connection */ + u16_t listen_time; /* time to listen first (ms) */ + /* FIXME: make it a compile time option */ - u_short idle_time_limit; /* Disconnect if idle for this many seconds */ + u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ int maxconnect; /* Maximum connect time (seconds) */ char user [MAXNAMELEN + 1]; /* Username for PAP */ From f94ed922e5b0b00c0bb148f07191c809c2b983af Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 16:43:12 +0200 Subject: [PATCH 143/320] moved exit status global variable to ppp_control --- src/netif/ppp/auth.c | 14 ++++++++++---- src/netif/ppp/lcp.c | 6 ++++-- src/netif/ppp/ppp.c | 13 +++---------- src/netif/ppp/ppp_impl.h | 1 + 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index cfd23b19..41844e3d 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1113,6 +1113,7 @@ void auth_withpeer_fail(unit, protocol) int unit, protocol; { + ppp_control *pc = &ppp_control_list[unit]; int errcode = PPPERR_AUTHFAIL; /* * We've failed to authenticate ourselves to our peer. @@ -1120,7 +1121,7 @@ auth_withpeer_fail(unit, protocol) * is no point in persisting without any way to get updated * authentication secrets. */ - status = EXIT_AUTH_TOPEER_FAILED; + pc->status = EXIT_AUTH_TOPEER_FAILED; /* * We've failed to authenticate ourselves to our peer. @@ -1201,12 +1202,13 @@ np_up(unit, proto) int unit, proto; { int tlim; + ppp_control *pc = &ppp_control_list[unit]; if (num_np_up == 0) { /* * At this point we consider that the link has come up successfully. */ - status = EXIT_OK; + pc->status = EXIT_OK; new_phase(unit, PHASE_RUNNING); #if 0 /* UNUSED */ @@ -1319,6 +1321,8 @@ static void check_idle(arg) void *arg; { + /* FIXME: fix forced unit 0 */ + ppp_control *pc = &ppp_control_list[0]; struct ppp_idle idle; time_t itime; int tlim; @@ -1338,7 +1342,7 @@ check_idle(arg) if (tlim <= 0) { /* link is idle: shut it down. */ notice("Terminating connection due to lack of activity."); - status = EXIT_IDLE_TIMEOUT; + pc->status = EXIT_IDLE_TIMEOUT; lcp_close(0, "Link inactive"); #if 0 /* UNUSED */ need_holdoff = 0; @@ -1355,8 +1359,10 @@ static void connect_time_expired(arg) void *arg; { + /* FIXME: fix forced unit 0 */ + ppp_control *pc = &ppp_control_list[0]; info("Connect time expired"); - status = EXIT_CONNECT_TIME; + pc->status = EXIT_CONNECT_TIME; lcp_close(0, "Connect time expired"); /* Close connection */ } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index bbd5a41f..38b3829c 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1129,6 +1129,7 @@ lcp_nakci(f, p, len, treat_as_reject) int len; int treat_as_reject; { + ppp_control *pc = &ppp_control_list[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *wo = &lcp_wantoptions[f->unit]; u_char citype, cichar, *next; @@ -1555,7 +1556,7 @@ lcp_nakci(f, p, len, treat_as_reject) if (looped_back) { if (++try.numloops >= lcp_loopbackfail) { notice("Serial line is looped back."); - status = EXIT_LOOPBACK; + pc->status = EXIT_LOOPBACK; lcp_close(f->unit, "Loopback detected"); } } else @@ -2631,10 +2632,11 @@ static void LcpLinkFailure (f) fsm *f; { + ppp_control *pc = &ppp_control_list[f->unit]; if (f->state == OPENED) { info("No response to %d echo-requests", lcp_echos_pending); notice("Serial link appears to be disconnected."); - status = EXIT_PEER_DEAD; + pc->status = EXIT_PEER_DEAD; lcp_close(f->unit, "Peer not responding"); } } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index e271bc99..cb15c5ee 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -145,19 +145,11 @@ #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1" #endif -/* - * Global variables. - */ -/* FIXME: global variables per PPP session */ -/* FIXME: clean global variables */ -int status; /* exit status for pppd */ - -/* FIXME: outpacket_buf per PPP session */ - /* * Buffers for outgoing packets. This must be accessed only from the appropriate * PPP task so that it doesn't need to be protected to avoid collisions. */ +/* FIXME: outpacket_buf per PPP session */ u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ #if PPPOS_SUPPORT @@ -293,7 +285,6 @@ int ppp_init(void) { int i; struct protent *protp; - status = EXIT_OK; #if PPP_STATS_SUPPORT link_stats_valid = 0; #endif /* PPP_STATS_SUPPORT */ @@ -457,6 +448,7 @@ int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void pc->open_flag = 1; pc->fd = fd; + pc->status = EXIT_OK; new_phase(pd, PHASE_INITIALIZE); @@ -525,6 +517,7 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const memset(pc, 0, sizeof(ppp_control)); pc->open_flag = 1; pc->ethif = ethif; + pc->status = EXIT_OK; new_phase(pd, PHASE_INITIALIZE); diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 3a2901ec..1ade48c4 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -465,6 +465,7 @@ typedef struct ppp_control_s { ppp_control_rx rx; char open_flag; /* True when in use. */ u8_t phase; /* where the link is at */ + u8_t status; /* exit status */ #if PPPOE_SUPPORT struct netif *ethif; struct pppoe_softc *pppoe_sc; From c2d2034ae8faf3a5d96df98d86ee7c1090579808 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 16:56:32 +0200 Subject: [PATCH 144/320] PPPoE persist is working, removing FIXME comments about that --- src/netif/ppp/ppp.c | 10 +--------- src/netif/ppp/ppp_impl.h | 1 - 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index cb15c5ee..4ab02f2e 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1803,17 +1803,9 @@ static void ppp_over_ethernet_link_status_cb(int pd, int state) { void ppp_link_down(int pd) { PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pd)); -#if PPPOE_SUPPORT - if (ppp_control_list[pd].ethif) { -/* FIXME: find a way to set PPPoE down without disconnecting and freeing PPPoE structures */ -/* pppoe_disconnect(ppp_control_list[pd].pppoe_sc); */ - } else -#endif /* PPPOE_SUPPORT */ - { #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD - ppp_receive_wakeup(pd); + ppp_receive_wakeup(pd); #endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ - } } void ppp_link_terminated(int pd) { diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 1ade48c4..2ecbd500 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -255,7 +255,6 @@ struct epdisc { /* * Global variables. */ -extern int status; /* exit status for pppd */ extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ #ifdef HAVE_MULTILINK From 1cceb4e0ad967f185a5e3ed203ed9bb86e4c1199 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 17:05:19 +0200 Subject: [PATCH 145/320] moved hide_password global variable to ppp_options --- src/netif/ppp/ppp.c | 3 --- src/netif/ppp/ppp_impl.h | 3 +++ src/netif/ppp/upap.c | 7 +------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 4ab02f2e..06d4ce93 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -662,8 +662,6 @@ static void ppp_input(int unit, void *arg) { goto drop; } - /* FIXME: add a phase per connection */ - /* * Until we get past the authentication phase, toss all packets * except LCP, LQR and authentication packets. @@ -2146,7 +2144,6 @@ int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace LWIP_UNUSED_ARG(ouraddr); LWIP_UNUSED_ARG(gateway); - /* FIXME: handle replace condition */ LWIP_UNUSED_ARG(replace); if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 2ecbd500..b6247c0b 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -414,6 +414,9 @@ struct ppp_settings { u_int usehostname : 1; /* Use hostname for our_name */ u_int usepeerdns : 1; /* Ask peer for DNS adds */ u_int persist : 1; /* Persist mode, always try to reopen the connection */ +#if PRINTPKT_SUPPORT + u_int hide_password : 1; /* Hide password in dumped packets */ +#endif /* PRINTPKT_SUPPORT */ u16_t listen_time; /* time to listen first (ms) */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 2e49854d..61a46eb7 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -56,11 +56,6 @@ #include "upap.h" -/* FIXME: move that to ppp_options */ -#if PRINTPKT_SUPPORT -static bool hide_password = 1; -#endif /* PRINTPKT_SUPPORT */ - #if PPP_OPTIONS /* * Command-line options. @@ -693,7 +688,7 @@ upap_printpkt(p, plen, printer, arg) printer(arg, " user="); print_string(user, ulen, printer, arg); printer(arg, " password="); - if (!hide_password) + if (!ppp_settings.hide_password) print_string(pwd, wlen, printer, arg); else printer(arg, ""); From 8bd508a73de07e61c7ca3953c2429d1abb285f71 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 18:06:55 +0200 Subject: [PATCH 146/320] moved ppp_settings to ppp_control, improved PPP API to really allow multiple PPP sessions --- src/netif/ppp/auth.c | 39 +++++----- src/netif/ppp/chap-new.c | 5 +- src/netif/ppp/eap.c | 7 +- src/netif/ppp/ipcp.c | 8 ++- src/netif/ppp/lcp.c | 6 +- src/netif/ppp/ppp.c | 151 +++++++++++++++++++-------------------- src/netif/ppp/ppp.h | 49 ++++++++++++- src/netif/ppp/ppp_impl.h | 46 +----------- src/netif/ppp/upap.c | 3 +- 9 files changed, 159 insertions(+), 155 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 41844e3d..b0183508 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -763,6 +763,7 @@ link_established(unit) lcp_options *ho = &lcp_hisoptions[unit]; int i; struct protent *protp; + ppp_control *pc = &ppp_control_list[unit]; /* * Tell higher-level protocols that LCP is up. @@ -818,13 +819,13 @@ link_established(unit) #if PPP_SERVER #if EAP_SUPPORT if (go->neg_eap) { - eap_authpeer(unit, ppp_settings.our_name); + eap_authpeer(unit, pc->settings.our_name); auth |= EAP_PEER; } else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (go->neg_chap) { - chap_auth_peer(unit, ppp_settings.our_name, CHAP_DIGEST(go->chap_mdtype)); + chap_auth_peer(unit, pc->settings.our_name, CHAP_DIGEST(go->chap_mdtype)); auth |= CHAP_PEER; } else #endif /* CHAP_SUPPORT */ @@ -839,19 +840,19 @@ link_established(unit) #if EAP_SUPPORT if (ho->neg_eap) { - eap_authwithpeer(unit, ppp_settings.user); + eap_authwithpeer(unit, pc->settings.user); auth |= EAP_WITHPEER; } else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (ho->neg_chap) { - chap_auth_with_peer(unit, ppp_settings.user, CHAP_DIGEST(ho->chap_mdtype)); + chap_auth_with_peer(unit, pc->settings.user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if (ho->neg_upap) { - upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); + upap_authwithpeer(unit, pc->settings.user, pc->settings.passwd); auth |= PAP_WITHPEER; } else #endif /* PAP_SUPPORT */ @@ -1216,7 +1217,7 @@ np_up(unit, proto) tlim = (*idle_time_hook)(NULL); else #endif /* UNUSED */ - tlim = ppp_settings.idle_time_limit; + tlim = pc->settings.idle_time_limit; if (tlim > 0) TIMEOUT(check_idle, NULL, tlim); @@ -1224,8 +1225,8 @@ np_up(unit, proto) * Set a timeout to close the connection once the maximum * connect time has expired. */ - if (ppp_settings.maxconnect > 0) - TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect); + if (pc->settings.maxconnect > 0) + TIMEOUT(connect_time_expired, 0, pc->settings.maxconnect); #ifdef MAXOCTETS if (maxoctets > 0) @@ -1335,7 +1336,7 @@ check_idle(arg) } else { #endif /* UNUSED */ itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); - tlim = ppp_settings.idle_time_limit - itime; + tlim = pc->settings.idle_time_limit - itime; #if 0 /* UNUSED */ } #endif /* UNUSED */ @@ -1516,25 +1517,26 @@ auth_reset(unit) { lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; + ppp_control *pc = &ppp_control_list[unit]; - if( ppp_settings.passwd[0] ) { + if( pc->settings.passwd[0] ) { #if PAP_SUPPORT - ao->neg_upap = !ppp_settings.refuse_pap; + ao->neg_upap = !pc->settings.refuse_pap; #endif /* PAP_SUPPORT */ #if EAP_SUPPORT - ao->neg_eap = !ppp_settings.refuse_eap; + ao->neg_eap = !pc->settings.refuse_eap; #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT ao->chap_mdtype = MDTYPE_NONE; - if(!ppp_settings.refuse_chap) + if(!pc->settings.refuse_chap) ao->chap_mdtype |= MDTYPE_MD5; #if MSCHAP_SUPPORT - if(!ppp_settings.refuse_mschap) + if(!pc->settings.refuse_mschap) ao->chap_mdtype |= MDTYPE_MICROSOFT; - if(!ppp_settings.refuse_mschap_v2) + if(!pc->settings.refuse_mschap_v2) ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; #endif /* MSCHAP_SUPPORT */ @@ -1988,22 +1990,23 @@ get_secret(unit, client, server, secret, secret_len, am_server) int am_server; { int len; + ppp_control *pc = &ppp_control_list[unit]; LWIP_UNUSED_ARG(unit); LWIP_UNUSED_ARG(server); LWIP_UNUSED_ARG(am_server); - if(!client || !client[0] || strcmp(client, ppp_settings.user)) { + if(!client || !client[0] || strcmp(client, pc->settings.user)) { return 0; } - len = (int)strlen(ppp_settings.passwd); + len = (int)strlen(pc->settings.passwd); if (len > MAXSECRETLEN) { error("Secret for %s on %s is too long", client, server); len = MAXSECRETLEN; } - MEMCPY(secret, ppp_settings.passwd, len); + MEMCPY(secret, pc->settings.passwd, len); *secret_len = len; return 1; diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index d9ecd1e0..0251d0ff 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -480,6 +480,7 @@ chap_respond(struct chap_client_state *cs, int id, unsigned char response[RESP_MAX_PKTLEN]; char rname[MAXNAMELEN+1]; char secret[MAXSECRETLEN+1]; + ppp_control *pc = &ppp_control_list[0]; if ((cs->flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) return; /* not ready */ @@ -492,8 +493,8 @@ chap_respond(struct chap_client_state *cs, int id, slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); /* Microsoft doesn't send their name back in the PPP packet */ - if (ppp_settings.explicit_remote || (ppp_settings.remote_name[0] != 0 && rname[0] == 0)) - strlcpy(rname, ppp_settings.remote_name, sizeof(rname)); + if (pc->settings.explicit_remote || (pc->settings.remote_name[0] != 0 && rname[0] == 0)) + strlcpy(rname, pc->settings.remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index af50d789..5f6f0001 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -1333,6 +1333,7 @@ u_char *inp; int id; int len; { + ppp_control *pc = &ppp_control_list[esp->es_unit]; u_char typenum; u_char vallen; int secret_len; @@ -1451,9 +1452,9 @@ int len; } /* In case the remote doesn't give us his name. */ - if (ppp_settings.explicit_remote || - (ppp_settings.remote_name[0] != '\0' && vallen == len)) - strlcpy(rhostname, ppp_settings.remote_name, sizeof (rhostname)); + if (pc->settings.explicit_remote || + (pc->settings.remote_name[0] != '\0' && vallen == len)) + strlcpy(rhostname, pc->settings.remote_name, sizeof (rhostname)); /* * Get the secret for authenticating ourselves with diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index bb7eaf58..1ab2d95f 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -721,6 +721,7 @@ static void ipcp_resetci(f) fsm *f; { + ppp_control *pc = &ppp_control_list[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *ao = &ipcp_allowoptions[f->unit]; @@ -731,8 +732,8 @@ ipcp_resetci(f) wo->accept_local = 1; if (wo->hisaddr == 0) wo->accept_remote = 1; - wo->req_dns1 = ppp_settings.usepeerdns; /* Request DNS addresses from the peer */ - wo->req_dns2 = ppp_settings.usepeerdns; + wo->req_dns1 = pc->settings.usepeerdns; /* Request DNS addresses from the peer */ + wo->req_dns2 = pc->settings.usepeerdns; *go = *wo; if (!ask_for_local) go->ouraddr = 0; @@ -1800,6 +1801,7 @@ ipcp_up(f) fsm *f; { u_int32_t mask; + ppp_control *pc = &ppp_control_list[f->unit]; ipcp_options *ho = &ipcp_hisoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; @@ -1844,7 +1846,7 @@ ipcp_up(f) if (go->dnsaddr[1]) script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); #endif /* UNUSED */ - if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + if (pc->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { sdns(f->unit, go->dnsaddr[0], go->dnsaddr[1]); #if 0 /* UNUSED */ script_setenv("USEPEERDNS", "1", 0); diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 38b3829c..8a38f119 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -499,7 +499,7 @@ lcp_lowerup(unit) { lcp_options *wo = &lcp_wantoptions[unit]; fsm *f = &lcp_fsm[unit]; - + ppp_control *pc = &ppp_control_list[unit]; /* * Don't use A/C or protocol compression on transmission, * but accept A/C and protocol compressed packets @@ -526,9 +526,9 @@ lcp_lowerup(unit) xmit_accm[unit][0])); #endif /* PPPOS_SUPPORT */ - if (ppp_settings.listen_time != 0) { + if (pc->settings.listen_time != 0) { f->flags |= DELAYED_UP; - TIMEOUTMS(lcp_delayed_up, f, ppp_settings.listen_time); + TIMEOUTMS(lcp_delayed_up, f, pc->settings.listen_time); } else fsm_lowerup(f); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 06d4ce93..ea32cf62 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -282,18 +282,6 @@ PACK_STRUCT_END /* Initialize the PPP subsystem. */ int ppp_init(void) { - int i; - struct protent *protp; - -#if PPP_STATS_SUPPORT - link_stats_valid = 0; -#endif /* PPP_STATS_SUPPORT */ - - /* FIXME: Remove that, do a user provided ppp_settings with a ppp_settings init function */ - memset(&ppp_settings, 0, sizeof(ppp_settings)); - ppp_settings.usepeerdns = 1; - ppp_settings.persist = 1; - ppp_set_auth(PPPAUTHTYPE_NONE, NULL, NULL); /* * Initialize magic number generator now so that protocols may @@ -301,51 +289,82 @@ int ppp_init(void) { */ magic_init(); + return 0; +} + +/* Create a new PPP session. */ +int ppp_new(void) { + int i, pd; + ppp_control *pc; + struct protent *protp; + + /* Find a free PPP session descriptor. */ + for (pd = 0; pd < NUM_PPP && ppp_control_list[pd].open_flag != 0; pd++); + if (pd >= NUM_PPP) + return PPPERR_OPEN; + + pc = &ppp_control_list[pd]; + +#if PPP_STATS_SUPPORT + link_stats_valid = 0; +#endif /* PPP_STATS_SUPPORT */ + + memset(pc, 0, sizeof(ppp_control)); + pc->open_flag = 1; + pc->status = EXIT_OK; + new_phase(pd, PHASE_INITIALIZE); + + /* memset(&pc->settings, 0, sizeof(ppp_settings)); -- already done previously */ + pc->settings.usepeerdns = 1; + pc->settings.persist = 1; + /* * Initialize each protocol. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) - (*protp->init)(0); + (*protp->init)(pd); - return 0; + return pd; } -void ppp_set_auth(enum ppp_auth_type authtype, const char *user, const char *passwd) { +void ppp_set_auth(int unit, enum ppp_auth_type authtype, const char *user, const char *passwd) { + ppp_control *pc = &ppp_control_list[unit]; + /* FIXME: the following may look stupid, but this is just an easy way * to check different auth by changing compile time option */ #if PAP_SUPPORT - ppp_settings.refuse_pap = 0; + pc->settings.refuse_pap = 0; #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT #if PAP_SUPPORT - ppp_settings.refuse_pap = 1; + pc->settings.refuse_pap = 1; #endif /* PAP_SUPPORT */ - ppp_settings.refuse_chap = 0; + pc->settings.refuse_chap = 0; #endif /* CHAP_SUPPORT */ #if MSCHAP_SUPPORT #if PAP_SUPPORT - ppp_settings.refuse_pap = 1; + pc->settings.refuse_pap = 1; #endif /* PAP_SUPPORT */ - ppp_settings.refuse_chap = 1; - ppp_settings.refuse_mschap = 1; - ppp_settings.refuse_mschap_v2 = 0; + pc->settings.refuse_chap = 1; + pc->settings.refuse_mschap = 1; + pc->settings.refuse_mschap_v2 = 0; #endif /* MSCHAP_SUPPORT */ #if EAP_SUPPORT #if PAP_SUPPORT - ppp_settings.refuse_pap = 1; + pc->settings.refuse_pap = 1; #endif/* PAP_SUPPORT */ #if CHAP_SUPPORT - ppp_settings.refuse_chap = 1; + pc->settings.refuse_chap = 1; #if MSCHAP_SUPPORT - ppp_settings.refuse_mschap = 1; - ppp_settings.refuse_mschap_v2 = 1; + pc->settings.refuse_mschap = 1; + pc->settings.refuse_mschap_v2 = 1; #endif /* MSCHAP_SUPPORT */ #endif /* CHAP_SUPPORT */ - ppp_settings.refuse_eap = 0; + pc->settings.refuse_eap = 0; #endif /* EAP_SUPPORT */ /* FIXME: re-enable that */ @@ -399,17 +418,17 @@ void ppp_set_auth(enum ppp_auth_type authtype, const char *user, const char *pas #endif if(user) { - strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); - ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0'; + strncpy(pc->settings.user, user, sizeof(pc->settings.user)-1); + pc->settings.user[sizeof(pc->settings.user)-1] = '\0'; } else { - ppp_settings.user[0] = '\0'; + pc->settings.user[0] = '\0'; } if(passwd) { - strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1); - ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0'; + strncpy(pc->settings.passwd, passwd, sizeof(pc->settings.passwd)-1); + pc->settings.passwd[sizeof(pc->settings.passwd)-1] = '\0'; } else { - ppp_settings.passwd[0] = '\0'; + pc->settings.passwd[0] = '\0'; } } @@ -424,33 +443,21 @@ void ppp_set_auth(enum ppp_auth_type authtype, const char *user, const char *pas * * pppOpen() is directly defined to this function. */ -int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { - ppp_control *pc; - int pd; +int ppp_over_serial_open(int unit, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { + ppp_control *pc = &ppp_control_list[unit]; /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ if (link_status_cb == NULL) return PPPERR_PARAM; - /* Find a free PPP session descriptor. */ - for (pd = 0; pd < NUM_PPP && ppp_control_list[pd].open_flag != 0; pd++); - if (pd >= NUM_PPP) - return PPPERR_OPEN; - - pc = &ppp_control_list[pd]; /* input pbuf left over from last session? */ ppp_free_current_input_packet(&pc->rx); - /* @todo: is this correct or do I overwrite something? */ - memset(pc, 0, sizeof(ppp_control)); - pc->rx.pd = pd; - pc->rx.fd = fd; - pc->open_flag = 1; pc->fd = fd; - pc->status = EXIT_OK; - new_phase(pd, PHASE_INITIALIZE); + pc->rx.pd = unit; + pc->rx.fd = fd; #if VJ_SUPPORT vj_compress_init(&pc->vj_comp); @@ -470,12 +477,12 @@ int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void * Start the connection and handle incoming events (packet or timeout). */ PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pd)); - ppp_start(pd); + ppp_start(unit); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); #endif /* PPP_INPROC_OWNTHREAD */ - return pd; + return unit; } /* @@ -495,10 +502,9 @@ void ppp_set_xaccm(int unit, ext_accm *accm) { #if PPPOE_SUPPORT static void ppp_over_ethernet_link_status_cb(int pd, int state); -int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, +int ppp_over_ethernet_open(int unit, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { - ppp_control *pc; - int pd; + ppp_control *pc = &ppp_control_list[unit]; LWIP_UNUSED_ARG(service_name); LWIP_UNUSED_ARG(concentrator_name); @@ -508,39 +514,28 @@ int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const if (link_status_cb == NULL) return PPPERR_PARAM; - /* Find a free PPP session descriptor. Critical region? */ - for (pd = 0; pd < NUM_PPP && ppp_control_list[pd].open_flag != 0; pd++); - if (pd >= NUM_PPP) - pd = PPPERR_OPEN; - - pc = &ppp_control_list[pd]; - memset(pc, 0, sizeof(ppp_control)); - pc->open_flag = 1; pc->ethif = ethif; - pc->status = EXIT_OK; - - new_phase(pd, PHASE_INITIALIZE); pc->link_status_cb = link_status_cb; pc->link_status_ctx = link_status_ctx; - lcp_wantoptions[pd].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_wantoptions[pd].neg_asyncmap = 0; - lcp_wantoptions[pd].neg_pcompression = 0; - lcp_wantoptions[pd].neg_accompression = 0; + lcp_wantoptions[unit].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + lcp_wantoptions[unit].neg_asyncmap = 0; + lcp_wantoptions[unit].neg_pcompression = 0; + lcp_wantoptions[unit].neg_accompression = 0; - lcp_allowoptions[pd].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_allowoptions[pd].neg_asyncmap = 0; - lcp_allowoptions[pd].neg_pcompression = 0; - lcp_allowoptions[pd].neg_accompression = 0; + lcp_allowoptions[unit].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + lcp_allowoptions[unit].neg_asyncmap = 0; + lcp_allowoptions[unit].neg_pcompression = 0; + lcp_allowoptions[unit].neg_accompression = 0; - if(pppoe_create(ethif, pd, ppp_over_ethernet_link_status_cb, &pc->pppoe_sc) != ERR_OK) { + if(pppoe_create(ethif, unit, ppp_over_ethernet_link_status_cb, &pc->pppoe_sc) != ERR_OK) { pc->open_flag = 0; return PPPERR_OPEN; } - pppoe_connect(pc->pppoe_sc, ppp_settings.persist); - return pd; + pppoe_connect(pc->pppoe_sc, pc->settings.persist); + return unit; } #if 0 /* UNUSED */ @@ -1782,10 +1777,10 @@ static void ppp_over_ethernet_link_status_cb(int pd, int state) { pc = &ppp_control_list[pd]; /* Reconnect if persist mode is enabled */ - if(ppp_settings.persist) { + if(pc->settings.persist) { if(pc->link_status_cb) pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : pppoe_err_code, NULL); - pppoe_connect(pc->pppoe_sc, ppp_settings.persist); + pppoe_connect(pc->pppoe_sc, pc->settings.persist); return; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 06c425a9..1350a26d 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -88,6 +88,46 @@ typedef unsigned char u_char; *** PUBLIC DATA TYPES *** ************************/ +typedef struct ppp_settings_s { + + u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ + u_int auth_required : 1; /* Peer is required to authenticate */ + u_int explicit_remote : 1; /* remote_name specified with remotename opt */ +#if PAP_SUPPORT + u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ +#endif /* CHAP_SUPPORT */ +#if MSCHAP_SUPPORT + u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ + u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#endif /* MSCHAP_SUPPORT */ +#if EAP_SUPPORT + u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ +#endif /* EAP_SUPPORT */ + u_int usehostname : 1; /* Use hostname for our_name */ + u_int usepeerdns : 1; /* Ask peer for DNS adds */ + u_int persist : 1; /* Persist mode, always try to reopen the connection */ +#if PRINTPKT_SUPPORT + u_int hide_password : 1; /* Hide password in dumped packets */ +#endif /* PRINTPKT_SUPPORT */ + + u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ + + /* FIXME: make it a compile time option */ + u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ + int maxconnect; /* Maximum connect time (seconds) */ + + char user [MAXNAMELEN + 1]; /* Username for PAP */ + char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ +#if PPP_SERVER + char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ +#endif /* PPP_SERVER */ + /* FIXME: make it a compile time option */ + char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ +} ppp_settings; + struct ppp_addrs { ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; }; @@ -100,6 +140,9 @@ struct ppp_addrs { /* Initialize the PPP subsystem. */ int ppp_init(void); +/* Create a new PPP session, returns a PPP descriptor. */ +int ppp_new(void); + /* Warning: Using ppp_auth_type_ANY might have security consequences. * RFC 1994 says: * @@ -130,7 +173,7 @@ enum ppp_auth_type { PPPAUTHTYPE_NONE }; -void ppp_set_auth(enum ppp_auth_type authtype, const char *user, const char *passwd); +void ppp_set_auth(int unit, enum ppp_auth_type authtype, const char *user, const char *passwd); /* Link status callback function prototype */ typedef void (*ppp_link_status_cb_fn)(void *ctx, int errcode, void *arg); @@ -147,14 +190,14 @@ typedef void (*ppp_link_status_cb_fn)(void *ctx, int errcode, void *arg); * Return a new PPP connection descriptor on success or * an error code (negative) on failure. */ -int ppp_over_serial_open(sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +int ppp_over_serial_open(int unit, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT /* * Open a new PPP Over Ethernet (PPPoE) connection. */ -int ppp_over_ethernet_open(struct netif *ethif, const char *service_name, const char *concentrator_name, +int ppp_over_ethernet_open(int unit, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOE_SUPPORT */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index b6247c0b..34eaf11b 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -391,50 +391,6 @@ struct pppd_stats { }; #endif /* PPP_STATS_SUPPORT */ -/* FIXME: fill the struct below with option.c global variables */ - -struct ppp_settings { - - u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ - u_int auth_required : 1; /* Peer is required to authenticate */ - u_int explicit_remote : 1; /* remote_name specified with remotename opt */ -#if PAP_SUPPORT - u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ -#endif /* CHAP_SUPPORT */ -#if MSCHAP_SUPPORT - u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ - u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ -#endif /* MSCHAP_SUPPORT */ -#if EAP_SUPPORT - u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ -#endif /* EAP_SUPPORT */ - u_int usehostname : 1; /* Use hostname for our_name */ - u_int usepeerdns : 1; /* Ask peer for DNS adds */ - u_int persist : 1; /* Persist mode, always try to reopen the connection */ -#if PRINTPKT_SUPPORT - u_int hide_password : 1; /* Hide password in dumped packets */ -#endif /* PRINTPKT_SUPPORT */ - - u16_t listen_time; /* time to listen first (ms) */ - - /* FIXME: make it a compile time option */ - u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ - int maxconnect; /* Maximum connect time (seconds) */ - - char user [MAXNAMELEN + 1]; /* Username for PAP */ - char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ -#if PPP_SERVER - char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ -#endif /* PPP_SERVER */ - /* FIXME: make it a compile time option */ - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ -}; - -struct ppp_settings ppp_settings; - /* * PPP interface RX control block. */ @@ -464,6 +420,8 @@ typedef struct ppp_control_rx_s { * PPP interface control block. */ typedef struct ppp_control_s { + ppp_settings settings; + ppp_control_rx rx; char open_flag; /* True when in use. */ u8_t phase; /* where the link is at */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 61a46eb7..fda03f49 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -655,6 +655,7 @@ upap_printpkt(p, plen, printer, arg) int mlen, ulen, wlen; char *user, *pwd, *msg; u_char *pstart; + ppp_control *pc = &ppp_control_list[0]; if (plen < UPAP_HEADERLEN) return 0; @@ -688,7 +689,7 @@ upap_printpkt(p, plen, printer, arg) printer(arg, " user="); print_string(user, ulen, printer, arg); printer(arg, " password="); - if (!ppp_settings.hide_password) + if (!pc->settings.hide_password) print_string(pwd, wlen, printer, arg); else printer(arg, ""); From 444646b65edbf3fc6449e9e0a07bda6979cee5c3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 23:06:45 +0200 Subject: [PATCH 147/320] renamed ppp_control to ppp_pcb, replaced unit number to ppp_pcb in all ppp.h declared functions --- src/netif/ppp/auth.c | 22 +-- src/netif/ppp/chap-new.c | 2 +- src/netif/ppp/eap.c | 2 +- src/netif/ppp/ipcp.c | 4 +- src/netif/ppp/lcp.c | 8 +- src/netif/ppp/ppp.c | 291 +++++++++++++++++++-------------------- src/netif/ppp/ppp.h | 92 +++++++++++-- src/netif/ppp/ppp_impl.h | 67 +-------- src/netif/ppp/upap.c | 2 +- 9 files changed, 244 insertions(+), 246 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index b0183508..7e5d546b 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -633,7 +633,7 @@ void link_terminated(unit) int unit; { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; if (pc->phase == PHASE_DEAD || pc->phase == PHASE_MASTER) return; new_phase(unit, PHASE_DISCONNECT); @@ -712,7 +712,7 @@ void link_down(unit) int unit; { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; #if PPP_NOTIFY notify(link_down_notifier, 0); #endif /* #if PPP_NOTIFY */ @@ -763,7 +763,7 @@ link_established(unit) lcp_options *ho = &lcp_hisoptions[unit]; int i; struct protent *protp; - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; /* * Tell higher-level protocols that LCP is up. @@ -1114,7 +1114,7 @@ void auth_withpeer_fail(unit, protocol) int unit, protocol; { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pcb = &ppp_pcb_list[unit]; int errcode = PPPERR_AUTHFAIL; /* * We've failed to authenticate ourselves to our peer. @@ -1122,14 +1122,14 @@ auth_withpeer_fail(unit, protocol) * is no point in persisting without any way to get updated * authentication secrets. */ - pc->status = EXIT_AUTH_TOPEER_FAILED; + pcb->status = EXIT_AUTH_TOPEER_FAILED; /* * We've failed to authenticate ourselves to our peer. * He'll probably take the link down, and there's not much * we can do except wait for that. */ - ppp_ioctl(unit, PPPCTLS_ERRCODE, &errcode); + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(unit, "Failed to authenticate ourselves to peer"); } @@ -1203,7 +1203,7 @@ np_up(unit, proto) int unit, proto; { int tlim; - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; if (num_np_up == 0) { /* @@ -1323,7 +1323,7 @@ check_idle(arg) void *arg; { /* FIXME: fix forced unit 0 */ - ppp_control *pc = &ppp_control_list[0]; + ppp_pcb *pc = &ppp_pcb_list[0]; struct ppp_idle idle; time_t itime; int tlim; @@ -1361,7 +1361,7 @@ connect_time_expired(arg) void *arg; { /* FIXME: fix forced unit 0 */ - ppp_control *pc = &ppp_control_list[0]; + ppp_pcb *pc = &ppp_pcb_list[0]; info("Connect time expired"); pc->status = EXIT_CONNECT_TIME; lcp_close(0, "Connect time expired"); /* Close connection */ @@ -1517,7 +1517,7 @@ auth_reset(unit) { lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; if( pc->settings.passwd[0] ) { @@ -1990,7 +1990,7 @@ get_secret(unit, client, server, secret, secret_len, am_server) int am_server; { int len; - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; LWIP_UNUSED_ARG(unit); LWIP_UNUSED_ARG(server); diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 0251d0ff..62556c52 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -480,7 +480,7 @@ chap_respond(struct chap_client_state *cs, int id, unsigned char response[RESP_MAX_PKTLEN]; char rname[MAXNAMELEN+1]; char secret[MAXSECRETLEN+1]; - ppp_control *pc = &ppp_control_list[0]; + ppp_pcb *pc = &ppp_pcb_list[0]; if ((cs->flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) return; /* not ready */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 5f6f0001..0e382313 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -1333,7 +1333,7 @@ u_char *inp; int id; int len; { - ppp_control *pc = &ppp_control_list[esp->es_unit]; + ppp_pcb *pc = &ppp_pcb_list[esp->es_unit]; u_char typenum; u_char vallen; int secret_len; diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 1ab2d95f..2434b5f1 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -721,7 +721,7 @@ static void ipcp_resetci(f) fsm *f; { - ppp_control *pc = &ppp_control_list[f->unit]; + ppp_pcb *pc = &ppp_pcb_list[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *ao = &ipcp_allowoptions[f->unit]; @@ -1801,7 +1801,7 @@ ipcp_up(f) fsm *f; { u_int32_t mask; - ppp_control *pc = &ppp_control_list[f->unit]; + ppp_pcb *pc = &ppp_pcb_list[f->unit]; ipcp_options *ho = &ipcp_hisoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 8a38f119..9fb77307 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -462,7 +462,7 @@ lcp_close(unit, reason) int unit; char *reason; { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; fsm *f = &lcp_fsm[unit]; int oldstate; @@ -499,7 +499,7 @@ lcp_lowerup(unit) { lcp_options *wo = &lcp_wantoptions[unit]; fsm *f = &lcp_fsm[unit]; - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; /* * Don't use A/C or protocol compression on transmission, * but accept A/C and protocol compressed packets @@ -1129,7 +1129,7 @@ lcp_nakci(f, p, len, treat_as_reject) int len; int treat_as_reject; { - ppp_control *pc = &ppp_control_list[f->unit]; + ppp_pcb *pc = &ppp_pcb_list[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *wo = &lcp_wantoptions[f->unit]; u_char citype, cichar, *next; @@ -2632,7 +2632,7 @@ static void LcpLinkFailure (f) fsm *f; { - ppp_control *pc = &ppp_control_list[f->unit]; + ppp_pcb *pc = &ppp_pcb_list[f->unit]; if (f->state == OPENED) { info("No response to %d echo-requests", lcp_echos_pending); notice("Serial link appears to be disconnected."); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index ea32cf62..6b5ea415 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -242,9 +242,9 @@ static void ppp_hup(int pd); #if PPP_INPROC_OWNTHREAD static void ppp_input_thread(void *arg); #endif /* PPP_INPROC_OWNTHREAD */ -static void ppp_drop(ppp_control_rx *pcrx); -static void pppos_input_proc(ppp_control_rx *pcrx, u_char *s, int l); -static void ppp_free_current_input_packet(ppp_control_rx *pcrx); +static void ppp_drop(ppp_pcb_rx *pcrx); +static void pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l); +static void ppp_free_current_input_packet(ppp_pcb_rx *pcrx); #endif /* PPPOS_SUPPORT */ static err_t ppp_netif_init_cb(struct netif *netif); @@ -293,30 +293,30 @@ int ppp_init(void) { } /* Create a new PPP session. */ -int ppp_new(void) { +ppp_pcb *ppp_new(void) { int i, pd; - ppp_control *pc; + ppp_pcb *pcb; struct protent *protp; /* Find a free PPP session descriptor. */ - for (pd = 0; pd < NUM_PPP && ppp_control_list[pd].open_flag != 0; pd++); + for (pd = 0; pd < NUM_PPP && ppp_pcb_list[pd].open_flag != 0; pd++); if (pd >= NUM_PPP) - return PPPERR_OPEN; + return NULL; - pc = &ppp_control_list[pd]; + pcb = &ppp_pcb_list[pd]; #if PPP_STATS_SUPPORT link_stats_valid = 0; #endif /* PPP_STATS_SUPPORT */ - memset(pc, 0, sizeof(ppp_control)); - pc->open_flag = 1; - pc->status = EXIT_OK; + memset(pcb, 0, sizeof(ppp_pcb)); + pcb->unit = pd; + pcb->open_flag = 1; + pcb->status = EXIT_OK; new_phase(pd, PHASE_INITIALIZE); - /* memset(&pc->settings, 0, sizeof(ppp_settings)); -- already done previously */ - pc->settings.usepeerdns = 1; - pc->settings.persist = 1; + pcb->settings.usepeerdns = 1; + pcb->settings.persist = 1; /* * Initialize each protocol. @@ -324,47 +324,46 @@ int ppp_new(void) { for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(pd); - return pd; + return pcb; } -void ppp_set_auth(int unit, enum ppp_auth_type authtype, const char *user, const char *passwd) { - ppp_control *pc = &ppp_control_list[unit]; +void ppp_set_auth(ppp_pcb *pcb, enum ppp_auth_type authtype, const char *user, const char *passwd) { /* FIXME: the following may look stupid, but this is just an easy way * to check different auth by changing compile time option */ #if PAP_SUPPORT - pc->settings.refuse_pap = 0; + pcb->settings.refuse_pap = 0; #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT #if PAP_SUPPORT - pc->settings.refuse_pap = 1; + pcb->settings.refuse_pap = 1; #endif /* PAP_SUPPORT */ - pc->settings.refuse_chap = 0; + pcb->settings.refuse_chap = 0; #endif /* CHAP_SUPPORT */ #if MSCHAP_SUPPORT #if PAP_SUPPORT - pc->settings.refuse_pap = 1; + pcb->settings.refuse_pap = 1; #endif /* PAP_SUPPORT */ - pc->settings.refuse_chap = 1; - pc->settings.refuse_mschap = 1; - pc->settings.refuse_mschap_v2 = 0; + pcb->settings.refuse_chap = 1; + pcb->settings.refuse_mschap = 1; + pcb->settings.refuse_mschap_v2 = 0; #endif /* MSCHAP_SUPPORT */ #if EAP_SUPPORT #if PAP_SUPPORT - pc->settings.refuse_pap = 1; + pcb->settings.refuse_pap = 1; #endif/* PAP_SUPPORT */ #if CHAP_SUPPORT - pc->settings.refuse_chap = 1; + pcb->settings.refuse_chap = 1; #if MSCHAP_SUPPORT - pc->settings.refuse_mschap = 1; - pc->settings.refuse_mschap_v2 = 1; + pcb->settings.refuse_mschap = 1; + pcb->settings.refuse_mschap_v2 = 1; #endif /* MSCHAP_SUPPORT */ #endif /* CHAP_SUPPORT */ - pc->settings.refuse_eap = 0; + pcb->settings.refuse_eap = 0; #endif /* EAP_SUPPORT */ /* FIXME: re-enable that */ @@ -418,17 +417,17 @@ void ppp_set_auth(int unit, enum ppp_auth_type authtype, const char *user, const #endif if(user) { - strncpy(pc->settings.user, user, sizeof(pc->settings.user)-1); - pc->settings.user[sizeof(pc->settings.user)-1] = '\0'; + strncpy(pcb->settings.user, user, sizeof(pcb->settings.user)-1); + pcb->settings.user[sizeof(pcb->settings.user)-1] = '\0'; } else { - pc->settings.user[0] = '\0'; + pcb->settings.user[0] = '\0'; } if(passwd) { - strncpy(pc->settings.passwd, passwd, sizeof(pc->settings.passwd)-1); - pc->settings.passwd[sizeof(pc->settings.passwd)-1] = '\0'; + strncpy(pcb->settings.passwd, passwd, sizeof(pcb->settings.passwd)-1); + pcb->settings.passwd[sizeof(pcb->settings.passwd)-1] = '\0'; } else { - pc->settings.passwd[0] = '\0'; + pcb->settings.passwd[0] = '\0'; } } @@ -443,8 +442,7 @@ void ppp_set_auth(int unit, enum ppp_auth_type authtype, const char *user, const * * pppOpen() is directly defined to this function. */ -int ppp_over_serial_open(int unit, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { - ppp_control *pc = &ppp_control_list[unit]; +int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ @@ -452,26 +450,26 @@ int ppp_over_serial_open(int unit, sio_fd_t fd, ppp_link_status_cb_fn link_statu return PPPERR_PARAM; /* input pbuf left over from last session? */ - ppp_free_current_input_packet(&pc->rx); + ppp_free_current_input_packet(&pcb->rx); - pc->fd = fd; + pcb->fd = fd; - pc->rx.pd = unit; - pc->rx.fd = fd; + pcb->rx.pd = unit; + pcb->rx.fd = fd; #if VJ_SUPPORT - vj_compress_init(&pc->vj_comp); + vj_compress_init(&pcb->vj_comp); #endif /* VJ_SUPPORT */ /* * Default the in and out accm so that escape and flag characters * are always escaped. */ - pc->rx.in_accm[15] = 0x60; /* no need to protect since RX is not running */ - pc->out_accm[15] = 0x60; + pcb->rx.in_accm[15] = 0x60; /* no need to protect since RX is not running */ + pcb->out_accm[15] = 0x60; - pc->link_status_cb = link_status_cb; - pc->link_status_ctx = link_status_ctx; + pcb->link_status_cb = link_status_cb; + pcb->link_status_ctx = link_status_ctx; /* * Start the connection and handle incoming events (packet or timeout). @@ -479,7 +477,7 @@ int ppp_over_serial_open(int unit, sio_fd_t fd, ppp_link_status_cb_fn link_statu PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pd)); ppp_start(unit); #if PPP_INPROC_OWNTHREAD - sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); + sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); #endif /* PPP_INPROC_OWNTHREAD */ return unit; @@ -489,22 +487,21 @@ int ppp_over_serial_open(int unit, sio_fd_t fd, ppp_link_status_cb_fn link_statu * ppp_set_xaccm - set the extended transmit ACCM for the interface. */ void ppp_set_xaccm(int unit, ext_accm *accm) { - SMEMCPY(ppp_control_list[unit].out_accm, accm, sizeof(ext_accm)); + SMEMCPY(ppp_pcb_list[unit].out_accm, accm, sizeof(ext_accm)); PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: out_accm=%X %X %X %X\n", unit, - ppp_control_list[unit].out_accm[0], - ppp_control_list[unit].out_accm[1], - ppp_control_list[unit].out_accm[2], - ppp_control_list[unit].out_accm[3])); + ppp_pcb_list[unit].out_accm[0], + ppp_pcb_list[unit].out_accm[1], + ppp_pcb_list[unit].out_accm[2], + ppp_pcb_list[unit].out_accm[3])); } #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT static void ppp_over_ethernet_link_status_cb(int pd, int state); -int ppp_over_ethernet_open(int unit, struct netif *ethif, const char *service_name, const char *concentrator_name, +int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { - ppp_control *pc = &ppp_control_list[unit]; LWIP_UNUSED_ARG(service_name); LWIP_UNUSED_ARG(concentrator_name); @@ -514,38 +511,38 @@ int ppp_over_ethernet_open(int unit, struct netif *ethif, const char *service_na if (link_status_cb == NULL) return PPPERR_PARAM; - pc->ethif = ethif; + pcb->ethif = ethif; - pc->link_status_cb = link_status_cb; - pc->link_status_ctx = link_status_ctx; + pcb->link_status_cb = link_status_cb; + pcb->link_status_ctx = link_status_ctx; - lcp_wantoptions[unit].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_wantoptions[unit].neg_asyncmap = 0; - lcp_wantoptions[unit].neg_pcompression = 0; - lcp_wantoptions[unit].neg_accompression = 0; + lcp_wantoptions[pcb->unit].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + lcp_wantoptions[pcb->unit].neg_asyncmap = 0; + lcp_wantoptions[pcb->unit].neg_pcompression = 0; + lcp_wantoptions[pcb->unit].neg_accompression = 0; - lcp_allowoptions[unit].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_allowoptions[unit].neg_asyncmap = 0; - lcp_allowoptions[unit].neg_pcompression = 0; - lcp_allowoptions[unit].neg_accompression = 0; + lcp_allowoptions[pcb->unit].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + lcp_allowoptions[pcb->unit].neg_asyncmap = 0; + lcp_allowoptions[pcb->unit].neg_pcompression = 0; + lcp_allowoptions[pcb->unit].neg_accompression = 0; - if(pppoe_create(ethif, unit, ppp_over_ethernet_link_status_cb, &pc->pppoe_sc) != ERR_OK) { - pc->open_flag = 0; + if(pppoe_create(ethif, pcb->unit, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { + pcb->open_flag = 0; return PPPERR_OPEN; } - pppoe_connect(pc->pppoe_sc, pc->settings.persist); - return unit; + pppoe_connect(pcb->pppoe_sc, pcb->settings.persist); + return pcb->unit; } #if 0 /* UNUSED */ void ppp_over_ethernet_close(int pd) { - ppp_control* pc = &ppp_control_list[pd]; + ppp_pcb* pc = &ppp_pcb_list[pd]; /* *TJL* There's no lcp_deinit */ lcp_close(pd, NULL); - pppoe_destroy(&pc->netif); + pppoe_destroy(&pcb->netif); } #endif /* UNUSED */ #endif /* PPPOE_SUPPORT */ @@ -555,30 +552,29 @@ void ppp_over_ethernet_close(int pd) { * Any outstanding packets in the queues are dropped. * Return 0 on success, an error code on failure. */ int -ppp_close(int pd) +ppp_close(ppp_pcb *pcb) { - ppp_control *pc = &ppp_control_list[pd]; int st = 0; PPPDEBUG(LOG_DEBUG, ("ppp_close() called\n")); /* Disconnect */ #if PPPOE_SUPPORT - if(pc->ethif) { - PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pd)); - pc->err_code = PPPERR_USER; + if(pcb->ethif) { + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->unit)); + pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ - ppp_stop(pd); + ppp_stop(pcb->unit); } else #endif /* PPPOE_SUPPORT */ { #if PPPOS_SUPPORT - PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pd)); - pc->err_code = PPPERR_USER; + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->unit)); + pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ - ppp_stop(pd); + ppp_stop(pcb->unit); #if PPP_INPROC_OWNTHREAD - ppp_receive_wakeup(pd); + ppp_receive_wakeup(pcb->unit); #endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ } @@ -588,10 +584,10 @@ ppp_close(int pd) /* This function is called when carrier is lost on the PPP channel. */ void -ppp_sighup(int pd) +ppp_sighup(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hup\n", pd)); - ppp_hup(pd); + PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hup\n", pcb->unit)); + ppp_hup(pcb->unit); } @@ -632,7 +628,7 @@ ppp_hup(int pd) * or it is used in output ? have to find out... */ static void ppp_input(int unit, void *arg) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; struct pbuf *nb = (struct pbuf *)arg; u16_t protocol; int pd; @@ -646,8 +642,8 @@ static void ppp_input(int unit, void *arg) { } LINK_STATS_INC(link.recv); - snmp_inc_ifinucastpkts(&ppp_control_list[pd].netif); - snmp_add_ifinoctets(&ppp_control_list[pd].netif, nb->tot_len); + snmp_inc_ifinucastpkts(&ppp_pcb_list[pd].netif); + snmp_add_ifinoctets(&ppp_pcb_list[pd].netif, nb->tot_len); /* * Toss all non-LCP packets unless LCP is OPEN. @@ -692,8 +688,8 @@ static void ppp_input(int unit, void *arg) { * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, &ppp_control_list[pd].vj_comp) >= 0) && (ppp_control_list[pd].netif.input)) { - ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); + if ((vj_uncompress_tcp(&nb, &ppp_pcb_list[pd].vj_comp) >= 0) && (ppp_pcb_list[pd].netif.input)) { + ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); return; } /* Something's wrong so drop it. */ @@ -706,8 +702,8 @@ static void ppp_input(int unit, void *arg) { * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, &ppp_control_list[pd].vj_comp) >= 0) && ppp_control_list[pd].netif.input) { - ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); + if ((vj_uncompress_uncomp(nb, &ppp_pcb_list[pd].vj_comp) >= 0) && ppp_pcb_list[pd].netif.input) { + ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); return; } /* Something's wrong so drop it. */ @@ -717,8 +713,8 @@ static void ppp_input(int unit, void *arg) { case PPP_IP: /* Internet Protocol */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (ppp_control_list[pd].netif.input) { - ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); + if (ppp_pcb_list[pd].netif.input) { + ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); return; } break; @@ -773,7 +769,7 @@ static void ppp_input(int unit, void *arg) { drop: LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&ppp_control_list[pd].netif); + snmp_inc_ifindiscards(&ppp_pcb_list[pd].netif); out: pbuf_free(nb); @@ -801,8 +797,8 @@ out: * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, &ppp_control_list[pd].vj_comp) >= 0) && (ppp_control_list[pd].netif.input)) { - ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); + if ((vj_uncompress_tcp(&nb, &ppp_pcb_list[pd].vj_comp) >= 0) && (ppp_pcb_list[pd].netif.input)) { + ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); return; } /* Something's wrong so drop it. */ @@ -820,8 +816,8 @@ out: * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, &ppp_control_list[pd].vj_comp) >= 0) && ppp_control_list[pd].netif.input) { - ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); + if ((vj_uncompress_uncomp(nb, &ppp_pcb_list[pd].vj_comp) >= 0) && ppp_pcb_list[pd].netif.input) { + ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); return; } /* Something's wrong so drop it. */ @@ -836,8 +832,8 @@ out: case PPP_IP: /* Internet Protocol */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (ppp_control_list[pd].netif.input) { - ppp_control_list[pd].netif.input(nb, &ppp_control_list[pd].netif); + if (ppp_pcb_list[pd].netif.input) { + ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); return; } break; @@ -937,8 +933,8 @@ static void ppp_receive_wakeup(int pd) { PPPDEBUG(LOG_DEBUG, ("ppp_receive_wakeup: unit %d\n", pd)); - if (ppp_control_list[pd].open_flag != 0) { - sio_read_abort(ppp_control_list[pd].fd); + if (ppp_pcb_list[pd].open_flag != 0) { + sio_read_abort(ppp_pcb_list[pd].fd); } } #endif /* PPP_INPROC_OWNTHREAD */ @@ -986,7 +982,7 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb) { drop: LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&ppp_control_list[pd].netif); + snmp_inc_ifindiscards(&ppp_pcb_list[pd].netif); pbuf_free(pb); return; } @@ -1020,7 +1016,7 @@ static void ppp_input_thread(void *arg) { int count; - ppp_control_rx *pcrx = arg; + ppp_pcb_rx *pcrx = arg; while (phase != PHASE_DEAD) { count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); @@ -1037,7 +1033,7 @@ ppp_input_thread(void *arg) #if PPPOS_SUPPORT static void -pppos_put(ppp_control *pc, struct pbuf *nb) +pppos_put(ppp_pcb *pc, struct pbuf *nb) { struct pbuf *b; int c; @@ -1104,7 +1100,7 @@ ppp_append(u_char c, struct pbuf *nb, ext_accm *out_accm) */ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { int pd = (int)(size_t)netif->state; - ppp_control *pc = &ppp_control_list[pd]; + ppp_pcb *pc = &ppp_pcb_list[pd]; #if PPPOS_SUPPORT u_short protocol = PPP_IP; u_int fcs_out = PPP_INITFCS; @@ -1251,7 +1247,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i #if PPPOE_SUPPORT static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { - ppp_control *pc = &ppp_control_list[pd]; + ppp_pcb *pc = &ppp_pcb_list[pd]; struct pbuf *pb; u_short protocol = PPP_IP; int i=0; @@ -1295,32 +1291,31 @@ static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { /* Get and set parameters for the given connection. * Return 0 on success, an error code on failure. */ int -ppp_ioctl(int pd, int cmd, void *arg) +ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) { - ppp_control *pc = &ppp_control_list[pd]; int st = 0; - if (pd < 0 || pd >= NUM_PPP) { + if (pcb->unit < 0 || pcb->unit >= NUM_PPP) { st = PPPERR_PARAM; } else { switch(cmd) { case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ if (arg) { - *(int *)arg = (int)(pc->if_up); + *(int *)arg = (int)(pcb->if_up); } else { st = PPPERR_PARAM; } break; case PPPCTLS_ERRCODE: /* Set the PPP error code. */ if (arg) { - pc->err_code = *(int *)arg; + pcb->err_code = *(int *)arg; } else { st = PPPERR_PARAM; } break; case PPPCTLG_ERRCODE: /* Get the PPP error code. */ if (arg) { - *(int *)arg = (int)(pc->err_code); + *(int *)arg = (int)(pcb->err_code); } else { st = PPPERR_PARAM; } @@ -1328,7 +1323,7 @@ ppp_ioctl(int pd, int cmd, void *arg) #if PPPOS_SUPPORT case PPPCTLG_FD: /* Get the fd associated with the ppp */ if (arg) { - *(sio_fd_t *)arg = pc->fd; + *(sio_fd_t *)arg = pcb->fd; } else { st = PPPERR_PARAM; } @@ -1349,7 +1344,7 @@ ppp_ioctl(int pd, int cmd, void *arg) * -1 Failed to write to device */ int ppp_write(int pd, const u_char *s, int n) { - ppp_control *pc = &ppp_control_list[pd]; + ppp_pcb *pc = &ppp_pcb_list[pd]; #if PPPOS_SUPPORT u_char c; u_int fcs_out; @@ -1422,7 +1417,7 @@ int ppp_write(int pd, const u_char *s, int n) { #if PPPOE_SUPPORT static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { - ppp_control *pc = &ppp_control_list[pd]; + ppp_pcb *pc = &ppp_pcb_list[pd]; struct pbuf *pb; /* skip address & flags */ @@ -1467,7 +1462,7 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { * Drop the input packet. */ static void -ppp_free_current_input_packet(ppp_control_rx *pcrx) +ppp_free_current_input_packet(ppp_pcb_rx *pcrx) { if (pcrx->in_head != NULL) { if (pcrx->in_tail && (pcrx->in_tail != pcrx->in_head)) { @@ -1483,7 +1478,7 @@ ppp_free_current_input_packet(ppp_control_rx *pcrx) * Drop the input packet and increase error counters. */ static void -ppp_drop(ppp_control_rx *pcrx) +ppp_drop(ppp_pcb_rx *pcrx) { if (pcrx->in_head != NULL) { #if 0 @@ -1493,11 +1488,11 @@ ppp_drop(ppp_control_rx *pcrx) } ppp_free_current_input_packet(pcrx); #if VJ_SUPPORT - vj_uncompress_err(&ppp_control_list[pcrx->pd].vj_comp); + vj_uncompress_err(&ppp_pcb_list[pcrx->pd].vj_comp); #endif /* VJ_SUPPORT */ LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&ppp_control_list[pcrx->pd].netif); + snmp_inc_ifindiscards(&ppp_pcb_list[pcrx->pd].netif); } #if !PPP_INPROC_OWNTHREAD @@ -1509,9 +1504,9 @@ ppp_drop(ppp_control_rx *pcrx) * @param len length of received data */ void -pppos_input(int pd, u_char* data, int len) +pppos_input(ppp_pcb *pcb, u_char* data, int len) { - pppos_input_proc(&ppp_control_list[pd].rx, data, len); + pppos_input_proc(pcb->rx, data, len); } #endif @@ -1519,7 +1514,7 @@ pppos_input(int pd, u_char* data, int len) * Process a received octet string. */ static void -pppos_input_proc(ppp_control_rx *pcrx, u_char *s, int l) +pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) { struct pbuf *next_pbuf; u_char cur_char; @@ -1592,7 +1587,7 @@ pppos_input_proc(ppp_control_rx *pcrx, u_char *s, int l) PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); pbuf_free(inp); LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&ppp_control_list[pcrx->pd].netif); + snmp_inc_ifindiscards(&ppp_pcb_list[pcrx->pd].netif); } #else /* PPP_INPROC_MULTITHREADED */ ppp_input(inp); @@ -1751,7 +1746,7 @@ struct pbuf * ppp_singlebuf(struct pbuf *p) { #if PPPOE_SUPPORT static void ppp_over_ethernet_link_status_cb(int pd, int state) { int pppoe_err_code = PPPERR_NONE; - ppp_control *pc; + ppp_pcb *pc; switch(state) { @@ -1774,7 +1769,7 @@ static void ppp_over_ethernet_link_status_cb(int pd, int state) { break; } - pc = &ppp_control_list[pd]; + pc = &ppp_pcb_list[pd]; /* Reconnect if persist mode is enabled */ if(pc->settings.persist) { @@ -1805,17 +1800,17 @@ void ppp_link_terminated(int pd) { PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d\n", pd)); #if PPPOE_SUPPORT - if (ppp_control_list[pd].ethif) { - pppoe_disconnect(ppp_control_list[pd].pppoe_sc); + if (ppp_pcb_list[pd].ethif) { + pppoe_disconnect(ppp_pcb_list[pd].pppoe_sc); } else #endif /* PPPOE_SUPPORT */ { #if PPPOS_SUPPORT - ppp_control* pc; + ppp_pcb* pc; #if PPP_INPROC_OWNTHREAD ppp_receive_wakeup(pd); #endif /* PPP_INPROC_OWNTHREAD */ - pc = &ppp_control_list[pd]; + pc = &ppp_pcb_list[pd]; PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pd, pc->link_status_cb, pc->err_code)); if (pc->link_status_cb) { @@ -1838,9 +1833,9 @@ void ppp_link_terminated(int pd) { * @see netif_set_status_callback */ void -ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback) +ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback) { - netif_set_status_callback(&ppp_control_list[pd].netif, status_callback); + netif_set_status_callback(pcb->netif, status_callback); } #endif /* LWIP_NETIF_STATUS_CALLBACK */ @@ -1853,9 +1848,9 @@ ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback) * @see netif_set_link_callback */ void -ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback) +ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) { - netif_set_link_callback(&ppp_control_list[pd].netif, link_callback); + netif_set_link_callback(pcb->netif, link_callback); } #endif /* LWIP_NETIF_LINK_CALLBACK */ @@ -1868,7 +1863,7 @@ ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback) * new_phase - signal the start of a new phase of pppd's operation. */ void new_phase(int unit, int p) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; pc->phase = p; #if PPP_NOTIFY /* The one willing notify support should add here the code to be notified of phase changes */ @@ -1880,7 +1875,7 @@ void new_phase(int unit, int p) { * the ppp interface. */ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; #if PPPOS_SUPPORT int i; #endif /* PPPOS_SUPPORT */ @@ -1914,7 +1909,7 @@ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { */ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; int i; SYS_ARCH_DECL_PROTECT(lev); #endif /* PPPOS_SUPPORT */ @@ -1951,7 +1946,7 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { */ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; int st = 1; if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { @@ -1972,7 +1967,7 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, * through the interface if possible. */ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; int st = 1; LWIP_UNUSED_ARG(our_adr); @@ -1993,7 +1988,7 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { * sdns - Config the DNS servers */ int sdns (int unit, u_int32_t ns1, u_int32_t ns2) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; int st = 1; if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { @@ -2012,7 +2007,7 @@ int sdns (int unit, u_int32_t ns1, u_int32_t ns2) { * cdns - Clear the DNS servers */ int cdns (int unit, u_int32_t ns1, u_int32_t ns2) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; int st = 1; LWIP_UNUSED_ARG(ns1); @@ -2033,7 +2028,7 @@ int cdns (int unit, u_int32_t ns1, u_int32_t ns2) { */ int sifup(int u) { - ppp_control *pc = &ppp_control_list[u]; + ppp_pcb *pc = &ppp_pcb_list[u]; int st = 1; if (u < 0 || u >= NUM_PPP || !pc->open_flag) { @@ -2066,7 +2061,7 @@ int sifup(int u) * down if there are no remaining protocols. */ int sifdown(int unit) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; int st = 1; if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { @@ -2099,7 +2094,7 @@ int sifnpmode(int u, int proto, enum NPmode mode) { * netif_set_mtu - set the MTU on the PPP network interface. */ void netif_set_mtu(int unit, int mtu) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; /* Validate parameters. */ if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) @@ -2112,7 +2107,7 @@ void netif_set_mtu(int unit, int mtu) { * netif_get_mtu - get PPP interface MTU */ int netif_get_mtu(int unit) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; /* Validate parameters. */ if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) @@ -2134,7 +2129,7 @@ int netif_get_mtu(int unit) { * ppp connection when it has come up. */ int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; int st = 1; LWIP_UNUSED_ARG(ouraddr); @@ -2158,7 +2153,7 @@ int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace * cifdefaultroute - delete a default route through the address given. */ int cifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway) { - ppp_control *pc = &ppp_control_list[unit]; + ppp_pcb *pc = &ppp_pcb_list[unit]; int st = 1; LWIP_UNUSED_ARG(ouraddr); @@ -2200,7 +2195,7 @@ int cifproxyarp(int unit, u_int32_t his_adr) { */ int sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid) { #if PPPOS_SUPPORT && VJ_SUPPORT - ppp_control *pc = &ppp_control_list[u]; + ppp_pcb *pc = &ppp_pcb_list[u]; pc->vj_enabled = vjcomp; pc->vj_comp.compressSlot = cidcomp; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 1350a26d..2ecef6a8 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -88,6 +88,9 @@ typedef unsigned char u_char; *** PUBLIC DATA TYPES *** ************************/ +/* + * PPP configuration. + */ typedef struct ppp_settings_s { u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ @@ -132,6 +135,71 @@ struct ppp_addrs { ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; }; +/* + * PPP interface RX control block. + */ +typedef struct ppp_pcb_rx_s { + /** unit number / ppp descriptor */ + int pd; + /** the rx file descriptor */ + sio_fd_t fd; + /** receive buffer - encoded data is stored here */ +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD + u_char rxbuf[PPPOS_RX_BUFSIZE]; +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ + +#if PPPOS_SUPPORT + /* The input packet. */ + struct pbuf *in_head, *in_tail; + + u16_t in_protocol; /* The input protocol code. */ + u16_t in_fcs; /* Input Frame Check Sequence value. */ + ppp_dev_states in_state; /* The input process state. */ + char in_escaped; /* Escape next character. */ + ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ +#endif /* PPPOS_SUPPORT */ +} ppp_pcb_rx; + +/* + * PPP interface control block. + */ +typedef struct ppp_pcb_s { + ppp_settings settings; + int unit; + + ppp_pcb_rx rx; + char open_flag; /* True when in use. */ + u8_t phase; /* where the link is at */ + u8_t status; /* exit status */ +#if PPPOE_SUPPORT + struct netif *ethif; + struct pppoe_softc *pppoe_sc; +#endif /* PPPOE_SUPPORT */ + int if_up; /* True when the interface is up. */ + int err_code; /* Code indicating why interface is down. */ +#if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ +#endif /* PPPOS_SUPPORT */ + u16_t mtu; /* Peer's mru */ + int pcomp; /* Does peer accept protocol compression? */ + int accomp; /* Does peer accept addr/ctl compression? */ + u_long last_xmit; /* Time of last transmission. */ +#if PPPOS_SUPPORT + ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ +#endif /* PPPOS_SUPPORT */ +#if PPPOS_SUPPORT && VJ_SUPPORT + int vj_enabled; /* Flag indicating VJ compression enabled. */ + struct vjcompress vj_comp; /* Van Jacobson compression header. */ +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + struct netif netif; + + struct ppp_addrs addrs; + + void (*link_status_cb)(void *ctx, int err_code, void *arg); + void *link_status_ctx; + +} ppp_pcb; /************************ *** PUBLIC FUNCTIONS *** @@ -140,10 +208,10 @@ struct ppp_addrs { /* Initialize the PPP subsystem. */ int ppp_init(void); -/* Create a new PPP session, returns a PPP descriptor. */ -int ppp_new(void); +/* Create a new PPP session, returns a PPP PCB structure. */ +ppp_pcb *ppp_new(void); -/* Warning: Using ppp_auth_type_ANY might have security consequences. +/* Warning: Using PPPAUTHTYPE_ANY might have security consequences. * RFC 1994 says: * * In practice, within or associated with each PPP server, there is a @@ -173,7 +241,7 @@ enum ppp_auth_type { PPPAUTHTYPE_NONE }; -void ppp_set_auth(int unit, enum ppp_auth_type authtype, const char *user, const char *passwd); +void ppp_set_auth(ppp_pcb *pcb, enum ppp_auth_type authtype, const char *user, const char *passwd); /* Link status callback function prototype */ typedef void (*ppp_link_status_cb_fn)(void *ctx, int errcode, void *arg); @@ -190,14 +258,14 @@ typedef void (*ppp_link_status_cb_fn)(void *ctx, int errcode, void *arg); * Return a new PPP connection descriptor on success or * an error code (negative) on failure. */ -int ppp_over_serial_open(int unit, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT /* * Open a new PPP Over Ethernet (PPPoE) connection. */ -int ppp_over_ethernet_open(int unit, struct netif *ethif, const char *service_name, const char *concentrator_name, +int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOE_SUPPORT */ @@ -206,18 +274,18 @@ int ppp_over_ethernet_open(int unit, struct netif *ethif, const char *service_na * Any outstanding packets in the queues are dropped. * Return 0 on success, an error code on failure. */ -int ppp_close(int pd); +int ppp_close(ppp_pcb *pcb); /* * Indicate to the PPP process that the line has disconnected. */ -void ppp_sighup(int pd); +void ppp_sighup(ppp_pcb *pcb); /* * Get and set parameters for the given connection. * Return 0 on success, an error code on failure. */ -int ppp_ioctl(int pd, int cmd, void *arg); +int ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg); #if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD /* @@ -225,17 +293,17 @@ int ppp_ioctl(int pd, int cmd, void *arg); * If PPP_INPROC_OWNTHREAD==1, a seperate input thread using the blocking * sio_read() is used, so this is deactivated. */ -void pppos_input(int pd, u_char* data, int len); +void pppos_input(ppp_pcb *pcb, u_char* data, int len); #endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ #if LWIP_NETIF_STATUS_CALLBACK /* Set an lwIP-style status-callback for the selected PPP device */ -void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback); +void ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback); #endif /* LWIP_NETIF_STATUS_CALLBACK */ #if LWIP_NETIF_LINK_CALLBACK /* Set an lwIP-style link-callback for the selected PPP device */ -void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback); +void ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback); #endif /* LWIP_NETIF_LINK_CALLBACK */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 34eaf11b..5251865f 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -391,72 +391,7 @@ struct pppd_stats { }; #endif /* PPP_STATS_SUPPORT */ -/* - * PPP interface RX control block. - */ -typedef struct ppp_control_rx_s { - /** unit number / ppp descriptor */ - int pd; - /** the rx file descriptor */ - sio_fd_t fd; - /** receive buffer - encoded data is stored here */ -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD - u_char rxbuf[PPPOS_RX_BUFSIZE]; -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ - -#if PPPOS_SUPPORT - /* The input packet. */ - struct pbuf *in_head, *in_tail; - - u16_t in_protocol; /* The input protocol code. */ - u16_t in_fcs; /* Input Frame Check Sequence value. */ - ppp_dev_states in_state; /* The input process state. */ - char in_escaped; /* Escape next character. */ - ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ -#endif /* PPPOS_SUPPORT */ -} ppp_control_rx; - -/* - * PPP interface control block. - */ -typedef struct ppp_control_s { - ppp_settings settings; - - ppp_control_rx rx; - char open_flag; /* True when in use. */ - u8_t phase; /* where the link is at */ - u8_t status; /* exit status */ -#if PPPOE_SUPPORT - struct netif *ethif; - struct pppoe_softc *pppoe_sc; -#endif /* PPPOE_SUPPORT */ - int if_up; /* True when the interface is up. */ - int err_code; /* Code indicating why interface is down. */ -#if PPPOS_SUPPORT - sio_fd_t fd; /* File device ID of port. */ -#endif /* PPPOS_SUPPORT */ - u16_t mtu; /* Peer's mru */ - int pcomp; /* Does peer accept protocol compression? */ - int accomp; /* Does peer accept addr/ctl compression? */ - u_long last_xmit; /* Time of last transmission. */ -#if PPPOS_SUPPORT - ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ -#endif /* PPPOS_SUPPORT */ -#if PPPOS_SUPPORT && VJ_SUPPORT - int vj_enabled; /* Flag indicating VJ compression enabled. */ - struct vjcompress vj_comp; /* Van Jacobson compression header. */ -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - - struct netif netif; - - struct ppp_addrs addrs; - - void (*link_status_cb)(void *ctx, int err_code, void *arg); - void *link_status_ctx; - -} ppp_control; - -ppp_control ppp_control_list[NUM_PPP]; /* The PPP interface control blocks. */ +ppp_pcb ppp_pcb_list[NUM_PPP]; /* The PPP interface control blocks. */ /* PPP flow functions */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index fda03f49..cd8d2c2b 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -655,7 +655,7 @@ upap_printpkt(p, plen, printer, arg) int mlen, ulen, wlen; char *user, *pwd, *msg; u_char *pstart; - ppp_control *pc = &ppp_control_list[0]; + ppp_pcb *pc = &ppp_pcb_list[0]; if (plen < UPAP_HEADERLEN) return 0; From a3cfbfc6ba0389de8a9c3f2fe954fdb4e8395ada Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 23:32:31 +0200 Subject: [PATCH 148/320] ppp_set_auth() modified to handle new handled authtype (mschap + eap) --- src/netif/ppp/ppp.c | 101 +++++++++----------------------------------- src/netif/ppp/ppp.h | 20 ++++----- 2 files changed, 29 insertions(+), 92 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 6b5ea415..21129137 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -327,108 +327,47 @@ ppp_pcb *ppp_new(void) { return pcb; } -void ppp_set_auth(ppp_pcb *pcb, enum ppp_auth_type authtype, const char *user, const char *passwd) { +void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) { - /* FIXME: the following may look stupid, but this is just an easy way - * to check different auth by changing compile time option - */ #if PAP_SUPPORT - pcb->settings.refuse_pap = 0; + if(authtype & PPPAUTHTYPE_PAP) + pcb->settings.refuse_pap = 0; + else + pcb->settings.refuse_pap = 1; #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT -#if PAP_SUPPORT - pcb->settings.refuse_pap = 1; -#endif /* PAP_SUPPORT */ - pcb->settings.refuse_chap = 0; + if(authtype & PPPAUTHTYPE_CHAP) + pcb->settings.refuse_chap = 0; + else + pcb->settings.refuse_chap = 1; #endif /* CHAP_SUPPORT */ #if MSCHAP_SUPPORT -#if PAP_SUPPORT - pcb->settings.refuse_pap = 1; -#endif /* PAP_SUPPORT */ - pcb->settings.refuse_chap = 1; - pcb->settings.refuse_mschap = 1; - pcb->settings.refuse_mschap_v2 = 0; + if(authtype & PPPAUTHTYPE_MSCHAP) + pcb->settings.refuse_mschap = 0; + else + pcb->settings.refuse_mschap = 1; #endif /* MSCHAP_SUPPORT */ #if EAP_SUPPORT -#if PAP_SUPPORT - pcb->settings.refuse_pap = 1; -#endif/* PAP_SUPPORT */ -#if CHAP_SUPPORT - pcb->settings.refuse_chap = 1; -#if MSCHAP_SUPPORT - pcb->settings.refuse_mschap = 1; - pcb->settings.refuse_mschap_v2 = 1; -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ - pcb->settings.refuse_eap = 0; + if(authtype & PPPAUTHTYPE_EAP) + pcb->settings.refuse_eap = 0; + else + pcb->settings.refuse_eap = 1; #endif /* EAP_SUPPORT */ -/* FIXME: re-enable that */ -#if 0 - switch(authtype) { - case PPPAUTHTYPE_NONE: - default: -#ifdef LWIP_PPP_STRICT_PAP_REJECT - ppp_settings.refuse_pap = 1; -#else /* LWIP_PPP_STRICT_PAP_REJECT */ - /* some providers request pap and accept an empty login/pw */ - ppp_settings.refuse_pap = 0; -#endif /* LWIP_PPP_STRICT_PAP_REJECT */ - ppp_settings.refuse_chap = 1; - break; - - case PPPAUTHTYPE_ANY: - /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. - * RFC 1994 says: - * - * In practice, within or associated with each PPP server, there is a - * database which associates "user" names with authentication - * information ("secrets"). It is not anticipated that a particular - * named user would be authenticated by multiple methods. This would - * make the user vulnerable to attacks which negotiate the least secure - * method from among a set (such as PAP rather than CHAP). If the same - * secret was used, PAP would reveal the secret to be used later with - * CHAP. - * - * Instead, for each user name there should be an indication of exactly - * one method used to authenticate that user name. If a user needs to - * make use of different authentication methods under different - * circumstances, then distinct user names SHOULD be employed, each of - * which identifies exactly one authentication method. - * - */ - ppp_settings.refuse_pap = 0; - ppp_settings.refuse_chap = 0; - break; - - case PPPAUTHTYPE_PAP: - ppp_settings.refuse_pap = 0; - ppp_settings.refuse_chap = 1; - break; - - case PPPAUTHTYPE_CHAP: - ppp_settings.refuse_pap = 1; - ppp_settings.refuse_chap = 0; - break; - } -#endif - if(user) { strncpy(pcb->settings.user, user, sizeof(pcb->settings.user)-1); pcb->settings.user[sizeof(pcb->settings.user)-1] = '\0'; - } else { - pcb->settings.user[0] = '\0'; - } + } else + pcb->settings.user[0] = '\0'; if(passwd) { strncpy(pcb->settings.passwd, passwd, sizeof(pcb->settings.passwd)-1); pcb->settings.passwd[sizeof(pcb->settings.passwd)-1] = '\0'; - } else { + } else pcb->settings.passwd[0] = '\0'; - } } #if PPPOS_SUPPORT diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 2ecef6a8..53264232 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -211,6 +211,8 @@ int ppp_init(void); /* Create a new PPP session, returns a PPP PCB structure. */ ppp_pcb *ppp_new(void); +/* Set auth helper, optional, you can either fill ppp_pcb->settings. */ + /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. * RFC 1994 says: * @@ -230,18 +232,14 @@ ppp_pcb *ppp_new(void); * which identifies exactly one authentication method. * */ -enum ppp_auth_type { -#if CHAP_SUPPORT - PPPAUTHTYPE_CHAP, -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - PPPAUTHTYPE_PAP, -#endif /* PAP_SUPPORT */ - PPPAUTHTYPE_ANY, - PPPAUTHTYPE_NONE -}; +#define PPPAUTHTYPE_NONE 0x00 +#define PPPAUTHTYPE_PAP 0x01 +#define PPPAUTHTYPE_CHAP 0x02 +#define PPPAUTHTYPE_MSCHAP 0x04 +#define PPPAUTHTYPE_EAP 0x08 +#define PPPAUTHTYPE_ANY 0xff -void ppp_set_auth(ppp_pcb *pcb, enum ppp_auth_type authtype, const char *user, const char *passwd); +void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd); /* Link status callback function prototype */ typedef void (*ppp_link_status_cb_fn)(void *ctx, int errcode, void *arg); From fed76f29d056f332f1b8a1a2a49768b04181cfee Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 23:38:26 +0200 Subject: [PATCH 149/320] added missing EAP_SUPPORT macro --- src/netif/ppp/lcp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 9fb77307..12fbe0de 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -2469,9 +2469,11 @@ lcp_printpkt(p, plen, printer, arg) } break; #endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT case PPP_EAP: printer(arg, "eap"); break; +#endif /* EAP_SUPPORT */ default: printer(arg, "0x%x", cishort); } From f7ef9887d7a0004c3c37e73add6c611da090f110 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 9 Jun 2012 23:38:38 +0200 Subject: [PATCH 150/320] improved ppp_set_auth() mschap support --- src/netif/ppp/ppp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 21129137..cd7659a5 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -341,14 +341,16 @@ void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *pas pcb->settings.refuse_chap = 0; else pcb->settings.refuse_chap = 1; -#endif /* CHAP_SUPPORT */ - #if MSCHAP_SUPPORT - if(authtype & PPPAUTHTYPE_MSCHAP) + if(authtype & PPPAUTHTYPE_MSCHAP) { pcb->settings.refuse_mschap = 0; - else + pcb->settings.refuse_mschap_v2 = 0; + } else { pcb->settings.refuse_mschap = 1; + pcb->settings.refuse_mschap_v2 = 1; + } #endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ #if EAP_SUPPORT if(authtype & PPPAUTHTYPE_EAP) From 5abdc99f3efd809e3bfd2f9308d0199938f87326 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 10 Jun 2012 01:00:50 +0200 Subject: [PATCH 151/320] no more PPP unit number in PPPoE, now using ppp_pcb --- src/include/netif/ppp_oe.h | 6 ++--- src/netif/ppp/ppp.c | 45 ++++++++++++++++++-------------------- src/netif/ppp/ppp_impl.h | 2 +- src/netif/ppp/ppp_oe.c | 14 ++++++------ 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index c098f583..0d036014 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -145,8 +145,8 @@ PACK_STRUCT_END struct pppoe_softc { struct pppoe_softc *next; struct netif *sc_ethif; /* ethernet interface we are using */ - int sc_pd; /* ppp unit number */ - void (*sc_link_status_cb)(int pd, int up); + ppp_pcb *pcb; /* PPP PCB */ + void (*sc_link_status_cb)(ppp_pcb *pcb, int up); int sc_state; /* discovery phase or session connected */ struct eth_addr sc_dest; /* hardware address of concentrator */ @@ -171,7 +171,7 @@ struct pppoe_softc { #define pppoe_init() /* compatibility define, no initialization needed */ -err_t pppoe_create(struct netif *ethif, int pd, void (*link_status_cb)(int pd, int up), struct pppoe_softc **scptr); +err_t pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp_pcb *pcb, int up), struct pppoe_softc **scptr); err_t pppoe_destroy(struct netif *ifp); int pppoe_connect(struct pppoe_softc *sc, bool persist); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index cd7659a5..578e9ec9 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -439,7 +439,7 @@ void ppp_set_xaccm(int unit, ext_accm *accm) { #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT -static void ppp_over_ethernet_link_status_cb(int pd, int state); +static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state); int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { @@ -467,7 +467,7 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic lcp_allowoptions[pcb->unit].neg_pcompression = 0; lcp_allowoptions[pcb->unit].neg_accompression = 0; - if(pppoe_create(ethif, pcb->unit, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { + if(pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { pcb->open_flag = 0; return PPPERR_OPEN; } @@ -891,7 +891,7 @@ ppp_receive_wakeup(int pd) * this is totally stupid to make room for it and then modify the packet directly * or it is used in output ? have to find out... */ -void ppp_input_over_ethernet(int pd, struct pbuf *pb) { +void ppp_input_over_ethernet(ppp_pcb *pcb, struct pbuf *pb) { struct ppp_input_header *pih; u16_t in_protocol; @@ -914,16 +914,16 @@ void ppp_input_over_ethernet(int pd, struct pbuf *pb) { pih = pb->payload; - pih->unit = pd; + pih->unit = pcb->unit; pih->proto = in_protocol; /* pih->proto is now in host byte order */ /* Dispatch the packet thereby consuming it. */ - ppp_input(pd, pb); + ppp_input(pcb->unit, pb); return; drop: LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&ppp_pcb_list[pd].netif); + snmp_inc_ifindiscards(&pcb->netif); pbuf_free(pb); return; } @@ -1685,47 +1685,44 @@ struct pbuf * ppp_singlebuf(struct pbuf *p) { } #if PPPOE_SUPPORT -static void ppp_over_ethernet_link_status_cb(int pd, int state) { +static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { int pppoe_err_code = PPPERR_NONE; - ppp_pcb *pc; switch(state) { /* PPPoE link is established, starting PPP negotiation */ case PPPOE_CB_STATE_UP: - PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pd)); - ppp_start(pd); + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pcb->unit)); + ppp_start(pcb->unit); return; /* PPPoE link normally down (i.e. asked to do so) */ case PPPOE_CB_STATE_DOWN: - PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pd)); + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pcb->unit)); pppoe_err_code = PPPERR_CONNECT; break; /* PPPoE link failed to setup (i.e. PADI/PADO timeout */ case PPPOE_CB_STATE_FAILED: - PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pd)); + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pcb->unit)); pppoe_err_code = PPPERR_OPEN; break; } - pc = &ppp_pcb_list[pd]; - /* Reconnect if persist mode is enabled */ - if(pc->settings.persist) { - if(pc->link_status_cb) - pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : pppoe_err_code, NULL); - pppoe_connect(pc->pppoe_sc, pc->settings.persist); + if(pcb->settings.persist) { + if(pcb->link_status_cb) + pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : pppoe_err_code, NULL); + pppoe_connect(pcb->pppoe_sc, pcb->settings.persist); return; } - ppp_hup(pd); - ppp_stop(pd); - pppoe_destroy(&pc->netif); - pc->open_flag = 0; - if(pc->link_status_cb) - pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : pppoe_err_code, NULL); + ppp_hup(pcb->unit); + ppp_stop(pcb->unit); + pppoe_destroy(&pcb->netif); + pcb->open_flag = 0; + if(pcb->link_status_cb) + pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : pppoe_err_code, NULL); } #endif /* PPPOE_SUPPORT */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 5251865f..f84690b2 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -398,7 +398,7 @@ ppp_pcb ppp_pcb_list[NUM_PPP]; /* The PPP interface control blocks. */ #if PPPOE_SUPPORT void ppp_over_ethernet_init_failed(int pd); /* function called by pppoe.c */ -void ppp_input_over_ethernet(int pd, struct pbuf *pb); +void ppp_input_over_ethernet(ppp_pcb *pcb, struct pbuf *pb); #endif /* PPPOE_SUPPORT */ /* function called by all PPP subsystems to send packets */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 04f76987..c6ea2b02 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -141,7 +141,7 @@ static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct n static struct pppoe_softc *pppoe_softc_list; err_t -pppoe_create(struct netif *ethif, int pd, void (*link_status_cb)(int pd, int up), struct pppoe_softc **scptr) +pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp_pcb *pcb, int up), struct pppoe_softc **scptr) { struct pppoe_softc *sc; @@ -155,7 +155,7 @@ pppoe_create(struct netif *ethif, int pd, void (*link_status_cb)(int pd, int up) /* changed to real address later */ MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - sc->sc_pd = pd; + sc->pcb = pcb; sc->sc_link_status_cb = link_status_cb; sc->sc_ethif = ethif; @@ -277,7 +277,7 @@ pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) static void pppoe_linkstatus_up(struct pppoe_softc *sc) { - sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_UP); + sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_UP); } /* analyze and handle a single received packet while not in session state */ @@ -622,7 +622,7 @@ pppoe_data_input(struct netif *netif, struct pbuf *pb) goto drop; } - ppp_input_over_ethernet(sc->sc_pd, pb); + ppp_input_over_ethernet(sc->pcb, pb); return; @@ -874,7 +874,7 @@ pppoe_do_disconnect(struct pppoe_softc *sc) sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; - sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_DOWN); /* notify upper layers */ + sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_DOWN); /* notify upper layers */ return err; } @@ -892,7 +892,7 @@ pppoe_abort_connect(struct pppoe_softc *sc) sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; - sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_FAILED); /* notify upper layers */ + sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_FAILED); /* notify upper layers */ } /* Send a PADR packet */ @@ -1130,7 +1130,7 @@ pppoe_clear_softc(struct pppoe_softc *sc, const char *message) sc->sc_state = PPPOE_STATE_INITIAL; /* notify upper layers */ - sc->sc_link_status_cb(sc->sc_pd, PPPOE_CB_STATE_DOWN); + sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_DOWN); /* clean up softc */ MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); From 336ba8f419ad37c49b811b10cc78167f88bebf3b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 10 Jun 2012 01:08:37 +0200 Subject: [PATCH 152/320] pppoe now have access to the ppp_pcb structure, removed "persist" option copy --- src/include/netif/ppp_oe.h | 4 +--- src/netif/ppp/ppp.c | 4 ++-- src/netif/ppp/ppp_oe.c | 5 ++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index 0d036014..7078be01 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -164,8 +164,6 @@ struct pppoe_softc { #endif int sc_padi_retried; /* number of PADI retries already done */ int sc_padr_retried; /* number of PADR retries already done */ - - u_int persist : 1; /* Persist mode, don't timeout sending PADI packets */ }; @@ -174,7 +172,7 @@ struct pppoe_softc { err_t pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp_pcb *pcb, int up), struct pppoe_softc **scptr); err_t pppoe_destroy(struct netif *ifp); -int pppoe_connect(struct pppoe_softc *sc, bool persist); +int pppoe_connect(struct pppoe_softc *sc); void pppoe_disconnect(struct pppoe_softc *sc); void pppoe_disc_input(struct netif *netif, struct pbuf *p); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 578e9ec9..101ce264 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -472,7 +472,7 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic return PPPERR_OPEN; } - pppoe_connect(pcb->pppoe_sc, pcb->settings.persist); + pppoe_connect(pcb->pppoe_sc); return pcb->unit; } @@ -1713,7 +1713,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { if(pcb->settings.persist) { if(pcb->link_status_cb) pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : pppoe_err_code, NULL); - pppoe_connect(pcb->pppoe_sc, pcb->settings.persist); + pppoe_connect(pcb->pppoe_sc); return; } diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index c6ea2b02..f3fa34e9 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -755,7 +755,7 @@ pppoe_timeout(void *arg) */ if(sc->sc_padi_retried < 100000) sc->sc_padi_retried++; - if (!sc->persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { + if (!sc->pcb->settings.persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { #if 0 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { /* slow retry mode */ @@ -802,7 +802,7 @@ pppoe_timeout(void *arg) /* Start a connection (i.e. initiate discovery phase) */ int -pppoe_connect(struct pppoe_softc *sc, bool persist) +pppoe_connect(struct pppoe_softc *sc) { int err; @@ -815,7 +815,6 @@ pppoe_connect(struct pppoe_softc *sc, bool persist) sc->sc_session = 0; sc->sc_padi_retried = 0; sc->sc_padr_retried = 0; - sc->persist = persist; #ifdef PPPOE_SERVER /* wait PADI if IFF_PASSIVE */ if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { From a226099b048226dbebfbb6d9199733dbfc0e2dec Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 10 Jun 2012 01:45:29 +0200 Subject: [PATCH 153/320] ppp_close() on PPPoE actually works, clear persist mode if user asked the connection to shutdown --- src/netif/ppp/ppp.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 101ce264..c71ebe20 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -223,11 +223,6 @@ typedef enum { /* Prototypes for procedures local to this file. */ -/* FIXME: PPPoE close seem bogus, it was actually not exported at all in the previous port */ -#if 0 /* UNUSED */ -void ppp_over_ethernet_close(int pd); -#endif /* UNUSED */ - static void ppp_start(int pd); /** Initiate LCP open request */ static void ppp_input(int unit, void *arg); @@ -475,17 +470,6 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic pppoe_connect(pcb->pppoe_sc); return pcb->unit; } - -#if 0 /* UNUSED */ -void ppp_over_ethernet_close(int pd) { - ppp_pcb* pc = &ppp_pcb_list[pd]; - - /* *TJL* There's no lcp_deinit */ - lcp_close(pd, NULL); - - pppoe_destroy(&pcb->netif); -} -#endif /* UNUSED */ #endif /* PPPOE_SUPPORT */ @@ -498,6 +482,7 @@ ppp_close(ppp_pcb *pcb) int st = 0; PPPDEBUG(LOG_DEBUG, ("ppp_close() called\n")); + pcb->settings.persist = 0; /* Disconnect */ #if PPPOE_SUPPORT From 8694deaabb93ab53d03e9d14d0c24ae48cbb569b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 10 Jun 2012 21:06:02 +0200 Subject: [PATCH 154/320] don't add ppp_pcb_rx to ppp_pcb struct if PPPOS support is disabled --- src/netif/ppp/ppp.c | 2 +- src/netif/ppp/ppp.h | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index c71ebe20..d5012819 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -200,6 +200,7 @@ struct protent *protocols[] = { NULL }; +#if PPPOS_SUPPORT /* PPP packet parser states. Current state indicates operation yet to be * completed. */ typedef enum { @@ -212,7 +213,6 @@ typedef enum { PDDATA /* Process data byte. */ } ppp_dev_states; -#if PPPOS_SUPPORT #define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & ppp_accm_mask[c & 0x07]) /** RX buffer size: this may be configured smaller! */ diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 53264232..c2339d02 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -135,6 +135,7 @@ struct ppp_addrs { ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; }; +#if PPPOS_SUPPORT /* * PPP interface RX control block. */ @@ -144,11 +145,10 @@ typedef struct ppp_pcb_rx_s { /** the rx file descriptor */ sio_fd_t fd; /** receive buffer - encoded data is stored here */ -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD +#if PPP_INPROC_OWNTHREAD u_char rxbuf[PPPOS_RX_BUFSIZE]; #endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ -#if PPPOS_SUPPORT /* The input packet. */ struct pbuf *in_head, *in_tail; @@ -157,8 +157,8 @@ typedef struct ppp_pcb_rx_s { ppp_dev_states in_state; /* The input process state. */ char in_escaped; /* Escape next character. */ ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ -#endif /* PPPOS_SUPPORT */ } ppp_pcb_rx; +#endif /* PPPOS_SUPPORT */ /* * PPP interface control block. @@ -166,8 +166,9 @@ typedef struct ppp_pcb_rx_s { typedef struct ppp_pcb_s { ppp_settings settings; int unit; - +#if PPPOS_SUPPORT ppp_pcb_rx rx; +#endif /* PPPOS_SUPPORT */ char open_flag; /* True when in use. */ u8_t phase; /* where the link is at */ u8_t status; /* exit status */ From 6e2722a6d34a4ecb835a5bc9e36f9a84e856777c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 11 Jun 2012 01:39:03 +0200 Subject: [PATCH 155/320] started the unit to ppp_pcb replacement --- src/netif/ppp/auth.c | 98 ++++---- src/netif/ppp/ccp.c | 5 +- src/netif/ppp/chap-new.c | 12 +- src/netif/ppp/eap.c | 24 +- src/netif/ppp/fsm.c | 3 +- src/netif/ppp/ipcp.c | 58 ++--- src/netif/ppp/lcp.c | 30 +-- src/netif/ppp/ppp.c | 508 +++++++++++++++++---------------------- src/netif/ppp/ppp.h | 53 ++++ src/netif/ppp/ppp_impl.h | 55 ++--- src/netif/ppp/upap.c | 6 +- 11 files changed, 430 insertions(+), 422 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 7e5d546b..694283e6 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -569,10 +569,11 @@ link_required(unit) void start_link(unit) int unit; { + ppp_pcb *pcb = &ppp_pcb_list[unit]; char *msg; status = EXIT_NEGOTIATION_FAILED; - new_phase(unit, PHASE_SERIALCONN); + new_phase(pcb, PHASE_SERIALCONN); hungup = 0; devfd = the_channel->connect(); @@ -608,18 +609,18 @@ void start_link(unit) notice("Starting negotiation on %s", ppp_devnam); add_fd(fd_ppp); - new_phase(unit, PHASE_ESTABLISH); + new_phase(pcb, PHASE_ESTABLISH); lcp_lowerup(0); return; disconnect: - new_phase(unit, PHASE_DISCONNECT); + new_phase(pcb, PHASE_DISCONNECT); if (the_channel->disconnect) the_channel->disconnect(); fail: - new_phase(unit, PHASE_DEAD); + new_phase(pcb, PHASE_DEAD); if (the_channel->cleanup) (*the_channel->cleanup)(); } @@ -633,10 +634,10 @@ void link_terminated(unit) int unit; { - ppp_pcb *pc = &ppp_pcb_list[unit]; - if (pc->phase == PHASE_DEAD || pc->phase == PHASE_MASTER) + ppp_pcb *pcb = &ppp_pcb_list[unit]; + if (pcb->phase == PHASE_DEAD || pcb->phase == PHASE_MASTER) return; - new_phase(unit, PHASE_DISCONNECT); + new_phase(pcb, PHASE_DISCONNECT); #if 0 /* UNUSED */ if (pap_logout_hook) { @@ -656,7 +657,7 @@ link_terminated(unit) lcp_lowerdown(0); new_phase(unit, PHASE_DEAD); - ppp_link_terminated(unit); + ppp_link_terminated(pcb); #if 0 /* * Delete pid files before disestablishing ppp. Otherwise it @@ -697,11 +698,11 @@ link_terminated(unit) if (doing_multilink && multilink_master) { if (!bundle_terminating) - new_phase(unit, PHASE_MASTER); + new_phase(pcb, PHASE_MASTER); else mp_bundle_terminated(); } else - new_phase(unit, PHASE_DEAD); + new_phase(pcb, PHASE_DEAD); #endif } @@ -712,20 +713,20 @@ void link_down(unit) int unit; { - ppp_pcb *pc = &ppp_pcb_list[unit]; + ppp_pcb *pcb = &ppp_pcb_list[unit]; #if PPP_NOTIFY notify(link_down_notifier, 0); #endif /* #if PPP_NOTIFY */ if (!doing_multilink) { upper_layers_down(unit); - if (pc->phase != PHASE_DEAD && pc->phase != PHASE_MASTER) - new_phase(unit, PHASE_ESTABLISH); + if (pcb->phase != PHASE_DEAD && pcb->phase != PHASE_MASTER) + new_phase(pcb, PHASE_ESTABLISH); } /* XXX if doing_multilink, should do something to stop network-layer traffic on the link */ - ppp_link_down(unit); + ppp_link_down(pcb); } void upper_layers_down(int unit) @@ -753,6 +754,7 @@ void link_established(unit) int unit; { + ppp_pcb *pcb = &ppp_pcb_list[unit]; int auth; #if 0 /* UNUSED */ lcp_options *wo = &lcp_wantoptions[unit]; @@ -763,7 +765,6 @@ link_established(unit) lcp_options *ho = &lcp_hisoptions[unit]; int i; struct protent *protp; - ppp_pcb *pc = &ppp_pcb_list[unit]; /* * Tell higher-level protocols that LCP is up. @@ -814,18 +815,18 @@ link_established(unit) } #endif /* UNUSED */ - new_phase(unit, PHASE_AUTHENTICATE); + new_phase(pcb, PHASE_AUTHENTICATE); auth = 0; #if PPP_SERVER #if EAP_SUPPORT if (go->neg_eap) { - eap_authpeer(unit, pc->settings.our_name); + eap_authpeer(unit, pcb->settings.our_name); auth |= EAP_PEER; } else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (go->neg_chap) { - chap_auth_peer(unit, pc->settings.our_name, CHAP_DIGEST(go->chap_mdtype)); + chap_auth_peer(unit, pcb->settings.our_name, CHAP_DIGEST(go->chap_mdtype)); auth |= CHAP_PEER; } else #endif /* CHAP_SUPPORT */ @@ -840,19 +841,19 @@ link_established(unit) #if EAP_SUPPORT if (ho->neg_eap) { - eap_authwithpeer(unit, pc->settings.user); + eap_authwithpeer(unit, pcb->settings.user); auth |= EAP_WITHPEER; } else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (ho->neg_chap) { - chap_auth_with_peer(unit, pc->settings.user, CHAP_DIGEST(ho->chap_mdtype)); + chap_auth_with_peer(unit, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if (ho->neg_upap) { - upap_authwithpeer(unit, pc->settings.user, pc->settings.passwd); + upap_authwithpeer(unit, pcb->settings.user, pcb->settings.passwd); auth |= PAP_WITHPEER; } else #endif /* PAP_SUPPORT */ @@ -872,6 +873,7 @@ static void network_phase(unit) int unit; { + ppp_pcb *pcb = &ppp_pcb_list[unit]; #if 0 /* UNUSED */ lcp_options *go = &lcp_gotoptions[unit]; #endif /* UNUSED */ @@ -906,7 +908,7 @@ network_phase(unit) * If we negotiated callback, do it now. */ if (go->neg_cbcp) { - new_phase(unit, PHASE_CALLBACK); + new_phase(pcb, PHASE_CALLBACK); (*cbcp_protent.open)(unit); return; } @@ -929,6 +931,7 @@ void start_networks(unit) int unit; { + ppp_pcb *pcb = &ppp_pcb_list[unit]; #if CCP_SUPPORT || ECP_SUPPORT int i; struct protent *protp; @@ -940,7 +943,7 @@ start_networks(unit) int mppe_required; #endif /* MPPE */ - new_phase(unit, PHASE_NETWORK); + new_phase(pcb, PHASE_NETWORK); #ifdef HAVE_MULTILINK if (multilink) { @@ -1203,21 +1206,21 @@ np_up(unit, proto) int unit, proto; { int tlim; - ppp_pcb *pc = &ppp_pcb_list[unit]; + ppp_pcb *pcb = &ppp_pcb_list[unit]; if (num_np_up == 0) { /* * At this point we consider that the link has come up successfully. */ - pc->status = EXIT_OK; - new_phase(unit, PHASE_RUNNING); + pcb->status = EXIT_OK; + new_phase(pcb, PHASE_RUNNING); #if 0 /* UNUSED */ if (idle_time_hook != 0) tlim = (*idle_time_hook)(NULL); else #endif /* UNUSED */ - tlim = pc->settings.idle_time_limit; + tlim = pcb->settings.idle_time_limit; if (tlim > 0) TIMEOUT(check_idle, NULL, tlim); @@ -1225,8 +1228,8 @@ np_up(unit, proto) * Set a timeout to close the connection once the maximum * connect time has expired. */ - if (pc->settings.maxconnect > 0) - TIMEOUT(connect_time_expired, 0, pc->settings.maxconnect); + if (pcb->settings.maxconnect > 0) + TIMEOUT(connect_time_expired, 0, pcb->settings.maxconnect); #ifdef MAXOCTETS if (maxoctets > 0) @@ -1251,13 +1254,14 @@ void np_down(unit, proto) int unit, proto; { + ppp_pcb *pcb = &ppp_pcb_list[unit]; if (--num_np_up == 0) { UNTIMEOUT(check_idle, NULL); UNTIMEOUT(connect_time_expired, NULL); #ifdef MAXOCTETS UNTIMEOUT(check_maxoctets, NULL); #endif - new_phase(unit, PHASE_NETWORK); + new_phase(pcb, PHASE_NETWORK); } } @@ -1323,12 +1327,12 @@ check_idle(arg) void *arg; { /* FIXME: fix forced unit 0 */ - ppp_pcb *pc = &ppp_pcb_list[0]; + ppp_pcb *pcb = &ppp_pcb_list[0]; struct ppp_idle idle; time_t itime; int tlim; - if (!get_idle_time(0, &idle)) + if (!get_idle_time(pcb, &idle)) return; #if 0 /* UNUSED */ if (idle_time_hook != 0) { @@ -1336,14 +1340,14 @@ check_idle(arg) } else { #endif /* UNUSED */ itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); - tlim = pc->settings.idle_time_limit - itime; + tlim = pcb->settings.idle_time_limit - itime; #if 0 /* UNUSED */ } #endif /* UNUSED */ if (tlim <= 0) { /* link is idle: shut it down. */ notice("Terminating connection due to lack of activity."); - pc->status = EXIT_IDLE_TIMEOUT; + pcb->status = EXIT_IDLE_TIMEOUT; lcp_close(0, "Link inactive"); #if 0 /* UNUSED */ need_holdoff = 0; @@ -1361,9 +1365,9 @@ connect_time_expired(arg) void *arg; { /* FIXME: fix forced unit 0 */ - ppp_pcb *pc = &ppp_pcb_list[0]; + ppp_pcb *pcb = &ppp_pcb_list[0]; info("Connect time expired"); - pc->status = EXIT_CONNECT_TIME; + pcb->status = EXIT_CONNECT_TIME; lcp_close(0, "Connect time expired"); /* Close connection */ } @@ -1517,26 +1521,26 @@ auth_reset(unit) { lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; - ppp_pcb *pc = &ppp_pcb_list[unit]; + ppp_pcb *pcb = &ppp_pcb_list[unit]; - if( pc->settings.passwd[0] ) { + if( pcb->settings.passwd[0] ) { #if PAP_SUPPORT - ao->neg_upap = !pc->settings.refuse_pap; + ao->neg_upap = !pcb->settings.refuse_pap; #endif /* PAP_SUPPORT */ #if EAP_SUPPORT - ao->neg_eap = !pc->settings.refuse_eap; + ao->neg_eap = !pcb->settings.refuse_eap; #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT ao->chap_mdtype = MDTYPE_NONE; - if(!pc->settings.refuse_chap) + if(!pcb->settings.refuse_chap) ao->chap_mdtype |= MDTYPE_MD5; #if MSCHAP_SUPPORT - if(!pc->settings.refuse_mschap) + if(!pcb->settings.refuse_mschap) ao->chap_mdtype |= MDTYPE_MICROSOFT; - if(!pc->settings.refuse_mschap_v2) + if(!pcb->settings.refuse_mschap_v2) ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; #endif /* MSCHAP_SUPPORT */ @@ -1990,23 +1994,23 @@ get_secret(unit, client, server, secret, secret_len, am_server) int am_server; { int len; - ppp_pcb *pc = &ppp_pcb_list[unit]; + ppp_pcb *pcb = &ppp_pcb_list[unit]; LWIP_UNUSED_ARG(unit); LWIP_UNUSED_ARG(server); LWIP_UNUSED_ARG(am_server); - if(!client || !client[0] || strcmp(client, pc->settings.user)) { + if(!client || !client[0] || strcmp(client, pcb->settings.user)) { return 0; } - len = (int)strlen(pc->settings.passwd); + len = (int)strlen(pcb->settings.passwd); if (len > MAXSECRETLEN) { error("Secret for %s on %s is too long", client, server); len = MAXSECRETLEN; } - MEMCPY(secret, pc->settings.passwd, len); + MEMCPY(secret, pcb->settings.passwd, len); *secret_len = len; return 1; diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index d2e04569..de1ad4e8 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -1084,6 +1084,7 @@ ccp_reqci(f, p, lenp, dont_nak) int *lenp; int dont_nak; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; int ret, newret, res; u_char *p0, *retp; int len, clen, type, nb; @@ -1200,9 +1201,9 @@ ccp_reqci(f, p, lenp, dont_nak) * because MPPE frames **grow**. The kernel [must] * allocate MPPE_PAD extra bytes in xmit buffers. */ - mtu = netif_get_mtu(f->unit); + mtu = netif_get_mtu(pcb); if (mtu) - netif_set_mtu(f->unit, mtu - MPPE_PAD); + netif_set_mtu(pcb, mtu - MPPE_PAD); else newret = CONFREJ; } diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 62556c52..6d246dae 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -282,6 +282,8 @@ chap_auth_with_peer(int unit, char *our_name, int digest_code) static void chap_timeout(void *arg) { + /* FIXME: fix forced unit 0 */ + ppp_pcb *pcb = &ppp_pcb_list[0]; struct chap_server_state *ss = arg; ss->flags &= ~TIMEOUT_PENDING; @@ -296,7 +298,7 @@ chap_timeout(void *arg) return; } - ppp_write(0, ss->challenge, ss->challenge_pktlen); + ppp_write(pcb, ss->challenge, ss->challenge_pktlen); ++ss->challenge_xmits; ss->flags |= TIMEOUT_PENDING; TIMEOUT(chap_timeout, arg, chap_timeout_time); @@ -337,6 +339,8 @@ static void chap_handle_response(struct chap_server_state *ss, int id, unsigned char *pkt, int len) { + /* FIXME: fix forced unit 0 */ + ppp_pcb *pcb = &ppp_pcb_list[0]; int response_len, ok, mlen; unsigned char *response, *p; char *name = NULL; /* initialized to shut gcc up */ @@ -397,7 +401,7 @@ chap_handle_response(struct chap_server_state *ss, int id, p[3] = len; if (mlen > 0) memcpy(p + CHAP_HDRLEN, ss->message, mlen); - ppp_write(0, outpacket_buf, PPP_HDRLEN + len); + ppp_write(pcb, outpacket_buf, PPP_HDRLEN + len); if (ss->flags & CHALLENGE_VALID) { ss->flags &= ~CHALLENGE_VALID; @@ -474,6 +478,8 @@ static void chap_respond(struct chap_client_state *cs, int id, unsigned char *pkt, int len) { + /* FIXME: fix forced unit 0 */ + ppp_pcb *pcb = &ppp_pcb_list[0]; int clen, nlen; int secret_len; unsigned char *p; @@ -521,7 +527,7 @@ chap_respond(struct chap_client_state *cs, int id, p[2] = len >> 8; p[3] = len; - ppp_write(0, response, PPP_HDRLEN + len); + ppp_write(pcb, response, PPP_HDRLEN + len); } static void diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 0e382313..95176380 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -268,6 +268,7 @@ static void eap_send_failure(esp) eap_state *esp; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char *outp; outp = outpacket_buf; @@ -279,7 +280,7 @@ eap_state *esp; PUTCHAR(esp->es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_write(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); + ppp_write(pcb, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); esp->es_server.ea_state = eapBadAuth; auth_peer_fail(esp->es_unit, PPP_EAP); @@ -293,6 +294,7 @@ static void eap_send_success(esp) eap_state *esp; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char *outp; outp = outpacket_buf; @@ -304,7 +306,7 @@ eap_state *esp; PUTCHAR(esp->es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); + ppp_write(pcb, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); auth_peer_success(esp->es_unit, PPP_EAP, 0, esp->es_server.ea_peer, esp->es_server.ea_peerlen); @@ -648,6 +650,7 @@ static void eap_send_request(esp) eap_state *esp; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char *outp; u_char *lenloc; u_char *ptr; @@ -867,7 +870,7 @@ eap_state *esp; outlen = (outp - outpacket_buf) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); - ppp_write(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); esp->es_server.ea_requests++; @@ -1066,6 +1069,7 @@ u_char typenum; u_char *str; int lenstr; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char *outp; int msglen; @@ -1083,7 +1087,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); } /* @@ -1097,6 +1101,7 @@ u_char *hash; char *name; int namelen; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char *outp; int msglen; @@ -1118,7 +1123,7 @@ int namelen; MEMCPY(outp, name, namelen); } - ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); } #ifdef USE_SRP @@ -1133,6 +1138,7 @@ u_char subtypenum; u_char *str; int lenstr; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char *outp; int msglen; @@ -1151,7 +1157,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); } /* @@ -1164,6 +1170,7 @@ u_char id; u_int32_t flags; u_char *str; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char *outp; int msglen; @@ -1182,7 +1189,7 @@ u_char *str; PUTLONG(flags, outp); MEMCPY(outp, str, SHA_DIGESTSIZE); - ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); } #endif /* USE_SRP */ @@ -1192,6 +1199,7 @@ eap_state *esp; u_char id; u_char type; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char *outp; int msglen; @@ -1207,7 +1215,7 @@ u_char type; PUTCHAR(EAPT_NAK, outp); PUTCHAR(type, outp); - ppp_write(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); } #ifdef USE_SRP diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 57b366b2..856ccfcd 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -808,6 +808,7 @@ fsm_sdata(f, code, id, data, datalen) u_char *data; int datalen; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; u_char *outp; int outlen; @@ -822,7 +823,7 @@ fsm_sdata(f, code, id, data, datalen) PUTCHAR(code, outp); PUTCHAR(id, outp); PUTSHORT(outlen, outp); - ppp_write(f->unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); } #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 2434b5f1..3b8589e5 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1756,6 +1756,7 @@ static int ip_demand_conf(u) int u; { + ppp_pcb *pcb = &ppp_pcb_list[u]; ipcp_options *wo = &ipcp_wantoptions[u]; if (wo->hisaddr == 0 && !noremoteip) { @@ -1769,18 +1770,18 @@ ip_demand_conf(u) wo->accept_local = 1; ask_for_local = 0; /* don't tell the peer this address */ } - if (!sifaddr(u, wo->ouraddr, wo->hisaddr, get_mask(wo->ouraddr))) + if (!sifaddr(pcb, wo->ouraddr, wo->hisaddr, get_mask(wo->ouraddr))) return 0; - if (!sifup(u)) + if (!sifup(pcb)) return 0; - if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) + if (!sifnpmode(pcb, PPP_IP, NPMODE_QUEUE)) return 0; if (wo->default_route) - if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr, + if (sifdefaultroute(pcb, wo->ouraddr, wo->hisaddr, wo->replace_default_route)) default_route_set[u] = 1; if (wo->proxy_arp) - if (sifproxyarp(u, wo->hisaddr)) + if (sifproxyarp(pcb, wo->hisaddr)) proxy_arp_set[u] = 1; notice("local IP address %I", wo->ouraddr); @@ -1800,8 +1801,8 @@ static void ipcp_up(f) fsm *f; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; u_int32_t mask; - ppp_pcb *pc = &ppp_pcb_list[f->unit]; ipcp_options *ho = &ipcp_hisoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; @@ -1846,8 +1847,8 @@ ipcp_up(f) if (go->dnsaddr[1]) script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); #endif /* UNUSED */ - if (pc->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { - sdns(f->unit, go->dnsaddr[0], go->dnsaddr[1]); + if (pcb->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + sdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); #if 0 /* UNUSED */ script_setenv("USEPEERDNS", "1", 0); create_resolv(go->dnsaddr[0], go->dnsaddr[1]); @@ -1867,7 +1868,7 @@ ipcp_up(f) #endif /* Unused */ /* set tcp compression */ - sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); + sifvjcomp(pcb, ho->neg_vj, ho->cflag, ho->maxslotindex); #if DEMAND_SUPPORT /* @@ -1894,7 +1895,7 @@ ipcp_up(f) /* Set the interface to the new addresses */ mask = get_mask(go->ouraddr); - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { + if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { #if PPP_DEBUG warn("Interface configuration failed"); #endif /* PPP_DEBUG */ @@ -1904,18 +1905,18 @@ ipcp_up(f) /* assign a default route through the interface if required */ if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, + if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(f->unit, ho->hisaddr)) + if (sifproxyarp(pcb, ho->hisaddr)) proxy_arp_set[f->unit] = 1; } demand_rexmit(PPP_IP,go->ouraddr); - sifnpmode(f->unit, PPP_IP, NPMODE_PASS); + sifnpmode(pcb, PPP_IP, NPMODE_PASS); } else #endif /* DEMAND_SUPPORT */ @@ -1926,7 +1927,7 @@ ipcp_up(f) mask = get_mask(go->ouraddr); #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { + if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { #if PPP_DEBUG warn("Interface configuration failed"); #endif /* PPP_DEBUG */ @@ -1936,7 +1937,7 @@ ipcp_up(f) #endif /* bring the interface up for IP */ - if (!sifup(f->unit)) { + if (!sifup(pcb)) { #if PPP_DEBUG warn("Interface failed to come up"); #endif /* PPP_DEBUG */ @@ -1945,7 +1946,7 @@ ipcp_up(f) } #if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { + if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { #if PPP_DEBUG warn("Interface configuration failed"); #endif /* PPP_DEBUG */ @@ -1953,17 +1954,17 @@ ipcp_up(f) return; } #endif - sifnpmode(f->unit, PPP_IP, NPMODE_PASS); + sifnpmode(pcb, 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, + if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(f->unit, ho->hisaddr)) + if (sifproxyarp(pcb, ho->hisaddr)) proxy_arp_set[f->unit] = 1; ipcp_wantoptions[0].ouraddr = go->ouraddr; @@ -2004,6 +2005,7 @@ static void ipcp_down(f) fsm *f; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; IPCPDEBUG(("ipcp: down")); #if PPP_STATS_SUPPORT /* XXX a bit IPv4-centric here, we only need to get the stats @@ -2023,7 +2025,7 @@ ipcp_down(f) ipcp_is_up = 0; np_down(f->unit, PPP_IP); } - sifvjcomp(f->unit, 0, 0, 0); + sifvjcomp(pcb, 0, 0, 0); #if PPP_STATS_SUPPORT print_link_stats(); /* _after_ running the notifiers and ip_down_hook(), @@ -2037,15 +2039,15 @@ ipcp_down(f) * to queue up outgoing packets (for now). */ if (demand) { - sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE); + sifnpmode(pcb, PPP_IP, NPMODE_QUEUE); } else #endif /* DEMAND_SUPPORT */ { - sifnpmode(f->unit, PPP_IP, NPMODE_DROP); - sifdown(f->unit); + sifnpmode(pcb, PPP_IP, NPMODE_DROP); + sifdown(pcb); ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, ipcp_hisoptions[f->unit].hisaddr, 0); - cdns(f->unit, ipcp_gotoptions[f->unit].dnsaddr[0], ipcp_gotoptions[f->unit].dnsaddr[1]); + cdns(pcb, ipcp_gotoptions[f->unit].dnsaddr[0], ipcp_gotoptions[f->unit].dnsaddr[1]); } } @@ -2056,8 +2058,10 @@ ipcp_down(f) */ static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + if (proxy_arp_set[unit]) { - cifproxyarp(unit, hisaddr); + cifproxyarp(pcb, hisaddr); proxy_arp_set[unit] = 0; } /* If replacedefaultroute, sifdefaultroute will be called soon @@ -2069,10 +2073,10 @@ static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, boo * is one saved by an sifdefaultroute with replacedefaultroute. */ if (!replacedefaultroute && default_route_set[unit]) { - cifdefaultroute(unit, ouraddr, hisaddr); + cifdefaultroute(pcb, ouraddr, hisaddr); default_route_set[unit] = 0; } - cifaddr(unit, ouraddr, hisaddr); + cifaddr(pcb, ouraddr, hisaddr); } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 12fbe0de..acfd4116 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -462,12 +462,12 @@ lcp_close(unit, reason) int unit; char *reason; { - ppp_pcb *pc = &ppp_pcb_list[unit]; + ppp_pcb *pcb = &ppp_pcb_list[unit]; fsm *f = &lcp_fsm[unit]; int oldstate; - if (pc->phase != PHASE_DEAD && pc->phase != PHASE_MASTER) - new_phase(unit, PHASE_TERMINATE); + if (pcb->phase != PHASE_DEAD && pcb->phase != PHASE_MASTER) + new_phase(pcb, PHASE_TERMINATE); if (f->flags & DELAYED_UP) { UNTIMEOUT(lcp_delayed_up, f); @@ -497,19 +497,19 @@ void lcp_lowerup(unit) int unit; { + ppp_pcb *pcb = &ppp_pcb_list[unit]; lcp_options *wo = &lcp_wantoptions[unit]; fsm *f = &lcp_fsm[unit]; - ppp_pcb *pc = &ppp_pcb_list[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. */ #if PPPOS_SUPPORT - ppp_set_xaccm(unit, &xmit_accm[unit]); + ppp_set_xaccm(pcb, &xmit_accm[unit]); #endif /* PPPOS_SUPPORT */ - if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0 - || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), + if (ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0) < 0 + || ppp_recv_config(pcb, PPP_MRU, (lax_recv? 0: 0xffffffff), wo->neg_pcompression, wo->neg_accompression) < 0) return; peer_mru[unit] = PPP_MRU; @@ -526,9 +526,9 @@ lcp_lowerup(unit) xmit_accm[unit][0])); #endif /* PPPOS_SUPPORT */ - if (pc->settings.listen_time != 0) { + if (pcb->settings.listen_time != 0) { f->flags |= DELAYED_UP; - TIMEOUTMS(lcp_delayed_up, f, pc->settings.listen_time); + TIMEOUTMS(lcp_delayed_up, f, pcb->settings.listen_time); } else fsm_lowerup(f); } @@ -2278,6 +2278,7 @@ static void lcp_up(f) fsm *f; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; lcp_options *wo = &lcp_wantoptions[f->unit]; lcp_options *ho = &lcp_hisoptions[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; @@ -2303,11 +2304,11 @@ lcp_up(f) #ifdef HAVE_MULTILINK if (!(multilink && go->neg_mrru && ho->neg_mrru)) #endif /* HAVE_MULTILINK */ - netif_set_mtu(f->unit, LWIP_MIN(LWIP_MIN(mtu, mru), ao->mru)); - ppp_send_config(f->unit, mtu, + netif_set_mtu(pcb, LWIP_MIN(LWIP_MIN(mtu, mru), ao->mru)); + ppp_send_config(pcb, mtu, (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), ho->neg_pcompression, ho->neg_accompression); - ppp_recv_config(f->unit, mru, + ppp_recv_config(pcb, mru, (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); @@ -2329,14 +2330,15 @@ static void lcp_down(f) fsm *f; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; 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, + ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0); + ppp_recv_config(pcb, PPP_MRU, (go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); peer_mru[f->unit] = PPP_MRU; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index d5012819..e4851095 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -126,25 +126,6 @@ /*** LOCAL DEFINITIONS ***/ /*************************/ -/** PPP_INPROC_MULTITHREADED==1 call ppp_input using tcpip_callback(). - * Set this to 0 if pppos_input_proc is called inside tcpip_thread or with NO_SYS==1. - * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). - */ -#ifndef PPP_INPROC_MULTITHREADED -#define PPP_INPROC_MULTITHREADED (NO_SYS==0) -#endif - -/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session. - * Default is 0: call pppos_input() for received raw characters, character - * reception is up to the port */ -#ifndef PPP_INPROC_OWNTHREAD -#define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED -#endif - -#if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED - #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1" -#endif - /* * Buffers for outgoing packets. This must be accessed only from the appropriate * PPP task so that it doesn't need to be protected to avoid collisions. @@ -201,24 +182,7 @@ struct protent *protocols[] = { }; #if PPPOS_SUPPORT -/* PPP packet parser states. Current state indicates operation yet to be - * completed. */ -typedef enum { - PDIDLE = 0, /* Idle state - waiting. */ - PDSTART, /* Process start flag. */ - PDADDRESS, /* Process address field. */ - PDCONTROL, /* Process control field. */ - PDPROTOCOL1, /* Process protocol field 1. */ - PDPROTOCOL2, /* Process protocol field 2. */ - PDDATA /* Process data byte. */ -} ppp_dev_states; - #define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & ppp_accm_mask[c & 0x07]) - -/** RX buffer size: this may be configured smaller! */ -#ifndef PPPOS_RX_BUFSIZE -#define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN) -#endif #endif /* PPPOS_SUPPORT */ /* Prototypes for procedures local to this file. */ @@ -227,7 +191,7 @@ static void ppp_start(int pd); /** Initiate LCP open request */ static void ppp_input(int unit, void *arg); #if PPPOS_SUPPORT -static void ppp_receive_wakeup(int pd); +static void ppp_receive_wakeup(ppp_pcb *pcb); #endif /* #if PPPOS_SUPPORT */ static void ppp_stop(int pd); @@ -246,9 +210,9 @@ static err_t ppp_netif_init_cb(struct netif *netif); static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); #if PPPOE_SUPPORT -static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p); +static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p); /* function called by ppp_write() */ -static int ppp_write_over_ethernet(int pd, const u_char *s, int n); +static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n); #endif /* PPPOE_SUPPORT */ /******************************/ @@ -308,7 +272,7 @@ ppp_pcb *ppp_new(void) { pcb->unit = pd; pcb->open_flag = 1; pcb->status = EXIT_OK; - new_phase(pd, PHASE_INITIALIZE); + new_phase(pcb, PHASE_INITIALIZE); pcb->settings.usepeerdns = 1; pcb->settings.persist = 1; @@ -390,7 +354,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s pcb->fd = fd; - pcb->rx.pd = unit; + pcb->rx.pd = pcb->unit; pcb->rx.fd = fd; #if VJ_SUPPORT @@ -410,26 +374,26 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s /* * Start the connection and handle incoming events (packet or timeout). */ - PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pd)); - ppp_start(unit); + PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->unit)); + ppp_start(pcb->unit); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); #endif /* PPP_INPROC_OWNTHREAD */ - return unit; + return pcb->unit; } /* * ppp_set_xaccm - set the extended transmit ACCM for the interface. */ -void ppp_set_xaccm(int unit, ext_accm *accm) { - SMEMCPY(ppp_pcb_list[unit].out_accm, accm, sizeof(ext_accm)); +void ppp_set_xaccm(ppp_pcb *pcb, ext_accm *accm) { + SMEMCPY(pcb->out_accm, accm, sizeof(ext_accm)); PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: out_accm=%X %X %X %X\n", - unit, - ppp_pcb_list[unit].out_accm[0], - ppp_pcb_list[unit].out_accm[1], - ppp_pcb_list[unit].out_accm[2], - ppp_pcb_list[unit].out_accm[3])); + pcb->unit, + pcb->out_accm[0], + pcb->out_accm[1], + pcb->out_accm[2], + pcb->out_accm[3])); } #endif /* PPPOS_SUPPORT */ @@ -500,7 +464,7 @@ ppp_close(ppp_pcb *pcb) /* This will leave us at PHASE_DEAD. */ ppp_stop(pcb->unit); #if PPP_INPROC_OWNTHREAD - ppp_receive_wakeup(pcb->unit); + ppp_receive_wakeup(pcb); #endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ } @@ -554,7 +518,7 @@ ppp_hup(int pd) * or it is used in output ? have to find out... */ static void ppp_input(int unit, void *arg) { - ppp_pcb *pc = &ppp_pcb_list[unit]; + ppp_pcb *pcb = &ppp_pcb_list[unit]; struct pbuf *nb = (struct pbuf *)arg; u16_t protocol; int pd; @@ -583,7 +547,7 @@ static void ppp_input(int unit, void *arg) { * Until we get past the authentication phase, toss all packets * except LCP, LQR and authentication packets. */ - if (pc->phase <= PHASE_AUTHENTICATE + if (pcb->phase <= PHASE_AUTHENTICATE && !(protocol == PPP_LCP #if LQR_SUPPORT || protocol == PPP_LQR @@ -599,7 +563,7 @@ static void ppp_input(int unit, void *arg) { #endif /* EAP_SUPPORT */ )) { dbglog("discarding proto 0x%x in phase %d", - protocol, pc->phase); + protocol, pcb->phase); goto drop; } @@ -856,12 +820,11 @@ static u_char ppp_accm_mask[] = { #if PPP_INPROC_OWNTHREAD /** Wake up the task blocked in reading from serial line (if any) */ static void -ppp_receive_wakeup(int pd) +ppp_receive_wakeup(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_receive_wakeup: unit %d\n", pd)); - if (ppp_pcb_list[pd].open_flag != 0) { - sio_read_abort(ppp_pcb_list[pd].fd); - } + PPPDEBUG(LOG_DEBUG, ("ppp_receive_wakeup: unit %d\n", pcb->unit)); + if (pcb->open_flag != 0) + sio_read_abort(pcb->fd); } #endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ @@ -921,7 +884,7 @@ static err_t ppp_netif_init_cb(struct netif *netif) { netif->name[0] = 'p'; netif->name[1] = 'p'; netif->output = ppp_netif_output; - netif->mtu = netif_get_mtu((int)(size_t)netif->state); + netif->mtu = netif_get_mtu((ppp_pcb*)netif->state); netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; #if LWIP_NETIF_HOSTNAME /* @todo: Initialize interface hostname */ @@ -943,8 +906,9 @@ ppp_input_thread(void *arg) { int count; ppp_pcb_rx *pcrx = arg; + ppp_pcb *pcb = &ppp_pcb_list[pcrx->pd]; - while (phase != PHASE_DEAD) { + while (pcb->phase != PHASE_DEAD) { count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); if(count > 0) { pppos_input_proc(pcrx, pcrx->rxbuf, count); @@ -959,25 +923,25 @@ ppp_input_thread(void *arg) #if PPPOS_SUPPORT static void -pppos_put(ppp_pcb *pc, struct pbuf *nb) +pppos_put(ppp_pcb *pcb, struct pbuf *nb) { struct pbuf *b; int c; for(b = nb; b != NULL; b = b->next) { - if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) { + if((c = sio_write(pcb->fd, b->payload, b->len)) != b->len) { PPPDEBUG(LOG_WARNING, - ("PPP pppos_put: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); + ("PPP pppos_put: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pcb->fd, b->len, c, c)); LINK_STATS_INC(link.err); - pc->last_xmit = 0; /* prepend PPP_FLAG to next packet */ - snmp_inc_ifoutdiscards(&pc->netif); + pcb->last_xmit = 0; /* prepend PPP_FLAG to next packet */ + snmp_inc_ifoutdiscards(&pcb->netif); pbuf_free(nb); return; } } - snmp_add_ifoutoctets(&pc->netif, nb->tot_len); - snmp_inc_ifoutucastpkts(&pc->netif); + snmp_add_ifoutoctets(&pcb->netif, nb->tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); pbuf_free(nb); LINK_STATS_INC(link.xmit); } @@ -1025,8 +989,7 @@ ppp_append(u_char c, struct pbuf *nb, ext_accm *out_accm) * This is the low level function that send the PPP packet. */ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { - int pd = (int)(size_t)netif->state; - ppp_pcb *pc = &ppp_pcb_list[pd]; + ppp_pcb *pcb = (ppp_pcb*)netif->state; #if PPPOS_SUPPORT u_short protocol = PPP_IP; u_int fcs_out = PPP_INITFCS; @@ -1039,9 +1002,9 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i /* Validate parameters. */ /* We let any protocol value go through - it can't hurt us * and the peer will just drop it if it's not accepting it. */ - if (pd < 0 || pd >= NUM_PPP || !pc->open_flag || !pb) { + if (!pcb->open_flag || !pb) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad params prot=%d pb=%p\n", - pd, PPP_IP, (void*)pb)); + pcb->unit, PPP_IP, (void*)pb)); LINK_STATS_INC(link.opterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -1049,8 +1012,8 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i } /* Check that the link is up. */ - if (pc->phase == PHASE_DEAD) { - PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pd)); + if (pcb->phase == PHASE_DEAD) { + PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->unit)); LINK_STATS_INC(link.rterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -1058,8 +1021,8 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i } #if PPPOE_SUPPORT - if(pc->ethif) { - return ppp_netif_output_over_ethernet(pd, pb); + if(pcb->ethif) { + return ppp_netif_output_over_ethernet(pcb, pb); } #endif /* PPPOE_SUPPORT */ @@ -1067,7 +1030,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i /* Grab an output buffer. */ head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (head == NULL) { - PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: first alloc fail\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: first alloc fail\n", pcb->unit)); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -1079,8 +1042,8 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i * Attempt Van Jacobson header compression if VJ is configured and * this is an IP packet. */ - if (protocol == PPP_IP && pc->vj_enabled) { - switch (vj_compress_tcp(&pc->vj_comp, pb)) { + if (protocol == PPP_IP && pcb->vj_enabled) { + switch (vj_compress_tcp(&pcb->vj_comp, pb)) { case TYPE_IP: /* No change... protocol = PPP_IP_PROTOCOL; */ @@ -1092,7 +1055,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i protocol = PPP_VJC_UNCOMP; break; default: - PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->unit)); LINK_STATS_INC(link.proterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -1105,25 +1068,25 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i tail = head; /* Build the PPP header. */ - if ((sys_jiffies() - pc->last_xmit) >= PPP_MAXIDLEFLAG) { + if ((sys_jiffies() - pcb->last_xmit) >= PPP_MAXIDLEFLAG) { tail = ppp_append(PPP_FLAG, tail, NULL); } - pc->last_xmit = sys_jiffies(); - if (!pc->accomp) { + pcb->last_xmit = sys_jiffies(); + if (!pcb->accomp) { fcs_out = PPP_FCS(fcs_out, PPP_ALLSTATIONS); - tail = ppp_append(PPP_ALLSTATIONS, tail, &pc->out_accm); + tail = ppp_append(PPP_ALLSTATIONS, tail, &pcb->out_accm); fcs_out = PPP_FCS(fcs_out, PPP_UI); - tail = ppp_append(PPP_UI, tail, &pc->out_accm); + tail = ppp_append(PPP_UI, tail, &pcb->out_accm); } - if (!pc->pcomp || protocol > 0xFF) { + if (!pcb->pcomp || protocol > 0xFF) { c = (protocol >> 8) & 0xFF; fcs_out = PPP_FCS(fcs_out, c); - tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(c, tail, &pcb->out_accm); } c = protocol & 0xFF; fcs_out = PPP_FCS(fcs_out, c); - tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(c, tail, &pcb->out_accm); /* Load packet. */ for(p = pb; p; p = p->next) { @@ -1139,22 +1102,22 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i fcs_out = PPP_FCS(fcs_out, c); /* Copy to output buffer escaping special characters. */ - tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(c, tail, &pcb->out_accm); } } /* Add FCS and trailing flag. */ c = ~fcs_out & 0xFF; - tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(c, tail, &pcb->out_accm); c = (~fcs_out >> 8) & 0xFF; - tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(c, tail, &pcb->out_accm); tail = ppp_append(PPP_FLAG, tail, NULL); /* If we failed to complete the packet, throw it away. */ if (!tail) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: Alloc err - dropping proto=%d\n", - pd, protocol)); + pcb->unit, protocol)); pbuf_free(head); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); @@ -1163,17 +1126,16 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i } /* Send it. */ - PPPDEBUG(LOG_INFO, ("ppp_netif_output[%d]: proto=0x%"X16_F"\n", pd, protocol)); + PPPDEBUG(LOG_INFO, ("ppp_netif_output[%d]: proto=0x%"X16_F"\n", pcb->unit, protocol)); - pppos_put(pc, head); + pppos_put(pcb, head); #endif /* PPPOS_SUPPORT */ return ERR_OK; } #if PPPOE_SUPPORT -static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { - ppp_pcb *pc = &ppp_pcb_list[pd]; +static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { struct pbuf *pb; u_short protocol = PPP_IP; int i=0; @@ -1184,15 +1146,15 @@ static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { if(!pb) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); + snmp_inc_ifoutdiscards(&pcb->netif); return ERR_MEM; } pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - pc->last_xmit = sys_jiffies(); + pcb->last_xmit = sys_jiffies(); - if (!pc->pcomp || protocol > 0xFF) { + if (!pcb->pcomp || protocol > 0xFF) { *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; } *((u_char*)pb->payload + i) = protocol & 0xFF; @@ -1200,14 +1162,14 @@ static err_t ppp_netif_output_over_ethernet(int pd, struct pbuf *p) { pbuf_chain(pb, p); tot_len = pb->tot_len; - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + if(pppoe_xmit(pcb->pppoe_sc, pb) != ERR_OK) { LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); + snmp_inc_ifoutdiscards(&pcb->netif); return PPPERR_DEVICE; } - snmp_add_ifoutoctets(&pc->netif, tot_len); - snmp_inc_ifoutucastpkts(&pc->netif); + snmp_add_ifoutoctets(&pcb->netif, tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); LINK_STATS_INC(link.xmit); return ERR_OK; } @@ -1269,8 +1231,7 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) * RETURN: >= 0 Number of characters written * -1 Failed to write to device */ -int ppp_write(int pd, const u_char *s, int n) { - ppp_pcb *pc = &ppp_pcb_list[pd]; +int ppp_write(ppp_pcb *pcb, const u_char *s, int n) { #if PPPOS_SUPPORT u_char c; u_int fcs_out; @@ -1278,8 +1239,8 @@ int ppp_write(int pd, const u_char *s, int n) { #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT - if(pc->ethif) { - return ppp_write_over_ethernet(pd, s, n); + if(pcb->ethif) { + return ppp_write_over_ethernet(pcb, s, n); } #endif /* PPPOE_SUPPORT */ @@ -1288,7 +1249,7 @@ int ppp_write(int pd, const u_char *s, int n) { if (head == NULL) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); + snmp_inc_ifoutdiscards(&pcb->netif); return PPPERR_ALLOC; } @@ -1296,10 +1257,10 @@ int ppp_write(int pd, const u_char *s, int n) { /* If the link has been idle, we'll send a fresh flag character to * flush any noise. */ - if ((sys_jiffies() - pc->last_xmit) >= PPP_MAXIDLEFLAG) { + if ((sys_jiffies() - pcb->last_xmit) >= PPP_MAXIDLEFLAG) { tail = ppp_append(PPP_FLAG, tail, NULL); } - pc->last_xmit = sys_jiffies(); + pcb->last_xmit = sys_jiffies(); fcs_out = PPP_INITFCS; /* Load output buffer. */ @@ -1310,40 +1271,39 @@ int ppp_write(int pd, const u_char *s, int n) { fcs_out = PPP_FCS(fcs_out, c); /* Copy to output buffer escaping special characters. */ - tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(c, tail, &pcb->out_accm); } /* Add FCS and trailing flag. */ c = ~fcs_out & 0xFF; - tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(c, tail, &pcb->out_accm); c = (~fcs_out >> 8) & 0xFF; - tail = ppp_append(c, tail, &pc->out_accm); + tail = ppp_append(c, tail, &pcb->out_accm); tail = ppp_append(PPP_FLAG, tail, NULL); /* If we failed to complete the packet, throw it away. * Otherwise send it. */ if (!tail) { PPPDEBUG(LOG_WARNING, - ("ppp_write[%d]: Alloc err - dropping pbuf len=%d\n", pd, head->len)); + ("ppp_write[%d]: Alloc err - dropping pbuf len=%d\n", pcb->unit, head->len)); /*"ppp_write[%d]: Alloc err - dropping %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ pbuf_free(head); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); + snmp_inc_ifoutdiscards(&pcb->netif); return PPPERR_ALLOC; } - PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pd, head->len)); + PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pcb->unit, head->len)); /* "ppp_write[%d]: %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ - pppos_put(pc, head); + pppos_put(pcb, head); #endif /* PPPOS_SUPPORT */ return PPPERR_NONE; } #if PPPOE_SUPPORT -static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { - ppp_pcb *pc = &ppp_pcb_list[pd]; +static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n) { struct pbuf *pb; /* skip address & flags */ @@ -1355,19 +1315,19 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { if(!pb) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); - snmp_inc_ifoutdiscards(&pc->netif); + snmp_inc_ifoutdiscards(&pcb->netif); return PPPERR_ALLOC; } pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); - pc->last_xmit = sys_jiffies(); + pcb->last_xmit = sys_jiffies(); MEMCPY(pb->payload, s, n); - if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + if(pppoe_xmit(pcb->pppoe_sc, pb) != ERR_OK) { LINK_STATS_INC(link.err); - snmp_inc_ifoutdiscards(&pc->netif); + snmp_inc_ifoutdiscards(&pcb->netif); return PPPERR_DEVICE; } @@ -1375,8 +1335,8 @@ static int ppp_write_over_ethernet(int pd, const u_char *s, int n) { dump_packet("sent", (unsigned char *)s, n); #endif /* PRINTPKT_SUPPORT */ - snmp_add_ifoutoctets(&pc->netif, (u16_t)n); - snmp_inc_ifoutucastpkts(&pc->netif); + snmp_add_ifoutoctets(&pcb->netif, (u16_t)n); + snmp_inc_ifoutucastpkts(&pcb->netif); LINK_STATS_INC(link.xmit); return PPPERR_NONE; } @@ -1711,36 +1671,34 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { } #endif /* PPPOE_SUPPORT */ -void ppp_link_down(int pd) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pd)); +void ppp_link_down(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pcb->unit)); #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD - ppp_receive_wakeup(pd); + ppp_receive_wakeup(pcb); #endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ } -void ppp_link_terminated(int pd) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d\n", pd)); +void ppp_link_terminated(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d\n", pcb->unit)); #if PPPOE_SUPPORT - if (ppp_pcb_list[pd].ethif) { - pppoe_disconnect(ppp_pcb_list[pd].pppoe_sc); + if (pcb->ethif) { + pppoe_disconnect(pcb->pppoe_sc); } else #endif /* PPPOE_SUPPORT */ { #if PPPOS_SUPPORT - ppp_pcb* pc; #if PPP_INPROC_OWNTHREAD - ppp_receive_wakeup(pd); + ppp_receive_wakeup(pcb); #endif /* PPP_INPROC_OWNTHREAD */ - pc = &ppp_pcb_list[pd]; - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pd, pc->link_status_cb, pc->err_code)); - if (pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, pc->err_code ? pc->err_code : PPPERR_PROTOCOL, NULL); + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pcb->unit, pcb->link_status_cb, pcb->err_code)); + if (pcb->link_status_cb) { + pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, NULL); } - pc->open_flag = 0;/**/ + pcb->open_flag = 0; #endif /* PPPOS_SUPPORT */ } PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: finished.\n")); @@ -1785,9 +1743,8 @@ ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) /* * new_phase - signal the start of a new phase of pppd's operation. */ -void new_phase(int unit, int p) { - ppp_pcb *pc = &ppp_pcb_list[unit]; - pc->phase = p; +void new_phase(ppp_pcb *pcb, int p) { + pcb->phase = p; #if PPP_NOTIFY /* The one willing notify support should add here the code to be notified of phase changes */ #endif /* PPP_NOTIFY */ @@ -1797,20 +1754,19 @@ void new_phase(int unit, int p) { * ppp_send_config - configure the transmit-side characteristics of * the ppp interface. */ -int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { - ppp_pcb *pc = &ppp_pcb_list[unit]; +int ppp_send_config(ppp_pcb *pcb, int mtu, u_int32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT int i; #endif /* PPPOS_SUPPORT */ - /* pc->mtu = mtu; -- set correctly with netif_set_mtu */ - pc->pcomp = pcomp; - pc->accomp = accomp; + /* pcb->mtu = mtu; -- set correctly with netif_set_mtu */ + pcb->pcomp = pcomp; + pcb->accomp = accomp; #if PPPOS_SUPPORT /* Load the ACCM bits for the 32 control codes. */ for (i = 0; i < 32/8; i++) { - pc->out_accm[i] = (u_char)((accm >> (8 * i)) & 0xFF); + pcb->out_accm[i] = (u_char)((accm >> (8 * i)) & 0xFF); } #else LWIP_UNUSED_ARG(accm); @@ -1818,10 +1774,10 @@ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: out_accm=%X %X %X %X\n", - unit, - pc->out_accm[0], pc->out_accm[1], pc->out_accm[2], pc->out_accm[3])); + pcb->unit, + pcb->out_accm[0], pcb->out_accm[1], pcb->out_accm[2], pcb->out_accm[3])); #else - PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", unit) ); + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->unit) ); #endif /* PPPOS_SUPPORT */ return 0; } @@ -1830,9 +1786,8 @@ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { * ppp_recv_config - configure the receive-side characteristics of * the ppp interface. */ -int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { +int ppp_recv_config(ppp_pcb *pcb, int mru, u_int32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT - ppp_pcb *pc = &ppp_pcb_list[unit]; int i; SYS_ARCH_DECL_PROTECT(lev); #endif /* PPPOS_SUPPORT */ @@ -1846,7 +1801,7 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { SYS_ARCH_PROTECT(lev); for (i = 0; i < 32 / 8; i++) { /* @todo: does this work? ext_accm has been modified from pppd! */ - pc->rx.in_accm[i] = (u_char)(accm >> (i * 8)); + pcb->rx.in_accm[i] = (u_char)(accm >> (i * 8)); } SYS_ARCH_UNPROTECT(lev); #else @@ -1855,10 +1810,10 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: in_accm=%X %X %X %X\n", - unit, - pc->rx.in_accm[0], pc->rx.in_accm[1], pc->rx.in_accm[2], pc->rx.in_accm[3])); + pcb->unit, + pcb->rx.in_accm[0], pcb->rx.in_accm[1], pcb->rx.in_accm[2], pcb->rx.in_accm[3])); #else - PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", unit) ); + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->unit) ); #endif /* PPPOS_SUPPORT */ return 0; } @@ -1867,20 +1822,18 @@ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { /* * sifaddr - Config the interface IP addresses and netmask. */ -int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, +int sifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask) { - ppp_pcb *pc = &ppp_pcb_list[unit]; - int st = 1; - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifaddr[%d]: bad params\n", unit)); - } else { - SMEMCPY(&pc->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); - SMEMCPY(&pc->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); - SMEMCPY(&pc->addrs.netmask, &net_mask, sizeof(net_mask)); + if(!pcb->open_flag) { + PPPDEBUG(LOG_WARNING, ("sifaddr[%d]: bad params\n", pcb->unit)); + return 0; } - return st; + + SMEMCPY(&pcb->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); + SMEMCPY(&pcb->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); + SMEMCPY(&pcb->addrs.netmask, &net_mask, sizeof(net_mask)); + return 1; } @@ -1889,39 +1842,36 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */ -int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { - ppp_pcb *pc = &ppp_pcb_list[unit]; - int st = 1; +int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr) { LWIP_UNUSED_ARG(our_adr); LWIP_UNUSED_ARG(his_adr); - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad params\n", unit)); - } else { - IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); - IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); - IP4_ADDR(&pc->addrs.netmask, 255,255,255,255); + + if(!pcb->open_flag) { + PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad params\n", pcb->unit)); + return 0; } - return st; + + IP4_ADDR(&pcb->addrs.our_ipaddr, 0,0,0,0); + IP4_ADDR(&pcb->addrs.his_ipaddr, 0,0,0,0); + IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); + return 1; } /* * sdns - Config the DNS servers */ -int sdns (int unit, u_int32_t ns1, u_int32_t ns2) { - ppp_pcb *pc = &ppp_pcb_list[unit]; - int st = 1; +int sdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sdns[%d]: bad params\n", unit)); - } else { - SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); - SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); + if(!pcb->open_flag) { + PPPDEBUG(LOG_WARNING, ("sdns[%d]: bad params\n", pcb->unit)); + return 0; } - return st; + + SMEMCPY(&pcb->addrs.dns1, &ns1, sizeof(ns1)); + SMEMCPY(&pcb->addrs.dns2, &ns2, sizeof(ns2)); + return 1; } @@ -1929,53 +1879,48 @@ int sdns (int unit, u_int32_t ns1, u_int32_t ns2) { * * cdns - Clear the DNS servers */ -int cdns (int unit, u_int32_t ns1, u_int32_t ns2) { - ppp_pcb *pc = &ppp_pcb_list[unit]; - int st = 1; +int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { LWIP_UNUSED_ARG(ns1); LWIP_UNUSED_ARG(ns2); - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("cdns[%d]: bad params\n", unit)); - } else { - IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); - IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); + + if(!pcb->open_flag) { + PPPDEBUG(LOG_WARNING, ("cdns[%d]: bad params\n", pcb->unit)); + return 0; } - return st; + + IP4_ADDR(&pcb->addrs.dns1, 0,0,0,0); + IP4_ADDR(&pcb->addrs.dns2, 0,0,0,0); + return 1; } /* * sifup - Config the interface up and enable IP packets to pass. */ -int sifup(int u) -{ - ppp_pcb *pc = &ppp_pcb_list[u]; - int st = 1; +int sifup(ppp_pcb *pcb) { - if (u < 0 || u >= NUM_PPP || !pc->open_flag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad params\n", u)); - } else { - netif_remove(&pc->netif); - if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, - &pc->addrs.his_ipaddr, (void *)(size_t)u, ppp_netif_init_cb, ip_input)) { - netif_set_up(&pc->netif); - pc->if_up = 1; - pc->err_code = PPPERR_NONE; - - PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p err_code=%d\n", u, pc->link_status_cb, pc->err_code)); - if (pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, pc->err_code, &pc->addrs); - } - } else { - st = 0; - PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", u)); - } + if(!pcb->open_flag) { + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad params\n", pcb->unit)); + return 0; } - return st; + netif_remove(&pcb->netif); + if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, ip_input)) { + PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pcb->unit)); + return 0; + } + + netif_set_up(&pcb->netif); + pcb->if_up = 1; + pcb->err_code = PPPERR_NONE; + + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p err_code=%d\n", pcb->unit, pcb->link_status_cb, pcb->err_code)); + if (pcb->link_status_cb) + pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code, &pcb->addrs); + + return 1; } /******************************************************************** @@ -1983,31 +1928,29 @@ int sifup(int u) * sifdown - Disable the indicated protocol and config the interface * down if there are no remaining protocols. */ -int sifdown(int unit) { - ppp_pcb *pc = &ppp_pcb_list[unit]; - int st = 1; +int sifdown(ppp_pcb *pcb) { - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad params\n", unit)); - } else { - pc->if_up = 0; - /* make sure the netif status callback is called */ - netif_set_down(&pc->netif); - netif_remove(&pc->netif); - PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p err_code=%d\n", unit, pc->link_status_cb, pc->err_code)); - if (pc->link_status_cb) { - pc->link_status_cb(pc->link_status_ctx, PPPERR_CONNECT, NULL); - } + if(!pcb->open_flag) { + PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad params\n", pcb->unit)); + return 0; } - return st; + + pcb->if_up = 0; + /* make sure the netif status callback is called */ + netif_set_down(&pcb->netif); + netif_remove(&pcb->netif); + PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p err_code=%d\n", pcb->unit, pcb->link_status_cb, pcb->err_code)); + if (pcb->link_status_cb) + pcb->link_status_cb(pcb->link_status_ctx, PPPERR_CONNECT, NULL); + + return 1; } /* * sifnpmode - Set the mode for handling packets for a given NP. */ -int sifnpmode(int u, int proto, enum NPmode mode) { - LWIP_UNUSED_ARG(u); +int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) { + LWIP_UNUSED_ARG(pcb); LWIP_UNUSED_ARG(proto); LWIP_UNUSED_ARG(mode); return 0; @@ -2016,27 +1959,25 @@ int sifnpmode(int u, int proto, enum NPmode mode) { /* * netif_set_mtu - set the MTU on the PPP network interface. */ -void netif_set_mtu(int unit, int mtu) { - ppp_pcb *pc = &ppp_pcb_list[unit]; +void netif_set_mtu(ppp_pcb *pcb, int mtu) { /* Validate parameters. */ - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) + if(!pcb->open_flag) return; - pc->mtu = mtu; + pcb->mtu = mtu; } /* * netif_get_mtu - get PPP interface MTU */ -int netif_get_mtu(int unit) { - ppp_pcb *pc = &ppp_pcb_list[unit]; +int netif_get_mtu(ppp_pcb *pcb) { /* Validate parameters. */ - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) - return 0; + if(!pcb->open_flag) + return 0; - return pc->mtu; + return pcb->mtu; } /******************************************************************** @@ -2051,45 +1992,37 @@ int netif_get_mtu(int unit) { * and then changes the temporary addresses to the addresses for the real * ppp connection when it has come up. */ -int sifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { - ppp_pcb *pc = &ppp_pcb_list[unit]; - int st = 1; +int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, bool replace) { LWIP_UNUSED_ARG(ouraddr); LWIP_UNUSED_ARG(gateway); LWIP_UNUSED_ARG(replace); - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("sifdefaultroute[%d]: bad params\n", unit)); - } else { - netif_set_default(&pc->netif); + if(!pcb->open_flag) { + PPPDEBUG(LOG_WARNING, ("sifdefaultroute[%d]: bad params\n", pcb->unit)); + return 0; } - /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */ - - return st; + netif_set_default(&pcb->netif); + return 1; } /******************************************************************** * * cifdefaultroute - delete a default route through the address given. */ -int cifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway) { - ppp_pcb *pc = &ppp_pcb_list[unit]; - int st = 1; +int cifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway) { LWIP_UNUSED_ARG(ouraddr); LWIP_UNUSED_ARG(gateway); - if (unit < 0 || unit >= NUM_PPP || !pc->open_flag) { - st = 0; - PPPDEBUG(LOG_WARNING, ("cifdefaultroute[%d]: bad params\n", unit)); - } else { - netif_set_default(NULL); + if(!pcb->open_flag) { + PPPDEBUG(LOG_WARNING, ("cifdefaultroute[%d]: bad params\n", pcb->unit)); + return 0; } - return st; + netif_set_default(NULL); + return 1; } /******************************************************************** @@ -2097,9 +2030,11 @@ int cifdefaultroute(int unit, u_int32_t ouraddr, u_int32_t gateway) { * sifproxyarp - Make a proxy ARP entry for the peer. */ -int sifproxyarp(int unit, u_int32_t his_adr) { - /* FIXME: do we really need that in IPCP ? */ - return 0; +int sifproxyarp(ppp_pcb *pcb, u_int32_t his_adr) { + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(his_adr); + /* FIXME: do we really need that in IPCP ? */ + return 0; } /******************************************************************** @@ -2107,26 +2042,27 @@ int sifproxyarp(int unit, u_int32_t his_adr) { * cifproxyarp - Delete the proxy ARP entry for the peer. */ -int cifproxyarp(int unit, u_int32_t his_adr) { - /* FIXME: do we really need that in IPCP ? */ - return 0; +int cifproxyarp(ppp_pcb *pcb, u_int32_t his_adr) { + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(his_adr); + /* FIXME: do we really need that in IPCP ? */ + return 0; } /******************************************************************** * * sifvjcomp - config tcp header compression */ -int sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid) { -#if PPPOS_SUPPORT && VJ_SUPPORT - ppp_pcb *pc = &ppp_pcb_list[u]; +int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) { - pc->vj_enabled = vjcomp; - pc->vj_comp.compressSlot = cidcomp; - pc->vj_comp.maxSlotIndex = maxcid; +#if PPPOS_SUPPORT && VJ_SUPPORT + pcb->vj_enabled = vjcomp; + pcb->vj_comp.compressSlot = cidcomp; + pcb->vj_comp.maxSlotIndex = maxcid; PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", vjcomp, cidcomp, maxcid)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ - LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(pcb); LWIP_UNUSED_ARG(vjcomp); LWIP_UNUSED_ARG(cidcomp); LWIP_UNUSED_ARG(maxcid); @@ -2139,9 +2075,9 @@ int sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid) { * * get_idle_time - return how long the link has been idle. */ -int get_idle_time(int u, struct ppp_idle *ip) { +int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) { /* FIXME: add idle time support and make it optional */ - LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(pcb); LWIP_UNUSED_ARG(ip); return 1; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index c2339d02..27a82b6f 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -45,6 +45,35 @@ #include "lwip/sys.h" #include "lwip/timers.h" +#include "vj.h" + + +/** PPP_INPROC_MULTITHREADED==1 call ppp_input using tcpip_callback(). + * Set this to 0 if pppos_input_proc is called inside tcpip_thread or with NO_SYS==1. + * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). + */ +#ifndef PPP_INPROC_MULTITHREADED +#define PPP_INPROC_MULTITHREADED (NO_SYS==0) +#endif + +/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session. + * Default is 0: call pppos_input() for received raw characters, character + * reception is up to the port */ +#ifndef PPP_INPROC_OWNTHREAD +#define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED +#endif + +#if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED + #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1" +#endif + +#if PPPOS_SUPPORT +/** RX buffer size: this may be configured smaller! */ +#ifndef PPPOS_RX_BUFSIZE +#define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN) +#endif +#endif /* PPPOS_SUPPORT */ + #ifndef __u_char_defined @@ -61,6 +90,12 @@ typedef unsigned char u_char; *** PUBLIC DEFINITIONS *** *************************/ +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ + /* Error codes. */ #define PPPERR_NONE 0 /* No error. */ #define PPPERR_PARAM -1 /* Invalid parameter. */ @@ -135,7 +170,25 @@ struct ppp_addrs { ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; }; +/* FIXME: find a way to move ppp_dev_states and ppp_pcb_rx_s to ppp_impl.h */ #if PPPOS_SUPPORT +/* + * Extended asyncmap - allows any character to be escaped. + */ +typedef u_char ext_accm[32]; + +/* PPP packet parser states. Current state indicates operation yet to be + * completed. */ +typedef enum { + PDIDLE = 0, /* Idle state - waiting. */ + PDSTART, /* Process start flag. */ + PDADDRESS, /* Process address field. */ + PDCONTROL, /* Process control field. */ + PDPROTOCOL1, /* Process protocol field 1. */ + PDPROTOCOL2, /* Process protocol field 2. */ + PDDATA /* Process data byte. */ +} ppp_dev_states; + /* * PPP interface RX control block. */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index f84690b2..d10af710 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -69,9 +69,6 @@ typedef unsigned char bool; /* * The basic PPP frame. */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - #define PPP_ADDRESS(p) (((u_char *)(p))[0]) #define PPP_CONTROL(p) (((u_char *)(p))[1]) #define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) @@ -155,11 +152,6 @@ typedef unsigned short u_int16_t; #endif #endif -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u_char ext_accm[32]; - /* * What to do with network protocol (NP) packets. */ @@ -312,7 +304,7 @@ struct protent { */ /* Process a received data packet */ void (*datainput) (int unit, u_char *pkt, int len); - bool enabled_flag; /* 0 iff protocol is disabled */ + bool enabled_flag; /* 0 if protocol is disabled */ #if PRINTPKT_SUPPORT char *name; /* Text name of protocol */ char *data_name; /* Text name of corresponding data protocol */ @@ -396,17 +388,16 @@ ppp_pcb ppp_pcb_list[NUM_PPP]; /* The PPP interface control blocks. */ /* PPP flow functions */ #if PPPOE_SUPPORT -void ppp_over_ethernet_init_failed(int pd); /* function called by pppoe.c */ void ppp_input_over_ethernet(ppp_pcb *pcb, struct pbuf *pb); #endif /* PPPOE_SUPPORT */ /* function called by all PPP subsystems to send packets */ -int ppp_write(int pd, const u_char *s, int n); +int ppp_write(ppp_pcb *pcb, const u_char *s, int n); /* functions called by auth.c link_terminated() */ -void ppp_link_down(int pd); -void ppp_link_terminated(int pd); +void ppp_link_down(ppp_pcb *pcb); +void ppp_link_terminated(ppp_pcb *pcb); /* merge a pbuf chain into one pbuf */ struct pbuf * ppp_singlebuf(struct pbuf *p); @@ -415,37 +406,37 @@ struct pbuf * ppp_singlebuf(struct pbuf *p); /* Functions called by various PPP subsystems to configure * the PPP interface or change the PPP phase. */ -void new_phase(int unit, int p); +void new_phase(ppp_pcb *pcb, int p); #if PPPOS_SUPPORT -void ppp_set_xaccm(int unit, ext_accm *accm); +void ppp_set_xaccm(ppp_pcb *pcb, ext_accm *accm); #endif /* PPPOS_SUPPORT */ -int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp); -int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp); +int ppp_send_config(ppp_pcb *pcb, int mtu, u_int32_t accm, int pcomp, int accomp); +int ppp_recv_config(ppp_pcb *pcb, int mru, u_int32_t accm, int pcomp, int accomp); -int sifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); -int cifaddr(int unit, u_int32_t our_adr, u_int32_t his_adr); +int sifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); +int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr); -int sdns(int unit, u_int32_t ns1, u_int32_t ns2); -int cdns(int unit, u_int32_t ns1, u_int32_t ns2); +int sdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2); +int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2); -int sifup(int u); -int sifdown (int u); +int sifup(ppp_pcb *pcb); +int sifdown (ppp_pcb *pcb); -int sifnpmode(int u, int proto, enum NPmode mode); +int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode); -void netif_set_mtu(int unit, int mtu); -int netif_get_mtu(int unit); +void netif_set_mtu(ppp_pcb *pcb, int mtu); +int netif_get_mtu(ppp_pcb *pcb); -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace); -int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway); +int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, bool replace); +int cifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway); -int sifproxyarp (int unit, u_int32_t his_adr); -int cifproxyarp (int unit, u_int32_t his_adr); +int sifproxyarp(ppp_pcb *pcb, u_int32_t his_adr); +int cifproxyarp(ppp_pcb *pcb, u_int32_t his_adr); -int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid); +int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid); -int get_idle_time(int u, struct ppp_idle *ip); +int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip); int get_loop_output(void); diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index cd8d2c2b..8f471920 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -584,6 +584,7 @@ static void upap_sauthreq(u) upap_state *u; { + ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; u_char *outp; int outlen; @@ -602,7 +603,7 @@ upap_sauthreq(u) PUTCHAR(u->us_passwdlen, outp); MEMCPY(outp, u->us_passwd, u->us_passwdlen); - ppp_write(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); TIMEOUT(upap_timeout, u, u->us_timeouttime); ++u->us_transmits; @@ -620,6 +621,7 @@ upap_sresp(u, code, id, msg, msglen) char *msg; int msglen; { + ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; u_char *outp; int outlen; @@ -632,7 +634,7 @@ upap_sresp(u, code, id, msg, msglen) PUTSHORT(outlen, outp); PUTCHAR(msglen, outp); MEMCPY(outp, msg, msglen); - ppp_write(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); } #endif /* UNUSED */ From 527d99fd39c249f8142763ddfbffad8b94697834 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 12 Jun 2012 00:55:53 +0200 Subject: [PATCH 156/320] removed all PPP unit in ppp.c except pih->unit and unit used in debugging output --- src/netif/ppp/auth.c | 4 +- src/netif/ppp/ppp.c | 135 +++++++++++++++++++++---------------------- 2 files changed, 69 insertions(+), 70 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 694283e6..07adc9a1 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -656,7 +656,7 @@ link_terminated(unit) lcp_lowerdown(0); - new_phase(unit, PHASE_DEAD); + new_phase(pcb, PHASE_DEAD); ppp_link_terminated(pcb); #if 0 /* @@ -873,7 +873,9 @@ static void network_phase(unit) int unit; { +#if CBCP_SUPPORT ppp_pcb *pcb = &ppp_pcb_list[unit]; +#endif #if 0 /* UNUSED */ lcp_options *go = &lcp_gotoptions[unit]; #endif /* UNUSED */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index e4851095..ec727508 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -187,15 +187,15 @@ struct protent *protocols[] = { /* Prototypes for procedures local to this file. */ -static void ppp_start(int pd); /** Initiate LCP open request */ -static void ppp_input(int unit, void *arg); +static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ +static void ppp_input(void *arg); #if PPPOS_SUPPORT static void ppp_receive_wakeup(ppp_pcb *pcb); #endif /* #if PPPOS_SUPPORT */ -static void ppp_stop(int pd); -static void ppp_hup(int pd); +static void ppp_stop(ppp_pcb *pcb); +static void ppp_hup(ppp_pcb *pcb); #if PPPOS_SUPPORT #if PPP_INPROC_OWNTHREAD @@ -375,7 +375,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s * Start the connection and handle incoming events (packet or timeout). */ PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->unit)); - ppp_start(pcb->unit); + ppp_start(pcb); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); #endif /* PPP_INPROC_OWNTHREAD */ @@ -454,7 +454,7 @@ ppp_close(ppp_pcb *pcb) PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->unit)); pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ - ppp_stop(pcb->unit); + ppp_stop(pcb); } else #endif /* PPPOE_SUPPORT */ { @@ -462,7 +462,7 @@ ppp_close(ppp_pcb *pcb) PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->unit)); pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ - ppp_stop(pcb->unit); + ppp_stop(pcb); #if PPP_INPROC_OWNTHREAD ppp_receive_wakeup(pcb); #endif /* PPP_INPROC_OWNTHREAD */ @@ -477,35 +477,31 @@ void ppp_sighup(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hup\n", pcb->unit)); - ppp_hup(pcb->unit); + ppp_hup(pcb); } /** Initiate LCP open request */ -static void ppp_start(int pd) { - PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pd)); - lcp_open(pd); /* Start protocol */ - lcp_lowerup(pd); +static void ppp_start(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->unit)); + lcp_open(pcb->unit); /* Start protocol */ + lcp_lowerup(pcb->unit); PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); } /** LCP close request */ -static void -ppp_stop(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("ppp_stop: unit %d\n", pd)); - lcp_close(pd, "User request"); +static void ppp_stop(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_stop: unit %d\n", pcb->unit)); + lcp_close(pcb->unit, "User request"); } /** Called when carrier/link is lost */ -static void -ppp_hup(int pd) -{ - PPPDEBUG(LOG_DEBUG, ("ppp_hup: unit %d\n", pd)); - lcp_lowerdown(pd); - link_terminated(pd); +static void ppp_hup(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_hup: unit %d\n", pcb->unit)); + lcp_lowerdown(pcb->unit); + link_terminated(pcb->unit); } /* @@ -517,13 +513,14 @@ ppp_hup(int pd) * this is totally stupid to make room for it and then modify the packet directly * or it is used in output ? have to find out... */ -static void ppp_input(int unit, void *arg) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ppp_input(void *arg) { struct pbuf *nb = (struct pbuf *)arg; u16_t protocol; - int pd; + int unit; + ppp_pcb *pcb; - pd = ((struct ppp_input_header *)nb->payload)->unit; + unit = ((struct ppp_input_header *)nb->payload)->unit; + pcb = &ppp_pcb_list[unit]; protocol = ((struct ppp_input_header *)nb->payload)->proto; if(pbuf_header(nb, -(int)sizeof(struct ppp_input_header))) { @@ -532,8 +529,8 @@ static void ppp_input(int unit, void *arg) { } LINK_STATS_INC(link.recv); - snmp_inc_ifinucastpkts(&ppp_pcb_list[pd].netif); - snmp_add_ifinoctets(&ppp_pcb_list[pd].netif, nb->tot_len); + snmp_inc_ifinucastpkts(&pcb->netif); + snmp_add_ifinoctets(&pcb->netif, nb->tot_len); /* * Toss all non-LCP packets unless LCP is OPEN. @@ -573,38 +570,38 @@ static void ppp_input(int unit, void *arg) { #if PPPOS_SUPPORT && VJ_SUPPORT case PPP_VJC_COMP: /* VJ compressed TCP */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->unit, nb->len)); /* * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, &ppp_pcb_list[pd].vj_comp) >= 0) && (ppp_pcb_list[pd].netif.input)) { - ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); + if ((vj_uncompress_tcp(&nb, pcb->vj_comp) >= 0) && (pcb->netif.input)) { + pcb->netif.input(nb, &pcb->netif); return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->unit)); break; case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->unit, nb->len)); /* * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, &ppp_pcb_list[pd].vj_comp) >= 0) && ppp_pcb_list[pd].netif.input) { - ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); + if ((vj_uncompress_uncomp(nb, pcb->vj_comp) >= 0) && pcb->netif.input) { + pcb->netif.input(nb, &pcb->netif); return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->unit)); break; #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (ppp_pcb_list[pd].netif.input) { - ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->unit, nb->len)); + if (pcb->netif.input) { + pcb->netif.input(nb, &pcb->netif); return; } break; @@ -619,7 +616,7 @@ static void ppp_input(int unit, void *arg) { for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { nb = ppp_singlebuf(nb); - (*protp->input)(pd, nb->payload, nb->len); + (*protp->input)(pcb->unit, nb->payload, nb->len); goto out; } #if 0 /* UNUSED @@ -633,7 +630,7 @@ static void ppp_input(int unit, void *arg) { */ if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag && protp->datainput != NULL) { - (*protp->datainput)(pd, nb->payload, nb->len); + (*protp->datainput)(pcb->unit, nb->payload, nb->len); goto out; } #endif /* UNUSED */ @@ -652,14 +649,14 @@ static void ppp_input(int unit, void *arg) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } - lcp_sprotrej(pd, nb->payload, nb->len); + lcp_sprotrej(pcb->unit, nb->payload, nb->len); } break; } drop: LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&ppp_pcb_list[pd].netif); + snmp_inc_ifindiscards(&pcb->netif); out: pbuf_free(nb); @@ -671,10 +668,10 @@ out: * Until we get past the authentication phase, toss all packets * except LCP, LQR and authentication packets. */ - if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { + if((lcp_phase[pcb->unit] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || - (lcp_phase[pd] != PHASE_AUTHENTICATE)) { - PPPDEBUG(LOG_INFO, ("ppp_input: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); + (lcp_phase[pcb->unit] != PHASE_AUTHENTICATE)) { + PPPDEBUG(LOG_INFO, ("ppp_input: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pcb->unit])); goto drop; } } @@ -682,48 +679,48 @@ out: switch(protocol) { case PPP_VJC_COMP: /* VJ compressed TCP */ #if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->unit, nb->len)); /* * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, &ppp_pcb_list[pd].vj_comp) >= 0) && (ppp_pcb_list[pd].netif.input)) { - ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); + if ((vj_uncompress_tcp(&nb, pcb->vj_comp) >= 0) && (pcb->netif.input)) { + pcb->netif.input(nb, pcb->netif); return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->unit)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: drop VJ Comp in %d:%s\n", pcb->unit, nb->len, nb->payload)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ #if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->unit, nb->len)); /* * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, &ppp_pcb_list[pd].vj_comp) >= 0) && ppp_pcb_list[pd].netif.input) { - ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); + if ((vj_uncompress_uncomp(nb, pcb->vj_comp) >= 0) && pcb->netif.input) { + pcb->netif.input(nb, pcb->netif); return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pd)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->unit)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ /* No handler for this protocol so drop the packet. */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: drop VJ UnComp in %d:.*H\n", - pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); + pcb->unit, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pd, nb->len)); - if (ppp_pcb_list[pd].netif.input) { - ppp_pcb_list[pd].netif.input(nb, &ppp_pcb_list[pd].netif); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->unit, nb->len)); + if (pcb->netif.input) { + pcb->netif.input(nb, pcb->netif); return; } break; @@ -737,16 +734,16 @@ out: */ for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: %s len=%d\n", pd, protp->name, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: %s len=%d\n", pcb->unit, protp->name, nb->len)); nb = ppp_singlebuf(nb); - (*protp->input)(pd, nb->payload, nb->len); - PPPDEBUG(LOG_DETAIL, ("ppp_input[%d]: packet processed\n", pd)); + (*protp->input)(pcb->unit, nb->payload, nb->len); + PPPDEBUG(LOG_DETAIL, ("ppp_input[%d]: packet processed\n", pcb->unit)); goto out; } } /* No handler for this protocol so reject the packet. */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pcb->unit, protocol, nb->len)); if (pbuf_header(nb, sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; @@ -755,7 +752,7 @@ out: protocol = htons(protocol); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ SMEMCPY(nb->payload, &protocol, sizeof(protocol)); - lcp_sprotrej(pd, nb->payload, nb->len); + lcp_sprotrej(pcb->unit, nb->payload, nb->len); } break; } @@ -866,7 +863,7 @@ void ppp_input_over_ethernet(ppp_pcb *pcb, struct pbuf *pb) { pih->proto = in_protocol; /* pih->proto is now in host byte order */ /* Dispatch the packet thereby consuming it. */ - ppp_input(pcb->unit, pb); + ppp_input(pb); return; drop: @@ -1638,7 +1635,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { /* PPPoE link is established, starting PPP negotiation */ case PPPOE_CB_STATE_UP: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pcb->unit)); - ppp_start(pcb->unit); + ppp_start(pcb); return; /* PPPoE link normally down (i.e. asked to do so) */ @@ -1662,8 +1659,8 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { return; } - ppp_hup(pcb->unit); - ppp_stop(pcb->unit); + ppp_hup(pcb); + ppp_stop(pcb); pppoe_destroy(&pcb->netif); pcb->open_flag = 0; if(pcb->link_status_cb) From a87096cdc9e7324f1d87c1ebb626350127d0a7e5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 12 Jun 2012 00:59:02 +0200 Subject: [PATCH 157/320] fixed PPPoS support, improved ppp_input() --- src/netif/ppp/ppp.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index ec727508..c377e931 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -516,11 +516,9 @@ static void ppp_hup(ppp_pcb *pcb) { static void ppp_input(void *arg) { struct pbuf *nb = (struct pbuf *)arg; u16_t protocol; - int unit; ppp_pcb *pcb; - unit = ((struct ppp_input_header *)nb->payload)->unit; - pcb = &ppp_pcb_list[unit]; + pcb = &ppp_pcb_list[((struct ppp_input_header *)nb->payload)->unit]; protocol = ((struct ppp_input_header *)nb->payload)->proto; if(pbuf_header(nb, -(int)sizeof(struct ppp_input_header))) { @@ -575,7 +573,7 @@ static void ppp_input(void *arg) { * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, pcb->vj_comp) >= 0) && (pcb->netif.input)) { + if ((vj_uncompress_tcp(&nb, &pcb->vj_comp) >= 0) && (pcb->netif.input)) { pcb->netif.input(nb, &pcb->netif); return; } @@ -589,7 +587,7 @@ static void ppp_input(void *arg) { * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, pcb->vj_comp) >= 0) && pcb->netif.input) { + if ((vj_uncompress_uncomp(nb, &pcb->vj_comp) >= 0) && pcb->netif.input) { pcb->netif.input(nb, &pcb->netif); return; } From 3a30e5bf78fa6cff6a00e2dc8eb637f1811fbf2b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 12 Jun 2012 23:28:09 +0200 Subject: [PATCH 158/320] removed ppp_input_header, replaced using 2 chained pbuf the only area we need it --- src/netif/ppp/ppp.c | 233 +++++++++++++++++---------------------- src/netif/ppp/ppp.h | 4 +- src/netif/ppp/ppp_impl.h | 4 +- src/netif/ppp/ppp_oe.c | 4 +- 4 files changed, 104 insertions(+), 141 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index c377e931..f75057f0 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -188,7 +188,6 @@ struct protent *protocols[] = { /* Prototypes for procedures local to this file. */ static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ -static void ppp_input(void *arg); #if PPPOS_SUPPORT static void ppp_receive_wakeup(ppp_pcb *pcb); @@ -203,6 +202,7 @@ static void ppp_input_thread(void *arg); #endif /* PPP_INPROC_OWNTHREAD */ static void ppp_drop(ppp_pcb_rx *pcrx); static void pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l); +static void pppos_input_callback(void *arg); static void ppp_free_current_input_packet(ppp_pcb_rx *pcrx); #endif /* PPPOS_SUPPORT */ @@ -215,25 +215,6 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p); static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n); #endif /* PPPOE_SUPPORT */ -/******************************/ -/*** PUBLIC DATA STRUCTURES ***/ -/******************************/ - -/** Input helper struct, must be packed since it is stored to pbuf->payload, - * which might be unaligned. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ppp_input_header { - PACK_STRUCT_FIELD(int unit); - PACK_STRUCT_FIELD(u16_t proto); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif /***********************************/ /*** PUBLIC FUNCTION DEFINITIONS ***/ @@ -354,7 +335,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s pcb->fd = fd; - pcb->rx.pd = pcb->unit; + pcb->rx.pcb = (void*)pcb; pcb->rx.fd = fd; #if VJ_SUPPORT @@ -508,27 +489,23 @@ static void ppp_hup(ppp_pcb *pcb) { * Pass the processed input packet to the appropriate handler. * This function and all handlers run in the context of the tcpip_thread */ - -/* FIXME: maybe we should pass in two arguments ppp_input_header and payload - * this is totally stupid to make room for it and then modify the packet directly - * or it is used in output ? have to find out... - */ -static void ppp_input(void *arg) { - struct pbuf *nb = (struct pbuf *)arg; +void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { u16_t protocol; - ppp_pcb *pcb; - pcb = &ppp_pcb_list[((struct ppp_input_header *)nb->payload)->unit]; - protocol = ((struct ppp_input_header *)nb->payload)->proto; + protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - if(pbuf_header(nb, -(int)sizeof(struct ppp_input_header))) { +#if PRINTPKT_SUPPORT + dump_packet("rcvd", pb->payload, pb->len); +#endif /* PRINTPKT_SUPPORT */ + + if(pbuf_header(pb, -(int)sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } LINK_STATS_INC(link.recv); snmp_inc_ifinucastpkts(&pcb->netif); - snmp_add_ifinoctets(&pcb->netif, nb->tot_len); + snmp_add_ifinoctets(&pcb->netif, pb->tot_len); /* * Toss all non-LCP packets unless LCP is OPEN. @@ -568,13 +545,13 @@ static void ppp_input(void *arg) { #if PPPOS_SUPPORT && VJ_SUPPORT case PPP_VJC_COMP: /* VJ compressed TCP */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->unit, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->unit, pb->len)); /* * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, &pcb->vj_comp) >= 0) && (pcb->netif.input)) { - pcb->netif.input(nb, &pcb->netif); + if ((vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) && (pcb->netif.input)) { + pcb->netif.input(pb, &pcb->netif); return; } /* Something's wrong so drop it. */ @@ -582,13 +559,13 @@ static void ppp_input(void *arg) { break; case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->unit, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->unit, pb->len)); /* * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, &pcb->vj_comp) >= 0) && pcb->netif.input) { - pcb->netif.input(nb, &pcb->netif); + if ((vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) && pcb->netif.input) { + pcb->netif.input(pb, &pcb->netif); return; } /* Something's wrong so drop it. */ @@ -597,9 +574,9 @@ static void ppp_input(void *arg) { #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->unit, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->unit, pb->len)); if (pcb->netif.input) { - pcb->netif.input(nb, &pcb->netif); + pcb->netif.input(pb, &pcb->netif); return; } break; @@ -613,8 +590,8 @@ static void ppp_input(void *arg) { */ for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { - nb = ppp_singlebuf(nb); - (*protp->input)(pcb->unit, nb->payload, nb->len); + pb = ppp_singlebuf(pb); + (*protp->input)(pcb->unit, pb->payload, pb->len); goto out; } #if 0 /* UNUSED @@ -628,7 +605,7 @@ static void ppp_input(void *arg) { */ if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag && protp->datainput != NULL) { - (*protp->datainput)(pcb->unit, nb->payload, nb->len); + (*protp->datainput)(pcb->unit, pb->payload, pb->len); goto out; } #endif /* UNUSED */ @@ -643,11 +620,11 @@ static void ppp_input(void *arg) { #endif /* PPP_PROTOCOLNAME */ warn("Unsupported protocol 0x%x received", protocol); #endif /* PPP_DEBUG */ - if (pbuf_header(nb, sizeof(protocol))) { + if (pbuf_header(pb, sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } - lcp_sprotrej(pcb->unit, nb->payload, nb->len); + lcp_sprotrej(pcb->unit, pb->payload, pb->len); } break; } @@ -657,7 +634,7 @@ drop: snmp_inc_ifindiscards(&pcb->netif); out: - pbuf_free(nb); + pbuf_free(pb); return; #if 0 @@ -677,32 +654,32 @@ out: switch(protocol) { case PPP_VJC_COMP: /* VJ compressed TCP */ #if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->unit, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->unit, pb->len)); /* * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&nb, pcb->vj_comp) >= 0) && (pcb->netif.input)) { - pcb->netif.input(nb, pcb->netif); + if ((vj_uncompress_tcp(&pb, pcb->vj_comp) >= 0) && (pcb->netif.input)) { + pcb->netif.input(pb, pcb->netif); return; } /* Something's wrong so drop it. */ PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->unit)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: drop VJ Comp in %d:%s\n", pcb->unit, nb->len, nb->payload)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: drop VJ Comp in %d:%s\n", pcb->unit, pb->len, pb->payload)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ #if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->unit, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->unit, pb->len)); /* * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(nb, pcb->vj_comp) >= 0) && pcb->netif.input) { - pcb->netif.input(nb, pcb->netif); + if ((vj_uncompress_uncomp(pb, pcb->vj_comp) >= 0) && pcb->netif.input) { + pcb->netif.input(pb, pcb->netif); return; } /* Something's wrong so drop it. */ @@ -711,14 +688,14 @@ out: /* No handler for this protocol so drop the packet. */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: drop VJ UnComp in %d:.*H\n", - pcb->unit, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); + pcb->unit, pb->len, LWIP_MIN(pb->len * 2, 40), pb->payload)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->unit, nb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->unit, pb->len)); if (pcb->netif.input) { - pcb->netif.input(nb, pcb->netif); + pcb->netif.input(pb, pcb->netif); return; } break; @@ -732,25 +709,25 @@ out: */ for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: %s len=%d\n", pcb->unit, protp->name, nb->len)); - nb = ppp_singlebuf(nb); - (*protp->input)(pcb->unit, nb->payload, nb->len); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: %s len=%d\n", pcb->unit, protp->name, pb->len)); + pb = ppp_singlebuf(pb); + (*protp->input)(pcb->unit, pb->payload, pb->len); PPPDEBUG(LOG_DETAIL, ("ppp_input[%d]: packet processed\n", pcb->unit)); goto out; } } /* No handler for this protocol so reject the packet. */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pcb->unit, protocol, nb->len)); - if (pbuf_header(nb, sizeof(protocol))) { + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pcb->unit, protocol, pb->len)); + if (pbuf_header(pb, sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } #if BYTE_ORDER == LITTLE_ENDIAN protocol = htons(protocol); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ - SMEMCPY(nb->payload, &protocol, sizeof(protocol)); - lcp_sprotrej(pcb->unit, nb->payload, nb->len); + SMEMCPY(pb->payload, &protocol, sizeof(protocol)); + lcp_sprotrej(pcb->unit, pb->payload, pb->len); } break; } @@ -824,54 +801,6 @@ ppp_receive_wakeup(ppp_pcb *pcb) #endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ -#if PPPOE_SUPPORT -/* ppp_input_over_ethernet - * - * take a packet from PPPoE subsystem and pass it to the PPP stack through ppp_input() - */ - -/* FIXME: maybe we should pass in two arguments ppp_input_header and payload - * this is totally stupid to make room for it and then modify the packet directly - * or it is used in output ? have to find out... - */ -void ppp_input_over_ethernet(ppp_pcb *pcb, struct pbuf *pb) { - struct ppp_input_header *pih; - u16_t in_protocol; - - if(pb->len < sizeof(in_protocol)) { - PPPDEBUG(LOG_ERR, ("ppp_input_over_ethernet: too small for protocol field\n")); - goto drop; - } - -#if PRINTPKT_SUPPORT - dump_packet("rcvd", pb->payload, pb->len); -#endif /* PRINTPKT_SUPPORT */ - - in_protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - - /* make room for ppp_input_header - should not fail */ - if (pbuf_header(pb, sizeof(*pih) - sizeof(in_protocol)) != 0) { - PPPDEBUG(LOG_ERR, ("ppp_input_over_ethernet: could not allocate room for header\n")); - goto drop; - } - - pih = pb->payload; - - pih->unit = pcb->unit; - pih->proto = in_protocol; /* pih->proto is now in host byte order */ - - /* Dispatch the packet thereby consuming it. */ - ppp_input(pb); - return; - -drop: - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pcb->netif); - pbuf_free(pb); - return; -} -#endif /* PPPOE_SUPPORT */ - /* * ppp_netif_init_cb - netif init callback */ @@ -901,7 +830,7 @@ ppp_input_thread(void *arg) { int count; ppp_pcb_rx *pcrx = arg; - ppp_pcb *pcb = &ppp_pcb_list[pcrx->pd]; + ppp_pcb *pcb = (ppp_pcb*)pcrx->pcb; while (pcb->phase != PHASE_DEAD) { count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); @@ -1361,6 +1290,7 @@ ppp_free_current_input_packet(ppp_pcb_rx *pcrx) static void ppp_drop(ppp_pcb_rx *pcrx) { + ppp_pcb *pcb = (ppp_pcb*)pcrx->pcb; if (pcrx->in_head != NULL) { #if 0 PPPDEBUG(LOG_INFO, ("ppp_drop: %d:%.*H\n", pcrx->in_head->len, min(60, pcrx->in_head->len * 2), pcrx->in_head->payload)); @@ -1369,11 +1299,11 @@ ppp_drop(ppp_pcb_rx *pcrx) } ppp_free_current_input_packet(pcrx); #if VJ_SUPPORT - vj_uncompress_err(&ppp_pcb_list[pcrx->pd].vj_comp); + vj_uncompress_err(&pcb->vj_comp); #endif /* VJ_SUPPORT */ LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&ppp_pcb_list[pcrx->pd].netif); + snmp_inc_ifindiscards(&pcb->netif); } #if !PPP_INPROC_OWNTHREAD @@ -1397,12 +1327,13 @@ pppos_input(ppp_pcb *pcb, u_char* data, int len) static void pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) { + ppp_pcb *pcb = (ppp_pcb*)pcrx->pcb; struct pbuf *next_pbuf; u_char cur_char; u_char escaped; SYS_ARCH_DECL_PROTECT(lev); - PPPDEBUG(LOG_DEBUG, ("pppos_input_proc[%d]: got %d bytes\n", pcrx->pd, l)); + PPPDEBUG(LOG_DEBUG, ("pppos_input_proc[%d]: got %d bytes\n", pcb->unit, l)); while (l-- > 0) { cur_char = *s++; @@ -1427,20 +1358,23 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) } else if (pcrx->in_state < PDDATA) { PPPDEBUG(LOG_WARNING, ("pppos_input_proc[%d]: Dropping incomplete packet %d\n", - pcrx->pd, pcrx->in_state)); + pcb->unit, pcrx->in_state)); LINK_STATS_INC(link.lenerr); ppp_drop(pcrx); /* If the fcs is invalid, drop the packet. */ } else if (pcrx->in_fcs != PPP_GOODFCS) { PPPDEBUG(LOG_INFO, ("pppos_input_proc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", - pcrx->pd, pcrx->in_fcs, pcrx->in_protocol)); + pcb->unit, pcrx->in_fcs, pcrx->in_protocol)); /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ LINK_STATS_INC(link.chkerr); ppp_drop(pcrx); /* Otherwise it's a good packet so pass it on. */ } else { struct pbuf *inp; +#if PPP_INPROC_MULTITHREADED + struct pbuf *head; +#endif /* PPP_INPROC_MULTITHREADED */ /* Trim off the checksum. */ if(pcrx->in_tail->len > 2) { pcrx->in_tail->len -= 2; @@ -1464,14 +1398,20 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) pcrx->in_head = NULL; pcrx->in_tail = NULL; #if PPP_INPROC_MULTITHREADED - if(tcpip_callback_with_block(ppp_input, inp, 0) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); - pbuf_free(inp); - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&ppp_pcb_list[pcrx->pd].netif); + head = pbuf_alloc(PBUF_RAW, sizeof(void*), PBUF_POOL); + if(NULL != head) { + MEMCPY(head->payload, pcb, sizeof(void*)); + pbuf_chain(head, inp); + if(tcpip_callback_with_block(pppos_input_callback, head, 0) != ERR_OK) { + PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: tcpip_callback() failed, dropping packet\n", pcb->unit)); + pbuf_free(head); + pbuf_free(inp); + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pcb->netif); + } } #else /* PPP_INPROC_MULTITHREADED */ - ppp_input(inp); + ppp_input(pcrx->pcb, inp); #endif /* PPP_INPROC_MULTITHREADED */ } @@ -1483,7 +1423,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) * been inserted by the physical layer so here we just drop them. */ } else { PPPDEBUG(LOG_WARNING, - ("pppos_input_proc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, cur_char)); + ("pppos_input_proc[%d]: Dropping ACCM char <%d>\n", pcb->unit, cur_char)); } /* Process other characters. */ } else { @@ -1530,7 +1470,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) #if 0 else { PPPDEBUG(LOG_WARNING, - ("pppos_input_proc[%d]: Invalid control <%d>\n", pcrx->pd, cur_char)); + ("pppos_input_proc[%d]: Invalid control <%d>\n", pcb->unit, cur_char)); pcrx->in_state = PDSTART; } #endif @@ -1566,19 +1506,16 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) /* No free buffers. Drop the input packet and let the * higher layers deal with it. Continue processing * the received pbuf chain in case a new packet starts. */ - PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: NO FREE MBUFS!\n", pcrx->pd)); + PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: NO FREE MBUFS!\n", pcb->unit)); LINK_STATS_INC(link.memerr); ppp_drop(pcrx); pcrx->in_state = PDSTART; /* Wait for flag sequence. */ break; } if (pcrx->in_head == NULL) { - struct ppp_input_header *pih = next_pbuf->payload; - - pih->unit = pcrx->pd; - pih->proto = pcrx->in_protocol; - - next_pbuf->len += sizeof(*pih); + ((u8_t*)next_pbuf->payload)[0] = pcrx->in_protocol & 0xFF; + ((u8_t*)next_pbuf->payload)[1] = pcrx->in_protocol >> 8; + next_pbuf->len += sizeof(pcrx->in_protocol); pcrx->in_head = next_pbuf; } @@ -1596,6 +1533,34 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) magic_randomize(); } + +/* PPPoS input callback using one input pointer + * *arg is a pbuf chain of two chained pbuf, the first contains + * a pointer to the PPP PCB structure, the second contains the + * PPP payload + */ +static void pppos_input_callback(void *arg) { + struct pbuf *hd, *pl; + ppp_pcb *pcb; + + hd = (struct pbuf *)arg; + pcb = (ppp_pcb *)hd->payload; + + pl = hd->next; + pbuf_free(hd); + if(NULL == pl) + goto drop; + + /* Dispatch the packet thereby consuming it. */ + ppp_input(pcb, pl); + return; + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pcb->netif); + pbuf_free(pl); + return; +} #endif /* PPPOS_SUPPORT */ /* merge a pbuf chain into one pbuf */ @@ -1642,7 +1607,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { pppoe_err_code = PPPERR_CONNECT; break; - /* PPPoE link failed to setup (i.e. PADI/PADO timeout */ + /* PPPoE link failed to setup (i.e. PADI/PADO timeout) */ case PPPOE_CB_STATE_FAILED: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pcb->unit)); pppoe_err_code = PPPERR_OPEN; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 27a82b6f..c16d8f59 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -193,8 +193,8 @@ typedef enum { * PPP interface RX control block. */ typedef struct ppp_pcb_rx_s { - /** unit number / ppp descriptor */ - int pd; + /** ppp descriptor */ + void *pcb; /** the rx file descriptor */ sio_fd_t fd; /** receive buffer - encoded data is stored here */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index d10af710..0fc5f519 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -387,10 +387,8 @@ ppp_pcb ppp_pcb_list[NUM_PPP]; /* The PPP interface control blocks. */ /* PPP flow functions */ -#if PPPOE_SUPPORT /* function called by pppoe.c */ -void ppp_input_over_ethernet(ppp_pcb *pcb, struct pbuf *pb); -#endif /* PPPOE_SUPPORT */ +void ppp_input(ppp_pcb *pcb, struct pbuf *pb); /* function called by all PPP subsystems to send packets */ int ppp_write(ppp_pcb *pcb, const u_char *s, int n); diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index f3fa34e9..4f1aed31 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -622,8 +622,8 @@ pppoe_data_input(struct netif *netif, struct pbuf *pb) goto drop; } - ppp_input_over_ethernet(sc->pcb, pb); - + /* Dispatch the packet thereby consuming it. */ + ppp_input(sc->pcb, pb); return; drop: From 81a0fd782f5ce35ec427d2a494b9e94f9eeb0fdb Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 13 Jun 2012 00:12:55 +0200 Subject: [PATCH 159/320] removed unit from ppp_ioctl() --- src/netif/ppp/ppp.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index f75057f0..ebf20c97 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -361,7 +361,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); #endif /* PPP_INPROC_OWNTHREAD */ - return pcb->unit; + return PPPERR_NONE; } /* @@ -413,7 +413,7 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic } pppoe_connect(pcb->pppoe_sc); - return pcb->unit; + return PPPERR_NONE; } #endif /* PPPOE_SUPPORT */ @@ -1105,49 +1105,50 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { int ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) { - int st = 0; + if(NULL == pcb) + return PPPERR_PARAM; - if (pcb->unit < 0 || pcb->unit >= NUM_PPP) { - st = PPPERR_PARAM; - } else { - switch(cmd) { + switch(cmd) { case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ if (arg) { *(int *)arg = (int)(pcb->if_up); - } else { - st = PPPERR_PARAM; + return PPPERR_NONE; } + return PPPERR_PARAM; break; + case PPPCTLS_ERRCODE: /* Set the PPP error code. */ if (arg) { pcb->err_code = *(int *)arg; - } else { - st = PPPERR_PARAM; + return PPPERR_NONE; } + return PPPERR_PARAM; break; + case PPPCTLG_ERRCODE: /* Get the PPP error code. */ if (arg) { *(int *)arg = (int)(pcb->err_code); - } else { - st = PPPERR_PARAM; + return PPPERR_NONE; } + return PPPERR_PARAM; break; + #if PPPOS_SUPPORT case PPPCTLG_FD: /* Get the fd associated with the ppp */ if (arg) { *(sio_fd_t *)arg = pcb->fd; - } else { - st = PPPERR_PARAM; + return PPPERR_NONE; } + return PPPERR_PARAM; break; #endif /* PPPOS_SUPPORT */ + default: - st = PPPERR_PARAM; + return PPPERR_PARAM; break; - } } - return st; + return PPPERR_PARAM; } /* From 51bfac71b044a2dc35f829fff446a65fb1710aa7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 14 Jun 2012 00:08:56 +0200 Subject: [PATCH 160/320] auth.c functions now use ppp_pcb* as first argument --- src/netif/ppp/auth.c | 164 ++++++++++++--------------------------- src/netif/ppp/chap-new.c | 13 ++-- src/netif/ppp/eap.c | 30 +++---- src/netif/ppp/ipcp.c | 7 +- src/netif/ppp/lcp.c | 23 +++--- src/netif/ppp/ppp.c | 2 +- src/netif/ppp/ppp_impl.h | 28 +++---- src/netif/ppp/upap.c | 14 ++-- 8 files changed, 113 insertions(+), 168 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 07adc9a1..50c295b5 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -139,8 +139,10 @@ #define ISWILD(word) (word[0] == '*' && word[1] == 0) #endif /* UNUSED */ +#if PPP_SERVER /* The name by which the peer authenticated itself to us. */ char peer_authname[MAXNAMELEN]; +#endif /* PPP_SERVER */ /* Records which authentication operations haven't completed yet. */ static int auth_pending[NUM_PPP]; @@ -251,9 +253,9 @@ extern char *crypt (const char *, const char *); #endif /* UNUSED */ /* Prototypes for procedures local to this file. */ -static void network_phase (int); -static void check_idle (void *); -static void connect_time_expired (void *); +static void network_phase(ppp_pcb *pcb); +static void check_idle(void *arg); +static void connect_time_expired(void *arg); #if 0 /* UNUSED */ static int null_login (int); /* static int get_pap_passwd (char *); */ @@ -556,10 +558,7 @@ set_permitted_number(argv) /* * An Open on LCP has requested a change from Dead to Establish phase. */ -void -link_required(unit) - int unit; -{ +void link_required(ppp_pcb *pcb) { } #if 0 @@ -630,11 +629,7 @@ void start_link(unit) * LCP has terminated the link; go to the Dead phase and take the * physical layer down. */ -void -link_terminated(unit) - int unit; -{ - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void link_terminated(ppp_pcb *pcb) { if (pcb->phase == PHASE_DEAD || pcb->phase == PHASE_MASTER) return; new_phase(pcb, PHASE_DISCONNECT); @@ -709,17 +704,13 @@ link_terminated(unit) /* * LCP has gone down; it will either die or try to re-establish. */ -void -link_down(unit) - int unit; -{ - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void link_down(ppp_pcb *pcb) { #if PPP_NOTIFY notify(link_down_notifier, 0); #endif /* #if PPP_NOTIFY */ if (!doing_multilink) { - upper_layers_down(unit); + upper_layers_down(pcb); if (pcb->phase != PHASE_DEAD && pcb->phase != PHASE_MASTER) new_phase(pcb, PHASE_ESTABLISH); } @@ -729,8 +720,7 @@ link_down(unit) ppp_link_down(pcb); } -void upper_layers_down(int unit) -{ +void upper_layers_down(ppp_pcb *pcb) { int i; struct protent *protp; @@ -738,9 +728,9 @@ void upper_layers_down(int unit) if (!protp->enabled_flag) continue; if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) - (*protp->lowerdown)(unit); + (*protp->lowerdown)(pcb->unit); if (protp->protocol < 0xC000 && protp->close != NULL) - (*protp->close)(unit, "LCP down"); + (*protp->close)(pcb->unit, "LCP down"); } num_np_open = 0; num_np_up = 0; @@ -750,19 +740,15 @@ void upper_layers_down(int unit) * The link is established. * Proceed to the Dead, Authenticate or Network phase as appropriate. */ -void -link_established(unit) - int unit; -{ - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void link_established(ppp_pcb *pcb) { int auth; #if 0 /* UNUSED */ - lcp_options *wo = &lcp_wantoptions[unit]; + lcp_options *wo = &lcp_wantoptions[pcb->unit]; #endif /* UNUSED */ #if PPP_SERVER - lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *go = &lcp_gotoptions[pcb->unit]; #endif /* #if PPP_SERVER */ - lcp_options *ho = &lcp_hisoptions[unit]; + lcp_options *ho = &lcp_hisoptions[pcb->unit]; int i; struct protent *protp; @@ -773,7 +759,7 @@ link_established(unit) for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) - (*protp->lowerup)(unit); + (*protp->lowerup)(pcb->unit); } #if 0 /* UNUSED */ @@ -809,7 +795,7 @@ link_established(unit) if (!wo->neg_upap || uselogin || !null_login(unit)) { warn("peer refused to authenticate: terminating link"); status = EXIT_PEER_AUTH_FAILED; - lcp_close(unit, "peer refused to authenticate"); + lcp_close(pcb->unit, "peer refused to authenticate"); return; } } @@ -841,38 +827,35 @@ link_established(unit) #if EAP_SUPPORT if (ho->neg_eap) { - eap_authwithpeer(unit, pcb->settings.user); + eap_authwithpeer(pcb->unit, pcb->settings.user); auth |= EAP_WITHPEER; } else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (ho->neg_chap) { - chap_auth_with_peer(unit, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); + chap_auth_with_peer(pcb->unit, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if (ho->neg_upap) { - upap_authwithpeer(unit, pcb->settings.user, pcb->settings.passwd); + upap_authwithpeer(pcb->unit, pcb->settings.user, pcb->settings.passwd); auth |= PAP_WITHPEER; } else #endif /* PAP_SUPPORT */ {} - auth_pending[unit] = auth; - auth_done[unit] = 0; + auth_pending[pcb->unit] = auth; + auth_done[pcb->unit] = 0; if (!auth) - network_phase(unit); + network_phase(pcb); } /* * Proceed to the network phase. */ -static void -network_phase(unit) - int unit; -{ +static void network_phase(ppp_pcb *pcb) { #if CBCP_SUPPORT ppp_pcb *pcb = &ppp_pcb_list[unit]; #endif @@ -926,14 +909,10 @@ network_phase(unit) extra_options = 0; } #endif /* PPP_OPTIONS */ - start_networks(unit); + start_networks(pcb); } -void -start_networks(unit) - int unit; -{ - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void start_networks(ppp_pcb *pcb) { #if CCP_SUPPORT || ECP_SUPPORT int i; struct protent *protp; @@ -997,13 +976,10 @@ start_networks(unit) && !mppe_required #endif /* MPPE */ ) - continue_networks(unit); + continue_networks(pcb); } -void -continue_networks(unit) - int unit; -{ +void continue_networks(ppp_pcb *pcb) { int i; struct protent *protp; @@ -1115,11 +1091,7 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) /* * We have failed to authenticate ourselves to the peer using `protocol'. */ -void -auth_withpeer_fail(unit, protocol) - int unit, protocol; -{ - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void auth_withpeer_fail(ppp_pcb *pcb, int protocol) { int errcode = PPPERR_AUTHFAIL; /* * We've failed to authenticate ourselves to our peer. @@ -1135,16 +1107,13 @@ auth_withpeer_fail(unit, protocol) * we can do except wait for that. */ ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); - lcp_close(unit, "Failed to authenticate ourselves to peer"); + lcp_close(pcb->unit, "Failed to authenticate ourselves to peer"); } /* * We have successfully authenticated ourselves with the peer using `protocol'. */ -void -auth_withpeer_success(unit, protocol, prot_flavor) - int unit, protocol, prot_flavor; -{ +void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { int bit; const char *prot = ""; @@ -1189,26 +1158,22 @@ auth_withpeer_success(unit, protocol, prot_flavor) notice("%s authentication succeeded", prot); /* Save the authentication method for later. */ - auth_done[unit] |= bit; + auth_done[pcb->unit] |= bit; /* * 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); + if ((auth_pending[pcb->unit] &= ~bit) == 0) + network_phase(pcb); } /* * np_up - a network protocol has come up. */ -void -np_up(unit, proto) - int unit, proto; -{ +void np_up(ppp_pcb *pcb, int proto) { int tlim; - ppp_pcb *pcb = &ppp_pcb_list[unit]; if (num_np_up == 0) { /* @@ -1224,14 +1189,14 @@ np_up(unit, proto) #endif /* UNUSED */ tlim = pcb->settings.idle_time_limit; if (tlim > 0) - TIMEOUT(check_idle, NULL, tlim); + TIMEOUT(check_idle, (void*)pcb, tlim); /* * Set a timeout to close the connection once the maximum * connect time has expired. */ if (pcb->settings.maxconnect > 0) - TIMEOUT(connect_time_expired, 0, pcb->settings.maxconnect); + TIMEOUT(connect_time_expired, (void*)pcb, pcb->settings.maxconnect); #ifdef MAXOCTETS if (maxoctets > 0) @@ -1252,13 +1217,9 @@ np_up(unit, proto) /* * np_down - a network protocol has gone down. */ -void -np_down(unit, proto) - int unit, proto; -{ - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void np_down(ppp_pcb *pcb, int proto) { if (--num_np_up == 0) { - UNTIMEOUT(check_idle, NULL); + UNTIMEOUT(check_idle, (void*)pcb); UNTIMEOUT(connect_time_expired, NULL); #ifdef MAXOCTETS UNTIMEOUT(check_maxoctets, NULL); @@ -1270,10 +1231,7 @@ np_down(unit, proto) /* * np_finished - a network protocol has finished using the link. */ -void -np_finished(unit, proto) - int unit, proto; -{ +void np_finished(ppp_pcb *pcb, int proto) { if (--num_np_open <= 0) { /* no further use for the link: shut up shop. */ lcp_close(0, "No network protocols running"); @@ -1324,12 +1282,8 @@ check_maxoctets(arg) * check_idle - check whether the link has been idle for long * enough that we can shut it down. */ -static void -check_idle(arg) - void *arg; -{ - /* FIXME: fix forced unit 0 */ - ppp_pcb *pcb = &ppp_pcb_list[0]; +static void check_idle(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; struct ppp_idle idle; time_t itime; int tlim; @@ -1355,19 +1309,15 @@ check_idle(arg) need_holdoff = 0; #endif /* UNUSED */ } else { - TIMEOUT(check_idle, NULL, tlim); + TIMEOUT(check_idle, (void*)pcb, tlim); } } /* * connect_time_expired - log a message and close the connection. */ -static void -connect_time_expired(arg) - void *arg; -{ - /* FIXME: fix forced unit 0 */ - ppp_pcb *pcb = &ppp_pcb_list[0]; +static void connect_time_expired(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; info("Connect time expired"); pcb->status = EXIT_CONNECT_TIME; lcp_close(0, "Connect time expired"); /* Close connection */ @@ -1517,13 +1467,9 @@ auth_check_options() * authentication options, i.e. whether we have appropriate secrets * to use for authenticating ourselves and/or the peer. */ -void -auth_reset(unit) - int unit; -{ - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void auth_reset(ppp_pcb *pcb) { + lcp_options *go = &lcp_gotoptions[pcb->unit]; + lcp_options *ao = &lcp_allowoptions[pcb->unit]; if( pcb->settings.passwd[0] ) { @@ -1986,19 +1932,9 @@ have_srp_secret(client, server, need_ip, lacks_ipp) * for authenticating the given client on the given server. * (We could be either client or server). */ -int -get_secret(unit, client, server, secret, secret_len, am_server) - int unit; - char *client; - char *server; - char *secret; - int *secret_len; - int am_server; -{ +int get_secret(ppp_pcb *pcb, char *client, char *server, char *secret, int *secret_len, int am_server) { int len; - ppp_pcb *pcb = &ppp_pcb_list[unit]; - LWIP_UNUSED_ARG(unit); LWIP_UNUSED_ARG(server); LWIP_UNUSED_ARG(am_server); diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 6d246dae..0ba348fe 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -458,7 +458,7 @@ chap_verify_response(char *name, char *ourname, int id, int secret_len; /* Get the secret that the peer is supposed to know */ - if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) { + if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) { error("No CHAP secret found for authenticating %q", name); return 0; } @@ -503,7 +503,7 @@ chap_respond(struct chap_client_state *cs, int id, strlcpy(rname, pc->settings.remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ - if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { + if (!get_secret(pcb, cs->name, rname, 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", rname); } @@ -534,6 +534,8 @@ static void chap_handle_status(struct chap_client_state *cs, int code, int id, unsigned char *pkt, int len) { + /* FIXME: fix forced unit 0 */ + ppp_pcb *pcb = &ppp_pcb_list[0]; const char *msg = NULL; if ((cs->flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) @@ -561,11 +563,11 @@ chap_handle_status(struct chap_client_state *cs, int code, int id, info("%s", msg); } if (code == CHAP_SUCCESS) - auth_withpeer_success(0, PPP_CHAP, cs->digest->code); + auth_withpeer_success(pcb, PPP_CHAP, cs->digest->code); else { cs->flags |= AUTH_FAILED; error("CHAP authentication failed"); - auth_withpeer_fail(0, PPP_CHAP); + auth_withpeer_fail(pcb, PPP_CHAP); } } @@ -608,6 +610,7 @@ chap_input(int unit, unsigned char *pkt, int pktlen) static void chap_protrej(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; struct chap_client_state *cs = &client; #if PPP_SERVER struct chap_server_state *ss = &server; @@ -624,7 +627,7 @@ chap_protrej(int unit) if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { cs->flags &= ~AUTH_STARTED; error("CHAP authentication failed due to protocol-reject"); - auth_withpeer_fail(0, PPP_CHAP); + auth_withpeer_fail(pcb, PPP_CHAP); } } diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 95176380..a6605ded 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -222,12 +222,13 @@ eap_client_timeout(arg) void *arg; { eap_state *esp = (eap_state *) arg; + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; if (!eap_client_active(esp)) return; error("EAP: timeout waiting for Request from peer"); - auth_withpeer_fail(esp->es_unit, PPP_EAP); + auth_withpeer_fail(pcb, PPP_EAP); esp->es_client.ea_state = eapBadAuth; } @@ -1043,16 +1044,17 @@ static void eap_protrej(unit) int unit; { + ppp_pcb *pcb = &ppp_pcb_list[unit]; eap_state *esp = &eap_states[unit]; if (eap_client_active(esp)) { error("EAP authentication failed due to Protocol-Reject"); - auth_withpeer_fail(unit, PPP_EAP); + auth_withpeer_fail(pcb, PPP_EAP); } #if PPP_SERVER if (eap_server_active(esp)) { error("EAP authentication of peer failed on Protocol-Reject"); - auth_peer_fail(unit, PPP_EAP); + auth_peer_fail(pcb, PPP_EAP); } #endif /* PPP_SERVER */ eap_lowerdown(unit); @@ -1341,7 +1343,7 @@ u_char *inp; int id; int len; { - ppp_pcb *pc = &ppp_pcb_list[esp->es_unit]; + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; u_char typenum; u_char vallen; int secret_len; @@ -1371,7 +1373,7 @@ int len; if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } - auth_withpeer_fail(esp->es_unit, PPP_EAP); + auth_withpeer_fail(pcb, PPP_EAP); return; } @@ -1460,15 +1462,15 @@ int len; } /* In case the remote doesn't give us his name. */ - if (pc->settings.explicit_remote || - (pc->settings.remote_name[0] != '\0' && vallen == len)) - strlcpy(rhostname, pc->settings.remote_name, sizeof (rhostname)); + if (pcb->settings.explicit_remote || + (pcb->settings.remote_name[0] != '\0' && vallen == len)) + strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname)); /* * Get the secret for authenticating ourselves with * the specified host. */ - if (!get_secret(esp->es_unit, esp->es_client.ea_name, + if (!get_secret(pcb, esp->es_client.ea_name, rhostname, secret, &secret_len, 0)) { dbglog("EAP: no MD5 secret for auth to %q", rhostname); eap_send_nak(esp, id, EAPT_SRP); @@ -1738,7 +1740,7 @@ client_failure: } esp->es_client.ea_session = NULL; t_clientclose(tc); - auth_withpeer_fail(esp->es_unit, PPP_EAP); + auth_withpeer_fail(pcb, PPP_EAP); #endif /* USE_SRP */ } @@ -1896,7 +1898,7 @@ int len; * Get the secret for authenticating the specified * host. */ - if (!get_secret(esp->es_unit, rhostname, + if (!get_secret(pcb, rhostname, esp->es_server.ea_name, secret, &secret_len, 1)) { dbglog("EAP: no MD5 secret for auth of %q", rhostname); eap_send_failure(esp); @@ -2050,6 +2052,7 @@ u_char *inp; int id; int len; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) { dbglog("EAP unexpected success message in state %s (%d)", eap_state_name(esp->es_client.ea_state), @@ -2067,7 +2070,7 @@ int len; } esp->es_client.ea_state = eapOpen; - auth_withpeer_success(esp->es_unit, PPP_EAP, 0); + auth_withpeer_success(pcb, PPP_EAP, 0); } /* @@ -2080,6 +2083,7 @@ u_char *inp; int id; int len; { + ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; if (!eap_client_active(esp)) { dbglog("EAP unexpected failure message in state %s (%d)", eap_state_name(esp->es_client.ea_state), @@ -2098,7 +2102,7 @@ int len; esp->es_client.ea_state = eapBadAuth; error("EAP: peer reports authentication failure"); - auth_withpeer_fail(esp->es_unit, PPP_EAP); + auth_withpeer_fail(pcb, PPP_EAP); } /* diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 3b8589e5..f5b84f55 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1982,7 +1982,7 @@ ipcp_up(f) reset_link_stats(f->unit); #endif /* PPP_STATS_SUPPORT */ - np_up(f->unit, PPP_IP); + np_up(pcb, PPP_IP); ipcp_is_up = 1; #if PPP_NOTIFY @@ -2023,7 +2023,7 @@ ipcp_down(f) #endif /* UNUSED */ if (ipcp_is_up) { ipcp_is_up = 0; - np_down(f->unit, PPP_IP); + np_down(pcb, PPP_IP); } sifvjcomp(pcb, 0, 0, 0); @@ -2087,9 +2087,10 @@ static void ipcp_finished(f) fsm *f; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; if (ipcp_is_open) { ipcp_is_open = 0; - np_finished(f->unit, PPP_IP); + np_finished(pcb, PPP_IP); } } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index acfd4116..c671d44c 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -735,6 +735,7 @@ static void lcp_resetci(f) fsm *f; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; lcp_options *wo = &lcp_wantoptions[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *ao = &lcp_allowoptions[f->unit]; @@ -754,7 +755,7 @@ lcp_resetci(f) if (noendpoint) ao->neg_endpoint = 0; peer_mru[f->unit] = PPP_MRU; - auth_reset(f->unit); + auth_reset(pcb); } @@ -2317,7 +2318,7 @@ lcp_up(f) lcp_echo_lowerup(f->unit); /* Enable echo messages */ - link_established(f->unit); + link_established(pcb); } @@ -2335,7 +2336,7 @@ lcp_down(f) lcp_echo_lowerdown(f->unit); - link_down(f->unit); + link_down(pcb); ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0); ppp_recv_config(pcb, PPP_MRU, @@ -2348,22 +2349,18 @@ lcp_down(f) /* * lcp_starting - LCP needs the lower layer up. */ -static void -lcp_starting(f) - fsm *f; -{ - link_required(f->unit); +static void lcp_starting(fsm *f) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + link_required(pcb); } /* * lcp_finished - LCP has finished with the lower layer. */ -static void -lcp_finished(f) - fsm *f; -{ - link_terminated(f->unit); +static void lcp_finished(fsm *f) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + link_terminated(pcb); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index ebf20c97..4b3d6e4b 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -482,7 +482,7 @@ static void ppp_stop(ppp_pcb *pcb) { static void ppp_hup(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_hup: unit %d\n", pcb->unit)); lcp_lowerdown(pcb->unit); - link_terminated(pcb->unit); + link_terminated(pcb); } /* diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 0fc5f519..6d208c4b 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -544,27 +544,27 @@ void update_link_stats(int u); /* Get stats at link termination */ #define EXIT_CNID_AUTH_FAILED 21 /* 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 upper_layers_down (int);/* take all NCPs down */ -void link_established (int); /* the link is up; authenticate now */ -void start_networks (int); /* start all the network control protos */ -void continue_networks (int); /* start network [ip, etc] control protos */ +void link_required(ppp_pcb *pcb); /* we are starting to use the link */ +void link_terminated(ppp_pcb *pcb); /* we are finished with the link */ +void link_down(ppp_pcb *pcb); /* the LCP layer has left the Opened state */ +void upper_layers_down(ppp_pcb *pcb); /* take all NCPs down */ +void link_established(ppp_pcb *pcb); /* the link is up; authenticate now */ +void start_networks(ppp_pcb *pcb); /* start all the network control protos */ +void continue_networks(ppp_pcb *pcb); /* start network [ip, etc] control protos */ void auth_peer_fail (int, int); /* peer failed to authenticate itself */ void auth_peer_success (int, int, int, char *, int); /* peer successfully authenticated itself */ -void auth_withpeer_fail (int, int); +void auth_withpeer_fail(ppp_pcb *pcb, int protocol); /* we failed to authenticate ourselves */ -void auth_withpeer_success (int, int, int); +void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor); /* we successfully authenticated ourselves */ -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_reset (int); /* check what secrets we have */ -int get_secret (int, char *, char *, char *, int *, int); +void np_up(ppp_pcb *pcb, int proto); /* a network protocol has come up */ +void np_down(ppp_pcb *pcb, int proto); /* a network protocol has gone down */ +void np_finished(ppp_pcb *pcb, int proto); /* a network protocol no longer needs link */ +void auth_reset(ppp_pcb *pcb); /* check what secrets we have */ +int get_secret(ppp_pcb *pcb, char *client, char *server, char *secret, int *secret_len, int am_server); /* get "secret" for chap */ /* Procedures exported from ipcp.c */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 8f471920..29a71eff 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -222,6 +222,7 @@ upap_timeout(arg) void *arg; { upap_state *u = (upap_state *) arg; + ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; if (u->us_clientstate != UPAPCS_AUTHREQ) return; @@ -230,7 +231,7 @@ upap_timeout(arg) /* give up in disgust */ error("No response to PAP authenticate-requests"); u->us_clientstate = UPAPCS_BADAUTH; - auth_withpeer_fail(u->us_unit, PPP_PAP); + auth_withpeer_fail(pcb, PPP_PAP); return; } @@ -321,15 +322,16 @@ upap_protrej(unit) int unit; { upap_state *u = &upap[unit]; + ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; if (u->us_clientstate == UPAPCS_AUTHREQ) { error("PAP authentication failed due to protocol-reject"); - auth_withpeer_fail(unit, PPP_PAP); + auth_withpeer_fail(pcb, PPP_PAP); } #if PPP_SERVER if (u->us_serverstate == UPAPSS_LISTEN) { error("PAP authentication of peer failed (protocol-reject)"); - auth_peer_fail(unit, PPP_PAP); + auth_peer_fail(pcb, PPP_PAP); } #endif /* PPP_SERVER */ upap_lowerdown(unit); @@ -506,6 +508,7 @@ upap_rauthack(u, inp, id, len) int id; int len; { + ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; u_char msglen; char *msg; @@ -532,7 +535,7 @@ upap_rauthack(u, inp, id, len) u->us_clientstate = UPAPCS_OPEN; - auth_withpeer_success(u->us_unit, PPP_PAP, 0); + auth_withpeer_success(pcb, PPP_PAP, 0); } @@ -546,6 +549,7 @@ upap_rauthnak(u, inp, id, len) int id; int len; { + ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; u_char msglen; char *msg; @@ -573,7 +577,7 @@ upap_rauthnak(u, inp, id, len) u->us_clientstate = UPAPCS_BADAUTH; error("PAP authentication failed"); - auth_withpeer_fail(u->us_unit, PPP_PAP); + auth_withpeer_fail(pcb, PPP_PAP); } From 844f5e5af140b824964fd2258b00c9677435d15f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 14 Jun 2012 00:25:45 +0200 Subject: [PATCH 161/320] moved auth.c global variables to ppp_pcb --- src/netif/ppp/auth.c | 69 +++++++++++++--------------------------- src/netif/ppp/chap-new.c | 8 ++--- src/netif/ppp/eap.c | 4 +-- src/netif/ppp/ppp.h | 9 ++++++ src/netif/ppp/ppp_impl.h | 7 ++-- src/netif/ppp/upap.c | 6 ++-- 6 files changed, 44 insertions(+), 59 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 50c295b5..b516ad23 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -139,17 +139,6 @@ #define ISWILD(word) (word[0] == '*' && word[1] == 0) #endif /* UNUSED */ -#if PPP_SERVER -/* The name by which the peer authenticated itself to us. */ -char peer_authname[MAXNAMELEN]; -#endif /* PPP_SERVER */ - -/* Records which authentication operations haven't completed yet. */ -static int auth_pending[NUM_PPP]; - -/* Records which authentication operations have been completed. */ -int auth_done[NUM_PPP]; - #if 0 /* UNUSED */ /* List of addresses which the peer may use. */ static struct permitted_ip *addresses[NUM_PPP]; @@ -168,12 +157,6 @@ static struct wordlist *permitted_numbers; static struct wordlist *extra_options; #endif /* UNUSED */ -/* 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; - #if 0 /* UNUSED */ /* Set if we require authentication only because we have a default route. */ static bool default_auth; @@ -732,8 +715,8 @@ void upper_layers_down(ppp_pcb *pcb) { if (protp->protocol < 0xC000 && protp->close != NULL) (*protp->close)(pcb->unit, "LCP down"); } - num_np_open = 0; - num_np_up = 0; + pcb->num_np_open = 0; + pcb->num_np_up = 0; } /* @@ -845,8 +828,8 @@ void link_established(ppp_pcb *pcb) { #endif /* PAP_SUPPORT */ {} - auth_pending[pcb->unit] = auth; - auth_done[pcb->unit] = 0; + pcb->auth_pending = auth; + pcb->auth_done = 0; if (!auth) network_phase(pcb); @@ -996,10 +979,10 @@ void continue_networks(ppp_pcb *pcb) { #endif /* ECP_SUPPORT */ && protp->enabled_flag && protp->open != NULL) { (*protp->open)(0); - ++num_np_open; + ++pcb->num_np_open; } - if (num_np_open == 0) + if (pcb->num_np_open == 0) /* nothing to do */ lcp_close(0, "No network protocols running"); } @@ -1008,26 +991,18 @@ void continue_networks(ppp_pcb *pcb) { /* * The peer has failed to authenticate himself using `protocol'. */ -void -auth_peer_fail(unit, protocol) - int unit, protocol; -{ +void auth_peer_fail(ppp_pcb *pcb, int protocol) { /* * Authentication failure: take the link down */ status = EXIT_PEER_AUTH_FAILED; - lcp_close(unit, "Authentication failed"); + lcp_close(pcb->unit, "Authentication failed"); } /* * The peer has been successfully authenticated using `protocol'. */ -void -auth_peer_success(unit, protocol, prot_flavor, name, namelen) - int unit, protocol, prot_flavor; - char *name; - int namelen; -{ +void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, char *name, int namelen) { int bit; switch (protocol) { @@ -1068,22 +1043,22 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen) * Save the authenticated name of the peer for later. */ /* FIXME: do we need that ? */ - if (namelen > sizeof(peer_authname) - 1) - namelen = sizeof(peer_authname) - 1; - MEMCPY(peer_authname, name, namelen); - peer_authname[namelen] = 0; + if (namelen > sizeof(pcb->peer_authname) - 1) + namelen = sizeof(pcb->peer_authname) - 1; + MEMCPY(pcb->peer_authname, name, namelen); + pcb->peer_authname[namelen] = 0; #if 0 /* UNUSED */ - script_setenv("PEERNAME", peer_authname, 0); + script_setenv("PEERNAME", , 0); #endif /* UNUSED */ /* Save the authentication method for later. */ - auth_done[unit] |= bit; + pcb->auth_done |= bit; /* * If there is no more authentication still to be done, * proceed to the network (or callback) phase. */ - if ((auth_pending[unit] &= ~bit) == 0) + if ((pcb->auth_pending &= ~bit) == 0) network_phase(unit); } #endif /* PPP_SERVER */ @@ -1158,13 +1133,13 @@ void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { notice("%s authentication succeeded", prot); /* Save the authentication method for later. */ - auth_done[pcb->unit] |= bit; + pcb->auth_done |= bit; /* * If there is no more authentication still being done, * proceed to the network (or callback) phase. */ - if ((auth_pending[pcb->unit] &= ~bit) == 0) + if ((pcb->auth_pending &= ~bit) == 0) network_phase(pcb); } @@ -1175,7 +1150,7 @@ void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { void np_up(ppp_pcb *pcb, int proto) { int tlim; - if (num_np_up == 0) { + if (pcb->num_np_up == 0) { /* * At this point we consider that the link has come up successfully. */ @@ -1211,14 +1186,14 @@ void np_up(ppp_pcb *pcb, int proto) { detach(); #endif /* Unused */ } - ++num_np_up; + ++pcb->num_np_up; } /* * np_down - a network protocol has gone down. */ void np_down(ppp_pcb *pcb, int proto) { - if (--num_np_up == 0) { + if (--pcb->num_np_up == 0) { UNTIMEOUT(check_idle, (void*)pcb); UNTIMEOUT(connect_time_expired, NULL); #ifdef MAXOCTETS @@ -1232,7 +1207,7 @@ void np_down(ppp_pcb *pcb, int proto) { * np_finished - a network protocol has finished using the link. */ void np_finished(ppp_pcb *pcb, int proto) { - if (--num_np_open <= 0) { + if (--pcb->num_np_open <= 0) { /* no further use for the link: shut up shop. */ lcp_close(0, "No network protocols running"); } diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 0ba348fe..2cf2ab74 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -294,7 +294,7 @@ chap_timeout(void *arg) } else if (ss->challenge_xmits >= chap_max_transmits) { ss->flags &= ~CHALLENGE_VALID; ss->flags |= AUTH_DONE | AUTH_FAILED; - auth_peer_fail(0, PPP_CHAP); + auth_peer_fail(pcb, PPP_CHAP); return; } @@ -426,10 +426,10 @@ chap_handle_response(struct chap_server_state *ss, int id, } if (ss->flags & AUTH_FAILED) { - auth_peer_fail(0, PPP_CHAP); + auth_peer_fail(pcb, PPP_CHAP); } else { if ((ss->flags & AUTH_DONE) == 0) - auth_peer_success(0, PPP_CHAP, + auth_peer_success(pcb, PPP_CHAP, ss->digest->code, name, strlen(name)); if (chap_rechallenge_time) { @@ -621,7 +621,7 @@ chap_protrej(int unit) } if (ss->flags & AUTH_STARTED) { ss->flags = 0; - auth_peer_fail(0, PPP_CHAP); + auth_peer_fail(pcb, PPP_CHAP); } #endif /* PPP_SERVER */ if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index a6605ded..58bd5ed4 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -284,7 +284,7 @@ eap_state *esp; ppp_write(pcb, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); esp->es_server.ea_state = eapBadAuth; - auth_peer_fail(esp->es_unit, PPP_EAP); + auth_peer_fail(pcb, PPP_EAP); } /* @@ -309,7 +309,7 @@ eap_state *esp; ppp_write(pcb, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); - auth_peer_success(esp->es_unit, PPP_EAP, 0, + auth_peer_success(pcb, PPP_EAP, 0, esp->es_server.ea_peer, esp->es_server.ea_peerlen); } #endif /* PPP_SERVER */ diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index c16d8f59..a524e117 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -157,6 +157,7 @@ typedef struct ppp_settings_s { u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ int maxconnect; /* Maximum connect time (seconds) */ + /* auth data */ char user [MAXNAMELEN + 1]; /* Username for PAP */ char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ #if PPP_SERVER @@ -253,6 +254,14 @@ typedef struct ppp_pcb_s { void (*link_status_cb)(void *ctx, int err_code, void *arg); void *link_status_ctx; + /* auth data */ +#if PPP_SERVER + char peer_authname[MAXNAMELEN + 1]; /* The name by which the peer authenticated itself to us. */ +#endif /* PPP_SERVER */ + int auth_pending; /* Records which authentication operations haven't completed yet. */ + int auth_done; /* Records which authentication operations have been completed. */ + int num_np_open; /* Number of network protocols which we have opened. */ + int num_np_up; /* Number of network protocols which have come up. */ } ppp_pcb; /************************ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 6d208c4b..487adb96 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -551,11 +551,12 @@ void upper_layers_down(ppp_pcb *pcb); /* take all NCPs down */ void link_established(ppp_pcb *pcb); /* the link is up; authenticate now */ void start_networks(ppp_pcb *pcb); /* start all the network control protos */ void continue_networks(ppp_pcb *pcb); /* start network [ip, etc] control protos */ - -void auth_peer_fail (int, int); +#if PPP_SERVER +void auth_peer_fail(ppp_pcb *pcb, int protocol); /* peer failed to authenticate itself */ -void auth_peer_success (int, int, int, char *, int); +void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, char *name, int namelen); /* peer successfully authenticated itself */ +#endif /* PPP_SERVER */ void auth_withpeer_fail(ppp_pcb *pcb, int protocol); /* we failed to authenticate ourselves */ void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor); diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 29a71eff..df6ea1fe 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -252,7 +252,7 @@ upap_reqtimeout(arg) if (u->us_serverstate != UPAPSS_LISTEN) return; /* huh?? */ - auth_peer_fail(u->us_unit, PPP_PAP); + auth_peer_fail(pcb, PPP_PAP); u->us_serverstate = UPAPSS_BADAUTH; } #endif /* PPP_SERVER */ @@ -486,11 +486,11 @@ upap_rauthreq(u, inp, id, len) if (retcode == UPAP_AUTHACK) { u->us_serverstate = UPAPSS_OPEN; notice("PAP peer authentication succeeded for %q", rhostname); - auth_peer_success(u->us_unit, PPP_PAP, 0, ruser, ruserlen); + auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen); } else { u->us_serverstate = UPAPSS_BADAUTH; warn("PAP peer authentication failed for %q", rhostname); - auth_peer_fail(u->us_unit, PPP_PAP); + auth_peer_fail(pcb, PPP_PAP); } if (u->us_reqtimeout > 0) From 1ece33e79a8a46e0d1ba773aa3c1107dd40d7cdf Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 15 Jun 2012 00:24:39 +0200 Subject: [PATCH 162/320] PAP and CHAP are now using ppp_pcb* --- src/netif/ppp/auth.c | 7 +- src/netif/ppp/chap-new.c | 311 +++++++++++++++------------------------ src/netif/ppp/chap-new.h | 4 +- src/netif/ppp/ppp.h | 58 ++++++++ src/netif/ppp/upap.c | 291 ++++++++++++++---------------------- src/netif/ppp/upap.h | 35 ++--- 6 files changed, 301 insertions(+), 405 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index b516ad23..12b5e896 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -795,7 +795,7 @@ void link_established(ppp_pcb *pcb) { #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (go->neg_chap) { - chap_auth_peer(unit, pcb->settings.our_name, CHAP_DIGEST(go->chap_mdtype)); + chap_auth_peer(pcb, pcb->settings.our_name, CHAP_DIGEST(go->chap_mdtype)); auth |= CHAP_PEER; } else #endif /* CHAP_SUPPORT */ @@ -816,13 +816,13 @@ void link_established(ppp_pcb *pcb) { #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (ho->neg_chap) { - chap_auth_with_peer(pcb->unit, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); + chap_auth_with_peer(pcb, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if (ho->neg_upap) { - upap_authwithpeer(pcb->unit, pcb->settings.user, pcb->settings.passwd); + upap_authwithpeer(pcb, pcb->settings.user, pcb->settings.passwd); auth |= PAP_WITHPEER; } else #endif /* PAP_SUPPORT */ @@ -832,6 +832,7 @@ void link_established(ppp_pcb *pcb) { pcb->auth_done = 0; if (!auth) + network_phase(pcb); } diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 2cf2ab74..a70e5bdb 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -82,17 +82,6 @@ static option_t chap_option_list[] = { }; #endif /* PPP_OPTIONS */ -/* - * Internal state. - */ -/* FIXME: one client struct per ppp session */ -static struct chap_client_state { - int flags; - char *name; - struct chap_digest_type *digest; - unsigned char priv[64]; /* private area for digest's use */ -} client; - /* * These limits apply to challenge and response packets we send. * The +4 is the +1 that we actually need rounded up. @@ -100,20 +89,6 @@ static struct chap_client_state { #define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) #define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) -#if PPP_SERVER -/* FIXME: one server struct per ppp session */ -static struct chap_server_state { - int flags; - int id; - char *name; - struct chap_digest_type *digest; - int challenge_xmits; - int challenge_pktlen; - unsigned char challenge[CHAL_MAX_PKTLEN]; - char message[256]; -} server; -#endif /* PPP_SERVER */ - /* Values for flags in chap_client_state and chap_server_state */ #define LOWERUP 1 #define AUTH_STARTED 2 @@ -130,17 +105,17 @@ static void chap_lowerup(int unit); static void chap_lowerdown(int unit); #if PPP_SERVER static void chap_timeout(void *arg); -static void chap_generate_challenge(struct chap_server_state *ss); -static void chap_handle_response(struct chap_server_state *ss, int code, +static void chap_generate_challenge(ppp_pcb *pcb); +static void chap_handle_response(ppp_pcb *pcb, int code, unsigned char *pkt, int len); static int chap_verify_response(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space); #endif /* PPP_SERVER */ -static void chap_respond(struct chap_client_state *cs, int id, +static void chap_respond(ppp_pcb *pcb, int id, unsigned char *pkt, int len); -static void chap_handle_status(struct chap_client_state *cs, int code, int id, +static void chap_handle_status(ppp_pcb *pcb, int code, int id, unsigned char *pkt, int len); static void chap_protrej(int unit); static void chap_input(int unit, unsigned char *pkt, int pktlen); @@ -155,12 +130,12 @@ static struct chap_digest_type *chap_digests; /* * chap_init - reset to initial state. */ -static void -chap_init(int unit) -{ - memset(&client, 0, sizeof(client)); +static void chap_init(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + + memset(&pcb->chap_client, 0, sizeof(chap_client_state)); #if PPP_SERVER - memset(&server, 0, sizeof(server)); + memset(&pcb->chap_server, 0, sizeof(chap_server_state)); #endif /* PPP_SERVER */ chap_md5_init(); @@ -172,9 +147,7 @@ chap_init(int unit) /* * Add a new digest type to the list. */ -void -chap_register_digest(struct chap_digest_type *dp) -{ +void chap_register_digest(struct chap_digest_type *dp) { dp->next = chap_digests; chap_digests = dp; } @@ -182,35 +155,25 @@ chap_register_digest(struct chap_digest_type *dp) /* * chap_lowerup - we can start doing stuff now. */ -static void -chap_lowerup(int unit) -{ - struct chap_client_state *cs = &client; -#if PPP_SERVER - struct chap_server_state *ss = &server; -#endif /* PPP_SERVER */ +static void chap_lowerup(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; - cs->flags |= LOWERUP; + pcb->chap_client.flags |= LOWERUP; #if PPP_SERVER - ss->flags |= LOWERUP; - if (ss->flags & AUTH_STARTED) - chap_timeout(ss); + pcb->chap_server.flags |= LOWERUP; + if (pcb->chap_server.flags & AUTH_STARTED) + chap_timeout(pcb); #endif /* PPP_SERVER */ } -static void -chap_lowerdown(int unit) -{ - struct chap_client_state *cs = &client; -#if PPP_SERVER - struct chap_server_state *ss = &server; -#endif /* PPP_SERVER */ +static void chap_lowerdown(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; - cs->flags = 0; + pcb->chap_client.flags = 0; #if PPP_SERVER - if (ss->flags & TIMEOUT_PENDING) - UNTIMEOUT(chap_timeout, ss); - ss->flags = 0; + if (pcb->chap_server.flags & TIMEOUT_PENDING) + UNTIMEOUT(chap_timeout, pcb); + pcb->chap_server.flags = 0; #endif /* PPP_SERVER */ } @@ -220,13 +183,11 @@ chap_lowerdown(int unit) * If the lower layer is already up, we start sending challenges, * otherwise we wait for the lower layer to come up. */ -void -chap_auth_peer(int unit, char *our_name, int digest_code) -{ +void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code) { struct chap_server_state *ss = &server; struct chap_digest_type *dp; - if (ss->flags & AUTH_STARTED) { + if (pcb->chap_server.flags & AUTH_STARTED) { error("CHAP: peer authentication already started!"); return; } @@ -237,12 +198,12 @@ chap_auth_peer(int unit, char *our_name, int digest_code) fatal("CHAP digest 0x%x requested but not available", digest_code); - ss->digest = dp; - ss->name = our_name; + pcb->chap_server.digest = dp; + pcb->chap_server.name = our_name; /* Start with a random ID value */ - ss->id = (unsigned char)(drand48() * 256); - ss->flags |= AUTH_STARTED; - if (ss->flags & LOWERUP) + pcb->chap_server.id = (unsigned char)(drand48() * 256); + pcb->chap_server.flags |= AUTH_STARTED; + if (pcb->chap_server.flags & LOWERUP) chap_timeout(ss); } #endif /* PPP_SERVER */ @@ -251,13 +212,10 @@ chap_auth_peer(int unit, char *our_name, int digest_code) * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. * There isn't much to do until we receive a challenge. */ -void -chap_auth_with_peer(int unit, char *our_name, int digest_code) -{ - struct chap_client_state *cs = &client; +void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code) { struct chap_digest_type *dp; - if (cs->flags & AUTH_STARTED) { + if (pcb->chap_client.flags & AUTH_STARTED) { error("CHAP: authentication with peer already started!"); return; } @@ -268,9 +226,9 @@ chap_auth_with_peer(int unit, char *our_name, int digest_code) fatal("CHAP digest 0x%x requested but not available", digest_code); - cs->digest = dp; - cs->name = our_name; - cs->flags |= AUTH_STARTED; + pcb->chap_client.digest = dp; + pcb->chap_client.name = our_name; + pcb->chap_client.flags |= AUTH_STARTED; } # if PPP_SERVER @@ -279,55 +237,49 @@ chap_auth_with_peer(int unit, char *our_name, int digest_code) * This could be either a retransmission of a previous challenge, * or a new challenge to start re-authentication. */ -static void -chap_timeout(void *arg) -{ - /* FIXME: fix forced unit 0 */ - ppp_pcb *pcb = &ppp_pcb_list[0]; - struct chap_server_state *ss = arg; +static void chap_timeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; - ss->flags &= ~TIMEOUT_PENDING; - if ((ss->flags & CHALLENGE_VALID) == 0) { - ss->challenge_xmits = 0; - chap_generate_challenge(ss); - ss->flags |= CHALLENGE_VALID; - } else if (ss->challenge_xmits >= chap_max_transmits) { - ss->flags &= ~CHALLENGE_VALID; - ss->flags |= AUTH_DONE | AUTH_FAILED; + pcb->chap_server.flags &= ~TIMEOUT_PENDING; + if ((pcb->chap_server.flags & CHALLENGE_VALID) == 0) { + pcb->chap_server.challenge_xmits = 0; + chap_generate_challenge(pcb); + pcb->chap_server.flags |= CHALLENGE_VALID; + } else if (pcb->chap_server.challenge_xmits >= chap_max_transmits) { + pcb->chap_server.flags &= ~CHALLENGE_VALID; + pcb->chap_server.flags |= AUTH_DONE | AUTH_FAILED; auth_peer_fail(pcb, PPP_CHAP); return; } - ppp_write(pcb, ss->challenge, ss->challenge_pktlen); - ++ss->challenge_xmits; - ss->flags |= TIMEOUT_PENDING; + ppp_write(pcb, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); + ++pcb->chap_server.challenge_xmits; + pcb->chap_server.flags |= TIMEOUT_PENDING; TIMEOUT(chap_timeout, arg, chap_timeout_time); } /* * chap_generate_challenge - generate a challenge string and format - * the challenge packet in ss->challenge_pkt. + * the challenge packet in pcb->chap_server.challenge_pkt. */ -static void -chap_generate_challenge(struct chap_server_state *ss) -{ +static void chap_generate_challenge(ppp_pcb *pcb) { int clen = 1, nlen, len; unsigned char *p; - p = ss->challenge; + p = pcb->chap_server.challenge; MAKEHEADER(p, PPP_CHAP); p += CHAP_HDRLEN; - ss->digest->generate_challenge(p); + pcb->chap_server.digest->generate_challenge(p); clen = *p; - nlen = strlen(ss->name); - memcpy(p + 1 + clen, ss->name, nlen); + nlen = strlen(pcb->chap_server.name); + memcpy(p + 1 + clen, pcb->chap_server.name, nlen); len = CHAP_HDRLEN + 1 + clen + nlen; - ss->challenge_pktlen = PPP_HDRLEN + len; + pcb->chap_server.challenge_pktlen = PPP_HDRLEN + len; - p = ss->challenge + PPP_HDRLEN; + p = pcb->chap_server.challenge + PPP_HDRLEN; p[0] = CHAP_CHALLENGE; - p[1] = ++ss->id; + p[1] = ++pcb->chap_server.id; p[2] = len >> 8; p[3] = len; } @@ -335,12 +287,8 @@ chap_generate_challenge(struct chap_server_state *ss) /* * chap_handle_response - check the response to our challenge. */ -static void -chap_handle_response(struct chap_server_state *ss, int id, - unsigned char *pkt, int len) -{ - /* FIXME: fix forced unit 0 */ - ppp_pcb *pcb = &ppp_pcb_list[0]; +static void chap_handle_response(ppp_pcb *pcb, int id, + unsigned char *pkt, int len) { int response_len, ok, mlen; unsigned char *response, *p; char *name = NULL; /* initialized to shut gcc up */ @@ -348,11 +296,11 @@ chap_handle_response(struct chap_server_state *ss, int id, unsigned char *, unsigned char *, char *, int); char rname[MAXNAMELEN+1]; - if ((ss->flags & LOWERUP) == 0) + if ((pcb->chap_server.flags & LOWERUP) == 0) return; - if (id != ss->challenge[PPP_HDRLEN+1] || len < 2) + if (id != pcb->chap_server.challenge[PPP_HDRLEN+1] || len < 2) return; - if (ss->flags & CHALLENGE_VALID) { + if (pcb->chap_server.flags & CHALLENGE_VALID) { response = pkt; GETCHAR(response_len, pkt); len -= response_len + 1; /* length of name */ @@ -360,9 +308,9 @@ chap_handle_response(struct chap_server_state *ss, int id, if (len < 0) return; - if (ss->flags & TIMEOUT_PENDING) { - ss->flags &= ~TIMEOUT_PENDING; - UNTIMEOUT(chap_timeout, ss); + if (pcb->chap_server.flags & TIMEOUT_PENDING) { + pcb->chap_server.flags &= ~TIMEOUT_PENDING; + UNTIMEOUT(chap_timeout, pcb); } if (explicit_remote) { @@ -377,35 +325,35 @@ chap_handle_response(struct chap_server_state *ss, int id, verifier = chap_verify_hook; else verifier = chap_verify_response; - ok = (*verifier)(name, ss->name, id, ss->digest, - ss->challenge + PPP_HDRLEN + CHAP_HDRLEN, - response, ss->message, sizeof(ss->message)); + ok = (*verifier)(name, pcb->chap_server.name, id, pcb->chap_server.digest, + pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN, + response, pcb->chap_server.message, sizeof(pcb->chap_server.message)); #if 0 /* UNUSED */ if (!ok || !auth_number()) { #endif /* UNUSED */ if (!ok) { - ss->flags |= AUTH_FAILED; + pcb->chap_server.flags |= AUTH_FAILED; warn("Peer %q failed CHAP authentication", name); } - } else if ((ss->flags & AUTH_DONE) == 0) + } else if ((pcb->chap_server.flags & AUTH_DONE) == 0) return; /* send the response */ p = outpacket_buf; MAKEHEADER(p, PPP_CHAP); - mlen = strlen(ss->message); + mlen = strlen(pcb->chap_server.message); len = CHAP_HDRLEN + mlen; - p[0] = (ss->flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; + p[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; p[1] = id; p[2] = len >> 8; p[3] = len; if (mlen > 0) - memcpy(p + CHAP_HDRLEN, ss->message, mlen); + memcpy(p + CHAP_HDRLEN, pcb->chap_server.message, mlen); ppp_write(pcb, outpacket_buf, PPP_HDRLEN + len); - if (ss->flags & CHALLENGE_VALID) { - ss->flags &= ~CHALLENGE_VALID; - if (!(ss->flags & AUTH_DONE) && !(ss->flags & AUTH_FAILED)) { + if (pcb->chap_server.flags & CHALLENGE_VALID) { + pcb->chap_server.flags &= ~CHALLENGE_VALID; + if (!(pcb->chap_server.flags & AUTH_DONE) && !(pcb->chap_server.flags & AUTH_FAILED)) { #if 0 /* UNUSED */ /* @@ -419,26 +367,26 @@ chap_handle_response(struct chap_server_state *ss, int id, */ if (session_mgmt && session_check(name, NULL, devnam, NULL) == 0) { - ss->flags |= AUTH_FAILED; + pcb->chap_server.flags |= AUTH_FAILED; warn("Peer %q failed CHAP Session verification", name); } #endif /* UNUSED */ } - if (ss->flags & AUTH_FAILED) { + if (pcb->chap_server.flags & AUTH_FAILED) { auth_peer_fail(pcb, PPP_CHAP); } else { - if ((ss->flags & AUTH_DONE) == 0) + if ((pcb->chap_server.flags & AUTH_DONE) == 0) auth_peer_success(pcb, PPP_CHAP, - ss->digest->code, + pcb->chap_server.digest->code, name, strlen(name)); if (chap_rechallenge_time) { - ss->flags |= TIMEOUT_PENDING; - TIMEOUT(chap_timeout, ss, + pcb->chap_server.flags |= TIMEOUT_PENDING; + TIMEOUT(chap_timeout, pcb, chap_rechallenge_time); } } - ss->flags |= AUTH_DONE; + pcb->chap_server.flags |= AUTH_DONE; } } @@ -447,12 +395,10 @@ chap_handle_response(struct chap_server_state *ss, int id, * what we think it should be. Returns 1 if it does (authentication * succeeded), or 0 if it doesn't. */ -static int -chap_verify_response(char *name, char *ourname, int id, +static int chap_verify_response(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, - char *message, int message_space) -{ + char *message, int message_space) { int ok; unsigned char secret[MAXSECRETLEN]; int secret_len; @@ -474,12 +420,8 @@ chap_verify_response(char *name, char *ourname, int id, /* * chap_respond - Generate and send a response to a challenge. */ -static void -chap_respond(struct chap_client_state *cs, int id, - unsigned char *pkt, int len) -{ - /* FIXME: fix forced unit 0 */ - ppp_pcb *pcb = &ppp_pcb_list[0]; +static void chap_respond(ppp_pcb *pcb, int id, + unsigned char *pkt, int len) { int clen, nlen; int secret_len; unsigned char *p; @@ -488,7 +430,7 @@ chap_respond(struct chap_client_state *cs, int id, char secret[MAXSECRETLEN+1]; ppp_pcb *pc = &ppp_pcb_list[0]; - if ((cs->flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) + if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) return; /* not ready */ if (len < 2 || len < pkt[0] + 1) return; /* too short */ @@ -503,7 +445,7 @@ chap_respond(struct chap_client_state *cs, int id, strlcpy(rname, pc->settings.remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ - if (!get_secret(pcb, cs->name, rname, secret, &secret_len, 0)) { + if (!get_secret(pcb, pcb->chap_client.name, rname, 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", rname); } @@ -512,13 +454,13 @@ chap_respond(struct chap_client_state *cs, int id, MAKEHEADER(p, PPP_CHAP); p += CHAP_HDRLEN; - cs->digest->make_response(p, id, cs->name, pkt, - secret, secret_len, cs->priv); + pcb->chap_client.digest->make_response(p, id, pcb->chap_client.name, pkt, + secret, secret_len, pcb->chap_client.priv); memset(secret, 0, secret_len); clen = *p; - nlen = strlen(cs->name); - memcpy(p + clen + 1, cs->name, nlen); + nlen = strlen(pcb->chap_client.name); + memcpy(p + clen + 1, pcb->chap_client.name, nlen); p = response + PPP_HDRLEN; len = CHAP_HDRLEN + clen + 1 + nlen; @@ -530,29 +472,25 @@ chap_respond(struct chap_client_state *cs, int id, ppp_write(pcb, response, PPP_HDRLEN + len); } -static void -chap_handle_status(struct chap_client_state *cs, int code, int id, - unsigned char *pkt, int len) -{ - /* FIXME: fix forced unit 0 */ - ppp_pcb *pcb = &ppp_pcb_list[0]; +static void chap_handle_status(ppp_pcb *pcb, int code, int id, + unsigned char *pkt, int len) { const char *msg = NULL; - if ((cs->flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) + if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) != (AUTH_STARTED|LOWERUP)) return; - cs->flags |= AUTH_DONE; + pcb->chap_client.flags |= AUTH_DONE; if (code == CHAP_SUCCESS) { /* used for MS-CHAP v2 mutual auth, yuck */ - if (cs->digest->check_success != NULL) { - if (!(*cs->digest->check_success)(pkt, len, cs->priv)) + if (pcb->chap_client.digest->check_success != NULL) { + if (!(*pcb->chap_client.digest->check_success)(pkt, len, pcb->chap_client.priv)) code = CHAP_FAILURE; } else msg = "CHAP authentication succeeded"; } else { - if (cs->digest->handle_failure != NULL) - (*cs->digest->handle_failure)(pkt, len); + if (pcb->chap_client.digest->handle_failure != NULL) + (*pcb->chap_client.digest->handle_failure)(pkt, len); else msg = "CHAP authentication failed"; } @@ -563,22 +501,16 @@ chap_handle_status(struct chap_client_state *cs, int code, int id, info("%s", msg); } if (code == CHAP_SUCCESS) - auth_withpeer_success(pcb, PPP_CHAP, cs->digest->code); + auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code); else { - cs->flags |= AUTH_FAILED; + pcb->chap_client.flags |= AUTH_FAILED; error("CHAP authentication failed"); auth_withpeer_fail(pcb, PPP_CHAP); } } -static void -chap_input(int unit, unsigned char *pkt, int pktlen) -{ - struct chap_client_state *cs = &client; -#if PPP_SERVER - struct chap_server_state *ss = &server; -#endif /* PPP_SERVER */ - +static void chap_input(int unit, unsigned char *pkt, int pktlen) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; unsigned char code, id; int len; @@ -593,39 +525,35 @@ chap_input(int unit, unsigned char *pkt, int pktlen) switch (code) { case CHAP_CHALLENGE: - chap_respond(cs, id, pkt, len); + chap_respond(pcb, id, pkt, len); break; #if PPP_SERVER case CHAP_RESPONSE: - chap_handle_response(ss, id, pkt, len); + chap_handle_response(pcb, id, pkt, len); break; #endif /* PPP_SERVER */ case CHAP_FAILURE: case CHAP_SUCCESS: - chap_handle_status(cs, code, id, pkt, len); + chap_handle_status(pcb, code, id, pkt, len); break; } } -static void -chap_protrej(int unit) -{ +static void chap_protrej(int unit) { ppp_pcb *pcb = &ppp_pcb_list[unit]; - struct chap_client_state *cs = &client; -#if PPP_SERVER - struct chap_server_state *ss = &server; - if (ss->flags & TIMEOUT_PENDING) { - ss->flags &= ~TIMEOUT_PENDING; - UNTIMEOUT(chap_timeout, ss); +#if PPP_SERVER + if (pcb->chap_server.flags & TIMEOUT_PENDING) { + pcb->chap_server.flags &= ~TIMEOUT_PENDING; + UNTIMEOUT(chap_timeout, pcb); } - if (ss->flags & AUTH_STARTED) { - ss->flags = 0; + if (pcb->chap_server.flags & AUTH_STARTED) { + pcb->chap_server.flags = 0; auth_peer_fail(pcb, PPP_CHAP); } #endif /* PPP_SERVER */ - if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { - cs->flags &= ~AUTH_STARTED; + if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { + pcb->chap_client.flags &= ~AUTH_STARTED; error("CHAP authentication failed due to protocol-reject"); auth_withpeer_fail(pcb, PPP_CHAP); } @@ -639,10 +567,8 @@ static char *chap_code_names[] = { "Challenge", "Response", "Success", "Failure" }; -static int -chap_print_pkt(unsigned char *p, int plen, - void (*printer) (void *, char *, ...), void *arg) -{ +static int chap_print_pkt(unsigned char *p, int plen, + void (*printer) (void *, char *, ...), void *arg) { int code, id, len; int clen, nlen; unsigned char x; @@ -689,6 +615,7 @@ chap_print_pkt(unsigned char *p, int plen, GETCHAR(x, p); printer(arg, " %.2x", x); } + /* no break */ } return len + CHAP_HDRLEN; diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h index 0713dca8..902fed7e 100644 --- a/src/netif/ppp/chap-new.h +++ b/src/netif/ppp/chap-new.h @@ -151,11 +151,11 @@ extern void chap_register_digest(struct chap_digest_type *); #if PPP_SERVER /* Called by authentication code to start authenticating the peer. */ -extern void chap_auth_peer(int unit, char *our_name, int digest_code); +extern void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code); #endif /* PPP_SERVER */ /* Called by auth. code to start authenticating us to the peer. */ -extern void chap_auth_with_peer(int unit, char *our_name, int digest_code); +extern void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code); /* Represents the CHAP protocol to the main pppd code */ extern struct protent chap_protent; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index a524e117..dde28bf5 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -214,6 +214,53 @@ typedef struct ppp_pcb_rx_s { } ppp_pcb_rx; #endif /* PPPOS_SUPPORT */ +/* + * Each interface is described by upap structure. + */ +#if PAP_SUPPORT +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 */ +#if PPP_SERVER + int us_serverstate; /* Server state */ +#endif /* PPP_SERVER */ + 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; +#endif /* PAP_SUPPORT */ + +/* + * Each interface is described by chap structure. + */ +#if CHAP_SUPPORT +typedef struct chap_client_state { + int flags; + char *name; + struct chap_digest_type *digest; + unsigned char priv[64]; /* private area for digest's use */ +} chap_client_state; + +#if PPP_SERVER +static struct chap_server_state { + int flags; + int id; + char *name; + struct chap_digest_type *digest; + int challenge_xmits; + int challenge_pktlen; + unsigned char challenge[CHAL_MAX_PKTLEN]; + char message[256]; +} chap_server_state; +#endif /* PPP_SERVER */ +#endif /* CHAP_SUPPORT */ + /* * PPP interface control block. */ @@ -262,6 +309,17 @@ typedef struct ppp_pcb_s { int auth_done; /* Records which authentication operations have been completed. */ int num_np_open; /* Number of network protocols which we have opened. */ int num_np_up; /* Number of network protocols which have come up. */ + +#if PAP_SUPPORT + upap_state upap; /* PAP data */ +#endif /* PAP_SUPPORT */ + +#if CHAP_SUPPORT + chap_client_state chap_client; +#if PPP_SERVER + chap_server_state chap_server; +#endif /* PPP_SERVER */ +#endif /* CHAP_SUPPORT */ } ppp_pcb; /************************ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index df6ea1fe..f498044f 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -80,14 +80,13 @@ static option_t pap_option_list[] = { /* * 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 void upap_init(int unit); +static void upap_lowerup(int unit); +static void upap_lowerdown(int unit); +static void upap_input(int unit, u_char *inpacket, int l); +static void upap_protrej(int unit); #if PRINTPKT_SUPPORT -static int upap_printpkt (u_char *, int, - void (*) (void *, char *, ...), void *); +static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ struct protent pap_protent = { @@ -118,45 +117,40 @@ struct protent pap_protent = { #endif /* DEMAND_SUPPORT */ }; -upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ - -static void upap_timeout (void *); +static void upap_timeout(void *arg); #if PPP_SERVER -static void upap_reqtimeout (void *); +static void upap_reqtimeout(void *arg); #endif /* PPP_SERVER */ #if 0 /* UNUSED */ -static void upap_rauthreq (upap_state *, u_char *, int, int); +static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len); #endif /* UNUSED */ -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_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len); +static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len); +static void upap_sauthreq(ppp_pcb *pcb); #if 0 /* UNUSED */ -static void upap_sresp (upap_state *, int, int, char *, int); +static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msglen); #endif /* UNUSED */ /* * upap_init - Initialize a UPAP unit. */ -static void -upap_init(unit) - int unit; -{ - upap_state *u = &upap[unit]; +static void upap_init(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[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; + pcb->upap.us_unit = unit; + pcb->upap.us_user = NULL; + pcb->upap.us_userlen = 0; + pcb->upap.us_passwd = NULL; + pcb->upap.us_passwdlen = 0; + pcb->upap.us_clientstate = UPAPCS_INITIAL; #if PPP_SERVER - u->us_serverstate = UPAPSS_INITIAL; + pcb->upap.us_serverstate = UPAPSS_INITIAL; #endif /* PPP_SERVER */ - u->us_id = 0; - u->us_timeouttime = UPAP_DEFTIMEOUT; - u->us_maxtransmits = 10; - u->us_reqtimeout = UPAP_DEFREQTIME; + pcb->upap.us_id = 0; + pcb->upap.us_timeouttime = UPAP_DEFTIMEOUT; + pcb->upap.us_maxtransmits = 10; + pcb->upap.us_reqtimeout = UPAP_DEFREQTIME; } @@ -165,28 +159,22 @@ upap_init(unit) * * Set new state and send authenticate's. */ -void -upap_authwithpeer(unit, user, password) - int unit; - char *user, *password; -{ - upap_state *u = &upap[unit]; - +void upap_authwithpeer(ppp_pcb *pcb, char *user, char *password) { /* 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; + pcb->upap.us_user = user; + pcb->upap.us_userlen = strlen(user); + pcb->upap.us_passwd = password; + pcb->upap.us_passwdlen = strlen(password); + pcb->upap.us_transmits = 0; /* Lower layer up yet? */ - if (u->us_clientstate == UPAPCS_INITIAL || - u->us_clientstate == UPAPCS_PENDING) { - u->us_clientstate = UPAPCS_PENDING; + if (pcb->upap.us_clientstate == UPAPCS_INITIAL || + pcb->upap.us_clientstate == UPAPCS_PENDING) { + pcb->upap.us_clientstate = UPAPCS_PENDING; return; } - upap_sauthreq(u); /* Start protocol */ + upap_sauthreq(pcb); /* Start protocol */ } #if PPP_SERVER @@ -195,47 +183,39 @@ upap_authwithpeer(unit, user, password) * * Set new state. */ -void -upap_authpeer(unit) - int unit; -{ - upap_state *u = &upap[unit]; +void upap_authpeer(ppp_pcb *pcb) { /* Lower layer up yet? */ - if (u->us_serverstate == UPAPSS_INITIAL || - u->us_serverstate == UPAPSS_PENDING) { - u->us_serverstate = UPAPSS_PENDING; + if (pcb->upap.us_serverstate == UPAPSS_INITIAL || + pcb->upap.us_serverstate == UPAPSS_PENDING) { + pcb->upap.us_serverstate = UPAPSS_PENDING; return; } - u->us_serverstate = UPAPSS_LISTEN; - if (u->us_reqtimeout > 0) - TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); + pcb->upap.us_serverstate = UPAPSS_LISTEN; + if (pcb->upap.us_reqtimeout > 0) + TIMEOUT(upap_reqtimeout, pcb, pcb->upap.us_reqtimeout); } #endif /* PPP_SERVER */ /* * upap_timeout - Retransmission timer for sending auth-reqs expired. */ -static void -upap_timeout(arg) - void *arg; -{ - upap_state *u = (upap_state *) arg; - ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; +static void upap_timeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; - if (u->us_clientstate != UPAPCS_AUTHREQ) + if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) return; - if (u->us_transmits >= u->us_maxtransmits) { + if (pcb->upap.us_transmits >= pcb->upap.us_maxtransmits) { /* give up in disgust */ error("No response to PAP authenticate-requests"); - u->us_clientstate = UPAPCS_BADAUTH; + pcb->upap.us_clientstate = UPAPCS_BADAUTH; auth_withpeer_fail(pcb, PPP_PAP); return; } - upap_sauthreq(u); /* Send Authenticate-Request */ + upap_sauthreq(pcb); /* Send Authenticate-Request */ } @@ -243,17 +223,14 @@ upap_timeout(arg) /* * upap_reqtimeout - Give up waiting for the peer to send an auth-req. */ -static void -upap_reqtimeout(arg) - void *arg; -{ - upap_state *u = (upap_state *) arg; +static void upap_reqtimeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; - if (u->us_serverstate != UPAPSS_LISTEN) + if (pcb->upap.us_serverstate != UPAPSS_LISTEN) return; /* huh?? */ auth_peer_fail(pcb, PPP_PAP); - u->us_serverstate = UPAPSS_BADAUTH; + pcb->upap.us_serverstate = UPAPSS_BADAUTH; } #endif /* PPP_SERVER */ @@ -263,25 +240,22 @@ upap_reqtimeout(arg) * * Start authenticating if pending. */ -static void -upap_lowerup(unit) - int unit; -{ - upap_state *u = &upap[unit]; +static void upap_lowerup(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[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 (pcb->upap.us_clientstate == UPAPCS_INITIAL) + pcb->upap.us_clientstate = UPAPCS_CLOSED; + else if (pcb->upap.us_clientstate == UPAPCS_PENDING) { + upap_sauthreq(pcb); /* send an auth-request */ } #if PPP_SERVER - 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); + if (pcb->upap.us_serverstate == UPAPSS_INITIAL) + pcb->upap.us_serverstate = UPAPSS_CLOSED; + else if (pcb->upap.us_serverstate == UPAPSS_PENDING) { + pcb->upap.us_serverstate = UPAPSS_LISTEN; + if (pcb->upap.us_reqtimeout > 0) + TIMEOUT(upap_reqtimeout, u, pcb->upap.us_reqtimeout); } #endif /* PPP_SERVER */ } @@ -292,22 +266,19 @@ upap_lowerup(unit) * * Cancel all timeouts. */ -static void -upap_lowerdown(unit) - int unit; -{ - upap_state *u = &upap[unit]; +static void upap_lowerdown(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; - if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ - UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ + if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ + UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */ #if PPP_SERVER - if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) + if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->upap.us_reqtimeout > 0) UNTIMEOUT(upap_reqtimeout, u); #endif /* PPP_SERVER */ - u->us_clientstate = UPAPCS_INITIAL; + pcb->upap.us_clientstate = UPAPCS_INITIAL; #if PPP_SERVER - u->us_serverstate = UPAPSS_INITIAL; + pcb->upap.us_serverstate = UPAPSS_INITIAL; #endif /* PPP_SERVER */ } @@ -317,19 +288,15 @@ upap_lowerdown(unit) * * This shouldn't happen. In any case, pretend lower layer went down. */ -static void -upap_protrej(unit) - int unit; -{ - upap_state *u = &upap[unit]; - ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; +static void upap_protrej(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; - if (u->us_clientstate == UPAPCS_AUTHREQ) { + if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) { error("PAP authentication failed due to protocol-reject"); auth_withpeer_fail(pcb, PPP_PAP); } #if PPP_SERVER - if (u->us_serverstate == UPAPSS_LISTEN) { + if (pcb->upap.us_serverstate == UPAPSS_LISTEN) { error("PAP authentication of peer failed (protocol-reject)"); auth_peer_fail(pcb, PPP_PAP); } @@ -341,13 +308,8 @@ upap_protrej(unit) /* * upap_input - Input UPAP packet. */ -static void -upap_input(unit, inpacket, l) - int unit; - u_char *inpacket; - int l; -{ - upap_state *u = &upap[unit]; +static void upap_input(int unit, u_char *inpacket, int l) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; u_char *inp; u_char code, id; int len; @@ -380,16 +342,16 @@ upap_input(unit, inpacket, l) switch (code) { case UPAP_AUTHREQ: #if 0 /* UNUSED */ - upap_rauthreq(u, inp, id, len); + upap_rauthreq(pcb, inp, id, len); #endif /* UNUSED */ break; case UPAP_AUTHACK: - upap_rauthack(u, inp, id, len); + upap_rauthack(pcb, inp, id, len); break; case UPAP_AUTHNAK: - upap_rauthnak(u, inp, id, len); + upap_rauthnak(pcb, inp, id, len); break; default: /* XXX Need code reject */ @@ -401,13 +363,7 @@ upap_input(unit, inpacket, l) /* * upap_rauth - Receive Authenticate. */ -static void -upap_rauthreq(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; -{ +static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) { u_char ruserlen, rpasswdlen; char *ruser, *rpasswd; char rhostname[256]; @@ -415,18 +371,18 @@ upap_rauthreq(u, inp, id, len) char *msg; int msglen; - if (u->us_serverstate < UPAPSS_LISTEN) + if (pcb->upap.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) { + if (pcb->upap.us_serverstate == UPAPSS_OPEN) { upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ return; } - if (u->us_serverstate == UPAPSS_BADAUTH) { + if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) { upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ return; } @@ -456,7 +412,7 @@ upap_rauthreq(u, inp, id, len) /* * Check the username and password given. */ - retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, + retcode = check_passwd(pcb->upap.us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg); BZERO(rpasswd, rpasswdlen); @@ -484,16 +440,16 @@ upap_rauthreq(u, inp, id, len) slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); if (retcode == UPAP_AUTHACK) { - u->us_serverstate = UPAPSS_OPEN; + pcb->upap.us_serverstate = UPAPSS_OPEN; notice("PAP peer authentication succeeded for %q", rhostname); auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen); } else { - u->us_serverstate = UPAPSS_BADAUTH; + pcb->upap.us_serverstate = UPAPSS_BADAUTH; warn("PAP peer authentication failed for %q", rhostname); auth_peer_fail(pcb, PPP_PAP); } - if (u->us_reqtimeout > 0) + if (pcb->upap.us_reqtimeout > 0) UNTIMEOUT(upap_reqtimeout, u); } #endif /* UNUSED */ @@ -501,18 +457,11 @@ upap_rauthreq(u, inp, id, len) /* * upap_rauthack - Receive Authenticate-Ack. */ -static void -upap_rauthack(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; +static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len) { u_char msglen; char *msg; - if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ + if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */ return; /* @@ -533,7 +482,7 @@ upap_rauthack(u, inp, id, len) } } - u->us_clientstate = UPAPCS_OPEN; + pcb->upap.us_clientstate = UPAPCS_OPEN; auth_withpeer_success(pcb, PPP_PAP, 0); } @@ -542,18 +491,11 @@ upap_rauthack(u, inp, id, len) /* * upap_rauthnak - Receive Authenticate-Nak. */ -static void -upap_rauthnak(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; +static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) { u_char msglen; char *msg; - if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ + if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */ return; /* @@ -574,7 +516,7 @@ upap_rauthnak(u, inp, id, len) } } - u->us_clientstate = UPAPCS_BADAUTH; + pcb->upap.us_clientstate = UPAPCS_BADAUTH; error("PAP authentication failed"); auth_withpeer_fail(pcb, PPP_PAP); @@ -584,48 +526,37 @@ upap_rauthnak(u, inp, id, len) /* * upap_sauthreq - Send an Authenticate-Request. */ -static void -upap_sauthreq(u) - upap_state *u; -{ - ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; +static void upap_sauthreq(ppp_pcb *pcb) { u_char *outp; int outlen; outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + - u->us_userlen + u->us_passwdlen; + pcb->upap.us_userlen + pcb->upap.us_passwdlen; outp = outpacket_buf; MAKEHEADER(outp, PPP_PAP); PUTCHAR(UPAP_AUTHREQ, outp); - PUTCHAR(++u->us_id, outp); + PUTCHAR(++pcb->upap.us_id, outp); PUTSHORT(outlen, outp); - PUTCHAR(u->us_userlen, outp); - MEMCPY(outp, u->us_user, u->us_userlen); - INCPTR(u->us_userlen, outp); - PUTCHAR(u->us_passwdlen, outp); - MEMCPY(outp, u->us_passwd, u->us_passwdlen); + PUTCHAR(pcb->upap.us_userlen, outp); + MEMCPY(outp, pcb->upap.us_user, pcb->upap.us_userlen); + INCPTR(pcb->upap.us_userlen, outp); + PUTCHAR(pcb->upap.us_passwdlen, outp); + MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen); ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); - TIMEOUT(upap_timeout, u, u->us_timeouttime); - ++u->us_transmits; - u->us_clientstate = UPAPCS_AUTHREQ; + TIMEOUT(upap_timeout, pcb, pcb->upap.us_timeouttime); + ++pcb->upap.us_transmits; + pcb->upap.us_clientstate = UPAPCS_AUTHREQ; } #if 0 /* UNUSED */ /* * upap_sresp - Send a response (ack or nak). */ -static void -upap_sresp(u, code, id, msg, msglen) - upap_state *u; - u_char code, id; - char *msg; - int msglen; -{ - ppp_pcb *pcb = &ppp_pcb_list[u->us_unit]; +static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msglen) { u_char *outp; int outlen; @@ -650,13 +581,7 @@ static char *upap_codenames[] = { "AuthReq", "AuthAck", "AuthNak" }; -static int -upap_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) (void *, char *, ...); - void *arg; -{ +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; diff --git a/src/netif/ppp/upap.h b/src/netif/ppp/upap.h index c0bdae99..18aaa6d1 100644 --- a/src/netif/ppp/upap.h +++ b/src/netif/ppp/upap.h @@ -45,6 +45,11 @@ #include "lwip/opt.h" #if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#ifndef UPAP_H +#define UPAP_H + +#include "ppp.h" + /* * Packet header = Code, id, length. */ @@ -59,27 +64,6 @@ #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 */ -#if PPP_SERVER - int us_serverstate; /* Server state */ -#endif /* PPP_SERVER */ - 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. */ @@ -109,11 +93,12 @@ typedef struct upap_state { #endif /* moved to opt.h */ #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); +void upap_authwithpeer(ppp_pcb *pcb, char *user, char *password); +#if PPP_SERVER +void upap_authpeer(ppp_pcb *pcb); +#endif /* PPP_SERVER */ extern struct protent pap_protent; +#endif /* UPAP_H */ #endif /* PPP_SUPPORT && PAP_SUPPORT */ From 2deb13df43af3fd2de1bcfcfe9e4d81388639947 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 15 Jun 2012 01:06:27 +0200 Subject: [PATCH 163/320] EAP is now using ppp_pcb as well --- src/netif/ppp/auth.c | 6 +- src/netif/ppp/chap-md5.c | 20 +- src/netif/ppp/chap_ms.c | 129 ++----- src/netif/ppp/chap_ms.h | 2 +- src/netif/ppp/eap.c | 746 +++++++++++++++++---------------------- src/netif/ppp/eap.h | 68 +--- src/netif/ppp/ppp.h | 63 ++++ src/netif/ppp/ppp_impl.h | 4 - 8 files changed, 448 insertions(+), 590 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 12b5e896..1780ad0f 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -789,7 +789,7 @@ void link_established(ppp_pcb *pcb) { #if PPP_SERVER #if EAP_SUPPORT if (go->neg_eap) { - eap_authpeer(unit, pcb->settings.our_name); + eap_authpeer(pcb, pcb->settings.our_name); auth |= EAP_PEER; } else #endif /* EAP_SUPPORT */ @@ -801,7 +801,7 @@ void link_established(ppp_pcb *pcb) { #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if (go->neg_upap) { - upap_authpeer(unit); + upap_authpeer(pcb); auth |= PAP_PEER; } else #endif /* PAP_SUPPORT */ @@ -810,7 +810,7 @@ void link_established(ppp_pcb *pcb) { #if EAP_SUPPORT if (ho->neg_eap) { - eap_authwithpeer(pcb->unit, pcb->settings.user); + eap_authwithpeer(pcb, pcb->settings.user); auth |= EAP_WITHPEER; } else #endif /* EAP_SUPPORT */ diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index d3866e4b..62b69c5f 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -48,9 +48,7 @@ #define MD5_MAX_CHALLENGE 24 #if PPP_SERVER -static void -chap_md5_generate_challenge(unsigned char *cp) -{ +static void chap_md5_generate_challenge(unsigned char *cp) { int clen; clen = (int)(drand48() * (MD5_MAX_CHALLENGE - MD5_MIN_CHALLENGE)) @@ -59,12 +57,10 @@ chap_md5_generate_challenge(unsigned char *cp) random_bytes(cp, clen); } -static int -chap_md5_verify_response(int id, char *name, +static int chap_md5_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, - char *message, int message_space) -{ + char *message, int message_space) { md5_context ctx; unsigned char idbyte = id; unsigned char hash[MD5_HASH_SIZE]; @@ -91,11 +87,9 @@ chap_md5_verify_response(int id, char *name, } #endif /* PPP_SERVER */ -static void -chap_md5_make_response(unsigned char *response, int id, char *our_name, +static void chap_md5_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, - unsigned char *private) -{ + unsigned char *private) { md5_context ctx; unsigned char idbyte = id; int challenge_len = *challenge++; @@ -119,9 +113,7 @@ static struct chap_digest_type md5_digest = { NULL, /* handle_failure */ }; -void -chap_md5_init(void) -{ +void chap_md5_init(void) { chap_register_digest(&md5_digest); } diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 8dde4827..b9f55b34 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -166,9 +166,7 @@ static option_t chapms_option_list[] = { * The length goes in challenge[0] and the actual challenge starts * at challenge[1]. */ -static void -chapms_generate_challenge(unsigned char *challenge) -{ +static void chapms_generate_challenge(unsigned char *challenge) { *challenge++ = 8; #ifdef DEBUGMPPEKEY if (mschap_challenge && strlen(mschap_challenge) == 8) @@ -178,9 +176,7 @@ chapms_generate_challenge(unsigned char *challenge) random_bytes(challenge, 8); } -static void -chapms2_generate_challenge(unsigned char *challenge) -{ +static void chapms2_generate_challenge(unsigned char *challenge) { *challenge++ = 16; #ifdef DEBUGMPPEKEY if (mschap_challenge && strlen(mschap_challenge) == 16) @@ -190,12 +186,10 @@ chapms2_generate_challenge(unsigned char *challenge) random_bytes(challenge, 16); } -static int -chapms_verify_response(int id, char *name, +static int chapms_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, - char *message, int message_space) -{ + char *message, int message_space) { unsigned char md[MS_CHAP_RESPONSE_LEN]; int diff; int challenge_len, response_len; @@ -238,12 +232,10 @@ chapms_verify_response(int id, char *name, return 0; } -static int -chapms2_verify_response(int id, char *name, +static int chapms2_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, - char *message, int message_space) -{ + char *message, int message_space) { unsigned char md[MS_CHAP2_RESPONSE_LEN]; char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; int challenge_len, response_len; @@ -316,21 +308,17 @@ chapms2_verify_response(int id, char *name, } #endif /* PPP_SERVER */ -static void -chapms_make_response(unsigned char *response, int id, char *our_name, +static void chapms_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, - unsigned char *private) -{ + unsigned char *private) { challenge++; /* skip length, should be 8 */ *response++ = MS_CHAP_RESPONSE_LEN; ChapMS(challenge, secret, secret_len, response); } -static void -chapms2_make_response(unsigned char *response, int id, char *our_name, +static void chapms2_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, - unsigned char *private) -{ + unsigned char *private) { challenge++; /* skip length, should be 16 */ *response++ = MS_CHAP2_RESPONSE_LEN; ChapMS2(challenge, @@ -343,9 +331,7 @@ chapms2_make_response(unsigned char *response, int id, char *our_name, MS_CHAP2_AUTHENTICATEE); } -static int -chapms2_check_success(unsigned char *msg, int len, unsigned char *private) -{ +static int chapms2_check_success(unsigned char *msg, int len, unsigned char *private) { if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || strncmp((char *)msg, "S=", 2) != 0) { /* Packet does not start with "S=" */ @@ -373,9 +359,7 @@ chapms2_check_success(unsigned char *msg, int len, unsigned char *private) return 1; } -static void -chapms_handle_failure(unsigned char *inp, int len) -{ +static void chapms_handle_failure(unsigned char *inp, int len) { int err; char *p, msg[64]; @@ -438,11 +422,9 @@ print_msg: error("MS-CHAP authentication failed: %v", p); } -static void -ChallengeResponse(u_char *challenge, +static void ChallengeResponse(u_char *challenge, u_char PasswordHash[MD4_SIGNATURE_SIZE], - u_char response[24]) -{ + u_char response[24]) { u_char ZPasswordHash[21]; des_context des; u_char des_key[8]; @@ -472,11 +454,8 @@ ChallengeResponse(u_char *challenge, #endif } -void -ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, - char *username, u_char Challenge[8]) - -{ +void ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, + char *username, u_char Challenge[8]) { sha1_context sha1Context; u_char sha1Hash[SHA1_SIGNATURE_SIZE]; char *user; @@ -503,9 +482,7 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, * is assumed by all M$ CHAP RFCs. (Unicode byte ordering * is machine-dependent.) */ -static void -ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) -{ +static void ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) { int i; BZERO(unicode, ascii_len * 2); @@ -513,9 +490,7 @@ ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) unicode[i * 2] = (u_char) ascii[i]; } -static void -NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) -{ +static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) { md4_context md4Context; md4_starts(&md4Context); @@ -523,10 +498,8 @@ NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) md4_finish(&md4Context, hash); } -static void -ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, - u_char NTResponse[24]) -{ +static void ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, + u_char NTResponse[24]) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_SIGNATURE_SIZE]; @@ -537,10 +510,8 @@ ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, ChallengeResponse(rchallenge, PasswordHash, NTResponse); } -static void -ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, - char *secret, int secret_len, u_char NTResponse[24]) -{ +static void ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, + char *secret, int secret_len, u_char NTResponse[24]) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char Challenge[8]; @@ -557,10 +528,8 @@ ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, #ifdef MSLANMAN static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ -static void -ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, - unsigned char *response) -{ +static void ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, + unsigned char *response) { int i; u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ u_char PasswordHash[MD4_SIGNATURE_SIZE]; @@ -585,12 +554,10 @@ ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, #endif -void -GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], +void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], u_char PeerChallenge[16], u_char *rchallenge, char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) -{ + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { /* * "Magic" constants used in response generation, from RFC 2759. */ @@ -631,13 +598,11 @@ GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], } -static void -GenerateAuthenticatorResponsePlain +static void GenerateAuthenticatorResponsePlain (char *secret, int secret_len, u_char NTResponse[24], u_char PeerChallenge[16], u_char *rchallenge, char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) -{ + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; @@ -658,9 +623,7 @@ GenerateAuthenticatorResponsePlain * Set mppe_xxxx_key from the NTPasswordHashHash. * RFC 2548 (RADIUS support) requires us to export this function (ugh). */ -void -mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) -{ +void mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) { sha1_context sha1Context; u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ @@ -680,9 +643,7 @@ mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) /* * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) */ -static void -Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) -{ +static void Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; @@ -701,10 +662,8 @@ Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) * This helper function used in the Winbind module, which gets the * NTHashHash from the server. */ -void -mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], int IsServer) -{ +void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], int IsServer) { sha1_context sha1Context; u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ @@ -795,9 +754,7 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], /* * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) */ -static void -SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) -{ +static void SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; @@ -811,10 +768,8 @@ SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) #endif /* MPPE */ -void -ChapMS(u_char *rchallenge, char *secret, int secret_len, - unsigned char *response) -{ +void ChapMS(u_char *rchallenge, char *secret, int secret_len, + unsigned char *response) { BZERO(response, MS_CHAP_RESPONSE_LEN); ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); @@ -845,11 +800,9 @@ ChapMS(u_char *rchallenge, char *secret, int secret_len, * The PeerChallenge field of response is then used for calculation of the * Authenticator Response. */ -void -ChapMS2(u_char *rchallenge, u_char *PeerChallenge, +void ChapMS2(u_char *rchallenge, u_char *PeerChallenge, char *user, char *secret, int secret_len, unsigned char *response, - u_char authResponse[], int authenticator) -{ + u_char authResponse[], int authenticator) { /* ARGSUSED */ u_char *p = &response[MS_CHAP2_PEER_CHALLENGE]; int i; @@ -884,9 +837,7 @@ ChapMS2(u_char *rchallenge, u_char *PeerChallenge, /* * Set MPPE options from plugins. */ -void -set_mppe_enc_types(int policy, int types) -{ +void set_mppe_enc_types(int policy, int types) { /* Early exit for unknown policies. */ if (policy != MPPE_ENC_POL_ENC_ALLOWED || policy != MPPE_ENC_POL_ENC_REQUIRED) @@ -935,9 +886,7 @@ static struct chap_digest_type chapms2_digest = { chapms_handle_failure, }; -void -chapms_init(void) -{ +void chapms_init(void) { chap_register_digest(&chapms_digest); chap_register_digest(&chapms2_digest); #if PPP_OPTIONS diff --git a/src/netif/ppp/chap_ms.h b/src/netif/ppp/chap_ms.h index 70211d3d..7d53dbfd 100644 --- a/src/netif/ppp/chap_ms.h +++ b/src/netif/ppp/chap_ms.h @@ -43,7 +43,7 @@ #define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */ /* as ASCII */ -/* E=eeeeeeeeee error codes for MS-CHAP failure messages. */ +/* Error codes for MS-CHAP failure messages. */ #define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646 #define MS_CHAP_ERROR_ACCT_DISABLED 647 #define MS_CHAP_ERROR_PASSWD_EXPIRED 648 diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 58bd5ed4..4f8747bb 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -62,7 +62,6 @@ #define SHA_DIGESTSIZE 20 #endif -eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */ #ifdef USE_SRP static char *pn_secret = NULL; /* Pseudonym generating secret */ #endif @@ -97,13 +96,13 @@ static option_t eap_option_list[] = { /* * Protocol entry points. */ -static void eap_init (int unit); -static void eap_input (int unit, u_char *inp, int inlen); -static void eap_protrej (int unit); -static void eap_lowerup (int unit); -static void eap_lowerdown (int unit); +static void eap_init(int unit); +static void eap_input(int unit, u_char *inp, int inlen); +static void eap_protrej(int unit); +static void eap_lowerup(int unit); +static void eap_lowerdown(int unit); #if PRINTPKT_SUPPORT -static int eap_printpkt (u_char *inp, int inlen, +static int eap_printpkt(u_char *inp, int inlen, void (*)(void *arg, char *fmt, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ @@ -177,7 +176,7 @@ static const u_char wkmodulus[] = { #if PPP_SERVER /* Local forward declarations. */ -static void eap_server_timeout (void *arg); +static void eap_server_timeout(void *arg); #endif /* PPP_SERVER */ /* @@ -196,40 +195,33 @@ enum eap_state_code esc; * eap_init - Initialize state for an EAP user. This is currently * called once by main() during start-up. */ -static void -eap_init(unit) -int unit; -{ - eap_state *esp = &eap_states[unit]; +static void eap_init(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; - BZERO(esp, sizeof (*esp)); - esp->es_unit = unit; + BZERO(&pcb->eap, sizeof(eap_state)); + pcb->eap.es_unit = unit; #if PPP_SERVER - esp->es_server.ea_timeout = EAP_DEFTIMEOUT; - esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS; - esp->es_server.ea_id = (u_char)(drand48() * 0x100); + pcb->eap.es_server.ea_timeout = EAP_DEFTIMEOUT; + pcb->eap.es_server.ea_maxrequests = EAP_DEFTRANSMITS; + pcb->eap.es_server.ea_id = (u_char)(drand48() * 0x100); #endif /* PPP_SERVER */ - esp->es_client.ea_timeout = EAP_DEFREQTIME; - esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; + pcb->eap.es_client.ea_timeout = EAP_DEFREQTIME; + pcb->eap.es_client.ea_maxrequests = EAP_DEFALLOWREQ; } /* * eap_client_timeout - Give up waiting for the peer to send any * Request messages. */ -static void -eap_client_timeout(arg) -void *arg; -{ - eap_state *esp = (eap_state *) arg; - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; +static void eap_client_timeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; - if (!eap_client_active(esp)) + if (!eap_client_active(pcb)) return; error("EAP: timeout waiting for Request from peer"); auth_withpeer_fail(pcb, PPP_EAP); - esp->es_client.ea_state = eapBadAuth; + pcb->eap.es_client.ea_state = eapBadAuth; } /* @@ -238,26 +230,21 @@ void *arg; * Start client state and wait for requests. This is called only * after eap_lowerup. */ -void -eap_authwithpeer(unit, localname) -int unit; -char *localname; -{ - eap_state *esp = &eap_states[unit]; +void eap_authwithpeer(ppp_pcb *pcb, char *localname) { /* Save the peer name we're given */ - esp->es_client.ea_name = localname; - esp->es_client.ea_namelen = strlen(localname); + pcb->eap.es_client.ea_name = localname; + pcb->eap.es_client.ea_namelen = strlen(localname); - esp->es_client.ea_state = eapListen; + pcb->eap.es_client.ea_state = eapListen; /* * Start a timer so that if the other end just goes * silent, we don't sit here waiting forever. */ - if (esp->es_client.ea_timeout > 0) - TIMEOUT(eap_client_timeout, (void *)esp, - esp->es_client.ea_timeout); + if (pcb->eap.es_client.ea_timeout > 0) + TIMEOUT(eap_client_timeout, pcb, + pcb->eap.es_client.ea_timeout); } #if PPP_SERVER @@ -269,7 +256,7 @@ static void eap_send_failure(esp) eap_state *esp; { - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; + ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; u_char *outp; outp = outpacket_buf; @@ -277,13 +264,13 @@ eap_state *esp; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_FAILURE, outp); - esp->es_server.ea_id++; - PUTCHAR(esp->es_server.ea_id, outp); + pcb->eap.es_server.ea_id++; + PUTCHAR(pcb->eap.es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); ppp_write(pcb, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); - esp->es_server.ea_state = eapBadAuth; + pcb->eap.es_server.ea_state = eapBadAuth; auth_peer_fail(pcb, PPP_EAP); } @@ -295,7 +282,7 @@ static void eap_send_success(esp) eap_state *esp; { - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; + ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; u_char *outp; outp = outpacket_buf; @@ -303,14 +290,14 @@ eap_state *esp; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_SUCCESS, outp); - esp->es_server.ea_id++; - PUTCHAR(esp->es_server.ea_id, outp); + pcb->eap.es_server.ea_id++; + PUTCHAR(pcb->eap.es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); ppp_write(pcb, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); auth_peer_success(pcb, PPP_EAP, 0, - esp->es_server.ea_peer, esp->es_server.ea_peerlen); + pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen); } #endif /* PPP_SERVER */ @@ -446,36 +433,36 @@ int status; struct b64state bs; #endif /* USE_SRP */ - esp->es_server.ea_timeout = esp->es_savedtime; - switch (esp->es_server.ea_state) { + pcb->eap.es_server.ea_timeout = pcb->eap.es_savedtime; + switch (pcb->eap.es_server.ea_state) { case eapBadAuth: return; case eapIdentify: #ifdef USE_SRP /* Discard any previous session. */ - ts = (struct t_server *)esp->es_server.ea_session; + ts = (struct t_server *)pcb->eap.es_server.ea_session; if (ts != NULL) { t_serverclose(ts); - esp->es_server.ea_session = NULL; - esp->es_server.ea_skey = NULL; + pcb->eap.es_server.ea_session = NULL; + pcb->eap.es_server.ea_skey = NULL; } #endif /* USE_SRP */ if (status != 0) { - esp->es_server.ea_state = eapBadAuth; + pcb->eap.es_server.ea_state = eapBadAuth; break; } #ifdef USE_SRP /* If we've got a pseudonym, try to decode to real name. */ - if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN && - strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID, + if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN && + strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID, SRP_PSEUDO_LEN) == 0 && - (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 < + (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 < sizeof (secbuf)) { BZERO(&bs, sizeof (bs)); plen = b64dec(&bs, - esp->es_server.ea_peer + SRP_PSEUDO_LEN, - esp->es_server.ea_peerlen - SRP_PSEUDO_LEN, + pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN, + pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN, secbuf); toffs = 0; for (i = 0; i < 5; i++) { @@ -499,8 +486,8 @@ int status; */ if ((i = plen = *(unsigned char *)clear) > 7) i = 7; - esp->es_server.ea_peerlen = plen; - dp = (unsigned char *)esp->es_server.ea_peer; + pcb->eap.es_server.ea_peerlen = plen; + dp = (unsigned char *)pcb->eap.es_server.ea_peer; MEMCPY(dp, clear + 1, i); plen -= i; dp += i; @@ -512,11 +499,11 @@ int status; dp += 8; plen -= 8; } - esp->es_server.ea_peer[ - esp->es_server.ea_peerlen] = '\0'; + pcb->eap.es_server.ea_peer[ + pcb->eap.es_server.ea_peerlen] = '\0'; dbglog("decoded pseudonym to \"%.*q\"", - esp->es_server.ea_peerlen, - esp->es_server.ea_peer); + pcb->eap.es_server.ea_peerlen, + pcb->eap.es_server.ea_peer); } else { dbglog("failed to decode real name"); /* Stay in eapIdentfy state; requery */ @@ -524,10 +511,10 @@ int status; } } /* Look up user in secrets database. */ - if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer, - esp->es_server.ea_name, (char *)secbuf, 1) != 0) { + if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer, + pcb->eap.es_server.ea_name, (char *)secbuf, 1) != 0) { /* Set up default in case SRP entry is bad */ - esp->es_server.ea_state = eapMD5Chall; + pcb->eap.es_server.ea_state = eapMD5Chall; /* Get t_confent based on index in srp-secrets */ id = strtol((char *)secbuf, &cp, 10); if (*cp++ != ':' || id < 0) @@ -545,16 +532,16 @@ int status; * generator combination, and that will take * a while. Lengthen the timeout here. */ - if (esp->es_server.ea_timeout > 0 && - esp->es_server.ea_timeout < 30) - esp->es_server.ea_timeout = 30; + if (pcb->eap.es_server.ea_timeout > 0 && + pcb->eap.es_server.ea_timeout < 30) + pcb->eap.es_server.ea_timeout = 30; } else { break; } if ((cp2 = strchr(cp, ':')) == NULL) break; *cp2++ = '\0'; - tpw.pebuf.name = esp->es_server.ea_peer; + tpw.pebuf.name = pcb->eap.es_server.ea_peer; tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf, cp); tpw.pebuf.password.data = tpw.pwbuf; @@ -563,9 +550,9 @@ int status; tpw.pebuf.salt.data = tpw.saltbuf; if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL) break; - esp->es_server.ea_session = (void *)ts; - esp->es_server.ea_state = eapSRP1; - vals[0] = esp->es_server.ea_id + 1; + pcb->eap.es_server.ea_session = (void *)ts; + pcb->eap.es_server.ea_state = eapSRP1; + vals[0] = pcb->eap.es_server.ea_id + 1; vals[1] = EAPT_SRP; t_serveraddexdata(ts, vals, 2); /* Generate B; must call before t_servergetkey() */ @@ -573,73 +560,73 @@ int status; break; } #endif /* USE_SRP */ - esp->es_server.ea_state = eapMD5Chall; + pcb->eap.es_server.ea_state = eapMD5Chall; break; case eapSRP1: #ifdef USE_SRP - ts = (struct t_server *)esp->es_server.ea_session; + ts = (struct t_server *)pcb->eap.es_server.ea_session; if (ts != NULL && status != 0) { t_serverclose(ts); - esp->es_server.ea_session = NULL; - esp->es_server.ea_skey = NULL; + pcb->eap.es_server.ea_session = NULL; + pcb->eap.es_server.ea_skey = NULL; } #endif /* USE_SRP */ if (status == 1) { - esp->es_server.ea_state = eapMD5Chall; - } else if (status != 0 || esp->es_server.ea_session == NULL) { - esp->es_server.ea_state = eapBadAuth; + pcb->eap.es_server.ea_state = eapMD5Chall; + } else if (status != 0 || pcb->eap.es_server.ea_session == NULL) { + pcb->eap.es_server.ea_state = eapBadAuth; } else { - esp->es_server.ea_state = eapSRP2; + pcb->eap.es_server.ea_state = eapSRP2; } break; case eapSRP2: #ifdef USE_SRP - ts = (struct t_server *)esp->es_server.ea_session; + ts = (struct t_server *)pcb->eap.es_server.ea_session; if (ts != NULL && status != 0) { t_serverclose(ts); - esp->es_server.ea_session = NULL; - esp->es_server.ea_skey = NULL; + pcb->eap.es_server.ea_session = NULL; + pcb->eap.es_server.ea_skey = NULL; } #endif /* USE_SRP */ - if (status != 0 || esp->es_server.ea_session == NULL) { - esp->es_server.ea_state = eapBadAuth; + if (status != 0 || pcb->eap.es_server.ea_session == NULL) { + pcb->eap.es_server.ea_state = eapBadAuth; } else { - esp->es_server.ea_state = eapSRP3; + pcb->eap.es_server.ea_state = eapSRP3; } break; case eapSRP3: case eapSRP4: #ifdef USE_SRP - ts = (struct t_server *)esp->es_server.ea_session; + ts = (struct t_server *)pcb->eap.es_server.ea_session; if (ts != NULL && status != 0) { t_serverclose(ts); - esp->es_server.ea_session = NULL; - esp->es_server.ea_skey = NULL; + pcb->eap.es_server.ea_session = NULL; + pcb->eap.es_server.ea_skey = NULL; } #endif /* USE_SRP */ - if (status != 0 || esp->es_server.ea_session == NULL) { - esp->es_server.ea_state = eapBadAuth; + if (status != 0 || pcb->eap.es_server.ea_session == NULL) { + pcb->eap.es_server.ea_state = eapBadAuth; } else { - esp->es_server.ea_state = eapOpen; + pcb->eap.es_server.ea_state = eapOpen; } break; case eapMD5Chall: if (status != 0) { - esp->es_server.ea_state = eapBadAuth; + pcb->eap.es_server.ea_state = eapBadAuth; } else { - esp->es_server.ea_state = eapOpen; + pcb->eap.es_server.ea_state = eapOpen; } break; default: - esp->es_server.ea_state = eapBadAuth; + pcb->eap.es_server.ea_state = eapBadAuth; break; } - if (esp->es_server.ea_state == eapBadAuth) + if (pcb->eap.es_server.ea_state == eapBadAuth) eap_send_failure(esp); } @@ -651,7 +638,7 @@ static void eap_send_request(esp) eap_state *esp; { - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; + ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; u_char *outp; u_char *lenloc; u_char *ptr; @@ -667,24 +654,24 @@ eap_state *esp; #endif /* USE_SRP */ /* Handle both initial auth and restart */ - if (esp->es_server.ea_state < eapIdentify && - esp->es_server.ea_state != eapInitial) { - esp->es_server.ea_state = eapIdentify; + if (pcb->eap.es_server.ea_state < eapIdentify && + pcb->eap.es_server.ea_state != eapInitial) { + pcb->eap.es_server.ea_state = eapIdentify; if (explicit_remote) { /* * If we already know the peer's * unauthenticated name, then there's no * reason to ask. Go to next state instead. */ - esp->es_server.ea_peer = remote_name; - esp->es_server.ea_peerlen = strlen(remote_name); + pcb->eap.es_server.ea_peer = remote_name; + pcb->eap.es_server.ea_peerlen = strlen(remote_name); eap_figure_next_state(esp, 0); } } - if (esp->es_server.ea_maxrequests > 0 && - esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) { - if (esp->es_server.ea_responses > 0) + if (pcb->eap.es_server.ea_maxrequests > 0 && + pcb->eap.es_server.ea_requests >= pcb->eap.es_server.ea_maxrequests) { + if (pcb->eap.es_server.ea_responses > 0) error("EAP: too many Requests sent"); else error("EAP: no response to Requests"); @@ -697,11 +684,11 @@ eap_state *esp; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_REQUEST, outp); - PUTCHAR(esp->es_server.ea_id, outp); + PUTCHAR(pcb->eap.es_server.ea_id, outp); lenloc = outp; INCPTR(2, outp); - switch (esp->es_server.ea_state) { + switch (pcb->eap.es_server.ea_state) { case eapIdentify: PUTCHAR(EAPT_IDENTITY, outp); str = "Name"; @@ -714,20 +701,20 @@ eap_state *esp; PUTCHAR(EAPT_MD5CHAP, outp); /* * pick a random challenge length between - * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH + * EAP_MIN_CHALLENGE_LENGTH and EAP_MAX_CHALLENGE_LENGTH */ challen = (drand48() * - (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) + - MIN_CHALLENGE_LENGTH; + (EAP_MAX_CHALLENGE_LENGTH - EAP_MIN_CHALLENGE_LENGTH)) + + EAP_MIN_CHALLENGE_LENGTH; PUTCHAR(challen, outp); - esp->es_challen = challen; - ptr = esp->es_challenge; + pcb->eap.es_challen = challen; + ptr = pcb->eap.es_challenge; while (--challen >= 0) *ptr++ = (u_char) (drand48() * 0x100); - MEMCPY(outp, esp->es_challenge, esp->es_challen); - INCPTR(esp->es_challen, outp); - MEMCPY(outp, esp->es_server.ea_name, esp->es_server.ea_namelen); - INCPTR(esp->es_server.ea_namelen, outp); + MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen); + INCPTR(pcb->eap.es_challen, outp); + MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen); + INCPTR(pcb->eap.es_server.ea_namelen, outp); break; #ifdef USE_SRP @@ -735,11 +722,11 @@ eap_state *esp; PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_CHALLENGE, outp); - PUTCHAR(esp->es_server.ea_namelen, outp); - MEMCPY(outp, esp->es_server.ea_name, esp->es_server.ea_namelen); - INCPTR(esp->es_server.ea_namelen, outp); + PUTCHAR(pcb->eap.es_server.ea_namelen, outp); + MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen); + INCPTR(pcb->eap.es_server.ea_namelen, outp); - ts = (struct t_server *)esp->es_server.ea_session; + ts = (struct t_server *)pcb->eap.es_server.ea_session; assert(ts != NULL); PUTCHAR(ts->s.len, outp); MEMCPY(outp, ts->s.data, ts->s.len); @@ -764,7 +751,7 @@ eap_state *esp; PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_SKEY, outp); - ts = (struct t_server *)esp->es_server.ea_session; + ts = (struct t_server *)pcb->eap.es_server.ea_session; assert(ts != NULL); MEMCPY(outp, ts->B.data, ts->B.len); INCPTR(ts->B.len, outp); @@ -774,7 +761,7 @@ eap_state *esp; PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_SVALIDATOR, outp); PUTLONG(SRPVAL_EBIT, outp); - ts = (struct t_server *)esp->es_server.ea_session; + ts = (struct t_server *)pcb->eap.es_server.ea_session; assert(ts != NULL); MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE); INCPTR(SHA_DIGESTSIZE, outp); @@ -782,8 +769,8 @@ eap_state *esp; if (pncrypt_setkey(0)) { /* Generate pseudonym */ optr = outp; - cp = (unsigned char *)esp->es_server.ea_peer; - if ((j = i = esp->es_server.ea_peerlen) > 7) + cp = (unsigned char *)pcb->eap.es_server.ea_peer; + if ((j = i = pcb->eap.es_server.ea_peerlen) > 7) j = 7; clear[0] = i; MEMCPY(clear + 1, cp, j); @@ -830,19 +817,19 @@ eap_state *esp; /* Obscure the pseudonym with SHA1 hash */ SHA1Init(&ctxt); - SHA1Update(&ctxt, &esp->es_server.ea_id, 1); - SHA1Update(&ctxt, esp->es_server.ea_skey, + SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1); + SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, SESSION_KEY_LEN); - SHA1Update(&ctxt, esp->es_server.ea_peer, - esp->es_server.ea_peerlen); + SHA1Update(&ctxt, pcb->eap.es_server.ea_peer, + pcb->eap.es_server.ea_peerlen); while (optr < outp) { SHA1Final(dig, &ctxt); cp = dig; while (cp < dig + SHA_DIGESTSIZE) *optr++ ^= *cp++; SHA1Init(&ctxt); - SHA1Update(&ctxt, &esp->es_server.ea_id, 1); - SHA1Update(&ctxt, esp->es_server.ea_skey, + SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1); + SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, SESSION_KEY_LEN); SHA1Update(&ctxt, optr - SHA_DIGESTSIZE, SHA_DIGESTSIZE); @@ -853,14 +840,14 @@ eap_state *esp; case eapSRP4: PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_LWRECHALLENGE, outp); - challen = MIN_CHALLENGE_LENGTH + - ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48()); - esp->es_challen = challen; - ptr = esp->es_challenge; + challen = EAP_MIN_CHALLENGE_LENGTH + + ((EAP_MAX_CHALLENGE_LENGTH - EAP_MIN_CHALLENGE_LENGTH) * drand48()); + pcb->eap.es_challen = challen; + ptr = pcb->eap.es_challenge; while (--challen >= 0) *ptr++ = drand48() * 0x100; - MEMCPY(outp, esp->es_challenge, esp->es_challen); - INCPTR(esp->es_challen, outp); + MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen); + INCPTR(pcb->eap.es_challen, outp); break; #endif /* USE_SRP */ @@ -873,10 +860,10 @@ eap_state *esp; ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); - esp->es_server.ea_requests++; + pcb->eap.es_server.ea_requests++; - if (esp->es_server.ea_timeout > 0) - TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); + if (pcb->eap.es_server.ea_timeout > 0) + TIMEOUT(eap_server_timeout, pcb, pcb->eap.es_server.ea_timeout); } /* @@ -885,27 +872,23 @@ eap_state *esp; * Start server state and send first request. This is called only * after eap_lowerup. */ -void -eap_authpeer(unit, localname) -int unit; -char *localname; -{ +void eap_authpeer(ppp_pcb *pcb, char *localname) { eap_state *esp = &eap_states[unit]; /* Save the name we're given. */ - esp->es_server.ea_name = localname; - esp->es_server.ea_namelen = strlen(localname); + pcb->eap.es_server.ea_name = localname; + pcb->eap.es_server.ea_namelen = strlen(localname); - esp->es_savedtime = esp->es_server.ea_timeout; + pcb->eap.es_savedtime = pcb->eap.es_server.ea_timeout; /* Lower layer up yet? */ - if (esp->es_server.ea_state == eapInitial || - esp->es_server.ea_state == eapPending) { - esp->es_server.ea_state = eapPending; + if (pcb->eap.es_server.ea_state == eapInitial || + pcb->eap.es_server.ea_state == eapPending) { + pcb->eap.es_server.ea_state = eapPending; return; } - esp->es_server.ea_state = eapPending; + pcb->eap.es_server.ea_state = eapPending; /* ID number not updated here intentionally; hashed into M1 */ eap_send_request(esp); @@ -915,11 +898,8 @@ char *localname; * eap_server_timeout - Retransmission timer for sending Requests * expired. */ -static void -eap_server_timeout(arg) -void *arg; -{ - eap_state *esp = (eap_state *) arg; +static void eap_server_timeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; if (!eap_server_active(esp)) return; @@ -939,14 +919,14 @@ void *arg; { eap_state *esp = (eap_state *)arg; - if (esp->es_server.ea_state != eapOpen && - esp->es_server.ea_state != eapSRP4) + if (pcb->eap.es_server.ea_state != eapOpen && + pcb->eap.es_server.ea_state != eapSRP4) return; - esp->es_server.ea_requests = 0; - esp->es_server.ea_state = eapIdentify; + pcb->eap.es_server.ea_requests = 0; + pcb->eap.es_server.ea_state = eapIdentify; eap_figure_next_state(esp, 0); - esp->es_server.ea_id++; + pcb->eap.es_server.ea_id++; eap_send_request(esp); } @@ -956,13 +936,13 @@ void *arg; { eap_state *esp = (eap_state *)arg; - if (esp->es_server.ea_state != eapOpen || - esp->es_server.ea_type != EAPT_SRP) + if (pcb->eap.es_server.ea_state != eapOpen || + pcb->eap.es_server.ea_type != EAPT_SRP) return; - esp->es_server.ea_requests = 0; - esp->es_server.ea_state = eapSRP4; - esp->es_server.ea_id++; + pcb->eap.es_server.ea_requests = 0; + pcb->eap.es_server.ea_state = eapSRP4; + pcb->eap.es_server.ea_id++; eap_send_request(esp); } #endif /* PPP_SERVER */ @@ -975,26 +955,23 @@ void *arg; * return to closed state so that those two routines will do the right * thing. */ -static void -eap_lowerup(unit) -int unit; -{ - eap_state *esp = &eap_states[unit]; +static void eap_lowerup(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; /* Discard any (possibly authenticated) peer name. */ #if PPP_SERVER - if (esp->es_server.ea_peer != NULL && - esp->es_server.ea_peer != remote_name) - free(esp->es_server.ea_peer); - esp->es_server.ea_peer = NULL; + if (pcb->eap.es_server.ea_peer != NULL && + pcb->eap.es_server.ea_peer != remote_name) + free(pcb->eap.es_server.ea_peer); + pcb->eap.es_server.ea_peer = NULL; #endif /* PPP_SERVER */ - if (esp->es_client.ea_peer != NULL) - free(esp->es_client.ea_peer); - esp->es_client.ea_peer = NULL; + if (pcb->eap.es_client.ea_peer != NULL) + free(pcb->eap.es_client.ea_peer); + pcb->eap.es_client.ea_peer = NULL; - esp->es_client.ea_state = eapClosed; + pcb->eap.es_client.ea_state = eapClosed; #if PPP_SERVER - esp->es_server.ea_state = eapClosed; + pcb->eap.es_server.ea_state = eapClosed; #endif /* PPP_SERVER */ } @@ -1003,34 +980,31 @@ int unit; * * Cancel all timeouts and return to initial state. */ -static void -eap_lowerdown(unit) -int unit; -{ - eap_state *esp = &eap_states[unit]; +static void eap_lowerdown(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; - if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) { - UNTIMEOUT(eap_client_timeout, (void *)esp); + if (eap_client_active(pcb) && pcb->eap.es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, pcb); } #if PPP_SERVER if (eap_server_active(esp)) { - if (esp->es_server.ea_timeout > 0) { - UNTIMEOUT(eap_server_timeout, (void *)esp); + if (pcb->eap.es_server.ea_timeout > 0) { + UNTIMEOUT(eap_server_timeout, pcb); } } else { - if ((esp->es_server.ea_state == eapOpen || - esp->es_server.ea_state == eapSRP4) && - esp->es_rechallenge > 0) { + if ((pcb->eap.es_server.ea_state == eapOpen || + pcb->eap.es_server.ea_state == eapSRP4) && + pcb->eap.es_rechallenge > 0) { UNTIMEOUT(eap_rechallenge, (void *)esp); } - if (esp->es_server.ea_state == eapOpen && - esp->es_lwrechallenge > 0) { + if (pcb->eap.es_server.ea_state == eapOpen && + pcb->eap.es_lwrechallenge > 0) { UNTIMEOUT(srp_lwrechallenge, (void *)esp); } } - esp->es_client.ea_state = esp->es_server.ea_state = eapInitial; - esp->es_client.ea_requests = esp->es_server.ea_requests = 0; + pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial; + pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0; #endif /* PPP_SERVER */ } @@ -1040,14 +1014,10 @@ int unit; * This shouldn't happen. If it does, it represents authentication * failure. */ -static void -eap_protrej(unit) -int unit; -{ +static void eap_protrej(int unit) { ppp_pcb *pcb = &ppp_pcb_list[unit]; - eap_state *esp = &eap_states[unit]; - if (eap_client_active(esp)) { + if (eap_client_active(pcb)) { error("EAP authentication failed due to Protocol-Reject"); auth_withpeer_fail(pcb, PPP_EAP); } @@ -1063,15 +1033,7 @@ int unit; /* * Format and send a regular EAP Response message. */ -static void -eap_send_response(esp, id, typenum, str, lenstr) -eap_state *esp; -u_char id; -u_char typenum; -u_char *str; -int lenstr; -{ - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; +static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, u_char *str, int lenstr) { u_char *outp; int msglen; @@ -1081,7 +1043,7 @@ int lenstr; PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); - esp->es_client.ea_id = id; + pcb->eap.es_client.ea_id = id; msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; PUTSHORT(msglen, outp); PUTCHAR(typenum, outp); @@ -1095,15 +1057,7 @@ int lenstr; /* * Format and send an MD5-Challenge EAP Response message. */ -static void -eap_chap_response(esp, id, hash, name, namelen) -eap_state *esp; -u_char id; -u_char *hash; -char *name; -int namelen; -{ - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; +static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, char *name, int namelen) { u_char *outp; int msglen; @@ -1113,7 +1067,7 @@ int namelen; PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); - esp->es_client.ea_id = id; + pcb->eap.es_client.ea_id = id; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + namelen; PUTSHORT(msglen, outp); @@ -1140,7 +1094,7 @@ u_char subtypenum; u_char *str; int lenstr; { - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; + ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; u_char *outp; int msglen; @@ -1150,7 +1104,7 @@ int lenstr; PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); - esp->es_client.ea_id = id; + pcb->eap.es_client.ea_id = id; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; PUTSHORT(msglen, outp); PUTCHAR(EAPT_SRP, outp); @@ -1172,7 +1126,7 @@ u_char id; u_int32_t flags; u_char *str; { - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; + ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; u_char *outp; int msglen; @@ -1182,7 +1136,7 @@ u_char *str; PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); - esp->es_client.ea_id = id; + pcb->eap.es_client.ea_id = id; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) + SHA_DIGESTSIZE; PUTSHORT(msglen, outp); @@ -1195,13 +1149,7 @@ u_char *str; } #endif /* USE_SRP */ -static void -eap_send_nak(esp, id, type) -eap_state *esp; -u_char id; -u_char type; -{ - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; +static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { u_char *outp; int msglen; @@ -1211,7 +1159,7 @@ u_char type; PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); - esp->es_client.ea_id = id; + pcb->eap.es_client.ea_id = id; msglen = EAP_HEADERLEN + 2 * sizeof (u_char); PUTSHORT(msglen, outp); PUTCHAR(EAPT_NAK, outp); @@ -1298,12 +1246,12 @@ int len, id; datp = inp + len; SHA1Init(&ctxt); SHA1Update(&ctxt, &val, 1); - SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN); + SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN); if (len > 0) { SHA1Update(&ctxt, datp, SHA_DIGESTSIZE); } else { - SHA1Update(&ctxt, esp->es_client.ea_name, - esp->es_client.ea_namelen); + SHA1Update(&ctxt, pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_namelen); } SHA1Final(dig, &ctxt); for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++) @@ -1325,7 +1273,7 @@ int len, id; len = write(fd, inp + 1, *inp); if (close(fd) != -1 && len == *inp) { dbglog("EAP: saved pseudonym"); - esp->es_usedpseudo = 0; + pcb->eap.es_usedpseudo = 0; } else { dbglog("EAP: failed to save pseudonym"); remove_pn_file(); @@ -1336,14 +1284,7 @@ int len, id; /* * eap_request - Receive EAP Request message (client mode). */ -static void -eap_request(esp, inp, id, len) -eap_state *esp; -u_char *inp; -int id; -int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; +static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { u_char typenum; u_char vallen; int secret_len; @@ -1366,12 +1307,12 @@ int len; * same for duplicate detection purposes. */ - esp->es_client.ea_requests++; - if (esp->es_client.ea_maxrequests != 0 && - esp->es_client.ea_requests > esp->es_client.ea_maxrequests) { + pcb->eap.es_client.ea_requests++; + if (pcb->eap.es_client.ea_maxrequests != 0 && + pcb->eap.es_client.ea_requests > pcb->eap.es_client.ea_maxrequests) { info("EAP: received too many Request messages"); - if (esp->es_client.ea_timeout > 0) { - UNTIMEOUT(eap_client_timeout, (void *)esp); + if (pcb->eap.es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, pcb); } auth_withpeer_fail(pcb, PPP_EAP); return; @@ -1390,11 +1331,11 @@ int len; if (len > 0) info("EAP: Identity prompt \"%.*q\"", len, inp); #ifdef USE_SRP - if (esp->es_usepseudo && - (esp->es_usedpseudo == 0 || - (esp->es_usedpseudo == 1 && - id == esp->es_client.ea_id))) { - esp->es_usedpseudo = 1; + if (pcb->eap.es_usepseudo && + (pcb->eap.es_usedpseudo == 0 || + (pcb->eap.es_usedpseudo == 1 && + id == pcb->eap.es_client.ea_id))) { + pcb->eap.es_usedpseudo = 1; /* Try to get a pseudonym */ if ((fd = open_pn_file(O_RDONLY)) >= 0) { strcpy(rhostname, SRP_PSEUDO_ID); @@ -1402,7 +1343,7 @@ int len; sizeof (rhostname) - SRP_PSEUDO_LEN); /* XXX NAI unsupported */ if (len > 0) { - eap_send_response(esp, id, typenum, + eap_send_response(pcb, id, typenum, rhostname, len + SRP_PSEUDO_LEN); } (void) close(fd); @@ -1411,19 +1352,19 @@ int len; } } /* Stop using pseudonym now. */ - if (esp->es_usepseudo && esp->es_usedpseudo != 2) { + if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) { remove_pn_file(); - esp->es_usedpseudo = 2; + pcb->eap.es_usedpseudo = 2; } #endif /* USE_SRP */ - eap_send_response(esp, id, typenum, esp->es_client.ea_name, - esp->es_client.ea_namelen); + eap_send_response(pcb, id, typenum, (u_char*)pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_namelen); break; case EAPT_NOTIFICATION: if (len > 0) info("EAP: Notification \"%.*q\"", len, inp); - eap_send_response(esp, id, typenum, NULL, 0); + eap_send_response(pcb, id, typenum, NULL, 0); break; case EAPT_NAK: @@ -1447,7 +1388,7 @@ int len; error("EAP: MD5-Challenge with bad length %d (8..%d)", vallen, len); /* Try something better. */ - eap_send_nak(esp, id, EAPT_SRP); + eap_send_nak(pcb, id, EAPT_SRP); break; } @@ -1470,10 +1411,10 @@ int len; * Get the secret for authenticating ourselves with * the specified host. */ - if (!get_secret(pcb, esp->es_client.ea_name, + if (!get_secret(pcb, pcb->eap.es_client.ea_name, rhostname, secret, &secret_len, 0)) { dbglog("EAP: no MD5 secret for auth to %q", rhostname); - eap_send_nak(esp, id, EAPT_SRP); + eap_send_nak(pcb, id, EAPT_SRP); break; } md5_starts(&mdContext); @@ -1483,8 +1424,8 @@ int len; BZERO(secret, sizeof (secret)); md5_update(&mdContext, inp, vallen); md5_finish(&mdContext, hash); - eap_chap_response(esp, id, hash, esp->es_client.ea_name, - esp->es_client.ea_namelen); + eap_chap_response(pcb, id, hash, pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_namelen); break; #ifdef USE_SRP @@ -1501,22 +1442,22 @@ int len; switch (vallen) { case EAPSRP_CHALLENGE: tc = NULL; - if (esp->es_client.ea_session != NULL) { - tc = (struct t_client *)esp->es_client. + if (pcb->eap.es_client.ea_session != NULL) { + tc = (struct t_client *)pcb->eap.es_client. ea_session; /* * If this is a new challenge, then start * over with a new client session context. * Otherwise, just resend last response. */ - if (id != esp->es_client.ea_id) { + if (id != pcb->eap.es_client.ea_id) { t_clientclose(tc); - esp->es_client.ea_session = NULL; + pcb->eap.es_client.ea_session = NULL; tc = NULL; } } /* No session key just yet */ - esp->es_client.ea_skey = NULL; + pcb->eap.es_client.ea_skey = NULL; if (tc == NULL) { GETCHAR(vallen, inp); len--; @@ -1541,10 +1482,10 @@ int len; sizeof (rhostname)); } - if (esp->es_client.ea_peer != NULL) - free(esp->es_client.ea_peer); - esp->es_client.ea_peer = strdup(rhostname); - esp->es_client.ea_peerlen = strlen(rhostname); + if (pcb->eap.es_client.ea_peer != NULL) + free(pcb->eap.es_client.ea_peer); + pcb->eap.es_client.ea_peer = strdup(rhostname); + pcb->eap.es_client.ea_peerlen = strlen(rhostname); GETCHAR(vallen, inp); len--; @@ -1589,13 +1530,13 @@ int len; Nval.data = inp; Nval.len = len; } - tc = t_clientopen(esp->es_client.ea_name, + tc = t_clientopen(pcb->eap.es_client.ea_name, &Nval, &gval, &sval); if (tc == NULL) { - eap_send_nak(esp, id, EAPT_MD5CHAP); + eap_send_nak(pcb, id, EAPT_MD5CHAP); break; } - esp->es_client.ea_session = (void *)tc; + pcb->eap.es_client.ea_session = (void *)tc; /* Add Challenge ID & type to verifier */ vals[0] = id; @@ -1608,41 +1549,41 @@ int len; break; case EAPSRP_SKEY: - tc = (struct t_client *)esp->es_client.ea_session; + tc = (struct t_client *)pcb->eap.es_client.ea_session; if (tc == NULL) { warn("EAP: peer sent Subtype 2 without 1"); - eap_send_nak(esp, id, EAPT_MD5CHAP); + eap_send_nak(pcb, id, EAPT_MD5CHAP); break; } - if (esp->es_client.ea_skey != NULL) { + if (pcb->eap.es_client.ea_skey != NULL) { /* * ID number should not change here. Warn * if it does (but otherwise ignore). */ - if (id != esp->es_client.ea_id) { + if (id != pcb->eap.es_client.ea_id) { warn("EAP: ID changed from %d to %d " "in SRP Subtype 2 rexmit", - esp->es_client.ea_id, id); + pcb->eap.es_client.ea_id, id); } } else { - if (get_srp_secret(esp->es_unit, - esp->es_client.ea_name, - esp->es_client.ea_peer, secret, 0) == 0) { + if (get_srp_secret(pcb->eap.es_unit, + pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_peer, secret, 0) == 0) { /* * Can't work with this peer because * the secret is missing. Just give * up. */ - eap_send_nak(esp, id, EAPT_MD5CHAP); + eap_send_nak(pcb, id, EAPT_MD5CHAP); break; } Bval.data = inp; Bval.len = len; t_clientpasswd(tc, secret); BZERO(secret, sizeof (secret)); - esp->es_client.ea_skey = + pcb->eap.es_client.ea_skey = t_clientgetkey(tc, &Bval); - if (esp->es_client.ea_skey == NULL) { + if (pcb->eap.es_client.ea_skey == NULL) { /* Server is rogue; stop now */ error("EAP: SRP server is rogue"); goto client_failure; @@ -1653,10 +1594,10 @@ int len; break; case EAPSRP_SVALIDATOR: - tc = (struct t_client *)esp->es_client.ea_session; - if (tc == NULL || esp->es_client.ea_skey == NULL) { + tc = (struct t_client *)pcb->eap.es_client.ea_session; + if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) { warn("EAP: peer sent Subtype 3 without 1/2"); - eap_send_nak(esp, id, EAPT_MD5CHAP); + eap_send_nak(pcb, id, EAPT_MD5CHAP); break; } /* @@ -1664,11 +1605,11 @@ int len; * duplicate. Otherwise, check that the server is * who we think it is. */ - if (esp->es_client.ea_state == eapOpen) { - if (id != esp->es_client.ea_id) { + if (pcb->eap.es_client.ea_state == eapOpen) { + if (id != pcb->eap.es_client.ea_id) { warn("EAP: ID changed from %d to %d " "in SRP Subtype 3 rexmit", - esp->es_client.ea_id, id); + pcb->eap.es_client.ea_id, id); } } else { len -= sizeof (u_int32_t) + SHA_DIGESTSIZE; @@ -1678,9 +1619,9 @@ int len; "failed"); goto client_failure; } - GETLONG(esp->es_client.ea_keyflags, inp); + GETLONG(pcb->eap.es_client.ea_keyflags, inp); /* Save pseudonym if user wants it. */ - if (len > 0 && esp->es_usepseudo) { + if (len > 0 && pcb->eap.es_usepseudo) { INCPTR(SHA_DIGESTSIZE, inp); write_pseudonym(esp, inp, len, id); } @@ -1701,11 +1642,11 @@ int len; SHA1Init(&ctxt); vals[0] = id; SHA1Update(&ctxt, vals, 1); - SHA1Update(&ctxt, esp->es_client.ea_skey, + SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN); SHA1Update(&ctxt, inp, len); - SHA1Update(&ctxt, esp->es_client.ea_name, - esp->es_client.ea_namelen); + SHA1Update(&ctxt, pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_namelen); SHA1Final(dig, &ctxt); eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig, SHA_DIGESTSIZE); @@ -1713,7 +1654,7 @@ int len; default: error("EAP: unknown SRP Subtype %d", vallen); - eap_send_nak(esp, id, EAPT_MD5CHAP); + eap_send_nak(pcb, id, EAPT_MD5CHAP); break; } break; @@ -1721,24 +1662,24 @@ int len; default: info("EAP: unknown authentication type %d; Naking", typenum); - eap_send_nak(esp, id, EAPT_SRP); + eap_send_nak(pcb, id, EAPT_SRP); break; } - if (esp->es_client.ea_timeout > 0) { - UNTIMEOUT(eap_client_timeout, (void *)esp); - TIMEOUT(eap_client_timeout, (void *)esp, - esp->es_client.ea_timeout); + if (pcb->eap.es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, pcb); + TIMEOUT(eap_client_timeout, pcb, + pcb->eap.es_client.ea_timeout); } return; #ifdef USE_SRP client_failure: - esp->es_client.ea_state = eapBadAuth; - if (esp->es_client.ea_timeout > 0) { + pcb->eap.es_client.ea_state = eapBadAuth; + if (pcb->eap.es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } - esp->es_client.ea_session = NULL; + pcb->eap.es_client.ea_session = NULL; t_clientclose(tc); auth_withpeer_fail(pcb, PPP_EAP); #endif /* USE_SRP */ @@ -1749,13 +1690,7 @@ client_failure: /* * eap_response - Receive EAP Response message (server mode). */ -static void -eap_response(esp, inp, id, len) -eap_state *esp; -u_char *inp; -int id; -int len; -{ +static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { u_char typenum; u_char vallen; int secret_len; @@ -1770,13 +1705,13 @@ int len; u_char dig[SHA_DIGESTSIZE]; #endif /* USE_SRP */ - if (esp->es_server.ea_id != id) { + if (pcb->eap.es_server.ea_id != id) { dbglog("EAP: discarding Response %d; expected ID %d", id, - esp->es_server.ea_id); + pcb->eap.es_server.ea_id); return; } - esp->es_server.ea_responses++; + pcb->eap.es_server.ea_responses++; if (len <= 0) { error("EAP: empty Response message discarded"); @@ -1788,24 +1723,24 @@ int len; switch (typenum) { case EAPT_IDENTITY: - if (esp->es_server.ea_state != eapIdentify) { + if (pcb->eap.es_server.ea_state != eapIdentify) { dbglog("EAP discarding unwanted Identify \"%.q\"", len, inp); break; } info("EAP: unauthenticated peer name \"%.*q\"", len, inp); - if (esp->es_server.ea_peer != NULL && - esp->es_server.ea_peer != remote_name) - free(esp->es_server.ea_peer); - esp->es_server.ea_peer = malloc(len + 1); - if (esp->es_server.ea_peer == NULL) { - esp->es_server.ea_peerlen = 0; + if (pcb->eap.es_server.ea_peer != NULL && + pcb->eap.es_server.ea_peer != remote_name) + free(pcb->eap.es_server.ea_peer); + pcb->eap.es_server.ea_peer = malloc(len + 1); + if (pcb->eap.es_server.ea_peer == NULL) { + pcb->eap.es_server.ea_peerlen = 0; eap_figure_next_state(esp, 1); break; } - MEMCPY(esp->es_server.ea_peer, inp, len); - esp->es_server.ea_peer[len] = '\0'; - esp->es_server.ea_peerlen = len; + MEMCPY(pcb->eap.es_server.ea_peer, inp, len); + pcb->eap.es_server.ea_peer[len] = '\0'; + pcb->eap.es_server.ea_peerlen = len; eap_figure_next_state(esp, 0); break; @@ -1823,7 +1758,7 @@ int len; GETCHAR(vallen, inp); len--; - if (!explicit_remote && esp->es_server.ea_state == eapIdentify){ + if (!explicit_remote && pcb->eap.es_server.ea_state == eapIdentify){ /* Peer cannot Nak Identify Request */ eap_figure_next_state(esp, 1); break; @@ -1832,25 +1767,25 @@ int len; switch (vallen) { case EAPT_SRP: /* Run through SRP validator selection again. */ - esp->es_server.ea_state = eapIdentify; + pcb->eap.es_server.ea_state = eapIdentify; eap_figure_next_state(esp, 0); break; case EAPT_MD5CHAP: - esp->es_server.ea_state = eapMD5Chall; + pcb->eap.es_server.ea_state = eapMD5Chall; break; default: dbglog("EAP: peer requesting unknown Type %d", vallen); - switch (esp->es_server.ea_state) { + switch (pcb->eap.es_server.ea_state) { case eapSRP1: case eapSRP2: case eapSRP3: - esp->es_server.ea_state = eapMD5Chall; + pcb->eap.es_server.ea_state = eapMD5Chall; break; case eapMD5Chall: case eapSRP4: - esp->es_server.ea_state = eapIdentify; + pcb->eap.es_server.ea_state = eapIdentify; eap_figure_next_state(esp, 0); break; default: @@ -1861,7 +1796,7 @@ int len; break; case EAPT_MD5CHAP: - if (esp->es_server.ea_state != eapMD5Chall) { + if (pcb->eap.es_server.ea_state != eapMD5Chall) { error("EAP: unexpected MD5-Response"); eap_figure_next_state(esp, 1); break; @@ -1899,26 +1834,26 @@ int len; * host. */ if (!get_secret(pcb, rhostname, - esp->es_server.ea_name, secret, &secret_len, 1)) { + pcb->eap.es_server.ea_name, secret, &secret_len, 1)) { dbglog("EAP: no MD5 secret for auth of %q", rhostname); eap_send_failure(esp); break; } md5_starts(&mdContext); - md5_update(&mdContext, &esp->es_server.ea_id, 1); + md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1); md5_update(&mdContext, (u_char *)secret, secret_len); BZERO(secret, sizeof (secret)); - md5_update(&mdContext, esp->es_challenge, esp->es_challen); + md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen); md5_finish(&mdContext, hash); if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { eap_send_failure(esp); break; } - esp->es_server.ea_type = EAPT_MD5CHAP; + pcb->eap.es_server.ea_type = EAPT_MD5CHAP; eap_send_success(esp); eap_figure_next_state(esp, 0); - if (esp->es_rechallenge != 0) - TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge); + if (pcb->eap.es_rechallenge != 0) + TIMEOUT(eap_rechallenge, esp, pcb->eap.es_rechallenge); break; #ifdef USE_SRP @@ -1932,17 +1867,17 @@ int len; len--; switch (typenum) { case EAPSRP_CKEY: - if (esp->es_server.ea_state != eapSRP1) { + if (pcb->eap.es_server.ea_state != eapSRP1) { error("EAP: unexpected SRP Subtype 1 Response"); eap_figure_next_state(esp, 1); break; } A.data = inp; A.len = len; - ts = (struct t_server *)esp->es_server.ea_session; + ts = (struct t_server *)pcb->eap.es_server.ea_session; assert(ts != NULL); - esp->es_server.ea_skey = t_servergetkey(ts, &A); - if (esp->es_server.ea_skey == NULL) { + pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A); + if (pcb->eap.es_server.ea_skey == NULL) { /* Client's A value is bogus; terminate now */ error("EAP: bogus A value from client"); eap_send_failure(esp); @@ -1952,7 +1887,7 @@ int len; break; case EAPSRP_CVALIDATOR: - if (esp->es_server.ea_state != eapSRP2) { + if (pcb->eap.es_server.ea_state != eapSRP2) { error("EAP: unexpected SRP Subtype 2 Response"); eap_figure_next_state(esp, 1); break; @@ -1963,8 +1898,8 @@ int len; eap_figure_next_state(esp, 1); break; } - GETLONG(esp->es_server.ea_keyflags, inp); - ts = (struct t_server *)esp->es_server.ea_session; + GETLONG(pcb->eap.es_server.ea_keyflags, inp); + ts = (struct t_server *)pcb->eap.es_server.ea_session; assert(ts != NULL); if (t_serververify(ts, inp)) { info("EAP: unable to validate client identity"); @@ -1975,24 +1910,24 @@ int len; break; case EAPSRP_ACK: - if (esp->es_server.ea_state != eapSRP3) { + if (pcb->eap.es_server.ea_state != eapSRP3) { error("EAP: unexpected SRP Subtype 3 Response"); eap_send_failure(esp); break; } - esp->es_server.ea_type = EAPT_SRP; + pcb->eap.es_server.ea_type = EAPT_SRP; eap_send_success(esp); eap_figure_next_state(esp, 0); - if (esp->es_rechallenge != 0) + if (pcb->eap.es_rechallenge != 0) TIMEOUT(eap_rechallenge, esp, - esp->es_rechallenge); - if (esp->es_lwrechallenge != 0) + pcb->eap.es_rechallenge); + if (pcb->eap.es_lwrechallenge != 0) TIMEOUT(srp_lwrechallenge, esp, - esp->es_lwrechallenge); + pcb->eap.es_lwrechallenge); break; case EAPSRP_LWRECHALLENGE: - if (esp->es_server.ea_state != eapSRP4) { + if (pcb->eap.es_server.ea_state != eapSRP4) { info("EAP: unexpected SRP Subtype 4 Response"); return; } @@ -2004,21 +1939,21 @@ int len; SHA1Init(&ctxt); vallen = id; SHA1Update(&ctxt, &vallen, 1); - SHA1Update(&ctxt, esp->es_server.ea_skey, + SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, SESSION_KEY_LEN); - SHA1Update(&ctxt, esp->es_challenge, esp->es_challen); - SHA1Update(&ctxt, esp->es_server.ea_peer, - esp->es_server.ea_peerlen); + SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen); + SHA1Update(&ctxt, pcb->eap.es_server.ea_peer, + pcb->eap.es_server.ea_peerlen); SHA1Final(dig, &ctxt); if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { error("EAP: failed Lightweight rechallenge"); eap_send_failure(esp); break; } - esp->es_server.ea_state = eapOpen; - if (esp->es_lwrechallenge != 0) + pcb->eap.es_server.ea_state = eapOpen; + if (pcb->eap.es_lwrechallenge != 0) TIMEOUT(srp_lwrechallenge, esp, - esp->es_lwrechallenge); + pcb->eap.es_lwrechallenge); break; } break; @@ -2030,13 +1965,13 @@ int len; return; } - if (esp->es_server.ea_timeout > 0) { - UNTIMEOUT(eap_server_timeout, (void *)esp); + if (pcb->eap.es_server.ea_timeout > 0) { + UNTIMEOUT(eap_server_timeout, pcb); } - if (esp->es_server.ea_state != eapBadAuth && - esp->es_server.ea_state != eapOpen) { - esp->es_server.ea_id++; + if (pcb->eap.es_server.ea_state != eapBadAuth && + pcb->eap.es_server.ea_state != eapOpen) { + pcb->eap.es_server.ea_id++; eap_send_request(esp); } } @@ -2045,23 +1980,16 @@ int len; /* * eap_success - Receive EAP Success message (client mode). */ -static void -eap_success(esp, inp, id, len) -eap_state *esp; -u_char *inp; -int id; -int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; - if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) { +static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) { + if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) { dbglog("EAP unexpected success message in state %s (%d)", - eap_state_name(esp->es_client.ea_state), - esp->es_client.ea_state); + eap_state_name(pcb->eap.es_client.ea_state), + pcb->eap.es_client.ea_state); return; } - if (esp->es_client.ea_timeout > 0) { - UNTIMEOUT(eap_client_timeout, (void *)esp); + if (pcb->eap.es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, pcb); } if (len > 0) { @@ -2069,29 +1997,22 @@ int len; PRINTMSG(inp, len); } - esp->es_client.ea_state = eapOpen; + pcb->eap.es_client.ea_state = eapOpen; auth_withpeer_success(pcb, PPP_EAP, 0); } /* * eap_failure - Receive EAP Failure message (client mode). */ -static void -eap_failure(esp, inp, id, len) -eap_state *esp; -u_char *inp; -int id; -int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[esp->es_unit]; - if (!eap_client_active(esp)) { +static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) { + if (!eap_client_active(pcb)) { dbglog("EAP unexpected failure message in state %s (%d)", - eap_state_name(esp->es_client.ea_state), - esp->es_client.ea_state); + eap_state_name(pcb->eap.es_client.ea_state), + pcb->eap.es_client.ea_state); } - if (esp->es_client.ea_timeout > 0) { - UNTIMEOUT(eap_client_timeout, (void *)esp); + if (pcb->eap.es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, pcb); } if (len > 0) { @@ -2099,7 +2020,7 @@ int len; PRINTMSG(inp, len); } - esp->es_client.ea_state = eapBadAuth; + pcb->eap.es_client.ea_state = eapBadAuth; error("EAP: peer reports authentication failure"); auth_withpeer_fail(pcb, PPP_EAP); @@ -2108,13 +2029,8 @@ int len; /* * eap_input - Handle received EAP message. */ -static void -eap_input(unit, inp, inlen) -int unit; -u_char *inp; -int inlen; -{ - eap_state *esp = &eap_states[unit]; +static void eap_input(int unit, u_char *inp, int inlen) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; u_char code, id; int len; @@ -2139,21 +2055,21 @@ int inlen; /* Dispatch based on message code */ switch (code) { case EAP_REQUEST: - eap_request(esp, inp, id, len); + eap_request(pcb, inp, id, len); break; #if PPP_SERVER case EAP_RESPONSE: - eap_response(esp, inp, id, len); + eap_response(pcb, inp, id, len); break; #endif /* PPP_SERVER */ case EAP_SUCCESS: - eap_success(esp, inp, id, len); + eap_success(pcb, inp, id, len); break; case EAP_FAILURE: - eap_failure(esp, inp, id, len); + eap_failure(pcb, inp, id, len); break; default: /* XXX Need code reject */ @@ -2179,13 +2095,7 @@ static char *eap_typenames[] = { "Cisco", "Nokia", "SRP" }; -static int -eap_printpkt(inp, inlen, printer, arg) -u_char *inp; -int inlen; -void (*printer) (void *, char *, ...); -void *arg; -{ +static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, ...), void *arg) { int code, id, len, rtype, vallen; u_char *pstart; u_int32_t uval; diff --git a/src/netif/ppp/eap.h b/src/netif/ppp/eap.h index 2a7eed47..1f2fc5bf 100644 --- a/src/netif/ppp/eap.h +++ b/src/netif/ppp/eap.h @@ -78,70 +78,20 @@ extern "C" { #define SRP_PSEUDO_LEN 7 #define MD5_SIGNATURE_SIZE 16 -#define MIN_CHALLENGE_LENGTH 16 -#define MAX_CHALLENGE_LENGTH 24 - -enum eap_state_code { - eapInitial = 0, /* No EAP authentication yet requested */ - eapPending, /* Waiting for LCP (no timer) */ - eapClosed, /* Authentication not in use */ - eapListen, /* Client ready (and timer running) */ - eapIdentify, /* EAP Identify sent */ - eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ - eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ - eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ - eapMD5Chall, /* Sent MD5-Challenge */ - eapOpen, /* Completed authentication */ - eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ - eapBadAuth /* Failed authentication */ -}; +#define EAP_MIN_CHALLENGE_LENGTH 16 +#define EAP_MAX_CHALLENGE_LENGTH 24 #define EAP_STATES \ "Initial", "Pending", "Closed", "Listen", "Identify", \ "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" -#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) +#define eap_client_active(pcb) ((pcb)->eap.es_client.ea_state == eapListen) #if PPP_SERVER -#define eap_server_active(esp) \ - ((esp)->es_server.ea_state >= eapIdentify && \ - (esp)->es_server.ea_state <= eapMD5Chall) +#define eap_server_active(pcb) \ + ((pcb)->eap.es_server.ea_state >= eapIdentify && \ + (pcb)->eap.es_server.ea_state <= eapMD5Chall) #endif /* PPP_SERVER */ -struct eap_auth { - char *ea_name; /* Our name */ - char *ea_peer; /* Peer's name */ - void *ea_session; /* Authentication library linkage */ - u_char *ea_skey; /* Shared encryption key */ - int ea_timeout; /* Time to wait (for retransmit/fail) */ - int ea_maxrequests; /* Max Requests allowed */ - u_short ea_namelen; /* Length of our name */ - u_short ea_peerlen; /* Length of peer's name */ - enum eap_state_code ea_state; - u_char ea_id; /* Current id */ - u_char ea_requests; /* Number of Requests sent/received */ - u_char ea_responses; /* Number of Responses */ - u_char ea_type; /* One of EAPT_* */ - u_int32_t ea_keyflags; /* SRP shared key usage flags */ -}; - -/* - * Complete EAP state for one PPP session. - */ -typedef struct eap_state { - int es_unit; /* Interface unit number */ - struct eap_auth es_client; /* Client (authenticatee) data */ -#if PPP_SERVER - struct eap_auth es_server; /* Server (authenticator) data */ -#endif /* PPP_SERVER */ - int es_savedtime; /* Saved timeout */ - int es_rechallenge; /* EAP rechallenge interval */ - int es_lwrechallenge; /* SRP lightweight rechallenge inter */ - bool es_usepseudo; /* Use SRP Pseudonym if offered one */ - int es_usedpseudo; /* Set if we already sent PN */ - int es_challen; /* Length of challenge string */ - u_char es_challenge[MAX_CHALLENGE_LENGTH]; -} eap_state; - /* * Timeouts. */ @@ -150,10 +100,8 @@ typedef struct eap_state { #define EAP_DEFREQTIME 20 /* Time to wait for peer request */ #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ -extern eap_state eap_states[]; - -void eap_authwithpeer (int unit, char *localname); -void eap_authpeer (int unit, char *localname); +void eap_authwithpeer(ppp_pcb *pcb, char *localname); +void eap_authpeer(ppp_pcb *pcb, char *localname); extern struct protent eap_protent; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index dde28bf5..274f177b 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -85,6 +85,10 @@ typedef unsigned char u_char; #endif +#ifndef bool +typedef unsigned char bool; +#endif + /************************* *** PUBLIC DEFINITIONS *** @@ -261,6 +265,61 @@ static struct chap_server_state { #endif /* PPP_SERVER */ #endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +/* + * Complete EAP state for one PPP session. + */ +enum eap_state_code { + eapInitial = 0, /* No EAP authentication yet requested */ + eapPending, /* Waiting for LCP (no timer) */ + eapClosed, /* Authentication not in use */ + eapListen, /* Client ready (and timer running) */ + eapIdentify, /* EAP Identify sent */ + eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ + eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ + eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ + eapMD5Chall, /* Sent MD5-Challenge */ + eapOpen, /* Completed authentication */ + eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ + eapBadAuth /* Failed authentication */ +}; + +struct eap_auth { + char *ea_name; /* Our name */ + char *ea_peer; /* Peer's name */ + void *ea_session; /* Authentication library linkage */ + u_char *ea_skey; /* Shared encryption key */ + int ea_timeout; /* Time to wait (for retransmit/fail) */ + int ea_maxrequests; /* Max Requests allowed */ + u_short ea_namelen; /* Length of our name */ + u_short ea_peerlen; /* Length of peer's name */ + enum eap_state_code ea_state; + u_char ea_id; /* Current id */ + u_char ea_requests; /* Number of Requests sent/received */ + u_char ea_responses; /* Number of Responses */ + u_char ea_type; /* One of EAPT_* */ + u_int32_t ea_keyflags; /* SRP shared key usage flags */ +}; + +#ifndef EAP_MAX_CHALLENGE_LENGTH +#define EAP_MAX_CHALLENGE_LENGTH 24 +#endif +typedef struct eap_state { + int es_unit; /* Interface unit number */ + struct eap_auth es_client; /* Client (authenticatee) data */ +#if PPP_SERVER + struct eap_auth es_server; /* Server (authenticator) data */ +#endif /* PPP_SERVER */ + int es_savedtime; /* Saved timeout */ + int es_rechallenge; /* EAP rechallenge interval */ + int es_lwrechallenge; /* SRP lightweight rechallenge inter */ + bool es_usepseudo; /* Use SRP Pseudonym if offered one */ + int es_usedpseudo; /* Set if we already sent PN */ + int es_challen; /* Length of challenge string */ + u_char es_challenge[EAP_MAX_CHALLENGE_LENGTH]; +} eap_state; +#endif /* EAP_SUPPORT */ + /* * PPP interface control block. */ @@ -320,6 +379,10 @@ typedef struct ppp_pcb_s { chap_server_state chap_server; #endif /* PPP_SERVER */ #endif /* CHAP_SUPPORT */ + +#if EAP_SUPPORT + eap_state eap; +#endif /* EAP_SUPPORT */ } ppp_pcb; /************************ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 487adb96..680f9287 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -40,10 +40,6 @@ #include /* formats */ #include -#ifndef bool -typedef unsigned char bool; -#endif - #include "lwip/netif.h" #include "lwip/def.h" #include "lwip/timers.h" From 19238a910c39b6ee0bd714586cdc3a96d0a8e83b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 15 Jun 2012 01:22:01 +0200 Subject: [PATCH 164/320] global variables removed from chap support --- src/netif/ppp/auth.c | 4 ++-- src/netif/ppp/chap-new.c | 23 ++++++++--------------- src/netif/ppp/chap-new.h | 3 --- src/netif/ppp/lcp.c | 3 ++- src/netif/ppp/ppp.c | 5 +++++ src/netif/ppp/ppp.h | 8 ++++++++ 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 1780ad0f..fe197942 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1348,8 +1348,8 @@ auth_check_options() #endif /* EAP_SUPPORT */ ) { #if CHAP_SUPPORT - wo->neg_chap = chap_mdtype_all != MDTYPE_NONE; - wo->chap_mdtype = chap_mdtype_all; + wo->neg_chap = pcb->chap_mdtype_all != MDTYPE_NONE; + wo->chap_mdtype = pcb->chap_mdtype_all; #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT wo->neg_upap = 1; diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index a70e5bdb..cb90a4e0 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -52,21 +52,12 @@ #define MDTYPE_ALL (MDTYPE_MD5) #endif -int chap_mdtype_all = MDTYPE_ALL; - /* Hook for a plugin to validate CHAP challenge */ int (*chap_verify_hook)(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space) = NULL; -/* - * Option variables. - */ -int chap_timeout_time = 3; -int chap_max_transmits = 10; -int chap_rechallenge_time = 0; - #if PPP_OPTIONS /* * Command-line options. @@ -74,9 +65,9 @@ int chap_rechallenge_time = 0; static option_t chap_option_list[] = { { "chap-restart", o_int, &chap_timeout_time, "Set timeout for CHAP", OPT_PRIO }, - { "chap-max-challenge", o_int, &chap_max_transmits, + { "chap-max-challenge", o_int, &pcb->settings.chap_max_transmits, "Set max #xmits for challenge", OPT_PRIO }, - { "chap-interval", o_int, &chap_rechallenge_time, + { "chap-interval", o_int, &pcb->settings.chap_rechallenge_time, "Set interval for rechallenge", OPT_PRIO }, { NULL } }; @@ -138,6 +129,8 @@ static void chap_init(int unit) { memset(&pcb->chap_server, 0, sizeof(chap_server_state)); #endif /* PPP_SERVER */ + pcb->chap_mdtype_all = MDTYPE_ALL; + chap_md5_init(); #if MSCHAP_SUPPORT chapms_init(); @@ -245,7 +238,7 @@ static void chap_timeout(void *arg) { pcb->chap_server.challenge_xmits = 0; chap_generate_challenge(pcb); pcb->chap_server.flags |= CHALLENGE_VALID; - } else if (pcb->chap_server.challenge_xmits >= chap_max_transmits) { + } else if (pcb->chap_server.challenge_xmits >= pcb->settings.chap_max_transmits) { pcb->chap_server.flags &= ~CHALLENGE_VALID; pcb->chap_server.flags |= AUTH_DONE | AUTH_FAILED; auth_peer_fail(pcb, PPP_CHAP); @@ -255,7 +248,7 @@ static void chap_timeout(void *arg) { ppp_write(pcb, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); ++pcb->chap_server.challenge_xmits; pcb->chap_server.flags |= TIMEOUT_PENDING; - TIMEOUT(chap_timeout, arg, chap_timeout_time); + TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time); } /* @@ -380,10 +373,10 @@ static void chap_handle_response(ppp_pcb *pcb, int id, auth_peer_success(pcb, PPP_CHAP, pcb->chap_server.digest->code, name, strlen(name)); - if (chap_rechallenge_time) { + if (pcb->settings.chap_rechallenge_time) { pcb->chap_server.flags |= TIMEOUT_PENDING; TIMEOUT(chap_timeout, pcb, - chap_rechallenge_time); + pcb->settings.chap_rechallenge_time); } } pcb->chap_server.flags |= AUTH_DONE; diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h index 902fed7e..c85a91af 100644 --- a/src/netif/ppp/chap-new.h +++ b/src/netif/ppp/chap-new.h @@ -67,9 +67,6 @@ #define MDTYPE_MD5 0x4 #define MDTYPE_NONE 0 -/* hashes supported by this instance of pppd */ -extern int chap_mdtype_all; - #if MSCHAP_SUPPORT /* Return the digest alg. ID for the most preferred digest type. */ #define CHAP_DIGEST(mdtype) \ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index c671d44c..9279bf7f 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -378,6 +378,7 @@ static void lcp_init(unit) int unit; { + ppp_pcb *pcb = &ppp_pcb_list[unit]; fsm *f = &lcp_fsm[unit]; lcp_options *wo = &lcp_wantoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; @@ -402,7 +403,7 @@ lcp_init(unit) ao->neg_asyncmap = 1; #if CHAP_SUPPORT ao->neg_chap = 1; - ao->chap_mdtype = chap_mdtype_all; + ao->chap_mdtype = pcb->chap_mdtype_all; #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT ao->neg_upap = 1; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 4b3d6e4b..261d86f6 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -255,8 +255,13 @@ ppp_pcb *ppp_new(void) { pcb->status = EXIT_OK; new_phase(pcb, PHASE_INITIALIZE); + /* default configuration */ pcb->settings.usepeerdns = 1; pcb->settings.persist = 1; +#if CHAP_SUPPORT + pcb->settings.chap_timeout_time = 3; + pcb->settings.chap_max_transmits = 10; +#endif /* CHAP_SUPPPORT */ /* * Initialize each protocol. diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 274f177b..282b018f 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -169,6 +169,12 @@ typedef struct ppp_settings_s { #endif /* PPP_SERVER */ /* FIXME: make it a compile time option */ char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ + +#if CHAP_SUPPORT + int chap_timeout_time; + int chap_max_transmits; + int chap_rechallenge_time; +#endif /* CHAP_SUPPPORT */ } ppp_settings; struct ppp_addrs { @@ -374,6 +380,8 @@ typedef struct ppp_pcb_s { #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT + /* FIXME: we can probably remove this entry */ + int chap_mdtype_all; /* hashes supported by this instance of pppd */ chap_client_state chap_client; #if PPP_SERVER chap_server_state chap_server; From 4b7e3af77c4b0dbd156a1987f4b5ed96ebb87a36 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 02:13:50 +0200 Subject: [PATCH 165/320] IPCP and LCP structures moved to ppp_pcb --- src/netif/ppp/auth.c | 6 +- src/netif/ppp/fsm.h | 4 + src/netif/ppp/ipcp.c | 254 ++++++++++++++++----------------------- src/netif/ppp/ipcp.h | 10 +- src/netif/ppp/lcp.c | 192 +++++++++++++---------------- src/netif/ppp/lcp.h | 28 +++-- src/netif/ppp/ppp.c | 21 ++-- src/netif/ppp/ppp.h | 18 ++- src/netif/ppp/ppp_impl.h | 9 +- 9 files changed, 244 insertions(+), 298 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index fe197942..cb4d6295 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -731,7 +731,7 @@ void link_established(ppp_pcb *pcb) { #if PPP_SERVER lcp_options *go = &lcp_gotoptions[pcb->unit]; #endif /* #if PPP_SERVER */ - lcp_options *ho = &lcp_hisoptions[pcb->unit]; + lcp_options *ho = &pcb->lcp_hisoptions; int i; struct protent *protp; @@ -1444,8 +1444,8 @@ auth_check_options() * to use for authenticating ourselves and/or the peer. */ void auth_reset(ppp_pcb *pcb) { - lcp_options *go = &lcp_gotoptions[pcb->unit]; - lcp_options *ao = &lcp_allowoptions[pcb->unit]; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *ao = &pcb->lcp_allowoptions; if( pcb->settings.passwd[0] ) { diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index 679dc187..8fba09fd 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -45,6 +45,9 @@ #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#ifndef FSM_H +#define FSM_H + /* * Packet header = Code, id, length. */ @@ -170,4 +173,5 @@ void fsm_sdata (fsm *, int, int, u_char *, int); */ extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ +#endif /* FSM_H */ #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index f5b84f55..96653f1b 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -65,14 +65,11 @@ #include "ipcp.h" /* 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 */ - u_int32_t netmask = 0; /* IP netmask to set on interface */ +#if 0 /* UNUSED */ bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ +#endif /* UNUSED */ bool noremoteip = 0; /* Let him have no IP address */ #if 0 /* UNUSED */ @@ -106,18 +103,16 @@ static char netmask_str[20]; /* string form of netmask value */ /* * 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, 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 void ipcp_resetci(fsm *f); /* Reset our CI */ +static int ipcp_cilen(fsm *f); /* Return length of our CI */ +static void ipcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */ +static int ipcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ +static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject);/* Peer nak'd our CI */ +static int ipcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ +static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */ +static void ipcp_up(fsm *f); /* We're UP */ +static void ipcp_down(fsm *f); /* We're DOWN */ +static void ipcp_finished(fsm *f); /* Don't need lower layer */ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ ipcp_resetci, /* Reset our Configuration Information */ @@ -254,16 +249,16 @@ static option_t ipcp_option_list[] = { /* * 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 void ipcp_init(int unit); +static void ipcp_open(int unit); +static void ipcp_close(int unit, char *reason); +static void ipcp_lowerup(int unit); +static void ipcp_lowerdown(int unit); +static void ipcp_input(int unit, u_char *p, int len); +static void ipcp_protrej(int unit); #if PRINTPKT_SUPPORT -static int ipcp_printpkt (u_char *, int, - void (*) (void *, char *, ...), void *); +static int ipcp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ #if PPP_OPTIONS static void ip_check_options (void); @@ -589,18 +584,17 @@ parse_dotted_ip(p, vp) /* * ipcp_init - Initialize IPCP. */ -static void -ipcp_init(unit) - int unit; -{ - fsm *f = &ipcp_fsm[unit]; - ipcp_options *wo = &ipcp_wantoptions[unit]; - ipcp_options *ao = &ipcp_allowoptions[unit]; +static void ipcp_init(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->ipcp_fsm; + + ipcp_options *wo = &pcb->ipcp_wantoptions; + ipcp_options *ao = &pcb->ipcp_allowoptions; f->unit = unit; f->protocol = PPP_IPCP; f->callbacks = &ipcp_callbacks; - fsm_init(&ipcp_fsm[unit]); + fsm_init(f); /* * Some 3G modems use repeated IPCP NAKs as a way of stalling @@ -644,11 +638,10 @@ ipcp_init(unit) /* * ipcp_open - IPCP is allowed to come up. */ -static void -ipcp_open(unit) - int unit; -{ - fsm_open(&ipcp_fsm[unit]); +static void ipcp_open(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->ipcp_fsm; + fsm_open(f); ipcp_is_open = 1; } @@ -656,47 +649,40 @@ ipcp_open(unit) /* * ipcp_close - Take IPCP down. */ -static void -ipcp_close(unit, reason) - int unit; - char *reason; -{ - fsm_close(&ipcp_fsm[unit], reason); +static void ipcp_close(int unit, char *reason) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->ipcp_fsm; + fsm_close(f, reason); } /* * ipcp_lowerup - The lower layer is up. */ -static void -ipcp_lowerup(unit) - int unit; -{ - fsm_lowerup(&ipcp_fsm[unit]); +static void ipcp_lowerup(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->ipcp_fsm; + fsm_lowerup(f); } /* * ipcp_lowerdown - The lower layer is down. */ -static void -ipcp_lowerdown(unit) - int unit; -{ - fsm_lowerdown(&ipcp_fsm[unit]); +static void ipcp_lowerdown(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->ipcp_fsm; + fsm_lowerdown(f); } /* * ipcp_input - Input IPCP packet. */ -static void -ipcp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm_input(&ipcp_fsm[unit], p, len); +static void ipcp_input(int unit, u_char *p, int len) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->ipcp_fsm; + fsm_input(f, p, len); } @@ -705,11 +691,10 @@ ipcp_input(unit, p, len) * * Pretend the lower layer went down, so we shut up. */ -static void -ipcp_protrej(unit) - int unit; -{ - fsm_lowerdown(&ipcp_fsm[unit]); +static void ipcp_protrej(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->ipcp_fsm; + fsm_lowerdown(f); } @@ -717,14 +702,11 @@ ipcp_protrej(unit) * ipcp_resetci - Reset our CI. * Called by fsm_sconfreq, Send Configure Request. */ -static void -ipcp_resetci(f) - fsm *f; -{ - ppp_pcb *pc = &ppp_pcb_list[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *ao = &ipcp_allowoptions[f->unit]; +static void ipcp_resetci(fsm *f) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ipcp_options *wo = &pcb->ipcp_wantoptions; + ipcp_options *go = &pcb->ipcp_gotoptions; + ipcp_options *ao = &pcb->ipcp_allowoptions; wo->req_addr = (wo->neg_addr || wo->old_addrs) && (ao->neg_addr || ao->old_addrs); @@ -732,8 +714,8 @@ ipcp_resetci(f) wo->accept_local = 1; if (wo->hisaddr == 0) wo->accept_remote = 1; - wo->req_dns1 = pc->settings.usepeerdns; /* Request DNS addresses from the peer */ - wo->req_dns2 = pc->settings.usepeerdns; + wo->req_dns1 = pcb->settings.usepeerdns; /* Request DNS addresses from the peer */ + wo->req_dns2 = pcb->settings.usepeerdns; *go = *wo; if (!ask_for_local) go->ouraddr = 0; @@ -745,7 +727,7 @@ ipcp_resetci(f) } } #endif /* UNUSED */ - BZERO(&ipcp_hisoptions[f->unit], sizeof(ipcp_options)); + BZERO(&pcb->ipcp_hisoptions, sizeof(ipcp_options)); } @@ -753,13 +735,11 @@ ipcp_resetci(f) * ipcp_cilen - Return length of our CI. * Called by fsm_sconfreq, Send Configure Request. */ -static int -ipcp_cilen(f) - fsm *f; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; +static int ipcp_cilen(fsm *f) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ipcp_options *go = &pcb->ipcp_gotoptions; + ipcp_options *wo = &pcb->ipcp_wantoptions; + ipcp_options *ho = &pcb->ipcp_hisoptions; #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) @@ -797,13 +777,9 @@ ipcp_cilen(f) * ipcp_addci - Add our desired CIs to a packet. * Called by fsm_sconfreq, Send Configure Request. */ -static void -ipcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; +static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ipcp_options *go = &pcb->ipcp_gotoptions; int len = *lenp; #define ADDCIADDRS(opt, neg, val1, val2) \ @@ -904,13 +880,9 @@ ipcp_addci(f, ucp, lenp) * 0 - Ack was bad. * 1 - Ack was good. */ -static int -ipcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; +static int ipcp_ackci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ipcp_options *go = &pcb->ipcp_gotoptions; u_short cilen, citype, cishort; u_int32_t cilong; u_char cimaxslotindex, cicflag; @@ -1029,14 +1001,9 @@ bad: * 0 - Nak was bad. * 1 - Nak was good. */ -static int -ipcp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; +static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ipcp_options *go = &pcb->ipcp_gotoptions; u_char cimaxslotindex, cicflag; u_char citype, cilen, *next; u_short cishort; @@ -1278,13 +1245,9 @@ bad: * ipcp_rejci - Reject some of our CIs. * Callback from fsm_rconfnakrej. */ -static int -ipcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; +static int ipcp_rejci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ipcp_options *go = &pcb->ipcp_gotoptions; u_char cimaxslotindex, ciflag, cilen; u_short cishort; u_int32_t cilong; @@ -1428,17 +1391,15 @@ bad: * 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. + * + * inp = Requested CIs + * len = Length of requested CIs */ -static int -ipcp_reqci(f, inp, len, reject_if_disagree) - 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]; +static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ipcp_options *wo = &pcb->ipcp_wantoptions; + ipcp_options *ho = &pcb->ipcp_hisoptions; + ipcp_options *ao = &pcb->ipcp_allowoptions; u_char *cip, *next; /* Pointer to current and next CIs */ u_short cilen, citype; /* Parsed len, type */ u_short cishort; /* Parsed short value */ @@ -1797,15 +1758,12 @@ ip_demand_conf(u) * * Configure the IP network interface appropriately and bring it up. */ -static void -ipcp_up(f) - fsm *f; -{ +static void ipcp_up(fsm *f) { ppp_pcb *pcb = &ppp_pcb_list[f->unit]; u_int32_t mask; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; + ipcp_options *ho = &pcb->ipcp_hisoptions; + ipcp_options *go = &pcb->ipcp_gotoptions; + ipcp_options *wo = &pcb->ipcp_wantoptions; IPCPDEBUG(("ipcp: up")); @@ -1957,17 +1915,17 @@ ipcp_up(f) sifnpmode(pcb, PPP_IP, NPMODE_PASS); /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) + if (wo->default_route) if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ - if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) + if (ho->hisaddr != 0 && wo->proxy_arp) if (sifproxyarp(pcb, ho->hisaddr)) proxy_arp_set[f->unit] = 1; - ipcp_wantoptions[0].ouraddr = go->ouraddr; + wo->ouraddr = go->ouraddr; notice("local IP address %I", go->ouraddr); if (ho->hisaddr != 0) @@ -2001,11 +1959,11 @@ ipcp_up(f) * Take the IP network interface down, clear its addresses * and delete routes through it. */ -static void -ipcp_down(f) - fsm *f; -{ +static void ipcp_down(fsm *f) { ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ipcp_options *ho = &pcb->ipcp_hisoptions; + ipcp_options *go = &pcb->ipcp_gotoptions; + IPCPDEBUG(("ipcp: down")); #if PPP_STATS_SUPPORT /* XXX a bit IPv4-centric here, we only need to get the stats @@ -2045,9 +2003,9 @@ ipcp_down(f) { sifnpmode(pcb, PPP_IP, NPMODE_DROP); sifdown(pcb); - ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, - ipcp_hisoptions[f->unit].hisaddr, 0); - cdns(pcb, ipcp_gotoptions[f->unit].dnsaddr[0], ipcp_gotoptions[f->unit].dnsaddr[1]); + ipcp_clear_addrs(f->unit, go->ouraddr, + ho->hisaddr, 0); + cdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); } } @@ -2083,10 +2041,7 @@ static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, boo /* * ipcp_finished - possibly shut down the lower layers. */ -static void -ipcp_finished(f) - fsm *f; -{ +static void ipcp_finished(fsm *f) { ppp_pcb *pcb = &ppp_pcb_list[f->unit]; if (ipcp_is_open) { ipcp_is_open = 0; @@ -2116,13 +2071,8 @@ static char *ipcp_codenames[] = { "TermReq", "TermAck", "CodeRej" }; -static int -ipcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) (void *, char *, ...); - void *arg; -{ +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; diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index fbd0214c..a443a168 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -45,6 +45,9 @@ #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#ifndef IPCP_H +#define IPCP_H + /* * Options. */ @@ -89,16 +92,11 @@ typedef struct ipcp_options { u_int32_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[]; - #if 0 /* UNUSED, already defined by lwIP */ char *ip_ntoa (u_int32_t); #endif /* UNUSED, already defined by lwIP */ extern struct protent ipcp_protent; +#endif /* IPCP_H */ #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 9279bf7f..0fc7b784 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -70,7 +70,7 @@ /* steal a bit in fsm flags word */ #define DELAYED_UP 0x100 -static void lcp_delayed_up (void *); +static void lcp_delayed_up(void *arg); /* * LCP-related command-line options. @@ -209,11 +209,6 @@ static option_t lcp_option_list[] = { #endif /* PPP_OPTIONS */ /* 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 */ #if PPPOS_SUPPORT ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */ #endif /* PPPOS_SUPPORT */ @@ -246,8 +241,8 @@ 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 lcp_echo_lowerup(int unit); +static void lcp_echo_lowerdown(int unit); static void LcpEchoTimeout (void *); static void lcp_received_echo_reply (fsm *, int, u_char *, int); static void LcpSendEchoRequest (fsm *); @@ -277,12 +272,12 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ * 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 void lcp_init(int unit); +static void lcp_input(int unit, u_char *p, int len); +static void lcp_protrej(int unit); #if PRINTPKT_SUPPORT -static int lcp_printpkt (u_char *, int, - void (*) (void *, char *, ...), void *); +static int lcp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ struct protent lcp_protent = { @@ -374,14 +369,11 @@ printendpoint(opt, printer, arg) /* * lcp_init - Initialize LCP. */ -static void -lcp_init(unit) - int unit; -{ +static void lcp_init(int unit) { ppp_pcb *pcb = &ppp_pcb_list[unit]; - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; + fsm *f = &pcb->lcp_fsm; + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; f->unit = unit; f->protocol = PPP_LCP; @@ -439,12 +431,10 @@ lcp_init(unit) /* * lcp_open - LCP is allowed to come up. */ -void -lcp_open(unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; +void lcp_open(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->lcp_fsm; + lcp_options *wo = &pcb->lcp_wantoptions; f->flags &= ~(OPT_PASSIVE | OPT_SILENT); if (wo->passive) @@ -458,13 +448,9 @@ lcp_open(unit) /* * lcp_close - Take LCP down. */ -void -lcp_close(unit, reason) - int unit; - char *reason; -{ +void lcp_close(int unit, char *reason) { ppp_pcb *pcb = &ppp_pcb_list[unit]; - fsm *f = &lcp_fsm[unit]; + fsm *f = &pcb->lcp_fsm; int oldstate; if (pcb->phase != PHASE_DEAD && pcb->phase != PHASE_MASTER) @@ -494,13 +480,13 @@ lcp_close(unit, reason) /* * lcp_lowerup - The lower layer is up. */ -void -lcp_lowerup(unit) - int unit; -{ +void lcp_lowerup(int unit) { ppp_pcb *pcb = &ppp_pcb_list[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - fsm *f = &lcp_fsm[unit]; + lcp_options *wo = &pcb->lcp_wantoptions; +#if PPPOS_SUPPORT + lcp_options *ao = &pcb->lcp_allowoptions; +#endif /* PPPOS_SUPPORT */ + fsm *f = &pcb->lcp_fsm; /* * Don't use A/C or protocol compression on transmission, * but accept A/C and protocol compressed packets @@ -515,8 +501,8 @@ lcp_lowerup(unit) return; peer_mru[unit] = PPP_MRU; - #if PPPOS_SUPPORT - lcp_allowoptions[unit].asyncmap = (u_long)xmit_accm[unit][0] +#if PPPOS_SUPPORT + ao->asyncmap = (u_long)xmit_accm[unit][0] | ((u_long)xmit_accm[unit][1] << 8) | ((u_long)xmit_accm[unit][2] << 16) | ((u_long)xmit_accm[unit][3] << 24); @@ -538,27 +524,22 @@ lcp_lowerup(unit) /* * lcp_lowerdown - The lower layer is down. */ -void -lcp_lowerdown(unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; +void lcp_lowerdown(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->lcp_fsm; if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; UNTIMEOUT(lcp_delayed_up, f); } else - fsm_lowerdown(&lcp_fsm[unit]); + fsm_lowerdown(f); } /* * lcp_delayed_up - Bring the lower layer up now. */ -static void -lcp_delayed_up(arg) - void *arg; -{ +static void lcp_delayed_up(void *arg) { fsm *f = arg; if (f->flags & DELAYED_UP) { @@ -571,13 +552,9 @@ lcp_delayed_up(arg) /* * lcp_input - Input LCP packet. */ -static void -lcp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm *f = &lcp_fsm[unit]; +static void lcp_input(int unit, u_char *p, int len) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->lcp_fsm; if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; @@ -597,6 +574,8 @@ lcp_extcode(f, code, id, inp, len) u_char *inp; int len; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; u_char *magp; switch( code ){ @@ -608,7 +587,7 @@ lcp_extcode(f, code, id, inp, len) if (f->state != OPENED) break; magp = inp; - PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); + PUTLONG(go->magicnumber, magp); fsm_sdata(f, ECHOREP, id, inp, len); break; @@ -696,27 +675,22 @@ lcp_rprotrej(f, inp, len) * lcp_protrej - A Protocol-Reject was received. */ /*ARGSUSED*/ -static void -lcp_protrej(unit) - int unit; -{ +static void lcp_protrej(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; /* * Can't reject LCP! */ error("Received Protocol-Reject for LCP!"); - fsm_protreject(&lcp_fsm[unit]); + fsm_protreject(&pcb->lcp_fsm); } /* * lcp_sprotrej - Send a Protocol-Reject for some protocol. */ -void -lcp_sprotrej(unit, p, len) - int unit; - u_char *p; - int len; -{ +void lcp_sprotrej(int unit, u_char *p, int len) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->lcp_fsm; /* * Send back the protocol and the information field of the * rejected packet. We only get here if LCP is in the OPENED state. @@ -724,7 +698,7 @@ lcp_sprotrej(unit, p, len) p += 2; len -= 2; - fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, + fsm_sdata(f, PROTREJ, ++f->id, p, len); } @@ -737,9 +711,9 @@ lcp_resetci(f) fsm *f; { ppp_pcb *pcb = &ppp_pcb_list[f->unit]; - lcp_options *wo = &lcp_wantoptions[f->unit]; - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *ao = &lcp_allowoptions[f->unit]; + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *ao = &pcb->lcp_allowoptions; wo->magicnumber = magic(); wo->numloops = 0; @@ -767,7 +741,8 @@ static int lcp_cilen(f) fsm *f; { - lcp_options *go = &lcp_gotoptions[f->unit]; + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) #if CHAP_SUPPORT @@ -833,7 +808,8 @@ lcp_addci(f, ucp, lenp) u_char *ucp; int *lenp; { - lcp_options *go = &lcp_gotoptions[f->unit]; + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; u_char *start_ucp = ucp; #define ADDCIVOID(opt, neg) \ @@ -948,7 +924,8 @@ lcp_ackci(f, p, len) u_char *p; int len; { - lcp_options *go = &lcp_gotoptions[f->unit]; + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; u_char cilen, citype, cichar; u_short cishort; u_int32_t cilong; @@ -1131,9 +1108,9 @@ lcp_nakci(f, p, len, treat_as_reject) int len; int treat_as_reject; { - ppp_pcb *pc = &ppp_pcb_list[f->unit]; - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *wo = &lcp_wantoptions[f->unit]; + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *wo = &pcb->lcp_wantoptions; u_char citype, cichar, *next; u_short cishort; u_int32_t cilong; @@ -1558,7 +1535,7 @@ lcp_nakci(f, p, len, treat_as_reject) if (looped_back) { if (++try.numloops >= lcp_loopbackfail) { notice("Serial line is looped back."); - pc->status = EXIT_LOOPBACK; + pcb->status = EXIT_LOOPBACK; lcp_close(f->unit, "Loopback detected"); } } else @@ -1589,7 +1566,8 @@ lcp_rejci(f, p, len) u_char *p; int len; { - lcp_options *go = &lcp_gotoptions[f->unit]; + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; u_char cichar; u_short cishort; u_int32_t cilong; @@ -1820,9 +1798,10 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) 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]; + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *ho = &pcb->lcp_hisoptions; + lcp_options *ao = &pcb->lcp_allowoptions; 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 */ @@ -2281,10 +2260,10 @@ lcp_up(f) fsm *f; { ppp_pcb *pcb = &ppp_pcb_list[f->unit]; - 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]; + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ho = &pcb->lcp_hisoptions; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *ao = &pcb->lcp_allowoptions; int mtu, mru; if (!go->neg_magicnumber) @@ -2333,7 +2312,7 @@ lcp_down(f) fsm *f; { ppp_pcb *pcb = &ppp_pcb_list[f->unit]; - lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; lcp_echo_lowerdown(f->unit); @@ -2376,13 +2355,8 @@ static char *lcp_codenames[] = { "TimeRem" }; -static int -lcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) (void *, char *, ...); - void *arg; -{ +static int lcp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg) { int code, id, len, olen, i; u_char *pstart, *optend; u_short cishort; @@ -2689,6 +2663,8 @@ lcp_received_echo_reply (f, id, inp, len) u_char *inp; int len; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; u_int32_t magic; /* Check the magic number - don't count replies from ourselves. */ @@ -2697,8 +2673,8 @@ lcp_received_echo_reply (f, id, inp, len) return; } GETLONG(magic, inp); - if (lcp_gotoptions[f->unit].neg_magicnumber - && magic == lcp_gotoptions[f->unit].magicnumber) { + if (go->neg_magicnumber + && magic == go->magicnumber) { warn("appear to have received our own echo-reply!"); return; } @@ -2715,6 +2691,8 @@ static void LcpSendEchoRequest (f) fsm *f; { + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + lcp_options *go = &pcb->lcp_gotoptions; u_int32_t lcp_magic; u_char pkt[4], *pktp; @@ -2752,7 +2730,7 @@ LcpSendEchoRequest (f) * Make and send the echo request frame. */ if (f->state == OPENED) { - lcp_magic = lcp_gotoptions[f->unit].magicnumber; + lcp_magic = go->magicnumber; pktp = pkt; PUTLONG(lcp_magic, pktp); fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt); @@ -2764,11 +2742,9 @@ LcpSendEchoRequest (f) * lcp_echo_lowerup - Start the timer for the LCP frame */ -static void -lcp_echo_lowerup (unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; +static void lcp_echo_lowerup(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->lcp_fsm; /* Clear the parameters for generating echo frames */ lcp_echos_pending = 0; @@ -2784,11 +2760,9 @@ lcp_echo_lowerup (unit) * lcp_echo_lowerdown - Stop the timer for the LCP frame */ -static void -lcp_echo_lowerdown (unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; +static void lcp_echo_lowerdown(int unit) { + ppp_pcb *pcb = &ppp_pcb_list[unit]; + fsm *f = &pcb->lcp_fsm; if (lcp_echo_timer_running != 0) { UNTIMEOUT (LcpEchoTimeout, f); diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index eb1e33f8..38350a53 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -45,6 +45,9 @@ #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#ifndef LCP_H +#define LCP_H + /* * Options. */ @@ -85,6 +88,15 @@ /* Value used as data for CI_CALLBACK option */ #define CBCP_OPT 6 /* Use callback control protocol */ +/* FIXME: moved temporarily from ppp.h */ +/* An endpoint discriminator, used with multilink. */ +#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ +struct epdisc { + unsigned char class; + unsigned char length; + unsigned char value[MAX_ENDP_LEN]; +}; + /* * The state of options is described by an lcp_options structure. */ @@ -127,11 +139,6 @@ typedef struct lcp_options { struct epdisc endpoint; /* endpoint discriminator */ } 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[]; #if PPPOS_SUPPORT extern ext_accm xmit_accm[]; #endif /* #if PPPOS_SUPPORT */ @@ -140,11 +147,11 @@ extern ext_accm xmit_accm[]; #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 */ +void lcp_open(int unit); +void lcp_close(int unit, char *reason); +void lcp_lowerup(int unit); +void lcp_lowerdown(int unit); +void lcp_sprotrej(int unit, u_char *p, int len); /* send protocol reject */ extern struct protent lcp_protent; @@ -152,4 +159,5 @@ extern struct protent lcp_protent; before deciding the link is looped-back. */ #define DEFLOOPBACKFAIL 10 +#endif /* LCP_H */ #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 261d86f6..004d0021 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -389,6 +389,9 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state); int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + LWIP_UNUSED_ARG(service_name); LWIP_UNUSED_ARG(concentrator_name); @@ -402,15 +405,15 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; - lcp_wantoptions[pcb->unit].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_wantoptions[pcb->unit].neg_asyncmap = 0; - lcp_wantoptions[pcb->unit].neg_pcompression = 0; - lcp_wantoptions[pcb->unit].neg_accompression = 0; + wo->mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + wo->neg_asyncmap = 0; + wo->neg_pcompression = 0; + wo->neg_accompression = 0; - lcp_allowoptions[pcb->unit].mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_allowoptions[pcb->unit].neg_asyncmap = 0; - lcp_allowoptions[pcb->unit].neg_pcompression = 0; - lcp_allowoptions[pcb->unit].neg_accompression = 0; + ao->mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + ao->neg_asyncmap = 0; + ao->neg_pcompression = 0; + ao->neg_accompression = 0; if(pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { pcb->open_flag = 0; @@ -515,7 +518,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { /* * Toss all non-LCP packets unless LCP is OPEN. */ - if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { + if (protocol != PPP_LCP && pcb->lcp_fsm.state != OPENED) { dbglog("Discarded non-LCP packet when LCP not open"); goto drop; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 282b018f..54a339a2 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -47,7 +47,6 @@ #include "vj.h" - /** PPP_INPROC_MULTITHREADED==1 call ppp_input using tcpip_callback(). * Set this to 0 if pppos_input_proc is called inside tcpip_thread or with NO_SYS==1. * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). @@ -89,6 +88,10 @@ typedef unsigned char u_char; typedef unsigned char bool; #endif +#include "fsm.h" +#include "lcp.h" +#include "ipcp.h" + /************************* *** PUBLIC DEFINITIONS *** @@ -391,6 +394,19 @@ typedef struct ppp_pcb_s { #if EAP_SUPPORT eap_state eap; #endif /* EAP_SUPPORT */ + + fsm lcp_fsm; /* LCP fsm structure */ + lcp_options lcp_wantoptions; /* Options that we want to request */ + lcp_options lcp_gotoptions; /* Options that peer ack'd */ + lcp_options lcp_allowoptions; /* Options we allow peer to request */ + lcp_options lcp_hisoptions; /* Options that we ack'd */ + + fsm ipcp_fsm; /* IPCP fsm structure */ + ipcp_options ipcp_wantoptions; /* Options that we want to request */ + ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ + ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ + ipcp_options ipcp_hisoptions; /* Options that we ack'd */ + } ppp_pcb; /************************ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 680f9287..1358cfb7 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -221,14 +221,7 @@ struct ppp_idle { }; /* FIXME: make endpoint discriminator optional */ - -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class; - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; +/* FIXME: moved temporarily to lcp.h */ /* values for epdisc.class */ #define EPD_NULL 0 /* null discriminator, no data */ From 4a8ff6d824949f119ae4d62dbb4199df66496cb4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 02:43:13 +0200 Subject: [PATCH 166/320] protent prototype switched from unit to ppp_pcb --- src/netif/ppp/auth.c | 10 +++--- src/netif/ppp/chap-new.c | 25 ++++++------- src/netif/ppp/eap.c | 28 ++++++--------- src/netif/ppp/fsm.h | 1 + src/netif/ppp/ipcp.c | 46 +++++++++++------------- src/netif/ppp/lcp.c | 77 ++++++++++++++++++---------------------- src/netif/ppp/lcp.h | 63 ++++---------------------------- src/netif/ppp/ppp.c | 14 ++++---- src/netif/ppp/ppp.h | 53 +++++++++++++++++++++++++-- src/netif/ppp/ppp_impl.h | 18 +++++----- src/netif/ppp/upap.c | 29 ++++++--------- 11 files changed, 165 insertions(+), 199 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index cb4d6295..d3913f2b 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -711,9 +711,9 @@ void upper_layers_down(ppp_pcb *pcb) { if (!protp->enabled_flag) continue; if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) - (*protp->lowerdown)(pcb->unit); + (*protp->lowerdown)(pcb); if (protp->protocol < 0xC000 && protp->close != NULL) - (*protp->close)(pcb->unit, "LCP down"); + (*protp->close)(pcb, "LCP down"); } pcb->num_np_open = 0; pcb->num_np_up = 0; @@ -742,7 +742,7 @@ void link_established(ppp_pcb *pcb) { for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) - (*protp->lowerup)(pcb->unit); + (*protp->lowerup)(pcb); } #if 0 /* UNUSED */ @@ -979,7 +979,7 @@ void continue_networks(ppp_pcb *pcb) { && protp->protocol != PPP_ECP #endif /* ECP_SUPPORT */ && protp->enabled_flag && protp->open != NULL) { - (*protp->open)(0); + (*protp->open)(pcb); ++pcb->num_np_open; } @@ -1083,7 +1083,7 @@ void auth_withpeer_fail(ppp_pcb *pcb, int protocol) { * we can do except wait for that. */ ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); - lcp_close(pcb->unit, "Failed to authenticate ourselves to peer"); + lcp_close(pcb, "Failed to authenticate ourselves to peer"); } /* diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index cb90a4e0..95cb870a 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -91,9 +91,9 @@ static option_t chap_option_list[] = { /* * Prototypes. */ -static void chap_init(int unit); -static void chap_lowerup(int unit); -static void chap_lowerdown(int unit); +static void chap_init(ppp_pcb *pcb); +static void chap_lowerup(ppp_pcb *pcb); +static void chap_lowerdown(ppp_pcb *pcb); #if PPP_SERVER static void chap_timeout(void *arg); static void chap_generate_challenge(ppp_pcb *pcb); @@ -108,8 +108,8 @@ static void chap_respond(ppp_pcb *pcb, int id, unsigned char *pkt, int len); static void chap_handle_status(ppp_pcb *pcb, int code, int id, unsigned char *pkt, int len); -static void chap_protrej(int unit); -static void chap_input(int unit, unsigned char *pkt, int pktlen); +static void chap_protrej(ppp_pcb *pcb); +static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen); #if PRINTPKT_SUPPORT static int chap_print_pkt(unsigned char *p, int plen, void (*printer) (void *, char *, ...), void *arg); @@ -121,8 +121,7 @@ static struct chap_digest_type *chap_digests; /* * chap_init - reset to initial state. */ -static void chap_init(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void chap_init(ppp_pcb *pcb) { memset(&pcb->chap_client, 0, sizeof(chap_client_state)); #if PPP_SERVER @@ -148,8 +147,7 @@ void chap_register_digest(struct chap_digest_type *dp) { /* * chap_lowerup - we can start doing stuff now. */ -static void chap_lowerup(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void chap_lowerup(ppp_pcb *pcb) { pcb->chap_client.flags |= LOWERUP; #if PPP_SERVER @@ -159,8 +157,7 @@ static void chap_lowerup(int unit) { #endif /* PPP_SERVER */ } -static void chap_lowerdown(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void chap_lowerdown(ppp_pcb *pcb) { pcb->chap_client.flags = 0; #if PPP_SERVER @@ -502,8 +499,7 @@ static void chap_handle_status(ppp_pcb *pcb, int code, int id, } } -static void chap_input(int unit, unsigned char *pkt, int pktlen) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen) { unsigned char code, id; int len; @@ -532,8 +528,7 @@ static void chap_input(int unit, unsigned char *pkt, int pktlen) { } } -static void chap_protrej(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void chap_protrej(ppp_pcb *pcb) { #if PPP_SERVER if (pcb->chap_server.flags & TIMEOUT_PENDING) { diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 4f8747bb..e410074f 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -96,11 +96,11 @@ static option_t eap_option_list[] = { /* * Protocol entry points. */ -static void eap_init(int unit); -static void eap_input(int unit, u_char *inp, int inlen); -static void eap_protrej(int unit); -static void eap_lowerup(int unit); -static void eap_lowerdown(int unit); +static void eap_init(ppp_pcb *pcb); +static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen); +static void eap_protrej(ppp_pcb *pcb); +static void eap_lowerup(ppp_pcb *pcb); +static void eap_lowerdown(ppp_pcb *pcb); #if PRINTPKT_SUPPORT static int eap_printpkt(u_char *inp, int inlen, void (*)(void *arg, char *fmt, ...), void *arg); @@ -195,11 +195,9 @@ enum eap_state_code esc; * eap_init - Initialize state for an EAP user. This is currently * called once by main() during start-up. */ -static void eap_init(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void eap_init(ppp_pcb *pcb) { BZERO(&pcb->eap, sizeof(eap_state)); - pcb->eap.es_unit = unit; #if PPP_SERVER pcb->eap.es_server.ea_timeout = EAP_DEFTIMEOUT; pcb->eap.es_server.ea_maxrequests = EAP_DEFTRANSMITS; @@ -955,8 +953,7 @@ void *arg; * return to closed state so that those two routines will do the right * thing. */ -static void eap_lowerup(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void eap_lowerup(ppp_pcb *pcb) { /* Discard any (possibly authenticated) peer name. */ #if PPP_SERVER @@ -980,8 +977,7 @@ static void eap_lowerup(int unit) { * * Cancel all timeouts and return to initial state. */ -static void eap_lowerdown(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void eap_lowerdown(ppp_pcb *pcb) { if (eap_client_active(pcb) && pcb->eap.es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, pcb); @@ -1014,8 +1010,7 @@ static void eap_lowerdown(int unit) { * This shouldn't happen. If it does, it represents authentication * failure. */ -static void eap_protrej(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void eap_protrej(ppp_pcb *pcb) { if (eap_client_active(pcb)) { error("EAP authentication failed due to Protocol-Reject"); @@ -1027,7 +1022,7 @@ static void eap_protrej(int unit) { auth_peer_fail(pcb, PPP_EAP); } #endif /* PPP_SERVER */ - eap_lowerdown(unit); + eap_lowerdown(pcb); } /* @@ -2029,8 +2024,7 @@ static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) { /* * eap_input - Handle received EAP message. */ -static void eap_input(int unit, u_char *inp, int inlen) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen) { u_char code, id; int len; diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index 8fba09fd..d1b0d970 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -71,6 +71,7 @@ */ typedef struct fsm { int unit; /* Interface unit number */ + void *pcb; /* FIXME: Temporary */ int protocol; /* Data Link Layer Protocol field value */ int state; /* State */ int flags; /* Contains option bits */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 96653f1b..cc2cedfd 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -249,13 +249,13 @@ static option_t ipcp_option_list[] = { /* * Protocol entry points from main code. */ -static void ipcp_init(int unit); -static void ipcp_open(int unit); -static void ipcp_close(int unit, char *reason); -static void ipcp_lowerup(int unit); -static void ipcp_lowerdown(int unit); -static void ipcp_input(int unit, u_char *p, int len); -static void ipcp_protrej(int unit); +static void ipcp_init(ppp_pcb *pcb); +static void ipcp_open(ppp_pcb *pcb); +static void ipcp_close(ppp_pcb *pcb, char *reason); +static void ipcp_lowerup(ppp_pcb *pcb); +static void ipcp_lowerdown(ppp_pcb *pcb); +static void ipcp_input(ppp_pcb *pcb, u_char *p, int len); +static void ipcp_protrej(ppp_pcb *pcb); #if PRINTPKT_SUPPORT static int ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg); @@ -584,14 +584,14 @@ parse_dotted_ip(p, vp) /* * ipcp_init - Initialize IPCP. */ -static void ipcp_init(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ipcp_init(ppp_pcb *pcb) { fsm *f = &pcb->ipcp_fsm; ipcp_options *wo = &pcb->ipcp_wantoptions; ipcp_options *ao = &pcb->ipcp_allowoptions; - f->unit = unit; + f->unit = pcb->unit; + f->pcb = (void*)pcb; f->protocol = PPP_IPCP; f->callbacks = &ipcp_callbacks; fsm_init(f); @@ -638,8 +638,7 @@ static void ipcp_init(int unit) { /* * ipcp_open - IPCP is allowed to come up. */ -static void ipcp_open(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ipcp_open(ppp_pcb *pcb) { fsm *f = &pcb->ipcp_fsm; fsm_open(f); ipcp_is_open = 1; @@ -649,8 +648,7 @@ static void ipcp_open(int unit) { /* * ipcp_close - Take IPCP down. */ -static void ipcp_close(int unit, char *reason) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ipcp_close(ppp_pcb *pcb, char *reason) { fsm *f = &pcb->ipcp_fsm; fsm_close(f, reason); } @@ -659,8 +657,7 @@ static void ipcp_close(int unit, char *reason) { /* * ipcp_lowerup - The lower layer is up. */ -static void ipcp_lowerup(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ipcp_lowerup(ppp_pcb *pcb) { fsm *f = &pcb->ipcp_fsm; fsm_lowerup(f); } @@ -669,8 +666,7 @@ static void ipcp_lowerup(int unit) { /* * ipcp_lowerdown - The lower layer is down. */ -static void ipcp_lowerdown(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ipcp_lowerdown(ppp_pcb *pcb) { fsm *f = &pcb->ipcp_fsm; fsm_lowerdown(f); } @@ -679,8 +675,7 @@ static void ipcp_lowerdown(int unit) { /* * ipcp_input - Input IPCP packet. */ -static void ipcp_input(int unit, u_char *p, int len) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ipcp_input(ppp_pcb *pcb, u_char *p, int len) { fsm *f = &pcb->ipcp_fsm; fsm_input(f, p, len); } @@ -691,8 +686,7 @@ static void ipcp_input(int unit, u_char *p, int len) { * * Pretend the lower layer went down, so we shut up. */ -static void ipcp_protrej(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ipcp_protrej(ppp_pcb *pcb) { fsm *f = &pcb->ipcp_fsm; fsm_lowerdown(f); } @@ -1776,12 +1770,12 @@ static void ipcp_up(fsm *f) { if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) && wo->ouraddr != 0) { error("Peer refused to agree to our IP address"); - ipcp_close(f->unit, "Refused our IP address"); + ipcp_close(f->pcb, "Refused our IP address"); return; } if (go->ouraddr == 0) { error("Could not determine local IP address"); - ipcp_close(f->unit, "Could not determine local IP address"); + ipcp_close(f->pcb, "Could not determine local IP address"); return; } if (ho->hisaddr == 0 && !noremoteip) { @@ -1889,7 +1883,7 @@ static void ipcp_up(fsm *f) { #if PPP_DEBUG warn("Interface configuration failed"); #endif /* PPP_DEBUG */ - ipcp_close(f->unit, "Interface configuration failed"); + ipcp_close(f->pcb, "Interface configuration failed"); return; } #endif @@ -1899,7 +1893,7 @@ static void ipcp_up(fsm *f) { #if PPP_DEBUG warn("Interface failed to come up"); #endif /* PPP_DEBUG */ - ipcp_close(f->unit, "Interface configuration failed"); + ipcp_close(f->pcb, "Interface configuration failed"); return; } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 0fc7b784..2c833a0e 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -241,8 +241,8 @@ static void lcp_rprotrej (fsm *, u_char *, int); * routines to send LCP echos to peer */ -static void lcp_echo_lowerup(int unit); -static void lcp_echo_lowerdown(int unit); +static void lcp_echo_lowerup(ppp_pcb *pcb); +static void lcp_echo_lowerdown(ppp_pcb *pcb); static void LcpEchoTimeout (void *); static void lcp_received_echo_reply (fsm *, int, u_char *, int); static void LcpSendEchoRequest (fsm *); @@ -272,9 +272,9 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ * Some of these are called directly. */ -static void lcp_init(int unit); -static void lcp_input(int unit, u_char *p, int len); -static void lcp_protrej(int unit); +static void lcp_init(ppp_pcb *pcb); +static void lcp_input(ppp_pcb *pcb, u_char *p, int len); +static void lcp_protrej(ppp_pcb *pcb); #if PRINTPKT_SUPPORT static int lcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg); @@ -369,13 +369,13 @@ printendpoint(opt, printer, arg) /* * lcp_init - Initialize LCP. */ -static void lcp_init(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void lcp_init(ppp_pcb *pcb) { fsm *f = &pcb->lcp_fsm; lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; - f->unit = unit; + f->unit = pcb->unit; + f->pcb = (void*)pcb; f->protocol = PPP_LCP; f->callbacks = &lcp_callbacks; @@ -413,12 +413,12 @@ static void lcp_init(int unit) { * Set transmit escape for the flag and escape characters plus anything * set for the allowable options. */ - memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); - xmit_accm[unit][15] = 0x60; - xmit_accm[unit][0] = (u_char)((ao->asyncmap & 0xFF)); - xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF); - xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF); - xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF); + memset(xmit_accm[pcb->unit], 0, sizeof(xmit_accm[0])); + xmit_accm[pcb->unit][15] = 0x60; + xmit_accm[pcb->unit][0] = (u_char)((ao->asyncmap & 0xFF)); + xmit_accm[pcb->unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF); + xmit_accm[pcb->unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF); + xmit_accm[pcb->unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF); LCPDEBUG(("lcp_init: xmit_accm=%X %X %X %X\n", xmit_accm[unit][0], xmit_accm[unit][1], @@ -431,8 +431,7 @@ static void lcp_init(int unit) { /* * lcp_open - LCP is allowed to come up. */ -void lcp_open(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void lcp_open(ppp_pcb *pcb) { fsm *f = &pcb->lcp_fsm; lcp_options *wo = &pcb->lcp_wantoptions; @@ -448,8 +447,7 @@ void lcp_open(int unit) { /* * lcp_close - Take LCP down. */ -void lcp_close(int unit, char *reason) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void lcp_close(ppp_pcb *pcb, char *reason) { fsm *f = &pcb->lcp_fsm; int oldstate; @@ -480,8 +478,7 @@ void lcp_close(int unit, char *reason) { /* * lcp_lowerup - The lower layer is up. */ -void lcp_lowerup(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void lcp_lowerup(ppp_pcb *pcb) { lcp_options *wo = &pcb->lcp_wantoptions; #if PPPOS_SUPPORT lcp_options *ao = &pcb->lcp_allowoptions; @@ -493,19 +490,19 @@ void lcp_lowerup(int unit) { * if we are going to ask for A/C and protocol compression. */ #if PPPOS_SUPPORT - ppp_set_xaccm(pcb, &xmit_accm[unit]); + ppp_set_xaccm(pcb, &xmit_accm[pcb->unit]); #endif /* PPPOS_SUPPORT */ if (ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0) < 0 || ppp_recv_config(pcb, PPP_MRU, (lax_recv? 0: 0xffffffff), wo->neg_pcompression, wo->neg_accompression) < 0) return; - peer_mru[unit] = PPP_MRU; + peer_mru[pcb->unit] = PPP_MRU; #if PPPOS_SUPPORT - ao->asyncmap = (u_long)xmit_accm[unit][0] - | ((u_long)xmit_accm[unit][1] << 8) - | ((u_long)xmit_accm[unit][2] << 16) - | ((u_long)xmit_accm[unit][3] << 24); + ao->asyncmap = (u_long)xmit_accm[f->unit][0] + | ((u_long)xmit_accm[pcb->unit][1] << 8) + | ((u_long)xmit_accm[pcb->unit][2] << 16) + | ((u_long)xmit_accm[pcb->unit][3] << 24); LCPDEBUG(("lcp_lowerup: asyncmap=%X %X %X %X\n", xmit_accm[unit][3], xmit_accm[unit][2], @@ -524,8 +521,7 @@ void lcp_lowerup(int unit) { /* * lcp_lowerdown - The lower layer is down. */ -void lcp_lowerdown(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void lcp_lowerdown(ppp_pcb *pcb) { fsm *f = &pcb->lcp_fsm; if (f->flags & DELAYED_UP) { @@ -552,8 +548,7 @@ static void lcp_delayed_up(void *arg) { /* * lcp_input - Input LCP packet. */ -static void lcp_input(int unit, u_char *p, int len) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void lcp_input(ppp_pcb *pcb, u_char *p, int len) { fsm *f = &pcb->lcp_fsm; if (f->flags & DELAYED_UP) { @@ -657,7 +652,7 @@ lcp_rprotrej(f, inp, len) else #endif /* PPP_PROTOCOLNAME */ dbglog("Protocol-Reject for 0x%x received", prot); - (*protp->protrej)(f->unit); + (*protp->protrej)(f->pcb); return; } @@ -675,8 +670,7 @@ lcp_rprotrej(f, inp, len) * lcp_protrej - A Protocol-Reject was received. */ /*ARGSUSED*/ -static void lcp_protrej(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void lcp_protrej(ppp_pcb *pcb) { /* * Can't reject LCP! */ @@ -688,8 +682,7 @@ static void lcp_protrej(int unit) { /* * lcp_sprotrej - Send a Protocol-Reject for some protocol. */ -void lcp_sprotrej(int unit, u_char *p, int len) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len) { fsm *f = &pcb->lcp_fsm; /* * Send back the protocol and the information field of the @@ -1536,7 +1529,7 @@ lcp_nakci(f, p, len, treat_as_reject) if (++try.numloops >= lcp_loopbackfail) { notice("Serial line is looped back."); pcb->status = EXIT_LOOPBACK; - lcp_close(f->unit, "Loopback detected"); + lcp_close(f->pcb, "Loopback detected"); } } else try.numloops = 0; @@ -2296,7 +2289,7 @@ lcp_up(f) if (ho->neg_mru) peer_mru[f->unit] = ho->mru; - lcp_echo_lowerup(f->unit); /* Enable echo messages */ + lcp_echo_lowerup(f->pcb); /* Enable echo messages */ link_established(pcb); } @@ -2314,7 +2307,7 @@ lcp_down(f) ppp_pcb *pcb = &ppp_pcb_list[f->unit]; lcp_options *go = &pcb->lcp_gotoptions; - lcp_echo_lowerdown(f->unit); + lcp_echo_lowerdown(f->pcb); link_down(pcb); @@ -2613,7 +2606,7 @@ void LcpLinkFailure (f) info("No response to %d echo-requests", lcp_echos_pending); notice("Serial link appears to be disconnected."); pc->status = EXIT_PEER_DEAD; - lcp_close(f->unit, "Peer not responding"); + lcp_close(f->pcb, "Peer not responding"); } } @@ -2742,8 +2735,7 @@ LcpSendEchoRequest (f) * lcp_echo_lowerup - Start the timer for the LCP frame */ -static void lcp_echo_lowerup(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void lcp_echo_lowerup(ppp_pcb *pcb) { fsm *f = &pcb->lcp_fsm; /* Clear the parameters for generating echo frames */ @@ -2760,8 +2752,7 @@ static void lcp_echo_lowerup(int unit) { * lcp_echo_lowerdown - Stop the timer for the LCP frame */ -static void lcp_echo_lowerdown(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void lcp_echo_lowerdown(ppp_pcb *pcb) { fsm *f = &pcb->lcp_fsm; if (lcp_echo_timer_running != 0) { diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index 38350a53..4b815593 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -48,6 +48,8 @@ #ifndef LCP_H #define LCP_H +#include "ppp.h" + /* * Options. */ @@ -88,57 +90,6 @@ /* Value used as data for CI_CALLBACK option */ #define CBCP_OPT 6 /* Use callback control protocol */ -/* FIXME: moved temporarily from ppp.h */ -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class; - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; - -/* - * 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? */ -#if PAP_SUPPORT - bool neg_upap; /* Ask for UPAP authentication? */ -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - bool neg_chap; /* Ask for CHAP authentication? */ -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - bool neg_eap; /* Ask for EAP authentication? */ -#endif /* EAP_SUPPORT */ - bool neg_magicnumber; /* Ask for magic number? */ - bool neg_pcompression; /* HDLC Protocol Field Compression? */ - bool neg_accompression; /* HDLC Address/Control Field Compression? */ -#if LQR_SUPPORT - bool neg_lqr; /* Negotiate use of Link Quality Reports */ -#endif /* LQR_SUPPORT */ - bool neg_cbcp; /* Negotiate use of CBCP */ - bool neg_mrru; /* negotiate multilink MRRU */ - bool neg_ssnhf; /* negotiate short sequence numbers */ - bool neg_endpoint; /* negotiate endpoint discriminator */ - int mru; /* Value of MRU */ - int mrru; /* Value of MRRU, and multilink enable */ -#if CHAP_SUPPORT - u_char chap_mdtype; /* which MD types (hashing algorithm) */ -#endif /* CHAP_SUPPORT */ - u_int32_t asyncmap; /* Value of async map */ - u_int32_t magicnumber; - int numloops; /* Number of loops during magic number neg. */ -#if LQR_SUPPORT - u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ -#endif /* LQR_SUPPORT */ - struct epdisc endpoint; /* endpoint discriminator */ -} lcp_options; - #if PPPOS_SUPPORT extern ext_accm xmit_accm[]; #endif /* #if PPPOS_SUPPORT */ @@ -147,11 +98,11 @@ extern ext_accm xmit_accm[]; #define MINMRU 128 /* No MRUs below this */ #define MAXMRU 16384 /* Normally limit MRU to this */ -void lcp_open(int unit); -void lcp_close(int unit, char *reason); -void lcp_lowerup(int unit); -void lcp_lowerdown(int unit); -void lcp_sprotrej(int unit, u_char *p, int len); /* send protocol reject */ +void lcp_open(ppp_pcb *pcb); +void lcp_close(ppp_pcb *pcb, char *reason); +void lcp_lowerup(ppp_pcb *pcb); +void lcp_lowerdown(ppp_pcb *pcb); +void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len); /* send protocol reject */ extern struct protent lcp_protent; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 004d0021..8369e8cc 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -267,7 +267,7 @@ ppp_pcb *ppp_new(void) { * Initialize each protocol. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) - (*protp->init)(pd); + (*protp->init)(pcb); return pcb; } @@ -475,21 +475,21 @@ ppp_sighup(ppp_pcb *pcb) /** Initiate LCP open request */ static void ppp_start(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->unit)); - lcp_open(pcb->unit); /* Start protocol */ - lcp_lowerup(pcb->unit); + lcp_open(pcb); /* Start protocol */ + lcp_lowerup(pcb); PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); } /** LCP close request */ static void ppp_stop(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_stop: unit %d\n", pcb->unit)); - lcp_close(pcb->unit, "User request"); + lcp_close(pcb, "User request"); } /** Called when carrier/link is lost */ static void ppp_hup(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_hup: unit %d\n", pcb->unit)); - lcp_lowerdown(pcb->unit); + lcp_lowerdown(pcb); link_terminated(pcb); } @@ -599,7 +599,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { pb = ppp_singlebuf(pb); - (*protp->input)(pcb->unit, pb->payload, pb->len); + (*protp->input)(pcb, pb->payload, pb->len); goto out; } #if 0 /* UNUSED @@ -632,7 +632,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } - lcp_sprotrej(pcb->unit, pb->payload, pb->len); + lcp_sprotrej(pcb, pb->payload, pb->len); } break; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 54a339a2..0b49b9fb 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -89,7 +89,6 @@ typedef unsigned char bool; #endif #include "fsm.h" -#include "lcp.h" #include "ipcp.h" @@ -227,12 +226,61 @@ typedef struct ppp_pcb_rx_s { } ppp_pcb_rx; #endif /* PPPOS_SUPPORT */ +/* An endpoint discriminator, used with multilink. */ +#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ +struct epdisc { + unsigned char class; + unsigned char length; + unsigned char value[MAX_ENDP_LEN]; +}; + +/* + * 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? */ +#if PAP_SUPPORT + bool neg_upap; /* Ask for UPAP authentication? */ +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + bool neg_chap; /* Ask for CHAP authentication? */ +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + bool neg_eap; /* Ask for EAP authentication? */ +#endif /* EAP_SUPPORT */ + bool neg_magicnumber; /* Ask for magic number? */ + bool neg_pcompression; /* HDLC Protocol Field Compression? */ + bool neg_accompression; /* HDLC Address/Control Field Compression? */ +#if LQR_SUPPORT + bool neg_lqr; /* Negotiate use of Link Quality Reports */ +#endif /* LQR_SUPPORT */ + bool neg_cbcp; /* Negotiate use of CBCP */ + bool neg_mrru; /* negotiate multilink MRRU */ + bool neg_ssnhf; /* negotiate short sequence numbers */ + bool neg_endpoint; /* negotiate endpoint discriminator */ + int mru; /* Value of MRU */ + int mrru; /* Value of MRRU, and multilink enable */ +#if CHAP_SUPPORT + u_char chap_mdtype; /* which MD types (hashing algorithm) */ +#endif /* CHAP_SUPPORT */ + u_int32_t asyncmap; /* Value of async map */ + u_int32_t magicnumber; + int numloops; /* Number of loops during magic number neg. */ +#if LQR_SUPPORT + u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ +#endif /* LQR_SUPPORT */ + struct epdisc endpoint; /* endpoint discriminator */ +} lcp_options; + /* * Each interface is described by upap structure. */ #if PAP_SUPPORT typedef struct upap_state { - int us_unit; /* Interface unit number */ char *us_user; /* User */ int us_userlen; /* User length */ char *us_passwd; /* Password */ @@ -314,7 +362,6 @@ struct eap_auth { #define EAP_MAX_CHALLENGE_LENGTH 24 #endif typedef struct eap_state { - int es_unit; /* Interface unit number */ struct eap_auth es_client; /* Client (authenticatee) data */ #if PPP_SERVER struct eap_auth es_server; /* Server (authenticator) data */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 1358cfb7..fa6cf119 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -221,7 +221,7 @@ struct ppp_idle { }; /* FIXME: make endpoint discriminator optional */ -/* FIXME: moved temporarily to lcp.h */ +/* FIXME: moved temporarily to ppp.h */ /* values for epdisc.class */ #define EPD_NULL 0 /* null discriminator, no data */ @@ -269,19 +269,19 @@ extern int maxoctets_timeout; /* Timeout for check of octets limit */ struct protent { u_short protocol; /* PPP protocol number */ /* Initialization procedure */ - void (*init) (int unit); + void (*init) (ppp_pcb *pcb); /* Process a received packet */ - void (*input) (int unit, u_char *pkt, int len); + void (*input) (ppp_pcb *pcb, u_char *pkt, int len); /* Process a received protocol-reject */ - void (*protrej) (int unit); + void (*protrej) (ppp_pcb *pcb); /* Lower layer has come up */ - void (*lowerup) (int unit); + void (*lowerup) (ppp_pcb *pcb); /* Lower layer has gone down */ - void (*lowerdown) (int unit); + void (*lowerdown) (ppp_pcb *pcb); /* Open the protocol */ - void (*open) (int unit); + void (*open) (ppp_pcb *pcb); /* Close the protocol */ - void (*close) (int unit, char *reason); + void (*close) (ppp_pcb *pcb, char *reason); #if PRINTPKT_SUPPORT /* Print a packet in readable form */ int (*printpkt) (u_char *pkt, int len, @@ -292,7 +292,7 @@ struct protent { * should we remove this entry and save some flash ? */ /* Process a received data packet */ - void (*datainput) (int unit, u_char *pkt, int len); + void (*datainput) (ppp_pcb *pcb, u_char *pkt, int len); bool enabled_flag; /* 0 if protocol is disabled */ #if PRINTPKT_SUPPORT char *name; /* Text name of protocol */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index f498044f..400e8d27 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -80,11 +80,11 @@ static option_t pap_option_list[] = { /* * Protocol entry points. */ -static void upap_init(int unit); -static void upap_lowerup(int unit); -static void upap_lowerdown(int unit); -static void upap_input(int unit, u_char *inpacket, int l); -static void upap_protrej(int unit); +static void upap_init(ppp_pcb *pcb); +static void upap_lowerup(ppp_pcb *pcb); +static void upap_lowerdown(ppp_pcb *pcb); +static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l); +static void upap_protrej(ppp_pcb *pcb); #if PRINTPKT_SUPPORT static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ @@ -135,10 +135,7 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl /* * upap_init - Initialize a UPAP unit. */ -static void upap_init(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; - - pcb->upap.us_unit = unit; +static void upap_init(ppp_pcb *pcb) { pcb->upap.us_user = NULL; pcb->upap.us_userlen = 0; pcb->upap.us_passwd = NULL; @@ -240,8 +237,7 @@ static void upap_reqtimeout(void *arg) { * * Start authenticating if pending. */ -static void upap_lowerup(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void upap_lowerup(ppp_pcb *pcb) { if (pcb->upap.us_clientstate == UPAPCS_INITIAL) pcb->upap.us_clientstate = UPAPCS_CLOSED; @@ -266,8 +262,7 @@ static void upap_lowerup(int unit) { * * Cancel all timeouts. */ -static void upap_lowerdown(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void upap_lowerdown(ppp_pcb *pcb) { if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */ @@ -288,8 +283,7 @@ static void upap_lowerdown(int unit) { * * This shouldn't happen. In any case, pretend lower layer went down. */ -static void upap_protrej(int unit) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void upap_protrej(ppp_pcb *pcb) { if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) { error("PAP authentication failed due to protocol-reject"); @@ -301,15 +295,14 @@ static void upap_protrej(int unit) { auth_peer_fail(pcb, PPP_PAP); } #endif /* PPP_SERVER */ - upap_lowerdown(unit); + upap_lowerdown(pcb); } /* * upap_input - Input UPAP packet. */ -static void upap_input(int unit, u_char *inpacket, int l) { - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) { u_char *inp; u_char code, id; int len; From f10ddea305eeffc5ea4954f54f9a20b15437759d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 03:14:26 +0200 Subject: [PATCH 167/320] removed fsm->unit --- src/netif/ppp/fsm.c | 132 ++++++++------------------------ src/netif/ppp/fsm.h | 19 +++-- src/netif/ppp/ipcp.c | 27 ++++--- src/netif/ppp/lcp.c | 174 ++++++++++++++----------------------------- 4 files changed, 106 insertions(+), 246 deletions(-) diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 856ccfcd..84d7ccaf 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -60,13 +60,13 @@ #include "fsm.h" static void fsm_timeout (void *); -static void fsm_rconfreq (fsm *, int, 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); +static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len); +static void fsm_rconfack(fsm *f, int id, u_char *inp, int len); +static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len); +static void fsm_rtermreq(fsm *f, int id, u_char *p, int len); +static void fsm_rtermack(fsm *f); +static void fsm_rcoderej(fsm *f, u_char *inp, int len); +static void fsm_sconfreq(fsm *f, int retransmit); #define PROTO_NAME(f) ((f)->callbacks->proto_name) @@ -78,10 +78,7 @@ int peer_mru[NUM_PPP]; * * Initialize fsm state. */ -void -fsm_init(f) - fsm *f; -{ +void fsm_init(fsm *f) { f->state = INITIAL; f->flags = 0; f->id = 0; /* XXX Start with random id? */ @@ -96,10 +93,7 @@ fsm_init(f) /* * fsm_lowerup - The lower layer is up. */ -void -fsm_lowerup(f) - fsm *f; -{ +void fsm_lowerup(fsm *f) { switch( f->state ){ case INITIAL: f->state = CLOSED; @@ -127,10 +121,7 @@ fsm_lowerup(f) * * Cancel all timeouts and inform upper layers. */ -void -fsm_lowerdown(f) - fsm *f; -{ +void fsm_lowerdown(fsm *f) { switch( f->state ){ case CLOSED: f->state = INITIAL; @@ -171,10 +162,7 @@ fsm_lowerdown(f) /* * fsm_open - Link is allowed to come up. */ -void -fsm_open(f) - fsm *f; -{ +void fsm_open(fsm *f) { switch( f->state ){ case INITIAL: f->state = STARTING; @@ -212,11 +200,7 @@ fsm_open(f) * Cancel any timeout running, notify upper layers we're done, and * send a terminate-request message as configured. */ -static void -terminate_layer(f, nextstate) - fsm *f; - int nextstate; -{ +static void terminate_layer(fsm *f, int nextstate) { if( f->state != OPENED ) UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ else if( f->callbacks->down ) @@ -251,11 +235,7 @@ terminate_layer(f, nextstate) * Cancel timeouts and either initiate close or possibly go directly to * the CLOSED state. */ -void -fsm_close(f, reason) - fsm *f; - char *reason; -{ +void fsm_close(fsm *f, char *reason) { f->term_reason = reason; f->term_reason_len = (reason == NULL? 0: strlen(reason)); switch( f->state ){ @@ -282,10 +262,7 @@ fsm_close(f, reason) /* * fsm_timeout - Timeout expired. */ -static void -fsm_timeout(arg) - void *arg; -{ +static void fsm_timeout(void *arg) { fsm *f = (fsm *) arg; switch (f->state) { @@ -336,12 +313,7 @@ fsm_timeout(arg) /* * fsm_input - Input packet. */ -void -fsm_input(f, inpacket, l) - fsm *f; - u_char *inpacket; - int l; -{ +void fsm_input(fsm *f, u_char *inpacket, int l) { u_char *inp; u_char code, id; int len; @@ -415,13 +387,7 @@ fsm_input(f, inpacket, l) /* * fsm_rconfreq - Receive Configure-Request. */ -static void -fsm_rconfreq(f, id, inp, len) - fsm *f; - u_char id; - u_char *inp; - int len; -{ +static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) { int code, reject_if_disagree; switch( f->state ){ @@ -486,13 +452,7 @@ fsm_rconfreq(f, id, inp, len) /* * fsm_rconfack - Receive Configure-Ack. */ -static void -fsm_rconfack(f, id, inp, len) - fsm *f; - int id; - u_char *inp; - int len; -{ +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): @@ -544,13 +504,7 @@ fsm_rconfack(f, id, inp, len) /* * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. */ -static void -fsm_rconfnakrej(f, code, id, inp, len) - fsm *f; - int code, id; - u_char *inp; - int len; -{ +static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { int ret; int treat_as_reject; @@ -613,13 +567,7 @@ fsm_rconfnakrej(f, code, id, inp, len) /* * fsm_rtermreq - Receive Terminate-Req. */ -static void -fsm_rtermreq(f, id, p, len) - fsm *f; - int id; - u_char *p; - int len; -{ +static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { switch (f->state) { case ACKRCVD: case ACKSENT: @@ -646,10 +594,7 @@ fsm_rtermreq(f, id, p, len) /* * fsm_rtermack - Receive Terminate-Ack. */ -static void -fsm_rtermack(f) - fsm *f; -{ +static void fsm_rtermack(fsm *f) { switch (f->state) { case CLOSING: UNTIMEOUT(fsm_timeout, f); @@ -681,12 +626,7 @@ fsm_rtermack(f) /* * fsm_rcoderej - Receive an Code-Reject. */ -static void -fsm_rcoderej(f, inp, len) - fsm *f; - u_char *inp; - int len; -{ +static void fsm_rcoderej(fsm *f, u_char *inp, int len) { u_char code, id; if (len < HEADERLEN) { @@ -707,10 +647,7 @@ fsm_rcoderej(f, inp, len) * * Treat this as a catastrophic error (RXJ-). */ -void -fsm_protreject(f) - fsm *f; -{ +void fsm_protreject(fsm *f) { switch( f->state ){ case CLOSING: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ @@ -750,11 +687,8 @@ fsm_protreject(f) /* * fsm_sconfreq - Send a Configure-Request. */ -static void -fsm_sconfreq(f, retransmit) - fsm *f; - int retransmit; -{ +static void fsm_sconfreq(fsm *f, int retransmit) { + ppp_pcb *pcb = f->pcb; u_char *outp; int cilen; @@ -780,8 +714,8 @@ fsm_sconfreq(f, retransmit) 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( cilen > peer_mru[pcb->unit] - HEADERLEN ) + cilen = peer_mru[pcb->unit] - HEADERLEN; if (f->callbacks->addci) (*f->callbacks->addci)(f, outp, &cilen); } else @@ -801,21 +735,15 @@ fsm_sconfreq(f, retransmit) * * Used for all packets sent to our peer by this module. */ -void -fsm_sdata(f, code, id, data, datalen) - fsm *f; - u_char code, id; - u_char *data; - int datalen; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { + ppp_pcb *pcb = f->pcb; 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 > peer_mru[pcb->unit] - HEADERLEN) + datalen = peer_mru[pcb->unit] - HEADERLEN; if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen); outlen = datalen + HEADERLEN; diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index d1b0d970..217521fc 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -70,8 +70,7 @@ * Each FSM is described by an fsm structure and fsm callbacks. */ typedef struct fsm { - int unit; /* Interface unit number */ - void *pcb; /* FIXME: Temporary */ + void *pcb; /* PPP Interface */ /* FIXME: try to use ppp_pcb here */ int protocol; /* Data Link Layer Protocol field value */ int state; /* State */ int flags; /* Contains option bits */ @@ -159,14 +158,14 @@ typedef struct fsm_callbacks { /* * 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 *, int, int, u_char *, int); +void fsm_init(fsm *f); +void fsm_lowerup(fsm *f); +void fsm_lowerdown(fsm *f); +void fsm_open(fsm *f); +void fsm_close(fsm *f, char *reason); +void fsm_input(fsm *f, u_char *inpacket, int l); +void fsm_protreject(fsm *f); +void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen); /* diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index cc2cedfd..ec67e5c1 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -590,7 +590,6 @@ static void ipcp_init(ppp_pcb *pcb) { ipcp_options *wo = &pcb->ipcp_wantoptions; ipcp_options *ao = &pcb->ipcp_allowoptions; - f->unit = pcb->unit; f->pcb = (void*)pcb; f->protocol = PPP_IPCP; f->callbacks = &ipcp_callbacks; @@ -697,7 +696,7 @@ static void ipcp_protrej(ppp_pcb *pcb) { * Called by fsm_sconfreq, Send Configure Request. */ static void ipcp_resetci(fsm *f) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; ipcp_options *wo = &pcb->ipcp_wantoptions; ipcp_options *go = &pcb->ipcp_gotoptions; ipcp_options *ao = &pcb->ipcp_allowoptions; @@ -730,7 +729,7 @@ static void ipcp_resetci(fsm *f) { * Called by fsm_sconfreq, Send Configure Request. */ static int ipcp_cilen(fsm *f) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; ipcp_options *go = &pcb->ipcp_gotoptions; ipcp_options *wo = &pcb->ipcp_wantoptions; ipcp_options *ho = &pcb->ipcp_hisoptions; @@ -772,7 +771,7 @@ static int ipcp_cilen(fsm *f) { * Called by fsm_sconfreq, Send Configure Request. */ static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; ipcp_options *go = &pcb->ipcp_gotoptions; int len = *lenp; @@ -875,7 +874,7 @@ static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { * 1 - Ack was good. */ static int ipcp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; ipcp_options *go = &pcb->ipcp_gotoptions; u_short cilen, citype, cishort; u_int32_t cilong; @@ -996,7 +995,7 @@ bad: * 1 - Nak was good. */ static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; ipcp_options *go = &pcb->ipcp_gotoptions; u_char cimaxslotindex, cicflag; u_char citype, cilen, *next; @@ -1240,7 +1239,7 @@ bad: * Callback from fsm_rconfnakrej. */ static int ipcp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; ipcp_options *go = &pcb->ipcp_gotoptions; u_char cimaxslotindex, ciflag, cilen; u_short cishort; @@ -1390,7 +1389,7 @@ bad: * len = Length of requested CIs */ static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; ipcp_options *wo = &pcb->ipcp_wantoptions; ipcp_options *ho = &pcb->ipcp_hisoptions; ipcp_options *ao = &pcb->ipcp_allowoptions; @@ -1753,7 +1752,7 @@ ip_demand_conf(u) * Configure the IP network interface appropriately and bring it up. */ static void ipcp_up(fsm *f) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; u_int32_t mask; ipcp_options *ho = &pcb->ipcp_hisoptions; ipcp_options *go = &pcb->ipcp_gotoptions; @@ -1912,12 +1911,12 @@ static void ipcp_up(fsm *f) { if (wo->default_route) if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, wo->replace_default_route)) - default_route_set[f->unit] = 1; + default_route_set[pcb->unit] = 1; /* Make a proxy ARP entry if requested. */ if (ho->hisaddr != 0 && wo->proxy_arp) if (sifproxyarp(pcb, ho->hisaddr)) - proxy_arp_set[f->unit] = 1; + proxy_arp_set[pcb->unit] = 1; wo->ouraddr = go->ouraddr; @@ -1954,7 +1953,7 @@ static void ipcp_up(fsm *f) { * and delete routes through it. */ static void ipcp_down(fsm *f) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; ipcp_options *ho = &pcb->ipcp_hisoptions; ipcp_options *go = &pcb->ipcp_gotoptions; @@ -1997,7 +1996,7 @@ static void ipcp_down(fsm *f) { { sifnpmode(pcb, PPP_IP, NPMODE_DROP); sifdown(pcb); - ipcp_clear_addrs(f->unit, go->ouraddr, + ipcp_clear_addrs(pcb->unit, go->ouraddr, ho->hisaddr, 0); cdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); } @@ -2036,7 +2035,7 @@ static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, boo * ipcp_finished - possibly shut down the lower layers. */ static void ipcp_finished(fsm *f) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; if (ipcp_is_open) { ipcp_is_open = 0; np_finished(pcb, PPP_IP); diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 2c833a0e..e30af511 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -223,19 +223,19 @@ 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, 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_resetci(fsm *f); /* Reset our CI */ +static int lcp_cilen(fsm *f); /* Return length of our CI */ +static void lcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI to pkt */ +static int lcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ +static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */ +static int lcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ +static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree); /* Rcv peer CI */ +static void lcp_up(fsm *f); /* We're UP */ +static void lcp_down(fsm *f); /* 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); +static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len); +static void lcp_rprotrej(fsm *f, u_char *inp, int len); /* * routines to send LCP echos to peer @@ -243,11 +243,11 @@ static void lcp_rprotrej (fsm *, u_char *, int); static void lcp_echo_lowerup(ppp_pcb *pcb); static void lcp_echo_lowerdown(ppp_pcb *pcb); -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 void LcpEchoTimeout(void *arg); +static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len); +static void LcpSendEchoRequest(fsm *f); +static void LcpLinkFailure(fsm *f); +static void LcpEchoCheck(fsm *f); static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ lcp_resetci, /* Reset our Configuration Information */ @@ -374,7 +374,6 @@ static void lcp_init(ppp_pcb *pcb) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; - f->unit = pcb->unit; f->pcb = (void*)pcb; f->protocol = PPP_LCP; f->callbacks = &lcp_callbacks; @@ -499,7 +498,7 @@ void lcp_lowerup(ppp_pcb *pcb) { peer_mru[pcb->unit] = PPP_MRU; #if PPPOS_SUPPORT - ao->asyncmap = (u_long)xmit_accm[f->unit][0] + ao->asyncmap = (u_long)xmit_accm[pcb->unit][0] | ((u_long)xmit_accm[pcb->unit][1] << 8) | ((u_long)xmit_accm[pcb->unit][2] << 16) | ((u_long)xmit_accm[pcb->unit][3] << 24); @@ -562,14 +561,8 @@ static void lcp_input(ppp_pcb *pcb, u_char *p, int len) { /* * lcp_extcode - Handle a LCP-specific code. */ -static int -lcp_extcode(f, code, id, inp, len) - fsm *f; - int code, id; - u_char *inp; - int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; u_char *magp; @@ -607,12 +600,7 @@ lcp_extcode(f, code, id, inp, len) * * Figure out which protocol is rejected and inform it. */ -static void -lcp_rprotrej(f, inp, len) - fsm *f; - u_char *inp; - int len; -{ +static void lcp_rprotrej(fsm *f, u_char *inp, int len) { int i; struct protent *protp; u_short prot; @@ -699,11 +687,8 @@ void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len) { /* * lcp_resetci - Reset our CI. */ -static void -lcp_resetci(f) - fsm *f; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static void lcp_resetci(fsm *f) { + ppp_pcb *pcb = f->pcb; lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *go = &pcb->lcp_gotoptions; lcp_options *ao = &pcb->lcp_allowoptions; @@ -722,7 +707,7 @@ lcp_resetci(f) #endif /* HAVE_MULTILINK */ if (noendpoint) ao->neg_endpoint = 0; - peer_mru[f->unit] = PPP_MRU; + peer_mru[pcb->unit] = PPP_MRU; auth_reset(pcb); } @@ -730,11 +715,8 @@ lcp_resetci(f) /* * lcp_cilen - Return length of our CI. */ -static int -lcp_cilen(f) - fsm *f; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static int lcp_cilen(fsm *f) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) @@ -795,13 +777,8 @@ lcp_cilen(f) /* * lcp_addci - Add our desired CIs to a packet. */ -static void -lcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static void lcp_addci(fsm *f, u_char *ucp, int *lenp) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; u_char *start_ucp = ucp; @@ -911,13 +888,8 @@ lcp_addci(f, ucp, lenp) * 0 - Ack was bad. * 1 - Ack was good. */ -static int -lcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static int lcp_ackci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; u_char cilen, citype, cichar; u_short cishort; @@ -1094,14 +1066,8 @@ bad: * 0 - Nak was bad. * 1 - Nak was good. */ -static int -lcp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; lcp_options *wo = &pcb->lcp_wantoptions; u_char citype, cichar, *next; @@ -1553,13 +1519,8 @@ bad: * 0 - Reject was bad. * 1 - Reject was good. */ -static int -lcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static int lcp_rejci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; u_char cichar; u_short cishort; @@ -1783,15 +1744,12 @@ bad: * 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. + * + * inp = Requested CIs + * lenp = Length of requested CIs */ -static int -lcp_reqci(f, inp, lenp, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *lenp; /* Length of requested CIs */ - int reject_if_disagree; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; lcp_options *ho = &pcb->lcp_hisoptions; lcp_options *ao = &pcb->lcp_allowoptions; @@ -2248,11 +2206,8 @@ endswitch: /* * lcp_up - LCP has come UP. */ -static void -lcp_up(f) - fsm *f; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static void lcp_up(fsm *f) { + ppp_pcb *pcb = f->pcb; lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ho = &pcb->lcp_hisoptions; lcp_options *go = &pcb->lcp_gotoptions; @@ -2287,7 +2242,7 @@ lcp_up(f) go->neg_pcompression, go->neg_accompression); if (ho->neg_mru) - peer_mru[f->unit] = ho->mru; + peer_mru[pcb->unit] = ho->mru; lcp_echo_lowerup(f->pcb); /* Enable echo messages */ @@ -2300,11 +2255,8 @@ lcp_up(f) * * Alert other protocols. */ -static void -lcp_down(f) - fsm *f; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static void lcp_down(fsm *f) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; lcp_echo_lowerdown(f->pcb); @@ -2315,7 +2267,7 @@ lcp_down(f) ppp_recv_config(pcb, PPP_MRU, (go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); - peer_mru[f->unit] = PPP_MRU; + peer_mru[pcb->unit] = PPP_MRU; } @@ -2323,7 +2275,7 @@ lcp_down(f) * lcp_starting - LCP needs the lower layer up. */ static void lcp_starting(fsm *f) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; link_required(pcb); } @@ -2332,7 +2284,7 @@ static void lcp_starting(fsm *f) { * lcp_finished - LCP has finished with the lower layer. */ static void lcp_finished(fsm *f) { - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + ppp_pcb *pcb = f->pcb; link_terminated(pcb); } @@ -2597,11 +2549,8 @@ static int lcp_printpkt(u_char *p, int plen, * Time to shut down the link because there is nothing out there. */ -static -void LcpLinkFailure (f) - fsm *f; -{ - ppp_pcb *pc = &ppp_pcb_list[f->unit]; +static void LcpLinkFailure(fsm *f) { + ppp_pcb *pc = f->pcb; if (f->state == OPENED) { info("No response to %d echo-requests", lcp_echos_pending); notice("Serial link appears to be disconnected."); @@ -2614,10 +2563,7 @@ void LcpLinkFailure (f) * Timer expired for the LCP echo requests from this process. */ -static void -LcpEchoCheck (f) - fsm *f; -{ +static void LcpEchoCheck(fsm *f) { LcpSendEchoRequest (f); if (f->state != OPENED) return; @@ -2635,10 +2581,7 @@ LcpEchoCheck (f) * LcpEchoTimeout - Timer expired on the LCP echo */ -static void -LcpEchoTimeout (arg) - void *arg; -{ +static void LcpEchoTimeout(void *arg) { if (lcp_echo_timer_running != 0) { lcp_echo_timer_running = 0; LcpEchoCheck ((fsm *) arg); @@ -2649,14 +2592,8 @@ LcpEchoTimeout (arg) * LcpEchoReply - LCP has received a reply to the echo */ -static void -lcp_received_echo_reply (f, id, inp, len) - fsm *f; - int id; - u_char *inp; - int len; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; u_int32_t magic; @@ -2680,11 +2617,8 @@ lcp_received_echo_reply (f, id, inp, len) * LcpSendEchoRequest - Send an echo request frame to the peer */ -static void -LcpSendEchoRequest (f) - fsm *f; -{ - ppp_pcb *pcb = &ppp_pcb_list[f->unit]; +static void LcpSendEchoRequest(fsm *f) { + ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; u_int32_t lcp_magic; u_char pkt[4], *pktp; From 93559a54e95d19c891e4fa37b3e998a03327126a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 03:25:31 +0200 Subject: [PATCH 168/320] IPCP global variables moved to ppp_pcb --- src/netif/ppp/ipcp.c | 39 +++++++++++++++++++++++---------------- src/netif/ppp/ppp.h | 6 ++++++ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index ec67e5c1..a5aa6f39 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -64,13 +64,18 @@ #include "fsm.h" #include "ipcp.h" +#if 0 /* UNUSED */ /* global vars */ u_int32_t netmask = 0; /* IP netmask to set on interface */ +#endif /* UNUSED */ #if 0 /* UNUSED */ bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ #endif /* UNUSED */ + +#if 0 /* moved to ppp_settings */ bool noremoteip = 0; /* Let him have no IP address */ +#endif /* moved to ppp_setting */ #if 0 /* UNUSED */ /* Hook for a plugin to know when IP protocol has come up */ @@ -90,11 +95,13 @@ struct notifier *ip_down_notifier = NULL; #endif /* PPP_NOTIFY */ /* local vars */ +#if 0 /* moved to ppp_pcb */ 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 int ipcp_is_up; /* have called np_up() */ static int ipcp_is_open; /* haven't called np_finished() */ static bool ask_for_local; /* request our address from peer */ +#endif /* moved to ppp_pcb */ #if 0 /* UNUSED */ static char vj_value[8]; /* string form of vj option value */ static char netmask_str[20]; /* string form of netmask value */ @@ -640,7 +647,7 @@ static void ipcp_init(ppp_pcb *pcb) { static void ipcp_open(ppp_pcb *pcb) { fsm *f = &pcb->ipcp_fsm; fsm_open(f); - ipcp_is_open = 1; + pcb->ipcp_is_open = 1; } @@ -710,7 +717,7 @@ static void ipcp_resetci(fsm *f) { wo->req_dns1 = pcb->settings.usepeerdns; /* Request DNS addresses from the peer */ wo->req_dns2 = pcb->settings.usepeerdns; *go = *wo; - if (!ask_for_local) + if (!pcb->ask_for_local) go->ouraddr = 0; #if 0 /* UNUSED */ if (ip_choose_hook) { @@ -1650,7 +1657,7 @@ endswitch: * option safely. */ if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs && - wo->req_addr && !reject_if_disagree && !noremoteip) { + wo->req_addr && !reject_if_disagree && !pcb->settings.noremoteip) { if (rc == CONFACK) { rc = CONFNAK; ucp = inp; /* reset pointer */ @@ -1713,7 +1720,7 @@ ip_demand_conf(u) ppp_pcb *pcb = &ppp_pcb_list[u]; ipcp_options *wo = &ipcp_wantoptions[u]; - if (wo->hisaddr == 0 && !noremoteip) { + if (wo->hisaddr == 0 && !pcb->settings.noremoteip) { /* make up an arbitrary address for the peer */ wo->hisaddr = htonl(0x0a707070 + ifunit); wo->accept_remote = 1; @@ -1777,7 +1784,7 @@ static void ipcp_up(fsm *f) { ipcp_close(f->pcb, "Could not determine local IP address"); return; } - if (ho->hisaddr == 0 && !noremoteip) { + if (ho->hisaddr == 0 && !pcb->settings.noremoteip) { ho->hisaddr = htonl(0x0a404040); warn("Could not determine remote IP address: defaulting to %I", ho->hisaddr); @@ -1911,12 +1918,12 @@ static void ipcp_up(fsm *f) { if (wo->default_route) if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, wo->replace_default_route)) - default_route_set[pcb->unit] = 1; + pcb->default_route_set = 1; /* Make a proxy ARP entry if requested. */ if (ho->hisaddr != 0 && wo->proxy_arp) if (sifproxyarp(pcb, ho->hisaddr)) - proxy_arp_set[pcb->unit] = 1; + pcb->proxy_arp_set = 1; wo->ouraddr = go->ouraddr; @@ -1934,7 +1941,7 @@ static void ipcp_up(fsm *f) { #endif /* PPP_STATS_SUPPORT */ np_up(pcb, PPP_IP); - ipcp_is_up = 1; + pcb->ipcp_is_up = 1; #if PPP_NOTIFY notify(ip_up_notifier, 0); @@ -1972,8 +1979,8 @@ static void ipcp_down(fsm *f) { if (ip_down_hook) ip_down_hook(); #endif /* UNUSED */ - if (ipcp_is_up) { - ipcp_is_up = 0; + if (pcb->ipcp_is_up) { + pcb->ipcp_is_up = 0; np_down(pcb, PPP_IP); } sifvjcomp(pcb, 0, 0, 0); @@ -2011,9 +2018,9 @@ static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, boo ppp_pcb *pcb = &ppp_pcb_list[unit]; - if (proxy_arp_set[unit]) { + if (pcb->proxy_arp_set) { cifproxyarp(pcb, hisaddr); - proxy_arp_set[unit] = 0; + pcb->proxy_arp_set = 0; } /* If replacedefaultroute, sifdefaultroute will be called soon * with replacedefaultroute set and that will overwrite the current @@ -2023,9 +2030,9 @@ static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, boo * case, we'll delete the default route and restore the old if there * is one saved by an sifdefaultroute with replacedefaultroute. */ - if (!replacedefaultroute && default_route_set[unit]) { + if (!replacedefaultroute && pcb->default_route_set) { cifdefaultroute(pcb, ouraddr, hisaddr); - default_route_set[unit] = 0; + pcb->default_route_set = 0; } cifaddr(pcb, ouraddr, hisaddr); } @@ -2036,8 +2043,8 @@ static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, boo */ static void ipcp_finished(fsm *f) { ppp_pcb *pcb = f->pcb; - if (ipcp_is_open) { - ipcp_is_open = 0; + if (pcb->ipcp_is_open) { + pcb->ipcp_is_open = 0; np_finished(pcb, PPP_IP); } } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 0b49b9fb..752f0c30 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -156,6 +156,7 @@ typedef struct ppp_settings_s { #if PRINTPKT_SUPPORT u_int hide_password : 1; /* Hide password in dumped packets */ #endif /* PRINTPKT_SUPPORT */ + u_int noremoteip : 1; u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ @@ -453,6 +454,11 @@ typedef struct ppp_pcb_s { ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ ipcp_options ipcp_hisoptions; /* Options that we ack'd */ + int default_route_set; /* Have set up a default route */ + int proxy_arp_set; /* Have created proxy arp entry */ + int ipcp_is_open; /* haven't called np_finished() */ + int ipcp_is_up; /* have called np_up() */ + bool ask_for_local; /* request our address from peer */ } ppp_pcb; From 708147625f1bb9008722dfc12bd2ef7a612f5490 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 03:30:36 +0200 Subject: [PATCH 169/320] FSM global variables moved to ppp_pcb --- src/netif/ppp/fsm.c | 11 ++++------- src/netif/ppp/fsm.h | 5 ----- src/netif/ppp/lcp.c | 8 ++++---- src/netif/ppp/ppp.h | 2 ++ 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 84d7ccaf..b022e312 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -70,9 +70,6 @@ static void fsm_sconfreq(fsm *f, int retransmit); #define PROTO_NAME(f) ((f)->callbacks->proto_name) -int peer_mru[NUM_PPP]; - - /* * fsm_init - Initialize fsm. * @@ -714,8 +711,8 @@ static void fsm_sconfreq(fsm *f, int retransmit) { outp = outpacket_buf + PPP_HDRLEN + HEADERLEN; if( f->callbacks->cilen && f->callbacks->addci ){ cilen = (*f->callbacks->cilen)(f); - if( cilen > peer_mru[pcb->unit] - HEADERLEN ) - cilen = peer_mru[pcb->unit] - HEADERLEN; + if( cilen > pcb->peer_mru - HEADERLEN ) + cilen = pcb->peer_mru - HEADERLEN; if (f->callbacks->addci) (*f->callbacks->addci)(f, outp, &cilen); } else @@ -742,8 +739,8 @@ void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { /* Adjust length to be smaller than MTU */ outp = outpacket_buf; - if (datalen > peer_mru[pcb->unit] - HEADERLEN) - datalen = peer_mru[pcb->unit] - HEADERLEN; + if (datalen > pcb->peer_mru - HEADERLEN) + datalen = pcb->peer_mru - HEADERLEN; if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen); outlen = datalen + HEADERLEN; diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index 217521fc..d02301ab 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -168,10 +168,5 @@ void fsm_protreject(fsm *f); void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen); -/* - * Variables - */ -extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ - #endif /* FSM_H */ #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index e30af511..c46ee2bb 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -495,7 +495,7 @@ void lcp_lowerup(ppp_pcb *pcb) { || ppp_recv_config(pcb, PPP_MRU, (lax_recv? 0: 0xffffffff), wo->neg_pcompression, wo->neg_accompression) < 0) return; - peer_mru[pcb->unit] = PPP_MRU; + pcb->peer_mru = PPP_MRU; #if PPPOS_SUPPORT ao->asyncmap = (u_long)xmit_accm[pcb->unit][0] @@ -707,7 +707,7 @@ static void lcp_resetci(fsm *f) { #endif /* HAVE_MULTILINK */ if (noendpoint) ao->neg_endpoint = 0; - peer_mru[pcb->unit] = PPP_MRU; + pcb->peer_mru = PPP_MRU; auth_reset(pcb); } @@ -2242,7 +2242,7 @@ static void lcp_up(fsm *f) { go->neg_pcompression, go->neg_accompression); if (ho->neg_mru) - peer_mru[pcb->unit] = ho->mru; + pcb->peer_mru = ho->mru; lcp_echo_lowerup(f->pcb); /* Enable echo messages */ @@ -2267,7 +2267,7 @@ static void lcp_down(fsm *f) { ppp_recv_config(pcb, PPP_MRU, (go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); - peer_mru[pcb->unit] = PPP_MRU; + pcb->peer_mru = PPP_MRU; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 752f0c30..94b8e86e 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -443,6 +443,8 @@ typedef struct ppp_pcb_s { eap_state eap; #endif /* EAP_SUPPORT */ + int peer_mru; /* currently negotiated peer MRU (per unit) */ + fsm lcp_fsm; /* LCP fsm structure */ lcp_options lcp_wantoptions; /* Options that we want to request */ lcp_options lcp_gotoptions; /* Options that peer ack'd */ From 82a4d4ec65a1e10b6a9bb79262167bf12585fbf2 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 03:53:05 +0200 Subject: [PATCH 170/320] LCP global variables moved to ppp_pcb as well as input/output buffers --- src/netif/ppp/chap-new.c | 4 +- src/netif/ppp/eap.c | 34 ++++++++--------- src/netif/ppp/fsm.c | 6 +-- src/netif/ppp/lcp.c | 80 +++++++++++++++++++--------------------- src/netif/ppp/ppp.c | 14 ++----- src/netif/ppp/ppp.h | 30 ++++++++++++++- src/netif/ppp/upap.c | 8 ++-- 7 files changed, 95 insertions(+), 81 deletions(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 95cb870a..e60f2a34 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -329,7 +329,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, return; /* send the response */ - p = outpacket_buf; + p = pcb->outpacket_buf; MAKEHEADER(p, PPP_CHAP); mlen = strlen(pcb->chap_server.message); len = CHAP_HDRLEN + mlen; @@ -339,7 +339,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, p[3] = len; if (mlen > 0) memcpy(p + CHAP_HDRLEN, pcb->chap_server.message, mlen); - ppp_write(pcb, outpacket_buf, PPP_HDRLEN + len); + ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + len); if (pcb->chap_server.flags & CHALLENGE_VALID) { pcb->chap_server.flags &= ~CHALLENGE_VALID; diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index e410074f..cb947f67 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -257,7 +257,7 @@ eap_state *esp; ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; u_char *outp; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_EAP); @@ -266,7 +266,7 @@ eap_state *esp; PUTCHAR(pcb->eap.es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_write(pcb, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); + ppp_write(pcb, pcb->outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); pcb->eap.es_server.ea_state = eapBadAuth; auth_peer_fail(pcb, PPP_EAP); @@ -283,7 +283,7 @@ eap_state *esp; ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; u_char *outp; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_EAP); @@ -292,7 +292,7 @@ eap_state *esp; PUTCHAR(pcb->eap.es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_write(pcb, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); + ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); auth_peer_success(pcb, PPP_EAP, 0, pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen); @@ -677,7 +677,7 @@ eap_state *esp; return; } - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_EAP); @@ -853,10 +853,10 @@ eap_state *esp; return; } - outlen = (outp - outpacket_buf) - PPP_HDRLEN; + outlen = (outp - pcb->outpacket_buf) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); - ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(pcb, pcb->outpacket_buf, outlen + PPP_HDRLEN); pcb->eap.es_server.ea_requests++; @@ -1032,7 +1032,7 @@ static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, u_char *s u_char *outp; int msglen; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_EAP); @@ -1046,7 +1046,7 @@ static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, u_char *s MEMCPY(outp, str, lenstr); } - ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); } /* @@ -1056,7 +1056,7 @@ static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, char *name, u_char *outp; int msglen; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_EAP); @@ -1074,7 +1074,7 @@ static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, char *name, MEMCPY(outp, name, namelen); } - ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); } #ifdef USE_SRP @@ -1093,7 +1093,7 @@ int lenstr; u_char *outp; int msglen; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_EAP); @@ -1108,7 +1108,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); } /* @@ -1125,7 +1125,7 @@ u_char *str; u_char *outp; int msglen; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_EAP); @@ -1140,7 +1140,7 @@ u_char *str; PUTLONG(flags, outp); MEMCPY(outp, str, SHA_DIGESTSIZE); - ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); } #endif /* USE_SRP */ @@ -1148,7 +1148,7 @@ static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { u_char *outp; int msglen; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_EAP); @@ -1160,7 +1160,7 @@ static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { PUTCHAR(EAPT_NAK, outp); PUTCHAR(type, outp); - ppp_write(pcb, outpacket_buf, PPP_HDRLEN + msglen); + ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); } #ifdef USE_SRP diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index b022e312..fe5354c9 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -708,7 +708,7 @@ static void fsm_sconfreq(fsm *f, int retransmit) { /* * Make up the request packet */ - outp = outpacket_buf + PPP_HDRLEN + HEADERLEN; + outp = pcb->outpacket_buf + PPP_HDRLEN + HEADERLEN; if( f->callbacks->cilen && f->callbacks->addci ){ cilen = (*f->callbacks->cilen)(f); if( cilen > pcb->peer_mru - HEADERLEN ) @@ -738,7 +738,7 @@ void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { int outlen; /* Adjust length to be smaller than MTU */ - outp = outpacket_buf; + outp = pcb->outpacket_buf; if (datalen > pcb->peer_mru - HEADERLEN) datalen = pcb->peer_mru - HEADERLEN; if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) @@ -748,7 +748,7 @@ void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { PUTCHAR(code, outp); PUTCHAR(id, outp); PUTSHORT(outlen, outp); - ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(pcb, pcb->outpacket_buf, outlen + PPP_HDRLEN); } #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index c46ee2bb..70222747 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -80,15 +80,19 @@ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ #endif /* UNUSED */ +#if 0 /* UNUSED */ /* options */ static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ +#endif /* UNUSED */ +#if 0 /* UNUSED */ #if PPP_LCP_ADAPTIVE bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ #endif bool lax_recv = 0; /* accept control chars in asyncmap */ bool noendpoint = 0; /* don't send/accept endpoint discriminator */ +#endif /* UNUSED */ #if PPP_OPTIONS static int noopt (char **); @@ -208,18 +212,6 @@ static option_t lcp_option_list[] = { }; #endif /* PPP_OPTIONS */ -/* global vars */ -#if PPPOS_SUPPORT -ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */ -#endif /* PPPOS_SUPPORT */ - -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 */ - -/* FIXME: do we really need such a large buffer? The typical 1500 bytes seem too much. */ -static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ - /* * Callbacks for fsm code. (CI = Configuration Information) */ @@ -308,8 +300,6 @@ struct protent lcp_protent = { #endif /* DEMAND_SUPPORT */ }; -int lcp_loopbackfail = DEFLOOPBACKFAIL; - /* * Length of each type of configuration option (in octets) */ @@ -492,7 +482,7 @@ void lcp_lowerup(ppp_pcb *pcb) { ppp_set_xaccm(pcb, &xmit_accm[pcb->unit]); #endif /* PPPOS_SUPPORT */ if (ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0) < 0 - || ppp_recv_config(pcb, PPP_MRU, (lax_recv? 0: 0xffffffff), + || ppp_recv_config(pcb, PPP_MRU, (pcb->settings.lax_recv? 0: 0xffffffff), wo->neg_pcompression, wo->neg_accompression) < 0) return; pcb->peer_mru = PPP_MRU; @@ -705,7 +695,7 @@ static void lcp_resetci(fsm *f) { #ifdef HAVE_MULTILINK } #endif /* HAVE_MULTILINK */ - if (noendpoint) + if (pcb->settings.noendpoint) ao->neg_endpoint = 0; pcb->peer_mru = PPP_MRU; auth_reset(pcb); @@ -1492,7 +1482,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { */ if (f->state != OPENED) { if (looped_back) { - if (++try.numloops >= lcp_loopbackfail) { + if (++try.numloops >= pcb->lcp_loopbackfail) { notice("Serial line is looped back."); pcb->status = EXIT_LOOPBACK; lcp_close(f->pcb, "Loopback detected"); @@ -1773,7 +1763,7 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { * Process all his options. */ next = inp; - nakp = nak_buffer; + nakp = pcb->nak_buffer; rejp = inp; while (l) { orc = CONFACK; /* Assume success */ @@ -2190,8 +2180,8 @@ endswitch: /* * Copy the Nak'd options from the nak_buffer to the caller's buffer. */ - *lenp = nakp - nak_buffer; - MEMCPY(inp, nak_buffer, *lenp); + *lenp = nakp - pcb->nak_buffer; + MEMCPY(inp, pcb->nak_buffer, *lenp); break; case CONFREJ: *lenp = rejp - inp; @@ -2238,7 +2228,7 @@ static void lcp_up(fsm *f) { (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), ho->neg_pcompression, ho->neg_accompression); ppp_recv_config(pcb, mru, - (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), + (pcb->settings.lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); if (ho->neg_mru) @@ -2550,12 +2540,12 @@ static int lcp_printpkt(u_char *p, int plen, */ static void LcpLinkFailure(fsm *f) { - ppp_pcb *pc = f->pcb; + ppp_pcb *pcb = f->pcb; if (f->state == OPENED) { - info("No response to %d echo-requests", lcp_echos_pending); + info("No response to %d echo-requests", pcb->lcp_echos_pending); notice("Serial link appears to be disconnected."); - pc->status = EXIT_PEER_DEAD; - lcp_close(f->pcb, "Peer not responding"); + pcb->status = EXIT_PEER_DEAD; + lcp_close(pcb, "Peer not responding"); } } @@ -2564,6 +2554,8 @@ static void LcpLinkFailure(fsm *f) { */ static void LcpEchoCheck(fsm *f) { + ppp_pcb *pcb = f->pcb; + LcpSendEchoRequest (f); if (f->state != OPENED) return; @@ -2571,10 +2563,10 @@ static void LcpEchoCheck(fsm *f) { /* * Start the timer for the next interval. */ - if (lcp_echo_timer_running) + if (pcb->lcp_echo_timer_running) warn("assertion lcp_echo_timer_running==0 failed"); - TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); - lcp_echo_timer_running = 1; + TIMEOUT (LcpEchoTimeout, f, pcb->settings.lcp_echo_interval); + pcb->lcp_echo_timer_running = 1; } /* @@ -2582,8 +2574,10 @@ static void LcpEchoCheck(fsm *f) { */ static void LcpEchoTimeout(void *arg) { - if (lcp_echo_timer_running != 0) { - lcp_echo_timer_running = 0; + fsm *f = (fsm*)f; + ppp_pcb *pcb = f->pcb; + if (pcb->lcp_echo_timer_running != 0) { + pcb->lcp_echo_timer_running = 0; LcpEchoCheck ((fsm *) arg); } } @@ -2610,7 +2604,7 @@ static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) { } /* Reset the number of outstanding echo frames */ - lcp_echos_pending = 0; + pcb->lcp_echos_pending = 0; } /* @@ -2626,10 +2620,10 @@ static void LcpSendEchoRequest(fsm *f) { /* * Detect the failure of the peer at this point. */ - if (lcp_echo_fails != 0) { - if (lcp_echos_pending >= lcp_echo_fails) { + if (pcb->settings.lcp_echo_fails != 0) { + if (pcb->lcp_echos_pending >= pcb->settings.lcp_echo_fails) { LcpLinkFailure(f); - lcp_echos_pending = 0; + pcb->lcp_echos_pending = 0; } } @@ -2638,7 +2632,7 @@ static void LcpSendEchoRequest(fsm *f) { * If adaptive echos have been enabled, only send the echo request if * no traffic was received since the last one. */ - if (lcp_echo_adaptive) { + if (pcb->settings.lcp_echo_adaptive) { static unsigned int last_pkts_in = 0; #if PPP_STATS_SUPPORT @@ -2660,8 +2654,8 @@ static void LcpSendEchoRequest(fsm *f) { lcp_magic = go->magicnumber; pktp = pkt; PUTLONG(lcp_magic, pktp); - fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt); - ++lcp_echos_pending; + fsm_sdata(f, ECHOREQ, pcb->lcp_echo_number++ & 0xFF, pkt, pktp - pkt); + ++pcb->lcp_echos_pending; } } @@ -2673,12 +2667,12 @@ static void lcp_echo_lowerup(ppp_pcb *pcb) { fsm *f = &pcb->lcp_fsm; /* Clear the parameters for generating echo frames */ - lcp_echos_pending = 0; - lcp_echo_number = 0; - lcp_echo_timer_running = 0; + pcb->lcp_echos_pending = 0; + pcb->lcp_echo_number = 0; + pcb->lcp_echo_timer_running = 0; /* If a timeout interval is specified then start the timer */ - if (lcp_echo_interval != 0) + if (pcb->settings.lcp_echo_interval != 0) LcpEchoCheck (f); } @@ -2689,9 +2683,9 @@ static void lcp_echo_lowerup(ppp_pcb *pcb) { static void lcp_echo_lowerdown(ppp_pcb *pcb) { fsm *f = &pcb->lcp_fsm; - if (lcp_echo_timer_running != 0) { + if (pcb->lcp_echo_timer_running != 0) { UNTIMEOUT (LcpEchoTimeout, f); - lcp_echo_timer_running = 0; + pcb->lcp_echo_timer_running = 0; } } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 8369e8cc..bb7bd0be 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -126,17 +126,6 @@ /*** LOCAL DEFINITIONS ***/ /*************************/ -/* - * Buffers for outgoing packets. This must be accessed only from the appropriate - * PPP task so that it doesn't need to be protected to avoid collisions. - */ -/* FIXME: outpacket_buf per PPP session */ -u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ - -#if PPPOS_SUPPORT -u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ -#endif /* PPPOS_SUPPORT */ - /* FIXME: add stats per PPP session */ #if PPP_STATS_SUPPORT static struct timeval start_time; /* Time when link was started. */ @@ -253,6 +242,7 @@ ppp_pcb *ppp_new(void) { pcb->unit = pd; pcb->open_flag = 1; pcb->status = EXIT_OK; + pcb->lcp_loopbackfail = DEFLOOPBACKFAIL; new_phase(pcb, PHASE_INITIALIZE); /* default configuration */ @@ -262,6 +252,8 @@ ppp_pcb *ppp_new(void) { pcb->settings.chap_timeout_time = 3; pcb->settings.chap_max_transmits = 10; #endif /* CHAP_SUPPPORT */ + pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; + pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; /* * Initialize each protocol. diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 94b8e86e..49d87851 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -178,6 +178,15 @@ typedef struct ppp_settings_s { int chap_max_transmits; int chap_rechallenge_time; #endif /* CHAP_SUPPPORT */ + + u_int lcp_echo_interval; /* Interval between LCP echo-requests */ + u_int lcp_echo_fails; /* Tolerance to unanswered echo-requests */ +#if PPP_LCP_ADAPTIVE + bool lcp_echo_adaptive; /* request echo only if the link was idle */ +#endif + bool lax_recv; /* accept control chars in asyncmap */ + bool noendpoint; /* don't send/accept endpoint discriminator */ + } ppp_settings; struct ppp_addrs { @@ -450,8 +459,17 @@ typedef struct ppp_pcb_s { lcp_options lcp_gotoptions; /* Options that peer ack'd */ lcp_options lcp_allowoptions; /* Options we allow peer to request */ lcp_options lcp_hisoptions; /* Options that we ack'd */ +#if PPPOS_SUPPORT + ext_accm xmit_accm; /* extended transmit ACCM */ +#endif /* PPPOS_SUPPORT */ + int lcp_echos_pending; /* Number of outstanding echo msgs */ + int lcp_echo_number; /* ID number of next echo frame */ + int lcp_echo_timer_running; /* set if a timer is running */ + /* FIXME: do we really need such a large buffer? The typical 1500 bytes seem too much. */ + u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ + int lcp_loopbackfail; - fsm ipcp_fsm; /* IPCP fsm structure */ + fsm ipcp_fsm; /* IPCP fsm structure */ ipcp_options ipcp_wantoptions; /* Options that we want to request */ ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ @@ -462,6 +480,16 @@ typedef struct ppp_pcb_s { int ipcp_is_up; /* have called np_up() */ bool ask_for_local; /* request our address from peer */ + /* + * Buffers for outgoing packets. This must be accessed only from the appropriate + * PPP task so that it doesn't need to be protected to avoid collisions. + */ + u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ + +#if PPPOS_SUPPORT + u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ +#endif /* PPPOS_SUPPORT */ + } ppp_pcb; /************************ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 400e8d27..f72ccd62 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -525,7 +525,7 @@ static void upap_sauthreq(ppp_pcb *pcb) { outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + pcb->upap.us_userlen + pcb->upap.us_passwdlen; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_PAP); @@ -538,7 +538,7 @@ static void upap_sauthreq(ppp_pcb *pcb) { PUTCHAR(pcb->upap.us_passwdlen, outp); MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen); - ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(pcb, pcb->outpacket_buf, outlen + PPP_HDRLEN); TIMEOUT(upap_timeout, pcb, pcb->upap.us_timeouttime); ++pcb->upap.us_transmits; @@ -554,7 +554,7 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl int outlen; outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - outp = outpacket_buf; + outp = pcb->outpacket_buf; MAKEHEADER(outp, PPP_PAP); PUTCHAR(code, outp); @@ -562,7 +562,7 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl PUTSHORT(outlen, outp); PUTCHAR(msglen, outp); MEMCPY(outp, msg, msglen); - ppp_write(pcb, outpacket_buf, outlen + PPP_HDRLEN); + ppp_write(pcb, pcb->outpacket_buf, outlen + PPP_HDRLEN); } #endif /* UNUSED */ From cce5fbc7b153c735c4232ce97b2ed09edda01ed8 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 03:58:48 +0200 Subject: [PATCH 171/320] fixed PPPoS xmit_accm ppp_pcb variable access --- src/netif/ppp/lcp.c | 22 +++++++++++----------- src/netif/ppp/lcp.h | 4 ---- src/netif/ppp/ppp.h | 3 +++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 70222747..f8e51e35 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -402,12 +402,12 @@ static void lcp_init(ppp_pcb *pcb) { * Set transmit escape for the flag and escape characters plus anything * set for the allowable options. */ - memset(xmit_accm[pcb->unit], 0, sizeof(xmit_accm[0])); - xmit_accm[pcb->unit][15] = 0x60; - xmit_accm[pcb->unit][0] = (u_char)((ao->asyncmap & 0xFF)); - xmit_accm[pcb->unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF); - xmit_accm[pcb->unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF); - xmit_accm[pcb->unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF); + memset(pcb->xmit_accm, 0, sizeof(ext_accm)); + pcb->xmit_accm[15] = 0x60; + pcb->xmit_accm[0] = (u_char)((ao->asyncmap & 0xFF)); + pcb->xmit_accm[1] = (u_char)((ao->asyncmap >> 8) & 0xFF); + pcb->xmit_accm[2] = (u_char)((ao->asyncmap >> 16) & 0xFF); + pcb->xmit_accm[3] = (u_char)((ao->asyncmap >> 24) & 0xFF); LCPDEBUG(("lcp_init: xmit_accm=%X %X %X %X\n", xmit_accm[unit][0], xmit_accm[unit][1], @@ -479,7 +479,7 @@ void lcp_lowerup(ppp_pcb *pcb) { * if we are going to ask for A/C and protocol compression. */ #if PPPOS_SUPPORT - ppp_set_xaccm(pcb, &xmit_accm[pcb->unit]); + ppp_set_xaccm(pcb, &pcb->xmit_accm); #endif /* PPPOS_SUPPORT */ if (ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0) < 0 || ppp_recv_config(pcb, PPP_MRU, (pcb->settings.lax_recv? 0: 0xffffffff), @@ -488,10 +488,10 @@ void lcp_lowerup(ppp_pcb *pcb) { pcb->peer_mru = PPP_MRU; #if PPPOS_SUPPORT - ao->asyncmap = (u_long)xmit_accm[pcb->unit][0] - | ((u_long)xmit_accm[pcb->unit][1] << 8) - | ((u_long)xmit_accm[pcb->unit][2] << 16) - | ((u_long)xmit_accm[pcb->unit][3] << 24); + ao->asyncmap = (u_long)pcb->xmit_accm[0] + | ((u_long)pcb->xmit_accm[1] << 8) + | ((u_long)pcb->xmit_accm[2] << 16) + | ((u_long)pcb->xmit_accm[3] << 24); LCPDEBUG(("lcp_lowerup: asyncmap=%X %X %X %X\n", xmit_accm[unit][3], xmit_accm[unit][2], diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index 4b815593..372cb155 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -90,10 +90,6 @@ /* Value used as data for CI_CALLBACK option */ #define CBCP_OPT 6 /* Use callback control protocol */ -#if PPPOS_SUPPORT -extern ext_accm xmit_accm[]; -#endif /* #if PPPOS_SUPPORT */ - #define DEFMRU 1500 /* Try for this */ #define MINMRU 128 /* No MRUs below this */ #define MAXMRU 16384 /* Normally limit MRU to this */ diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 49d87851..13783364 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -468,6 +468,9 @@ typedef struct ppp_pcb_s { /* FIXME: do we really need such a large buffer? The typical 1500 bytes seem too much. */ u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ int lcp_loopbackfail; +#if PPPOS_SUPPORT + +#endif /* #if PPPOS_SUPPORT */ fsm ipcp_fsm; /* IPCP fsm structure */ ipcp_options ipcp_wantoptions; /* Options that we want to request */ From 3065b9f9682e9830e47b411c8a4a450a357a867b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 04:12:10 +0200 Subject: [PATCH 172/320] no more pcb->unit, new user selectable pcb->num for debugging purpose (like netif does) --- src/netif/ppp/ipcp.c | 8 ++-- src/netif/ppp/ppp.c | 106 +++++++++++++++++++++---------------------- src/netif/ppp/ppp.h | 4 +- 3 files changed, 58 insertions(+), 60 deletions(-) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index a5aa6f39..1f09cf5d 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -306,7 +306,7 @@ struct protent ipcp_protent = { #endif /* DEMAND_SUPPORT */ }; -static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute); +static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute); /* * Lengths of configuration options. @@ -2003,7 +2003,7 @@ static void ipcp_down(fsm *f) { { sifnpmode(pcb, PPP_IP, NPMODE_DROP); sifdown(pcb); - ipcp_clear_addrs(pcb->unit, go->ouraddr, + ipcp_clear_addrs(pcb, go->ouraddr, ho->hisaddr, 0); cdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); } @@ -2014,9 +2014,7 @@ static void ipcp_down(fsm *f) { * ipcp_clear_addrs() - clear the interface addresses, routes, * proxy arp entries, etc. */ -static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute) { - - ppp_pcb *pcb = &ppp_pcb_list[unit]; +static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute) { if (pcb->proxy_arp_set) { cifproxyarp(pcb, hisaddr); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index bb7bd0be..58b4434f 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -222,7 +222,7 @@ int ppp_init(void) { } /* Create a new PPP session. */ -ppp_pcb *ppp_new(void) { +ppp_pcb *ppp_new(u8_t num) { int i, pd; ppp_pcb *pcb; struct protent *protp; @@ -239,7 +239,7 @@ ppp_pcb *ppp_new(void) { #endif /* PPP_STATS_SUPPORT */ memset(pcb, 0, sizeof(ppp_pcb)); - pcb->unit = pd; + pcb->num = num; pcb->open_flag = 1; pcb->status = EXIT_OK; pcb->lcp_loopbackfail = DEFLOOPBACKFAIL; @@ -352,7 +352,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s /* * Start the connection and handle incoming events (packet or timeout). */ - PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->unit)); + PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->num)); ppp_start(pcb); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); @@ -367,7 +367,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s void ppp_set_xaccm(ppp_pcb *pcb, ext_accm *accm) { SMEMCPY(pcb->out_accm, accm, sizeof(ext_accm)); PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: out_accm=%X %X %X %X\n", - pcb->unit, + pcb->num, pcb->out_accm[0], pcb->out_accm[1], pcb->out_accm[2], @@ -432,7 +432,7 @@ ppp_close(ppp_pcb *pcb) /* Disconnect */ #if PPPOE_SUPPORT if(pcb->ethif) { - PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ ppp_stop(pcb); @@ -440,7 +440,7 @@ ppp_close(ppp_pcb *pcb) #endif /* PPPOE_SUPPORT */ { #if PPPOS_SUPPORT - PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ ppp_stop(pcb); @@ -457,7 +457,7 @@ ppp_close(ppp_pcb *pcb) void ppp_sighup(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hup\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hup\n", pcb->num)); ppp_hup(pcb); } @@ -466,7 +466,7 @@ ppp_sighup(ppp_pcb *pcb) /** Initiate LCP open request */ static void ppp_start(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->num)); lcp_open(pcb); /* Start protocol */ lcp_lowerup(pcb); PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); @@ -474,13 +474,13 @@ static void ppp_start(ppp_pcb *pcb) { /** LCP close request */ static void ppp_stop(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_stop: unit %d\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_stop: unit %d\n", pcb->num)); lcp_close(pcb, "User request"); } /** Called when carrier/link is lost */ static void ppp_hup(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_hup: unit %d\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_hup: unit %d\n", pcb->num)); lcp_lowerdown(pcb); link_terminated(pcb); } @@ -545,7 +545,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { #if PPPOS_SUPPORT && VJ_SUPPORT case PPP_VJC_COMP: /* VJ compressed TCP */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->unit, pb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->num, pb->len)); /* * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. @@ -555,11 +555,11 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->num)); break; case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->unit, pb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->num, pb->len)); /* * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. @@ -569,12 +569,12 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { return; } /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->num)); break; #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->unit, pb->len)); + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->num, pb->len)); if (pcb->netif.input) { pcb->netif.input(pb, &pcb->netif); return; @@ -605,7 +605,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { */ if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag && protp->datainput != NULL) { - (*protp->datainput)(pcb->unit, pb->payload, pb->len); + (*protp->datainput)(pcb, pb->payload, pb->len); goto out; } #endif /* UNUSED */ @@ -794,7 +794,7 @@ static u_char ppp_accm_mask[] = { static void ppp_receive_wakeup(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_receive_wakeup: unit %d\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_receive_wakeup: unit %d\n", pcb->num)); if (pcb->open_flag != 0) sio_read_abort(pcb->fd); } @@ -928,7 +928,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i * and the peer will just drop it if it's not accepting it. */ if (!pcb->open_flag || !pb) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad params prot=%d pb=%p\n", - pcb->unit, PPP_IP, (void*)pb)); + pcb->num, PPP_IP, (void*)pb)); LINK_STATS_INC(link.opterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -937,7 +937,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i /* Check that the link is up. */ if (pcb->phase == PHASE_DEAD) { - PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->unit)); + PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->num)); LINK_STATS_INC(link.rterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -954,7 +954,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i /* Grab an output buffer. */ head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (head == NULL) { - PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: first alloc fail\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: first alloc fail\n", pcb->num)); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -979,7 +979,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i protocol = PPP_VJC_UNCOMP; break; default: - PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->num)); LINK_STATS_INC(link.proterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -1041,7 +1041,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i if (!tail) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: Alloc err - dropping proto=%d\n", - pcb->unit, protocol)); + pcb->num, protocol)); pbuf_free(head); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); @@ -1050,7 +1050,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i } /* Send it. */ - PPPDEBUG(LOG_INFO, ("ppp_netif_output[%d]: proto=0x%"X16_F"\n", pcb->unit, protocol)); + PPPDEBUG(LOG_INFO, ("ppp_netif_output[%d]: proto=0x%"X16_F"\n", pcb->num, protocol)); pppos_put(pcb, head); #endif /* PPPOS_SUPPORT */ @@ -1210,7 +1210,7 @@ int ppp_write(ppp_pcb *pcb, const u_char *s, int n) { * Otherwise send it. */ if (!tail) { PPPDEBUG(LOG_WARNING, - ("ppp_write[%d]: Alloc err - dropping pbuf len=%d\n", pcb->unit, head->len)); + ("ppp_write[%d]: Alloc err - dropping pbuf len=%d\n", pcb->num, head->len)); /*"ppp_write[%d]: Alloc err - dropping %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ pbuf_free(head); LINK_STATS_INC(link.memerr); @@ -1219,7 +1219,7 @@ int ppp_write(ppp_pcb *pcb, const u_char *s, int n) { return PPPERR_ALLOC; } - PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pcb->unit, head->len)); + PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pcb->num, head->len)); /* "ppp_write[%d]: %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ pppos_put(pcb, head); #endif /* PPPOS_SUPPORT */ @@ -1334,7 +1334,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) u_char escaped; SYS_ARCH_DECL_PROTECT(lev); - PPPDEBUG(LOG_DEBUG, ("pppos_input_proc[%d]: got %d bytes\n", pcb->unit, l)); + PPPDEBUG(LOG_DEBUG, ("pppos_input_proc[%d]: got %d bytes\n", pcb->num, l)); while (l-- > 0) { cur_char = *s++; @@ -1359,14 +1359,14 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) } else if (pcrx->in_state < PDDATA) { PPPDEBUG(LOG_WARNING, ("pppos_input_proc[%d]: Dropping incomplete packet %d\n", - pcb->unit, pcrx->in_state)); + pcb->num, pcrx->in_state)); LINK_STATS_INC(link.lenerr); ppp_drop(pcrx); /* If the fcs is invalid, drop the packet. */ } else if (pcrx->in_fcs != PPP_GOODFCS) { PPPDEBUG(LOG_INFO, ("pppos_input_proc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", - pcb->unit, pcrx->in_fcs, pcrx->in_protocol)); + pcb->num, pcrx->in_fcs, pcrx->in_protocol)); /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ LINK_STATS_INC(link.chkerr); ppp_drop(pcrx); @@ -1404,7 +1404,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) MEMCPY(head->payload, pcb, sizeof(void*)); pbuf_chain(head, inp); if(tcpip_callback_with_block(pppos_input_callback, head, 0) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: tcpip_callback() failed, dropping packet\n", pcb->unit)); + PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: tcpip_callback() failed, dropping packet\n", pcb->num)); pbuf_free(head); pbuf_free(inp); LINK_STATS_INC(link.drop); @@ -1424,7 +1424,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) * been inserted by the physical layer so here we just drop them. */ } else { PPPDEBUG(LOG_WARNING, - ("pppos_input_proc[%d]: Dropping ACCM char <%d>\n", pcb->unit, cur_char)); + ("pppos_input_proc[%d]: Dropping ACCM char <%d>\n", pcb->num, cur_char)); } /* Process other characters. */ } else { @@ -1471,7 +1471,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) #if 0 else { PPPDEBUG(LOG_WARNING, - ("pppos_input_proc[%d]: Invalid control <%d>\n", pcb->unit, cur_char)); + ("pppos_input_proc[%d]: Invalid control <%d>\n", pcb->num, cur_char)); pcrx->in_state = PDSTART; } #endif @@ -1507,7 +1507,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) /* No free buffers. Drop the input packet and let the * higher layers deal with it. Continue processing * the received pbuf chain in case a new packet starts. */ - PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: NO FREE MBUFS!\n", pcb->unit)); + PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: NO FREE MBUFS!\n", pcb->num)); LINK_STATS_INC(link.memerr); ppp_drop(pcrx); pcrx->in_state = PDSTART; /* Wait for flag sequence. */ @@ -1598,19 +1598,19 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { /* PPPoE link is established, starting PPP negotiation */ case PPPOE_CB_STATE_UP: - PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pcb->unit)); + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pcb->num)); ppp_start(pcb); return; /* PPPoE link normally down (i.e. asked to do so) */ case PPPOE_CB_STATE_DOWN: - PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pcb->unit)); + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pcb->num)); pppoe_err_code = PPPERR_CONNECT; break; /* PPPoE link failed to setup (i.e. PADI/PADO timeout) */ case PPPOE_CB_STATE_FAILED: - PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pcb->unit)); + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pcb->num)); pppoe_err_code = PPPERR_OPEN; break; } @@ -1633,7 +1633,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { #endif /* PPPOE_SUPPORT */ void ppp_link_down(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pcb->num)); #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD ppp_receive_wakeup(pcb); @@ -1641,7 +1641,7 @@ void ppp_link_down(ppp_pcb *pcb) { } void ppp_link_terminated(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d\n", pcb->unit)); + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d\n", pcb->num)); #if PPPOE_SUPPORT if (pcb->ethif) { @@ -1654,7 +1654,7 @@ void ppp_link_terminated(ppp_pcb *pcb) { ppp_receive_wakeup(pcb); #endif /* PPP_INPROC_OWNTHREAD */ - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pcb->unit, pcb->link_status_cb, pcb->err_code)); + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); if (pcb->link_status_cb) { pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, NULL); } @@ -1735,10 +1735,10 @@ int ppp_send_config(ppp_pcb *pcb, int mtu, u_int32_t accm, int pcomp, int accomp #if PPPOS_SUPPORT PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: out_accm=%X %X %X %X\n", - pcb->unit, + pcb->num, pcb->out_accm[0], pcb->out_accm[1], pcb->out_accm[2], pcb->out_accm[3])); #else - PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->unit) ); + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->num) ); #endif /* PPPOS_SUPPORT */ return 0; } @@ -1771,10 +1771,10 @@ int ppp_recv_config(ppp_pcb *pcb, int mru, u_int32_t accm, int pcomp, int accomp #if PPPOS_SUPPORT PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: in_accm=%X %X %X %X\n", - pcb->unit, + pcb->num, pcb->rx.in_accm[0], pcb->rx.in_accm[1], pcb->rx.in_accm[2], pcb->rx.in_accm[3])); #else - PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->unit) ); + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->num) ); #endif /* PPPOS_SUPPORT */ return 0; } @@ -1787,7 +1787,7 @@ int sifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask) { if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sifaddr[%d]: bad params\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("sifaddr[%d]: bad params\n", pcb->num)); return 0; } @@ -1809,7 +1809,7 @@ int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr) { LWIP_UNUSED_ARG(his_adr); if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad params\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad params\n", pcb->num)); return 0; } @@ -1826,7 +1826,7 @@ int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr) { int sdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sdns[%d]: bad params\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("sdns[%d]: bad params\n", pcb->num)); return 0; } @@ -1846,7 +1846,7 @@ int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { LWIP_UNUSED_ARG(ns2); if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("cdns[%d]: bad params\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("cdns[%d]: bad params\n", pcb->num)); return 0; } @@ -1862,14 +1862,14 @@ int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { int sifup(ppp_pcb *pcb) { if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad params\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad params\n", pcb->num)); return 0; } netif_remove(&pcb->netif); if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, ip_input)) { - PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pcb->unit)); + PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pcb->num)); return 0; } @@ -1877,7 +1877,7 @@ int sifup(ppp_pcb *pcb) { pcb->if_up = 1; pcb->err_code = PPPERR_NONE; - PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p err_code=%d\n", pcb->unit, pcb->link_status_cb, pcb->err_code)); + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); if (pcb->link_status_cb) pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code, &pcb->addrs); @@ -1892,7 +1892,7 @@ int sifup(ppp_pcb *pcb) { int sifdown(ppp_pcb *pcb) { if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad params\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad params\n", pcb->num)); return 0; } @@ -1900,7 +1900,7 @@ int sifdown(ppp_pcb *pcb) { /* make sure the netif status callback is called */ netif_set_down(&pcb->netif); netif_remove(&pcb->netif); - PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p err_code=%d\n", pcb->unit, pcb->link_status_cb, pcb->err_code)); + PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); if (pcb->link_status_cb) pcb->link_status_cb(pcb->link_status_ctx, PPPERR_CONNECT, NULL); @@ -1960,7 +1960,7 @@ int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, bool rep LWIP_UNUSED_ARG(replace); if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sifdefaultroute[%d]: bad params\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("sifdefaultroute[%d]: bad params\n", pcb->num)); return 0; } @@ -1978,7 +1978,7 @@ int cifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway) { LWIP_UNUSED_ARG(gateway); if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("cifdefaultroute[%d]: bad params\n", pcb->unit)); + PPPDEBUG(LOG_WARNING, ("cifdefaultroute[%d]: bad params\n", pcb->num)); return 0; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 13783364..53c6ca80 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -391,7 +391,7 @@ typedef struct eap_state { */ typedef struct ppp_pcb_s { ppp_settings settings; - int unit; + u8_t num; /* Interface number - only useful for debugging */ #if PPPOS_SUPPORT ppp_pcb_rx rx; #endif /* PPPOS_SUPPORT */ @@ -503,7 +503,7 @@ typedef struct ppp_pcb_s { int ppp_init(void); /* Create a new PPP session, returns a PPP PCB structure. */ -ppp_pcb *ppp_new(void); +ppp_pcb *ppp_new(u8_t num); /* Set auth helper, optional, you can either fill ppp_pcb->settings. */ From 0e2d5f9d0e3f161c9a5e79cfa1783826d07cd835 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 14:53:13 +0200 Subject: [PATCH 173/320] removed unused inpacket_buf in ppp_pcb --- src/netif/ppp/ppp.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 53c6ca80..fda50588 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -468,9 +468,6 @@ typedef struct ppp_pcb_s { /* FIXME: do we really need such a large buffer? The typical 1500 bytes seem too much. */ u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ int lcp_loopbackfail; -#if PPPOS_SUPPORT - -#endif /* #if PPPOS_SUPPORT */ fsm ipcp_fsm; /* IPCP fsm structure */ ipcp_options ipcp_wantoptions; /* Options that we want to request */ @@ -489,10 +486,6 @@ typedef struct ppp_pcb_s { */ u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ -#if PPPOS_SUPPORT - u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ -#endif /* PPPOS_SUPPORT */ - } ppp_pcb; /************************ From 99bf9775d975a0429cf5ea46258099e11ee93f5e Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 16 Jun 2012 18:45:53 +0200 Subject: [PATCH 174/320] NUM_PPP is defined is opt.h, clearing from ppp_impl.h --- src/netif/ppp/ppp_impl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index fa6cf119..f40e4b6d 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -55,7 +55,6 @@ /* * 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 */ From ea7bf1905773d979ea42f35bd85560d24e77543d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 17 Jun 2012 00:17:22 +0200 Subject: [PATCH 175/320] fixed most "unit 0" used instead of pcb pointer --- src/netif/ppp/auth.c | 26 +++++++++++++------------- src/netif/ppp/demand.c | 18 +++++++++--------- src/netif/ppp/multilink.c | 14 +++++++------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index d3913f2b..3d191709 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -593,7 +593,7 @@ void start_link(unit) new_phase(pcb, PHASE_ESTABLISH); - lcp_lowerup(0); + lcp_lowerup(pcb); return; disconnect: @@ -632,7 +632,7 @@ void link_terminated(ppp_pcb *pcb) { } else notice("Link terminated."); - lcp_lowerdown(0); + lcp_lowerdown(pcb); new_phase(pcb, PHASE_DEAD); ppp_link_terminated(pcb); @@ -659,7 +659,7 @@ void link_terminated(ppp_pcb *pcb) { fd_ppp = -1; } if (!hungup) - lcp_lowerdown(0); + lcp_lowerdown(pcb); if (!doing_multilink && !demand) script_unsetenv("IFNAME"); @@ -778,7 +778,7 @@ void link_established(ppp_pcb *pcb) { if (!wo->neg_upap || uselogin || !null_login(unit)) { warn("peer refused to authenticate: terminating link"); status = EXIT_PEER_AUTH_FAILED; - lcp_close(pcb->unit, "peer refused to authenticate"); + lcp_close(pcb, "peer refused to authenticate"); return; } } @@ -878,7 +878,7 @@ static void network_phase(ppp_pcb *pcb) { */ if (go->neg_cbcp) { new_phase(pcb, PHASE_CALLBACK); - (*cbcp_protent.open)(unit); + (*cbcp_protent.open)(pcb); return; } #endif @@ -939,7 +939,7 @@ void start_networks(ppp_pcb *pcb) { #endif /* CCP_SUPPORT */ ) && protp->enabled_flag && protp->open != NULL) - (*protp->open)(0); + (*protp->open)(pcb); #endif /* CCP_SUPPORT || ECP_SUPPORT */ /* @@ -985,7 +985,7 @@ void continue_networks(ppp_pcb *pcb) { if (pcb->num_np_open == 0) /* nothing to do */ - lcp_close(0, "No network protocols running"); + lcp_close(pcb, "No network protocols running"); } #if PPP_SERVER @@ -997,7 +997,7 @@ void auth_peer_fail(ppp_pcb *pcb, int protocol) { * Authentication failure: take the link down */ status = EXIT_PEER_AUTH_FAILED; - lcp_close(pcb->unit, "Authentication failed"); + lcp_close(pcb, "Authentication failed"); } /* @@ -1210,7 +1210,7 @@ void np_down(ppp_pcb *pcb, int proto) { void np_finished(ppp_pcb *pcb, int proto) { if (--pcb->num_np_open <= 0) { /* no further use for the link: shut up shop. */ - lcp_close(0, "No network protocols running"); + lcp_close(pcb, "No network protocols running"); } } @@ -1243,7 +1243,7 @@ check_maxoctets(arg) if (used > maxoctets) { notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); status = EXIT_TRAFFIC_LIMIT; - lcp_close(0, "Traffic limit"); + lcp_close(pcb, "Traffic limit"); #if 0 /* UNUSED */ need_holdoff = 0; #endif /* UNUSED */ @@ -1280,7 +1280,7 @@ static void check_idle(void *arg) { /* link is idle: shut it down. */ notice("Terminating connection due to lack of activity."); pcb->status = EXIT_IDLE_TIMEOUT; - lcp_close(0, "Link inactive"); + lcp_close(pcb, "Link inactive"); #if 0 /* UNUSED */ need_holdoff = 0; #endif /* UNUSED */ @@ -1296,7 +1296,7 @@ static void connect_time_expired(void *arg) { ppp_pcb *pcb = (ppp_pcb*)arg; info("Connect time expired"); pcb->status = EXIT_CONNECT_TIME; - lcp_close(0, "Connect time expired"); /* Close connection */ + lcp_close(pcb, "Connect time expired"); /* Close connection */ } #if PPP_OPTIONS @@ -1662,7 +1662,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) */ if (attempts++ >= 10) { warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); - lcp_close(unit, "login failed"); + lcp_close(pcb, "login failed"); } if (attempts > 3) sleep((u_int) (attempts - 3) * 5); diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index b7c33e0f..75b43a13 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -98,9 +98,9 @@ demand_conf() flush_flag = 0; fcs = PPP_INITFCS; - netif_set_mtu(0, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU)); - if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0 - || ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0) + netif_set_mtu(pcb, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU)); + if (ppp_send_config(pcb, PPP_MRU, (u_int32_t) 0, 0, 0) < 0 + || ppp_recv_config(pcb, PPP_MRU, (u_int32_t) 0, 0, 0) < 0) fatal("Couldn't set up demand-dialled PPP interface: %m"); #ifdef PPP_FILTER @@ -112,10 +112,10 @@ demand_conf() */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) - ((*protp->demand_conf)(0)); + ((*protp->demand_conf)(pcb)); /* FIXME: find a way to die() here */ #if 0 - if (!((*protp->demand_conf)(0))) + if (!((*protp->demand_conf)(pcb))) die(1); #endif } @@ -132,7 +132,7 @@ demand_block() for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE); + sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_QUEUE); get_loop_output(); } @@ -149,7 +149,7 @@ demand_discard() for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR); + sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_ERROR); get_loop_output(); /* discard all saved packets */ @@ -175,7 +175,7 @@ demand_unblock() for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS); + sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_PASS); } /* @@ -411,7 +411,7 @@ demand_rexmit(proto, newip) ntohs(*( (short *) (pkt->data+iphdr+6)))); } } - output(0, pkt->data, pkt->length); + output(pcb, pkt->data, pkt->length); free(pkt); } else { if (prev == NULL) diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 5648d26c..551a067c 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -130,7 +130,7 @@ mp_join_bundle() /* have previously joined a bundle */ if (!go->neg_mrru || !ho->neg_mrru) { notice("oops, didn't get multilink on renegotiation"); - lcp_close(0, "multilink required"); + lcp_close(pcb, "multilink required"); return 0; } /* XXX should check the peer_authname and ho->endpoint @@ -148,12 +148,12 @@ mp_join_bundle() if (demand) { /* already have a bundle */ cfg_bundle(0, 0, 0, 0); - netif_set_mtu(0, mtu); + netif_set_mtu(pcb, mtu); return 0; } make_new_bundle(0, 0, 0, 0); set_ifunit(1); - netif_set_mtu(0, mtu); + netif_set_mtu(pcb, mtu); return 0; } @@ -198,7 +198,7 @@ mp_join_bundle() mtu = LWIP_MIN(ho->mrru, ao->mru); if (demand) { cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); - netif_set_mtu(0, mtu); + netif_set_mtu(pcb, mtu); script_setenv("BUNDLE", bundle_id + 7, 1); return 0; } @@ -245,9 +245,9 @@ mp_join_bundle() /* we have to make a new bundle */ make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); set_ifunit(1); - netif_set_mtu(0, mtu); + netif_set_mtu(pcb, mtu); script_setenv("BUNDLE", bundle_id + 7, 1); - make_bundle_links(0); + make_bundle_links(pcb); unlock_db(); info("New bundle %s created", ifname); multilink_master = 1; @@ -277,7 +277,7 @@ void mp_bundle_terminated() TDB_DATA key; bundle_terminating = 1; - upper_layers_down(0); + upper_layers_down(pcb); notice("Connection terminated."); #if PPP_STATS_SUPPORT print_link_stats(); From 0c68fc409e80dcd36df94d2f7b266bf54b13c9dc Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 17 Jun 2012 00:33:02 +0200 Subject: [PATCH 176/320] fixed pppoe_find_softc_by_session() when we have the same PPPoE session id on 2 ethif --- src/netif/ppp/ppp_oe.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 4f1aed31..6bb21e24 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -134,8 +134,8 @@ static err_t pppoe_send_pads(struct pppoe_softc *); static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *); /* internal helper functions */ -static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *); -static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *); +static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif); +static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif); /** linked list of created pppoe interfaces */ static struct pppoe_softc *pppoe_softc_list; @@ -211,9 +211,7 @@ pppoe_destroy(struct netif *ifp) * and lean implementation, so number of open sessions typically should * be 1. */ -static struct pppoe_softc * -pppoe_find_softc_by_session(u_int session, struct netif *rcvif) -{ +static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif) { struct pppoe_softc *sc; if (session == 0) { @@ -222,22 +220,17 @@ pppoe_find_softc_by_session(u_int session, struct netif *rcvif) for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { if (sc->sc_state == PPPOE_STATE_SESSION - && sc->sc_session == session) { - if (sc->sc_ethif == rcvif) { - return sc; - } else { - return NULL; + && sc->sc_session == session + && sc->sc_ethif == rcvif) { + return sc; } - } } return NULL; } /* Check host unique token passed and return appropriate softc pointer, * or NULL if token is bogus. */ -static struct pppoe_softc * -pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) -{ +static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) { struct pppoe_softc *sc, *t; if (pppoe_softc_list == NULL) { From 4404ef0281c183156d319054950aa9149458af38 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 17 Jun 2012 00:55:11 +0200 Subject: [PATCH 177/320] prevent conflict with existing (md4|md5|sha1|des) object file if polarssl is already used elsewhere in the project --- src/netif/ppp/chap-md5.c | 5 +++++ src/netif/ppp/chap_ms.c | 21 ++++++++++++++++--- src/netif/ppp/eap.c | 5 +++++ src/netif/ppp/magic.c | 5 +++++ src/netif/ppp/polarssl/{des.c => lwip_des.c} | 2 +- src/netif/ppp/polarssl/{des.h => lwip_des.h} | 0 src/netif/ppp/polarssl/{md4.c => lwip_md4.c} | 2 +- src/netif/ppp/polarssl/{md4.h => lwip_md4.h} | 0 src/netif/ppp/polarssl/{md5.c => lwip_md5.c} | 2 +- src/netif/ppp/polarssl/{md5.h => lwip_md5.h} | 0 .../ppp/polarssl/{sha1.c => lwip_sha1.c} | 2 +- .../ppp/polarssl/{sha1.h => lwip_sha1.h} | 0 12 files changed, 37 insertions(+), 7 deletions(-) rename src/netif/ppp/polarssl/{des.c => lwip_des.c} (99%) rename src/netif/ppp/polarssl/{des.h => lwip_des.h} (100%) rename src/netif/ppp/polarssl/{md4.c => lwip_md4.c} (99%) rename src/netif/ppp/polarssl/{md4.h => lwip_md4.h} (100%) rename src/netif/ppp/polarssl/{md5.c => lwip_md5.c} (99%) rename src/netif/ppp/polarssl/{md5.h => lwip_md5.h} (100%) rename src/netif/ppp/polarssl/{sha1.c => lwip_sha1.c} (99%) rename src/netif/ppp/polarssl/{sha1.h => lwip_sha1.h} (100%) diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 62b69c5f..9239723f 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -41,7 +41,12 @@ #include "chap-new.h" #include "chap-md5.h" #include "magic.h" + +#if LWIP_INCLUDED_POLARSSL_MD5 +#include "polarssl/lwip_md5.h" +#else #include "polarssl/md5.h" +#endif #define MD5_HASH_SIZE 16 #define MD5_MIN_CHALLENGE 16 diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index b9f55b34..64762dbc 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -91,12 +91,27 @@ #include "chap-new.h" #include "chap_ms.h" -#include "polarssl/md4.h" -#include "polarssl/sha1.h" -#include "polarssl/des.h" #include "pppcrypt.h" #include "magic.h" +#if LWIP_INCLUDED_POLARSSL_MD4 +#include "polarssl/lwip_md4.h" +#else +#include "polarssl/md4.h" +#endif + +#if LWIP_INCLUDED_POLARSSL_SHA1 +#include "polarssl/lwip_sha1.h" +#else +#include "polarssl/sha1.h" +#endif + +#if LWIP_INCLUDED_POLARSSL_DES +#include "polarssl/lwip_des.h" +#else +#include "polarssl/des.h" +#endif + #define SHA1_SIGNATURE_SIZE 20 static void ascii2unicode (char[], int, u_char[]); diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index cb947f67..7fb3ed64 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -48,7 +48,12 @@ #include "ppp_impl.h" +#if LWIP_INCLUDED_POLARSSL_MD5 +#include "polarssl/lwip_md5.h" +#else #include "polarssl/md5.h" +#endif + #include "eap.h" #ifdef USE_SRP diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 45237b0a..5dea7320 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -77,7 +77,12 @@ #include "ppp_impl.h" +#if LWIP_INCLUDED_POLARSSL_MD5 +#include "polarssl/lwip_md5.h" +#else #include "polarssl/md5.h" +#endif + #include "magic.h" #if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */ diff --git a/src/netif/ppp/polarssl/des.c b/src/netif/ppp/polarssl/lwip_des.c similarity index 99% rename from src/netif/ppp/polarssl/des.c rename to src/netif/ppp/polarssl/lwip_des.c index 2e2a61c3..07c00513 100644 --- a/src/netif/ppp/polarssl/des.c +++ b/src/netif/ppp/polarssl/lwip_des.c @@ -42,7 +42,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_DES -#include "des.h" +#include "lwip_des.h" /* * 32-bit integer manipulation macros (big endian) diff --git a/src/netif/ppp/polarssl/des.h b/src/netif/ppp/polarssl/lwip_des.h similarity index 100% rename from src/netif/ppp/polarssl/des.h rename to src/netif/ppp/polarssl/lwip_des.h diff --git a/src/netif/ppp/polarssl/md4.c b/src/netif/ppp/polarssl/lwip_md4.c similarity index 99% rename from src/netif/ppp/polarssl/md4.c rename to src/netif/ppp/polarssl/lwip_md4.c index bf7f9347..b654542e 100644 --- a/src/netif/ppp/polarssl/md4.c +++ b/src/netif/ppp/polarssl/lwip_md4.c @@ -42,7 +42,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_MD4 -#include "md4.h" +#include "lwip_md4.h" /* * 32-bit integer manipulation macros (little endian) diff --git a/src/netif/ppp/polarssl/md4.h b/src/netif/ppp/polarssl/lwip_md4.h similarity index 100% rename from src/netif/ppp/polarssl/md4.h rename to src/netif/ppp/polarssl/lwip_md4.h diff --git a/src/netif/ppp/polarssl/md5.c b/src/netif/ppp/polarssl/lwip_md5.c similarity index 99% rename from src/netif/ppp/polarssl/md5.c rename to src/netif/ppp/polarssl/lwip_md5.c index e2854a1b..38ad9d41 100644 --- a/src/netif/ppp/polarssl/md5.c +++ b/src/netif/ppp/polarssl/lwip_md5.c @@ -41,7 +41,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_MD5 -#include "md5.h" +#include "lwip_md5.h" /* * 32-bit integer manipulation macros (little endian) diff --git a/src/netif/ppp/polarssl/md5.h b/src/netif/ppp/polarssl/lwip_md5.h similarity index 100% rename from src/netif/ppp/polarssl/md5.h rename to src/netif/ppp/polarssl/lwip_md5.h diff --git a/src/netif/ppp/polarssl/sha1.c b/src/netif/ppp/polarssl/lwip_sha1.c similarity index 99% rename from src/netif/ppp/polarssl/sha1.c rename to src/netif/ppp/polarssl/lwip_sha1.c index 5d7a59c8..2d62fdfe 100644 --- a/src/netif/ppp/polarssl/sha1.c +++ b/src/netif/ppp/polarssl/lwip_sha1.c @@ -41,7 +41,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_SHA1 -#include "sha1.h" +#include "lwip_sha1.h" /* * 32-bit integer manipulation macros (big endian) diff --git a/src/netif/ppp/polarssl/sha1.h b/src/netif/ppp/polarssl/lwip_sha1.h similarity index 100% rename from src/netif/ppp/polarssl/sha1.h rename to src/netif/ppp/polarssl/lwip_sha1.h From 3120487243824829f5ca1c67f1a76b9db5553aef Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 17 Jun 2012 01:47:45 +0200 Subject: [PATCH 178/320] cleanified old style C function declaration from utils.c --- src/netif/ppp/ppp_impl.h | 30 ++++++-------- src/netif/ppp/utils.c | 90 ++++++++++------------------------------ 2 files changed, 34 insertions(+), 86 deletions(-) diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index f40e4b6d..9e3e6950 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -586,24 +586,20 @@ int str_to_epdisc (struct epdisc *, char *); /* endpt disc. from str */ #endif /* Procedures exported from utils.c. */ -void print_string (char *, 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 dbglog (char *, ...); /* log a debug message */ -void info (char *, ...); /* log an informational message */ -void notice (char *, ...); /* log a notice-level message */ -void warn (char *, ...); /* log a warning message */ -void error (char *, ...); /* log an error message */ -void fatal (char *, ...); /* log an error message and die(1) */ -void init_pr_log (const char *, int); /* initialize for using pr_log */ -void pr_log (void *, char *, ...); /* printer fn, output to syslog */ -void end_pr_log (void); /* finish up after using pr_log */ +void print_string(char *p, int len, void (*printer) (void *, char *, ...), void *arg); /* Format a string for output */ +int slprintf(char *buf, int buflen, char *fmt, ...); /* sprintf++ */ +int vslprintf(char *buf, int buflen, char *fmt, va_list args); /* vsprintf++ */ +size_t strlcpy(char *dest, const char *src, size_t len); /* safe strcpy */ +size_t strlcat(char *dest, const char *src, size_t len); /* safe strncpy */ +void dbglog(char *fmt, ...); /* log a debug message */ +void info(char *fmt, ...); /* log an informational message */ +void notice(char *fmt, ...); /* log a notice-level message */ +void warn(char *fmt, ...); /* log a warning message */ +void error(char *fmt, ...); /* log an error message */ +void fatal(char *fmt, ...); /* log an error message and die(1) */ #if PRINTPKT_SUPPORT -void dump_packet (const char *, u_char *, int); - /* dump packet to debug log if interesting */ +void dump_packet(const char *tag, unsigned char *p, int len); + /* dump packet to debug log if interesting */ #endif /* PRINTPKT_SUPPORT */ diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index c0eee4be..95cf9cbc 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -69,12 +69,12 @@ extern char *strerror(); #endif -static void logit (int, char *, va_list); -static void log_write (int, char *); +static void logit(int level, char *fmt, va_list args); +static void log_write(int level, char *buf); #if PRINTPKT_SUPPORT -static void vslp_printer (void *, char *, ...); -static void format_packet (u_char *, int, void (*) (void *, char *, ...), - void *); +static void vslp_printer(void *arg, char *fmt, ...); +static void format_packet(u_char *p, int len, + void (*printer) (void *, char *, ...), void *arg); struct buffer_info { char *ptr; @@ -86,12 +86,7 @@ struct buffer_info { * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, * always leaves destination null-terminated (for len > 0). */ -size_t -strlcpy(dest, src, len) - char *dest; - const char *src; - size_t len; -{ +size_t strlcpy(char *dest, const char *src, size_t len) { size_t ret = strlen(src); if (len != 0) { @@ -109,12 +104,7 @@ strlcpy(dest, src, len) * strlcat - like strcat/strncat, doesn't overflow destination buffer, * always leaves destination null-terminated (for len > 0). */ -size_t -strlcat(dest, src, len) - char *dest; - const char *src; - size_t len; -{ +size_t strlcat(char *dest, const char *src, size_t len) { size_t dlen = strlen(dest); return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); @@ -129,9 +119,7 @@ strlcat(dest, src, len) * Doesn't do floating-point formats. * Returns the number of chars put into buf. */ -int -slprintf (char *buf, int buflen, char *fmt, ...) -{ +int slprintf(char *buf, int buflen, char *fmt, ...) { va_list args; int n; @@ -146,13 +134,7 @@ slprintf (char *buf, int buflen, char *fmt, ...) */ #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) -int -vslprintf(buf, buflen, fmt, args) - char *buf; - int buflen; - char *fmt; - va_list args; -{ +int vslprintf(char *buf, int buflen, char *fmt, va_list args) { int c, i, n; int width, prec, fillch; int base, len, neg, quoted; @@ -431,9 +413,7 @@ vslprintf(buf, buflen, fmt, args) /* * vslp_printer - used in processing a %P format */ -static void -vslp_printer (void *arg, char *fmt, ...) -{ +static void vslp_printer(void *arg, char *fmt, ...) { int n; va_list pvar; struct buffer_info *bi; @@ -471,13 +451,8 @@ log_packet(p, len, prefix, level) * format_packet - make a readable representation of a packet, * calling `printer(arg, format, ...)' to output it. */ -static void -format_packet(p, len, printer, arg) - u_char *p; - int len; - void (*printer) (void *, char *, ...); - void *arg; -{ +static void format_packet(u_char *p, int len, + void (*printer) (void *, char *, ...), void *arg) { int i, n; u_short proto; struct protent *protp; @@ -635,23 +610,14 @@ void print_string(char *p, int len, void (*printer) (void *, char *, ...), void /* * logit - does the hard work for fatal et al. */ -static void -logit(level, fmt, args) - int level; - char *fmt; - va_list args; -{ +static void logit(int level, char *fmt, va_list args) { char buf[1024]; vslprintf(buf, sizeof(buf), fmt, args); log_write(level, buf); } -static void -log_write(level, buf) - int level; - char *buf; -{ +static void log_write(int level, char *buf) { PPPDEBUG(level, ("%s\n", buf) ); #if 0 if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { @@ -669,9 +635,7 @@ log_write(level, buf) /* * fatal - log an error message and die horribly. */ -void -fatal (char *fmt, ...) -{ +void fatal(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); @@ -687,9 +651,7 @@ fatal (char *fmt, ...) /* * error - log an error message. */ -void -error (char *fmt, ...) -{ +void error(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); @@ -703,9 +665,7 @@ error (char *fmt, ...) /* * warn - log a warning message. */ -void -warn (char *fmt, ...) -{ +void warn(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); @@ -716,9 +676,7 @@ warn (char *fmt, ...) /* * notice - log a notice-level message. */ -void -notice (char *fmt, ...) -{ +void notice(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); @@ -729,9 +687,7 @@ notice (char *fmt, ...) /* * info - log an informational message. */ -void -info (char *fmt, ...) -{ +void info(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); @@ -742,9 +698,7 @@ info (char *fmt, ...) /* * dbglog - log a debug message. */ -void -dbglog (char *fmt, ...) -{ +void dbglog(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); @@ -757,9 +711,7 @@ dbglog (char *fmt, ...) * dump_packet - print out a packet in readable form if it is interesting. * Assumes len >= PPP_HDRLEN. */ -void -dump_packet(const char *tag, unsigned char *p, int len) -{ +void dump_packet(const char *tag, unsigned char *p, int len) { int proto; /* From be2d3b5886b3ee518119e6acb3fdbb932bcfcbb4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 17 Jun 2012 02:33:47 +0200 Subject: [PATCH 179/320] moved back temporarily moved structure definitions from various headers to ppp.h during unit to ppp_pcb transition --- src/netif/ppp/chap-new.h | 31 +++++++ src/netif/ppp/eap.h | 54 ++++++++++++ src/netif/ppp/fsm.h | 4 +- src/netif/ppp/ipcp.c | 2 +- src/netif/ppp/lcp.c | 2 +- src/netif/ppp/lcp.h | 50 +++++++++++ src/netif/ppp/ppp.c | 2 +- src/netif/ppp/ppp.h | 181 ++++++--------------------------------- src/netif/ppp/upap.h | 22 +++++ 9 files changed, 187 insertions(+), 161 deletions(-) diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h index c85a91af..98f4c54d 100644 --- a/src/netif/ppp/chap-new.h +++ b/src/netif/ppp/chap-new.h @@ -31,6 +31,11 @@ #include "lwip/opt.h" #if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#ifndef CHAP_H +#define CHAP_H + +#include "ppp.h" + /* * CHAP packets begin with a standard header with code, id, len (2 bytes). */ @@ -135,6 +140,31 @@ struct chap_digest_type { struct chap_digest_type *next; }; +/* + * Each interface is described by chap structure. + */ +#if CHAP_SUPPORT +typedef struct chap_client_state { + int flags; + char *name; + struct chap_digest_type *digest; + unsigned char priv[64]; /* private area for digest's use */ +} chap_client_state; + +#if PPP_SERVER +static struct chap_server_state { + int flags; + int id; + char *name; + struct chap_digest_type *digest; + int challenge_xmits; + int challenge_pktlen; + unsigned char challenge[CHAL_MAX_PKTLEN]; + char message[256]; +} chap_server_state; +#endif /* PPP_SERVER */ +#endif /* CHAP_SUPPORT */ + #if 0 /* UNUSED */ /* Hook for a plugin to validate CHAP challenge */ extern int (*chap_verify_hook)(char *name, char *ourname, int id, @@ -157,4 +187,5 @@ extern void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code); /* Represents the CHAP protocol to the main pppd code */ extern struct protent chap_protent; +#endif /* CHAP_H */ #endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/netif/ppp/eap.h b/src/netif/ppp/eap.h index 1f2fc5bf..5ee6daf4 100644 --- a/src/netif/ppp/eap.h +++ b/src/netif/ppp/eap.h @@ -26,6 +26,8 @@ #ifndef PPP_EAP_H #define PPP_EAP_H +#include "ppp.h" + #ifdef __cplusplus extern "C" { #endif @@ -92,6 +94,58 @@ extern "C" { (pcb)->eap.es_server.ea_state <= eapMD5Chall) #endif /* PPP_SERVER */ +/* + * Complete EAP state for one PPP session. + */ +enum eap_state_code { + eapInitial = 0, /* No EAP authentication yet requested */ + eapPending, /* Waiting for LCP (no timer) */ + eapClosed, /* Authentication not in use */ + eapListen, /* Client ready (and timer running) */ + eapIdentify, /* EAP Identify sent */ + eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ + eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ + eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ + eapMD5Chall, /* Sent MD5-Challenge */ + eapOpen, /* Completed authentication */ + eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ + eapBadAuth /* Failed authentication */ +}; + +struct eap_auth { + char *ea_name; /* Our name */ + char *ea_peer; /* Peer's name */ + void *ea_session; /* Authentication library linkage */ + u_char *ea_skey; /* Shared encryption key */ + int ea_timeout; /* Time to wait (for retransmit/fail) */ + int ea_maxrequests; /* Max Requests allowed */ + u_short ea_namelen; /* Length of our name */ + u_short ea_peerlen; /* Length of peer's name */ + enum eap_state_code ea_state; + u_char ea_id; /* Current id */ + u_char ea_requests; /* Number of Requests sent/received */ + u_char ea_responses; /* Number of Responses */ + u_char ea_type; /* One of EAPT_* */ + u_int32_t ea_keyflags; /* SRP shared key usage flags */ +}; + +#ifndef EAP_MAX_CHALLENGE_LENGTH +#define EAP_MAX_CHALLENGE_LENGTH 24 +#endif +typedef struct eap_state { + struct eap_auth es_client; /* Client (authenticatee) data */ +#if PPP_SERVER + struct eap_auth es_server; /* Server (authenticator) data */ +#endif /* PPP_SERVER */ + int es_savedtime; /* Saved timeout */ + int es_rechallenge; /* EAP rechallenge interval */ + int es_lwrechallenge; /* SRP lightweight rechallenge inter */ + bool es_usepseudo; /* Use SRP Pseudonym if offered one */ + int es_usedpseudo; /* Set if we already sent PN */ + int es_challen; /* Length of challenge string */ + u_char es_challenge[EAP_MAX_CHALLENGE_LENGTH]; +} eap_state; + /* * Timeouts. */ diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index d02301ab..afa33edf 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -48,6 +48,8 @@ #ifndef FSM_H #define FSM_H +#include "ppp.h" + /* * Packet header = Code, id, length. */ @@ -70,7 +72,7 @@ * Each FSM is described by an fsm structure and fsm callbacks. */ typedef struct fsm { - void *pcb; /* PPP Interface */ /* FIXME: try to use ppp_pcb here */ + ppp_pcb *pcb; /* PPP Interface */ int protocol; /* Data Link Layer Protocol field value */ int state; /* State */ int flags; /* Contains option bits */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 1f09cf5d..9445c63e 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -597,7 +597,7 @@ static void ipcp_init(ppp_pcb *pcb) { ipcp_options *wo = &pcb->ipcp_wantoptions; ipcp_options *ao = &pcb->ipcp_allowoptions; - f->pcb = (void*)pcb; + f->pcb = pcb; f->protocol = PPP_IPCP; f->callbacks = &ipcp_callbacks; fsm_init(f); diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index f8e51e35..1b05cb87 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -364,7 +364,7 @@ static void lcp_init(ppp_pcb *pcb) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; - f->pcb = (void*)pcb; + f->pcb = pcb; f->protocol = PPP_LCP; f->callbacks = &lcp_callbacks; diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index 372cb155..3cfc1175 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -94,6 +94,56 @@ #define MINMRU 128 /* No MRUs below this */ #define MAXMRU 16384 /* Normally limit MRU to this */ +/* An endpoint discriminator, used with multilink. */ +#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ +struct epdisc { + unsigned char class; + unsigned char length; + unsigned char value[MAX_ENDP_LEN]; +}; + +/* + * 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? */ +#if PAP_SUPPORT + bool neg_upap; /* Ask for UPAP authentication? */ +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + bool neg_chap; /* Ask for CHAP authentication? */ +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + bool neg_eap; /* Ask for EAP authentication? */ +#endif /* EAP_SUPPORT */ + bool neg_magicnumber; /* Ask for magic number? */ + bool neg_pcompression; /* HDLC Protocol Field Compression? */ + bool neg_accompression; /* HDLC Address/Control Field Compression? */ +#if LQR_SUPPORT + bool neg_lqr; /* Negotiate use of Link Quality Reports */ +#endif /* LQR_SUPPORT */ + bool neg_cbcp; /* Negotiate use of CBCP */ + bool neg_mrru; /* negotiate multilink MRRU */ + bool neg_ssnhf; /* negotiate short sequence numbers */ + bool neg_endpoint; /* negotiate endpoint discriminator */ + int mru; /* Value of MRU */ + int mrru; /* Value of MRRU, and multilink enable */ +#if CHAP_SUPPORT + u_char chap_mdtype; /* which MD types (hashing algorithm) */ +#endif /* CHAP_SUPPORT */ + u_int32_t asyncmap; /* Value of async map */ + u_int32_t magicnumber; + int numloops; /* Number of loops during magic number neg. */ +#if LQR_SUPPORT + u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ +#endif /* LQR_SUPPORT */ + struct epdisc endpoint; /* endpoint discriminator */ +} lcp_options; + void lcp_open(ppp_pcb *pcb); void lcp_close(ppp_pcb *pcb, char *reason); void lcp_lowerup(ppp_pcb *pcb); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 58b4434f..58507306 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -332,7 +332,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s pcb->fd = fd; - pcb->rx.pcb = (void*)pcb; + pcb->rx.pcb = pcb; pcb->rx.fd = fd; #if VJ_SUPPORT diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index fda50588..eebe58d8 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -88,10 +88,6 @@ typedef unsigned char u_char; typedef unsigned char bool; #endif -#include "fsm.h" -#include "ipcp.h" - - /************************* *** PUBLIC DEFINITIONS *** *************************/ @@ -129,6 +125,27 @@ typedef unsigned char bool; *** PUBLIC DATA TYPES *** ************************/ +/* + * Other headers require ppp_pcb definition for prototypes, but ppp_pcb + * require some structure definition from other headers as well, we are + * fixing the dependency loop here by declaring the ppp_pcb type then + * by including headers containing necessary struct definition for ppp_pcb + */ +typedef struct ppp_pcb_s ppp_pcb; + +#include "fsm.h" +#include "lcp.h" +#include "ipcp.h" +#if PAP_SUPPORT +#include "upap.h" +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#include "chap-new.h" +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +#include "eap.h" +#endif /* EAP_SUPPORT */ + /* * PPP configuration. */ @@ -217,7 +234,7 @@ typedef enum { */ typedef struct ppp_pcb_rx_s { /** ppp descriptor */ - void *pcb; + ppp_pcb *pcb; /** the rx file descriptor */ sio_fd_t fd; /** receive buffer - encoded data is stored here */ @@ -236,160 +253,10 @@ typedef struct ppp_pcb_rx_s { } ppp_pcb_rx; #endif /* PPPOS_SUPPORT */ -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class; - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; - -/* - * 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? */ -#if PAP_SUPPORT - bool neg_upap; /* Ask for UPAP authentication? */ -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - bool neg_chap; /* Ask for CHAP authentication? */ -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - bool neg_eap; /* Ask for EAP authentication? */ -#endif /* EAP_SUPPORT */ - bool neg_magicnumber; /* Ask for magic number? */ - bool neg_pcompression; /* HDLC Protocol Field Compression? */ - bool neg_accompression; /* HDLC Address/Control Field Compression? */ -#if LQR_SUPPORT - bool neg_lqr; /* Negotiate use of Link Quality Reports */ -#endif /* LQR_SUPPORT */ - bool neg_cbcp; /* Negotiate use of CBCP */ - bool neg_mrru; /* negotiate multilink MRRU */ - bool neg_ssnhf; /* negotiate short sequence numbers */ - bool neg_endpoint; /* negotiate endpoint discriminator */ - int mru; /* Value of MRU */ - int mrru; /* Value of MRRU, and multilink enable */ -#if CHAP_SUPPORT - u_char chap_mdtype; /* which MD types (hashing algorithm) */ -#endif /* CHAP_SUPPORT */ - u_int32_t asyncmap; /* Value of async map */ - u_int32_t magicnumber; - int numloops; /* Number of loops during magic number neg. */ -#if LQR_SUPPORT - u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ -#endif /* LQR_SUPPORT */ - struct epdisc endpoint; /* endpoint discriminator */ -} lcp_options; - -/* - * Each interface is described by upap structure. - */ -#if PAP_SUPPORT -typedef struct upap_state { - char *us_user; /* User */ - int us_userlen; /* User length */ - char *us_passwd; /* Password */ - int us_passwdlen; /* Password length */ - int us_clientstate; /* Client state */ -#if PPP_SERVER - int us_serverstate; /* Server state */ -#endif /* PPP_SERVER */ - 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; -#endif /* PAP_SUPPORT */ - -/* - * Each interface is described by chap structure. - */ -#if CHAP_SUPPORT -typedef struct chap_client_state { - int flags; - char *name; - struct chap_digest_type *digest; - unsigned char priv[64]; /* private area for digest's use */ -} chap_client_state; - -#if PPP_SERVER -static struct chap_server_state { - int flags; - int id; - char *name; - struct chap_digest_type *digest; - int challenge_xmits; - int challenge_pktlen; - unsigned char challenge[CHAL_MAX_PKTLEN]; - char message[256]; -} chap_server_state; -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPORT */ - -#if EAP_SUPPORT -/* - * Complete EAP state for one PPP session. - */ -enum eap_state_code { - eapInitial = 0, /* No EAP authentication yet requested */ - eapPending, /* Waiting for LCP (no timer) */ - eapClosed, /* Authentication not in use */ - eapListen, /* Client ready (and timer running) */ - eapIdentify, /* EAP Identify sent */ - eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ - eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ - eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ - eapMD5Chall, /* Sent MD5-Challenge */ - eapOpen, /* Completed authentication */ - eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ - eapBadAuth /* Failed authentication */ -}; - -struct eap_auth { - char *ea_name; /* Our name */ - char *ea_peer; /* Peer's name */ - void *ea_session; /* Authentication library linkage */ - u_char *ea_skey; /* Shared encryption key */ - int ea_timeout; /* Time to wait (for retransmit/fail) */ - int ea_maxrequests; /* Max Requests allowed */ - u_short ea_namelen; /* Length of our name */ - u_short ea_peerlen; /* Length of peer's name */ - enum eap_state_code ea_state; - u_char ea_id; /* Current id */ - u_char ea_requests; /* Number of Requests sent/received */ - u_char ea_responses; /* Number of Responses */ - u_char ea_type; /* One of EAPT_* */ - u_int32_t ea_keyflags; /* SRP shared key usage flags */ -}; - -#ifndef EAP_MAX_CHALLENGE_LENGTH -#define EAP_MAX_CHALLENGE_LENGTH 24 -#endif -typedef struct eap_state { - struct eap_auth es_client; /* Client (authenticatee) data */ -#if PPP_SERVER - struct eap_auth es_server; /* Server (authenticator) data */ -#endif /* PPP_SERVER */ - int es_savedtime; /* Saved timeout */ - int es_rechallenge; /* EAP rechallenge interval */ - int es_lwrechallenge; /* SRP lightweight rechallenge inter */ - bool es_usepseudo; /* Use SRP Pseudonym if offered one */ - int es_usedpseudo; /* Set if we already sent PN */ - int es_challen; /* Length of challenge string */ - u_char es_challenge[EAP_MAX_CHALLENGE_LENGTH]; -} eap_state; -#endif /* EAP_SUPPORT */ - /* * PPP interface control block. */ -typedef struct ppp_pcb_s { +struct ppp_pcb_s { ppp_settings settings; u8_t num; /* Interface number - only useful for debugging */ #if PPPOS_SUPPORT @@ -486,7 +353,7 @@ typedef struct ppp_pcb_s { */ u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ -} ppp_pcb; +}; /************************ *** PUBLIC FUNCTIONS *** diff --git a/src/netif/ppp/upap.h b/src/netif/ppp/upap.h index 18aaa6d1..27209265 100644 --- a/src/netif/ppp/upap.h +++ b/src/netif/ppp/upap.h @@ -93,6 +93,28 @@ #endif /* moved to opt.h */ #define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +/* + * Each interface is described by upap structure. + */ +#if PAP_SUPPORT +typedef struct upap_state { + char *us_user; /* User */ + int us_userlen; /* User length */ + char *us_passwd; /* Password */ + int us_passwdlen; /* Password length */ + int us_clientstate; /* Client state */ +#if PPP_SERVER + int us_serverstate; /* Server state */ +#endif /* PPP_SERVER */ + 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; +#endif /* PAP_SUPPORT */ + + void upap_authwithpeer(ppp_pcb *pcb, char *user, char *password); #if PPP_SERVER void upap_authpeer(ppp_pcb *pcb); From 8641b8a36e0d6e4b8ebc8d81e7b41a806b45d97a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 17 Jun 2012 23:48:55 +0200 Subject: [PATCH 180/320] PPP_PCB are now allocated using memp_alloc() --- src/include/lwip/memp_std.h | 4 ++ src/include/lwip/opt.h | 15 ++++---- src/netif/ppp/chap-new.c | 5 +-- src/netif/ppp/ppp.c | 75 +++++++------------------------------ src/netif/ppp/ppp.h | 1 - src/netif/ppp/ppp_impl.h | 1 - src/netif/ppp/upap.c | 8 +++- 7 files changed, 33 insertions(+), 76 deletions(-) diff --git a/src/include/lwip/memp_std.h b/src/include/lwip/memp_std.h index 592a2824..be547cfa 100644 --- a/src/include/lwip/memp_std.h +++ b/src/include/lwip/memp_std.h @@ -87,6 +87,10 @@ LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, #if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") #endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +#if PPP_SUPPORT +LWIP_MEMPOOL(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB") +#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ #if PPP_SUPPORT && PPPOE_SUPPORT LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") #endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index fcda2e3e..66bf9af2 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -399,6 +399,14 @@ #define MEMP_NUM_LOCALHOSTLIST 1 #endif +/** + * MEMP_NUM_PPP_PCB: the number of simultaneously active PPP + * connections (requires the PPP_SUPPORT option) + */ +#ifndef MEMP_NUM_PPP_PCB +#define MEMP_NUM_PPP_PCB 1 +#endif + /** * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE * interfaces (only used with PPPOE_SUPPORT==1) @@ -1695,13 +1703,6 @@ #if PPP_SUPPORT -/** - * NUM_PPP: Max PPP sessions. - */ -#ifndef NUM_PPP -#define NUM_PPP 1 -#endif - /** * PAP_SUPPORT==1: Support PAP. */ diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index e60f2a34..b50c86b6 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -418,7 +418,6 @@ static void chap_respond(ppp_pcb *pcb, int id, unsigned char response[RESP_MAX_PKTLEN]; char rname[MAXNAMELEN+1]; char secret[MAXSECRETLEN+1]; - ppp_pcb *pc = &ppp_pcb_list[0]; if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) return; /* not ready */ @@ -431,8 +430,8 @@ static void chap_respond(ppp_pcb *pcb, int id, slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); /* Microsoft doesn't send their name back in the PPP packet */ - if (pc->settings.explicit_remote || (pc->settings.remote_name[0] != 0 && rname[0] == 0)) - strlcpy(rname, pc->settings.remote_name, sizeof(rname)); + if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0)) + strlcpy(rname, pcb->settings.remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ if (!get_secret(pcb, pcb->chap_client.name, rname, secret, &secret_len, 0)) { diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 58507306..2757087b 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -204,6 +204,7 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p); static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n); #endif /* PPPOE_SUPPORT */ +static void ppp_destroy(ppp_pcb *pcb); /***********************************/ /*** PUBLIC FUNCTION DEFINITIONS ***/ @@ -223,24 +224,20 @@ int ppp_init(void) { /* Create a new PPP session. */ ppp_pcb *ppp_new(u8_t num) { - int i, pd; + int i; ppp_pcb *pcb; struct protent *protp; - /* Find a free PPP session descriptor. */ - for (pd = 0; pd < NUM_PPP && ppp_pcb_list[pd].open_flag != 0; pd++); - if (pd >= NUM_PPP) + pcb = (ppp_pcb*)memp_malloc(MEMP_PPP_PCB); + if (pcb == NULL) return NULL; - pcb = &ppp_pcb_list[pd]; - #if PPP_STATS_SUPPORT link_stats_valid = 0; #endif /* PPP_STATS_SUPPORT */ memset(pcb, 0, sizeof(ppp_pcb)); pcb->num = num; - pcb->open_flag = 1; pcb->status = EXIT_OK; pcb->lcp_loopbackfail = DEFLOOPBACKFAIL; new_phase(pcb, PHASE_INITIALIZE); @@ -408,7 +405,6 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic ao->neg_accompression = 0; if(pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { - pcb->open_flag = 0; return PPPERR_OPEN; } @@ -795,8 +791,7 @@ static void ppp_receive_wakeup(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_receive_wakeup: unit %d\n", pcb->num)); - if (pcb->open_flag != 0) - sio_read_abort(pcb->fd); + sio_read_abort(pcb->fd); } #endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ @@ -926,7 +921,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i /* Validate parameters. */ /* We let any protocol value go through - it can't hurt us * and the peer will just drop it if it's not accepting it. */ - if (!pcb->open_flag || !pb) { + if (!pcb || !pb) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad params prot=%d pb=%p\n", pcb->num, PPP_IP, (void*)pb)); LINK_STATS_INC(link.opterr); @@ -1626,9 +1621,9 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { ppp_hup(pcb); ppp_stop(pcb); pppoe_destroy(&pcb->netif); - pcb->open_flag = 0; if(pcb->link_status_cb) pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : pppoe_err_code, NULL); + ppp_destroy(pcb); } #endif /* PPPOE_SUPPORT */ @@ -1658,13 +1653,17 @@ void ppp_link_terminated(ppp_pcb *pcb) { if (pcb->link_status_cb) { pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, NULL); } - - pcb->open_flag = 0; + ppp_destroy(pcb); #endif /* PPPOS_SUPPORT */ } PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: finished.\n")); } +static void ppp_destroy(ppp_pcb *pcb) { + + PPPDEBUG(LOG_DEBUG, ("ppp_destroy: unit %d\n", pcb->num)); + memp_free(MEMP_PPP_PCB, pcb); +} #if LWIP_NETIF_STATUS_CALLBACK /** Set the status callback of a PPP's netif @@ -1786,11 +1785,6 @@ int ppp_recv_config(ppp_pcb *pcb, int mru, u_int32_t accm, int pcomp, int accomp int sifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask) { - if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sifaddr[%d]: bad params\n", pcb->num)); - return 0; - } - SMEMCPY(&pcb->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); SMEMCPY(&pcb->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); SMEMCPY(&pcb->addrs.netmask, &net_mask, sizeof(net_mask)); @@ -1808,11 +1802,6 @@ int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr) { LWIP_UNUSED_ARG(our_adr); LWIP_UNUSED_ARG(his_adr); - if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("cifaddr[%d]: bad params\n", pcb->num)); - return 0; - } - IP4_ADDR(&pcb->addrs.our_ipaddr, 0,0,0,0); IP4_ADDR(&pcb->addrs.his_ipaddr, 0,0,0,0); IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); @@ -1825,11 +1814,6 @@ int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr) { */ int sdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { - if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sdns[%d]: bad params\n", pcb->num)); - return 0; - } - SMEMCPY(&pcb->addrs.dns1, &ns1, sizeof(ns1)); SMEMCPY(&pcb->addrs.dns2, &ns2, sizeof(ns2)); return 1; @@ -1845,11 +1829,6 @@ int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { LWIP_UNUSED_ARG(ns1); LWIP_UNUSED_ARG(ns2); - if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("cdns[%d]: bad params\n", pcb->num)); - return 0; - } - IP4_ADDR(&pcb->addrs.dns1, 0,0,0,0); IP4_ADDR(&pcb->addrs.dns2, 0,0,0,0); return 1; @@ -1861,11 +1840,6 @@ int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { */ int sifup(ppp_pcb *pcb) { - if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad params\n", pcb->num)); - return 0; - } - netif_remove(&pcb->netif); if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, ip_input)) { @@ -1891,11 +1865,6 @@ int sifup(ppp_pcb *pcb) { */ int sifdown(ppp_pcb *pcb) { - if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad params\n", pcb->num)); - return 0; - } - pcb->if_up = 0; /* make sure the netif status callback is called */ netif_set_down(&pcb->netif); @@ -1922,10 +1891,6 @@ int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) { */ void netif_set_mtu(ppp_pcb *pcb, int mtu) { - /* Validate parameters. */ - if(!pcb->open_flag) - return; - pcb->mtu = mtu; } @@ -1934,10 +1899,6 @@ void netif_set_mtu(ppp_pcb *pcb, int mtu) { */ int netif_get_mtu(ppp_pcb *pcb) { - /* Validate parameters. */ - if(!pcb->open_flag) - return 0; - return pcb->mtu; } @@ -1959,11 +1920,6 @@ int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, bool rep LWIP_UNUSED_ARG(gateway); LWIP_UNUSED_ARG(replace); - if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("sifdefaultroute[%d]: bad params\n", pcb->num)); - return 0; - } - netif_set_default(&pcb->netif); return 1; } @@ -1977,11 +1933,6 @@ int cifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway) { LWIP_UNUSED_ARG(ouraddr); LWIP_UNUSED_ARG(gateway); - if(!pcb->open_flag) { - PPPDEBUG(LOG_WARNING, ("cifdefaultroute[%d]: bad params\n", pcb->num)); - return 0; - } - netif_set_default(NULL); return 1; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index eebe58d8..1593c63f 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -262,7 +262,6 @@ struct ppp_pcb_s { #if PPPOS_SUPPORT ppp_pcb_rx rx; #endif /* PPPOS_SUPPORT */ - char open_flag; /* True when in use. */ u8_t phase; /* where the link is at */ u8_t status; /* exit status */ #if PPPOE_SUPPORT diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 9e3e6950..53160c4a 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -371,7 +371,6 @@ struct pppd_stats { }; #endif /* PPP_STATS_SUPPORT */ -ppp_pcb ppp_pcb_list[NUM_PPP]; /* The PPP interface control blocks. */ /* PPP flow functions */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index f72ccd62..6417d422 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -579,7 +579,6 @@ static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, char *, . int mlen, ulen, wlen; char *user, *pwd, *msg; u_char *pstart; - ppp_pcb *pc = &ppp_pcb_list[0]; if (plen < UPAP_HEADERLEN) return 0; @@ -613,10 +612,15 @@ static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, char *, . printer(arg, " user="); print_string(user, ulen, printer, arg); printer(arg, " password="); - if (!pc->settings.hide_password) +/* FIXME: require ppp_pcb struct as printpkt() argument */ +#if 0 + if (!pcb->settings.hide_password) +#endif print_string(pwd, wlen, printer, arg); +#if 0 else printer(arg, ""); +#endif break; case UPAP_AUTHACK: case UPAP_AUTHNAK: From 22fad86453090e2944c8baf4a3a48b523ec9501e Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 18 Jun 2012 01:10:21 +0200 Subject: [PATCH 181/320] PAP is now using pbuf instead of pcb->outpacket_buf --- src/netif/ppp/ppp.c | 5 +++++ src/netif/ppp/ppp.h | 2 +- src/netif/ppp/ppp_impl.h | 1 + src/netif/ppp/upap.c | 20 +++++++++++++++----- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 2757087b..33e4d466 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1146,6 +1146,11 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) return PPPERR_PARAM; } +int ppp_write_pbuf(ppp_pcb *pcb, struct pbuf *p) { + ppp_write(pcb, p->payload, p->len); + pbuf_free(p); +} + /* * Write n characters to a ppp link. * RETURN: >= 0 Number of characters written diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 1593c63f..513b3f47 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -285,7 +285,7 @@ struct ppp_pcb_s { struct vjcompress vj_comp; /* Van Jacobson compression header. */ #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - struct netif netif; + struct netif netif; /* PPP interface */ struct ppp_addrs addrs; diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 53160c4a..23126cdf 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -377,6 +377,7 @@ struct pppd_stats { /* function called by pppoe.c */ void ppp_input(ppp_pcb *pcb, struct pbuf *pb); +int ppp_write_pbuf(ppp_pcb *pcb, struct pbuf *p); /* function called by all PPP subsystems to send packets */ int ppp_write(ppp_pcb *pcb, const u_char *s, int n); diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 6417d422..2df9ce3b 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -520,13 +520,17 @@ static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) { * upap_sauthreq - Send an Authenticate-Request. */ static void upap_sauthreq(ppp_pcb *pcb) { + struct pbuf *p; u_char *outp; int outlen; outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + pcb->upap.us_userlen + pcb->upap.us_passwdlen; - outp = pcb->outpacket_buf; - + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_PAP); PUTCHAR(UPAP_AUTHREQ, outp); @@ -538,7 +542,7 @@ static void upap_sauthreq(ppp_pcb *pcb) { PUTCHAR(pcb->upap.us_passwdlen, outp); MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen); - ppp_write(pcb, pcb->outpacket_buf, outlen + PPP_HDRLEN); + ppp_write_pbuf(pcb, p); TIMEOUT(upap_timeout, pcb, pcb->upap.us_timeouttime); ++pcb->upap.us_transmits; @@ -550,11 +554,16 @@ static void upap_sauthreq(ppp_pcb *pcb) { * upap_sresp - Send a response (ack or nak). */ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msglen) { + struct pbuf *p; u_char *outp; int outlen; outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - outp = pcb->outpacket_buf; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_PAP); PUTCHAR(code, outp); @@ -562,7 +571,8 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl PUTSHORT(outlen, outp); PUTCHAR(msglen, outp); MEMCPY(outp, msg, msglen); - ppp_write(pcb, pcb->outpacket_buf, outlen + PPP_HDRLEN); + + ppp_write_pbuf(pcb, p); } #endif /* UNUSED */ From 503162ec54bdcf769dbcc62344d8fcc5ba27cb27 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 18 Jun 2012 01:18:24 +0200 Subject: [PATCH 182/320] CHAP is now using pbuf instead of pcb->outpacket_buf --- src/netif/ppp/chap-new.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index b50c86b6..2d05d87d 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -280,7 +280,7 @@ static void chap_generate_challenge(ppp_pcb *pcb) { static void chap_handle_response(ppp_pcb *pcb, int id, unsigned char *pkt, int len) { int response_len, ok, mlen; - unsigned char *response, *p; + unsigned char *response, *outp; char *name = NULL; /* initialized to shut gcc up */ int (*verifier)(char *, char *, int, struct chap_digest_type *, unsigned char *, unsigned char *, char *, int); @@ -329,17 +329,22 @@ static void chap_handle_response(ppp_pcb *pcb, int id, return; /* send the response */ - p = pcb->outpacket_buf; - MAKEHEADER(p, PPP_CHAP); mlen = strlen(pcb->chap_server.message); len = CHAP_HDRLEN + mlen; - p[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; - p[1] = id; - p[2] = len >> 8; - p[3] = len; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; + MAKEHEADER(outp, PPP_CHAP); + + outp[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; + outp[1] = id; + outp[2] = len >> 8; + outp[3] = len; if (mlen > 0) - memcpy(p + CHAP_HDRLEN, pcb->chap_server.message, mlen); - ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + len); + memcpy(outp + CHAP_HDRLEN, pcb->chap_server.message, mlen); + ppp_write_pbuf(pcb, p); if (pcb->chap_server.flags & CHALLENGE_VALID) { pcb->chap_server.flags &= ~CHALLENGE_VALID; From 4a7f2ffc5e3f761bf2bf1f1493dd15ff3ce57af9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 18 Jun 2012 02:21:18 +0200 Subject: [PATCH 183/320] pcb->outpacket_buf replaced by pbuf everywhere it was used --- src/netif/ppp/chap-new.c | 1 + src/netif/ppp/eap.c | 92 +++++++++++++++++++++++++++++----------- src/netif/ppp/fsm.c | 31 +++++++++++--- src/netif/ppp/ppp.c | 1 + src/netif/ppp/ppp.h | 7 --- src/netif/ppp/ppp_impl.h | 2 - 6 files changed, 94 insertions(+), 40 deletions(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 2d05d87d..6701b2fe 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -281,6 +281,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, unsigned char *pkt, int len) { int response_len, ok, mlen; unsigned char *response, *outp; + struct pbuf *p; char *name = NULL; /* initialized to shut gcc up */ int (*verifier)(char *, char *, int, struct chap_digest_type *, unsigned char *, unsigned char *, char *, int); diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 7fb3ed64..0b1088ee 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -260,10 +260,15 @@ eap_send_failure(esp) eap_state *esp; { ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; + struct pbuf *p; u_char *outp; - outp = pcb->outpacket_buf; - + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; + MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_FAILURE, outp); @@ -271,7 +276,7 @@ eap_state *esp; PUTCHAR(pcb->eap.es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_write(pcb, pcb->outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); + ppp_write_pbuf(pcb, p); pcb->eap.es_server.ea_state = eapBadAuth; auth_peer_fail(pcb, PPP_EAP); @@ -286,9 +291,14 @@ eap_send_success(esp) eap_state *esp; { ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; + struct pbuf *p; u_char *outp; - outp = pcb->outpacket_buf; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_EAP); @@ -297,7 +307,7 @@ eap_state *esp; PUTCHAR(pcb->eap.es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); + ppp_write_pbuf(pcb, p); auth_peer_success(pcb, PPP_EAP, 0, pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen); @@ -642,6 +652,7 @@ eap_send_request(esp) eap_state *esp; { ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; + struct pbuf *p; u_char *outp; u_char *lenloc; u_char *ptr; @@ -682,7 +693,12 @@ eap_state *esp; return; } - outp = pcb->outpacket_buf; + /* FIXME: improve buffer size */ + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_MRU+PPP_HDRLEN), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_EAP); @@ -858,10 +874,11 @@ eap_state *esp; return; } - outlen = (outp - pcb->outpacket_buf) - PPP_HDRLEN; + outlen = (outp - p->payload) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); - ppp_write(pcb, pcb->outpacket_buf, outlen + PPP_HDRLEN); + pbuf_realloc(p, outlen + PPP_HDRLEN); + ppp_write_pbuf(pcb, p); pcb->eap.es_server.ea_requests++; @@ -1034,42 +1051,52 @@ static void eap_protrej(ppp_pcb *pcb) { * Format and send a regular EAP Response message. */ static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, u_char *str, int lenstr) { + struct pbuf *p; u_char *outp; int msglen; - outp = pcb->outpacket_buf; + msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); pcb->eap.es_client.ea_id = id; - msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; PUTSHORT(msglen, outp); PUTCHAR(typenum, outp); if (lenstr > 0) { MEMCPY(outp, str, lenstr); } - ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); + ppp_write_pbuf(pcb, p); } /* * Format and send an MD5-Challenge EAP Response message. */ static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, char *name, int namelen) { + struct pbuf *p; u_char *outp; int msglen; - outp = pcb->outpacket_buf; + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + + namelen; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); pcb->eap.es_client.ea_id = id; - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + - namelen; PUTSHORT(msglen, outp); PUTCHAR(EAPT_MD5CHAP, outp); PUTCHAR(MD5_SIGNATURE_SIZE, outp); @@ -1079,7 +1106,7 @@ static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, char *name, MEMCPY(outp, name, namelen); } - ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); + ppp_write_pbuf(pcb, p); } #ifdef USE_SRP @@ -1095,17 +1122,22 @@ u_char *str; int lenstr; { ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; + struct pbuf *p; u_char *outp; int msglen; - outp = pcb->outpacket_buf; + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); pcb->eap.es_client.ea_id = id; - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; PUTSHORT(msglen, outp); PUTCHAR(EAPT_SRP, outp); PUTCHAR(subtypenum, outp); @@ -1113,7 +1145,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); + ppp_write_pbuf(pcb, p); } /* @@ -1127,45 +1159,55 @@ u_int32_t flags; u_char *str; { ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; + struct pbuf *p; u_char *outp; int msglen; - outp = pcb->outpacket_buf; + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) + + SHA_DIGESTSIZE; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); pcb->eap.es_client.ea_id = id; - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) + - SHA_DIGESTSIZE; PUTSHORT(msglen, outp); PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_CVALIDATOR, outp); PUTLONG(flags, outp); MEMCPY(outp, str, SHA_DIGESTSIZE); - ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); + ppp_write_pbuf(pcb, p); } #endif /* USE_SRP */ static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { + struct pbuf *p; u_char *outp; int msglen; - outp = pcb->outpacket_buf; + msglen = EAP_HEADERLEN + 2 * sizeof (u_char); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); pcb->eap.es_client.ea_id = id; - msglen = EAP_HEADERLEN + 2 * sizeof (u_char); PUTSHORT(msglen, outp); PUTCHAR(EAPT_NAK, outp); PUTCHAR(type, outp); - ppp_write(pcb, pcb->outpacket_buf, PPP_HDRLEN + msglen); + ppp_write_pbuf(pcb, p); } #ifdef USE_SRP diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index fe5354c9..bde8965b 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -686,6 +686,7 @@ void fsm_protreject(fsm *f) { */ static void fsm_sconfreq(fsm *f, int retransmit) { ppp_pcb *pcb = f->pcb; + struct pbuf *p; u_char *outp; int cilen; @@ -705,10 +706,15 @@ static void fsm_sconfreq(fsm *f, int retransmit) { f->seen_ack = 0; + /* FIXME: improve buffer size */ + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_MRU+PPP_HDRLEN), PBUF_RAM); + if(NULL == p) + return; + /* * Make up the request packet */ - outp = pcb->outpacket_buf + PPP_HDRLEN + HEADERLEN; + outp = (u_char*)p->payload + PPP_HDRLEN + HEADERLEN; if( f->callbacks->cilen && f->callbacks->addci ){ cilen = (*f->callbacks->cilen)(f); if( cilen > pcb->peer_mru - HEADERLEN ) @@ -719,7 +725,14 @@ static void fsm_sconfreq(fsm *f, int retransmit) { cilen = 0; /* send the request to our peer */ - fsm_sdata(f, CONFREQ, f->reqid, outp, cilen); + outp = p->payload; + MAKEHEADER(outp, f->protocol); + PUTCHAR(CONFREQ, outp); + PUTCHAR(f->reqid, outp); + PUTSHORT(cilen + HEADERLEN, outp); + + pbuf_realloc(p, cilen + HEADERLEN + PPP_HDRLEN); + ppp_write_pbuf(pcb, p); /* start the retransmit timer */ --f->retransmits; @@ -734,21 +747,27 @@ static void fsm_sconfreq(fsm *f, int retransmit) { */ void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { ppp_pcb *pcb = f->pcb; + struct pbuf *p; u_char *outp; int outlen; /* Adjust length to be smaller than MTU */ - outp = pcb->outpacket_buf; if (datalen > pcb->peer_mru - HEADERLEN) datalen = pcb->peer_mru - HEADERLEN; - if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) - MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen); outlen = datalen + HEADERLEN; + + p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PBUF_RAM); + if(NULL == p) + return; + + outp = p->payload; +/* if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) -- was only for fsm_sconfreq() */ + MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen); MAKEHEADER(outp, f->protocol); PUTCHAR(code, outp); PUTCHAR(id, outp); PUTSHORT(outlen, outp); - ppp_write(pcb, pcb->outpacket_buf, outlen + PPP_HDRLEN); + ppp_write_pbuf(pcb, p); } #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 33e4d466..a1d41d6a 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1146,6 +1146,7 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) return PPPERR_PARAM; } +/* FIXME: improve that */ int ppp_write_pbuf(ppp_pcb *pcb, struct pbuf *p) { ppp_write(pcb, p->payload, p->len); pbuf_free(p); diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 513b3f47..ffd94ef1 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -345,13 +345,6 @@ struct ppp_pcb_s { int ipcp_is_open; /* haven't called np_finished() */ int ipcp_is_up; /* have called np_up() */ bool ask_for_local; /* request our address from peer */ - - /* - * Buffers for outgoing packets. This must be accessed only from the appropriate - * PPP task so that it doesn't need to be protected to avoid collisions. - */ - u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ - }; /************************ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 23126cdf..0a487f13 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -235,8 +235,6 @@ struct ppp_idle { /* * Global variables. */ -extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ - #ifdef HAVE_MULTILINK extern bool multilink; /* enable multilink operation */ extern bool doing_multilink; From 1b586b69bc90624bda0f280806027489ea3cfd76 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 18 Jun 2012 15:07:48 +0200 Subject: [PATCH 184/320] do not allocated pbuf of more than pcb->peer_mru instead of PPP_MRU, to save some memory --- src/netif/ppp/eap.c | 2 +- src/netif/ppp/fsm.c | 2 +- src/netif/ppp/ppp.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 0b1088ee..78faf0c7 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -694,7 +694,7 @@ eap_state *esp; } /* FIXME: improve buffer size */ - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_MRU+PPP_HDRLEN), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->peer_mru+PPP_HDRLEN), PBUF_RAM); if(NULL == p) return; diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index bde8965b..ad524a37 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -707,7 +707,7 @@ static void fsm_sconfreq(fsm *f, int retransmit) { f->seen_ack = 0; /* FIXME: improve buffer size */ - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_MRU+PPP_HDRLEN), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->peer_mru+PPP_HDRLEN), PBUF_RAM); if(NULL == p) return; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index ffd94ef1..48cd8d9d 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -318,7 +318,7 @@ struct ppp_pcb_s { eap_state eap; #endif /* EAP_SUPPORT */ - int peer_mru; /* currently negotiated peer MRU (per unit) */ + int peer_mru; /* currently negotiated peer MRU */ fsm lcp_fsm; /* LCP fsm structure */ lcp_options lcp_wantoptions; /* Options that we want to request */ From a44b56dc61a288ea71c9458bb3ad594a37e6b086 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 15:36:53 +0200 Subject: [PATCH 185/320] pcb->nak_buffer replaced with a pbuf --- src/netif/ppp/lcp.c | 99 ++++++++++++++++++++++++--------------------- src/netif/ppp/ppp.h | 2 - 2 files changed, 52 insertions(+), 49 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 1b05cb87..fc74f1bd 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1751,7 +1751,8 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { 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 */ + struct pbuf *nakp; /* Nak buffer */ + u_char *nakoutp; /* Pointer to next char in Nak frame */ int l = *lenp; /* Length left */ /* @@ -1763,7 +1764,10 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { * Process all his options. */ next = inp; - nakp = pcb->nak_buffer; + nakp = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->peer_mru), PBUF_RAM); + if(NULL == nakp) + return 0; + nakoutp = nakp->payload; rejp = inp; while (l) { orc = CONFACK; /* Assume success */ @@ -1799,9 +1803,9 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { */ if (cishort < MINMRU) { orc = CONFNAK; /* Nak CI */ - PUTCHAR(CI_MRU, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(MINMRU, nakp); /* Give him a hint */ + PUTCHAR(CI_MRU, nakoutp); + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(MINMRU, nakoutp); /* Give him a hint */ break; } ho->neg_mru = 1; /* Remember he sent MRU */ @@ -1822,9 +1826,9 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { */ if ((ao->asyncmap & ~cilong) != 0) { orc = CONFNAK; - PUTCHAR(CI_ASYNCMAP, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(ao->asyncmap | cilong, nakp); + PUTCHAR(CI_ASYNCMAP, nakoutp); + PUTCHAR(CILEN_LONG, nakoutp); + PUTLONG(ao->asyncmap | cilong, nakoutp); break; } ho->neg_asyncmap = 1; @@ -1881,17 +1885,17 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { } if (!ao->neg_upap) { /* we don't want to do PAP */ orc = CONFNAK; /* NAK it and suggest CHAP or EAP */ - PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CI_AUTHTYPE, nakoutp); #if EAP_SUPPORT if (ao->neg_eap) { - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_EAP, nakp); + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(PPP_EAP, nakoutp); } else { #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); + PUTCHAR(CILEN_CHAP, nakoutp); + PUTSHORT(PPP_CHAP, nakoutp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); #endif /* CHAP_SUPPORT */ #if EAP_SUPPORT } @@ -1919,16 +1923,16 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { } if (!ao->neg_chap) { /* we don't want to do CHAP */ orc = CONFNAK; /* NAK it and suggest EAP or PAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_SHORT, nakp); + PUTCHAR(CI_AUTHTYPE, nakoutp); + PUTCHAR(CILEN_SHORT, nakoutp); #if EAP_SUPPORT if (ao->neg_eap) { - PUTSHORT(PPP_EAP, nakp); + PUTSHORT(PPP_EAP, nakoutp); } else #endif /* EAP_SUPPORT */ #if PAP_SUPPORT if(1) { - PUTSHORT(PPP_PAP, nakp); + PUTSHORT(PPP_PAP, nakoutp); } else #endif /* PAP_SUPPORT */ @@ -1942,10 +1946,10 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { * suggest something else. */ orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); + PUTCHAR(CI_AUTHTYPE, nakoutp); + PUTCHAR(CILEN_CHAP, nakoutp); + PUTSHORT(PPP_CHAP, nakoutp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); break; } ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */ @@ -1970,18 +1974,18 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { } if (!ao->neg_eap) { /* we don't want to do EAP */ orc = CONFNAK; /* NAK it and suggest CHAP or PAP */ - PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CI_AUTHTYPE, nakoutp); #if CHAP_SUPPORT if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); + PUTCHAR(CILEN_CHAP, nakoutp); + PUTSHORT(PPP_CHAP, nakoutp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); } else #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if(1) { - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(PPP_PAP, nakoutp); } else #endif /* PAP_SUPPORT */ {} @@ -1999,25 +2003,25 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { * ao->neg_eap.) */ orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CI_AUTHTYPE, nakoutp); #if EAP_SUPPORT if (ao->neg_eap) { - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_EAP, nakp); + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(PPP_EAP, nakoutp); } else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); + PUTCHAR(CILEN_CHAP, nakoutp); + PUTSHORT(PPP_CHAP, nakoutp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); } else #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if(1) { - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(PPP_PAP, nakoutp); } else #endif /* PAP_SUPPORT */ {} @@ -2040,10 +2044,10 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { */ if (cishort != PPP_LQR) { orc = CONFNAK; - PUTCHAR(CI_QUALITY, nakp); - PUTCHAR(CILEN_LQR, nakp); - PUTSHORT(PPP_LQR, nakp); - PUTLONG(ao->lqr_period, nakp); + PUTCHAR(CI_QUALITY, nakoutp); + PUTCHAR(CILEN_LQR, nakoutp); + PUTSHORT(PPP_LQR, nakoutp); + PUTLONG(ao->lqr_period, nakoutp); break; } break; @@ -2064,9 +2068,9 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { cilong == go->magicnumber) { cilong = magic(); /* Don't put magic() inside macro! */ orc = CONFNAK; - PUTCHAR(CI_MAGICNUMBER, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(cilong, nakp); + PUTCHAR(CI_MAGICNUMBER, nakoutp); + PUTCHAR(CILEN_LONG, nakoutp); + PUTLONG(cilong, nakoutp); break; } ho->neg_magicnumber = 1; @@ -2167,7 +2171,7 @@ endswitch: /* * If we wanted to send additional NAKs (for unsent CIs), the - * code would go here. The extra NAKs would go at *nakp. + * code would go here. The extra NAKs would go at *nakoutp. * At present there are no cases where we want to ask the * peer to negotiate an option. */ @@ -2178,16 +2182,17 @@ endswitch: break; case CONFNAK: /* - * Copy the Nak'd options from the nak_buffer to the caller's buffer. + * Copy the Nak'd options from the nak buffer to the caller's buffer. */ - *lenp = nakp - pcb->nak_buffer; - MEMCPY(inp, pcb->nak_buffer, *lenp); + *lenp = nakoutp - (u_char*)nakp->payload; + MEMCPY(inp, nakp->payload, *lenp); break; case CONFREJ: *lenp = rejp - inp; break; } + pbuf_free(nakp); LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); return (rc); /* Return final code */ } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 48cd8d9d..cfb3aeda 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -331,8 +331,6 @@ struct ppp_pcb_s { int lcp_echos_pending; /* Number of outstanding echo msgs */ int lcp_echo_number; /* ID number of next echo frame */ int lcp_echo_timer_running; /* set if a timer is running */ - /* FIXME: do we really need such a large buffer? The typical 1500 bytes seem too much. */ - u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ int lcp_loopbackfail; fsm ipcp_fsm; /* IPCP fsm structure */ From 111a1cef5263c9faecf8b1bf6a318ddca56e6b44 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 17:07:02 +0200 Subject: [PATCH 186/320] moved ppp_settings.lax_recv and ppp_settings.noendpoint bool types (so char) to the ppp_settings bitfield --- src/netif/ppp/ppp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index cfb3aeda..13e79757 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -174,6 +174,8 @@ typedef struct ppp_settings_s { u_int hide_password : 1; /* Hide password in dumped packets */ #endif /* PRINTPKT_SUPPORT */ u_int noremoteip : 1; + u_int lax_recv : 1; /* accept control chars in asyncmap */ + u_int noendpoint : 1; /* don't send/accept endpoint discriminator */ u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ @@ -201,8 +203,6 @@ typedef struct ppp_settings_s { #if PPP_LCP_ADAPTIVE bool lcp_echo_adaptive; /* request echo only if the link was idle */ #endif - bool lax_recv; /* accept control chars in asyncmap */ - bool noendpoint; /* don't send/accept endpoint discriminator */ } ppp_settings; From ff2a737094f2e77acb72c4140be17c2cf7aae5d0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 17:38:02 +0200 Subject: [PATCH 187/320] ppp_settings.remote_name is now a compile time option --- src/netif/ppp/chap-new.c | 2 ++ src/netif/ppp/eap.c | 2 ++ src/netif/ppp/ppp.h | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 6701b2fe..8e026867 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -435,9 +435,11 @@ static void chap_respond(ppp_pcb *pcb, int id, /* Null terminate and clean remote name. */ slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); +#if PPP_REMOTENAME /* Microsoft doesn't send their name back in the PPP packet */ if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0)) strlcpy(rname, pcb->settings.remote_name, sizeof(rname)); +#endif /* PPP_REMOTENAME */ /* get secret for authenticating ourselves with the specified host */ if (!get_secret(pcb, pcb->chap_client.name, rname, secret, &secret_len, 0)) { diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 78faf0c7..1b2663ad 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -1444,10 +1444,12 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { rhostname[len - vallen] = '\0'; } +#if PPP_REMOTENAME /* In case the remote doesn't give us his name. */ if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != '\0' && vallen == len)) strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname)); +#endif /* PPP_REMOTENAME */ /* * Get the secret for authenticating ourselves with diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 13e79757..3223c942 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -153,7 +153,9 @@ typedef struct ppp_settings_s { u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ u_int auth_required : 1; /* Peer is required to authenticate */ +#if PPP_REMOTENAME u_int explicit_remote : 1; /* remote_name specified with remotename opt */ +#endif /* PPP_REMOTENAME */ #if PAP_SUPPORT u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ #endif /* PAP_SUPPORT */ @@ -189,8 +191,9 @@ typedef struct ppp_settings_s { #if PPP_SERVER char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ #endif /* PPP_SERVER */ - /* FIXME: make it a compile time option */ +#if PPP_REMOTENAME char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ +#endif /* PPP_REMOTENAME */ #if CHAP_SUPPORT int chap_timeout_time; From f744d7a7894eb58ff9b918ad841172b25941ba0b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 17:42:13 +0200 Subject: [PATCH 188/320] reduced ppp_settings types size --- src/netif/ppp/ppp.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 3223c942..a0e75018 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -178,34 +178,34 @@ typedef struct ppp_settings_s { u_int noremoteip : 1; u_int lax_recv : 1; /* accept control chars in asyncmap */ u_int noendpoint : 1; /* don't send/accept endpoint discriminator */ +#if PPP_LCP_ADAPTIVE + u_int lcp_echo_adaptive : 1; /* request echo only if the link was idle */ +#endif u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ /* FIXME: make it a compile time option */ - u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ - int maxconnect; /* Maximum connect time (seconds) */ + u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ + u32_t maxconnect; /* Maximum connect time (seconds) */ /* auth data */ - char user [MAXNAMELEN + 1]; /* Username for PAP */ - char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ + char user [MAXNAMELEN + 1]; /* Username for PAP */ + char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ #if PPP_SERVER - char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ + char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ #endif /* PPP_SERVER */ #if PPP_REMOTENAME - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ + char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ #endif /* PPP_REMOTENAME */ #if CHAP_SUPPORT - int chap_timeout_time; - int chap_max_transmits; - int chap_rechallenge_time; + u8_t chap_timeout_time; + u8_t chap_max_transmits; + u8_t chap_rechallenge_time; #endif /* CHAP_SUPPPORT */ - u_int lcp_echo_interval; /* Interval between LCP echo-requests */ - u_int lcp_echo_fails; /* Tolerance to unanswered echo-requests */ -#if PPP_LCP_ADAPTIVE - bool lcp_echo_adaptive; /* request echo only if the link was idle */ -#endif + u8_t lcp_echo_interval; /* Interval between LCP echo-requests */ + u8_t lcp_echo_fails; /* Tolerance to unanswered echo-requests */ } ppp_settings; From 08cbc1b22b2560107c1bf3520ef562cf180766f3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 17:50:02 +0200 Subject: [PATCH 189/320] idle time limit and connect time limit are now compile time options --- src/netif/ppp/auth.c | 18 ++++++++++++++++++ src/netif/ppp/ppp.h | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 3d191709..bb6b9c96 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -237,8 +237,12 @@ extern char *crypt (const char *, const char *); /* Prototypes for procedures local to this file. */ static void network_phase(ppp_pcb *pcb); +#if PPP_IDLETIMELIMIT static void check_idle(void *arg); +#endif /* PPP_IDLETIMELIMIT */ +#if PPP_MAXCONNECT static void connect_time_expired(void *arg); +#endif /* PPP_MAXCONNECT */ #if 0 /* UNUSED */ static int null_login (int); /* static int get_pap_passwd (char *); */ @@ -1149,7 +1153,9 @@ void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { * np_up - a network protocol has come up. */ void np_up(ppp_pcb *pcb, int proto) { +#if PPP_IDLETIMELIMIT int tlim; +#endif /* PPP_IDLETIMELIMIT */ if (pcb->num_np_up == 0) { /* @@ -1158,6 +1164,7 @@ void np_up(ppp_pcb *pcb, int proto) { pcb->status = EXIT_OK; new_phase(pcb, PHASE_RUNNING); +#if PPP_IDLETIMELIMIT #if 0 /* UNUSED */ if (idle_time_hook != 0) tlim = (*idle_time_hook)(NULL); @@ -1166,13 +1173,16 @@ void np_up(ppp_pcb *pcb, int proto) { tlim = pcb->settings.idle_time_limit; if (tlim > 0) TIMEOUT(check_idle, (void*)pcb, tlim); +#endif /* PPP_IDLETIMELIMIT */ +#if PPP_MAXCONNECT /* * Set a timeout to close the connection once the maximum * connect time has expired. */ if (pcb->settings.maxconnect > 0) TIMEOUT(connect_time_expired, (void*)pcb, pcb->settings.maxconnect); +#endif /* PPP_MAXCONNECT */ #ifdef MAXOCTETS if (maxoctets > 0) @@ -1195,8 +1205,12 @@ void np_up(ppp_pcb *pcb, int proto) { */ void np_down(ppp_pcb *pcb, int proto) { if (--pcb->num_np_up == 0) { +#if PPP_IDLETIMELIMIT UNTIMEOUT(check_idle, (void*)pcb); +#endif /* PPP_IDLETIMELIMIT */ +#if PPP_MAXCONNECT UNTIMEOUT(connect_time_expired, NULL); +#endif /* PPP_MAXCONNECT */ #ifdef MAXOCTETS UNTIMEOUT(check_maxoctets, NULL); #endif @@ -1254,6 +1268,7 @@ check_maxoctets(arg) } #endif /* MAXOCTETS */ +#if PPP_IDLETIMELIMIT /* * check_idle - check whether the link has been idle for long * enough that we can shut it down. @@ -1288,7 +1303,9 @@ static void check_idle(void *arg) { TIMEOUT(check_idle, (void*)pcb, tlim); } } +#endif /* PPP_IDLETIMELIMIT */ +#if PPP_MAXCONNECT /* * connect_time_expired - log a message and close the connection. */ @@ -1298,6 +1315,7 @@ static void connect_time_expired(void *arg) { pcb->status = EXIT_CONNECT_TIME; lcp_close(pcb, "Connect time expired"); /* Close connection */ } +#endif /* PPP_MAXCONNECT */ #if PPP_OPTIONS /* diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index a0e75018..c713a080 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -185,8 +185,12 @@ typedef struct ppp_settings_s { u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ /* FIXME: make it a compile time option */ +#if PPP_IDLETIMELIMIT u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ +#endif /* PPP_IDLETIMELIMIT */ +#if PPP_MAXCONNECT u32_t maxconnect; /* Maximum connect time (seconds) */ +#endif /* PPP_MAXCONNECT */ /* auth data */ char user [MAXNAMELEN + 1]; /* Username for PAP */ From 1d392f0e7617a0c90d28d785928e4cfde2ffeeee Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 17:54:29 +0200 Subject: [PATCH 190/320] removed useless flags from ppp_settings --- src/netif/ppp/ppp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index c713a080..a42a0a3d 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -151,8 +151,9 @@ typedef struct ppp_pcb_s ppp_pcb; */ typedef struct ppp_settings_s { - u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ +#if PPP_SERVER u_int auth_required : 1; /* Peer is required to authenticate */ +#endif /* PPP_SERVER */ #if PPP_REMOTENAME u_int explicit_remote : 1; /* remote_name specified with remotename opt */ #endif /* PPP_REMOTENAME */ @@ -169,13 +170,12 @@ typedef struct ppp_settings_s { #if EAP_SUPPORT u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ #endif /* EAP_SUPPORT */ - u_int usehostname : 1; /* Use hostname for our_name */ u_int usepeerdns : 1; /* Ask peer for DNS adds */ u_int persist : 1; /* Persist mode, always try to reopen the connection */ #if PRINTPKT_SUPPORT u_int hide_password : 1; /* Hide password in dumped packets */ #endif /* PRINTPKT_SUPPORT */ - u_int noremoteip : 1; + u_int noremoteip : 1; /* Let him have no IP address */ u_int lax_recv : 1; /* accept control chars in asyncmap */ u_int noendpoint : 1; /* don't send/accept endpoint discriminator */ #if PPP_LCP_ADAPTIVE From 8e9c07df39676aa7c8eac73ae033670719d63d00 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 18:02:23 +0200 Subject: [PATCH 191/320] more idle time limit macros --- src/netif/ppp/ppp.c | 3 ++- src/netif/ppp/ppp_impl.h | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index a1d41d6a..c733b197 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1989,6 +1989,7 @@ int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) { return 0; } +#if PPP_IDLETIMELIMIT /******************************************************************** * * get_idle_time - return how long the link has been idle. @@ -1999,7 +2000,7 @@ int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) { LWIP_UNUSED_ARG(ip); return 1; } - +#endif /* PPP_IDLETIMELIMIT */ /******************************************************************** * diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 0a487f13..eeab0a3b 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -209,15 +209,16 @@ struct ppp_comp_stats { #endif /* PPP_STATS_SUPPORT */ +#if PPP_IDLETIMELIMIT /* * The following structure records the time in seconds since * the last NP packet was sent or received. */ -/* FIXME: add idle time support and make it optional */ struct ppp_idle { time_t xmit_idle; /* time since last NP packet sent */ time_t recv_idle; /* time since last NP packet received */ }; +#endif /* PPP_IDLETIMELIMIT */ /* FIXME: make endpoint discriminator optional */ /* FIXME: moved temporarily to ppp.h */ @@ -420,7 +421,9 @@ int cifproxyarp(ppp_pcb *pcb, u_int32_t his_adr); int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid); +#if PPP_IDLETIMELIMIT int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip); +#endif /* PPP_IDLETIMELIMIT */ int get_loop_output(void); From 2aa9a66c57692226bce81082f2cb7e5ef09f6715 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 21:26:52 +0200 Subject: [PATCH 192/320] don't duplicate user and password anymore, anyway, the PPP user will have them already allocated as static strings or from configuration flash/file --- src/netif/ppp/auth.c | 4 ++-- src/netif/ppp/chap-new.c | 5 ++++- src/netif/ppp/eap.c | 3 +++ src/netif/ppp/ppp.c | 16 +++++----------- src/netif/ppp/ppp.h | 6 +++--- src/netif/ppp/upap.c | 4 ++++ 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index bb6b9c96..3d64fe73 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1465,7 +1465,7 @@ void auth_reset(ppp_pcb *pcb) { lcp_options *go = &pcb->lcp_gotoptions; lcp_options *ao = &pcb->lcp_allowoptions; - if( pcb->settings.passwd[0] ) { + if(pcb->settings.passwd) { #if PAP_SUPPORT ao->neg_upap = !pcb->settings.refuse_pap; @@ -1932,7 +1932,7 @@ int get_secret(ppp_pcb *pcb, char *client, char *server, char *secret, int *secr LWIP_UNUSED_ARG(server); LWIP_UNUSED_ARG(am_server); - if(!client || !client[0] || strcmp(client, pcb->settings.user)) { + if(!client || !client[0] || !pcb->settings.user || !pcb->settings.passwd || strcmp(client, pcb->settings.user)) { return 0; } diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 8e026867..825658d7 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -205,6 +205,9 @@ void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code) { void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code) { struct chap_digest_type *dp; + if(NULL == our_name) + return; + if (pcb->chap_client.flags & AUTH_STARTED) { error("CHAP: authentication with peer already started!"); return; @@ -221,7 +224,7 @@ void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code) { pcb->chap_client.flags |= AUTH_STARTED; } -# if PPP_SERVER +#if PPP_SERVER /* * chap_timeout - It's time to send another challenge to the peer. * This could be either a retransmission of a previous challenge, diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 1b2663ad..f930531c 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -235,6 +235,9 @@ static void eap_client_timeout(void *arg) { */ void eap_authwithpeer(ppp_pcb *pcb, char *localname) { + if(NULL == localname) + return; + /* Save the peer name we're given */ pcb->eap.es_client.ea_name = localname; pcb->eap.es_client.ea_namelen = strlen(localname); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index c733b197..8729acc9 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -261,7 +261,7 @@ ppp_pcb *ppp_new(u8_t num) { return pcb; } -void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) { +void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { #if PAP_SUPPORT if(authtype & PPPAUTHTYPE_PAP) @@ -293,17 +293,11 @@ void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *pas pcb->settings.refuse_eap = 1; #endif /* EAP_SUPPORT */ - if(user) { - strncpy(pcb->settings.user, user, sizeof(pcb->settings.user)-1); - pcb->settings.user[sizeof(pcb->settings.user)-1] = '\0'; - } else - pcb->settings.user[0] = '\0'; + if(user) + pcb->settings.user = user; - if(passwd) { - strncpy(pcb->settings.passwd, passwd, sizeof(pcb->settings.passwd)-1); - pcb->settings.passwd[sizeof(pcb->settings.passwd)-1] = '\0'; - } else - pcb->settings.passwd[0] = '\0'; + if(passwd) + pcb->settings.passwd = passwd; } #if PPPOS_SUPPORT diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index a42a0a3d..c6998aac 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -193,8 +193,8 @@ typedef struct ppp_settings_s { #endif /* PPP_MAXCONNECT */ /* auth data */ - char user [MAXNAMELEN + 1]; /* Username for PAP */ - char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ + char *user; /* Username for PAP */ + char *passwd; /* Password for PAP, secret for CHAP */ #if PPP_SERVER char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ #endif /* PPP_SERVER */ @@ -390,7 +390,7 @@ ppp_pcb *ppp_new(u8_t num); #define PPPAUTHTYPE_EAP 0x08 #define PPPAUTHTYPE_ANY 0xff -void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd); +void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd); /* Link status callback function prototype */ typedef void (*ppp_link_status_cb_fn)(void *ctx, int errcode, void *arg); diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 2df9ce3b..8e31f7ee 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -157,6 +157,10 @@ static void upap_init(ppp_pcb *pcb) { * Set new state and send authenticate's. */ void upap_authwithpeer(ppp_pcb *pcb, char *user, char *password) { + + if(!user || !password) + return; + /* Save the username and password we're given */ pcb->upap.us_user = user; pcb->upap.us_userlen = strlen(user); From eadd56a376c23e2dfc1de9cdb411db64c737edc2 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 22:00:12 +0200 Subject: [PATCH 193/320] replaced exit code (pcb->status) with ppp_ioctl() --- src/netif/ppp/auth.c | 14 ++++++-------- src/netif/ppp/lcp.c | 6 ++++-- src/netif/ppp/ppp.c | 1 - src/netif/ppp/ppp.h | 23 +++++++++++++---------- src/netif/ppp/ppp_impl.h | 28 ---------------------------- 5 files changed, 23 insertions(+), 49 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 3d64fe73..97b0a472 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1075,14 +1075,11 @@ void auth_withpeer_fail(ppp_pcb *pcb, int protocol) { int errcode = PPPERR_AUTHFAIL; /* * 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. - */ - pcb->status = EXIT_AUTH_TOPEER_FAILED; - - /* - * We've failed to authenticate ourselves to our peer. + * * He'll probably take the link down, and there's not much * we can do except wait for that. */ @@ -1161,7 +1158,6 @@ void np_up(ppp_pcb *pcb, int proto) { /* * At this point we consider that the link has come up successfully. */ - pcb->status = EXIT_OK; new_phase(pcb, PHASE_RUNNING); #if PPP_IDLETIMELIMIT @@ -1292,9 +1288,10 @@ static void check_idle(void *arg) { } #endif /* UNUSED */ if (tlim <= 0) { + int errcode = PPPERR_IDLETIMEOUT; /* link is idle: shut it down. */ notice("Terminating connection due to lack of activity."); - pcb->status = EXIT_IDLE_TIMEOUT; + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(pcb, "Link inactive"); #if 0 /* UNUSED */ need_holdoff = 0; @@ -1310,9 +1307,10 @@ static void check_idle(void *arg) { * connect_time_expired - log a message and close the connection. */ static void connect_time_expired(void *arg) { + int errcode = PPPERR_CONNECTTIME; ppp_pcb *pcb = (ppp_pcb*)arg; info("Connect time expired"); - pcb->status = EXIT_CONNECT_TIME; + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(pcb, "Connect time expired"); /* Close connection */ } #endif /* PPP_MAXCONNECT */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index fc74f1bd..67cba968 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1483,8 +1483,9 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { if (f->state != OPENED) { if (looped_back) { if (++try.numloops >= pcb->lcp_loopbackfail) { + int errcode = PPPERR_LOOPBACK; notice("Serial line is looped back."); - pcb->status = EXIT_LOOPBACK; + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(f->pcb, "Loopback detected"); } } else @@ -2547,9 +2548,10 @@ static int lcp_printpkt(u_char *p, int plen, static void LcpLinkFailure(fsm *f) { ppp_pcb *pcb = f->pcb; if (f->state == OPENED) { + int errcode = PPPERR_PEERDEAD; info("No response to %d echo-requests", pcb->lcp_echos_pending); notice("Serial link appears to be disconnected."); - pcb->status = EXIT_PEER_DEAD; + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(pcb, "Peer not responding"); } } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 8729acc9..e44d914f 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -238,7 +238,6 @@ ppp_pcb *ppp_new(u8_t num) { memset(pcb, 0, sizeof(ppp_pcb)); pcb->num = num; - pcb->status = EXIT_OK; pcb->lcp_loopbackfail = DEFLOOPBACKFAIL; new_phase(pcb, PHASE_INITIALIZE); diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index c6998aac..db12d2a7 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -99,15 +99,19 @@ typedef unsigned char bool; #define PPP_FCSLEN 2 /* octets for FCS */ /* Error codes. */ -#define PPPERR_NONE 0 /* No error. */ -#define PPPERR_PARAM -1 /* Invalid parameter. */ -#define PPPERR_OPEN -2 /* Unable to open PPP session. */ -#define PPPERR_DEVICE -3 /* Invalid I/O device for PPP. */ -#define PPPERR_ALLOC -4 /* Unable to allocate resources. */ -#define PPPERR_USER -5 /* User interrupt. */ -#define PPPERR_CONNECT -6 /* Connection lost. */ -#define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */ -#define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */ +#define PPPERR_NONE 0 /* No error. */ +#define PPPERR_PARAM 1 /* Invalid parameter. */ +#define PPPERR_OPEN 2 /* Unable to open PPP session. */ +#define PPPERR_DEVICE 3 /* Invalid I/O device for PPP. */ +#define PPPERR_ALLOC 4 /* Unable to allocate resources. */ +#define PPPERR_USER 5 /* User interrupt. */ +#define PPPERR_CONNECT 6 /* Connection lost. */ +#define PPPERR_AUTHFAIL 7 /* Failed authentication challenge. */ +#define PPPERR_PROTOCOL 8 /* Failed to meet protocol. */ +#define PPPERR_PEERDEAD 9 /* Connection timeout */ +#define PPPERR_IDLETIMEOUT 10 /* Idle Timeout */ +#define PPPERR_CONNECTTIME 11 /* Max connect time reached */ +#define PPPERR_LOOPBACK 12 /* Loopback detected */ /* * PPP IOCTL commands. @@ -270,7 +274,6 @@ struct ppp_pcb_s { ppp_pcb_rx rx; #endif /* PPPOS_SUPPORT */ u8_t phase; /* where the link is at */ - u8_t status; /* exit status */ #if PPPOE_SUPPORT struct netif *ethif; struct pppoe_softc *pppoe_sc; diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index eeab0a3b..a55cdfb0 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -504,34 +504,6 @@ void update_link_stats(int u); /* Get stats at link termination */ 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 -#ifdef MAXOCTETS -#define EXIT_TRAFFIC_LIMIT 20 -#endif -#define EXIT_CNID_AUTH_FAILED 21 - /* Procedures exported from auth.c */ void link_required(ppp_pcb *pcb); /* we are starting to use the link */ void link_terminated(ppp_pcb *pcb); /* we are finished with the link */ From b21cb8a39619afa9a7c5d91302f8c9915c8d473d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 22:08:14 +0200 Subject: [PATCH 194/320] removed pcb->num if PPP debug is not compiled --- src/netif/ppp/ppp.c | 15 ++++++++++++--- src/netif/ppp/ppp.h | 4 +++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index e44d914f..1924b03e 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -122,6 +122,12 @@ #include "netif/ppp_oe.h" #endif /* PPPOE_SUPPORT */ +/* Global variables */ + +#if PPP_DEBUG +u8_t ppp_num; /* PPP Interface counter, used for debugging messages */ +#endif /* PPP_DEBUG */ + /*************************/ /*** LOCAL DEFINITIONS ***/ /*************************/ @@ -223,7 +229,7 @@ int ppp_init(void) { } /* Create a new PPP session. */ -ppp_pcb *ppp_new(u8_t num) { +ppp_pcb *ppp_new(void) { int i; ppp_pcb *pcb; struct protent *protp; @@ -237,7 +243,9 @@ ppp_pcb *ppp_new(u8_t num) { #endif /* PPP_STATS_SUPPORT */ memset(pcb, 0, sizeof(ppp_pcb)); - pcb->num = num; +#if PPP_DEBUG + pcb->num = ppp_num++; +#endif /* PPP_DEBUG */ pcb->lcp_loopbackfail = DEFLOOPBACKFAIL; new_phase(pcb, PHASE_INITIALIZE); @@ -1141,8 +1149,9 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) /* FIXME: improve that */ int ppp_write_pbuf(ppp_pcb *pcb, struct pbuf *p) { - ppp_write(pcb, p->payload, p->len); + int ret = ppp_write(pcb, p->payload, p->len); pbuf_free(p); + return ret; } /* diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index db12d2a7..d3ac6b9f 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -269,7 +269,9 @@ typedef struct ppp_pcb_rx_s { */ struct ppp_pcb_s { ppp_settings settings; +#if PPP_DEBUG u8_t num; /* Interface number - only useful for debugging */ +#endif /* PPP_DEBUG */ #if PPPOS_SUPPORT ppp_pcb_rx rx; #endif /* PPPOS_SUPPORT */ @@ -363,7 +365,7 @@ struct ppp_pcb_s { int ppp_init(void); /* Create a new PPP session, returns a PPP PCB structure. */ -ppp_pcb *ppp_new(u8_t num); +ppp_pcb *ppp_new(void); /* Set auth helper, optional, you can either fill ppp_pcb->settings. */ From b7be03801c102728538e8b3452d6b369c2d7f181 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 22:53:38 +0200 Subject: [PATCH 195/320] improved much more ppp_pcb entry size --- src/netif/ppp/ppp.c | 2 +- src/netif/ppp/ppp.h | 53 ++++++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 1924b03e..723af60d 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1115,7 +1115,7 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) case PPPCTLS_ERRCODE: /* Set the PPP error code. */ if (arg) { - pcb->err_code = *(int *)arg; + pcb->err_code = *(u8_t *)arg; return PPPERR_NONE; } return PPPERR_PARAM; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index d3ac6b9f..0150acd3 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -268,50 +268,53 @@ typedef struct ppp_pcb_rx_s { * PPP interface control block. */ struct ppp_pcb_s { + u_int if_up :1; /* True when the interface is up. */ + u_int pcomp :1; /* Does peer accept protocol compression? */ + u_int accomp :1; /* Does peer accept addr/ctl compression? */ +#if PPPOS_SUPPORT && VJ_SUPPORT + u_int vj_enabled :1; /* Flag indicating VJ compression enabled. */ +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + ppp_settings settings; + #if PPP_DEBUG u8_t num; /* Interface number - only useful for debugging */ #endif /* PPP_DEBUG */ + #if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ + ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ ppp_pcb_rx rx; +#if VJ_SUPPORT + struct vjcompress vj_comp; /* Van Jacobson compression header. */ +#endif /* VJ_SUPPORT */ #endif /* PPPOS_SUPPORT */ - u8_t phase; /* where the link is at */ + #if PPPOE_SUPPORT struct netif *ethif; struct pppoe_softc *pppoe_sc; #endif /* PPPOE_SUPPORT */ - int if_up; /* True when the interface is up. */ - int err_code; /* Code indicating why interface is down. */ -#if PPPOS_SUPPORT - sio_fd_t fd; /* File device ID of port. */ -#endif /* PPPOS_SUPPORT */ - u16_t mtu; /* Peer's mru */ - int pcomp; /* Does peer accept protocol compression? */ - int accomp; /* Does peer accept addr/ctl compression? */ - u_long last_xmit; /* Time of last transmission. */ -#if PPPOS_SUPPORT - ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ -#endif /* PPPOS_SUPPORT */ -#if PPPOS_SUPPORT && VJ_SUPPORT - int vj_enabled; /* Flag indicating VJ compression enabled. */ - struct vjcompress vj_comp; /* Van Jacobson compression header. */ -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + u8_t phase; /* where the link is at */ + u8_t err_code; /* Code indicating why interface is down. */ + + u16_t mtu; /* Peer's mru */ + u32_t last_xmit; /* Time of last transmission. */ + + struct ppp_addrs addrs; /* PPP addresses */ struct netif netif; /* PPP interface */ - struct ppp_addrs addrs; - - void (*link_status_cb)(void *ctx, int err_code, void *arg); - void *link_status_ctx; + void (*link_status_cb)(void *ctx, int err_code, void *arg); /* Status change callback */ + void *link_status_ctx; /* Status change callback optional pointer */ /* auth data */ #if PPP_SERVER char peer_authname[MAXNAMELEN + 1]; /* The name by which the peer authenticated itself to us. */ #endif /* PPP_SERVER */ - int auth_pending; /* Records which authentication operations haven't completed yet. */ - int auth_done; /* Records which authentication operations have been completed. */ - int num_np_open; /* Number of network protocols which we have opened. */ - int num_np_up; /* Number of network protocols which have come up. */ + u16_t auth_pending; /* Records which authentication operations haven't completed yet. */ + u16_t auth_done; /* Records which authentication operations have been completed. */ + u8_t num_np_open; /* Number of network protocols which we have opened. */ + u8_t num_np_up; /* Number of network protocols which have come up. */ #if PAP_SUPPORT upap_state upap; /* PAP data */ From 7ecfe6304a5b9dc01b1e590b8768683ce6f0a04f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 23:03:47 +0200 Subject: [PATCH 196/320] reduced MTU/MRU variables --- src/netif/ppp/ppp.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 0150acd3..fd67fd97 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -298,7 +298,10 @@ struct ppp_pcb_s { u8_t phase; /* where the link is at */ u8_t err_code; /* Code indicating why interface is down. */ + /* FIXME: maybe we should cleanup one of those MTU variables */ u16_t mtu; /* Peer's mru */ + u16_t peer_mru; /* currently negotiated peer MRU */ + u32_t last_xmit; /* Time of last transmission. */ struct ppp_addrs addrs; /* PPP addresses */ @@ -333,8 +336,6 @@ struct ppp_pcb_s { eap_state eap; #endif /* EAP_SUPPORT */ - int peer_mru; /* currently negotiated peer MRU */ - fsm lcp_fsm; /* LCP fsm structure */ lcp_options lcp_wantoptions; /* Options that we want to request */ lcp_options lcp_gotoptions; /* Options that peer ack'd */ From 26250f1953fdbf272601a727f056b1da2b8cb200 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 23:14:31 +0200 Subject: [PATCH 197/320] removed pcb->chap_mdtype_all --- src/netif/ppp/auth.c | 4 ++-- src/netif/ppp/chap-new.c | 6 ------ src/netif/ppp/lcp.c | 2 +- src/netif/ppp/ppp.h | 2 -- src/netif/ppp/ppp_impl.h | 11 +++++++++++ 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 97b0a472..97b9b5e9 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -1364,8 +1364,8 @@ auth_check_options() #endif /* EAP_SUPPORT */ ) { #if CHAP_SUPPORT - wo->neg_chap = pcb->chap_mdtype_all != MDTYPE_NONE; - wo->chap_mdtype = pcb->chap_mdtype_all; + wo->neg_chap = CHAP_MDTYPE_SUPPORTED != MDTYPE_NONE; + wo->chap_mdtype = CHAP_MDTYPE_SUPPORTED; #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT wo->neg_upap = 1; diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 825658d7..c97844bb 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -44,12 +44,8 @@ #include "chap-new.h" #include "chap-md5.h" - #if MSCHAP_SUPPORT #include "chap_ms.h" -#define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) -#else -#define MDTYPE_ALL (MDTYPE_MD5) #endif /* Hook for a plugin to validate CHAP challenge */ @@ -128,8 +124,6 @@ static void chap_init(ppp_pcb *pcb) { memset(&pcb->chap_server, 0, sizeof(chap_server_state)); #endif /* PPP_SERVER */ - pcb->chap_mdtype_all = MDTYPE_ALL; - chap_md5_init(); #if MSCHAP_SUPPORT chapms_init(); diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 67cba968..78bc645d 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -384,7 +384,7 @@ static void lcp_init(ppp_pcb *pcb) { ao->neg_asyncmap = 1; #if CHAP_SUPPORT ao->neg_chap = 1; - ao->chap_mdtype = pcb->chap_mdtype_all; + ao->chap_mdtype = CHAP_MDTYPE_SUPPORTED; #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT ao->neg_upap = 1; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index fd67fd97..feaba30c 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -324,8 +324,6 @@ struct ppp_pcb_s { #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT - /* FIXME: we can probably remove this entry */ - int chap_mdtype_all; /* hashes supported by this instance of pppd */ chap_client_state chap_client; #if PPP_SERVER chap_server_state chap_server; diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index a55cdfb0..2c0c7194 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -357,6 +357,17 @@ extern struct protent *protocols[]; #define PHASE_HOLDOFF 11 #define PHASE_MASTER 12 +/* Supported CHAP protocols */ +#if CHAP_SUPPORT +#include "chap-new.h" +#if MSCHAP_SUPPORT +#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) +#else +#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MD5) +#endif +#else +#define CHAP_MDTYPE_SUPPORTED (MDTYPE_NONE) +#endif #if PPP_STATS_SUPPORT /* From c51c55b7827e3fd46b06371e2163123c31e79c4c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 23:25:57 +0200 Subject: [PATCH 198/320] LCP and IPCP variable size improved --- src/netif/ppp/lcp.c | 2 +- src/netif/ppp/ppp.h | 46 ++++++++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 78bc645d..d72b8c03 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -2661,7 +2661,7 @@ static void LcpSendEchoRequest(fsm *f) { lcp_magic = go->magicnumber; pktp = pkt; PUTLONG(lcp_magic, pktp); - fsm_sdata(f, ECHOREQ, pcb->lcp_echo_number++ & 0xFF, pkt, pktp - pkt); + fsm_sdata(f, ECHOREQ, pcb->lcp_echo_number++, pkt, pktp - pkt); ++pcb->lcp_echos_pending; } } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index feaba30c..36bf58a6 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -268,11 +268,17 @@ typedef struct ppp_pcb_rx_s { * PPP interface control block. */ struct ppp_pcb_s { - u_int if_up :1; /* True when the interface is up. */ - u_int pcomp :1; /* Does peer accept protocol compression? */ - u_int accomp :1; /* Does peer accept addr/ctl compression? */ + u_int if_up :1; /* True when the interface is up. */ + u_int pcomp :1; /* Does peer accept protocol compression? */ + u_int accomp :1; /* Does peer accept addr/ctl compression? */ + u_int default_route_set :1; /* Have set up a default route */ + u_int proxy_arp_set :1; /* Have created proxy arp entry */ + u_int ipcp_is_open :1; /* haven't called np_finished() */ + u_int ipcp_is_up :1; /* have called np_up() */ + u_int ask_for_local :1; /* request our address from peer */ + u_int lcp_echo_timer_running :1; /* set if a timer is running */ #if PPPOS_SUPPORT && VJ_SUPPORT - u_int vj_enabled :1; /* Flag indicating VJ compression enabled. */ + u_int vj_enabled :1; /* Flag indicating VJ compression enabled. */ #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ ppp_settings settings; @@ -334,29 +340,23 @@ struct ppp_pcb_s { eap_state eap; #endif /* EAP_SUPPORT */ - fsm lcp_fsm; /* LCP fsm structure */ - lcp_options lcp_wantoptions; /* Options that we want to request */ - lcp_options lcp_gotoptions; /* Options that peer ack'd */ - lcp_options lcp_allowoptions; /* Options we allow peer to request */ - lcp_options lcp_hisoptions; /* Options that we ack'd */ + fsm lcp_fsm; /* LCP fsm structure */ + lcp_options lcp_wantoptions; /* Options that we want to request */ + lcp_options lcp_gotoptions; /* Options that peer ack'd */ + lcp_options lcp_allowoptions; /* Options we allow peer to request */ + lcp_options lcp_hisoptions; /* Options that we ack'd */ #if PPPOS_SUPPORT ext_accm xmit_accm; /* extended transmit ACCM */ #endif /* PPPOS_SUPPORT */ - int lcp_echos_pending; /* Number of outstanding echo msgs */ - int lcp_echo_number; /* ID number of next echo frame */ - int lcp_echo_timer_running; /* set if a timer is running */ - int lcp_loopbackfail; + u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ + u8_t lcp_echo_number; /* ID number of next echo frame */ + u8_t lcp_loopbackfail; - fsm ipcp_fsm; /* IPCP fsm structure */ - ipcp_options ipcp_wantoptions; /* Options that we want to request */ - ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ - ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ - ipcp_options ipcp_hisoptions; /* Options that we ack'd */ - int default_route_set; /* Have set up a default route */ - int proxy_arp_set; /* Have created proxy arp entry */ - int ipcp_is_open; /* haven't called np_finished() */ - int ipcp_is_up; /* have called np_up() */ - bool ask_for_local; /* request our address from peer */ + fsm ipcp_fsm; /* IPCP fsm structure */ + ipcp_options ipcp_wantoptions; /* Options that we want to request */ + ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ + ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ + ipcp_options ipcp_hisoptions; /* Options that we ack'd */ }; /************************ From 0bdc27186dd1d6bed9ce899b19b176b53474835a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 23:31:20 +0200 Subject: [PATCH 199/320] some more improvements to ppp_pcb --- src/netif/ppp/ppp.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 36bf58a6..1a7cc87e 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -188,7 +188,6 @@ typedef struct ppp_settings_s { u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ - /* FIXME: make it a compile time option */ #if PPP_IDLETIMELIMIT u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ #endif /* PPP_IDLETIMELIMIT */ @@ -289,7 +288,9 @@ struct ppp_pcb_s { #if PPPOS_SUPPORT sio_fd_t fd; /* File device ID of port. */ +/* FIXME: there is probably one superfluous */ ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ + ext_accm xmit_accm; /* extended transmit ACCM */ ppp_pcb_rx rx; #if VJ_SUPPORT struct vjcompress vj_comp; /* Van Jacobson compression header. */ @@ -326,18 +327,18 @@ struct ppp_pcb_s { u8_t num_np_up; /* Number of network protocols which have come up. */ #if PAP_SUPPORT - upap_state upap; /* PAP data */ + upap_state upap; /* PAP data */ #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT - chap_client_state chap_client; + chap_client_state chap_client; /* CHAP client data */ #if PPP_SERVER - chap_server_state chap_server; + chap_server_state chap_server; /* CHAP server data */ #endif /* PPP_SERVER */ #endif /* CHAP_SUPPORT */ #if EAP_SUPPORT - eap_state eap; + eap_state eap; /* EAP data */ #endif /* EAP_SUPPORT */ fsm lcp_fsm; /* LCP fsm structure */ @@ -345,11 +346,8 @@ struct ppp_pcb_s { lcp_options lcp_gotoptions; /* Options that peer ack'd */ lcp_options lcp_allowoptions; /* Options we allow peer to request */ lcp_options lcp_hisoptions; /* Options that we ack'd */ -#if PPPOS_SUPPORT - ext_accm xmit_accm; /* extended transmit ACCM */ -#endif /* PPPOS_SUPPORT */ - u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ - u8_t lcp_echo_number; /* ID number of next echo frame */ + u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ + u8_t lcp_echo_number; /* ID number of next echo frame */ u8_t lcp_loopbackfail; fsm ipcp_fsm; /* IPCP fsm structure */ From 0234c62c3ef9b8c14b6dd48b51158c3e2e72ee51 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 23:37:33 +0200 Subject: [PATCH 200/320] improved PAP control structure size --- src/netif/ppp/upap.c | 4 ++-- src/netif/ppp/upap.h | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 8e31f7ee..91235821 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -163,9 +163,9 @@ void upap_authwithpeer(ppp_pcb *pcb, char *user, char *password) { /* Save the username and password we're given */ pcb->upap.us_user = user; - pcb->upap.us_userlen = strlen(user); + pcb->upap.us_userlen = LWIP_MIN(strlen(user), 0xff); pcb->upap.us_passwd = password; - pcb->upap.us_passwdlen = strlen(password); + pcb->upap.us_passwdlen = LWIP_MIN(strlen(password), 0xff); pcb->upap.us_transmits = 0; /* Lower layer up yet? */ diff --git a/src/netif/ppp/upap.h b/src/netif/ppp/upap.h index 27209265..2b58b750 100644 --- a/src/netif/ppp/upap.h +++ b/src/netif/ppp/upap.h @@ -99,18 +99,18 @@ #if PAP_SUPPORT typedef struct upap_state { char *us_user; /* User */ - int us_userlen; /* User length */ + u8_t us_userlen; /* User length */ char *us_passwd; /* Password */ - int us_passwdlen; /* Password length */ - int us_clientstate; /* Client state */ + u8_t us_passwdlen; /* Password length */ + u8_t us_clientstate; /* Client state */ #if PPP_SERVER - int us_serverstate; /* Server state */ + u8_t us_serverstate /* Server state */ #endif /* PPP_SERVER */ - 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 */ + u8_t us_id; /* Current id */ + u8_t us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ + u8_t us_transmits; /* Number of auth-reqs sent */ + u8_t us_maxtransmits; /* Maximum number of auth-reqs to send */ + u8_t us_reqtimeout; /* Time to wait for auth-req from peer */ } upap_state; #endif /* PAP_SUPPORT */ From 4bbf443ba257e9913a045c9d7bc5101db55b5df5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 19 Jun 2012 23:42:41 +0200 Subject: [PATCH 201/320] improved CHAP structure size, however there is not much we can do --- src/netif/ppp/chap-new.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/chap-new.h b/src/netif/ppp/chap-new.h index 98f4c54d..d7f42f13 100644 --- a/src/netif/ppp/chap-new.h +++ b/src/netif/ppp/chap-new.h @@ -145,7 +145,7 @@ struct chap_digest_type { */ #if CHAP_SUPPORT typedef struct chap_client_state { - int flags; + u8_t flags; char *name; struct chap_digest_type *digest; unsigned char priv[64]; /* private area for digest's use */ @@ -153,7 +153,7 @@ typedef struct chap_client_state { #if PPP_SERVER static struct chap_server_state { - int flags; + u8_t flags; int id; char *name; struct chap_digest_type *digest; From e330983408364315819f31ce188a1d6bce7f8b1c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 20 Jun 2012 00:03:08 +0200 Subject: [PATCH 202/320] improved lcp_options structure size --- src/netif/ppp/lcp.c | 18 +++++++++++++++--- src/netif/ppp/lcp.h | 44 ++++++++++++++++++++++++-------------------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index d72b8c03..da4435d4 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -688,8 +688,8 @@ static void lcp_resetci(fsm *f) { *go = *wo; #ifdef HAVE_MULTILINK if (!multilink) { -#endif /* HAVE_MULTILINK */ go->neg_mrru = 0; +#endif /* HAVE_MULTILINK */ go->neg_ssnhf = 0; go->neg_endpoint = 0; #ifdef HAVE_MULTILINK @@ -758,7 +758,9 @@ static int lcp_cilen(fsm *f) { LENCILONG(go->neg_magicnumber) + LENCIVOID(go->neg_pcompression) + LENCIVOID(go->neg_accompression) + +#ifdef HAVE_MULTILINK LENCISHORT(go->neg_mrru) + +#endif /* HAVE_MULTILINK */ LENCIVOID(go->neg_ssnhf) + (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); } @@ -858,7 +860,9 @@ static void lcp_addci(fsm *f, u_char *ucp, int *lenp) { ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); +#ifdef HAVE_MULTILINK ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); +#endif ADDCIVOID(CI_SSNHF, go->neg_ssnhf); ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, go->endpoint.value, go->endpoint.length); @@ -1030,7 +1034,9 @@ static int lcp_ackci(fsm *f, u_char *p, int len) { ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); +#ifdef HAVE_MULTILINK ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); +#endif /* HAVE_MULTILINK */ ACKCIVOID(CI_SSNHF, go->neg_ssnhf); ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, go->endpoint.value, go->endpoint.length); @@ -1360,6 +1366,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { NAKCIVOID(CI_PCOMPRESSION, neg_pcompression); NAKCIVOID(CI_ACCOMPRESSION, neg_accompression); +#ifdef HAVE_MULTILINK /* * Nak for MRRU option - accept their value if it is smaller * than the one we want. @@ -1372,6 +1379,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { try.mrru = cishort; ); } +#endif /* HAVE_MULTILINK */ /* * Nak for short sequence numbers shouldn't be sent, treat it @@ -1459,10 +1467,12 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { goto bad; break; #endif /* LQR_SUPPORT */ +#ifdef HAVE_MULTILINK case CI_MRRU: if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) goto bad; break; +#endif /* HAVE_MULTILINK */ case CI_SSNHF: if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) goto bad; @@ -1706,7 +1716,9 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); REJCIVOID(CI_PCOMPRESSION, neg_pcompression); REJCIVOID(CI_ACCOMPRESSION, neg_accompression); +#ifdef HAVE_MULTILINK REJCISHORT(CI_MRRU, neg_mrru, go->mrru); +#endif /* HAVE_MULTILINK */ REJCIVOID(CI_SSNHF, neg_ssnhf); REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class, go->endpoint.value, go->endpoint.length); @@ -2097,11 +2109,10 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { ho->neg_accompression = 1; break; +#ifdef HAVE_MULTILINK case CI_MRRU: if (!ao->neg_mrru -#ifdef HAVE_MULTILINK || !multilink -#endif /* HAVE_MULTILINK */ || cilen != CILEN_SHORT) { orc = CONFREJ; break; @@ -2112,6 +2123,7 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { ho->neg_mrru = 1; ho->mrru = cishort; break; +#endif /* HAVE_MULTILINK */ case CI_SSNHF: if (!ao->neg_ssnhf diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index 3cfc1175..8a1c841a 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -106,38 +106,42 @@ struct epdisc { * 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? */ + u_int passive :1; /* Don't die if we don't get a response */ + u_int silent :1; /* Wait for the other end to start first */ + u_int restart :1; /* Restart vs. exit after close */ + u_int neg_mru :1; /* Negotiate the MRU? */ + u_int neg_asyncmap :1; /* Negotiate the async map? */ #if PAP_SUPPORT - bool neg_upap; /* Ask for UPAP authentication? */ + u_int neg_upap :1; /* Ask for UPAP authentication? */ #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT - bool neg_chap; /* Ask for CHAP authentication? */ + u_int neg_chap :1; /* Ask for CHAP authentication? */ #endif /* CHAP_SUPPORT */ #if EAP_SUPPORT - bool neg_eap; /* Ask for EAP authentication? */ + u_int neg_eap :1; /* Ask for EAP authentication? */ #endif /* EAP_SUPPORT */ - bool neg_magicnumber; /* Ask for magic number? */ - bool neg_pcompression; /* HDLC Protocol Field Compression? */ - bool neg_accompression; /* HDLC Address/Control Field Compression? */ + u_int neg_magicnumber :1; /* Ask for magic number? */ + u_int neg_pcompression :1; /* HDLC Protocol Field Compression? */ + u_int neg_accompression :1; /* HDLC Address/Control Field Compression? */ #if LQR_SUPPORT - bool neg_lqr; /* Negotiate use of Link Quality Reports */ + u_int neg_lqr :1; /* Negotiate use of Link Quality Reports */ #endif /* LQR_SUPPORT */ - bool neg_cbcp; /* Negotiate use of CBCP */ - bool neg_mrru; /* negotiate multilink MRRU */ - bool neg_ssnhf; /* negotiate short sequence numbers */ - bool neg_endpoint; /* negotiate endpoint discriminator */ - int mru; /* Value of MRU */ - int mrru; /* Value of MRRU, and multilink enable */ + u_int neg_cbcp :1; /* Negotiate use of CBCP */ +#ifdef HAVE_MULTILINK + u_int neg_mrru :1; /* negotiate multilink MRRU */ +#endif /* HAVE_MULTILINK */ + u_int neg_ssnhf :1; /* negotiate short sequence numbers */ + u_int neg_endpoint :1; /* negotiate endpoint discriminator */ + u16_t mru; /* Value of MRU */ +#ifdef HAVE_MULTILINK + u16_t mrru; /* Value of MRRU, and multilink enable */ +#endif /* MULTILINK */ #if CHAP_SUPPORT - u_char chap_mdtype; /* which MD types (hashing algorithm) */ + u8_t chap_mdtype; /* which MD types (hashing algorithm) */ #endif /* CHAP_SUPPORT */ u_int32_t asyncmap; /* Value of async map */ u_int32_t magicnumber; - int numloops; /* Number of loops during magic number neg. */ + u8_t numloops; /* Number of loops during magic number neg. */ #if LQR_SUPPORT u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ #endif /* LQR_SUPPORT */ From 9871c4ff066091d50a95c7ed6467ee2b0b477ffc Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 20 Jun 2012 00:10:08 +0200 Subject: [PATCH 203/320] improved IPCP control structure size --- src/netif/ppp/ipcp.h | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index a443a168..d576509e 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -72,24 +72,26 @@ /* 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 replace_default_route; /* Replace 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; + u_int neg_addr :1; /* Negotiate IP Address? */ + u_int old_addrs :1; /* Use old (IP-Addresses) option? */ + u_int req_addr :1; /* Ask peer to send IP address? */ + u_int default_route :1; /* Assign default route through interface? */ + u_int replace_default_route :1; /* Replace default route through interface? */ + u_int proxy_arp :1; /* Make proxy ARP entry for peer? */ + u_int neg_vj :1; /* Van Jacobson Compression? */ + u_int old_vj :1; /* use old (short) form of VJ option? */ + u_int accept_local :1; /* accept peer's value for ouraddr */ + u_int accept_remote :1; /* accept peer's value for hisaddr */ + u_int req_dns1 :1; /* Ask peer to send primary DNS address? */ + u_int req_dns2 :1; /* Ask peer to send secondary DNS address? */ + u_int cflag :1; + u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ u_int32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ + + u16_t vj_protocol; /* protocol value to use in VJ option */ + u8_t maxslotindex; /* values for RFC1332 VJ compression neg. */ } ipcp_options; #if 0 /* UNUSED, already defined by lwIP */ From c36d73f42a8998815c4aeba5279a08dadc20e96b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 20 Jun 2012 13:29:21 +0200 Subject: [PATCH 204/320] added raw IPv6 PPP files --- src/netif/ppp/eui64.c | 57 ++ src/netif/ppp/eui64.h | 114 +++ src/netif/ppp/ipv6cp.c | 1562 ++++++++++++++++++++++++++++++++++++++++ src/netif/ppp/ipv6cp.h | 171 +++++ 4 files changed, 1904 insertions(+) create mode 100644 src/netif/ppp/eui64.c create mode 100644 src/netif/ppp/eui64.h create mode 100644 src/netif/ppp/ipv6cp.c create mode 100644 src/netif/ppp/ipv6cp.h diff --git a/src/netif/ppp/eui64.c b/src/netif/ppp/eui64.c new file mode 100644 index 00000000..d025eff4 --- /dev/null +++ b/src/netif/ppp/eui64.c @@ -0,0 +1,57 @@ +/* + * eui64.c - EUI64 routines for IPv6CP. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $ + */ + +#define RCSID "$Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $" + +#include "pppd.h" + +static const char rcsid[] = RCSID; + +/* + * eui64_ntoa - Make an ascii representation of an interface identifier + */ +char * +eui64_ntoa(e) + eui64_t e; +{ + static char buf[32]; + + snprintf(buf, 32, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", + e.e8[0], e.e8[1], e.e8[2], e.e8[3], + e.e8[4], e.e8[5], e.e8[6], e.e8[7]); + return buf; +} diff --git a/src/netif/ppp/eui64.h b/src/netif/ppp/eui64.h new file mode 100644 index 00000000..0f6b6fd4 --- /dev/null +++ b/src/netif/ppp/eui64.h @@ -0,0 +1,114 @@ +/* + * eui64.h - EUI64 routines for IPv6CP. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $ +*/ + +#ifndef __EUI64_H__ +#define __EUI64_H__ + +#if !defined(INET6) +#error "this file should only be included when INET6 is defined" +#endif /* not defined(INET6) */ + +#if defined(SOL2) +#include + +typedef union { + uint8_t e8[8]; /* lower 64-bit IPv6 address */ + uint32_t e32[2]; /* lower 64-bit IPv6 address */ +} eui64_t; + +/* + * Declare the two below, since in.h only defines them when _KERNEL + * is declared - which shouldn't be true when dealing with user-land programs + */ +#define s6_addr8 _S6_un._S6_u8 +#define s6_addr32 _S6_un._S6_u32 + +#else /* else if not defined(SOL2) */ + +/* + * TODO: + * + * Maybe this should be done by processing struct in6_addr directly... + */ +typedef union +{ + u_int8_t e8[8]; + u_int16_t e16[4]; + u_int32_t e32[2]; +} eui64_t; + +#endif /* defined(SOL2) */ + +#define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) +#define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ + ((e).e32[1] == (o).e32[1])) +#define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; + +#define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) + +#define eui64_magic(e) do { \ + (e).e32[0] = magic(); \ + (e).e32[1] = magic(); \ + (e).e8[0] &= ~2; \ + } while (0) +#define eui64_magic_nz(x) do { \ + eui64_magic(x); \ + } while (eui64_iszero(x)) +#define eui64_magic_ne(x, y) do { \ + eui64_magic(x); \ + } while (eui64_equals(x, y)) + +#define eui64_get(ll, cp) do { \ + eui64_copy((*cp), (ll)); \ + (cp) += sizeof(eui64_t); \ + } while (0) + +#define eui64_put(ll, cp) do { \ + eui64_copy((ll), (*cp)); \ + (cp) += sizeof(eui64_t); \ + } while (0) + +#define eui64_set32(e, l) do { \ + (e).e32[0] = 0; \ + (e).e32[1] = htonl(l); \ + } while (0) +#define eui64_setlo32(e, l) eui64_set32(e, l) + +char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */ + +#endif /* __EUI64_H__ */ + diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c new file mode 100644 index 00000000..4a09c9aa --- /dev/null +++ b/src/netif/ppp/ipv6cp.c @@ -0,0 +1,1562 @@ +/* + * ipv6cp.c - PPP IPV6 Control Protocol. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* Original version, based on RFC2023 : + + Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt + Économique ayant pour membres BULL S.A. et l'INRIA). + + Ce logiciel informatique est disponible aux conditions + usuelles dans la recherche, c'est-à-dire qu'il peut + être utilisé, copié, modifié, distribué à l'unique + condition que ce texte soit conservé afin que + l'origine de ce logiciel soit reconnue. + + Le nom de l'Institut National de Recherche en Informatique + et en Automatique (INRIA), de l'IMAG, ou d'une personne morale + ou physique ayant participé à l'élaboration de ce logiciel ne peut + être utilisé sans son accord préalable explicite. + + Ce logiciel est fourni tel quel sans aucune garantie, + support ou responsabilité d'aucune sorte. + Ce logiciel est dérivé de sources d'origine + "University of California at Berkeley" et + "Digital Equipment Corporation" couvertes par des copyrights. + + L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) + est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National + Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant + sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). + + This work has been done in the context of GIE DYADE (joint R & D venture + between BULL S.A. and INRIA). + + This software is available with usual "research" terms + with the aim of retain credits of the software. + Permission to use, copy, modify and distribute this software for any + purpose and without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies, + and the name of INRIA, IMAG, or any contributor not be used in advertising + or publicity pertaining to this material without the prior explicit + permission. The software is provided "as is" without any + warranties, support or liabilities of any kind. + This software is derived from source code from + "University of California at Berkeley" and + "Digital Equipment Corporation" protected by copyrights. + + Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) + is a federation of seven research units funded by the CNRS, National + Polytechnic Institute of Grenoble and University Joseph Fourier. + The research unit in Software, Systems, Networks (LSR) is member of IMAG. +*/ + +/* + * Derived from : + * + * + * ipcp.c - PPP IP Control Protocol. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $ + */ + +#define RCSID "$Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $" + +/* + * TODO: + * + * Proxy Neighbour Discovery. + * + * Better defines for selecting the ordering of + * interface up / set address. (currently checks for __linux__, + * since SVR4 && (SNI || __USLC__) didn't work properly) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pppd.h" +#include "fsm.h" +#include "ipcp.h" +#include "ipv6cp.h" +#include "magic.h" +#include "pathnames.h" + +static const char rcsid[] = RCSID; + +/* global vars */ +ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */ +ipv6cp_options ipv6cp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ +ipv6cp_options ipv6cp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ +ipv6cp_options ipv6cp_hisoptions[NUM_PPP]; /* Options that we ack'd */ +int no_ifaceid_neg = 0; + +/* local vars */ +static int ipv6cp_is_up; + +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void ipv6cp_resetci __P((fsm *)); /* Reset our CI */ +static int ipv6cp_cilen __P((fsm *)); /* Return length of our CI */ +static void ipv6cp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ +static int ipv6cp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ +static int ipv6cp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ +static int ipv6cp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ +static int ipv6cp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ +static void ipv6cp_up __P((fsm *)); /* We're UP */ +static void ipv6cp_down __P((fsm *)); /* We're DOWN */ +static void ipv6cp_finished __P((fsm *)); /* Don't need lower layer */ + +fsm ipv6cp_fsm[NUM_PPP]; /* IPV6CP fsm structure */ + +static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ + ipv6cp_resetci, /* Reset our Configuration Information */ + ipv6cp_cilen, /* Length of our Configuration Information */ + ipv6cp_addci, /* Add our Configuration Information */ + ipv6cp_ackci, /* ACK our Configuration Information */ + ipv6cp_nakci, /* NAK our Configuration Information */ + ipv6cp_rejci, /* Reject our Configuration Information */ + ipv6cp_reqci, /* Request peer's Configuration Information */ + ipv6cp_up, /* Called when fsm reaches OPENED state */ + ipv6cp_down, /* Called when fsm leaves OPENED state */ + NULL, /* Called when we want the lower layer up */ + ipv6cp_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 */ + "IPV6CP" /* String name of protocol */ +}; + +/* + * Command-line options. + */ +static int setifaceid __P((char **arg)); +static void printifaceid __P((option_t *, + void (*)(void *, char *, ...), void *)); + +static option_t ipv6cp_option_list[] = { + { "ipv6", o_special, (void *)setifaceid, + "Set interface identifiers for IPV6", + OPT_A2PRINTER, (void *)printifaceid }, + + { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag, + "Enable IPv6 and IPv6CP", OPT_PRIO | 1 }, + { "noipv6", o_bool, &ipv6cp_protent.enabled_flag, + "Disable IPv6 and IPv6CP", OPT_PRIOSUB }, + { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag, + "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS }, + + { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local, + "Accept peer's interface identifier for us", 1 }, + + { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, + "Use (default) IPv4 address as interface identifier", 1 }, + +#if defined(SOL2) || defined(__linux__) + { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent, + "Use uniquely-available persistent value for link local address", 1 }, +#endif /* defined(SOL2) */ + + { "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime, + "Set timeout for IPv6CP", OPT_PRIO }, + { "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits, + "Set max #xmits for term-reqs", OPT_PRIO }, + { "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits, + "Set max #xmits for conf-reqs", OPT_PRIO }, + { "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops, + "Set max #conf-naks for IPv6CP", OPT_PRIO }, + + { NULL } +}; + + +/* + * Protocol entry points from main code. + */ +static void ipv6cp_init __P((int)); +static void ipv6cp_open __P((int)); +static void ipv6cp_close __P((int, char *)); +static void ipv6cp_lowerup __P((int)); +static void ipv6cp_lowerdown __P((int)); +static void ipv6cp_input __P((int, u_char *, int)); +static void ipv6cp_protrej __P((int)); +static int ipv6cp_printpkt __P((u_char *, int, + void (*) __P((void *, char *, ...)), void *)); +static void ipv6_check_options __P((void)); +static int ipv6_demand_conf __P((int)); +static int ipv6_active_pkt __P((u_char *, int)); + +struct protent ipv6cp_protent = { + PPP_IPV6CP, + ipv6cp_init, + ipv6cp_input, + ipv6cp_protrej, + ipv6cp_lowerup, + ipv6cp_lowerdown, + ipv6cp_open, + ipv6cp_close, + ipv6cp_printpkt, + NULL, + 0, + "IPV6CP", + "IPV6", + ipv6cp_option_list, + ipv6_check_options, + ipv6_demand_conf, + ipv6_active_pkt +}; + +static void ipv6cp_clear_addrs __P((int, eui64_t, eui64_t)); +static void ipv6cp_script __P((char *)); +static void ipv6cp_script_done __P((void *)); + +/* + * Lengths of configuration options. + */ +#define CILEN_VOID 2 +#define CILEN_COMPRESS 4 /* length for RFC2023 compress opt. */ +#define CILEN_IFACEID 10 /* RFC2472, interface identifier */ + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + +/* + * This state variable is used to ensure that we don't + * run an ipcp-up/down script while one is already running. + */ +static enum script_state { + s_down, + s_up, +} ipv6cp_script_state; +static pid_t ipv6cp_script_pid; + +/* + * setifaceid - set the interface identifiers manually + */ +static int +setifaceid(argv) + char **argv; +{ + char *comma, *arg, c; + ipv6cp_options *wo = &ipv6cp_wantoptions[0]; + struct in6_addr addr; + static int prio_local, prio_remote; + +#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \ + (((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) ) + + arg = *argv; + if ((comma = strchr(arg, ',')) == NULL) + comma = arg + strlen(arg); + + /* + * If comma first character, then no local identifier + */ + if (comma != arg) { + c = *comma; + *comma = '\0'; + + if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) { + option_error("Illegal interface identifier (local): %s", arg); + return 0; + } + + if (option_priority >= prio_local) { + eui64_copy(addr.s6_addr32[2], wo->ourid); + wo->opt_local = 1; + prio_local = option_priority; + } + *comma = c; + } + + /* + * If comma last character, the no remote identifier + */ + if (*comma != 0 && *++comma != '\0') { + if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) { + option_error("Illegal interface identifier (remote): %s", comma); + return 0; + } + if (option_priority >= prio_remote) { + eui64_copy(addr.s6_addr32[2], wo->hisid); + wo->opt_remote = 1; + prio_remote = option_priority; + } + } + + if (override_value("+ipv6", option_priority, option_source)) + ipv6cp_protent.enabled_flag = 1; + return 1; +} + +char *llv6_ntoa(eui64_t ifaceid); + +static void +printifaceid(opt, printer, arg) + option_t *opt; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[0]; + + if (wo->opt_local) + printer(arg, "%s", llv6_ntoa(wo->ourid)); + printer(arg, ","); + if (wo->opt_remote) + printer(arg, "%s", llv6_ntoa(wo->hisid)); +} + +/* + * Make a string representation of a network address. + */ +char * +llv6_ntoa(ifaceid) + eui64_t ifaceid; +{ + static char b[64]; + + sprintf(b, "fe80::%s", eui64_ntoa(ifaceid)); + return b; +} + + +/* + * ipv6cp_init - Initialize IPV6CP. + */ +static void +ipv6cp_init(unit) + int unit; +{ + fsm *f = &ipv6cp_fsm[unit]; + ipv6cp_options *wo = &ipv6cp_wantoptions[unit]; + ipv6cp_options *ao = &ipv6cp_allowoptions[unit]; + + f->unit = unit; + f->protocol = PPP_IPV6CP; + f->callbacks = &ipv6cp_callbacks; + fsm_init(&ipv6cp_fsm[unit]); + + memset(wo, 0, sizeof(*wo)); + memset(ao, 0, sizeof(*ao)); + + wo->accept_local = 1; + wo->neg_ifaceid = 1; + ao->neg_ifaceid = 1; + +#ifdef IPV6CP_COMP + wo->neg_vj = 1; + ao->neg_vj = 1; + wo->vj_protocol = IPV6CP_COMP; +#endif + +} + + +/* + * ipv6cp_open - IPV6CP is allowed to come up. + */ +static void +ipv6cp_open(unit) + int unit; +{ + fsm_open(&ipv6cp_fsm[unit]); +} + + +/* + * ipv6cp_close - Take IPV6CP down. + */ +static void +ipv6cp_close(unit, reason) + int unit; + char *reason; +{ + fsm_close(&ipv6cp_fsm[unit], reason); +} + + +/* + * ipv6cp_lowerup - The lower layer is up. + */ +static void +ipv6cp_lowerup(unit) + int unit; +{ + fsm_lowerup(&ipv6cp_fsm[unit]); +} + + +/* + * ipv6cp_lowerdown - The lower layer is down. + */ +static void +ipv6cp_lowerdown(unit) + int unit; +{ + fsm_lowerdown(&ipv6cp_fsm[unit]); +} + + +/* + * ipv6cp_input - Input IPV6CP packet. + */ +static void +ipv6cp_input(unit, p, len) + int unit; + u_char *p; + int len; +{ + fsm_input(&ipv6cp_fsm[unit], p, len); +} + + +/* + * ipv6cp_protrej - A Protocol-Reject was received for IPV6CP. + * + * Pretend the lower layer went down, so we shut up. + */ +static void +ipv6cp_protrej(unit) + int unit; +{ + fsm_lowerdown(&ipv6cp_fsm[unit]); +} + + +/* + * ipv6cp_resetci - Reset our CI. + */ +static void +ipv6cp_resetci(f) + fsm *f; +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + + wo->req_ifaceid = wo->neg_ifaceid && ipv6cp_allowoptions[f->unit].neg_ifaceid; + + if (!wo->opt_local) { + eui64_magic_nz(wo->ourid); + } + + *go = *wo; + eui64_zero(go->hisid); /* last proposed interface identifier */ +} + + +/* + * ipv6cp_cilen - Return length of our CI. + */ +static int +ipv6cp_cilen(f) + fsm *f; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + +#define LENCIVJ(neg) (neg ? CILEN_COMPRESS : 0) +#define LENCIIFACEID(neg) (neg ? CILEN_IFACEID : 0) + + return (LENCIIFACEID(go->neg_ifaceid) + + LENCIVJ(go->neg_vj)); +} + + +/* + * ipv6cp_addci - Add our desired CIs to a packet. + */ +static void +ipv6cp_addci(f, ucp, lenp) + fsm *f; + u_char *ucp; + int *lenp; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + int len = *lenp; + +#define ADDCIVJ(opt, neg, val) \ + if (neg) { \ + int vjlen = CILEN_COMPRESS; \ + if (len >= vjlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(vjlen, ucp); \ + PUTSHORT(val, ucp); \ + len -= vjlen; \ + } else \ + neg = 0; \ + } + +#define ADDCIIFACEID(opt, neg, val1) \ + if (neg) { \ + int idlen = CILEN_IFACEID; \ + if (len >= idlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(idlen, ucp); \ + eui64_put(val1, ucp); \ + len -= idlen; \ + } else \ + neg = 0; \ + } + + ADDCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); + + ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); + + *lenp -= len; +} + + +/* + * ipv6cp_ackci - Ack our CIs. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int +ipv6cp_ackci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + u_short cilen, citype, cishort; + eui64_t ifaceid; + + /* + * 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) \ + if (neg) { \ + int vjlen = CILEN_COMPRESS; \ + 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; \ + } + +#define ACKCIIFACEID(opt, neg, val1) \ + if (neg) { \ + int idlen = CILEN_IFACEID; \ + if ((len -= idlen) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != idlen || \ + citype != opt) \ + goto bad; \ + eui64_get(ifaceid, p); \ + if (! eui64_equals(val1, ifaceid)) \ + goto bad; \ + } + + ACKCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); + + ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + return (1); + +bad: + IPV6CPDEBUG(("ipv6cp_ackci: received bad Ack!")); + return (0); +} + +/* + * ipv6cp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if IPV6CP is in the OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int +ipv6cp_nakci(f, p, len, treat_as_reject) + fsm *f; + u_char *p; + int len; + int treat_as_reject; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + u_char citype, cilen, *next; + u_short cishort; + eui64_t ifaceid; + ipv6cp_options no; /* options we've seen Naks for */ + ipv6cp_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 NAKCIIFACEID(opt, neg, code) \ + if (go->neg && \ + len >= (cilen = CILEN_IFACEID) && \ + p[1] == cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + eui64_get(ifaceid, p); \ + no.neg = 1; \ + code \ + } + +#define NAKCIVJ(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_COMPRESS) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } + + /* + * Accept the peer's idea of {our,his} interface identifier, if different + * from our idea, only if the accept_{local,remote} flag is set. + */ + NAKCIIFACEID(CI_IFACEID, neg_ifaceid, + if (treat_as_reject) { + try.neg_ifaceid = 0; + } else if (go->accept_local) { + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->hisid)) /* bad luck */ + eui64_magic(ifaceid); + try.ourid = ifaceid; + IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); + } + ); + +#ifdef IPV6CP_COMP + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + { + if (cishort == IPV6CP_COMP && !treat_as_reject) { + try.vj_protocol = cishort; + } else { + try.neg_vj = 0; + } + } + ); +#else + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + { + try.neg_vj = 0; + } + ); +#endif + + /* + * 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 interface identifier, we comply. + * If they want us to ask for compression, we refuse. + */ + 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_COMPRESSTYPE: + if (go->neg_vj || no.neg_vj || + (cilen != CILEN_COMPRESS)) + goto bad; + no.neg_vj = 1; + break; + case CI_IFACEID: + if (go->neg_ifaceid || no.neg_ifaceid || cilen != CILEN_IFACEID) + goto bad; + try.neg_ifaceid = 1; + eui64_get(ifaceid, p); + if (go->accept_local) { + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->hisid)) /* bad luck */ + eui64_magic(ifaceid); + try.ourid = ifaceid; + } + no.neg_ifaceid = 1; + break; + } + p = next; + } + + /* If there is still anything left, this packet is bad. */ + if (len != 0) + goto bad; + + /* + * OK, the Nak is good. Now we can update state. + */ + if (f->state != OPENED) + *go = try; + + return 1; + +bad: + IPV6CPDEBUG(("ipv6cp_nakci: received bad Nak!")); + return 0; +} + + +/* + * ipv6cp_rejci - Reject some of our CIs. + */ +static int +ipv6cp_rejci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + u_char cilen; + u_short cishort; + eui64_t ifaceid; + ipv6cp_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 REJCIIFACEID(opt, neg, val1) \ + if (go->neg && \ + len >= (cilen = CILEN_IFACEID) && \ + p[1] == cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + eui64_get(ifaceid, p); \ + /* Check rejected value. */ \ + if (! eui64_equals(ifaceid, val1)) \ + goto bad; \ + try.neg = 0; \ + } + +#define REJCIVJ(opt, neg, val) \ + if (go->neg && \ + p[1] == CILEN_COMPRESS && \ + len >= p[1] && \ + p[0] == opt) { \ + len -= p[1]; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) \ + goto bad; \ + try.neg = 0; \ + } + + REJCIIFACEID(CI_IFACEID, neg_ifaceid, go->ourid); + + REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol); + + /* + * 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: + IPV6CPDEBUG(("ipv6cp_rejci: received bad Reject!")); + return 0; +} + + +/* + * ipv6cp_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 +ipv6cp_reqci(f, inp, len, reject_if_disagree) + fsm *f; + u_char *inp; /* Requested CIs */ + int *len; /* Length of requested CIs */ + int reject_if_disagree; +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; + ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; + ipv6cp_options *ao = &ipv6cp_allowoptions[f->unit]; + ipv6cp_options *go = &ipv6cp_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 */ + eui64_t ifaceid; /* Parsed interface identifier */ + 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 */ + + /* + * 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? */ + IPV6CPDEBUG(("ipv6cp_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_IFACEID: + IPV6CPDEBUG(("ipv6cp: received interface identifier ")); + + if (!ao->neg_ifaceid || + cilen != CILEN_IFACEID) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no interface identifier, or if we both have same + * identifier then NAK it with new idea. + * In particular, if we don't know his identifier, but he does, + * then accept it. + */ + eui64_get(ifaceid, p); + IPV6CPDEBUG(("(%s)", llv6_ntoa(ifaceid))); + if (eui64_iszero(ifaceid) && eui64_iszero(go->ourid)) { + orc = CONFREJ; /* Reject CI */ + break; + } + if (!eui64_iszero(wo->hisid) && + !eui64_equals(ifaceid, wo->hisid) && + eui64_iszero(go->hisid)) { + + orc = CONFNAK; + ifaceid = wo->hisid; + go->hisid = ifaceid; + DECPTR(sizeof(ifaceid), p); + eui64_put(ifaceid, p); + } else + if (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) { + orc = CONFNAK; + if (eui64_iszero(go->hisid)) /* first time, try option */ + ifaceid = wo->hisid; + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->ourid)) /* bad luck */ + eui64_magic(ifaceid); + go->hisid = ifaceid; + DECPTR(sizeof(ifaceid), p); + eui64_put(ifaceid, p); + } + + ho->neg_ifaceid = 1; + ho->hisid = ifaceid; + break; + + case CI_COMPRESSTYPE: + IPV6CPDEBUG(("ipv6cp: received COMPRESSTYPE ")); + if (!ao->neg_vj || + (cilen != CILEN_COMPRESS)) { + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + IPV6CPDEBUG(("(%d)", cishort)); + +#ifdef IPV6CP_COMP + if (!(cishort == IPV6CP_COMP)) { + orc = CONFREJ; + break; + } + + ho->neg_vj = 1; + ho->vj_protocol = cishort; + break; +#else + orc = CONFREJ; + break; +#endif + + default: + orc = CONFREJ; + break; + } + +endswitch: + IPV6CPDEBUG((" (%s)\n", CODENAME(orc))); + + 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 identifier and they didn't send their identifier, then we + * send a NAK with a CI_IFACEID option appended. We assume the + * input buffer is long enough that we can append the extra + * option safely. + */ + if (rc != CONFREJ && !ho->neg_ifaceid && + wo->req_ifaceid && !reject_if_disagree) { + if (rc == CONFACK) { + rc = CONFNAK; + ucp = inp; /* reset pointer */ + wo->req_ifaceid = 0; /* don't ask again */ + } + PUTCHAR(CI_IFACEID, ucp); + PUTCHAR(CILEN_IFACEID, ucp); + eui64_put(wo->hisid, ucp); + } + + *len = ucp - inp; /* Compute output length */ + IPV6CPDEBUG(("ipv6cp: returning Configure-%s", CODENAME(rc))); + return (rc); /* Return final code */ +} + + +/* + * ipv6_check_options - check that any IP-related options are OK, + * and assign appropriate defaults. + */ +static void +ipv6_check_options() +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[0]; + + if (!ipv6cp_protent.enabled_flag) + return; + +#if defined(SOL2) || defined(__linux__) + /* + * Persistent link-local id is only used when user has not explicitly + * configure/hard-code the id + */ + if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) { + + /* + * On systems where there are no Ethernet interfaces used, there + * may be other ways to obtain a persistent id. Right now, it + * will fall back to using magic [see eui64_magic] below when + * an EUI-48 from MAC address can't be obtained. Other possibilities + * include obtaining EEPROM serial numbers, or some other unique + * yet persistent number. On Sparc platforms, this is possible, + * but too bad there's no standards yet for x86 machines. + */ + if (ether_to_eui64(&wo->ourid)) { + wo->opt_local = 1; + } + } +#endif + + if (!wo->opt_local) { /* init interface identifier */ + if (wo->use_ip && eui64_iszero(wo->ourid)) { + eui64_setlo32(wo->ourid, ntohl(ipcp_wantoptions[0].ouraddr)); + if (!eui64_iszero(wo->ourid)) + wo->opt_local = 1; + } + + while (eui64_iszero(wo->ourid)) + eui64_magic(wo->ourid); + } + + if (!wo->opt_remote) { + if (wo->use_ip && eui64_iszero(wo->hisid)) { + eui64_setlo32(wo->hisid, ntohl(ipcp_wantoptions[0].hisaddr)); + if (!eui64_iszero(wo->hisid)) + wo->opt_remote = 1; + } + } + + if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) { + option_error("local/remote LL address required for demand-dialling\n"); + exit(1); + } +} + + +/* + * ipv6_demand_conf - configure the interface as though + * IPV6CP were up, for use with dial-on-demand. + */ +static int +ipv6_demand_conf(u) + int u; +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[u]; + +#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) +#if defined(SOL2) + if (!sif6up(u)) + return 0; +#else + if (!sifup(u)) + return 0; +#endif /* defined(SOL2) */ +#endif + if (!sif6addr(u, wo->ourid, wo->hisid)) + return 0; +#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sifup(u)) + return 0; +#endif + if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) + return 0; + + notice("ipv6_demand_conf"); + notice("local LL address %s", llv6_ntoa(wo->ourid)); + notice("remote LL address %s", llv6_ntoa(wo->hisid)); + + return 1; +} + + +/* + * ipv6cp_up - IPV6CP has come UP. + * + * Configure the IPv6 network interface appropriately and bring it up. + */ +static void +ipv6cp_up(f) + fsm *f; +{ + ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; + + IPV6CPDEBUG(("ipv6cp: up")); + + /* + * We must have a non-zero LL address for both ends of the link. + */ + if (!ho->neg_ifaceid) + ho->hisid = wo->hisid; + + if(!no_ifaceid_neg) { + if (eui64_iszero(ho->hisid)) { + error("Could not determine remote LL address"); + ipv6cp_close(f->unit, "Could not determine remote LL address"); + return; + } + if (eui64_iszero(go->ourid)) { + error("Could not determine local LL address"); + ipv6cp_close(f->unit, "Could not determine local LL address"); + return; + } + if (eui64_equals(go->ourid, ho->hisid)) { + error("local and remote LL addresses are equal"); + ipv6cp_close(f->unit, "local and remote LL addresses are equal"); + return; + } + } + script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0); + script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0); + +#ifdef IPV6CP_COMP + /* set tcp compression */ + sif6comp(f->unit, ho->neg_vj); +#endif + + /* + * 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 IPv6 packets. + */ + if (demand) { + if (! eui64_equals(go->ourid, wo->ourid) || + ! eui64_equals(ho->hisid, wo->hisid)) { + if (! eui64_equals(go->ourid, wo->ourid)) + warn("Local LL address changed to %s", + llv6_ntoa(go->ourid)); + if (! eui64_equals(ho->hisid, wo->hisid)) + warn("Remote LL address changed to %s", + llv6_ntoa(ho->hisid)); + ipv6cp_clear_addrs(f->unit, go->ourid, ho->hisid); + + /* Set the interface to the new addresses */ + if (!sif6addr(f->unit, go->ourid, ho->hisid)) { + if (debug) + warn("sif6addr failed"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } + + } + demand_rexmit(PPP_IPV6); + sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); + + } else { + /* + * Set LL addresses + */ +#if !defined(__linux__) && !defined(SOL2) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sif6addr(f->unit, go->ourid, ho->hisid)) { + if (debug) + warn("sif6addr failed"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#endif + + /* bring the interface up for IPv6 */ +#if defined(SOL2) + if (!sif6up(f->unit)) { + if (debug) + warn("sifup failed (IPV6)"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#else + if (!sifup(f->unit)) { + if (debug) + warn("sifup failed (IPV6)"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#endif /* defined(SOL2) */ + +#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sif6addr(f->unit, go->ourid, ho->hisid)) { + if (debug) + warn("sif6addr failed"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#endif + sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); + + notice("local LL address %s", llv6_ntoa(go->ourid)); + notice("remote LL address %s", llv6_ntoa(ho->hisid)); + } + + np_up(f->unit, PPP_IPV6); + ipv6cp_is_up = 1; + + /* + * Execute the ipv6-up script, like this: + * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL + */ + if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) { + ipv6cp_script_state = s_up; + ipv6cp_script(_PATH_IPV6UP); + } +} + + +/* + * ipv6cp_down - IPV6CP has gone DOWN. + * + * Take the IPv6 network interface down, clear its addresses + * and delete routes through it. + */ +static void +ipv6cp_down(f) + fsm *f; +{ + IPV6CPDEBUG(("ipv6cp: down")); + update_link_stats(f->unit); + if (ipv6cp_is_up) { + ipv6cp_is_up = 0; + np_down(f->unit, PPP_IPV6); + } +#ifdef IPV6CP_COMP + sif6comp(f->unit, 0); +#endif + + /* + * If we are doing dial-on-demand, set the interface + * to queue up outgoing packets (for now). + */ + if (demand) { + sifnpmode(f->unit, PPP_IPV6, NPMODE_QUEUE); + } else { + sifnpmode(f->unit, PPP_IPV6, NPMODE_DROP); +#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC))) +#if defined(SOL2) + sif6down(f->unit); +#else + sifdown(f->unit); +#endif /* defined(SOL2) */ +#endif + ipv6cp_clear_addrs(f->unit, + ipv6cp_gotoptions[f->unit].ourid, + ipv6cp_hisoptions[f->unit].hisid); +#if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC))) + sifdown(f->unit); +#endif + } + + /* Execute the ipv6-down script */ + if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) { + ipv6cp_script_state = s_down; + ipv6cp_script(_PATH_IPV6DOWN); + } +} + + +/* + * ipv6cp_clear_addrs() - clear the interface addresses, routes, + * proxy neighbour discovery entries, etc. + */ +static void +ipv6cp_clear_addrs(unit, ourid, hisid) + int unit; + eui64_t ourid; + eui64_t hisid; +{ + cif6addr(unit, ourid, hisid); +} + + +/* + * ipv6cp_finished - possibly shut down the lower layers. + */ +static void +ipv6cp_finished(f) + fsm *f; +{ + np_finished(f->unit, PPP_IPV6); +} + + +/* + * ipv6cp_script_done - called when the ipv6-up or ipv6-down script + * has finished. + */ +static void +ipv6cp_script_done(arg) + void *arg; +{ + ipv6cp_script_pid = 0; + switch (ipv6cp_script_state) { + case s_up: + if (ipv6cp_fsm[0].state != OPENED) { + ipv6cp_script_state = s_down; + ipv6cp_script(_PATH_IPV6DOWN); + } + break; + case s_down: + if (ipv6cp_fsm[0].state == OPENED) { + ipv6cp_script_state = s_up; + ipv6cp_script(_PATH_IPV6UP); + } + break; + } +} + + +/* + * ipv6cp_script - Execute a script with arguments + * interface-name tty-name speed local-LL remote-LL. + */ +static void +ipv6cp_script(script) + char *script; +{ + char strspeed[32], strlocal[32], strremote[32]; + char *argv[8]; + + sprintf(strspeed, "%d", baud_rate); + strcpy(strlocal, llv6_ntoa(ipv6cp_gotoptions[0].ourid)); + strcpy(strremote, llv6_ntoa(ipv6cp_hisoptions[0].hisid)); + + argv[0] = script; + argv[1] = ifname; + argv[2] = devnam; + argv[3] = strspeed; + argv[4] = strlocal; + argv[5] = strremote; + argv[6] = ipparam; + argv[7] = NULL; + + ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, + NULL, 0); +} + +/* + * ipv6cp_printpkt - print the contents of an IPV6CP packet. + */ +static char *ipv6cp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej" +}; + +static int +ipv6cp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + eui64_t ifaceid; + + 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(ipv6cp_codenames) / sizeof(char *)) + printer(arg, " %s", ipv6cp_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_COMPRESSTYPE: + if (olen >= CILEN_COMPRESS) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "compress "); + printer(arg, "0x%x", cishort); + } + break; + case CI_IFACEID: + if (olen == CILEN_IFACEID) { + p += 2; + eui64_get(ifaceid, p); + printer(arg, "addr %s", llv6_ntoa(ifaceid)); + } + 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((char *)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; +} + +/* + * ipv6_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 IP6_HDRLEN 40 /* bytes */ +#define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ +#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 get_ip6nh(x) (((unsigned char *)(x))[6]) +#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) +#define get_tcpflags(x) (((unsigned char *)(x))[13]) + +static int +ipv6_active_pkt(pkt, len) + u_char *pkt; + int len; +{ + u_char *tcp; + + len -= PPP_HDRLEN; + pkt += PPP_HDRLEN; + if (len < IP6_HDRLEN) + return 0; + if (get_ip6nh(pkt) == IP6_NHDR_FRAG) + return 0; + if (get_ip6nh(pkt) != IPPROTO_TCP) + return 1; + if (len < IP6_HDRLEN + TCP_HDRLEN) + return 0; + tcp = pkt + IP6_HDRLEN; + if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == IP6_HDRLEN + get_tcpoff(tcp) * 4) + return 0; + return 1; +} diff --git a/src/netif/ppp/ipv6cp.h b/src/netif/ppp/ipv6cp.h new file mode 100644 index 00000000..cc4568de --- /dev/null +++ b/src/netif/ppp/ipv6cp.h @@ -0,0 +1,171 @@ +/* + * ipv6cp.h - PPP IPV6 Control Protocol. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* Original version, based on RFC2023 : + + Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt + Économique ayant pour membres BULL S.A. et l'INRIA). + + Ce logiciel informatique est disponible aux conditions + usuelles dans la recherche, c'est-à-dire qu'il peut + être utilisé, copié, modifié, distribué à l'unique + condition que ce texte soit conservé afin que + l'origine de ce logiciel soit reconnue. + + Le nom de l'Institut National de Recherche en Informatique + et en Automatique (INRIA), de l'IMAG, ou d'une personne morale + ou physique ayant participé à l'élaboration de ce logiciel ne peut + être utilisé sans son accord préalable explicite. + + Ce logiciel est fourni tel quel sans aucune garantie, + support ou responsabilité d'aucune sorte. + Ce logiciel est dérivé de sources d'origine + "University of California at Berkeley" et + "Digital Equipment Corporation" couvertes par des copyrights. + + L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) + est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National + Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant + sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). + + This work has been done in the context of GIE DYADE (joint R & D venture + between BULL S.A. and INRIA). + + This software is available with usual "research" terms + with the aim of retain credits of the software. + Permission to use, copy, modify and distribute this software for any + purpose and without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies, + and the name of INRIA, IMAG, or any contributor not be used in advertising + or publicity pertaining to this material without the prior explicit + permission. The software is provided "as is" without any + warranties, support or liabilities of any kind. + This software is derived from source code from + "University of California at Berkeley" and + "Digital Equipment Corporation" protected by copyrights. + + Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) + is a federation of seven research units funded by the CNRS, National + Polytechnic Institute of Grenoble and University Joseph Fourier. + The research unit in Software, Systems, Networks (LSR) is member of IMAG. +*/ + +/* + * Derived from : + * + * + * ipcp.h - IP Control Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $ + */ + +/* + * Options. + */ +#define CI_IFACEID 1 /* Interface Identifier */ +#define CI_COMPRESSTYPE 2 /* Compression Type */ + +/* No compression types yet defined. + *#define IPV6CP_COMP 0x004f + */ +typedef struct ipv6cp_options { + int neg_ifaceid; /* Negotiate interface identifier? */ + int req_ifaceid; /* Ask peer to send interface identifier? */ + int accept_local; /* accept peer's value for iface id? */ + int opt_local; /* ourtoken set by option */ + int opt_remote; /* histoken set by option */ + int use_ip; /* use IP as interface identifier */ +#if defined(SOL2) || defined(__linux__) + int use_persistent; /* use uniquely persistent value for address */ +#endif /* defined(SOL2) */ + int neg_vj; /* Van Jacobson Compression? */ + u_short vj_protocol; /* protocol value to use in VJ option */ + eui64_t ourid, hisid; /* Interface identifiers */ +} ipv6cp_options; + +extern fsm ipv6cp_fsm[]; +extern ipv6cp_options ipv6cp_wantoptions[]; +extern ipv6cp_options ipv6cp_gotoptions[]; +extern ipv6cp_options ipv6cp_allowoptions[]; +extern ipv6cp_options ipv6cp_hisoptions[]; + +extern struct protent ipv6cp_protent; From cd7894dfc9b41bc633337fbf2ba74b781341b321 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 20 Jun 2012 13:39:08 +0200 Subject: [PATCH 205/320] added compilation macro to eui64.[ch] and cleaned unix-dependant code --- src/netif/ppp/eui64.c | 15 +++++++-------- src/netif/ppp/eui64.h | 28 ++++------------------------ 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/src/netif/ppp/eui64.c b/src/netif/ppp/eui64.c index d025eff4..aeeaa1a3 100644 --- a/src/netif/ppp/eui64.c +++ b/src/netif/ppp/eui64.c @@ -35,19 +35,16 @@ * $Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $ */ -#define RCSID "$Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $" +#include "lwip/opt.h" +#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "pppd.h" - -static const char rcsid[] = RCSID; +#include "ppp_impl.h" +#include "eui64.h" /* * eui64_ntoa - Make an ascii representation of an interface identifier */ -char * -eui64_ntoa(e) - eui64_t e; -{ +char *eui64_ntoa(eui64_t e) { static char buf[32]; snprintf(buf, 32, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", @@ -55,3 +52,5 @@ eui64_ntoa(e) e.e8[4], e.e8[5], e.e8[6], e.e8[7]); return buf; } + +#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/src/netif/ppp/eui64.h b/src/netif/ppp/eui64.h index 0f6b6fd4..8d735340 100644 --- a/src/netif/ppp/eui64.h +++ b/src/netif/ppp/eui64.h @@ -35,30 +35,12 @@ * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ + #ifndef __EUI64_H__ #define __EUI64_H__ -#if !defined(INET6) -#error "this file should only be included when INET6 is defined" -#endif /* not defined(INET6) */ - -#if defined(SOL2) -#include - -typedef union { - uint8_t e8[8]; /* lower 64-bit IPv6 address */ - uint32_t e32[2]; /* lower 64-bit IPv6 address */ -} eui64_t; - -/* - * Declare the two below, since in.h only defines them when _KERNEL - * is declared - which shouldn't be true when dealing with user-land programs - */ -#define s6_addr8 _S6_un._S6_u8 -#define s6_addr32 _S6_un._S6_u32 - -#else /* else if not defined(SOL2) */ - /* * TODO: * @@ -71,8 +53,6 @@ typedef union u_int32_t e32[2]; } eui64_t; -#endif /* defined(SOL2) */ - #define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) #define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ ((e).e32[1] == (o).e32[1])) @@ -111,4 +91,4 @@ typedef union char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */ #endif /* __EUI64_H__ */ - +#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ From b6db4a0e2ef71d50cab053014adfd183c2f3d9e1 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 21 Jun 2012 18:05:17 +0200 Subject: [PATCH 206/320] PPP IPv6 local link support added --- src/netif/ppp/eui64.h | 2 +- src/netif/ppp/ipv6cp.c | 382 ++++++++++++++++++--------------------- src/netif/ppp/ipv6cp.h | 17 +- src/netif/ppp/ppp.c | 97 ++++++++-- src/netif/ppp/ppp.h | 20 +- src/netif/ppp/ppp_impl.h | 17 +- src/netif/ppp/utils.c | 2 +- 7 files changed, 297 insertions(+), 240 deletions(-) diff --git a/src/netif/ppp/eui64.h b/src/netif/ppp/eui64.h index 8d735340..00f3911f 100644 --- a/src/netif/ppp/eui64.h +++ b/src/netif/ppp/eui64.h @@ -88,7 +88,7 @@ typedef union } while (0) #define eui64_setlo32(e, l) eui64_set32(e, l) -char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */ +char *eui64_ntoa(eui64_t); /* Returns ascii representation of id */ #endif /* __EUI64_H__ */ #endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c index 4a09c9aa..593649ce 100644 --- a/src/netif/ppp/ipv6cp.c +++ b/src/netif/ppp/ipv6cp.c @@ -138,8 +138,6 @@ * $Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $ */ -#define RCSID "$Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $" - /* * TODO: * @@ -150,6 +148,10 @@ * since SVR4 && (SNI || __USLC__) didn't work properly) */ +#include "lwip/opt.h" +#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if 0 /* UNUSED */ #include #include #include @@ -159,21 +161,16 @@ #include #include #include +#endif /* UNUSED */ -#include "pppd.h" +#include "ppp_impl.h" #include "fsm.h" #include "ipcp.h" #include "ipv6cp.h" #include "magic.h" -#include "pathnames.h" - -static const char rcsid[] = RCSID; +/* FIXME: clean that */ /* global vars */ -ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */ -ipv6cp_options ipv6cp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -ipv6cp_options ipv6cp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -ipv6cp_options ipv6cp_hisoptions[NUM_PPP]; /* Options that we ack'd */ int no_ifaceid_neg = 0; /* local vars */ @@ -182,18 +179,16 @@ static int ipv6cp_is_up; /* * Callbacks for fsm code. (CI = Configuration Information) */ -static void ipv6cp_resetci __P((fsm *)); /* Reset our CI */ -static int ipv6cp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipv6cp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipv6cp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipv6cp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ -static int ipv6cp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipv6cp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipv6cp_up __P((fsm *)); /* We're UP */ -static void ipv6cp_down __P((fsm *)); /* We're DOWN */ -static void ipv6cp_finished __P((fsm *)); /* Don't need lower layer */ - -fsm ipv6cp_fsm[NUM_PPP]; /* IPV6CP fsm structure */ +static void ipv6cp_resetci(fsm *f); /* Reset our CI */ +static int ipv6cp_cilen(fsm *f); /* Return length of our CI */ +static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */ +static int ipv6cp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ +static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */ +static int ipv6cp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ +static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */ +static void ipv6cp_up(fsm *f); /* We're UP */ +static void ipv6cp_down(fsm *f); /* We're DOWN */ +static void ipv6cp_finished(fsm *f); /* Don't need lower layer */ static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ ipv6cp_resetci, /* Reset our Configuration Information */ @@ -213,11 +208,12 @@ static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ "IPV6CP" /* String name of protocol */ }; +#if PPP_OPTIONS /* * Command-line options. */ -static int setifaceid __P((char **arg)); -static void printifaceid __P((option_t *, +static int setifaceid(char **arg)); +static void printifaceid(option_t *, void (*)(void *, char *, ...), void *)); static option_t ipv6cp_option_list[] = { @@ -254,23 +250,31 @@ static option_t ipv6cp_option_list[] = { { NULL } }; - +#endif /* PPP_OPTIONS */ /* * Protocol entry points from main code. */ -static void ipv6cp_init __P((int)); -static void ipv6cp_open __P((int)); -static void ipv6cp_close __P((int, char *)); -static void ipv6cp_lowerup __P((int)); -static void ipv6cp_lowerdown __P((int)); -static void ipv6cp_input __P((int, u_char *, int)); -static void ipv6cp_protrej __P((int)); -static int ipv6cp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); -static void ipv6_check_options __P((void)); -static int ipv6_demand_conf __P((int)); -static int ipv6_active_pkt __P((u_char *, int)); +static void ipv6cp_init(ppp_pcb *pcb); +static void ipv6cp_open(ppp_pcb *pcb); +static void ipv6cp_close(ppp_pcb *pcb, char *reason); +static void ipv6cp_lowerup(ppp_pcb *pcb); +static void ipv6cp_lowerdown(ppp_pcb *pcb); +static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len); +static void ipv6cp_protrej(ppp_pcb *pcb); +#if PPP_OPTIONS +static void ipv6_check_options(void); +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT +static int ipv6_demand_conf(int u); +#endif /* DEMAND_SUPPORT */ +#if PRINTPKT_SUPPORT +static int ipv6cp_printpkt(u_char *p, int plen, + void (*printer)(void *, char *, ...), void *arg); +#endif /* PRINTPKT_SUPPORT */ +#if PPP_DEMAND +static int ipv6_active_pkt(u_char *pkt, int len); +#endif /* PPP_DEMAND */ struct protent ipv6cp_protent = { PPP_IPV6CP, @@ -281,20 +285,30 @@ struct protent ipv6cp_protent = { ipv6cp_lowerdown, ipv6cp_open, ipv6cp_close, +#if PRINTPKT_SUPPORT ipv6cp_printpkt, +#endif /* PRINTPKT_SUPPORT */ NULL, - 0, + 1, +#if PRINTPKT_SUPPORT "IPV6CP", "IPV6", +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS ipv6cp_option_list, ipv6_check_options, +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT ipv6_demand_conf, ipv6_active_pkt +#endif /* DEMAND_SUPPORT */ }; -static void ipv6cp_clear_addrs __P((int, eui64_t, eui64_t)); -static void ipv6cp_script __P((char *)); -static void ipv6cp_script_done __P((void *)); +static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid); +#if 0 /* UNUSED */ +static void ipv6cp_script(char *)); +static void ipv6cp_script_done(void *)); +#endif /* UNUSED */ /* * Lengths of configuration options. @@ -306,6 +320,7 @@ static void ipv6cp_script_done __P((void *)); #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") +#if 0 /* UNUSED */ /* * This state variable is used to ensure that we don't * run an ipcp-up/down script while one is already running. @@ -315,7 +330,9 @@ static enum script_state { s_up, } ipv6cp_script_state; static pid_t ipv6cp_script_pid; +#endif /* UNUSED */ +#if PPP_OPTIONS /* * setifaceid - set the interface identifiers manually */ @@ -380,7 +397,7 @@ char *llv6_ntoa(eui64_t ifaceid); static void printifaceid(opt, printer, arg) option_t *opt; - void (*printer) __P((void *, char *, ...)); + void (*printer)(void *, char *, ...)); void *arg; { ipv6cp_options *wo = &ipv6cp_wantoptions[0]; @@ -391,6 +408,7 @@ printifaceid(opt, printer, arg) if (wo->opt_remote) printer(arg, "%s", llv6_ntoa(wo->hisid)); } +#endif /* PPP_OPTIONS */ /* * Make a string representation of a network address. @@ -409,18 +427,15 @@ llv6_ntoa(ifaceid) /* * ipv6cp_init - Initialize IPV6CP. */ -static void -ipv6cp_init(unit) - int unit; -{ - fsm *f = &ipv6cp_fsm[unit]; - ipv6cp_options *wo = &ipv6cp_wantoptions[unit]; - ipv6cp_options *ao = &ipv6cp_allowoptions[unit]; +static void ipv6cp_init(ppp_pcb *pcb) { + fsm *f = &pcb->ipv6cp_fsm; + ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; + ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; - f->unit = unit; + f->pcb = pcb; f->protocol = PPP_IPV6CP; f->callbacks = &ipv6cp_callbacks; - fsm_init(&ipv6cp_fsm[unit]); + fsm_init(f); memset(wo, 0, sizeof(*wo)); memset(ao, 0, sizeof(*ao)); @@ -441,58 +456,40 @@ ipv6cp_init(unit) /* * ipv6cp_open - IPV6CP is allowed to come up. */ -static void -ipv6cp_open(unit) - int unit; -{ - fsm_open(&ipv6cp_fsm[unit]); +static void ipv6cp_open(ppp_pcb *pcb) { + fsm_open(&pcb->ipv6cp_fsm); } /* * ipv6cp_close - Take IPV6CP down. */ -static void -ipv6cp_close(unit, reason) - int unit; - char *reason; -{ - fsm_close(&ipv6cp_fsm[unit], reason); +static void ipv6cp_close(ppp_pcb *pcb, char *reason) { + fsm_close(&pcb->ipv6cp_fsm, reason); } /* * ipv6cp_lowerup - The lower layer is up. */ -static void -ipv6cp_lowerup(unit) - int unit; -{ - fsm_lowerup(&ipv6cp_fsm[unit]); +static void ipv6cp_lowerup(ppp_pcb *pcb) { + fsm_lowerup(&pcb->ipv6cp_fsm); } /* * ipv6cp_lowerdown - The lower layer is down. */ -static void -ipv6cp_lowerdown(unit) - int unit; -{ - fsm_lowerdown(&ipv6cp_fsm[unit]); +static void ipv6cp_lowerdown(ppp_pcb *pcb) { + fsm_lowerdown(&pcb->ipv6cp_fsm); } /* * ipv6cp_input - Input IPV6CP packet. */ -static void -ipv6cp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm_input(&ipv6cp_fsm[unit], p, len); +static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len) { + fsm_input(&pcb->ipv6cp_fsm, p, len); } @@ -501,25 +498,21 @@ ipv6cp_input(unit, p, len) * * Pretend the lower layer went down, so we shut up. */ -static void -ipv6cp_protrej(unit) - int unit; -{ - fsm_lowerdown(&ipv6cp_fsm[unit]); +static void ipv6cp_protrej(ppp_pcb *pcb) { + fsm_lowerdown(&pcb->ipv6cp_fsm); } /* * ipv6cp_resetci - Reset our CI. */ -static void -ipv6cp_resetci(f) - fsm *f; -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; +static void ipv6cp_resetci(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; - wo->req_ifaceid = wo->neg_ifaceid && ipv6cp_allowoptions[f->unit].neg_ifaceid; + wo->req_ifaceid = wo->neg_ifaceid && ao->neg_ifaceid; if (!wo->opt_local) { eui64_magic_nz(wo->ourid); @@ -533,11 +526,9 @@ ipv6cp_resetci(f) /* * ipv6cp_cilen - Return length of our CI. */ -static int -ipv6cp_cilen(f) - fsm *f; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; +static int ipv6cp_cilen(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; #define LENCIVJ(neg) (neg ? CILEN_COMPRESS : 0) #define LENCIIFACEID(neg) (neg ? CILEN_IFACEID : 0) @@ -550,13 +541,9 @@ ipv6cp_cilen(f) /* * ipv6cp_addci - Add our desired CIs to a packet. */ -static void -ipv6cp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; +static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; int len = *lenp; #define ADDCIVJ(opt, neg, val) \ @@ -598,13 +585,9 @@ ipv6cp_addci(f, ucp, lenp) * 0 - Ack was bad. * 1 - Ack was good. */ -static int -ipv6cp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; +static int ipv6cp_ackci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; u_short cilen, citype, cishort; eui64_t ifaceid; @@ -669,14 +652,9 @@ bad: * 0 - Nak was bad. * 1 - Nak was good. */ -static int -ipv6cp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; +static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; u_char citype, cilen, *next; u_short cishort; eui64_t ifaceid; @@ -807,13 +785,9 @@ bad: /* * ipv6cp_rejci - Reject some of our CIs. */ -static int -ipv6cp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; +static int ipv6cp_rejci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; u_char cilen; u_short cishort; eui64_t ifaceid; @@ -881,18 +855,17 @@ bad: * 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. + * + * inp = Requested CIs + * len = Length of requested CIs + * */ -static int -ipv6cp_reqci(f, inp, len, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *len; /* Length of requested CIs */ - int reject_if_disagree; -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; - ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; - ipv6cp_options *ao = &ipv6cp_allowoptions[f->unit]; - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; +static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; + ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; + ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; u_char *cip, *next; /* Pointer to current and next CIs */ u_short cilen, citype; /* Parsed len, type */ u_short cishort; /* Parsed short value */ @@ -1034,7 +1007,7 @@ endswitch: /* Need to move CI? */ if (ucp != cip) - BCOPY(cip, ucp, cilen); /* Move it */ + MEMCPY(ucp, cip, cilen); /* Move it */ /* Update output pointer */ INCPTR(cilen, ucp); @@ -1064,14 +1037,12 @@ endswitch: return (rc); /* Return final code */ } - +#if PPP_OPTION /* * ipv6_check_options - check that any IP-related options are OK, * and assign appropriate defaults. */ -static void -ipv6_check_options() -{ +static void ipv6_check_options() { ipv6cp_options *wo = &ipv6cp_wantoptions[0]; if (!ipv6cp_protent.enabled_flag) @@ -1123,16 +1094,14 @@ ipv6_check_options() exit(1); } } +#endif /* PPP_OPTION */ - +#if DEMAND_SUPPORT /* * ipv6_demand_conf - configure the interface as though * IPV6CP were up, for use with dial-on-demand. */ -static int -ipv6_demand_conf(u) - int u; -{ +static int ipv6_demand_conf(int u) { ipv6cp_options *wo = &ipv6cp_wantoptions[u]; #if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) @@ -1159,6 +1128,7 @@ ipv6_demand_conf(u) return 1; } +#endif /* DEMAND_SUPPORT */ /* @@ -1166,13 +1136,11 @@ ipv6_demand_conf(u) * * Configure the IPv6 network interface appropriately and bring it up. */ -static void -ipv6cp_up(f) - fsm *f; -{ - ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; +static void ipv6cp_up(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; + ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; IPV6CPDEBUG(("ipv6cp: up")); @@ -1185,28 +1153,31 @@ ipv6cp_up(f) if(!no_ifaceid_neg) { if (eui64_iszero(ho->hisid)) { error("Could not determine remote LL address"); - ipv6cp_close(f->unit, "Could not determine remote LL address"); + ipv6cp_close(f->pcb, "Could not determine remote LL address"); return; } if (eui64_iszero(go->ourid)) { error("Could not determine local LL address"); - ipv6cp_close(f->unit, "Could not determine local LL address"); + ipv6cp_close(f->pcb, "Could not determine local LL address"); return; } if (eui64_equals(go->ourid, ho->hisid)) { error("local and remote LL addresses are equal"); - ipv6cp_close(f->unit, "local and remote LL addresses are equal"); + ipv6cp_close(f->pcb, "local and remote LL addresses are equal"); return; } } +#if 0 /* UNUSED */ script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0); script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0); +#endif /* UNUSED */ #ifdef IPV6CP_COMP /* set tcp compression */ sif6comp(f->unit, ho->neg_vj); #endif +#if DEMAND_SUPPORT /* * If we are doing dial-on-demand, the interface is already * configured, so we put out any saved-up packets, then set the @@ -1221,10 +1192,10 @@ ipv6cp_up(f) if (! eui64_equals(ho->hisid, wo->hisid)) warn("Remote LL address changed to %s", llv6_ntoa(ho->hisid)); - ipv6cp_clear_addrs(f->unit, go->ourid, ho->hisid); + ipv6cp_clear_addrs(f->pcb, go->ourid, ho->hisid); /* Set the interface to the new addresses */ - if (!sif6addr(f->unit, go->ourid, ho->hisid)) { + if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { if (debug) warn("sif6addr failed"); ipv6cp_close(f->unit, "Interface configuration failed"); @@ -1235,7 +1206,9 @@ ipv6cp_up(f) demand_rexmit(PPP_IPV6); sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); - } else { + } else +#endif /* DEMAND_SUPPORT */ + { /* * Set LL addresses */ @@ -1257,31 +1230,30 @@ ipv6cp_up(f) return; } #else - if (!sifup(f->unit)) { - if (debug) - warn("sifup failed (IPV6)"); - ipv6cp_close(f->unit, "Interface configuration failed"); + if (!sifup(f->pcb)) { + PPPDEBUG(LOG_DEBUG, ("sifup failed (IPV6)")); + ipv6cp_close(f->pcb, "Interface configuration failed"); return; } #endif /* defined(SOL2) */ #if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sif6addr(f->unit, go->ourid, ho->hisid)) { - if (debug) - warn("sif6addr failed"); - ipv6cp_close(f->unit, "Interface configuration failed"); + if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { + PPPDEBUG(LOG_DEBUG, ("sif6addr failed")); + ipv6cp_close(f->pcb, "Interface configuration failed"); return; } #endif - sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); + sifnpmode(f->pcb, PPP_IPV6, NPMODE_PASS); notice("local LL address %s", llv6_ntoa(go->ourid)); notice("remote LL address %s", llv6_ntoa(ho->hisid)); } - np_up(f->unit, PPP_IPV6); + np_up(f->pcb, PPP_IPV6); ipv6cp_is_up = 1; +#if 0 /* UNUSED */ /* * Execute the ipv6-up script, like this: * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL @@ -1290,6 +1262,7 @@ ipv6cp_up(f) ipv6cp_script_state = s_up; ipv6cp_script(_PATH_IPV6UP); } +#endif /* UNUSED */ } @@ -1299,28 +1272,34 @@ ipv6cp_up(f) * Take the IPv6 network interface down, clear its addresses * and delete routes through it. */ -static void -ipv6cp_down(f) - fsm *f; -{ +static void ipv6cp_down(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; + IPV6CPDEBUG(("ipv6cp: down")); +#if PPP_STATS_SUPPORT update_link_stats(f->unit); +#endif /* PPP_STATS_SUPPORT */ if (ipv6cp_is_up) { ipv6cp_is_up = 0; - np_down(f->unit, PPP_IPV6); + np_down(f->pcb, PPP_IPV6); } #ifdef IPV6CP_COMP sif6comp(f->unit, 0); #endif +#if PPP_DEMAND /* * If we are doing dial-on-demand, set the interface * to queue up outgoing packets (for now). */ if (demand) { - sifnpmode(f->unit, PPP_IPV6, NPMODE_QUEUE); - } else { - sifnpmode(f->unit, PPP_IPV6, NPMODE_DROP); + sifnpmode(f->pcb, PPP_IPV6, NPMODE_QUEUE); + } else +#endif /* PPP_DEMAND */ + { + sifnpmode(f->pcb, PPP_IPV6, NPMODE_DROP); #if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC))) #if defined(SOL2) sif6down(f->unit); @@ -1328,19 +1307,21 @@ ipv6cp_down(f) sifdown(f->unit); #endif /* defined(SOL2) */ #endif - ipv6cp_clear_addrs(f->unit, - ipv6cp_gotoptions[f->unit].ourid, - ipv6cp_hisoptions[f->unit].hisid); + ipv6cp_clear_addrs(f->pcb, + go->ourid, + ho->hisid); #if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC))) - sifdown(f->unit); + sifdown(f->pcb); #endif } +#if 0 /* UNUSED */ /* Execute the ipv6-down script */ if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) { ipv6cp_script_state = s_down; ipv6cp_script(_PATH_IPV6DOWN); } +#endif /* UNUSED */ } @@ -1348,27 +1329,20 @@ ipv6cp_down(f) * ipv6cp_clear_addrs() - clear the interface addresses, routes, * proxy neighbour discovery entries, etc. */ -static void -ipv6cp_clear_addrs(unit, ourid, hisid) - int unit; - eui64_t ourid; - eui64_t hisid; -{ - cif6addr(unit, ourid, hisid); +static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid) { + cif6addr(pcb, ourid, hisid); } /* * ipv6cp_finished - possibly shut down the lower layers. */ -static void -ipv6cp_finished(f) - fsm *f; -{ - np_finished(f->unit, PPP_IPV6); +static void ipv6cp_finished(fsm *f) { + np_finished(f->pcb, PPP_IPV6); } +#if 0 /* UNUSED */ /* * ipv6cp_script_done - called when the ipv6-up or ipv6-down script * has finished. @@ -1422,7 +1396,9 @@ ipv6cp_script(script) ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, NULL, 0); } +#endif /* UNUSED */ +#if PRINTPKT_SUPPORT /* * ipv6cp_printpkt - print the contents of an IPV6CP packet. */ @@ -1431,13 +1407,8 @@ static char *ipv6cp_codenames[] = { "TermReq", "TermAck", "CodeRej" }; -static int -ipv6cp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ +static int ipv6cp_printpkt(u_char *p, int plen, + void (*printer)(void *, char *, ...), void *arg) { int code, id, len, olen; u_char *pstart, *optend; u_short cishort; @@ -1518,7 +1489,9 @@ ipv6cp_printpkt(p, plen, printer, arg) return p - pstart; } +#endif /* PRINTPKT_SUPPORT */ +#if PPP_DEMAND /* * ipv6_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 @@ -1538,11 +1511,7 @@ ipv6cp_printpkt(p, plen, printer, arg) #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) #define get_tcpflags(x) (((unsigned char *)(x))[13]) -static int -ipv6_active_pkt(pkt, len) - u_char *pkt; - int len; -{ +static int ipv6_active_pkt(u_char *pkt, int len) { u_char *tcp; len -= PPP_HDRLEN; @@ -1560,3 +1529,6 @@ ipv6_active_pkt(pkt, len) return 0; return 1; } +#endif /* PPP_DEMAND */ + +#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/src/netif/ppp/ipv6cp.h b/src/netif/ppp/ipv6cp.h index cc4568de..6c7fe489 100644 --- a/src/netif/ppp/ipv6cp.h +++ b/src/netif/ppp/ipv6cp.h @@ -138,6 +138,14 @@ * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $ */ +#include "lwip/opt.h" +#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef IPV6CP_H +#define IPV6CP_H + +#include "eui64.h" + /* * Options. */ @@ -162,10 +170,7 @@ typedef struct ipv6cp_options { eui64_t ourid, hisid; /* Interface identifiers */ } ipv6cp_options; -extern fsm ipv6cp_fsm[]; -extern ipv6cp_options ipv6cp_wantoptions[]; -extern ipv6cp_options ipv6cp_gotoptions[]; -extern ipv6cp_options ipv6cp_allowoptions[]; -extern ipv6cp_options ipv6cp_hisoptions[]; - extern struct protent ipv6cp_protent; + +#endif /* IPV6CP_H */ +#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 723af60d..27563925 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -117,6 +117,9 @@ #if VJ_SUPPORT #include "vj.h" #endif /* VJ_SUPPORT */ +#if PPP_IPV6_SUPPORT +#include "ipv6cp.h" +#endif /* PPP_IPV6_SUPPORT */ #if PPPOE_SUPPORT #include "netif/ppp_oe.h" @@ -158,7 +161,7 @@ struct protent *protocols[] = { &cbcp_protent, #endif &ipcp_protent, -#ifdef INET6 +#if PPP_IPV6_SUPPORT &ipv6cp_protent, #endif #if CCP_SUPPORT @@ -202,10 +205,12 @@ static void ppp_free_current_input_packet(ppp_pcb_rx *pcrx); #endif /* PPPOS_SUPPORT */ static err_t ppp_netif_init_cb(struct netif *netif); -static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); +static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); +static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr_t *ipaddr); +static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol); #if PPPOE_SUPPORT -static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p); +static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol); /* function called by ppp_write() */ static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n); #endif /* PPPOE_SUPPORT */ @@ -572,11 +577,15 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { case PPP_IP: /* Internet Protocol */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->num, pb->len)); - if (pcb->netif.input) { - pcb->netif.input(pb, &pcb->netif); - return; - } - break; + ip_input(pb, &pcb->netif); + return; + +#if PPP_IPV6_SUPPORT + case PPP_IPV6: /* Interval Protocol Version 6 */ + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->num, pb->len)); + ip6_input(pb, &pcb->netif); + return; +#endif /* PPP_IPV6_SUPPORT */ default: { @@ -803,7 +812,10 @@ ppp_receive_wakeup(ppp_pcb *pcb) static err_t ppp_netif_init_cb(struct netif *netif) { netif->name[0] = 'p'; netif->name[1] = 'p'; - netif->output = ppp_netif_output; + netif->output = ppp_netif_output_ip4; +#if PPP_IPV6_SUPPORT + netif->output_ip6 = ppp_netif_output_ip6; +#endif /* PPP_IPV6_SUPPORT */ netif->mtu = netif_get_mtu((ppp_pcb*)netif->state); netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; #if LWIP_NETIF_HOSTNAME @@ -904,21 +916,33 @@ ppp_append(u_char c, struct pbuf *nb, ext_accm *out_accm) } #endif /* PPPOS_SUPPORT */ + +/* Send a IPv4 packet on the given connection. + */ +static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { + LWIP_UNUSED_ARG(ipaddr); + return ppp_netif_output(netif, pb, PPP_IP); +} + +/* Send a IPv6 packet on the given connection. + */ +static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr_t *ipaddr) { + LWIP_UNUSED_ARG(ipaddr); + return ppp_netif_output(netif, pb, PPP_IPV6); +} + /* Send a packet on the given connection. * * This is the low level function that send the PPP packet. */ -static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { +static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol) { ppp_pcb *pcb = (ppp_pcb*)netif->state; #if PPPOS_SUPPORT - u_short protocol = PPP_IP; u_int fcs_out = PPP_INITFCS; struct pbuf *head = NULL, *tail = NULL, *p; u_char c; #endif /* PPPOS_SUPPORT */ - LWIP_UNUSED_ARG(ipaddr); - /* Validate parameters. */ /* We let any protocol value go through - it can't hurt us * and the peer will just drop it if it's not accepting it. */ @@ -942,7 +966,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i #if PPPOE_SUPPORT if(pcb->ethif) { - return ppp_netif_output_over_ethernet(pcb, pb); + return ppp_netif_output_over_ethernet(pcb, pb, protocol); } #endif /* PPPOE_SUPPORT */ @@ -1054,10 +1078,10 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, ip_addr_t *i return ERR_OK; } + #if PPPOE_SUPPORT -static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { +static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol) { struct pbuf *pb; - u_short protocol = PPP_IP; int i=0; u16_t tot_len; @@ -1817,6 +1841,40 @@ int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr) { } +#if PPP_IPV6_SUPPORT +#define IN6_LLADDR_FROM_EUI64(ip6, eui64) do { \ + memset(&ip6.addr, 0, sizeof(ip6_addr_t)); \ + ip6.addr[0] = PP_HTONL(0xfe800000); \ + eui64_copy(eui64, ip6.addr[2]); \ + } while (0) + +/******************************************************************** + * + * sif6addr - Config the interface with an IPv6 link-local address + */ +int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { + + IN6_LLADDR_FROM_EUI64(pcb->addrs.our6_ipaddr, our_eui64); + IN6_LLADDR_FROM_EUI64(pcb->addrs.his6_ipaddr, his_eui64); + return 1; +} + +/******************************************************************** + * + * cif6addr - Remove IPv6 address from interface + */ +int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { + + LWIP_UNUSED_ARG(our_eui64); + LWIP_UNUSED_ARG(his_eui64); + + IP6_ADDR(&pcb->addrs.our6_ipaddr, 0, 0,0,0,0); + IP6_ADDR(&pcb->addrs.his6_ipaddr, 0, 0,0,0,0); + return 1; +} +#endif /* PPP_IPV6_SUPPORT */ + + /* * sdns - Config the DNS servers */ @@ -1850,11 +1908,14 @@ int sifup(ppp_pcb *pcb) { netif_remove(&pcb->netif); if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, - &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, ip_input)) { + &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pcb->num)); return 0; } - +#if PPP_IPV6_SUPPORT + ip6_addr_copy(pcb->netif.ip6_addr[0], pcb->addrs.our6_ipaddr); + netif_ip6_addr_set_state(&pcb->netif, 0, IP6_ADDR_PREFERRED); +#endif /* PPP_IPV6_SUPPORT */ netif_set_up(&pcb->netif); pcb->if_up = 1; pcb->err_code = PPPERR_NONE; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 1a7cc87e..0c2a3cda 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -44,6 +44,9 @@ #include "lwip/netif.h" #include "lwip/sys.h" #include "lwip/timers.h" +#if PPP_IPV6_SUPPORT +#include "lwip/ip6_addr.h" +#endif /* PPP_IPV6_SUPPORT */ #include "vj.h" @@ -140,6 +143,9 @@ typedef struct ppp_pcb_s ppp_pcb; #include "fsm.h" #include "lcp.h" #include "ipcp.h" +#if PPP_IPV6_SUPPORT +#include "ipv6cp.h" +#endif /* PPP_IPV6_SUPPORT */ #if PAP_SUPPORT #include "upap.h" #endif /* PAP_SUPPORT */ @@ -217,7 +223,11 @@ typedef struct ppp_settings_s { } ppp_settings; struct ppp_addrs { - ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; + ip_addr_t our_ipaddr, his_ipaddr, netmask; + ip_addr_t dns1, dns2; +#if PPP_IPV6_SUPPORT + ip6_addr_t our6_ipaddr, his6_ipaddr; +#endif /* PPP_IPV6_SUPPORT */ }; /* FIXME: find a way to move ppp_dev_states and ppp_pcb_rx_s to ppp_impl.h */ @@ -355,6 +365,14 @@ struct ppp_pcb_s { ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ ipcp_options ipcp_hisoptions; /* Options that we ack'd */ + +#if PPP_IPV6_SUPPORT + fsm ipv6cp_fsm; /* IPV6CP fsm structure */ + ipv6cp_options ipv6cp_wantoptions; /* Options that we want to request */ + ipv6cp_options ipv6cp_gotoptions; /* Options that peer ack'd */ + ipv6cp_options ipv6cp_allowoptions; /* Options we allow peer to request */ + ipv6cp_options ipv6cp_hisoptions; /* Options that we ack'd */ +#endif /* PPP_IPV6_SUPPORT */ }; /************************ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 2c0c7194..25a3913f 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -48,10 +48,6 @@ #include "ppp.h" #include "pppdebug.h" -#ifdef INET6 -#include "eui64.h" -#endif - /* * Limits. */ @@ -89,9 +85,9 @@ #define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ #define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ #endif /* VJ_SUPPORT */ -#ifdef INET6 +#if PPP_IPV6_SUPPORT #define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ -#endif /* INET6 */ +#endif /* PPP_IPV6_SUPPORT */ #if CCP_SUPPORT #define PPP_COMP 0xfd /* compressed packet */ #endif /* CCP_SUPPORT */ @@ -100,9 +96,9 @@ #define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ #define PPP_IPXCP 0x802b /* IPX Control Protocol */ #endif /* UNUSED */ -#ifdef INET6 +#if PPP_IPV6_SUPPORT #define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#endif /* INET6 */ +#endif /* PPP_IPV6_SUPPORT */ #if CCP_SUPPORT #define PPP_CCP 0x80fd /* Compression Control Protocol */ #endif /* CCP_SUPPORT */ @@ -413,6 +409,11 @@ int ppp_recv_config(ppp_pcb *pcb, int mru, u_int32_t accm, int pcomp, int accomp int sifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr); +#if PPP_IPV6_SUPPORT +int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); +int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); +#endif /* PPP_IPV6_SUPPORT */ + int sdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2); int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2); diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 95cf9cbc..19abdbdd 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -720,7 +720,7 @@ void dump_packet(const char *tag, unsigned char *p, int len) { proto = (p[0] << 8) + p[1]; if (proto == PPP_IP) return; -#ifdef INET6 +#if PPP_IPV6_SUPPORT if (proto == PPP_IPV6 || proto == PPP_IPV6CP) return; #endif From 8093b55e861fe8a3fed96e32c31dfc579f225caa Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 21 Jun 2012 22:28:52 +0200 Subject: [PATCH 207/320] don't destroy and create the PPP interface each time sifup() is called (it is actually called twice with IPv4 + IPv6 enabled) --- src/netif/ppp/ppp.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 27563925..6ebbf797 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -251,6 +251,7 @@ ppp_pcb *ppp_new(void) { #if PPP_DEBUG pcb->num = ppp_num++; #endif /* PPP_DEBUG */ + IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); pcb->lcp_loopbackfail = DEFLOOPBACKFAIL; new_phase(pcb, PHASE_INITIALIZE); @@ -1906,16 +1907,22 @@ int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { */ int sifup(ppp_pcb *pcb) { - netif_remove(&pcb->netif); - if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, - &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { - PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pcb->num)); - return 0; + if(!pcb->if_up) { + if(!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { + PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pcb->num)); + return 0; + } + } else { + netif_set_addr(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr); } + #if PPP_IPV6_SUPPORT ip6_addr_copy(pcb->netif.ip6_addr[0], pcb->addrs.our6_ipaddr); netif_ip6_addr_set_state(&pcb->netif, 0, IP6_ADDR_PREFERRED); #endif /* PPP_IPV6_SUPPORT */ + netif_set_up(&pcb->netif); pcb->if_up = 1; pcb->err_code = PPPERR_NONE; @@ -1934,6 +1941,9 @@ int sifup(ppp_pcb *pcb) { */ int sifdown(ppp_pcb *pcb) { + if(!pcb->if_up) + return 1; + pcb->if_up = 0; /* make sure the netif status callback is called */ netif_set_down(&pcb->netif); From 8576ee098100759526f9ce3c99739e5225cb01b5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 21 Jun 2012 23:08:20 +0200 Subject: [PATCH 208/320] randomized seed when using MD5 random support and PPPoE --- src/netif/ppp/magic.c | 12 ++++++------ src/netif/ppp/ppp.c | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 5dea7320..49da633e 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -113,7 +113,7 @@ static long magic_randcount = 0; /* Pseudo-random incrementer */ void magic_churnrand(char *rand_data, u32_t rand_len) { md5_context md5; - /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", rand_len, rand_data)); */ + /* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: %u@%P\n", rand_len, rand_data)); */ md5_starts(&md5); md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); if (rand_data) { @@ -121,14 +121,14 @@ void magic_churnrand(char *rand_data, u32_t rand_len) { } else { struct { /* INCLUDE fields for any system sources of randomness */ - char foobar; + u32_t jiffies; } sys_data; - + sys_data.jiffies = sys_jiffies(); /* Load sys_data fields here. */ md5_update(&md5, (u_char *)&sys_data, sizeof(sys_data)); } md5_finish(&md5, (u_char *)magic_randpool); -/* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ +/* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: -> 0\n")); */ } /* @@ -149,14 +149,14 @@ void magic_randomize(void) { * random_bytes - Fill a buffer with random bytes. * * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using churnRand(). + * random when used faster than randomness is supplied using magic_churnrand(). * Note: It's important that there be sufficient randomness in magic_randpool * before this is called for otherwise the range of the result may be * narrow enough to make a search feasible. * * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 * - * XXX Why does he not just call churnRand() for each block? Probably + * XXX Why does he not just call magic_churnrand() for each block? Probably * so that you don't ever publish the seed which could possibly help * predict future values. * XXX Why don't we preserve md5 between blocks and just update it with diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 6ebbf797..61e5c13a 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -642,6 +642,7 @@ drop: out: pbuf_free(pb); + magic_randomize(); return; #if 0 From bda73b1bc966aadaeaca20b22f6c68af4f1ea65c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 21 Jun 2012 23:31:23 +0200 Subject: [PATCH 209/320] replaced call from ppp_write to ppp_write_pbuf --- src/netif/ppp/chap-new.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index c97844bb..a715b7aa 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -226,6 +226,7 @@ void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code) { */ static void chap_timeout(void *arg) { ppp_pcb *pcb = (ppp_pcb*)arg; + struct pbuf *p; pcb->chap_server.flags &= ~TIMEOUT_PENDING; if ((pcb->chap_server.flags & CHALLENGE_VALID) == 0) { @@ -239,7 +240,11 @@ static void chap_timeout(void *arg) { return; } - ppp_write(pcb, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); + p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PBUF_RAM); + if(NULL == p) + return; + MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); + ppp_write_pbuf(pcb, p); ++pcb->chap_server.challenge_xmits; pcb->chap_server.flags |= TIMEOUT_PENDING; TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time); @@ -417,11 +422,15 @@ static void chap_respond(ppp_pcb *pcb, int id, unsigned char *pkt, int len) { int clen, nlen; int secret_len; - unsigned char *p; - unsigned char response[RESP_MAX_PKTLEN]; + struct pbuf *p; + u_char *outp; char rname[MAXNAMELEN+1]; char secret[MAXSECRETLEN+1]; + p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PBUF_RAM); + if(NULL == p) + return; + if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) return; /* not ready */ if (len < 2 || len < pkt[0] + 1) @@ -444,26 +453,27 @@ static void chap_respond(ppp_pcb *pcb, int id, warn("No CHAP secret found for authenticating us to %q", rname); } - p = response; - MAKEHEADER(p, PPP_CHAP); - p += CHAP_HDRLEN; + outp = p->payload; + MAKEHEADER(outp, PPP_CHAP); + outp += CHAP_HDRLEN; - pcb->chap_client.digest->make_response(p, id, pcb->chap_client.name, pkt, + pcb->chap_client.digest->make_response(outp, id, pcb->chap_client.name, pkt, secret, secret_len, pcb->chap_client.priv); memset(secret, 0, secret_len); - clen = *p; + clen = *outp; nlen = strlen(pcb->chap_client.name); - memcpy(p + clen + 1, pcb->chap_client.name, nlen); + memcpy(outp + clen + 1, pcb->chap_client.name, nlen); - p = response + PPP_HDRLEN; + outp = (u_char*)p->payload + PPP_HDRLEN; len = CHAP_HDRLEN + clen + 1 + nlen; - p[0] = CHAP_RESPONSE; - p[1] = id; - p[2] = len >> 8; - p[3] = len; + outp[0] = CHAP_RESPONSE; + outp[1] = id; + outp[2] = len >> 8; + outp[3] = len; - ppp_write(pcb, response, PPP_HDRLEN + len); + pbuf_realloc(p, PPP_HDRLEN + len); + ppp_write_pbuf(pcb, p); } static void chap_handle_status(ppp_pcb *pcb, int code, int id, From 9b7860d6ec2493377ca526aa9af27e3db5eb6a57 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 14:17:35 +0200 Subject: [PATCH 210/320] merged ppp_write and ppp_write_pbuf --- src/netif/ppp/chap-new.c | 6 +++--- src/netif/ppp/eap.c | 16 ++++++++-------- src/netif/ppp/fsm.c | 4 ++-- src/netif/ppp/ppp.c | 27 +++++++++++++++------------ src/netif/ppp/ppp_impl.h | 3 +-- src/netif/ppp/upap.c | 4 ++-- 6 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index a715b7aa..f98719e4 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -244,7 +244,7 @@ static void chap_timeout(void *arg) { if(NULL == p) return; MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); ++pcb->chap_server.challenge_xmits; pcb->chap_server.flags |= TIMEOUT_PENDING; TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time); @@ -347,7 +347,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, outp[3] = len; if (mlen > 0) memcpy(outp + CHAP_HDRLEN, pcb->chap_server.message, mlen); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); if (pcb->chap_server.flags & CHALLENGE_VALID) { pcb->chap_server.flags &= ~CHALLENGE_VALID; @@ -473,7 +473,7 @@ static void chap_respond(ppp_pcb *pcb, int id, outp[3] = len; pbuf_realloc(p, PPP_HDRLEN + len); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); } static void chap_handle_status(ppp_pcb *pcb, int code, int id, diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index f930531c..afdebea6 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -279,7 +279,7 @@ eap_state *esp; PUTCHAR(pcb->eap.es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); pcb->eap.es_server.ea_state = eapBadAuth; auth_peer_fail(pcb, PPP_EAP); @@ -310,7 +310,7 @@ eap_state *esp; PUTCHAR(pcb->eap.es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); auth_peer_success(pcb, PPP_EAP, 0, pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen); @@ -881,7 +881,7 @@ eap_state *esp; PUTSHORT(outlen, lenloc); pbuf_realloc(p, outlen + PPP_HDRLEN); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); pcb->eap.es_server.ea_requests++; @@ -1076,7 +1076,7 @@ static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, u_char *s MEMCPY(outp, str, lenstr); } - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); } /* @@ -1109,7 +1109,7 @@ static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, char *name, MEMCPY(outp, name, namelen); } - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); } #ifdef USE_SRP @@ -1148,7 +1148,7 @@ int lenstr; MEMCPY(outp, str, lenstr); } - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); } /* @@ -1185,7 +1185,7 @@ u_char *str; PUTLONG(flags, outp); MEMCPY(outp, str, SHA_DIGESTSIZE); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); } #endif /* USE_SRP */ @@ -1210,7 +1210,7 @@ static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { PUTCHAR(EAPT_NAK, outp); PUTCHAR(type, outp); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); } #ifdef USE_SRP diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index ad524a37..4fe14be9 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -732,7 +732,7 @@ static void fsm_sconfreq(fsm *f, int retransmit) { PUTSHORT(cilen + HEADERLEN, outp); pbuf_realloc(p, cilen + HEADERLEN + PPP_HDRLEN); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); /* start the retransmit timer */ --f->retransmits; @@ -767,7 +767,7 @@ void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { PUTCHAR(code, outp); PUTCHAR(id, outp); PUTSHORT(outlen, outp); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); } #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 61e5c13a..3d7fcae2 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -212,7 +212,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot #if PPPOE_SUPPORT static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol); /* function called by ppp_write() */ -static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n); +static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p); #endif /* PPPOE_SUPPORT */ static void ppp_destroy(ppp_pcb *pcb); @@ -1173,20 +1173,15 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) return PPPERR_PARAM; } -/* FIXME: improve that */ -int ppp_write_pbuf(ppp_pcb *pcb, struct pbuf *p) { - int ret = ppp_write(pcb, p->payload, p->len); - pbuf_free(p); - return ret; -} - /* - * Write n characters to a ppp link. + * Write a pbuf to a ppp link. * RETURN: >= 0 Number of characters written * -1 Failed to write to device */ -int ppp_write(ppp_pcb *pcb, const u_char *s, int n) { +int ppp_write(ppp_pcb *pcb, struct pbuf *p) { #if PPPOS_SUPPORT + u_char *s = p->payload; + int n = p->len; u_char c; u_int fcs_out; struct pbuf *head, *tail; @@ -1194,7 +1189,7 @@ int ppp_write(ppp_pcb *pcb, const u_char *s, int n) { #if PPPOE_SUPPORT if(pcb->ethif) { - return ppp_write_over_ethernet(pcb, s, n); + return ppp_write_over_ethernet(pcb, p); } #endif /* PPPOE_SUPPORT */ @@ -1204,6 +1199,7 @@ int ppp_write(ppp_pcb *pcb, const u_char *s, int n) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); return PPPERR_ALLOC; } @@ -1245,6 +1241,7 @@ int ppp_write(ppp_pcb *pcb, const u_char *s, int n) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); return PPPERR_ALLOC; } @@ -1253,11 +1250,14 @@ int ppp_write(ppp_pcb *pcb, const u_char *s, int n) { pppos_put(pcb, head); #endif /* PPPOS_SUPPORT */ + pbuf_free(p); return PPPERR_NONE; } #if PPPOE_SUPPORT -static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n) { +static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { + u_char *s = p->payload; + int n = p->len; struct pbuf *pb; /* skip address & flags */ @@ -1270,6 +1270,7 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); return PPPERR_ALLOC; } @@ -1282,6 +1283,7 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n) { if(pppoe_xmit(pcb->pppoe_sc, pb) != ERR_OK) { LINK_STATS_INC(link.err); snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); return PPPERR_DEVICE; } @@ -1292,6 +1294,7 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, const u_char *s, int n) { snmp_add_ifoutoctets(&pcb->netif, (u16_t)n); snmp_inc_ifoutucastpkts(&pcb->netif); LINK_STATS_INC(link.xmit); + pbuf_free(p); return PPPERR_NONE; } #endif /* PPPOE_SUPPORT */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 25a3913f..53c218eb 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -383,9 +383,8 @@ struct pppd_stats { /* function called by pppoe.c */ void ppp_input(ppp_pcb *pcb, struct pbuf *pb); -int ppp_write_pbuf(ppp_pcb *pcb, struct pbuf *p); /* function called by all PPP subsystems to send packets */ -int ppp_write(ppp_pcb *pcb, const u_char *s, int n); +int ppp_write(ppp_pcb *pcb, struct pbuf *p); /* functions called by auth.c link_terminated() */ void ppp_link_down(ppp_pcb *pcb); diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 91235821..eb55ec11 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -546,7 +546,7 @@ static void upap_sauthreq(ppp_pcb *pcb) { PUTCHAR(pcb->upap.us_passwdlen, outp); MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); TIMEOUT(upap_timeout, pcb, pcb->upap.us_timeouttime); ++pcb->upap.us_transmits; @@ -576,7 +576,7 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl PUTCHAR(msglen, outp); MEMCPY(outp, msg, msglen); - ppp_write_pbuf(pcb, p); + ppp_write(pcb, p); } #endif /* UNUSED */ From 77aa06df64e50624c08bd77d5ce74bfc60b9d1e8 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 17:03:59 +0200 Subject: [PATCH 211/320] improved ppp_write_over_ethernet(), don't MEMCPY the entire packet into a new pbuf --- src/netif/ppp/ppp.c | 36 +++++++++++++++++++----------------- src/netif/ppp/ppp_oe.c | 4 ++-- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 3d7fcae2..5d5826f7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1174,7 +1174,13 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) } /* - * Write a pbuf to a ppp link. + * Write a pbuf to a ppp link, only used from PPP functions + * to send PPP packets. + * + * IPv4 and IPv6 packets from lwIP are sent, respectively, + * with ppp_netif_output_ip4() and ppp_netif_output_ip6() + * functions (which are callbacks of the netif PPP interface). + * * RETURN: >= 0 Number of characters written * -1 Failed to write to device */ @@ -1256,17 +1262,13 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { #if PPPOE_SUPPORT static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { - u_char *s = p->payload; - int n = p->len; - struct pbuf *pb; + struct pbuf *ph; /* Ethernet + PPPoE header */ /* skip address & flags */ - s += 2; - n -= 2; + pbuf_header(p, -(s16_t)2); - LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); - if(!pb) { + ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN), PBUF_RAM); + if(!ph) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pcb->netif); @@ -1274,27 +1276,27 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { return PPPERR_ALLOC; } - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + pbuf_header(ph, -(s16_t)PPPOE_HDRLEN); /* hide PPPoE header */ + pbuf_cat(ph, p); + pbuf_ref(ph); /* we need the pbuf after pppoe_xmit() returned, which free the pbuf */ pcb->last_xmit = sys_jiffies(); - MEMCPY(pb->payload, s, n); - - if(pppoe_xmit(pcb->pppoe_sc, pb) != ERR_OK) { + if(pppoe_xmit(pcb->pppoe_sc, ph) != ERR_OK) { LINK_STATS_INC(link.err); snmp_inc_ifoutdiscards(&pcb->netif); - pbuf_free(p); + pbuf_free(ph); return PPPERR_DEVICE; } #if PRINTPKT_SUPPORT - dump_packet("sent", (unsigned char *)s, n); + dump_packet("sent", (unsigned char *)ph->payload, ph->len); #endif /* PRINTPKT_SUPPORT */ - snmp_add_ifoutoctets(&pcb->netif, (u16_t)n); + snmp_add_ifoutoctets(&pcb->netif, (u16_t)ph->len); snmp_inc_ifoutucastpkts(&pcb->netif); LINK_STATS_INC(link.xmit); - pbuf_free(p); + pbuf_free(ph); return PPPERR_NONE; } #endif /* PPPOE_SUPPORT */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 6bb21e24..d73eedfe 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -1067,14 +1067,14 @@ pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) len = pb->tot_len; - /* make room for Ethernet header - should not fail */ + /* make room for Ethernet + PPPoE header - should not fail */ if (pbuf_header(pb, sizeof(struct eth_hdr) + PPPOE_HEADERLEN) != 0) { /* bail out */ PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); LINK_STATS_INC(link.lenerr); pbuf_free(pb); return ERR_BUF; - } + } p = (u8_t*)pb->payload + sizeof(struct eth_hdr); PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); From 9b60b55f033fcd99a93d11c7b9176d50e1fadbf0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 17:48:31 +0200 Subject: [PATCH 212/320] SNMP prefers tot_len --- src/netif/ppp/ppp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 5d5826f7..f72734d5 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1293,7 +1293,7 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { dump_packet("sent", (unsigned char *)ph->payload, ph->len); #endif /* PRINTPKT_SUPPORT */ - snmp_add_ifoutoctets(&pcb->netif, (u16_t)ph->len); + snmp_add_ifoutoctets(&pcb->netif, (u16_t)ph->tot_len); snmp_inc_ifoutucastpkts(&pcb->netif); LINK_STATS_INC(link.xmit); pbuf_free(ph); From 6a11134a185ce384d67a021cb2b3aa523c86c84f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 17:53:39 +0200 Subject: [PATCH 213/320] fixed PPPoS suppport compilation --- src/netif/ppp/lcp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index da4435d4..5e02836f 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -409,10 +409,10 @@ static void lcp_init(ppp_pcb *pcb) { pcb->xmit_accm[2] = (u_char)((ao->asyncmap >> 16) & 0xFF); pcb->xmit_accm[3] = (u_char)((ao->asyncmap >> 24) & 0xFF); LCPDEBUG(("lcp_init: xmit_accm=%X %X %X %X\n", - xmit_accm[unit][0], - xmit_accm[unit][1], - xmit_accm[unit][2], - xmit_accm[unit][3])); + pcb->xmit_accm[0], + pcb->xmit_accm[1], + pcb->xmit_accm[2], + pcb->xmit_accm[3])); #endif /* PPPOS_SUPPORT */ } @@ -493,10 +493,10 @@ void lcp_lowerup(ppp_pcb *pcb) { | ((u_long)pcb->xmit_accm[2] << 16) | ((u_long)pcb->xmit_accm[3] << 24); LCPDEBUG(("lcp_lowerup: asyncmap=%X %X %X %X\n", - xmit_accm[unit][3], - xmit_accm[unit][2], - xmit_accm[unit][1], - xmit_accm[unit][0])); + pcb->xmit_accm[3], + pcb->xmit_accm[2], + pcb->xmit_accm[1], + pcb->xmit_accm[0])); #endif /* PPPOS_SUPPORT */ if (pcb->settings.listen_time != 0) { From dd288f70ec3e417f491740109d8a2a8647ef0a24 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 18:07:59 +0200 Subject: [PATCH 214/320] fixed sent PPPoE dump packet and copy everything we need after pppoe_xmit() free'd the pbuf --- src/netif/ppp/ppp.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index f72734d5..130602fc 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -582,7 +582,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { return; #if PPP_IPV6_SUPPORT - case PPP_IPV6: /* Interval Protocol Version 6 */ + case PPP_IPV6: /* Internet Protocol Version 6 */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->num, pb->len)); ip6_input(pb, &pcb->netif); return; @@ -1263,10 +1263,15 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { #if PPPOE_SUPPORT static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { struct pbuf *ph; /* Ethernet + PPPoE header */ + u16_t tot_len; /* skip address & flags */ pbuf_header(p, -(s16_t)2); +#if PRINTPKT_SUPPORT + dump_packet("sent", (unsigned char *)p->payload, p->len); +#endif /* PRINTPKT_SUPPORT */ + ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN), PBUF_RAM); if(!ph) { LINK_STATS_INC(link.memerr); @@ -1278,25 +1283,18 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { pbuf_header(ph, -(s16_t)PPPOE_HDRLEN); /* hide PPPoE header */ pbuf_cat(ph, p); - pbuf_ref(ph); /* we need the pbuf after pppoe_xmit() returned, which free the pbuf */ pcb->last_xmit = sys_jiffies(); if(pppoe_xmit(pcb->pppoe_sc, ph) != ERR_OK) { LINK_STATS_INC(link.err); snmp_inc_ifoutdiscards(&pcb->netif); - pbuf_free(ph); return PPPERR_DEVICE; } -#if PRINTPKT_SUPPORT - dump_packet("sent", (unsigned char *)ph->payload, ph->len); -#endif /* PRINTPKT_SUPPORT */ - - snmp_add_ifoutoctets(&pcb->netif, (u16_t)ph->tot_len); + snmp_add_ifoutoctets(&pcb->netif, (u16_t)tot_len); snmp_inc_ifoutucastpkts(&pcb->netif); LINK_STATS_INC(link.xmit); - pbuf_free(ph); return PPPERR_NONE; } #endif /* PPPOE_SUPPORT */ From 8f1eeb10255472d3160c6cacd30f01949bb8d21d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 18:23:07 +0200 Subject: [PATCH 215/320] improved ipv6cp_options struct size --- src/netif/ppp/ipv6cp.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/netif/ppp/ipv6cp.h b/src/netif/ppp/ipv6cp.h index 6c7fe489..c7ff0c20 100644 --- a/src/netif/ppp/ipv6cp.h +++ b/src/netif/ppp/ipv6cp.h @@ -156,18 +156,18 @@ *#define IPV6CP_COMP 0x004f */ typedef struct ipv6cp_options { - int neg_ifaceid; /* Negotiate interface identifier? */ - int req_ifaceid; /* Ask peer to send interface identifier? */ - int accept_local; /* accept peer's value for iface id? */ - int opt_local; /* ourtoken set by option */ - int opt_remote; /* histoken set by option */ - int use_ip; /* use IP as interface identifier */ + u_int neg_ifaceid :1; /* Negotiate interface identifier? */ + u_int req_ifaceid :1; /* Ask peer to send interface identifier? */ + u_int accept_local :1; /* accept peer's value for iface id? */ + u_int opt_local :1; /* ourtoken set by option */ + u_int opt_remote :1; /* histoken set by option */ + u_int use_ip :1; /* use IP as interface identifier */ #if defined(SOL2) || defined(__linux__) - int use_persistent; /* use uniquely persistent value for address */ + u_int use_persistent :1; /* use uniquely persistent value for address */ #endif /* defined(SOL2) */ - int neg_vj; /* Van Jacobson Compression? */ - u_short vj_protocol; /* protocol value to use in VJ option */ - eui64_t ourid, hisid; /* Interface identifiers */ + u_int neg_vj :1; /* Van Jacobson Compression? */ + u_short vj_protocol; /* protocol value to use in VJ option */ + eui64_t ourid, hisid; /* Interface identifiers */ } ipv6cp_options; extern struct protent ipv6cp_protent; From 807afbc879827e83bd1b858fc45192d9cb756d72 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 18:50:09 +0200 Subject: [PATCH 216/320] improved FSM structure size --- src/netif/ppp/fsm.c | 2 +- src/netif/ppp/fsm.h | 29 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 4fe14be9..0804f476 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -234,7 +234,7 @@ static void terminate_layer(fsm *f, int nextstate) { */ void fsm_close(fsm *f, char *reason) { f->term_reason = reason; - f->term_reason_len = (reason == NULL? 0: strlen(reason)); + f->term_reason_len = (reason == NULL? 0: LWIP_MIN(strlen(reason), 0xFF) ); switch( f->state ){ case STARTING: f->state = INITIAL; diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index afa33edf..fe347118 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -73,22 +73,23 @@ */ typedef struct fsm { ppp_pcb *pcb; /* PPP Interface */ - 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 rnakloops; /* Number of naks received */ - 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 */ + u8_t seen_ack; /* Have received valid Ack/Nak/Rej to Req */ + /* -- This is our only flag, we might use u_int :1 if we have more flags */ + u16_t protocol; /* Data Link Layer Protocol field value */ + u8_t state; /* State */ + u8_t flags; /* Contains option bits */ + u8_t id; /* Current id */ + u8_t reqid; /* Current request id */ + u8_t timeouttime; /* Timeout time in seconds */ + u8_t maxconfreqtransmits; /* Maximum Configure-Request transmissions */ + u8_t retransmits; /* Number of retransmissions left */ + u8_t maxtermtransmits; /* Maximum Terminate-Request transmissions */ + u8_t nakloops; /* Number of nak loops since last ack */ + u8_t rnakloops; /* Number of naks received */ + u8_t maxnakloops; /* Maximum number of nak loops tolerated */ + u8_t term_reason_len; /* Length of term_reason */ } fsm; From 074d3dd2b18cb88452eae099c5175d7d644357ff Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 19:27:03 +0200 Subject: [PATCH 217/320] moved ipv6cp global variables to ppp_pcb --- src/netif/ppp/ipv6cp.c | 16 +++++++++------- src/netif/ppp/ppp.h | 6 +++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c index 593649ce..68b38ff8 100644 --- a/src/netif/ppp/ipv6cp.c +++ b/src/netif/ppp/ipv6cp.c @@ -169,12 +169,10 @@ #include "ipv6cp.h" #include "magic.h" -/* FIXME: clean that */ /* global vars */ +#if 0 /* UNUSED */ int no_ifaceid_neg = 0; - -/* local vars */ -static int ipv6cp_is_up; +#endif /* UNUSED */ /* * Callbacks for fsm code. (CI = Configuration Information) @@ -1150,7 +1148,9 @@ static void ipv6cp_up(fsm *f) { if (!ho->neg_ifaceid) ho->hisid = wo->hisid; +#if 0 /* UNUSED */ if(!no_ifaceid_neg) { +#endif /* UNUSED */ if (eui64_iszero(ho->hisid)) { error("Could not determine remote LL address"); ipv6cp_close(f->pcb, "Could not determine remote LL address"); @@ -1166,7 +1166,9 @@ static void ipv6cp_up(fsm *f) { ipv6cp_close(f->pcb, "local and remote LL addresses are equal"); return; } +#if 0 /* UNUSED */ } +#endif /* UNUSED */ #if 0 /* UNUSED */ script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0); script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0); @@ -1251,7 +1253,7 @@ static void ipv6cp_up(fsm *f) { } np_up(f->pcb, PPP_IPV6); - ipv6cp_is_up = 1; + pcb->ipv6cp_is_up = 1; #if 0 /* UNUSED */ /* @@ -1281,8 +1283,8 @@ static void ipv6cp_down(fsm *f) { #if PPP_STATS_SUPPORT update_link_stats(f->unit); #endif /* PPP_STATS_SUPPORT */ - if (ipv6cp_is_up) { - ipv6cp_is_up = 0; + if (pcb->ipv6cp_is_up) { + pcb->ipv6cp_is_up = 0; np_down(f->pcb, PPP_IPV6); } #ifdef IPV6CP_COMP diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 0c2a3cda..e1fb3239 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -192,6 +192,7 @@ typedef struct ppp_settings_s { u_int lcp_echo_adaptive : 1; /* request echo only if the link was idle */ #endif + u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ #if PPP_IDLETIMELIMIT @@ -283,7 +284,10 @@ struct ppp_pcb_s { u_int default_route_set :1; /* Have set up a default route */ u_int proxy_arp_set :1; /* Have created proxy arp entry */ u_int ipcp_is_open :1; /* haven't called np_finished() */ - u_int ipcp_is_up :1; /* have called np_up() */ + u_int ipcp_is_up :1; /* have called ipcp_up() */ +#if PPP_IPV6_SUPPORT + u_int ipv6cp_is_up :1; /* have called ip6cp_up() */ +#endif /* PPP_IPV6_SUPPORT */ u_int ask_for_local :1; /* request our address from peer */ u_int lcp_echo_timer_running :1; /* set if a timer is running */ #if PPPOS_SUPPORT && VJ_SUPPORT From dc242a01b4485acfa5b9060638c81550612dac3e Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 19:29:55 +0200 Subject: [PATCH 218/320] don't build ppp_netif_output_ip6() if PPP IPV6 support is disabled --- src/netif/ppp/ppp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 130602fc..2e95b806 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -206,7 +206,9 @@ static void ppp_free_current_input_packet(ppp_pcb_rx *pcrx); static err_t ppp_netif_init_cb(struct netif *netif); static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); +#if PPP_IPV6_SUPPORT static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr_t *ipaddr); +#endif /* PPP_IPV6_SUPPORT */ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol); #if PPPOE_SUPPORT @@ -926,12 +928,14 @@ static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, ip_addr_ return ppp_netif_output(netif, pb, PPP_IP); } +#if PPP_IPV6_SUPPORT /* Send a IPv6 packet on the given connection. */ static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr_t *ipaddr) { LWIP_UNUSED_ARG(ipaddr); return ppp_netif_output(netif, pb, PPP_IPV6); } +#endif /* PPP_IPV6_SUPPORT */ /* Send a packet on the given connection. * From fb6eed0087cc88ba2abc08a31e0d30668a433da0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 19:45:45 +0200 Subject: [PATCH 219/320] set LL addresses before bringing the interface up for IPv6 --- src/netif/ppp/ipv6cp.c | 43 +++++++----------------------------------- 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c index 68b38ff8..cd451e6b 100644 --- a/src/netif/ppp/ipv6cp.c +++ b/src/netif/ppp/ipv6cp.c @@ -1214,38 +1214,18 @@ static void ipv6cp_up(fsm *f) { /* * Set LL addresses */ -#if !defined(__linux__) && !defined(SOL2) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sif6addr(f->unit, go->ourid, ho->hisid)) { - if (debug) - warn("sif6addr failed"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - - /* bring the interface up for IPv6 */ -#if defined(SOL2) - if (!sif6up(f->unit)) { - if (debug) - warn("sifup failed (IPV6)"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } -#else - if (!sifup(f->pcb)) { - PPPDEBUG(LOG_DEBUG, ("sifup failed (IPV6)")); - ipv6cp_close(f->pcb, "Interface configuration failed"); - return; - } -#endif /* defined(SOL2) */ - -#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { PPPDEBUG(LOG_DEBUG, ("sif6addr failed")); ipv6cp_close(f->pcb, "Interface configuration failed"); return; } -#endif + + /* bring the interface up for IPv6 */ + if (!sifup(f->pcb)) { + PPPDEBUG(LOG_DEBUG, ("sifup failed (IPV6)")); + ipv6cp_close(f->pcb, "Interface configuration failed"); + return; + } sifnpmode(f->pcb, PPP_IPV6, NPMODE_PASS); notice("local LL address %s", llv6_ntoa(go->ourid)); @@ -1302,19 +1282,10 @@ static void ipv6cp_down(fsm *f) { #endif /* PPP_DEMAND */ { sifnpmode(f->pcb, PPP_IPV6, NPMODE_DROP); -#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC))) -#if defined(SOL2) - sif6down(f->unit); -#else - sifdown(f->unit); -#endif /* defined(SOL2) */ -#endif ipv6cp_clear_addrs(f->pcb, go->ourid, ho->hisid); -#if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC))) sifdown(f->pcb); -#endif } #if 0 /* UNUSED */ From a84f5d52ff51cd3a88fb5ecf0122a2423b9a851a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 19:59:46 +0200 Subject: [PATCH 220/320] added ppp_pcb to ppp callback --- src/netif/ppp/ppp.c | 10 +++++----- src/netif/ppp/ppp.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 2e95b806..1bfefffd 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1654,7 +1654,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { /* Reconnect if persist mode is enabled */ if(pcb->settings.persist) { if(pcb->link_status_cb) - pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : pppoe_err_code, NULL); + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); pppoe_connect(pcb->pppoe_sc); return; } @@ -1663,7 +1663,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { ppp_stop(pcb); pppoe_destroy(&pcb->netif); if(pcb->link_status_cb) - pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : pppoe_err_code, NULL); + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); ppp_destroy(pcb); } #endif /* PPPOE_SUPPORT */ @@ -1692,7 +1692,7 @@ void ppp_link_terminated(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); if (pcb->link_status_cb) { - pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, NULL); + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->link_status_ctx); } ppp_destroy(pcb); #endif /* PPPOS_SUPPORT */ @@ -1937,7 +1937,7 @@ int sifup(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); if (pcb->link_status_cb) - pcb->link_status_cb(pcb->link_status_ctx, pcb->err_code, &pcb->addrs); + pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); return 1; } @@ -1958,7 +1958,7 @@ int sifdown(ppp_pcb *pcb) { netif_remove(&pcb->netif); PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); if (pcb->link_status_cb) - pcb->link_status_cb(pcb->link_status_ctx, PPPERR_CONNECT, NULL); + pcb->link_status_cb(pcb, PPPERR_CONNECT, pcb->link_status_ctx); return 1; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index e1fb3239..d9191be1 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -328,7 +328,7 @@ struct ppp_pcb_s { struct ppp_addrs addrs; /* PPP addresses */ struct netif netif; /* PPP interface */ - void (*link_status_cb)(void *ctx, int err_code, void *arg); /* Status change callback */ + void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */ void *link_status_ctx; /* Status change callback optional pointer */ /* auth data */ @@ -420,7 +420,7 @@ ppp_pcb *ppp_new(void); void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd); /* Link status callback function prototype */ -typedef void (*ppp_link_status_cb_fn)(void *ctx, int errcode, void *arg); +typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx); #if PPPOS_SUPPORT /* From 408a56ffaf73b34a507ee60f4063dd67ca2cd936 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 20:48:08 +0200 Subject: [PATCH 221/320] phase must be set to initalize each time we try to reconnect --- src/netif/ppp/ppp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 1bfefffd..aaf87b4e 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -255,7 +255,6 @@ ppp_pcb *ppp_new(void) { #endif /* PPP_DEBUG */ IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); pcb->lcp_loopbackfail = DEFLOOPBACKFAIL; - new_phase(pcb, PHASE_INITIALIZE); /* default configuration */ pcb->settings.usepeerdns = 1; @@ -359,6 +358,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s * Start the connection and handle incoming events (packet or timeout). */ PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->num)); + new_phase(pcb, PHASE_INITIALIZE); ppp_start(pcb); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); @@ -417,6 +417,7 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic return PPPERR_OPEN; } + new_phase(pcb, PHASE_INITIALIZE); pppoe_connect(pcb->pppoe_sc); return PPPERR_NONE; } @@ -1655,6 +1656,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { if(pcb->settings.persist) { if(pcb->link_status_cb) pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); + new_phase(pcb, PHASE_INITIALIZE); pppoe_connect(pcb->pppoe_sc); return; } From 1f780e86d504f8ff374e2101688d0efb570fd933 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 21:29:12 +0200 Subject: [PATCH 222/320] PPP timeouts required depend on the number of allowed PPP sessions Furthermore we need up to 6 timeouts per PPP (AUTH + PAP|CHAP|EAP + LCP + IPCP + IP6CP + PPPoE) This can be improved with more conditions. --- src/include/lwip/opt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 66bf9af2..02df3359 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -313,7 +313,7 @@ * The formula expects settings to be either '0' or '1'. */ #ifndef MEMP_NUM_SYS_TIMEOUT -#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB) + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) #endif /** From f63b87e28b3996177e8b69b287d566302b3806da Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 21:43:22 +0200 Subject: [PATCH 223/320] setting tot_len before using it, oops --- src/netif/ppp/ppp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index aaf87b4e..626ed0bd 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1288,6 +1288,7 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { pbuf_header(ph, -(s16_t)PPPOE_HDRLEN); /* hide PPPoE header */ pbuf_cat(ph, p); + tot_len = ph->tot_len; pcb->last_xmit = sys_jiffies(); From 295eeef9b69141a7526a011c13c3067ebc2ab01f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Jun 2012 21:48:21 +0200 Subject: [PATCH 224/320] "ISO C forbids conversion of function pointer to object pointer type" - removed callback function pointer display in debug messages. Anyway, this is quite a meaningless information. --- src/netif/ppp/ppp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 626ed0bd..0a107ed7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1938,7 +1938,7 @@ int sifup(ppp_pcb *pcb) { pcb->if_up = 1; pcb->err_code = PPPERR_NONE; - PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); if (pcb->link_status_cb) pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); @@ -1959,7 +1959,7 @@ int sifdown(ppp_pcb *pcb) { /* make sure the netif status callback is called */ netif_set_down(&pcb->netif); netif_remove(&pcb->netif); - PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); + PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); if (pcb->link_status_cb) pcb->link_status_cb(pcb, PPPERR_CONNECT, pcb->link_status_ctx); From 5033e0e7529744a24031537ebea2d7a202009aa4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 23 Jun 2012 01:44:52 +0200 Subject: [PATCH 225/320] display IPV6CP packets --- src/netif/ppp/ppp.c | 10 +++++++--- src/netif/ppp/utils.c | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0a107ed7..0e741ef3 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -187,9 +187,9 @@ struct protent *protocols[] = { static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ -#if PPPOS_SUPPORT +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD static void ppp_receive_wakeup(ppp_pcb *pcb); -#endif /* #if PPPOS_SUPPORT */ +#endif /* #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ static void ppp_stop(ppp_pcb *pcb); static void ppp_hup(ppp_pcb *pcb); @@ -200,7 +200,9 @@ static void ppp_input_thread(void *arg); #endif /* PPP_INPROC_OWNTHREAD */ static void ppp_drop(ppp_pcb_rx *pcrx); static void pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l); +#if PPP_INPROC_MULTITHREADED static void pppos_input_callback(void *arg); +#endif /* PPP_INPROC_MULTITHREADED */ static void ppp_free_current_input_packet(ppp_pcb_rx *pcrx); #endif /* PPPOS_SUPPORT */ @@ -1356,7 +1358,7 @@ ppp_drop(ppp_pcb_rx *pcrx) void pppos_input(ppp_pcb *pcb, u_char* data, int len) { - pppos_input_proc(pcb->rx, data, len); + pppos_input_proc(&pcb->rx, data, len); } #endif @@ -1573,6 +1575,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) magic_randomize(); } +#if PPP_INPROC_MULTITHREADED /* PPPoS input callback using one input pointer * *arg is a pbuf chain of two chained pbuf, the first contains * a pointer to the PPP PCB structure, the second contains the @@ -1600,6 +1603,7 @@ drop: pbuf_free(pl); return; } +#endif /* PPP_INPROC_MULTITHREADED */ #endif /* PPPOS_SUPPORT */ /* merge a pbuf chain into one pbuf */ diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 19abdbdd..9f94ca4e 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -721,7 +721,7 @@ void dump_packet(const char *tag, unsigned char *p, int len) { if (proto == PPP_IP) return; #if PPP_IPV6_SUPPORT - if (proto == PPP_IPV6 || proto == PPP_IPV6CP) + if (proto == PPP_IPV6) return; #endif From 25c62780006d1e8345e73ba9d9d15863faa95549 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 23 Jun 2012 02:27:03 +0200 Subject: [PATCH 226/320] fixed some endianess issues with PPPoS --- src/netif/ppp/lcp.c | 2 ++ src/netif/ppp/ppp.c | 12 ++++++++---- src/netif/ppp/utils.c | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 5e02836f..499464b4 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -666,8 +666,10 @@ void lcp_sprotrej(ppp_pcb *pcb, 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. */ +#if 0 p += 2; len -= 2; +#endif fsm_sdata(f, PROTREJ, ++f->id, p, len); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0e741ef3..e2957e59 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -506,7 +506,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { dump_packet("rcvd", pb->payload, pb->len); #endif /* PRINTPKT_SUPPORT */ - if(pbuf_header(pb, -(int)sizeof(protocol))) { + if(pbuf_header(pb, -(s16_t)sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } @@ -632,7 +632,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { #endif /* PPP_PROTOCOLNAME */ warn("Unsupported protocol 0x%x received", protocol); #endif /* PPP_DEBUG */ - if (pbuf_header(pb, sizeof(protocol))) { + if (pbuf_header(pb, (s16_t)sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } @@ -867,6 +867,10 @@ pppos_put(ppp_pcb *pcb, struct pbuf *nb) struct pbuf *b; int c; +#if PRINTPKT_SUPPORT + dump_packet("sent", (unsigned char *)nb->payload+2, nb->len-2); +#endif /* PRINTPKT_SUPPORT */ + for(b = nb; b != NULL; b = b->next) { if((c = sio_write(pcb->fd, b->payload, b->len)) != b->len) { PPPDEBUG(LOG_WARNING, @@ -1554,8 +1558,8 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) break; } if (pcrx->in_head == NULL) { - ((u8_t*)next_pbuf->payload)[0] = pcrx->in_protocol & 0xFF; - ((u8_t*)next_pbuf->payload)[1] = pcrx->in_protocol >> 8; + ((u8_t*)next_pbuf->payload)[0] = pcrx->in_protocol >> 8; + ((u8_t*)next_pbuf->payload)[1] = pcrx->in_protocol & 0xFF; next_pbuf->len += sizeof(pcrx->in_protocol); pcrx->in_head = next_pbuf; diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 9f94ca4e..d3e18428 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -481,7 +481,7 @@ static void format_packet(u_char *p, int len, printer(arg, "%.*B", len, p); len = 0; } else - printer(arg, "[proto=0x%x]", proto); + printer(arg, "[proto=0x%x]", PP_NTOHS(proto)); } } From dc092653f4cce58a48c7be147d645be6cda88e7e Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 23 Jun 2012 12:04:27 +0200 Subject: [PATCH 227/320] now displaying sent packet before PPPoS add its escaping, trailing flags, ... --- src/netif/ppp/ppp.c | 15 ++++++--------- src/netif/ppp/utils.c | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index e2957e59..5793bf87 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -867,10 +867,6 @@ pppos_put(ppp_pcb *pcb, struct pbuf *nb) struct pbuf *b; int c; -#if PRINTPKT_SUPPORT - dump_packet("sent", (unsigned char *)nb->payload+2, nb->len-2); -#endif /* PRINTPKT_SUPPORT */ - for(b = nb; b != NULL; b = b->next) { if((c = sio_write(pcb->fd, b->payload, b->len)) != b->len) { PPPDEBUG(LOG_WARNING, @@ -946,7 +942,8 @@ static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr /* Send a packet on the given connection. * - * This is the low level function that send the PPP packet. + * This is the low level function that send the PPP packet, + * only for IPv4 and IPv6 packets coming from lwIP. */ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol) { ppp_pcb *pcb = (ppp_pcb*)netif->state; @@ -1204,6 +1201,10 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { struct pbuf *head, *tail; #endif /* PPPOS_SUPPORT */ +#if PRINTPKT_SUPPORT + dump_packet("sent", (unsigned char *)p->payload+2, p->len-2); +#endif /* PRINTPKT_SUPPORT */ + #if PPPOE_SUPPORT if(pcb->ethif) { return ppp_write_over_ethernet(pcb, p); @@ -1279,10 +1280,6 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { /* skip address & flags */ pbuf_header(p, -(s16_t)2); -#if PRINTPKT_SUPPORT - dump_packet("sent", (unsigned char *)p->payload, p->len); -#endif /* PRINTPKT_SUPPORT */ - ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN), PBUF_RAM); if(!ph) { LINK_STATS_INC(link.memerr); diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index d3e18428..9f94ca4e 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -481,7 +481,7 @@ static void format_packet(u_char *p, int len, printer(arg, "%.*B", len, p); len = 0; } else - printer(arg, "[proto=0x%x]", PP_NTOHS(proto)); + printer(arg, "[proto=0x%x]", proto); } } From a83fb308360fff6d69083ebf1924774fc1cdc996 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 23 Jun 2012 13:07:43 +0200 Subject: [PATCH 228/320] fixed PPPoS multithread support --- src/netif/ppp/ppp.c | 18 ++++++++++++++---- src/netif/ppp/ppp.h | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 5793bf87..620dbedb 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -845,7 +845,7 @@ ppp_input_thread(void *arg) { int count; ppp_pcb_rx *pcrx = arg; - ppp_pcb *pcb = (ppp_pcb*)pcrx->pcb; + ppp_pcb *pcb = pcrx->pcb; while (pcb->phase != PHASE_DEAD) { count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); @@ -1363,6 +1363,12 @@ pppos_input(ppp_pcb *pcb, u_char* data, int len) } #endif +#if PPP_INPROC_MULTITHREADED +struct ppp_tcpip_callback_header { + ppp_pcb *pcb; +}; +#endif /* PPP_INPROC_MULTITHREADED */ + /** * Process a received octet string. */ @@ -1416,6 +1422,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) struct pbuf *inp; #if PPP_INPROC_MULTITHREADED struct pbuf *head; + struct ppp_tcpip_callback_header *cbhead; #endif /* PPP_INPROC_MULTITHREADED */ /* Trim off the checksum. */ if(pcrx->in_tail->len > 2) { @@ -1440,9 +1447,10 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) pcrx->in_head = NULL; pcrx->in_tail = NULL; #if PPP_INPROC_MULTITHREADED - head = pbuf_alloc(PBUF_RAW, sizeof(void*), PBUF_POOL); + head = pbuf_alloc(PBUF_RAW, sizeof(struct ppp_tcpip_callback_header), PBUF_POOL); if(NULL != head) { - MEMCPY(head->payload, pcb, sizeof(void*)); + cbhead = (struct ppp_tcpip_callback_header*)head->payload; + cbhead->pcb = pcb; pbuf_chain(head, inp); if(tcpip_callback_with_block(pppos_input_callback, head, 0) != ERR_OK) { PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: tcpip_callback() failed, dropping packet\n", pcb->num)); @@ -1584,10 +1592,12 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) */ static void pppos_input_callback(void *arg) { struct pbuf *hd, *pl; + struct ppp_tcpip_callback_header *cbhead; ppp_pcb *pcb; hd = (struct pbuf *)arg; - pcb = (ppp_pcb *)hd->payload; + cbhead = (struct ppp_tcpip_callback_header *)hd->payload; + pcb = cbhead->pcb; pl = hd->next; pbuf_free(hd); diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index d9191be1..50ab2d1e 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -466,7 +466,7 @@ int ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg); #if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD /* * PPP over Serial: this is the input function to be called for received data. - * If PPP_INPROC_OWNTHREAD==1, a seperate input thread using the blocking + * If PPP_INPROC_OWNTHREAD==1, a separate input thread using the blocking * sio_read() is used, so this is deactivated. */ void pppos_input(ppp_pcb *pcb, u_char* data, int len); From ba0c619844e037ddcc656def8db8accc1b3b2623 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 23 Jun 2012 13:46:51 +0200 Subject: [PATCH 229/320] clarified PPP_INPROC_OWNTHREAD documentation --- src/netif/ppp/ppp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 50ab2d1e..68d69812 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -59,8 +59,10 @@ #endif /** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session. - * Default is 0: call pppos_input() for received raw characters, character - * reception is up to the port */ + * Default is 1 if PPP_INPROC_MULTITHREADED is enabled. + * If set to 0, call pppos_input() for received raw characters, character + * reception is up to the port. + */ #ifndef PPP_INPROC_OWNTHREAD #define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED #endif From 11a3057e8ed31883599a063dd88730d26b326e5e Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 23 Jun 2012 15:11:49 +0200 Subject: [PATCH 230/320] PPP: Add option to skip FCS table Option PPP_FCS_TABLE is created which controls if PPPoS FCS calculation should be done against precalculated table or by using a short algorithm. Default value is 1, keeps old behaviour. Setting it to 0 saves around 0.5 kB flash. --- src/include/lwip/opt.h | 7 +++++++ src/netif/ppp/ppp.c | 15 ++++++++++++++- src/netif/ppp/ppp_impl.h | 7 ++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 02df3359..2ed0714f 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1703,6 +1703,13 @@ #if PPP_SUPPORT +/** + * PPP_FCS_TABLE: Keep a 256*2 byte table to speed up FCS calculation + */ +#ifndef PPP_FCS_TABLE +#define PPP_FCS_TABLE 1 +#endif + /** * PAP_SUPPORT==1: Support PAP. */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 620dbedb..feaa965f 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -750,9 +750,9 @@ out: } #if PPPOS_SUPPORT +#if PPP_FCS_TABLE /* * FCS lookup table as calculated by genfcstab. - * @todo: smaller, slower implementation for lower memory footprint? */ static const u_short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, @@ -788,6 +788,19 @@ static const u_short fcstab[256] = { 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; +#else /* PPP_FCS_TABLE */ +/* The HDLC polynomial: X**0 + X**5 + X**12 + X**16 (0x8408) */ +#define PPP_FCS_POLYNOMIAL 0x8408 +u16_t ppp_get_fcs(u8_t byte) { + unsigned int octet; + int bit; + octet = byte; + for (bit = 8; bit-- > 0; ) { + octet = (octet & 0x01) ? ((octet >> 1) ^ PPP_FCS_POLYNOMIAL) : (octet >> 1); + } + return octet & 0xffff; +} +#endif /* PPP_FCS_TABLE */ /* PPP's Asynchronous-Control-Character-Map. The mask array is used * to select the specific bit for a character. */ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 53c218eb..8ced5819 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -127,7 +127,12 @@ */ #define PPP_INITFCS 0xffff /* Initial FCS value */ #define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) +#if PPP_FCS_TABLE + #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) +#else +u16_t ppp_get_fcs(u8_t byte); +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ ppp_get_fcs(((fcs) ^ (c)) & 0xff)) +#endif /* * A 32-bit unsigned integral type. From 2e069429c20ab661cfb7f1d4958909da8bae1107 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 3 Jul 2012 22:03:51 +0200 Subject: [PATCH 231/320] removed bool type, replaced by u8_t --- src/netif/ppp/eap.h | 2 +- src/netif/ppp/ipcp.c | 4 ++-- src/netif/ppp/ppp.c | 2 +- src/netif/ppp/ppp.h | 14 -------------- src/netif/ppp/ppp_impl.h | 27 +++++++-------------------- 5 files changed, 11 insertions(+), 38 deletions(-) diff --git a/src/netif/ppp/eap.h b/src/netif/ppp/eap.h index 5ee6daf4..a40a9d39 100644 --- a/src/netif/ppp/eap.h +++ b/src/netif/ppp/eap.h @@ -140,7 +140,7 @@ typedef struct eap_state { int es_savedtime; /* Saved timeout */ int es_rechallenge; /* EAP rechallenge interval */ int es_lwrechallenge; /* SRP lightweight rechallenge inter */ - bool es_usepseudo; /* Use SRP Pseudonym if offered one */ + u8_t es_usepseudo; /* Use SRP Pseudonym if offered one */ int es_usedpseudo; /* Set if we already sent PN */ int es_challen; /* Length of challenge string */ u_char es_challenge[EAP_MAX_CHALLENGE_LENGTH]; diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 9445c63e..fd411f6d 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -306,7 +306,7 @@ struct protent ipcp_protent = { #endif /* DEMAND_SUPPORT */ }; -static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute); +static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, u8_t replacedefaultroute); /* * Lengths of configuration options. @@ -2014,7 +2014,7 @@ static void ipcp_down(fsm *f) { * ipcp_clear_addrs() - clear the interface addresses, routes, * proxy arp entries, etc. */ -static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute) { +static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, u8_t replacedefaultroute) { if (pcb->proxy_arp_set) { cifproxyarp(pcb, hisaddr); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index feaa965f..3f4612ef 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -2032,7 +2032,7 @@ int netif_get_mtu(ppp_pcb *pcb) { * and then changes the temporary addresses to the addresses for the real * ppp connection when it has come up. */ -int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, bool replace) { +int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, u8_t replace) { LWIP_UNUSED_ARG(ouraddr); LWIP_UNUSED_ARG(gateway); diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 68d69812..cc8ad0ff 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -79,20 +79,6 @@ #endif /* PPPOS_SUPPORT */ -#ifndef __u_char_defined - -/* Type definitions for BSD code. */ -typedef unsigned long u_long; -typedef unsigned int u_int; -typedef unsigned short u_short; -typedef unsigned char u_char; - -#endif - -#ifndef bool -typedef unsigned char bool; -#endif - /************************* *** PUBLIC DEFINITIONS *** *************************/ diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 8ced5819..b19b88a7 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -134,19 +134,6 @@ u16_t ppp_get_fcs(u8_t byte); #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ ppp_get_fcs(((fcs) ^ (c)) & 0xff)) #endif -/* - * A 32-bit unsigned integral type. - */ - -#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \ - && !defined(__FreeBSD__) && (NS_TARGET < 40) -#ifdef UINT32_T -typedef UINT32_T u_int32_t; -#else -typedef unsigned int u_int32_t; -typedef unsigned short u_int16_t; -#endif -#endif /* * What to do with network protocol (NP) packets. @@ -238,11 +225,11 @@ struct ppp_idle { * Global variables. */ #ifdef HAVE_MULTILINK -extern bool multilink; /* enable multilink operation */ -extern bool doing_multilink; -extern bool multilink_master; -extern bool bundle_eof; -extern bool bundle_terminating; +extern u8_t multilink; /* enable multilink operation */ +extern u8_t doing_multilink; +extern u8_t multilink_master; +extern u8_t bundle_eof; +extern u8_t bundle_terminating; #endif #ifdef MAXOCTETS @@ -292,7 +279,7 @@ struct protent { */ /* Process a received data packet */ void (*datainput) (ppp_pcb *pcb, u_char *pkt, int len); - bool enabled_flag; /* 0 if protocol is disabled */ + u8_t enabled_flag; /* 0 if protocol is disabled */ #if PRINTPKT_SUPPORT char *name; /* Text name of protocol */ char *data_name; /* Text name of corresponding data protocol */ @@ -429,7 +416,7 @@ int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode); void netif_set_mtu(ppp_pcb *pcb, int mtu); int netif_get_mtu(ppp_pcb *pcb); -int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, bool replace); +int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, u8_t replace); int cifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway); int sifproxyarp(ppp_pcb *pcb, u_int32_t his_adr); From 90faecd86e16cffe31c1fe49f98613b3eaece8be Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 3 Jul 2012 22:59:50 +0200 Subject: [PATCH 232/320] replaced u_int{8,16,32}_t to lwIP u{8,16,32}_t types added padding to compiler generated bitfield, this is seen as best practice, maybe it helps buggy compilers --- src/netif/ppp/auth.c | 24 +++++------ src/netif/ppp/demand.c | 8 ++-- src/netif/ppp/eap.c | 24 +++++------ src/netif/ppp/eap.h | 2 +- src/netif/ppp/eui64.h | 6 +-- src/netif/ppp/ipcp.c | 90 +++++++++++++++++++-------------------- src/netif/ppp/ipcp.h | 35 +++++++-------- src/netif/ppp/ipv6cp.h | 19 +++++---- src/netif/ppp/lcp.c | 14 +++--- src/netif/ppp/lcp.h | 48 ++++++++++++--------- src/netif/ppp/multilink.c | 8 ++-- src/netif/ppp/ppp.c | 24 +++++------ src/netif/ppp/ppp.h | 73 ++++++++++++++++++++----------- src/netif/ppp/ppp_impl.h | 26 +++++------ src/netif/ppp/utils.c | 4 +- 15 files changed, 220 insertions(+), 185 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 97b9b5e9..61d08f47 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -189,7 +189,7 @@ int (*chap_passwd_hook) (char *user, char *passwd) = NULL; int (*null_auth_hook) (struct wordlist **paddrs, struct wordlist **popts) = NULL; -int (*allowed_address_hook) (u_int32_t addr) = NULL; +int (*allowed_address_hook) (u32_t addr) = NULL; #endif /* UNUSED */ #ifdef HAVE_MULTILINK @@ -250,7 +250,7 @@ static int have_pap_secret (int *); static int have_chap_secret (char *, char *, int, int *); static int have_srp_secret (char *client, char *server, int need_ip, int *lacks_ipp); -static int ip_addr_check (u_int32_t, struct permitted_ip *); +static int ip_addr_check (u32_t, struct permitted_ip *); static int scan_authfile (FILE *, char *, char *, char *, struct wordlist **, struct wordlist **, char *, int); @@ -2078,9 +2078,9 @@ set_allowed_addrs(unit, addrs, opts) char *ptr_word, *ptr_mask; struct hostent *hp; struct netent *np; - u_int32_t a, mask, ah, offset; + u32_t a, mask, ah, offset; struct ipcp_options *wo = &ipcp_wantoptions[unit]; - u_int32_t suggested_ip = 0; + u32_t suggested_ip = 0; if (addresses[unit] != NULL) free(addresses[unit]); @@ -2123,7 +2123,7 @@ set_allowed_addrs(unit, addrs, opts) ++ptr_word; } - mask = ~ (u_int32_t) 0; + mask = ~ (u32_t) 0; offset = 0; ptr_mask = strchr (ptr_word, '/'); if (ptr_mask != NULL) { @@ -2151,11 +2151,11 @@ set_allowed_addrs(unit, addrs, opts) hp = gethostbyname(ptr_word); if (hp != NULL && hp->h_addrtype == AF_INET) { - a = *(u_int32_t *)hp->h_addr; + a = *(u32_t *)hp->h_addr; } else { np = getnetbyname (ptr_word); if (np != NULL && np->n_addrtype == AF_INET) { - a = htonl ((u_int32_t)np->n_net); + a = htonl ((u32_t)np->n_net); if (ptr_mask == NULL) { /* calculate appropriate mask for net */ ah = ntohl(a); @@ -2174,7 +2174,7 @@ set_allowed_addrs(unit, addrs, opts) if (ptr_mask != NULL) *ptr_mask = '/'; - if (a == (u_int32_t)-1L) { + if (a == (u32_t)-1L) { warn("unknown host %s in auth. address list", ap->word); continue; } @@ -2185,7 +2185,7 @@ set_allowed_addrs(unit, addrs, opts) continue; } a = htonl((ntohl(a) & mask) + offset); - mask = ~(u_int32_t)0; + mask = ~(u32_t)0; } ip[n].mask = htonl(mask); ip[n].base = a & ip[n].mask; @@ -2225,7 +2225,7 @@ set_allowed_addrs(unit, addrs, opts) int auth_ip_addr(unit, addr) int unit; - u_int32_t addr; + u32_t addr; { int ok; @@ -2251,7 +2251,7 @@ auth_ip_addr(unit, addr) static int ip_addr_check(addr, addrs) - u_int32_t addr; + u32_t addr; struct permitted_ip *addrs; { for (; ; ++addrs) @@ -2266,7 +2266,7 @@ ip_addr_check(addr, addrs) */ int bad_ip_adrs(addr) - u_int32_t addr; + u32_t addr; { addr = ntohl(addr); return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index 75b43a13..81d307ec 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -99,8 +99,8 @@ demand_conf() fcs = PPP_INITFCS; netif_set_mtu(pcb, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU)); - if (ppp_send_config(pcb, PPP_MRU, (u_int32_t) 0, 0, 0) < 0 - || ppp_recv_config(pcb, PPP_MRU, (u_int32_t) 0, 0, 0) < 0) + if (ppp_send_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0 + || ppp_recv_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0) fatal("Couldn't set up demand-dialled PPP interface: %m"); #ifdef PPP_FILTER @@ -317,7 +317,7 @@ loop_frame(frame, len) void demand_rexmit(proto, newip) int proto; - u_int32_t newip; + u32_t newip; { struct packet *pkt, *prev, *nextpkt; unsigned short checksum; @@ -375,7 +375,7 @@ demand_rexmit(proto, newip) pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; /* Change Source-IP-Address */ - * ((u_int32_t *) (pkt->data + 16)) = newip; + * ((u32_t *) (pkt->data + 16)) = newip; /* Add new Source-IP-Address */ checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index afdebea6..dca92d3c 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -348,7 +348,7 @@ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; struct b64state { - u_int32_t bs_bits; + u32_t bs_bits; int bs_offs; }; @@ -1158,7 +1158,7 @@ static void eap_srpval_response(esp, id, flags, str) eap_state *esp; u_char id; -u_int32_t flags; +u32_t flags; u_char *str; { ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; @@ -1166,7 +1166,7 @@ u_char *str; u_char *outp; int msglen; - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) + + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u32_t) + SHA_DIGESTSIZE; p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); if(NULL == p) @@ -1659,9 +1659,9 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { pcb->eap.es_client.ea_id, id); } } else { - len -= sizeof (u_int32_t) + SHA_DIGESTSIZE; + len -= sizeof (u32_t) + SHA_DIGESTSIZE; if (len < 0 || t_clientverify(tc, inp + - sizeof (u_int32_t)) != 0) { + sizeof (u32_t)) != 0) { error("EAP: SRP server verification " "failed"); goto client_failure; @@ -1939,9 +1939,9 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { eap_figure_next_state(esp, 1); break; } - if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) { + if (len < sizeof (u32_t) + SHA_DIGESTSIZE) { error("EAP: M1 length %d < %d", len, - sizeof (u_int32_t) + SHA_DIGESTSIZE); + sizeof (u32_t) + SHA_DIGESTSIZE); eap_figure_next_state(esp, 1); break; } @@ -2144,7 +2144,7 @@ static char *eap_typenames[] = { static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, ...), void *arg) { int code, id, len, rtype, vallen; u_char *pstart; - u_int32_t uval; + u32_t uval; if (inlen < EAP_HEADERLEN) return (0); @@ -2265,10 +2265,10 @@ static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, break; case EAPSRP_SVALIDATOR: - if (len < sizeof (u_int32_t)) + if (len < sizeof (u32_t)) break; GETLONG(uval, inp); - len -= sizeof (u_int32_t); + len -= sizeof (u32_t); if (uval & SRPVAL_EBIT) { printer(arg, " E"); uval &= ~SRPVAL_EBIT; @@ -2371,10 +2371,10 @@ static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, break; case EAPSRP_CVALIDATOR: - if (len < sizeof (u_int32_t)) + if (len < sizeof (u32_t)) break; GETLONG(uval, inp); - len -= sizeof (u_int32_t); + len -= sizeof (u32_t); if (uval & SRPVAL_EBIT) { printer(arg, " E"); uval &= ~SRPVAL_EBIT; diff --git a/src/netif/ppp/eap.h b/src/netif/ppp/eap.h index a40a9d39..b96be43c 100644 --- a/src/netif/ppp/eap.h +++ b/src/netif/ppp/eap.h @@ -126,7 +126,7 @@ struct eap_auth { u_char ea_requests; /* Number of Requests sent/received */ u_char ea_responses; /* Number of Responses */ u_char ea_type; /* One of EAPT_* */ - u_int32_t ea_keyflags; /* SRP shared key usage flags */ + u32_t ea_keyflags; /* SRP shared key usage flags */ }; #ifndef EAP_MAX_CHALLENGE_LENGTH diff --git a/src/netif/ppp/eui64.h b/src/netif/ppp/eui64.h index 00f3911f..dffb5e41 100644 --- a/src/netif/ppp/eui64.h +++ b/src/netif/ppp/eui64.h @@ -48,9 +48,9 @@ */ typedef union { - u_int8_t e8[8]; - u_int16_t e16[4]; - u_int32_t e32[2]; + u8_t e8[8]; + u16_t e16[4]; + u32_t e32[2]; } eui64_t; #define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index fd411f6d..3c104c8f 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -66,7 +66,7 @@ #if 0 /* UNUSED */ /* global vars */ -u_int32_t netmask = 0; /* IP netmask to set on interface */ +u32_t netmask = 0; /* IP netmask to set on interface */ #endif /* UNUSED */ #if 0 /* UNUSED */ @@ -85,7 +85,7 @@ void (*ip_up_hook) (void) = NULL; void (*ip_down_hook) (void) = NULL; /* Hook for a plugin to choose the remote IP address */ -void (*ip_choose_hook) (u_int32_t *) = NULL; +void (*ip_choose_hook) (u32_t *) = NULL; #endif /* UNUSED */ #if PPP_NOTIFY @@ -275,7 +275,7 @@ static int ip_demand_conf (int); static int ip_active_pkt (u_char *, int); #endif /* DEMAND_SUPPORT */ #if 0 /* UNUSED */ -static void create_resolv (u_int32_t, u_int32_t); +static void create_resolv (u32_t, u32_t); #endif /* UNUSED */ struct protent ipcp_protent = { @@ -306,7 +306,7 @@ struct protent ipcp_protent = { #endif /* DEMAND_SUPPORT */ }; -static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, u8_t replacedefaultroute); +static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute); /* * Lengths of configuration options. @@ -327,7 +327,7 @@ static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, */ char * ip_ntoa(ipaddr) -u_int32_t ipaddr; +u32_t ipaddr; { static char b[64]; @@ -372,17 +372,17 @@ static int setdnsaddr(argv) char **argv; { - u_int32_t dns; + u32_t dns; struct hostent *hp; dns = inet_addr(*argv); - if (dns == (u_int32_t) -1) { + if (dns == (u32_t) -1) { if ((hp = gethostbyname(*argv)) == NULL) { option_error("invalid address parameter '%s' for ms-dns option", *argv); return 0; } - dns = *(u_int32_t *)hp->h_addr; + dns = *(u32_t *)hp->h_addr; } /* We take the last 2 values given, the 2nd-last as the primary @@ -408,17 +408,17 @@ static int setwinsaddr(argv) char **argv; { - u_int32_t wins; + u32_t wins; struct hostent *hp; wins = inet_addr(*argv); - if (wins == (u_int32_t) -1) { + if (wins == (u32_t) -1) { if ((hp = gethostbyname(*argv)) == NULL) { option_error("invalid address parameter '%s' for ms-wins option", *argv); return 0; } - wins = *(u_int32_t *)hp->h_addr; + wins = *(u32_t *)hp->h_addr; } /* We take the last 2 values given, the 2nd-last as the primary @@ -449,7 +449,7 @@ setipaddr(arg, argv, doit) { struct hostent *hp; char *colon; - u_int32_t local, remote; + u32_t local, remote; ipcp_options *wo = &ipcp_wantoptions[0]; static int prio_local = 0, prio_remote = 0; @@ -466,12 +466,12 @@ setipaddr(arg, argv, doit) */ if (colon != arg && option_priority >= prio_local) { *colon = '\0'; - if ((local = inet_addr(arg)) == (u_int32_t) -1) { + if ((local = inet_addr(arg)) == (u32_t) -1) { if ((hp = gethostbyname(arg)) == NULL) { option_error("unknown host: %s", arg); return 0; } - local = *(u_int32_t *)hp->h_addr; + local = *(u32_t *)hp->h_addr; } if (bad_ip_adrs(local)) { option_error("bad local IP address %s", ip_ntoa(local)); @@ -487,12 +487,12 @@ setipaddr(arg, argv, doit) * If colon last character, then no remote addr. */ if (*++colon != '\0' && option_priority >= prio_remote) { - if ((remote = inet_addr(colon)) == (u_int32_t) -1) { + if ((remote = inet_addr(colon)) == (u32_t) -1) { if ((hp = gethostbyname(colon)) == NULL) { option_error("unknown host: %s", colon); return 0; } - remote = *(u_int32_t *)hp->h_addr; + remote = *(u32_t *)hp->h_addr; if (remote_name[0] == 0) strlcpy(remote_name, colon, sizeof(remote_name)); } @@ -530,7 +530,7 @@ static int setnetmask(argv) char **argv; { - u_int32_t mask; + u32_t mask; int n; char *p; @@ -557,10 +557,10 @@ setnetmask(argv) int parse_dotted_ip(p, vp) char *p; - u_int32_t *vp; + u32_t *vp; { int n; - u_int32_t v, b; + u32_t v, b; char *endp, *p0 = p; v = 0; @@ -785,7 +785,7 @@ static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { #define ADDCIADDRS(opt, neg, val1, val2) \ if (neg) { \ if (len >= CILEN_ADDRS) { \ - u_int32_t l; \ + u32_t l; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_ADDRS, ucp); \ l = ntohl(val1); \ @@ -816,7 +816,7 @@ static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { #define ADDCIADDR(opt, neg, val) \ if (neg) { \ if (len >= CILEN_ADDR) { \ - u_int32_t l; \ + u32_t l; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_ADDR, ucp); \ l = ntohl(val); \ @@ -829,7 +829,7 @@ static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { #define ADDCIDNS(opt, neg, addr) \ if (neg) { \ if (len >= CILEN_ADDR) { \ - u_int32_t l; \ + u32_t l; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_ADDR, ucp); \ l = ntohl(addr); \ @@ -842,7 +842,7 @@ static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { #define ADDCIWINS(opt, addr) \ if (addr) { \ if (len >= CILEN_ADDR) { \ - u_int32_t l; \ + u32_t l; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_ADDR, ucp); \ l = ntohl(addr); \ @@ -884,7 +884,7 @@ static int ipcp_ackci(fsm *f, u_char *p, int len) { ppp_pcb *pcb = f->pcb; ipcp_options *go = &pcb->ipcp_gotoptions; u_short cilen, citype, cishort; - u_int32_t cilong; + u32_t cilong; u_char cimaxslotindex, cicflag; /* @@ -895,7 +895,7 @@ static int ipcp_ackci(fsm *f, u_char *p, int len) { #define ACKCIADDRS(opt, neg, val1, val2) \ if (neg) { \ - u_int32_t l; \ + u32_t l; \ if ((len -= CILEN_ADDRS) < 0) \ goto bad; \ GETCHAR(citype, p); \ @@ -938,7 +938,7 @@ static int ipcp_ackci(fsm *f, u_char *p, int len) { #define ACKCIADDR(opt, neg, val) \ if (neg) { \ - u_int32_t l; \ + u32_t l; \ if ((len -= CILEN_ADDR) < 0) \ goto bad; \ GETCHAR(citype, p); \ @@ -954,7 +954,7 @@ static int ipcp_ackci(fsm *f, u_char *p, int len) { #define ACKCIDNS(opt, neg, addr) \ if (neg) { \ - u_int32_t l; \ + u32_t l; \ if ((len -= CILEN_ADDR) < 0) \ goto bad; \ GETCHAR(citype, p); \ @@ -1007,7 +1007,7 @@ static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { u_char cimaxslotindex, cicflag; u_char citype, cilen, *next; u_short cishort; - u_int32_t ciaddr1, ciaddr2, l, cidnsaddr; + u32_t ciaddr1, ciaddr2, l, cidnsaddr; ipcp_options no; /* options we've seen Naks for */ ipcp_options try; /* options to request next time */ @@ -1250,7 +1250,7 @@ static int ipcp_rejci(fsm *f, u_char *p, int len) { ipcp_options *go = &pcb->ipcp_gotoptions; u_char cimaxslotindex, ciflag, cilen; u_short cishort; - u_int32_t cilong; + u32_t cilong; ipcp_options try; /* options to request next time */ try = *go; @@ -1264,7 +1264,7 @@ static int ipcp_rejci(fsm *f, u_char *p, int len) { (cilen = p[1]) == CILEN_ADDRS && \ len >= cilen && \ p[0] == opt) { \ - u_int32_t l; \ + u32_t l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ @@ -1307,7 +1307,7 @@ static int ipcp_rejci(fsm *f, u_char *p, int len) { (cilen = p[1]) == CILEN_ADDR && \ len >= cilen && \ p[0] == opt) { \ - u_int32_t l; \ + u32_t l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ @@ -1323,7 +1323,7 @@ static int ipcp_rejci(fsm *f, u_char *p, int len) { ((cilen = p[1]) == CILEN_ADDR) && \ len >= cilen && \ p[0] == opt) { \ - u_int32_t l; \ + u32_t l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ @@ -1339,7 +1339,7 @@ static int ipcp_rejci(fsm *f, u_char *p, int len) { ((cilen = p[1]) == CILEN_ADDR) && \ len >= cilen && \ p[0] == opt) { \ - u_int32_t l; \ + u32_t l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ @@ -1403,7 +1403,7 @@ static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { u_char *cip, *next; /* Pointer to current and next CIs */ u_short cilen, citype; /* Parsed len, type */ u_short cishort; /* Parsed short value */ - u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ + u32_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 */ @@ -1458,7 +1458,7 @@ static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { && (ciaddr1 == 0 || !wo->accept_remote)) { orc = CONFNAK; if (!reject_if_disagree) { - DECPTR(sizeof(u_int32_t), p); + DECPTR(sizeof(u32_t), p); tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } @@ -1481,7 +1481,7 @@ static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { if (ciaddr2 == 0 || !wo->accept_local) { orc = CONFNAK; if (!reject_if_disagree) { - DECPTR(sizeof(u_int32_t), p); + DECPTR(sizeof(u32_t), p); tl = ntohl(wo->ouraddr); PUTLONG(tl, p); } @@ -1514,7 +1514,7 @@ static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { && (ciaddr1 == 0 || !wo->accept_remote)) { orc = CONFNAK; if (!reject_if_disagree) { - DECPTR(sizeof(u_int32_t), p); + DECPTR(sizeof(u32_t), p); tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } @@ -1544,7 +1544,7 @@ static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { } GETLONG(tl, p); if (htonl(tl) != ao->dnsaddr[d]) { - DECPTR(sizeof(u_int32_t), p); + DECPTR(sizeof(u32_t), p); tl = ntohl(ao->dnsaddr[d]); PUTLONG(tl, p); orc = CONFNAK; @@ -1564,7 +1564,7 @@ static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { } GETLONG(tl, p); if (htonl(tl) != ao->winsaddr[d]) { - DECPTR(sizeof(u_int32_t), p); + DECPTR(sizeof(u32_t), p); tl = ntohl(ao->winsaddr[d]); PUTLONG(tl, p); orc = CONFNAK; @@ -1684,7 +1684,7 @@ static void ip_check_options() { struct hostent *hp; - u_int32_t local; + u32_t local; ipcp_options *wo = &ipcp_wantoptions[0]; /* @@ -1699,7 +1699,7 @@ ip_check_options() */ wo->accept_local = 1; /* don't insist on this default value */ if ((hp = gethostbyname(hostname)) != NULL) { - local = *(u_int32_t *)hp->h_addr; + local = *(u32_t *)hp->h_addr; if (local != 0 && !bad_ip_adrs(local)) wo->ouraddr = local; } @@ -1760,7 +1760,7 @@ ip_demand_conf(u) */ static void ipcp_up(fsm *f) { ppp_pcb *pcb = f->pcb; - u_int32_t mask; + u32_t mask; ipcp_options *ho = &pcb->ipcp_hisoptions; ipcp_options *go = &pcb->ipcp_gotoptions; ipcp_options *wo = &pcb->ipcp_wantoptions; @@ -2014,7 +2014,7 @@ static void ipcp_down(fsm *f) { * ipcp_clear_addrs() - clear the interface addresses, routes, * proxy arp entries, etc. */ -static void ipcp_clear_addrs(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t hisaddr, u8_t replacedefaultroute) { +static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute) { if (pcb->proxy_arp_set) { cifproxyarp(pcb, hisaddr); @@ -2054,7 +2054,7 @@ static void ipcp_finished(fsm *f) { */ static void create_resolv(peerdns1, peerdns2) - u_int32_t peerdns1, peerdns2; + u32_t peerdns1, peerdns2; { } @@ -2074,7 +2074,7 @@ static int ipcp_printpkt(u_char *p, int plen, int code, id, len, olen; u_char *pstart, *optend; u_short cishort; - u_int32_t cilong; + u32_t cilong; if (plen < HEADERLEN) return 0; diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index d576509e..ffd1f2eb 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -72,30 +72,31 @@ /* compression option*/ typedef struct ipcp_options { - u_int neg_addr :1; /* Negotiate IP Address? */ - u_int old_addrs :1; /* Use old (IP-Addresses) option? */ - u_int req_addr :1; /* Ask peer to send IP address? */ - u_int default_route :1; /* Assign default route through interface? */ - u_int replace_default_route :1; /* Replace default route through interface? */ - u_int proxy_arp :1; /* Make proxy ARP entry for peer? */ - u_int neg_vj :1; /* Van Jacobson Compression? */ - u_int old_vj :1; /* use old (short) form of VJ option? */ - u_int accept_local :1; /* accept peer's value for ouraddr */ - u_int accept_remote :1; /* accept peer's value for hisaddr */ - u_int req_dns1 :1; /* Ask peer to send primary DNS address? */ - u_int req_dns2 :1; /* Ask peer to send secondary DNS address? */ - u_int cflag :1; + unsigned int neg_addr :1; /* Negotiate IP Address? */ + unsigned int old_addrs :1; /* Use old (IP-Addresses) option? */ + unsigned int req_addr :1; /* Ask peer to send IP address? */ + unsigned int default_route :1; /* Assign default route through interface? */ + unsigned int replace_default_route :1; /* Replace default route through interface? */ + unsigned int proxy_arp :1; /* Make proxy ARP entry for peer? */ + unsigned int neg_vj :1; /* Van Jacobson Compression? */ + unsigned int old_vj :1; /* use old (short) form of VJ option? */ + unsigned int accept_local :1; /* accept peer's value for ouraddr */ + unsigned int accept_remote :1; /* accept peer's value for hisaddr */ + unsigned int req_dns1 :1; /* Ask peer to send primary DNS address? */ + unsigned int req_dns2 :1; /* Ask peer to send secondary DNS address? */ + unsigned int cflag :1; + unsigned int :3; /* 3 bits of padding to round out to 16 bits */ - u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ - u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ - u_int32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ + u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ + u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ + u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ u16_t vj_protocol; /* protocol value to use in VJ option */ u8_t maxslotindex; /* values for RFC1332 VJ compression neg. */ } ipcp_options; #if 0 /* UNUSED, already defined by lwIP */ -char *ip_ntoa (u_int32_t); +char *ip_ntoa (u32_t); #endif /* UNUSED, already defined by lwIP */ extern struct protent ipcp_protent; diff --git a/src/netif/ppp/ipv6cp.h b/src/netif/ppp/ipv6cp.h index c7ff0c20..8501d9c0 100644 --- a/src/netif/ppp/ipv6cp.h +++ b/src/netif/ppp/ipv6cp.h @@ -156,16 +156,19 @@ *#define IPV6CP_COMP 0x004f */ typedef struct ipv6cp_options { - u_int neg_ifaceid :1; /* Negotiate interface identifier? */ - u_int req_ifaceid :1; /* Ask peer to send interface identifier? */ - u_int accept_local :1; /* accept peer's value for iface id? */ - u_int opt_local :1; /* ourtoken set by option */ - u_int opt_remote :1; /* histoken set by option */ - u_int use_ip :1; /* use IP as interface identifier */ + unsigned int neg_ifaceid :1; /* Negotiate interface identifier? */ + unsigned int req_ifaceid :1; /* Ask peer to send interface identifier? */ + unsigned int accept_local :1; /* accept peer's value for iface id? */ + unsigned int opt_local :1; /* ourtoken set by option */ + unsigned int opt_remote :1; /* histoken set by option */ + unsigned int use_ip :1; /* use IP as interface identifier */ +#if 0 #if defined(SOL2) || defined(__linux__) - u_int use_persistent :1; /* use uniquely persistent value for address */ + unsigned int use_persistent :1; /* use uniquely persistent value for address */ #endif /* defined(SOL2) */ - u_int neg_vj :1; /* Van Jacobson Compression? */ +#endif + unsigned int neg_vj :1; /* Van Jacobson Compression? */ + unsigned int :1; /* 1 bit of padding to round out to 8 bits */ u_short vj_protocol; /* protocol value to use in VJ option */ eui64_t ourid, hisid; /* Interface identifiers */ } ipv6cp_options; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 499464b4..d5fea50a 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -889,7 +889,7 @@ static int lcp_ackci(fsm *f, u_char *p, int len) { lcp_options *go = &pcb->lcp_gotoptions; u_char cilen, citype, cichar; u_short cishort; - u_int32_t cilong; + u32_t cilong; /* * CIs must be in exactly the same order that we sent. @@ -1070,7 +1070,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { lcp_options *wo = &pcb->lcp_wantoptions; u_char citype, cichar, *next; u_short cishort; - u_int32_t cilong; + u32_t cilong; lcp_options no; /* options we've seen Naks for */ lcp_options try; /* options to request next time */ int looped_back = 0; @@ -1527,7 +1527,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { lcp_options *go = &pcb->lcp_gotoptions; u_char cichar; u_short cishort; - u_int32_t cilong; + u32_t cilong; lcp_options try; /* options to request next time */ try = *go; @@ -1761,7 +1761,7 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { 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 */ - u_int32_t cilong; /* Parse long value */ + u32_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 */ @@ -2315,7 +2315,7 @@ static int lcp_printpkt(u_char *p, int plen, int code, id, len, olen, i; u_char *pstart, *optend; u_short cishort; - u_int32_t cilong; + u32_t cilong; if (plen < HEADERLEN) return 0; @@ -2610,7 +2610,7 @@ static void LcpEchoTimeout(void *arg) { static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) { ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; - u_int32_t magic; + u32_t magic; /* Check the magic number - don't count replies from ourselves. */ if (len < 4) { @@ -2635,7 +2635,7 @@ static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) { static void LcpSendEchoRequest(fsm *f) { ppp_pcb *pcb = f->pcb; lcp_options *go = &pcb->lcp_gotoptions; - u_int32_t lcp_magic; + u32_t lcp_magic; u_char pkt[4], *pktp; /* diff --git a/src/netif/ppp/lcp.h b/src/netif/ppp/lcp.h index 8a1c841a..ec5e9a69 100644 --- a/src/netif/ppp/lcp.h +++ b/src/netif/ppp/lcp.h @@ -106,32 +106,42 @@ struct epdisc { * The state of options is described by an lcp_options structure. */ typedef struct lcp_options { - u_int passive :1; /* Don't die if we don't get a response */ - u_int silent :1; /* Wait for the other end to start first */ - u_int restart :1; /* Restart vs. exit after close */ - u_int neg_mru :1; /* Negotiate the MRU? */ - u_int neg_asyncmap :1; /* Negotiate the async map? */ + unsigned int passive :1; /* Don't die if we don't get a response */ + unsigned int silent :1; /* Wait for the other end to start first */ + unsigned int restart :1; /* Restart vs. exit after close */ + unsigned int neg_mru :1; /* Negotiate the MRU? */ + unsigned int neg_asyncmap :1; /* Negotiate the async map? */ #if PAP_SUPPORT - u_int neg_upap :1; /* Ask for UPAP authentication? */ + unsigned int neg_upap :1; /* Ask for UPAP authentication? */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT - u_int neg_chap :1; /* Ask for CHAP authentication? */ + unsigned int neg_chap :1; /* Ask for CHAP authentication? */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* CHAP_SUPPORT */ #if EAP_SUPPORT - u_int neg_eap :1; /* Ask for EAP authentication? */ + unsigned int neg_eap :1; /* Ask for EAP authentication? */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* EAP_SUPPORT */ - u_int neg_magicnumber :1; /* Ask for magic number? */ - u_int neg_pcompression :1; /* HDLC Protocol Field Compression? */ - u_int neg_accompression :1; /* HDLC Address/Control Field Compression? */ + unsigned int neg_magicnumber :1; /* Ask for magic number? */ + unsigned int neg_pcompression :1; /* HDLC Protocol Field Compression? */ + unsigned int neg_accompression :1; /* HDLC Address/Control Field Compression? */ #if LQR_SUPPORT - u_int neg_lqr :1; /* Negotiate use of Link Quality Reports */ + unsigned int neg_lqr :1; /* Negotiate use of Link Quality Reports */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* LQR_SUPPORT */ - u_int neg_cbcp :1; /* Negotiate use of CBCP */ + unsigned int neg_cbcp :1; /* Negotiate use of CBCP */ #ifdef HAVE_MULTILINK - u_int neg_mrru :1; /* negotiate multilink MRRU */ + unsigned int neg_mrru :1; /* negotiate multilink MRRU */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* HAVE_MULTILINK */ - u_int neg_ssnhf :1; /* negotiate short sequence numbers */ - u_int neg_endpoint :1; /* negotiate endpoint discriminator */ + unsigned int neg_ssnhf :1; /* negotiate short sequence numbers */ + unsigned int neg_endpoint :1; /* negotiate endpoint discriminator */ u16_t mru; /* Value of MRU */ #ifdef HAVE_MULTILINK u16_t mrru; /* Value of MRRU, and multilink enable */ @@ -139,11 +149,11 @@ typedef struct lcp_options { #if CHAP_SUPPORT u8_t chap_mdtype; /* which MD types (hashing algorithm) */ #endif /* CHAP_SUPPORT */ - u_int32_t asyncmap; /* Value of async map */ - u_int32_t magicnumber; + u32_t asyncmap; /* Value of async map */ + u32_t magicnumber; u8_t numloops; /* Number of loops during magic number neg. */ #if LQR_SUPPORT - u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ + u32_t lqr_period; /* Reporting period for LQR 1/100ths second */ #endif /* LQR_SUPPORT */ struct epdisc endpoint; /* endpoint discriminator */ } lcp_options; diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 551a067c..bb36fbd2 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -454,7 +454,7 @@ get_default_epdisc(ep) { char *p; struct hostent *hp; - u_int32_t addr; + u32_t addr; /* First try for an ethernet MAC address */ p = get_first_ethernet(); @@ -467,7 +467,7 @@ get_default_epdisc(ep) /* see if our hostname corresponds to a reasonable IP address */ hp = gethostbyname(hostname); if (hp != NULL) { - addr = *(u_int32_t *)hp->h_addr; + addr = *(u32_t *)hp->h_addr; if (!bad_ip_adrs(addr)) { addr = ntohl(addr); if (!LOCAL_IP_ADDR(addr)) { @@ -501,7 +501,7 @@ epdisc_to_str(ep) if (ep->class == EPD_NULL && ep->length == 0) return "null"; if (ep->class == EPD_IP && ep->length == 4) { - u_int32_t addr; + u32_t addr; GETLONG(addr, p); slprintf(str, sizeof(str), "IP:%I", htonl(addr)); @@ -572,7 +572,7 @@ str_to_epdisc(ep, str) ++str; if (i == EPD_IP) { - u_int32_t addr; + u32_t addr; i = parse_dotted_ip(str, &addr); if (i == 0 || str[i] != 0) return 0; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 3f4612ef..548e03c4 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1786,7 +1786,7 @@ void new_phase(ppp_pcb *pcb, int p) { * ppp_send_config - configure the transmit-side characteristics of * the ppp interface. */ -int ppp_send_config(ppp_pcb *pcb, int mtu, u_int32_t accm, int pcomp, int accomp) { +int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT int i; #endif /* PPPOS_SUPPORT */ @@ -1818,7 +1818,7 @@ int ppp_send_config(ppp_pcb *pcb, int mtu, u_int32_t accm, int pcomp, int accomp * ppp_recv_config - configure the receive-side characteristics of * the ppp interface. */ -int ppp_recv_config(ppp_pcb *pcb, int mru, u_int32_t accm, int pcomp, int accomp) { +int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp) { #if PPPOS_SUPPORT int i; SYS_ARCH_DECL_PROTECT(lev); @@ -1854,8 +1854,8 @@ int ppp_recv_config(ppp_pcb *pcb, int mru, u_int32_t accm, int pcomp, int accomp /* * sifaddr - Config the interface IP addresses and netmask. */ -int sifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr, - u_int32_t net_mask) { +int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, + u32_t net_mask) { SMEMCPY(&pcb->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); SMEMCPY(&pcb->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); @@ -1869,7 +1869,7 @@ int sifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr, * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */ -int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr) { +int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr) { LWIP_UNUSED_ARG(our_adr); LWIP_UNUSED_ARG(his_adr); @@ -1918,7 +1918,7 @@ int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { /* * sdns - Config the DNS servers */ -int sdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { +int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { SMEMCPY(&pcb->addrs.dns1, &ns1, sizeof(ns1)); SMEMCPY(&pcb->addrs.dns2, &ns2, sizeof(ns2)); @@ -1930,7 +1930,7 @@ int sdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { * * cdns - Clear the DNS servers */ -int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2) { +int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { LWIP_UNUSED_ARG(ns1); LWIP_UNUSED_ARG(ns2); @@ -2032,7 +2032,7 @@ int netif_get_mtu(ppp_pcb *pcb) { * and then changes the temporary addresses to the addresses for the real * ppp connection when it has come up. */ -int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, u8_t replace) { +int sifdefaultroute(ppp_pcb *pcb, u32_t ouraddr, u32_t gateway, u8_t replace) { LWIP_UNUSED_ARG(ouraddr); LWIP_UNUSED_ARG(gateway); @@ -2046,7 +2046,7 @@ int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, u8_t rep * * cifdefaultroute - delete a default route through the address given. */ -int cifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway) { +int cifdefaultroute(ppp_pcb *pcb, u32_t ouraddr, u32_t gateway) { LWIP_UNUSED_ARG(ouraddr); LWIP_UNUSED_ARG(gateway); @@ -2060,7 +2060,7 @@ int cifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway) { * sifproxyarp - Make a proxy ARP entry for the peer. */ -int sifproxyarp(ppp_pcb *pcb, u_int32_t his_adr) { +int sifproxyarp(ppp_pcb *pcb, u32_t his_adr) { LWIP_UNUSED_ARG(pcb); LWIP_UNUSED_ARG(his_adr); /* FIXME: do we really need that in IPCP ? */ @@ -2072,7 +2072,7 @@ int sifproxyarp(ppp_pcb *pcb, u_int32_t his_adr) { * cifproxyarp - Delete the proxy ARP entry for the peer. */ -int cifproxyarp(ppp_pcb *pcb, u_int32_t his_adr) { +int cifproxyarp(ppp_pcb *pcb, u32_t his_adr) { LWIP_UNUSED_ARG(pcb); LWIP_UNUSED_ARG(his_adr); /* FIXME: do we really need that in IPCP ? */ @@ -2134,7 +2134,7 @@ int get_loop_output(void) { * network as `addr'. If we find any, we OR in their netmask to the * user-specified netmask. */ -u_int32_t get_mask(u_int32_t addr) { +u32_t get_mask(u32_t addr) { #if 0 u32_t mask, nmask; diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index cc8ad0ff..9659b44e 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -150,36 +150,52 @@ typedef struct ppp_pcb_s ppp_pcb; typedef struct ppp_settings_s { #if PPP_SERVER - u_int auth_required : 1; /* Peer is required to authenticate */ + unsigned int auth_required : 1; /* Peer is required to authenticate */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* PPP_SERVER */ #if PPP_REMOTENAME - u_int explicit_remote : 1; /* remote_name specified with remotename opt */ + unsigned int explicit_remote : 1; /* remote_name specified with remotename opt */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* PPP_REMOTENAME */ #if PAP_SUPPORT - u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ + unsigned int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT - u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ + unsigned int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* CHAP_SUPPORT */ #if MSCHAP_SUPPORT - u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ - u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ + unsigned int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ + unsigned int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#else + unsigned int :2; /* 2 bits of padding */ #endif /* MSCHAP_SUPPORT */ #if EAP_SUPPORT - u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ + unsigned int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* EAP_SUPPORT */ - u_int usepeerdns : 1; /* Ask peer for DNS adds */ - u_int persist : 1; /* Persist mode, always try to reopen the connection */ + unsigned int usepeerdns : 1; /* Ask peer for DNS adds */ + unsigned int persist : 1; /* Persist mode, always try to reopen the connection */ #if PRINTPKT_SUPPORT - u_int hide_password : 1; /* Hide password in dumped packets */ + unsigned int hide_password : 1; /* Hide password in dumped packets */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* PRINTPKT_SUPPORT */ - u_int noremoteip : 1; /* Let him have no IP address */ - u_int lax_recv : 1; /* accept control chars in asyncmap */ - u_int noendpoint : 1; /* don't send/accept endpoint discriminator */ + unsigned int noremoteip : 1; /* Let him have no IP address */ + unsigned int lax_recv : 1; /* accept control chars in asyncmap */ + unsigned int noendpoint : 1; /* don't send/accept endpoint discriminator */ #if PPP_LCP_ADAPTIVE - u_int lcp_echo_adaptive : 1; /* request echo only if the link was idle */ + unsigned int lcp_echo_adaptive : 1; /* request echo only if the link was idle */ +#else + unsigned int :1; /* 1 bit of padding */ #endif - + unsigned int :2; /* 2 bits of padding to round out to 16 bits */ u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ @@ -266,21 +282,26 @@ typedef struct ppp_pcb_rx_s { * PPP interface control block. */ struct ppp_pcb_s { - u_int if_up :1; /* True when the interface is up. */ - u_int pcomp :1; /* Does peer accept protocol compression? */ - u_int accomp :1; /* Does peer accept addr/ctl compression? */ - u_int default_route_set :1; /* Have set up a default route */ - u_int proxy_arp_set :1; /* Have created proxy arp entry */ - u_int ipcp_is_open :1; /* haven't called np_finished() */ - u_int ipcp_is_up :1; /* have called ipcp_up() */ + unsigned int if_up :1; /* True when the interface is up. */ + unsigned int pcomp :1; /* Does peer accept protocol compression? */ + unsigned int accomp :1; /* Does peer accept addr/ctl compression? */ + unsigned int default_route_set :1; /* Have set up a default route */ + unsigned int proxy_arp_set :1; /* Have created proxy arp entry */ + unsigned int ipcp_is_open :1; /* haven't called np_finished() */ + unsigned int ipcp_is_up :1; /* have called ipcp_up() */ #if PPP_IPV6_SUPPORT - u_int ipv6cp_is_up :1; /* have called ip6cp_up() */ + unsigned int ipv6cp_is_up :1; /* have called ip6cp_up() */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* PPP_IPV6_SUPPORT */ - u_int ask_for_local :1; /* request our address from peer */ - u_int lcp_echo_timer_running :1; /* set if a timer is running */ + unsigned int ask_for_local :1; /* request our address from peer */ + unsigned int lcp_echo_timer_running :1; /* set if a timer is running */ #if PPPOS_SUPPORT && VJ_SUPPORT - u_int vj_enabled :1; /* Flag indicating VJ compression enabled. */ + unsigned int vj_enabled :1; /* Flag indicating VJ compression enabled. */ +#else + unsigned int :1; /* 1 bit of padding */ #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + unsigned int :5; /* 5 bits of padding to round out to 16 bits */ ppp_settings settings; diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index b19b88a7..4fb95f95 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -394,19 +394,19 @@ void new_phase(ppp_pcb *pcb, int p); #if PPPOS_SUPPORT void ppp_set_xaccm(ppp_pcb *pcb, ext_accm *accm); #endif /* PPPOS_SUPPORT */ -int ppp_send_config(ppp_pcb *pcb, int mtu, u_int32_t accm, int pcomp, int accomp); -int ppp_recv_config(ppp_pcb *pcb, int mru, u_int32_t accm, int pcomp, int accomp); +int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp); +int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp); -int sifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask); -int cifaddr(ppp_pcb *pcb, u_int32_t our_adr, u_int32_t his_adr); +int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t net_mask); +int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr); #if PPP_IPV6_SUPPORT int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); #endif /* PPP_IPV6_SUPPORT */ -int sdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2); -int cdns(ppp_pcb *pcb, u_int32_t ns1, u_int32_t ns2); +int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2); +int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2); int sifup(ppp_pcb *pcb); int sifdown (ppp_pcb *pcb); @@ -416,11 +416,11 @@ int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode); void netif_set_mtu(ppp_pcb *pcb, int mtu); int netif_get_mtu(ppp_pcb *pcb); -int sifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway, u8_t replace); -int cifdefaultroute(ppp_pcb *pcb, u_int32_t ouraddr, u_int32_t gateway); +int sifdefaultroute(ppp_pcb *pcb, u32_t ouraddr, u32_t gateway, u8_t replace); +int cifdefaultroute(ppp_pcb *pcb, u32_t ouraddr, u32_t gateway); -int sifproxyarp(ppp_pcb *pcb, u_int32_t his_adr); -int cifproxyarp(ppp_pcb *pcb, u_int32_t his_adr); +int sifproxyarp(ppp_pcb *pcb, u32_t his_adr); +int cifproxyarp(ppp_pcb *pcb, u32_t his_adr); int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid); @@ -430,7 +430,7 @@ int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip); int get_loop_output(void); -u_int32_t get_mask (u_int32_t addr); +u32_t get_mask (u32_t addr); /* Optional protocol names list, to make our messages a little more informative. */ @@ -533,7 +533,7 @@ int get_secret(ppp_pcb *pcb, char *client, char *server, char *secret, int *secr /* get "secret" for chap */ /* Procedures exported from ipcp.c */ -/* int parse_dotted_ip (char *, u_int32_t *); */ +/* int parse_dotted_ip (char *, u32_t *); */ /* Procedures exported from demand.c */ #if DEMAND_SUPPORT @@ -541,7 +541,7 @@ 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, u_int32_t); /* retransmit saved frames for an NP*/ +void demand_rexmit (int, u32_t); /* 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? */ #endif /* DEMAND_SUPPORT */ diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 9f94ca4e..074f8e94 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -145,7 +145,7 @@ int vslprintf(char *buf, int buflen, char *fmt, va_list args) { #if 0 /* need port */ time_t t; #endif /* need port */ - u_int32_t ip; + u32_t ip; static char hexchars[] = "0123456789abcdef"; #if PRINTPKT_SUPPORT struct buffer_info bufinfo; @@ -265,7 +265,7 @@ int vslprintf(char *buf, int buflen, char *fmt, va_list args) { break; #endif /* do we always have strerror() in embedded ? */ case 'I': - ip = va_arg(args, u_int32_t); + ip = va_arg(args, u32_t); ip = ntohl(ip); slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); From be9b23a082f82b21e342ac1bfe2cf01d32abfb69 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 7 Jul 2012 12:16:48 +0200 Subject: [PATCH 233/320] fixed LCP Echo Request/Reply feature --- src/netif/ppp/lcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index d5fea50a..04a2ac63 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -2595,7 +2595,7 @@ static void LcpEchoCheck(fsm *f) { */ static void LcpEchoTimeout(void *arg) { - fsm *f = (fsm*)f; + fsm *f = (fsm*)arg; ppp_pcb *pcb = f->pcb; if (pcb->lcp_echo_timer_running != 0) { pcb->lcp_echo_timer_running = 0; From 572e457e77d73976dbf2f2d2259ae69b043a4256 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 7 Jul 2012 15:05:15 +0200 Subject: [PATCH 234/320] improved PPP API header documentation --- src/netif/ppp/ppp.c | 10 ---------- src/netif/ppp/ppp.h | 36 +++++++++++++++++++++++------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 548e03c4..0e5c531e 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -317,16 +317,6 @@ void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { } #if PPPOS_SUPPORT -/** Open a new PPP connection using the given I/O device. - * This initializes the PPP control block but does not - * attempt to negotiate the LCP session. If this port - * connects to a modem, the modem connection must be - * established before calling this. - * Return a new PPP connection descriptor on success or - * an error code (negative) on failure. - * - * pppOpen() is directly defined to this function. - */ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { /* PPP is single-threaded: without a callback, diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 9659b44e..359f253b 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -392,15 +392,26 @@ struct ppp_pcb_s { *** PUBLIC FUNCTIONS *** ************************/ -/* Initialize the PPP subsystem. */ +/* + * Initialize the PPP subsystem. + */ int ppp_init(void); -/* Create a new PPP session, returns a PPP PCB structure. */ +/* + * Create a new PPP session. + * + * This initializes the PPP control block but does not + * attempt to negotiate the LCP session. + * + * Return a new PPP connection control block pointer + * on success or a null pointer on failure. + */ ppp_pcb *ppp_new(void); -/* Set auth helper, optional, you can either fill ppp_pcb->settings. */ - -/* Warning: Using PPPAUTHTYPE_ANY might have security consequences. +/* + * Set auth helper, optional, you can either fill ppp_pcb->settings. + * + * Warning: Using PPPAUTHTYPE_ANY might have security consequences. * RFC 1994 says: * * In practice, within or associated with each PPP server, there is a @@ -433,36 +444,35 @@ typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx); #if PPPOS_SUPPORT /* - * Open a new PPP connection using the given serial I/O device. - * This initializes the PPP control block but does not - * attempt to negotiate the LCP session. + * Start a new PPP connection using the given serial I/O device. * * If this port connects to a modem, the modem connection must be * established before calling this. * - * Return a new PPP connection descriptor on success or - * an error code (negative) on failure. + * Return 0 on success, an error code on failure. */ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT /* - * Open a new PPP Over Ethernet (PPPoE) connection. + * Start a new PPP Over Ethernet (PPPoE) connection. + * + * Return 0 on success, an error code on failure. */ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOE_SUPPORT */ /* - * Close a PPP connection and release the descriptor. + * Close a PPP connection and release the control block. * Any outstanding packets in the queues are dropped. * Return 0 on success, an error code on failure. */ int ppp_close(ppp_pcb *pcb); /* - * Indicate to the PPP process that the line has disconnected. + * Indicate to the PPP stack that the line has disconnected. */ void ppp_sighup(ppp_pcb *pcb); From f31b905847f923fc182850c5596c704752cf7d55 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 7 Jul 2012 17:33:34 +0200 Subject: [PATCH 235/320] initialize PPP in the lwip_init() function --- src/core/init.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/init.c b/src/core/init.c index 65c3f06f..e3865698 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -60,6 +60,7 @@ #include "lwip/nd6.h" #include "lwip/mld6.h" #include "lwip/api.h" +#include "ppp.h" /* Compile-time sanity checks for configuration errors. * These can be done independently of LWIP_DEBUG, without penalty. @@ -335,6 +336,9 @@ lwip_init(void) mld6_init(); #endif /* LWIP_IPV6_MLD */ #endif /* LWIP_IPV6 */ +#if PPP_SUPPORT + ppp_init(); +#endif #if LWIP_TIMERS sys_timeouts_init(); From d92c462466f90a6473fa80ea8c7b6b1f657a300d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 7 Jul 2012 19:50:56 +0200 Subject: [PATCH 236/320] added PPP Sequential API module, based from the Network Interface Sequential API module --- src/api/pppapi.c | 278 ++++++++++++++++++++++++++++++++++++++ src/api/tcpip.c | 57 ++++++++ src/include/lwip/opt.h | 7 + src/include/lwip/pppapi.h | 128 ++++++++++++++++++ src/include/lwip/tcpip.h | 18 +++ src/netif/ppp/ppp.c | 4 +- 6 files changed, 490 insertions(+), 2 deletions(-) create mode 100644 src/api/pppapi.c create mode 100644 src/include/lwip/pppapi.h diff --git a/src/api/pppapi.c b/src/api/pppapi.c new file mode 100644 index 00000000..84af376f --- /dev/null +++ b/src/api/pppapi.c @@ -0,0 +1,278 @@ +/** + * @file + * Point To Point Protocol Sequential API module + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pppapi.h" +#include "lwip/tcpip.h" + +/** + * Call ppp_new() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_new(struct pppapi_msg_msg *msg) { + msg->ppp = ppp_new(); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_new() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +ppp_pcb *pppapi_new(void) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_new; + TCPIP_PPPAPI(&msg); + return msg.msg.ppp; +} + + +/** + * Call ppp_set_auth() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_set_auth(struct pppapi_msg_msg *msg) { + ppp_set_auth(msg->ppp, msg->msg.setauth.authtype, + msg->msg.setauth.user, msg->msg.setauth.passwd); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_auth() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_auth; + msg.msg.ppp = pcb; + msg.msg.msg.setauth.authtype = authtype; + msg.msg.msg.setauth.user = user; + msg.msg.msg.setauth.passwd = passwd; + TCPIP_PPPAPI(&msg); +} + + +#if PPPOS_SUPPORT +/** + * Call ppp_over_serial_open() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_over_serial_open(struct pppapi_msg_msg *msg) { + msg->err = ppp_over_serial_open(msg->ppp, msg->msg.serialopen.fd, + msg->msg.serialopen.link_status_cb, msg->msg.serialopen.link_status_ctx); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_over_serial_open() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int pppapi_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_over_serial_open; + msg.msg.ppp = pcb; + msg.msg.msg.serialopen.fd = fd; + msg.msg.msg.serialopen.link_status_cb = link_status_cb; + msg.msg.msg.serialopen.link_status_ctx = link_status_ctx; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} +#endif /* PPPOS_SUPPORT */ + + +#if PPPOE_SUPPORT +/** + * Call ppp_over_ethernet_open() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_over_ethernet_open(struct pppapi_msg_msg *msg) { + + msg->err = ppp_over_ethernet_open(msg->ppp, msg->msg.ethernetopen.ethif, + msg->msg.ethernetopen.service_name, msg->msg.ethernetopen.concentrator_name, + msg->msg.ethernetopen.link_status_cb, msg->msg.ethernetopen.link_status_ctx); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_over_ethernet_open() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, + const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, + void *link_status_ctx) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_over_ethernet_open; + msg.msg.ppp = pcb; + msg.msg.msg.ethernetopen.ethif = ethif; + msg.msg.msg.ethernetopen.service_name = service_name; + msg.msg.msg.ethernetopen.concentrator_name = concentrator_name; + msg.msg.msg.ethernetopen.link_status_cb = link_status_cb; + msg.msg.msg.ethernetopen.link_status_ctx = link_status_ctx; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} +#endif /* PPPOE_SUPPORT */ + + +/** + * Call ppp_close() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_close(struct pppapi_msg_msg *msg) { + msg->err = ppp_close(msg->ppp); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_close() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int pppapi_close(ppp_pcb *pcb) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_close; + msg.msg.ppp = pcb; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} + + +/** + * Call ppp_sighup() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_sighup(struct pppapi_msg_msg *msg) { + ppp_sighup(msg->ppp); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_sighup() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void pppapi_sighup(ppp_pcb *pcb) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_sighup; + msg.msg.ppp = pcb; + TCPIP_PPPAPI(&msg); +} + + +/** + * Call ppp_ioctl() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_ioctl(struct pppapi_msg_msg *msg) { + msg->err = ppp_ioctl(msg->ppp, msg->msg.ioctl.cmd, msg->msg.ioctl.arg); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_ioctl() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_ioctl; + msg.msg.ppp = pcb; + msg.msg.msg.ioctl.cmd = cmd; + msg.msg.msg.ioctl.arg = arg; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} + + +#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD +/** + * Call pppos_input() inside the tcpip_thread context. + */ +static void pppapi_do_pppos_input(struct pppapi_msg_msg *msg) { + pppos_input(msg->ppp, msg->msg.ppposinput.data, msg->msg.ppposinput.len); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call pppos_input() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void ppposapi_input(ppp_pcb *pcb, u_char* data, int len) { + struct pppapi_msg msg; + msg.function = pppapi_do_pppos_input; + msg.msg.ppp = pcb; + msg.msg.msg.ppposinput.data = data; + msg.msg.msg.ppposinput.len = len; + TCPIP_PPPAPI(&msg); +} +#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ + + +#if LWIP_NETIF_STATUS_CALLBACK +/** + * Call ppp_set_netif_statuscallback() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_set_netif_statuscallback(struct pppapi_msg_msg *msg) { + ppp_set_netif_statuscallback(msg->ppp, msg->msg.netifstatuscallback.status_callback); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_netif_statuscallback() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void pppapi_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_netif_statuscallback; + msg.msg.ppp = pcb; + msg.msg.msg.netifstatuscallback.status_callback = status_callback; + TCPIP_PPPAPI(&msg); +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + + +#if LWIP_NETIF_LINK_CALLBACK +/** + * Call ppp_set_netif_linkcallback() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_set_netif_linkcallback(struct pppapi_msg_msg *msg) { + ppp_set_netif_linkcallback(msg->ppp, msg->msg.netiflinkcallback.link_callback); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_netif_linkcallback() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void pppapi_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_netif_linkcallback; + msg.msg.ppp = pcb; + msg.msg.msg.netiflinkcallback.link_callback = link_callback; + TCPIP_PPPAPI(&msg); +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#endif /* LWIP_PPP_API */ diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 7c1c9cad..44fb0989 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -122,6 +122,13 @@ tcpip_thread(void *arg) break; #endif /* LWIP_NETIF_API */ +#if LWIP_PPP_API + case TCPIP_MSG_PPPAPI: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PPP API message %p\n", (void *)msg)); + msg->msg.pppapimsg->function(&(msg->msg.pppapimsg->msg)); + break; +#endif /* LWIP_PPP_API */ + #if LWIP_TCPIP_TIMEOUT case TCPIP_MSG_TIMEOUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); @@ -378,6 +385,56 @@ tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) #endif /* !LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_NETIF_API */ +#if LWIP_PPP_API +#if !LWIP_TCPIP_CORE_LOCKING +/** + * Much like tcpip_apimsg, but calls the lower part of a pppapi_* + * function. + * + * @param pppapimsg a struct containing the function to call and its parameters + * @return error code given back by the function that was called + */ +err_t +tcpip_pppapi(struct pppapi_msg* pppapimsg) +{ + struct tcpip_msg msg; + + if (sys_mbox_valid(&mbox)) { + err_t err = sys_sem_new(&pppapimsg->msg.sem, 0); + if (err != ERR_OK) { + pppapimsg->msg.err = err; + return err; + } + + msg.type = TCPIP_MSG_PPPAPI; + msg.msg.pppapimsg = pppapimsg; + sys_mbox_post(&mbox, &msg); + sys_sem_wait(&pppapimsg->msg.sem); + sys_sem_free(&pppapimsg->msg.sem); + return pppapimsg->msg.err; + } + return ERR_VAL; +} +#else /* !LWIP_TCPIP_CORE_LOCKING */ +/** + * Call the lower part of a pppapi_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param pppapimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_pppapi()) + */ +err_t +tcpip_pppapi_lock(struct pppapi_msg* pppapimsg) +{ + LOCK_TCPIP_CORE(); + pppapimsg->function(&(pppapimsg->msg)); + UNLOCK_TCPIP_CORE(); + return pppapimsg->msg.err; +} +#endif /* !LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_PPP_API */ + /** * Allocate a structure for a static callback message and initialize it. * This is intended to be used to send "static" messages from interrupt context. diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 2ed0714f..467ad178 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1703,6 +1703,13 @@ #if PPP_SUPPORT +/** + * LWIP_PPP_API==1: Support PPP API (in pppapi.c) + */ +#ifndef LWIP_PPP_API +#define LWIP_PPP_API 0 +#endif + /** * PPP_FCS_TABLE: Keep a 256*2 byte table to speed up FCS calculation */ diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h new file mode 100644 index 00000000..0f618feb --- /dev/null +++ b/src/include/lwip/pppapi.h @@ -0,0 +1,128 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef __LWIP_PPPAPI_H__ +#define __LWIP_PPPAPI_H__ + +#include "lwip/opt.h" + +#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "ppp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct pppapi_msg_msg { +#if !LWIP_TCPIP_CORE_LOCKING + sys_sem_t sem; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + int err; + ppp_pcb *ppp; + union { + struct { + u8_t authtype; + char *user; + char *passwd; + } setauth; +#if PPPOS_SUPPORT + struct { + sio_fd_t fd; + ppp_link_status_cb_fn link_status_cb; + void *link_status_ctx; + } serialopen; +#endif /* PPPOS_SUPPORT */ +#if PPPOE_SUPPORT + struct { + struct netif *ethif; + const char *service_name; + const char *concentrator_name; + ppp_link_status_cb_fn link_status_cb; + void *link_status_ctx; + } ethernetopen; +#endif /* PPPOE_SUPPORT */ + struct { + int cmd; + void *arg; + } ioctl; +#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD + struct { + u_char *data; + int len; + } ppposinput; +#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ +#if LWIP_NETIF_STATUS_CALLBACK + struct { + netif_status_callback_fn status_callback; + } netifstatuscallback; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + struct { + netif_status_callback_fn link_callback; + } netiflinkcallback; +#endif /* LWIP_NETIF_LINK_CALLBACK */ + } msg; +}; + +struct pppapi_msg { + void (* function)(struct pppapi_msg_msg *msg); + struct pppapi_msg_msg msg; +}; + +/* API for application */ +ppp_pcb *pppapi_new(void); +void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd); +#if PPPOS_SUPPORT +int pppapi_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +#endif /* PPPOS_SUPPORT */ +#if PPPOE_SUPPORT +int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, + const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, + void *link_status_ctx); +#endif /* PPPOE_SUPPORT */ +int pppapi_close(ppp_pcb *pcb); +void pppapi_sighup(ppp_pcb *pcb); +int pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg); +#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD +void ppposapi_input(ppp_pcb *pcb, u_char* data, int len); +#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ +#if LWIP_NETIF_STATUS_CALLBACK +void pppapi_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK +void pppapi_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_PPP_API */ + +#endif /* __LWIP_PPPAPI_H__ */ diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h index 04567f2c..1f610f58 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -38,6 +38,7 @@ #include "lwip/api_msg.h" #include "lwip/netifapi.h" +#include "lwip/pppapi.h" #include "lwip/pbuf.h" #include "lwip/api.h" #include "lwip/sys.h" @@ -77,6 +78,8 @@ extern sys_mutex_t lock_tcpip_core; #define TCPIP_APIMSG_ACK(m) #define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) #define TCPIP_NETIFAPI_ACK(m) +#define TCPIP_PPPAPI(m) tcpip_pppapi_lock(m) +#define TCPIP_PPPAPI_ACK(m) #else /* LWIP_TCPIP_CORE_LOCKING */ #define LOCK_TCPIP_CORE() #define UNLOCK_TCPIP_CORE() @@ -85,6 +88,8 @@ extern sys_mutex_t lock_tcpip_core; #define TCPIP_APIMSG_ACK(m) sys_sem_signal(&m->conn->op_completed) #define TCPIP_NETIFAPI(m) tcpip_netifapi(m) #define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) +#define TCPIP_PPPAPI(m) tcpip_pppapi(m) +#define TCPIP_PPPAPI_ACK(m) sys_sem_signal(&m->sem) #endif /* LWIP_TCPIP_CORE_LOCKING */ /** Function prototype for the init_done function passed to tcpip_init */ @@ -110,6 +115,13 @@ err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); #endif /* LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_NETIF_API */ +#if LWIP_PPP_API +err_t tcpip_pppapi(struct pppapi_msg *pppapimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_pppapi_lock(struct pppapi_msg *pppapimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_PPP_API */ + err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); #define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) @@ -134,6 +146,9 @@ enum tcpip_msg_type { #if LWIP_NETIF_API TCPIP_MSG_NETIFAPI, #endif /* LWIP_NETIF_API */ +#if LWIP_PPP_API + TCPIP_MSG_PPPAPI, +#endif /* LWIP_PPP_API */ #if LWIP_TCPIP_TIMEOUT TCPIP_MSG_TIMEOUT, TCPIP_MSG_UNTIMEOUT, @@ -152,6 +167,9 @@ struct tcpip_msg { #if LWIP_NETIF_API struct netifapi_msg *netifapimsg; #endif /* LWIP_NETIF_API */ +#if LWIP_PPP_API + struct pppapi_msg *pppapimsg; +#endif /* LWIP_PPP_API */ struct { struct pbuf *p; struct netif *netif; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0e5c531e..b98481bd 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1738,7 +1738,7 @@ static void ppp_destroy(ppp_pcb *pcb) { void ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback) { - netif_set_status_callback(pcb->netif, status_callback); + netif_set_status_callback(&pcb->netif, status_callback); } #endif /* LWIP_NETIF_STATUS_CALLBACK */ @@ -1753,7 +1753,7 @@ ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callb void ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) { - netif_set_link_callback(pcb->netif, link_callback); + netif_set_link_callback(&pcb->netif, link_callback); } #endif /* LWIP_NETIF_LINK_CALLBACK */ From b4df26a75d7f851e2fda8f10ab623eddb42228fd Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 9 Jul 2012 22:04:09 +0200 Subject: [PATCH 237/320] some buggy compiler get confused with duplicated labels used in enum tcp_state and fsm.h, prepending PPP's ones --- src/netif/ppp/fsm.c | 220 +++++++++++++++++++++---------------------- src/netif/ppp/fsm.h | 24 ++--- src/netif/ppp/ipcp.c | 4 +- src/netif/ppp/lcp.c | 18 ++-- src/netif/ppp/ppp.c | 2 +- 5 files changed, 134 insertions(+), 134 deletions(-) diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 0804f476..60daf6ee 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -76,7 +76,7 @@ static void fsm_sconfreq(fsm *f, int retransmit); * Initialize fsm state. */ void fsm_init(fsm *f) { - f->state = INITIAL; + f->state = PPP_FSM_INITIAL; f->flags = 0; f->id = 0; /* XXX Start with random id? */ f->timeouttime = DEFTIMEOUT; @@ -92,17 +92,17 @@ void fsm_init(fsm *f) { */ void fsm_lowerup(fsm *f) { switch( f->state ){ - case INITIAL: - f->state = CLOSED; + case PPP_FSM_INITIAL: + f->state = PPP_FSM_CLOSED; break; - case STARTING: + case PPP_FSM_STARTING: if( f->flags & OPT_SILENT ) - f->state = STOPPED; + f->state = PPP_FSM_STOPPED; else { /* Send an initial configure-request */ fsm_sconfreq(f, 0); - f->state = REQSENT; + f->state = PPP_FSM_REQSENT; } break; @@ -120,33 +120,33 @@ void fsm_lowerup(fsm *f) { */ void fsm_lowerdown(fsm *f) { switch( f->state ){ - case CLOSED: - f->state = INITIAL; + case PPP_FSM_CLOSED: + f->state = PPP_FSM_INITIAL; break; - case STOPPED: - f->state = STARTING; + case PPP_FSM_STOPPED: + f->state = PPP_FSM_STARTING; if( f->callbacks->starting ) (*f->callbacks->starting)(f); break; - case CLOSING: - f->state = INITIAL; + case PPP_FSM_CLOSING: + f->state = PPP_FSM_INITIAL; UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ break; - case STOPPING: - case REQSENT: - case ACKRCVD: - case ACKSENT: - f->state = STARTING; + case PPP_FSM_STOPPING: + case PPP_FSM_REQSENT: + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: + f->state = PPP_FSM_STARTING; UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ break; - case OPENED: + case PPP_FSM_OPENED: if( f->callbacks->down ) (*f->callbacks->down)(f); - f->state = STARTING; + f->state = PPP_FSM_STARTING; break; default: @@ -161,28 +161,28 @@ void fsm_lowerdown(fsm *f) { */ void fsm_open(fsm *f) { switch( f->state ){ - case INITIAL: - f->state = STARTING; + case PPP_FSM_INITIAL: + f->state = PPP_FSM_STARTING; if( f->callbacks->starting ) (*f->callbacks->starting)(f); break; - case CLOSED: + case PPP_FSM_CLOSED: if( f->flags & OPT_SILENT ) - f->state = STOPPED; + f->state = PPP_FSM_STOPPED; else { /* Send an initial configure-request */ fsm_sconfreq(f, 0); - f->state = REQSENT; + f->state = PPP_FSM_REQSENT; } break; - case CLOSING: - f->state = STOPPING; + case PPP_FSM_CLOSING: + f->state = PPP_FSM_STOPPING; /* fall through */ /* no break */ - case STOPPED: - case OPENED: + case PPP_FSM_STOPPED: + case PPP_FSM_OPENED: if( f->flags & OPT_RESTART ){ fsm_lowerdown(f); fsm_lowerup(f); @@ -198,7 +198,7 @@ void fsm_open(fsm *f) { * send a terminate-request message as configured. */ static void terminate_layer(fsm *f, int nextstate) { - if( f->state != OPENED ) + if( f->state != PPP_FSM_OPENED ) UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ else if( f->callbacks->down ) (*f->callbacks->down)(f); /* Inform upper layers we're down */ @@ -214,7 +214,7 @@ static void terminate_layer(fsm *f, int nextstate) { * We've already fired off one Terminate-Request just to be nice * to the peer, but we're not going to wait for a reply. */ - f->state = nextstate == CLOSING ? CLOSED : STOPPED; + f->state = nextstate == PPP_FSM_CLOSING ? PPP_FSM_CLOSED : PPP_FSM_STOPPED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); return; @@ -230,27 +230,27 @@ static void terminate_layer(fsm *f, int nextstate) { * fsm_close - Start closing connection. * * Cancel timeouts and either initiate close or possibly go directly to - * the CLOSED state. + * the PPP_FSM_CLOSED state. */ void fsm_close(fsm *f, char *reason) { f->term_reason = reason; f->term_reason_len = (reason == NULL? 0: LWIP_MIN(strlen(reason), 0xFF) ); switch( f->state ){ - case STARTING: - f->state = INITIAL; + case PPP_FSM_STARTING: + f->state = PPP_FSM_INITIAL; break; - case STOPPED: - f->state = CLOSED; + case PPP_FSM_STOPPED: + f->state = PPP_FSM_CLOSED; break; - case STOPPING: - f->state = CLOSING; + case PPP_FSM_STOPPING: + f->state = PPP_FSM_CLOSING; break; - case REQSENT: - case ACKRCVD: - case ACKSENT: - case OPENED: - terminate_layer(f, CLOSING); + case PPP_FSM_REQSENT: + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: + case PPP_FSM_OPENED: + terminate_layer(f, PPP_FSM_CLOSING); break; } } @@ -263,13 +263,13 @@ static void fsm_timeout(void *arg) { fsm *f = (fsm *) arg; switch (f->state) { - case CLOSING: - case STOPPING: + case PPP_FSM_CLOSING: + case PPP_FSM_STOPPING: if( f->retransmits <= 0 ){ /* * We've waited for an ack long enough. Peer probably heard us. */ - f->state = (f->state == CLOSING)? CLOSED: STOPPED; + f->state = (f->state == PPP_FSM_CLOSING)? PPP_FSM_CLOSED: PPP_FSM_STOPPED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); } else { @@ -281,12 +281,12 @@ static void fsm_timeout(void *arg) { } break; - case REQSENT: - case ACKRCVD: - case ACKSENT: + case PPP_FSM_REQSENT: + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: if (f->retransmits <= 0) { warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); - f->state = STOPPED; + f->state = PPP_FSM_STOPPED; if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) (*f->callbacks->finished)(f); @@ -295,8 +295,8 @@ static void fsm_timeout(void *arg) { if (f->callbacks->retransmit) (*f->callbacks->retransmit)(f); fsm_sconfreq(f, 1); /* Re-send Configure-Request */ - if( f->state == ACKRCVD ) - f->state = REQSENT; + if( f->state == PPP_FSM_ACKRCVD ) + f->state = PPP_FSM_REQSENT; } break; @@ -337,7 +337,7 @@ void fsm_input(fsm *f, u_char *inpacket, int l) { } len -= HEADERLEN; /* subtract header length */ - if( f->state == INITIAL || f->state == STARTING ){ + if( f->state == PPP_FSM_INITIAL || f->state == PPP_FSM_STARTING ){ FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.", f->protocol, f->state)); return; @@ -388,26 +388,26 @@ static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) { int code, reject_if_disagree; switch( f->state ){ - case CLOSED: + case PPP_FSM_CLOSED: /* Go away, we're closed */ fsm_sdata(f, TERMACK, id, NULL, 0); return; - case CLOSING: - case STOPPING: + case PPP_FSM_CLOSING: + case PPP_FSM_STOPPING: return; - case OPENED: + case PPP_FSM_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; + f->state = PPP_FSM_REQSENT; break; - case STOPPED: + case PPP_FSM_STOPPED: /* Negotiation started by our peer */ fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; + f->state = PPP_FSM_REQSENT; break; } @@ -427,19 +427,19 @@ static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) { fsm_sdata(f, code, id, inp, len); if (code == CONFACK) { - if (f->state == ACKRCVD) { + if (f->state == PPP_FSM_ACKRCVD) { UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = OPENED; + f->state = PPP_FSM_OPENED; if (f->callbacks->up) (*f->callbacks->up)(f); /* Inform upper layers */ } else - f->state = ACKSENT; + f->state = PPP_FSM_ACKSENT; f->nakloops = 0; } else { /* we sent CONFACK or CONFREJ */ - if (f->state != ACKRCVD) - f->state = REQSENT; + if (f->state != PPP_FSM_ACKRCVD) + f->state = PPP_FSM_REQSENT; if( code == CONFNAK ) ++f->nakloops; } @@ -462,37 +462,37 @@ static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { f->rnakloops = 0; switch (f->state) { - case CLOSED: - case STOPPED: + case PPP_FSM_CLOSED: + case PPP_FSM_STOPPED: fsm_sdata(f, TERMACK, id, NULL, 0); break; - case REQSENT: - f->state = ACKRCVD; + case PPP_FSM_REQSENT: + f->state = PPP_FSM_ACKRCVD; f->retransmits = f->maxconfreqtransmits; break; - case ACKRCVD: + case PPP_FSM_ACKRCVD: /* Huh? an extra valid Ack? oh well... */ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ fsm_sconfreq(f, 0); - f->state = REQSENT; + f->state = PPP_FSM_REQSENT; break; - case ACKSENT: + case PPP_FSM_ACKSENT: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = OPENED; + f->state = PPP_FSM_OPENED; f->retransmits = f->maxconfreqtransmits; if (f->callbacks->up) (*f->callbacks->up)(f); /* Inform upper layers */ break; - case OPENED: + case PPP_FSM_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; + f->state = PPP_FSM_REQSENT; break; } } @@ -528,34 +528,34 @@ static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { f->seen_ack = 1; switch (f->state) { - case CLOSED: - case STOPPED: + case PPP_FSM_CLOSED: + case PPP_FSM_STOPPED: fsm_sdata(f, TERMACK, id, NULL, 0); break; - case REQSENT: - case ACKSENT: + case PPP_FSM_REQSENT: + case PPP_FSM_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 */ + f->state = PPP_FSM_STOPPED; /* kludge for stopping CCP */ else fsm_sconfreq(f, 0); /* Send Configure-Request */ break; - case ACKRCVD: + case PPP_FSM_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; + f->state = PPP_FSM_REQSENT; break; - case OPENED: + case PPP_FSM_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; + f->state = PPP_FSM_REQSENT; break; } } @@ -566,18 +566,18 @@ static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { */ 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 */ + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: + f->state = PPP_FSM_REQSENT; /* Start over but keep trying */ break; - case OPENED: + case PPP_FSM_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)); f->retransmits = 0; - f->state = STOPPING; + f->state = PPP_FSM_STOPPING; if (f->callbacks->down) (*f->callbacks->down)(f); /* Inform upper layers */ TIMEOUT(fsm_timeout, f, f->timeouttime); @@ -593,28 +593,28 @@ static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { */ static void fsm_rtermack(fsm *f) { switch (f->state) { - case CLOSING: + case PPP_FSM_CLOSING: UNTIMEOUT(fsm_timeout, f); - f->state = CLOSED; + f->state = PPP_FSM_CLOSED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); break; - case STOPPING: + case PPP_FSM_STOPPING: UNTIMEOUT(fsm_timeout, f); - f->state = STOPPED; + f->state = PPP_FSM_STOPPED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); break; - case ACKRCVD: - f->state = REQSENT; + case PPP_FSM_ACKRCVD: + f->state = PPP_FSM_REQSENT; break; - case OPENED: + case PPP_FSM_OPENED: if (f->callbacks->down) (*f->callbacks->down)(f); /* Inform upper layers */ fsm_sconfreq(f, 0); - f->state = REQSENT; + f->state = PPP_FSM_REQSENT; break; } } @@ -634,8 +634,8 @@ static void fsm_rcoderej(fsm *f, u_char *inp, int len) { 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; + if( f->state == PPP_FSM_ACKRCVD ) + f->state = PPP_FSM_REQSENT; } @@ -646,31 +646,31 @@ static void fsm_rcoderej(fsm *f, u_char *inp, int len) { */ void fsm_protreject(fsm *f) { switch( f->state ){ - case CLOSING: + case PPP_FSM_CLOSING: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ /* fall through */ /* no break */ - case CLOSED: - f->state = CLOSED; + case PPP_FSM_CLOSED: + f->state = PPP_FSM_CLOSED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); break; - case STOPPING: - case REQSENT: - case ACKRCVD: - case ACKSENT: + case PPP_FSM_STOPPING: + case PPP_FSM_REQSENT: + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ /* fall through */ /* no break */ - case STOPPED: - f->state = STOPPED; + case PPP_FSM_STOPPED: + f->state = PPP_FSM_STOPPED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); break; - case OPENED: - terminate_layer(f, STOPPING); + case PPP_FSM_OPENED: + terminate_layer(f, PPP_FSM_STOPPING); break; default: @@ -690,7 +690,7 @@ static void fsm_sconfreq(fsm *f, int retransmit) { u_char *outp; int cilen; - if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){ + if( f->state != PPP_FSM_REQSENT && f->state != PPP_FSM_ACKRCVD && f->state != PPP_FSM_ACKSENT ){ /* Not currently negotiating - reset options */ if( f->callbacks->resetci ) (*f->callbacks->resetci)(f); diff --git a/src/netif/ppp/fsm.h b/src/netif/ppp/fsm.h index fe347118..dbffd93c 100644 --- a/src/netif/ppp/fsm.h +++ b/src/netif/ppp/fsm.h @@ -108,9 +108,9 @@ typedef struct fsm_callbacks { (fsm *, u_char *, int); int (*reqci) /* Request peer's Configuration Information */ (fsm *, u_char *, int *, int); - void (*up) /* Called when fsm reaches OPENED state */ + void (*up) /* Called when fsm reaches PPP_FSM_OPENED state */ (fsm *); - void (*down) /* Called when fsm leaves OPENED state */ + void (*down) /* Called when fsm leaves PPP_FSM_OPENED state */ (fsm *); void (*starting) /* Called when we want the lower layer */ (fsm *); @@ -129,16 +129,16 @@ typedef struct 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 */ +#define PPP_FSM_INITIAL 0 /* Down, hasn't been opened */ +#define PPP_FSM_STARTING 1 /* Down, been opened */ +#define PPP_FSM_CLOSED 2 /* Up, hasn't been opened */ +#define PPP_FSM_STOPPED 3 /* Open, waiting for down event */ +#define PPP_FSM_CLOSING 4 /* Terminating the connection, not open */ +#define PPP_FSM_STOPPING 5 /* Terminating, but open */ +#define PPP_FSM_REQSENT 6 /* We've sent a Config Request */ +#define PPP_FSM_ACKRCVD 7 /* We've received a Config Ack */ +#define PPP_FSM_ACKSENT 8 /* We've sent a Config Ack */ +#define PPP_FSM_OPENED 9 /* Connection available */ /* diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 3c104c8f..da390b35 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1230,7 +1230,7 @@ static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { * OK, the Nak is good. Now we can update state. * If there are any remaining options, we ignore them. */ - if (f->state != OPENED) + if (f->state != PPP_FSM_OPENED) *go = try; return 1; @@ -1374,7 +1374,7 @@ static int ipcp_rejci(fsm *f, u_char *p, int len) { /* * Now we can update state. */ - if (f->state != OPENED) + if (f->state != PPP_FSM_OPENED) *go = try; return 1; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 04a2ac63..9e0f391c 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -445,12 +445,12 @@ void lcp_close(ppp_pcb *pcb, char *reason) { if (f->flags & DELAYED_UP) { UNTIMEOUT(lcp_delayed_up, f); - f->state = STOPPED; + f->state = PPP_FSM_STOPPED; } oldstate = f->state; fsm_close(f, reason); - if (oldstate == STOPPED && (f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP))) { + if (oldstate == PPP_FSM_STOPPED && (f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP))) { /* * This action is not strictly according to the FSM in RFC1548, * but it does mean that the program terminates if you do a @@ -562,7 +562,7 @@ static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) { break; case ECHOREQ: - if (f->state != OPENED) + if (f->state != PPP_FSM_OPENED) break; magp = inp; PUTLONG(go->magicnumber, magp); @@ -609,7 +609,7 @@ static void lcp_rprotrej(fsm *f, u_char *inp, int len) { * Protocol-Reject packets received in any state other than the LCP * OPENED state SHOULD be silently discarded. */ - if( f->state != OPENED ){ + if( f->state != PPP_FSM_OPENED ){ LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state)); return; } @@ -1492,7 +1492,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { * OK, the Nak is good. Now we can update state. * If there are any options left we ignore them. */ - if (f->state != OPENED) { + if (f->state != PPP_FSM_OPENED) { if (looped_back) { if (++try.numloops >= pcb->lcp_loopbackfail) { int errcode = PPPERR_LOOPBACK; @@ -1733,7 +1733,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* * Now we can update state. */ - if (f->state != OPENED) + if (f->state != PPP_FSM_OPENED) *go = try; return 1; @@ -2561,7 +2561,7 @@ static int lcp_printpkt(u_char *p, int plen, static void LcpLinkFailure(fsm *f) { ppp_pcb *pcb = f->pcb; - if (f->state == OPENED) { + if (f->state == PPP_FSM_OPENED) { int errcode = PPPERR_PEERDEAD; info("No response to %d echo-requests", pcb->lcp_echos_pending); notice("Serial link appears to be disconnected."); @@ -2578,7 +2578,7 @@ static void LcpEchoCheck(fsm *f) { ppp_pcb *pcb = f->pcb; LcpSendEchoRequest (f); - if (f->state != OPENED) + if (f->state != PPP_FSM_OPENED) return; /* @@ -2671,7 +2671,7 @@ static void LcpSendEchoRequest(fsm *f) { /* * Make and send the echo request frame. */ - if (f->state == OPENED) { + if (f->state == PPP_FSM_OPENED) { lcp_magic = go->magicnumber; pktp = pkt; PUTLONG(lcp_magic, pktp); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index b98481bd..12b76a44 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -508,7 +508,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { /* * Toss all non-LCP packets unless LCP is OPEN. */ - if (protocol != PPP_LCP && pcb->lcp_fsm.state != OPENED) { + if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) { dbglog("Discarded non-LCP packet when LCP not open"); goto drop; } From 0797ab6bc6382e94aa580db4a0b5eac17a38d0f9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 9 Jul 2012 22:12:14 +0200 Subject: [PATCH 238/320] some buggy compiler get confused with duplicated labels used in enum tcp_state and fsm.h, prepending PPP's ones --- src/netif/ppp/ipv6cp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c index cd451e6b..cfccb7f4 100644 --- a/src/netif/ppp/ipv6cp.c +++ b/src/netif/ppp/ipv6cp.c @@ -769,7 +769,7 @@ static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { /* * OK, the Nak is good. Now we can update state. */ - if (f->state != OPENED) + if (f->state != PPP_FSM_OPENED) *go = try; return 1; @@ -837,7 +837,7 @@ static int ipv6cp_rejci(fsm *f, u_char *p, int len) { /* * Now we can update state. */ - if (f->state != OPENED) + if (f->state != PPP_FSM_OPENED) *go = try; return 1; @@ -1327,13 +1327,13 @@ ipv6cp_script_done(arg) ipv6cp_script_pid = 0; switch (ipv6cp_script_state) { case s_up: - if (ipv6cp_fsm[0].state != OPENED) { + if (ipv6cp_fsm[0].state != PPP_FSM_OPENED) { ipv6cp_script_state = s_down; ipv6cp_script(_PATH_IPV6DOWN); } break; case s_down: - if (ipv6cp_fsm[0].state == OPENED) { + if (ipv6cp_fsm[0].state == PPP_FSM_OPENED) { ipv6cp_script_state = s_up; ipv6cp_script(_PATH_IPV6UP); } From f534e80c71f2b33b19e570217353b027471c5789 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 9 Jul 2012 23:25:32 +0200 Subject: [PATCH 239/320] added L2TPv2 (PPP over L2TP, a.k.a. UDP tunnels) support Supported: - L2TPv2 (PPP over L2TP, a.k.a. UDP tunnels) - LAC Not supported: - LNS (require PPP server support) - L2TPv3 ethernet pseudowires - L2TPv3 VLAN pseudowire - L2TPv3 PPP pseudowires - L2TPv3 IP encapsulation - L2TPv3 IP pseudowire - L2TP tunnel switching - http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08 - Multiple tunnels per UDP socket, as well as multiple sessions per tunnel - Hidden AVPs --- src/api/pppapi.c | 41 ++ src/core/memp.c | 1 + src/include/lwip/memp_std.h | 13 +- src/include/lwip/opt.h | 36 +- src/include/lwip/pppapi.h | 16 + src/include/netif/ppp_oe.h | 3 +- src/include/netif/pppol2tp.h | 219 ++++++++ src/netif/ppp/ppp.c | 180 +++++++ src/netif/ppp/ppp.h | 19 + src/netif/ppp/ppp_oe.c | 2 +- src/netif/ppp/pppol2tp.c | 990 +++++++++++++++++++++++++++++++++++ 11 files changed, 1505 insertions(+), 15 deletions(-) create mode 100644 src/include/netif/pppol2tp.h create mode 100644 src/netif/ppp/pppol2tp.c diff --git a/src/api/pppapi.c b/src/api/pppapi.c index 84af376f..40905362 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -142,6 +142,47 @@ int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *ser #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +/** + * Call ppp_over_l2tp_open() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_over_l2tp_open(struct pppapi_msg_msg *msg) { + + msg->err = ppp_over_l2tp_open(msg->ppp, msg->msg.l2tpopen.ipaddr, + msg->msg.l2tpopen.port, +#if PPPOL2TP_AUTH_SUPPORT + msg->msg.l2tpopen.secret, + msg->msg.l2tpopen.secret_len, +#else /* PPPOL2TP_AUTH_SUPPORT */ + NULL, +#endif /* PPPOL2TP_AUTH_SUPPORT */ + msg->msg.l2tpopen.link_status_cb, msg->msg.l2tpopen.link_status_ctx); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_over_l2tp_open() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int pppapi_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, + ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_over_l2tp_open; + msg.msg.ppp = pcb; + msg.msg.msg.l2tpopen.ipaddr = ipaddr; + msg.msg.msg.l2tpopen.port = port; +#if PPPOL2TP_AUTH_SUPPORT + msg.msg.msg.l2tpopen.secret = secret; + msg.msg.msg.l2tpopen.secret_len = secret_len; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + msg.msg.msg.l2tpopen.link_status_cb = link_status_cb; + msg.msg.msg.l2tpopen.link_status_ctx = link_status_ctx; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} +#endif /* PPPOL2TP_SUPPORT */ + + /** * Call ppp_close() inside the tcpip_thread context. */ diff --git a/src/core/memp.c b/src/core/memp.c index 3496f682..9db9a5e5 100644 --- a/src/core/memp.c +++ b/src/core/memp.c @@ -58,6 +58,7 @@ #include "lwip/snmp_msg.h" #include "lwip/dns.h" #include "netif/ppp_oe.h" +#include "netif/pppol2tp.h" #include "lwip/nd6.h" #include "lwip/ip6_frag.h" #include "lwip/mld6.h" diff --git a/src/include/lwip/memp_std.h b/src/include/lwip/memp_std.h index be547cfa..c0dee5ea 100644 --- a/src/include/lwip/memp_std.h +++ b/src/include/lwip/memp_std.h @@ -89,11 +89,14 @@ LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, #endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ #if PPP_SUPPORT -LWIP_MEMPOOL(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB") -#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ -#if PPP_SUPPORT && PPPOE_SUPPORT -LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") -#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ +LWIP_MEMPOOL(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB") +#if PPPOE_SUPPORT +LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +LWIP_MEMPOOL(PPPOL2TP_PCB, MEMP_NUM_PPPOL2TP_INTERFACES, sizeof(pppol2tp_pcb), "PPPOL2TP_PCB") +#endif /* PPPOL2TP_SUPPORT */ +#endif /* PPP_SUPPORT */ #if LWIP_IPV6 && LWIP_ND6_QUEUEING LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE") diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 467ad178..8e2be763 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -415,6 +415,14 @@ #define MEMP_NUM_PPPOE_INTERFACES 1 #endif +/** + * MEMP_NUM_PPPOL2TP_INTERFACES: the number of concurrently active PPPoL2TP + * interfaces (only used with PPPOL2TP_SUPPORT==1) + */ +#ifndef MEMP_NUM_PPPOL2TP_INTERFACES +#define MEMP_NUM_PPPOL2TP_INTERFACES 1 +#endif + /** * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ @@ -1694,6 +1702,20 @@ #define PPPOE_SUPPORT 0 #endif +/** + * PPPOL2TP_SUPPORT==1: Enable PPP Over L2TP + */ +#ifndef PPPOL2TP_SUPPORT +#define PPPOL2TP_SUPPORT 0 +#endif + +/** + * PPPOL2TP_AUTH_SUPPORT==1: Enable PPP Over L2TP Auth (enable MD5 support) + */ +#ifndef PPPOL2TP_AUTH_SUPPORT +#define PPPOL2TP_AUTH_SUPPORT PPPOL2TP_SUPPORT +#endif + /** * PPPOS_SUPPORT==1: Enable PPP Over Serial */ @@ -1782,15 +1804,15 @@ #endif /* !PPPOS_SUPPORT */ /** - * PPP_MD5_RANDM==1: Use MD5 for better randomness. Automatically enabled if CHAP support is enabled. + * PPP_MD5_RANDM==1: Use MD5 for better randomness. Automatically enabled if CHAP or L2TP AUTH support is enabled. */ #ifndef PPP_MD5_RANDM #define PPP_MD5_RANDM 0 #endif -#if CHAP_SUPPORT +#if CHAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT #undef PPP_MD5_RANDM -#define PPP_MD5_RANDM 1 /* MD5 Random is required for CHAP */ -#endif /* CHAP_SUPPORT */ +#define PPP_MD5_RANDM 1 /* MD5 Random is required for CHAP and L2TP AUTH */ +#endif /* CHAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT */ /** * PolarSSL library, used if necessary and not previously disabled @@ -1825,11 +1847,11 @@ * using our cleaned PolarSSL library. */ -#if CHAP_SUPPORT || EAP_SUPPORT || PPP_MD5_RANDM +#if CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM #ifndef LWIP_INCLUDED_POLARSSL_MD5 -#define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP, EAP and MD5 Random require MD5 support */ +#define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP, EAP, L2TP AUTH and MD5 Random require MD5 support */ #endif /* LWIP_INCLUDED_POLARSSL_MD5 */ -#endif /* CHAP_SUPPORT || EAP_SUPPORT || PPP_MD5_RANDM */ +#endif /* CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM */ #if MSCHAP_SUPPORT #ifndef LWIP_INCLUDED_POLARSSL_MD4 diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index 0f618feb..4b139ab8 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -67,6 +67,18 @@ struct pppapi_msg_msg { void *link_status_ctx; } ethernetopen; #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + struct { + ip_addr_t *ipaddr; + u16_t port; +#if PPPOL2TP_AUTH_SUPPORT + u8_t *secret; + u8_t secret_len; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + ppp_link_status_cb_fn link_status_cb; + void *link_status_ctx; + } l2tpopen; +#endif /* PPPOL2TP_SUPPORT */ struct { int cmd; void *arg; @@ -106,6 +118,10 @@ int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *ser const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +int pppapi_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, + ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +#endif /* PPPOL2TP_SUPPORT */ int pppapi_close(ppp_pcb *pcb); void pppapi_sighup(ppp_pcb *pcb); int pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg); diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index 7078be01..ac5deff8 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -73,8 +73,7 @@ #ifndef PPP_OE_H #define PPP_OE_H -#include "ppp_impl.h" - +#include "ppp.h" #include "netif/etharp.h" #ifdef PACK_STRUCT_USE_INCLUDES diff --git a/src/include/netif/pppol2tp.h b/src/include/netif/pppol2tp.h new file mode 100644 index 00000000..e417a07e --- /dev/null +++ b/src/include/netif/pppol2tp.h @@ -0,0 +1,219 @@ +/** + * @file + * Network Point to Point Protocol over Layer 2 Tunneling Protocol header file. + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPPOL2TP_H_ +#define PPPOL2TP_H_ + +#include "ppp.h" + +/* Timeout */ +#define PPPOL2TP_CONTROL_TIMEOUT (5*1000) /* base for quick timeout calculation */ +#define PPPOL2TP_SLOW_RETRY (60*1000) /* persistent retry interval */ + +#define PPPOL2TP_MAXSCCRQ 4 /* retry SCCRQ four times (quickly) */ +#define PPPOL2TP_MAXICRQ 4 /* retry IRCQ four times */ +#define PPPOL2TP_MAXICCN 4 /* retry ICCN four times */ + +/* L2TP header flags */ +#define PPPOL2TP_HEADERFLAG_CONTROL 0x8000 +#define PPPOL2TP_HEADERFLAG_LENGTH 0x4000 +#define PPPOL2TP_HEADERFLAG_SEQUENCE 0x0800 +#define PPPOL2TP_HEADERFLAG_OFFSET 0x0200 +#define PPPOL2TP_HEADERFLAG_PRIORITY 0x0100 +#define PPPOL2TP_HEADERFLAG_VERSION 0x0002 + +/* Mandatory bits for control: Control, Length, Sequence, Version 2 */ +#define PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY (PPPOL2TP_HEADERFLAG_CONTROL|PPPOL2TP_HEADERFLAG_LENGTH|PPPOL2TP_HEADERFLAG_SEQUENCE|PPPOL2TP_HEADERFLAG_VERSION) +/* Forbidden bits for control: Offset, Priority */ +#define PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN (PPPOL2TP_HEADERFLAG_OFFSET|PPPOL2TP_HEADERFLAG_PRIORITY) + +/* Mandatory bits for data: Version 2 */ +#define PPPOL2TP_HEADERFLAG_DATA_MANDATORY (PPPOL2TP_HEADERFLAG_VERSION) + +/* AVP (Attribute Value Pair) header */ +#define PPPOL2TP_AVPHEADERFLAG_MANDATORY 0x8000 +#define PPPOL2TP_AVPHEADERFLAG_HIDDEN 0x4000 +#define PPPOL2TP_AVPHEADERFLAG_LENGTHMASK 0x03ff + +/* -- AVP - Message type */ +#define PPPOL2TP_AVPTYPE_MESSAGE 0 /* Message type */ + +/* Control Connection Management */ +#define PPPOL2TP_MESSAGETYPE_SCCRQ 1 /* Start Control Connection Request */ +#define PPPOL2TP_MESSAGETYPE_SCCRP 2 /* Start Control Connection Reply */ +#define PPPOL2TP_MESSAGETYPE_SCCCN 3 /* Start Control Connection Connected */ +#define PPPOL2TP_MESSAGETYPE_STOPCCN 4 /* Stop Control Connection Notification */ +#define PPPOL2TP_MESSAGETYPE_HELLO 6 /* Hello */ +/* Call Management */ +#define PPPOL2TP_MESSAGETYPE_OCRQ 7 /* Outgoing Call Request */ +#define PPPOL2TP_MESSAGETYPE_OCRP 8 /* Outgoing Call Reply */ +#define PPPOL2TP_MESSAGETYPE_OCCN 9 /* Outgoing Call Connected */ +#define PPPOL2TP_MESSAGETYPE_ICRQ 10 /* Incoming Call Request */ +#define PPPOL2TP_MESSAGETYPE_ICRP 11 /* Incoming Call Reply */ +#define PPPOL2TP_MESSAGETYPE_ICCN 12 /* Incoming Call Connected */ +#define PPPOL2TP_MESSAGETYPE_CDN 14 /* Call Disconnect Notify */ +/* Error reporting */ +#define PPPOL2TP_MESSAGETYPE_WEN 15 /* WAN Error Notify */ +/* PPP Session Control */ +#define PPPOL2TP_MESSAGETYPE_SLI 16 /* Set Link Info */ + +/* -- AVP - Result code */ +#define PPPOL2TP_AVPTYPE_RESULTCODE 1 /* Result code */ +#define PPPOL2TP_RESULTCODE 1 /* General request to clear control connection */ + +/* -- AVP - Protocol version (!= L2TP Header version) */ +#define PPPOL2TP_AVPTYPE_VERSION 2 +#define PPPOL2TP_VERSION 0x0100 /* L2TP Protocol version 1, revision 0 */ + +/* -- AVP - Framing capabilities */ +#define PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES 3 /* Bearer capabilities */ +#define PPPOL2TP_FRAMINGCAPABILITIES 0x00000003 /* Async + Sync framing */ + +/* -- AVP - Bearer capabilities */ +#define PPPOL2TP_AVPTYPE_BEARERCAPABILITIES 4 /* Bearer capabilities */ +#define PPPOL2TP_BEARERCAPABILITIES 0x00000003 /* Analog + Digital Access */ + +/* -- AVP - Tie breaker */ +#define PPPOL2TP_AVPTYPE_TIEBREAKER 5 + +/* -- AVP - Host name */ +#define PPPOL2TP_AVPTYPE_HOSTNAME 7 /* Host name */ +#define PPPOL2TP_HOSTNAME "lwIP" /* FIXME: make it configurable */ + +/* -- AVP - Vendor name */ +#define PPPOL2TP_AVPTYPE_VENDORNAME 8 /* Vendor name */ +#define PPPOL2TP_VENDORNAME "lwIP" /* FIXME: make it configurable */ + +/* -- AVP - Assign tunnel ID */ +#define PPPOL2TP_AVPTYPE_TUNNELID 9 /* Assign Tunnel ID */ + +/* -- AVP - Receive window size */ +#define PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE 10 /* Receive window size */ +#define PPPOL2TP_RECEIVEWINDOWSIZE 8 /* FIXME: make it configurable */ + +/* -- AVP - Challenge */ +#define PPPOL2TP_AVPTYPE_CHALLENGE 11 /* Challenge */ + +/* -- AVP - Cause code */ +#define PPPOL2TP_AVPTYPE_CAUSECODE 12 /* Cause code*/ + +/* -- AVP - Challenge response */ +#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE 13 /* Challenge response */ +#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE 16 + +/* -- AVP - Assign session ID */ +#define PPPOL2TP_AVPTYPE_SESSIONID 14 /* Assign Session ID */ + +/* -- AVP - Call serial number */ +#define PPPOL2TP_AVPTYPE_CALLSERIALNUMBER 15 /* Call Serial Number */ + +/* -- AVP - Framing type */ +#define PPPOL2TP_AVPTYPE_FRAMINGTYPE 19 /* Framing Type */ +#define PPPOL2TP_FRAMINGTYPE 0x00000001 /* Sync framing */ + +/* -- AVP - TX Connect Speed */ +#define PPPOL2TP_AVPTYPE_TXCONNECTSPEED 24 /* TX Connect Speed */ +#define PPPOL2TP_TXCONNECTSPEED 100000000 /* Connect speed: 100 Mbits/s */ + +/* L2TP Session state */ +#define PPPOL2TP_STATE_INITIAL 0 +#define PPPOL2TP_STATE_SCCRQ_SENT 1 +#define PPPOL2TP_STATE_ICRQ_SENT 2 +#define PPPOL2TP_STATE_ICCN_SENT 3 +#define PPPOL2TP_STATE_DATA 4 +#define PPPOL2TP_STATE_CLOSING 5 + +#define PPPOL2TP_CB_STATE_UP 0 /* PPPoL2TP link is UP */ +#define PPPOL2TP_CB_STATE_DOWN 1 /* PPPo2TP link is DOWN - normal condition */ +#define PPPOL2TP_CB_STATE_FAILED 2 /* Failed to setup PPPo2TP link */ + +#define PPPOL2TP_OUTPUT_DATA_HEADER_LEN 6 /* Our data header len */ + +/* + * PPPoL2TP interface control block. + */ +typedef struct pppol2tp_pcb_s pppol2tp_pcb; +struct pppol2tp_pcb_s { + ppp_pcb *ppp; /* PPP PCB */ + u8_t phase; /* L2TP phase */ + void (*link_status_cb)(ppp_pcb *pcb, int status); + struct udp_pcb *udp; /* UDP L2TP Socket */ + ip_addr_t remote_ip; /* LNS IP Address */ + u16_t remote_port; /* LNS port */ +#if PPPOL2TP_AUTH_SUPPORT + u8_t *secret; /* Secret string */ + u8_t secret_len; /* Secret string length */ + u8_t secret_rv[16]; /* Random vector */ + u8_t challenge_hash[16]; /* Challenge response */ + u8_t send_challenge; /* Boolean whether the next sent packet should contains a challenge response */ +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + u16_t tunnel_port; /* Tunnel port */ + u16_t our_ns; /* NS to peer */ + u16_t peer_nr; /* NR from peer */ + u16_t peer_ns; /* NS from peer */ + u16_t source_tunnel_id; /* Tunnel ID assigned by peer */ + u16_t remote_tunnel_id; /* Tunnel ID assigned to peer */ + u16_t source_session_id; /* Session ID assigned by peer */ + u16_t remote_session_id; /* Session ID assigned to peer */ + + u8_t sccrq_retried; /* number of SCCRQ retries already done */ + u8_t icrq_retried; /* number of ICRQ retries already done */ + u8_t iccn_retried; /* number of ICCN retries already done */ +}; + + +/* Create a new L2TP session. */ +err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int status), + pppol2tp_pcb **l2tpptr, u8_t *secret, u8_t secret_len); + +/* Destroy a L2TP control block */ +err_t pppol2tp_destroy(pppol2tp_pcb *l2tp); + +/* Be a LAC, connect to a LNS. */ +err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port); + +/* Disconnect */ +void pppol2tp_disconnect(pppol2tp_pcb *l2tp); + +/* Reconnect to a LNS, using previously set L2TP server IP address and port. */ +err_t pppol2tp_reconnect(pppol2tp_pcb *l2tp); + +/* Data packet from PPP to L2TP */ +err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb); + +#endif /* PPPOL2TP_H_ */ +#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 12b76a44..69ebaf07 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -124,6 +124,9 @@ #if PPPOE_SUPPORT #include "netif/ppp_oe.h" #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +#include "netif/pppol2tp.h" +#endif /* PPPOL2TP_SUPPORT */ /* Global variables */ @@ -219,6 +222,12 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_shor static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p); #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short protocol); +/* function called by ppp_write() */ +static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p); +#endif /* PPPOL2TP_SUPPORT */ + static void ppp_destroy(ppp_pcb *pcb); /***********************************/ @@ -415,6 +424,44 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic } #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state); + +int ppp_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, + ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { + + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + if (link_status_cb == NULL) + return PPPERR_PARAM; + + pcb->link_status_cb = link_status_cb; + pcb->link_status_ctx = link_status_ctx; + + wo->mru = 1500; /* FIXME: MTU depends we support IP fragmentation or not */ + wo->neg_asyncmap = 0; + wo->neg_pcompression = 0; + wo->neg_accompression = 0; + + ao->mru = 1500; /* FIXME: MTU depends we support IP fragmentation or not */ + ao->neg_asyncmap = 0; + ao->neg_pcompression = 0; + ao->neg_accompression = 0; + + if(pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, secret, secret_len) != ERR_OK) { + return PPPERR_OPEN; + } + + new_phase(pcb, PHASE_INITIALIZE); + if(!pppol2tp_connect(pcb->l2tp_pcb, ipaddr, port) != ERR_OK) { + return PPPERR_OPEN; + } + return PPPERR_NONE; +} +#endif /* PPPOL2TP_SUPPORT */ /* Close a PPP connection and release the descriptor. * Any outstanding packets in the queues are dropped. @@ -983,6 +1030,12 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot } #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + if(pcb->l2tp_pcb) { + return ppp_netif_output_over_l2tp(pcb, pb, protocol); + } +#endif /* PPPOL2TP_SUPPORT */ + #if PPPOS_SUPPORT /* Grab an output buffer. */ head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); @@ -1133,6 +1186,47 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_shor #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short protocol) { + struct pbuf *pb; + int i=0; + u16_t tot_len; + + /* @todo: try to use pbuf_header() here! */ + pb = pbuf_alloc(PBUF_TRANSPORT, PPPOL2TP_OUTPUT_DATA_HEADER_LEN + sizeof(protocol), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pcb->netif); + return ERR_MEM; + } + + pbuf_header(pb, -(s16_t)PPPOL2TP_OUTPUT_DATA_HEADER_LEN); + + pcb->last_xmit = sys_jiffies(); + + if (!pcb->pcomp || protocol > 0xFF) { + *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; + } + *((u_char*)pb->payload + i) = protocol & 0xFF; + + pbuf_chain(pb, p); + tot_len = pb->tot_len; + + if(pppol2tp_xmit(pcb->l2tp_pcb, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pcb->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pcb->netif, tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); + LINK_STATS_INC(link.xmit); + return ERR_OK; +} +#endif /* PPPOL2TP_SUPPORT */ + + /* Get and set parameters for the given connection. * Return 0 on success, an error code on failure. */ int @@ -1214,6 +1308,12 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { } #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + if(pcb->l2tp_pcb) { + return ppp_write_over_l2tp(pcb, p); + } +#endif /* PPPOL2TP_SUPPORT */ + #if PPPOS_SUPPORT head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (head == NULL) { @@ -1311,6 +1411,38 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { } #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p) { + struct pbuf *ph; /* UDP + L2TP header */ + u16_t tot_len; + + ph = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(PPPOL2TP_OUTPUT_DATA_HEADER_LEN), PBUF_RAM); + if(!ph) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); + return PPPERR_ALLOC; + } + + pbuf_header(ph, -(s16_t)PPPOL2TP_OUTPUT_DATA_HEADER_LEN); /* hide L2TP header */ + pbuf_cat(ph, p); + tot_len = ph->tot_len; + + pcb->last_xmit = sys_jiffies(); + + if(pppol2tp_xmit(pcb->l2tp_pcb, ph) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pcb->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pcb->netif, (u16_t)tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); + LINK_STATS_INC(link.xmit); + return PPPERR_NONE; +} +#endif /* PPPOL2TP_SUPPORT */ #if PPPOS_SUPPORT /* @@ -1689,6 +1821,49 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { } #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { + int pppol2tp_err_code = PPPERR_NONE; + + switch(state) { + + /* PPPoL2TP link is established, starting PPP negotiation */ + case PPPOL2TP_CB_STATE_UP: + PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: UP, connecting\n", pcb->num)); + ppp_start(pcb); + return; + + /* PPPoL2TP link normally down (i.e. asked to do so) */ + case PPPOL2TP_CB_STATE_DOWN: + PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: DOWN, disconnected\n", pcb->num)); + pppol2tp_err_code = PPPERR_CONNECT; + break; + + /* PPPoL2TP link failed to setup (i.e. L2TP timeout) */ + case PPPOL2TP_CB_STATE_FAILED: + PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: FAILED, aborting\n", pcb->num)); + pppol2tp_err_code = PPPERR_OPEN; + break; + } + + /* Reconnect if persist mode is enabled */ + if(pcb->settings.persist) { + if(pcb->link_status_cb) + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); + new_phase(pcb, PHASE_INITIALIZE); + pppol2tp_reconnect(pcb->l2tp_pcb); + return; + } + + ppp_hup(pcb); + ppp_stop(pcb); + pppol2tp_destroy(pcb->l2tp_pcb); + if(pcb->link_status_cb) + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); + ppp_destroy(pcb); +} +#endif /* PPPOL2TP_SUPPORT */ + void ppp_link_down(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pcb->num)); @@ -1705,6 +1880,11 @@ void ppp_link_terminated(ppp_pcb *pcb) { pppoe_disconnect(pcb->pppoe_sc); } else #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + pppol2tp_disconnect(pcb->l2tp_pcb); + } else +#endif /* PPPOL2TP_SUPPORT */ { #if PPPOS_SUPPORT #if PPP_INPROC_OWNTHREAD diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 359f253b..375a4c5f 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -144,6 +144,13 @@ typedef struct ppp_pcb_s ppp_pcb; #include "eap.h" #endif /* EAP_SUPPORT */ +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +#include "netif/pppol2tp.h" +#endif /* PPPOL2TP_SUPPORT */ + /* * PPP configuration. */ @@ -325,6 +332,10 @@ struct ppp_pcb_s { struct pppoe_softc *pppoe_sc; #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + pppol2tp_pcb *l2tp_pcb; +#endif /* PPPOL2TP_SUPPORT */ + u8_t phase; /* where the link is at */ u8_t err_code; /* Code indicating why interface is down. */ @@ -464,6 +475,14 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +/* + * Open a new PPP Over L2TP (PPPoL2TP) connection. + */ +int ppp_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, + ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +#endif /* PPPOL2TP_SUPPORT */ + /* * Close a PPP connection and release the control block. * Any outstanding packets in the queues are dropped. diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index d73eedfe..1173db99 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -81,7 +81,6 @@ #include "lwip/stats.h" #include "ppp_impl.h" - #include "netif/ppp_oe.h" /* Add a 16 bit unsigned value to a buffer pointed to by PTR */ @@ -683,6 +682,7 @@ pppoe_send_padi(struct pppoe_softc *sc) LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); + /* FIXME: PBUF_LINK already allocate a eth_hdr */ /* allocate a buffer */ pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM); if (!pb) { diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c new file mode 100644 index 00000000..c30174e3 --- /dev/null +++ b/src/netif/ppp/pppol2tp.c @@ -0,0 +1,990 @@ +/** + * @file + * Network Point to Point Protocol over Layer 2 Tunneling Protocol program file. + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. 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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +/* + * L2TP Support status: + * + * Supported: + * - L2TPv2 (PPP over L2TP, a.k.a. UDP tunnels) + * - LAC + * + * Not supported: + * - LNS (require PPP server support) + * - L2TPv3 ethernet pseudowires + * - L2TPv3 VLAN pseudowire + * - L2TPv3 PPP pseudowires + * - L2TPv3 IP encapsulation + * - L2TPv3 IP pseudowire + * - L2TP tunnel switching - http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08 + * - Multiple tunnels per UDP socket, as well as multiple sessions per tunnel + * - Hidden AVPs + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/err.h" +#include "lwip/memp.h" +#include "lwip/udp.h" + +#include "ppp_impl.h" +#include "netif/pppol2tp.h" + +#include "magic.h" + +#if PPPOL2TP_AUTH_SUPPORT +#if LWIP_INCLUDED_POLARSSL_MD5 +#include "polarssl/lwip_md5.h" +#else +#include "polarssl/md5.h" +#endif +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + /* Prototypes for procedures local to this file. */ +static void pppol2tp_do_disconnect(pppol2tp_pcb *l2tp); +static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); +static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port, + struct pbuf *p, u16_t len, u16_t tunnel_id, u16_t session_id, u16_t ns, u16_t nr); +static void pppol2tp_timeout(void *arg); +static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp); +static void pppol2tp_clear(pppol2tp_pcb *l2tp); +static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp); +static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns); +static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns); +static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns); +static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns); +static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns); + + +/* Create a new L2TP session. */ +err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int status), + pppol2tp_pcb **l2tpptr, u8_t *secret, u8_t secret_len) { + pppol2tp_pcb *l2tp; + struct udp_pcb *udp; + + l2tp = (pppol2tp_pcb *)memp_malloc(MEMP_PPPOL2TP_PCB); + if (l2tp == NULL) { + *l2tpptr = NULL; + return ERR_MEM; + } + + udp = udp_new(); + if (udp == NULL) { + memp_free(MEMP_PPPOL2TP_PCB, l2tp); + *l2tpptr = NULL; + return ERR_MEM; + } + + memset(l2tp, 0, sizeof(pppol2tp_pcb)); + l2tp->phase = PPPOL2TP_STATE_INITIAL; + l2tp->ppp = ppp; + l2tp->udp = udp; + l2tp->link_status_cb = link_status_cb; +#if PPPOL2TP_AUTH_SUPPORT + l2tp->secret = secret; + l2tp->secret_len = secret_len; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + *l2tpptr = l2tp; + return ERR_OK; +} + +/* Destroy a L2TP control block */ +err_t pppol2tp_destroy(pppol2tp_pcb *l2tp) { + + sys_untimeout(pppol2tp_timeout, l2tp); + if (l2tp->udp != NULL) { + udp_remove(l2tp->udp); + } + memp_free(MEMP_PPPOL2TP_PCB, l2tp); + return ERR_OK; +} + +/* Be a LAC, connect to a LNS. */ +err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port) { + err_t err; + + if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { + return ERR_VAL; + } + + ip_addr_set(&l2tp->remote_ip, ipaddr); + l2tp->remote_port = l2tp->tunnel_port = port; + + /* Listen to a random source port, we need to do that instead of using udp_connect() + * because the L2TP LNS might answer with its own random source port (!= 1701) + */ + udp_bind(l2tp->udp, IP_ADDR_ANY, 0); + udp_recv(l2tp->udp, pppol2tp_input, l2tp); + +#if PPPOL2TP_AUTH_SUPPORT + /* Generate random vector */ + if (l2tp->secret != NULL) { + random_bytes(l2tp->secret_rv, sizeof(l2tp->secret_rv)); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + do { + l2tp->remote_tunnel_id = magic(); + } while(l2tp->remote_tunnel_id == 0); + /* save state, in case we fail to send SCCRQ */ + l2tp->sccrq_retried = 0; + l2tp->phase = PPPOL2TP_STATE_SCCRQ_SENT; + if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); + } + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + return err; +} + +/* Reconnect to a LNS, using previously set L2TP server IP address and port. */ +err_t pppol2tp_reconnect(pppol2tp_pcb *l2tp) { + err_t err; + + if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { + return ERR_VAL; + } + + pppol2tp_clear(l2tp); + + do { + l2tp->remote_tunnel_id = magic(); + } while(l2tp->remote_tunnel_id == 0); + /* save state, in case we fail to send SCCRQ */ + l2tp->sccrq_retried = 0; + l2tp->phase = PPPOL2TP_STATE_SCCRQ_SENT; + if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); + } + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + return err; +} + +/* Disconnect */ +void pppol2tp_disconnect(pppol2tp_pcb *l2tp) { + + if (l2tp->phase == PPPOL2TP_STATE_CLOSING) { + return; + } + + l2tp->our_ns++; + pppol2tp_send_stopccn(l2tp, l2tp->our_ns); + /* + * Do not call pppol2tp_disconnect here, the upper layer state + * machine gets confused by this. We must return from this + * function and defer disconnecting to the timeout handler. + */ + l2tp->phase = PPPOL2TP_STATE_CLOSING; + sys_timeout(20, pppol2tp_timeout, l2tp); +} + +static void pppol2tp_do_disconnect(pppol2tp_pcb *l2tp) { + + pppol2tp_clear(l2tp); + l2tp->link_status_cb(l2tp->ppp, PPPOL2TP_CB_STATE_DOWN); /* notify upper layers */ +} + +/* UDP Callback for incoming L2TP frames */ +static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { + pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg; + u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0; + u8_t *inp; + + printf("-----------\nL2TP INPUT, %d\n", p->len); + p = ppp_singlebuf(p); + + /* L2TP header */ + if (p->len < sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id) ) { + goto packet_too_short; + } + + inp = p->payload; + GETSHORT(hflags, inp); + + if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { + /* check mandatory flags for a control packet */ + if ( (hflags & PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY) != PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for control packet not set\n")); + goto free_and_return; + } + /* check forbidden flags for a control packet */ + if (hflags & PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: forbidden header flags for control packet found\n")); + goto free_and_return; + } + } else { + /* check mandatory flags for a data packet */ + if ( (hflags & PPPOL2TP_HEADERFLAG_DATA_MANDATORY) != PPPOL2TP_HEADERFLAG_DATA_MANDATORY) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for data packet not set\n")); + goto free_and_return; + } + } + + /* Expected header size */ + hlen = sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id); + if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) { + hlen += sizeof(len); + } + if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) { + hlen += sizeof(ns) + sizeof(nr); + } + if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) { + hlen += sizeof(offset); + } + if (p->len < hlen) { + goto packet_too_short; + } + + if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) { + GETSHORT(len, inp); + if (p->len < len || len < hlen) { + goto packet_too_short; + } + } + GETSHORT(tunnel_id, inp); + GETSHORT(session_id, inp); + if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) { + GETSHORT(ns, inp); + GETSHORT(nr, inp); + } + if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) { + GETSHORT(offset, inp) + if (offset > 4096) { /* don't be fooled with large offset which might overflow hlen */ + PPPDEBUG(LOG_DEBUG, ("pppol2tp: strange packet received, offset=%d\n", offset)); + goto free_and_return; + } + hlen += offset; + if (p->len < hlen) { + goto packet_too_short; + } + INCPTR(offset, inp); + } + + printf("HLEN = %d\n", hlen); + + /* skip L2TP header */ + if (pbuf_header(p, -hlen) != 0) { + goto free_and_return; + } + + printf("LEN=%d, TUNNEL_ID=%d, SESSION_ID=%d, NS=%d, NR=%d, OFFSET=%d\n", len, tunnel_id, session_id, ns, nr, offset); + + /* Control packet */ + if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { + pppol2tp_dispatch_control_packet(l2tp, addr, port, p, len, tunnel_id, session_id, ns, nr); + goto free_and_return; + } + + /* Data packet */ + if(l2tp->phase != PPPOL2TP_STATE_DATA) { + goto free_and_return; + } + if(tunnel_id != l2tp->remote_tunnel_id) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: tunnel ID mismatch, assigned=%d, received=%d\n", l2tp->remote_tunnel_id, tunnel_id)); + goto free_and_return; + } + if(session_id != l2tp->remote_session_id) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: session ID mismatch, assigned=%d, received=%d\n", l2tp->remote_session_id, session_id)); + goto free_and_return; + } + /* skip address & flags */ + pbuf_header(p, -(s16_t)2); + /* Dispatch the packet thereby consuming it. */ + ppp_input(l2tp->ppp, p); + return; + +packet_too_short: + PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len)); +free_and_return: + pbuf_free(p); +} + +/* L2TP Control packet entry point */ +static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port, + struct pbuf *p, u16_t len, u16_t tunnel_id, u16_t session_id, u16_t ns, u16_t nr) { + u8_t *inp; + u16_t avplen, avpflags, vendorid, attributetype, messagetype=0; + err_t err; +#if PPPOL2TP_AUTH_SUPPORT + md5_context md5_context; + u8_t md5_hash[16]; + u8_t challenge_id = 0; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + l2tp->peer_nr = nr; + l2tp->peer_ns = ns; + printf("L2TP CTRL INPUT, ns=%d, nr=%d, len=%d\n", ns, nr, p->len); + + /* Handle the special case of the ICCN acknowledge */ + if (l2tp->phase == PPPOL2TP_STATE_ICCN_SENT && l2tp->peer_nr > l2tp->our_ns) { + l2tp->phase = PPPOL2TP_STATE_DATA; + } + + /* ZLB packets */ + if (p->len == 0) { + return; + } + + inp = p->payload; + /* Decode AVPs */ + while (p->len > 0) { + if (p->len < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype) ) { + goto packet_too_short; + } + GETSHORT(avpflags, inp); + avplen = avpflags & PPPOL2TP_AVPHEADERFLAG_LENGTHMASK; + printf("AVPLEN = %d\n", avplen); + if (p->len < avplen || avplen < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) { + goto packet_too_short; + } + GETSHORT(vendorid, inp); + GETSHORT(attributetype, inp); + avplen -= sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype); + + /* Message type must be the first AVP */ + if (messagetype == 0) { + if (attributetype != 0 || vendorid != 0 || avplen != sizeof(messagetype) ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: message type must be the first AVP\n")); + return; + } + GETSHORT(messagetype, inp); + printf("Message type = %d\n", messagetype); + switch(messagetype) { + /* Start Control Connection Reply */ + case PPPOL2TP_MESSAGETYPE_SCCRP: + /* Only accept SCCRP packet if we sent a SCCRQ */ + if (l2tp->phase != PPPOL2TP_STATE_SCCRQ_SENT) { + goto send_zlb; + } + break; + /* Incoming Call Reply */ + case PPPOL2TP_MESSAGETYPE_ICRP: + /* Only accept ICRP packet if we sent a IRCQ */ + if (l2tp->phase != PPPOL2TP_STATE_ICRQ_SENT) { + goto send_zlb; + } + break; + /* Stop Control Connection Notification */ + case PPPOL2TP_MESSAGETYPE_STOPCCN: + if (l2tp->phase < PPPOL2TP_STATE_DATA) { + pppol2tp_abort_connect(l2tp); + } else if (l2tp->phase == PPPOL2TP_STATE_DATA) { + pppol2tp_disconnect(l2tp); + } + return; + } + goto nextavp; + } + + /* Skip proprietary L2TP extensions */ + if (vendorid != 0) { + goto skipavp; + } + + switch (messagetype) { + /* Start Control Connection Reply */ + case PPPOL2TP_MESSAGETYPE_SCCRP: + switch (attributetype) { + case PPPOL2TP_AVPTYPE_TUNNELID: + if (avplen != sizeof(l2tp->source_tunnel_id) ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign tunnel ID length check failed\n")); + return; + } + GETSHORT(l2tp->source_tunnel_id, inp); + printf("Assigned tunnel %d\n", l2tp->source_tunnel_id); + goto nextavp; +#if PPPOL2TP_AUTH_SUPPORT + case PPPOL2TP_AVPTYPE_CHALLENGE: + if (avplen == 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Challenge length check failed\n")); + return; + } + if (l2tp->secret == NULL) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge from peer and no secret key available\n")); + pppol2tp_abort_connect(l2tp); + return; + } + /* Generate hash of ID, secret, challenge */ + md5_starts(&md5_context); + challenge_id = PPPOL2TP_MESSAGETYPE_SCCCN; + md5_update(&md5_context, &challenge_id, 1); + md5_update(&md5_context, l2tp->secret, l2tp->secret_len); + md5_update(&md5_context, inp, avplen); + md5_finish(&md5_context, l2tp->challenge_hash); + l2tp->send_challenge = 1; + goto skipavp; + case PPPOL2TP_AVPTYPE_CHALLENGERESPONSE: + if (avplen != PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Challenge Response length check failed\n")); + return; + } + /* Generate hash of ID, secret, challenge */ + md5_starts(&md5_context); + challenge_id = PPPOL2TP_MESSAGETYPE_SCCRP; + md5_update(&md5_context, &challenge_id, 1); + md5_update(&md5_context, l2tp->secret, l2tp->secret_len); + md5_update(&md5_context, l2tp->secret_rv, sizeof(l2tp->secret_rv)); + md5_finish(&md5_context, md5_hash); + if ( memcmp(inp, md5_hash, sizeof(md5_hash)) ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge response from peer and secret key do not match\n")); + pppol2tp_abort_connect(l2tp); + return; + } + goto skipavp; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + } + break; + /* Incoming Call Reply */ + case PPPOL2TP_MESSAGETYPE_ICRP: + switch (attributetype) { + case PPPOL2TP_AVPTYPE_SESSIONID: + if (avplen != sizeof(l2tp->source_session_id) ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign session ID length check failed\n")); + return; + } + GETSHORT(l2tp->source_session_id, inp); + printf("Assigned session %d\n", l2tp->source_session_id); + goto nextavp; + } + break; + } + +skipavp: + INCPTR(avplen, inp); +nextavp: + printf("AVP Found, vendor=%d, attribute=%d, len=%d\n", vendorid, attributetype, avplen); + /* next AVP */ + if (pbuf_header(p, -avplen - sizeof(avpflags) - sizeof(vendorid) - sizeof(attributetype) ) != 0) { + return; + } + } + + switch(messagetype) { + /* Start Control Connection Reply */ + case PPPOL2TP_MESSAGETYPE_SCCRP: + do { + l2tp->remote_session_id = magic(); + } while(l2tp->remote_session_id == 0); + l2tp->tunnel_port = port; /* LNS server might have chosen its own local port */ + l2tp->icrq_retried = 0; + l2tp->phase = PPPOL2TP_STATE_ICRQ_SENT; + l2tp->our_ns++; + if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err)); + } + l2tp->our_ns++; + if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err)); + } + sys_untimeout(pppol2tp_timeout, l2tp); + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + /* Incoming Call Reply */ + case PPPOL2TP_MESSAGETYPE_ICRP: + l2tp->iccn_retried = 0; + l2tp->phase = PPPOL2TP_STATE_ICCN_SENT; + l2tp->our_ns++; + l2tp->link_status_cb(l2tp->ppp, PPPOL2TP_CB_STATE_UP); /* notify upper layers */ + if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err)); + } + sys_untimeout(pppol2tp_timeout, l2tp); + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + /* Unhandled packet, send ZLB ACK */ + default: + goto send_zlb; + } + return; + +send_zlb: + pppol2tp_send_zlb(l2tp, l2tp->our_ns); + return; +packet_too_short: + PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len)); +} + +/* L2TP Timeout handler */ +static void pppol2tp_timeout(void *arg) { + pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg; + err_t err; + u32_t retry_wait; + + PPPDEBUG(LOG_DEBUG, ("pppol2tp: timeout\n")); + + switch (l2tp->phase) { + case PPPOL2TP_STATE_SCCRQ_SENT: + /* backoff wait */ + if (l2tp->sccrq_retried < UCHAR_MAX) { + l2tp->sccrq_retried++; + } + if (!l2tp->ppp->settings.persist && l2tp->sccrq_retried >= PPPOL2TP_MAXSCCRQ) { + pppol2tp_abort_connect(l2tp); + return; + } + retry_wait = LWIP_MIN(PPPOL2TP_CONTROL_TIMEOUT * l2tp->sccrq_retried, PPPOL2TP_SLOW_RETRY); + PPPDEBUG(LOG_DEBUG, ("pppol2tp: sccrq_retried=%d\n", l2tp->sccrq_retried)); + if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { + l2tp->sccrq_retried--; + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); + } + sys_timeout(retry_wait, pppol2tp_timeout, l2tp); + break; + + case PPPOL2TP_STATE_ICRQ_SENT: + l2tp->icrq_retried++; + if (l2tp->icrq_retried >= PPPOL2TP_MAXICRQ) { + pppol2tp_abort_connect(l2tp); + return; + } + PPPDEBUG(LOG_DEBUG, ("pppol2tp: icrq_retried=%d\n", l2tp->icrq_retried)); + if (l2tp->peer_nr <= l2tp->our_ns -1) { /* the SCCCN was not acknowledged */ + if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns -1)) != 0) { + l2tp->icrq_retried--; + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err)); + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + } + } + if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) { + l2tp->icrq_retried--; + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err)); + } + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + + case PPPOL2TP_STATE_ICCN_SENT: + l2tp->iccn_retried++; + if (l2tp->iccn_retried >= PPPOL2TP_MAXICCN) { + pppol2tp_abort_connect(l2tp); + return; + } + PPPDEBUG(LOG_DEBUG, ("pppol2tp: iccn_retried=%d\n", l2tp->iccn_retried)); + if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) { + l2tp->iccn_retried--; + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err)); + } + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + + case PPPOL2TP_STATE_CLOSING: + pppol2tp_do_disconnect(l2tp); + break; + + default: + return; /* all done, work in peace */ + } +} + +/* Connection attempt aborted */ +static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: could not establish connection\n")); + pppol2tp_clear(l2tp); + l2tp->link_status_cb(l2tp->ppp, PPPOL2TP_CB_STATE_FAILED); /* notify upper layers */ +} + +/* Reset L2TP control block to its initial state */ +static void pppol2tp_clear(pppol2tp_pcb *l2tp) { + /* stop any timer */ + sys_untimeout(pppol2tp_timeout, l2tp); + l2tp->phase = PPPOL2TP_STATE_INITIAL; + l2tp->tunnel_port = l2tp->remote_port; + l2tp->our_ns = 0; + l2tp->peer_nr = 0; + l2tp->peer_ns = 0; + l2tp->source_tunnel_id = 0; + l2tp->remote_tunnel_id = 0; + l2tp->source_session_id = 0; + l2tp->remote_session_id = 0; + /* l2tp->*_retried are cleared when used */ +} + +/* Initiate a new tunnel */ +static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12 +8 +8 +10 +10 +6+sizeof(PPPOL2TP_HOSTNAME)-1 +6+sizeof(PPPOL2TP_VENDORNAME)-1 +8 +8; +#if PPPOL2TP_AUTH_SUPPORT + if (l2tp->secret != NULL) { + len += 6 + sizeof(l2tp->secret_rv); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(0, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(0, p); /* NS Sequence number - to peer */ + PUTSHORT(0, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCRQ, p); /* Attribute value: Message type: SCCRQ */ + + /* AVP - L2TP Version */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_VERSION, p); /* Attribute type: Version */ + PUTSHORT(PPPOL2TP_VERSION, p); /* Attribute value: L2TP Version */ + + /* AVP - Framing capabilities */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES, p); /* Attribute type: Framing capabilities */ + PUTLONG(PPPOL2TP_FRAMINGCAPABILITIES, p); /* Attribute value: Framing capabilities */ + + /* AVP - Bearer capabilities */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_BEARERCAPABILITIES, p); /* Attribute type: Bearer capabilities */ + PUTLONG(PPPOL2TP_BEARERCAPABILITIES, p); /* Attribute value: Bearer capabilities */ + + /* AVP - Host name */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6+sizeof(PPPOL2TP_HOSTNAME)-1, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_HOSTNAME, p); /* Attribute type: Hostname */ + MEMCPY(p, PPPOL2TP_HOSTNAME, sizeof(PPPOL2TP_HOSTNAME)-1); /* Attribute value: Hostname */ + INCPTR(sizeof(PPPOL2TP_HOSTNAME)-1, p); + + /* AVP - Vendor name */ + PUTSHORT(6+sizeof(PPPOL2TP_VENDORNAME)-1, p); /* len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_VENDORNAME, p); /* Attribute type: Vendor name */ + MEMCPY(p, PPPOL2TP_VENDORNAME, sizeof(PPPOL2TP_VENDORNAME)-1); /* Attribute value: Vendor name */ + INCPTR(sizeof(PPPOL2TP_VENDORNAME)-1, p); + + /* AVP - Assign tunnel ID */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */ + PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */ + + /* AVP - Receive window size */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE, p); /* Attribute type: Receive window size */ + PUTSHORT(PPPOL2TP_RECEIVEWINDOWSIZE, p); /* Attribute value: Receive window size */ + +#if PPPOL2TP_AUTH_SUPPORT + /* AVP - Challenge */ + if (l2tp->secret != NULL) { + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->secret_rv), p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGE, p); /* Attribute type: Challenge */ + MEMCPY(p, l2tp->secret_rv, sizeof(l2tp->secret_rv)); /* Attribute value: Random vector */ + INCPTR(sizeof(l2tp->secret_rv), p); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + pbuf_free(pb); + return ERR_OK; +} + +/* Complete tunnel establishment */ +static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12 +8; +#if PPPOL2TP_AUTH_SUPPORT + if (l2tp->send_challenge) { + len += 6 + sizeof(l2tp->challenge_hash); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCCN, p); /* Attribute value: Message type: SCCCN */ + +#if PPPOL2TP_AUTH_SUPPORT + /* AVP - Challenge response */ + if (l2tp->send_challenge) { + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->challenge_hash), p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGERESPONSE, p); /* Attribute type: Challenge response */ + MEMCPY(p, l2tp->challenge_hash, sizeof(l2tp->challenge_hash)); /* Attribute value: Computed challenge */ + INCPTR(sizeof(l2tp->challenge_hash), p); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + pbuf_free(pb); + return ERR_OK; +} + +/* Initiate a new session */ +static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + u32_t serialnumber; + + /* calculate UDP packet length */ + len = 12 +8 +8 +10; + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_ICRQ, p); /* Attribute value: Message type: ICRQ */ + + /* AVP - Assign session ID */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_SESSIONID, p); /* Attribute type: Session ID */ + PUTSHORT(l2tp->remote_session_id, p); /* Attribute value: Session ID */ + + /* AVP - Call Serial Number */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_CALLSERIALNUMBER, p); /* Attribute type: Serial number */ + serialnumber = magic(); + PUTLONG(serialnumber, p); /* Attribute value: Serial number */ + + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + pbuf_free(pb); + return ERR_OK; +} + +/* Complete tunnel establishment */ +static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12 +8 +10 +10; + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(l2tp->source_session_id, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_ICCN, p); /* Attribute value: Message type: ICCN */ + + /* AVP - Framing type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGTYPE, p); /* Attribute type: Framing type */ + PUTLONG(PPPOL2TP_FRAMINGTYPE, p); /* Attribute value: Framing type */ + + /* AVP - TX Connect speed */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_TXCONNECTSPEED, p); /* Attribute type: TX Connect speed */ + PUTLONG(PPPOL2TP_TXCONNECTSPEED, p); /* Attribute value: TX Connect speed */ + + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + pbuf_free(pb); + return ERR_OK; +} + +/* Send a ZLB ACK packet */ +static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12; + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + pbuf_free(pb); + return ERR_OK; +} + +/* Send a StopCCN packet */ +static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12 +8 +8 +8; + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_STOPCCN, p); /* Attribute value: Message type: StopCCN */ + + /* AVP - Assign tunnel ID */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */ + PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */ + + /* AVP - Result code */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_RESULTCODE, p); /* Attribute type: Result code */ + PUTSHORT(PPPOL2TP_RESULTCODE, p); /* Attribute value: Result code */ + + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + pbuf_free(pb); + return ERR_OK; +} + +err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb) { + u8_t *p; + + /* are we ready to process data yet? */ + if (l2tp->phase < PPPOL2TP_STATE_DATA) { + pbuf_free(pb); + return ERR_CONN; + } + + /* make room for L2TP header - should not fail */ + if (pbuf_header(pb, PPPOL2TP_OUTPUT_DATA_HEADER_LEN) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppol2tp: pppol2tp_pcb: could not allocate room for L2TP header\n")); + LINK_STATS_INC(link.lenerr); + pbuf_free(pb); + return ERR_BUF; + } + + p = pb->payload; + PUTSHORT(PPPOL2TP_HEADERFLAG_DATA_MANDATORY, p); + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(l2tp->source_session_id, p); /* Session Id */ + + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + pbuf_free(pb); + return ERR_OK; +} + +#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ From de6be743c6ae01d34c704e355bafba0432e4e3c3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 11 Jul 2012 23:50:33 +0200 Subject: [PATCH 240/320] added holdoff support for PPPoE and PPPoL2TP when persist mode is used --- src/include/netif/ppp_oe.h | 10 ++++++---- src/include/netif/pppol2tp.h | 13 +++++++------ src/netif/ppp/ppp.c | 3 ++- src/netif/ppp/ppp.h | 2 ++ src/netif/ppp/ppp_oe.c | 21 +++++++++++++++++++++ src/netif/ppp/pppol2tp.c | 30 ++++++++++++++++++++++++++---- 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index ac5deff8..c3021a14 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -106,10 +106,11 @@ PACK_STRUCT_END #define PPPOE_STATE_INITIAL 0 -#define PPPOE_STATE_PADI_SENT 1 -#define PPPOE_STATE_PADR_SENT 2 -#define PPPOE_STATE_SESSION 3 -#define PPPOE_STATE_CLOSING 4 +#define PPPOE_STATE_HOLDOFF 1 +#define PPPOE_STATE_PADI_SENT 2 +#define PPPOE_STATE_PADR_SENT 3 +#define PPPOE_STATE_SESSION 4 +#define PPPOE_STATE_CLOSING 5 /* passive */ #define PPPOE_STATE_PADO_SENT 1 @@ -172,6 +173,7 @@ err_t pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp err_t pppoe_destroy(struct netif *ifp); int pppoe_connect(struct pppoe_softc *sc); +void pppoe_reconnect(struct pppoe_softc *sc); void pppoe_disconnect(struct pppoe_softc *sc); void pppoe_disc_input(struct netif *netif, struct pbuf *p); diff --git a/src/include/netif/pppol2tp.h b/src/include/netif/pppol2tp.h index e417a07e..3dded088 100644 --- a/src/include/netif/pppol2tp.h +++ b/src/include/netif/pppol2tp.h @@ -150,11 +150,12 @@ /* L2TP Session state */ #define PPPOL2TP_STATE_INITIAL 0 -#define PPPOL2TP_STATE_SCCRQ_SENT 1 -#define PPPOL2TP_STATE_ICRQ_SENT 2 -#define PPPOL2TP_STATE_ICCN_SENT 3 -#define PPPOL2TP_STATE_DATA 4 -#define PPPOL2TP_STATE_CLOSING 5 +#define PPPOL2TP_STATE_HOLDOFF 1 +#define PPPOL2TP_STATE_SCCRQ_SENT 2 +#define PPPOL2TP_STATE_ICRQ_SENT 3 +#define PPPOL2TP_STATE_ICCN_SENT 4 +#define PPPOL2TP_STATE_DATA 5 +#define PPPOL2TP_STATE_CLOSING 6 #define PPPOL2TP_CB_STATE_UP 0 /* PPPoL2TP link is UP */ #define PPPOL2TP_CB_STATE_DOWN 1 /* PPPo2TP link is DOWN - normal condition */ @@ -210,7 +211,7 @@ err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port); void pppol2tp_disconnect(pppol2tp_pcb *l2tp); /* Reconnect to a LNS, using previously set L2TP server IP address and port. */ -err_t pppol2tp_reconnect(pppol2tp_pcb *l2tp); +void pppol2tp_reconnect(pppol2tp_pcb *l2tp); /* Data packet from PPP to L2TP */ err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 69ebaf07..af2cadd2 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -270,6 +270,7 @@ ppp_pcb *ppp_new(void) { /* default configuration */ pcb->settings.usepeerdns = 1; pcb->settings.persist = 1; + pcb->settings.holdoff = 30; #if CHAP_SUPPORT pcb->settings.chap_timeout_time = 3; pcb->settings.chap_max_transmits = 10; @@ -1808,7 +1809,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { if(pcb->link_status_cb) pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); new_phase(pcb, PHASE_INITIALIZE); - pppoe_connect(pcb->pppoe_sc); + pppoe_reconnect(pcb->pppoe_sc); return; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 375a4c5f..bc7422df 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -206,6 +206,8 @@ typedef struct ppp_settings_s { u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ + u16_t holdoff; /* time to wait (s) before re-initiating the link after it terminates */ + #if PPP_IDLETIMELIMIT u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ #endif /* PPP_IDLETIMELIMIT */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 1173db99..5a274b72 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -788,6 +788,10 @@ pppoe_timeout(void *arg) case PPPOE_STATE_CLOSING: pppoe_do_disconnect(sc); break; + case PPPOE_STATE_HOLDOFF: + sc->sc_state = PPPOE_STATE_INITIAL; + pppoe_connect(sc); + break; default: return; /* all done, work in peace */ } @@ -823,6 +827,23 @@ pppoe_connect(struct pppoe_softc *sc) return err; } +/* Start a reconnection */ +void pppoe_reconnect(struct pppoe_softc *sc) { + + if (sc->sc_state != PPPOE_STATE_INITIAL) { + return; + } + + if (sc->pcb->settings.holdoff == 0) { + pppoe_connect(sc); + return; + } + + sc->sc_state = PPPOE_STATE_HOLDOFF; + sys_timeout((u32_t)sc->pcb->settings.holdoff*1000, pppoe_timeout, sc); + return; +} + /* disconnect */ void pppoe_disconnect(struct pppoe_softc *sc) diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index c30174e3..f6940875 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -71,6 +71,7 @@ #endif /* PPPOL2TP_AUTH_SUPPORT */ /* Prototypes for procedures local to this file. */ +static void pppol2tp_do_reconnect(pppol2tp_pcb *l2tp); static void pppol2tp_do_disconnect(pppol2tp_pcb *l2tp); static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port, @@ -168,15 +169,27 @@ err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port) { } /* Reconnect to a LNS, using previously set L2TP server IP address and port. */ -err_t pppol2tp_reconnect(pppol2tp_pcb *l2tp) { - err_t err; +void pppol2tp_reconnect(pppol2tp_pcb *l2tp) { if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { - return ERR_VAL; + return; } pppol2tp_clear(l2tp); + if (l2tp->ppp->settings.holdoff == 0) { + pppol2tp_do_reconnect(l2tp); + return; + } + + l2tp->phase = PPPOL2TP_STATE_HOLDOFF; + sys_timeout((u32_t)l2tp->ppp->settings.holdoff*1000, pppol2tp_timeout, l2tp); + return; +} + +static void pppol2tp_do_reconnect(pppol2tp_pcb *l2tp) { + err_t err; + do { l2tp->remote_tunnel_id = magic(); } while(l2tp->remote_tunnel_id == 0); @@ -187,7 +200,7 @@ err_t pppol2tp_reconnect(pppol2tp_pcb *l2tp) { PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); } sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - return err; + return; } /* Disconnect */ @@ -220,6 +233,10 @@ static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struc u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0; u8_t *inp; + if (l2tp->phase < PPPOL2TP_STATE_SCCRQ_SENT) { + goto free_and_return; + } + printf("-----------\nL2TP INPUT, %d\n", p->len); p = ppp_singlebuf(p); @@ -396,6 +413,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr break; /* Stop Control Connection Notification */ case PPPOL2TP_MESSAGETYPE_STOPCCN: + pppol2tp_send_zlb(l2tp, l2tp->our_ns); /* Ack the StopCCN before we switch to down state */ if (l2tp->phase < PPPOL2TP_STATE_DATA) { pppol2tp_abort_connect(l2tp); } else if (l2tp->phase == PPPOL2TP_STATE_DATA) { @@ -601,6 +619,10 @@ static void pppol2tp_timeout(void *arg) { pppol2tp_do_disconnect(l2tp); break; + case PPPOL2TP_STATE_HOLDOFF: + pppol2tp_do_reconnect(l2tp); + break; + default: return; /* all done, work in peace */ } From 78565026acc4d4b4ffcbbdde54bf877d778cd1cf Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 12 Jul 2012 01:11:08 +0200 Subject: [PATCH 241/320] L2TP output netif is now selectable, making it useful to select a default route for the L2TP tunnel, in case the default interface is set to the L2TP PPP interface --- src/api/pppapi.c | 8 ++++--- src/include/lwip/pppapi.h | 4 +++- src/include/netif/pppol2tp.h | 3 ++- src/netif/ppp/ppp.c | 31 ++++++++++++------------ src/netif/ppp/ppp.h | 5 +++- src/netif/ppp/pppol2tp.c | 46 +++++++++++++++++++++++++++++------- 6 files changed, 67 insertions(+), 30 deletions(-) diff --git a/src/api/pppapi.c b/src/api/pppapi.c index 40905362..07fc0130 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -148,8 +148,8 @@ int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *ser */ static void pppapi_do_ppp_over_l2tp_open(struct pppapi_msg_msg *msg) { - msg->err = ppp_over_l2tp_open(msg->ppp, msg->msg.l2tpopen.ipaddr, - msg->msg.l2tpopen.port, + msg->err = ppp_over_l2tp_open(msg->ppp, + msg->msg.l2tpopen.netif, msg->msg.l2tpopen.ipaddr, msg->msg.l2tpopen.port, #if PPPOL2TP_AUTH_SUPPORT msg->msg.l2tpopen.secret, msg->msg.l2tpopen.secret_len, @@ -164,11 +164,13 @@ static void pppapi_do_ppp_over_l2tp_open(struct pppapi_msg_msg *msg) { * Call ppp_over_l2tp_open() in a thread-safe way by running that function inside the * tcpip_thread context. */ -int pppapi_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, +int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { struct pppapi_msg msg; msg.function = pppapi_do_ppp_over_l2tp_open; msg.msg.ppp = pcb; + msg.msg.msg.l2tpopen.netif = netif; msg.msg.msg.l2tpopen.ipaddr = ipaddr; msg.msg.msg.l2tpopen.port = port; #if PPPOL2TP_AUTH_SUPPORT diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index 4b139ab8..6b2897a7 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -69,6 +69,7 @@ struct pppapi_msg_msg { #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT struct { + struct netif *netif; ip_addr_t *ipaddr; u16_t port; #if PPPOL2TP_AUTH_SUPPORT @@ -119,7 +120,8 @@ int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *ser void *link_status_ctx); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT -int pppapi_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, +int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ int pppapi_close(ppp_pcb *pcb); diff --git a/src/include/netif/pppol2tp.h b/src/include/netif/pppol2tp.h index 3dded088..c7741431 100644 --- a/src/include/netif/pppol2tp.h +++ b/src/include/netif/pppol2tp.h @@ -172,6 +172,7 @@ struct pppol2tp_pcb_s { u8_t phase; /* L2TP phase */ void (*link_status_cb)(ppp_pcb *pcb, int status); struct udp_pcb *udp; /* UDP L2TP Socket */ + struct netif *netif; /* Output interface, used as a default route */ ip_addr_t remote_ip; /* LNS IP Address */ u16_t remote_port; /* LNS port */ #if PPPOL2TP_AUTH_SUPPORT @@ -205,7 +206,7 @@ err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int sta err_t pppol2tp_destroy(pppol2tp_pcb *l2tp); /* Be a LAC, connect to a LNS. */ -err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port); +err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipaddr, u16_t port); /* Disconnect */ void pppol2tp_disconnect(pppol2tp_pcb *l2tp); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index af2cadd2..66cccbe7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -284,6 +284,13 @@ ppp_pcb *ppp_new(void) { for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(pcb); + if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { + memp_free(MEMP_PPP_PCB, pcb); + PPPDEBUG(LOG_ERR, ("ppp_new[%d]: netif_add failed\n", pcb->num)); + return NULL; + } + return pcb; } @@ -428,7 +435,8 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic #if PPPOL2TP_SUPPORT static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state); -int ppp_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, +int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { lcp_options *wo = &pcb->lcp_wantoptions; @@ -457,7 +465,7 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret } new_phase(pcb, PHASE_INITIALIZE); - if(!pppol2tp_connect(pcb->l2tp_pcb, ipaddr, port) != ERR_OK) { + if(!pppol2tp_connect(pcb->l2tp_pcb, netif, ipaddr, port) != ERR_OK) { return PPPERR_OPEN; } return PPPERR_NONE; @@ -874,7 +882,6 @@ static err_t ppp_netif_init_cb(struct netif *netif) { #if PPP_IPV6_SUPPORT netif->output_ip6 = ppp_netif_output_ip6; #endif /* PPP_IPV6_SUPPORT */ - netif->mtu = netif_get_mtu((ppp_pcb*)netif->state); netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; #if LWIP_NETIF_HOSTNAME /* @todo: Initialize interface hostname */ @@ -1017,7 +1024,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot } /* Check that the link is up. */ - if (pcb->phase == PHASE_DEAD) { + if (!pcb->if_up) { PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->num)); LINK_STATS_INC(link.rterr); LINK_STATS_INC(link.drop); @@ -1905,6 +1912,7 @@ void ppp_link_terminated(ppp_pcb *pcb) { static void ppp_destroy(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_destroy: unit %d\n", pcb->num)); + netif_remove(&pcb->netif); memp_free(MEMP_PPP_PCB, pcb); } @@ -2117,22 +2125,14 @@ int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { */ int sifup(ppp_pcb *pcb) { - if(!pcb->if_up) { - if(!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, - &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { - PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pcb->num)); - return 0; - } - } else { - netif_set_addr(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, - &pcb->addrs.his_ipaddr); - } - + netif_set_addr(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr); #if PPP_IPV6_SUPPORT ip6_addr_copy(pcb->netif.ip6_addr[0], pcb->addrs.our6_ipaddr); netif_ip6_addr_set_state(&pcb->netif, 0, IP6_ADDR_PREFERRED); #endif /* PPP_IPV6_SUPPORT */ + pcb->netif.mtu = netif_get_mtu(pcb); netif_set_up(&pcb->netif); pcb->if_up = 1; pcb->err_code = PPPERR_NONE; @@ -2157,7 +2157,6 @@ int sifdown(ppp_pcb *pcb) { pcb->if_up = 0; /* make sure the netif status callback is called */ netif_set_down(&pcb->netif); - netif_remove(&pcb->netif); PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); if (pcb->link_status_cb) pcb->link_status_cb(pcb, PPPERR_CONNECT, pcb->link_status_ctx); diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index bc7422df..71e2bca6 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -481,7 +481,8 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic /* * Open a new PPP Over L2TP (PPPoL2TP) connection. */ -int ppp_over_l2tp_open(ppp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, +int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ @@ -512,6 +513,8 @@ int ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg); void pppos_input(ppp_pcb *pcb, u_char* data, int len); #endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ +/* Get the PPP netif interface */ +#define ppp_netif(ppp) (&(ppp)->netif) #if LWIP_NETIF_STATUS_CALLBACK /* Set an lwIP-style status-callback for the selected PPP device */ diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index f6940875..a911ba2f 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -55,6 +55,7 @@ #include "lwip/err.h" #include "lwip/memp.h" +#include "lwip/netif.h" #include "lwip/udp.h" #include "ppp_impl.h" @@ -132,13 +133,14 @@ err_t pppol2tp_destroy(pppol2tp_pcb *l2tp) { } /* Be a LAC, connect to a LNS. */ -err_t pppol2tp_connect(pppol2tp_pcb *l2tp, ip_addr_t *ipaddr, u16_t port) { +err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipaddr, u16_t port) { err_t err; if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { return ERR_VAL; } + l2tp->netif = netif; ip_addr_set(&l2tp->remote_ip, ipaddr); l2tp->remote_port = l2tp->tunnel_port = port; @@ -743,7 +745,11 @@ static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp) { } #endif /* PPPOL2TP_AUTH_SUPPORT */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -796,7 +802,11 @@ static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns) { } #endif /* PPPOL2TP_AUTH_SUPPORT */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -847,7 +857,11 @@ static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns) { serialnumber = magic(); PUTLONG(serialnumber, p); /* Attribute value: Serial number */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -896,7 +910,11 @@ static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) { PUTSHORT(PPPOL2TP_AVPTYPE_TXCONNECTSPEED, p); /* Attribute type: TX Connect speed */ PUTLONG(PPPOL2TP_TXCONNECTSPEED, p); /* Attribute value: TX Connect speed */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -927,7 +945,11 @@ static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns) { PUTSHORT(ns, p); /* NS Sequence number - to peer */ PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -976,7 +998,11 @@ static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns) { PUTSHORT(PPPOL2TP_AVPTYPE_RESULTCODE, p); /* Attribute type: Result code */ PUTSHORT(PPPOL2TP_RESULTCODE, p); /* Attribute value: Result code */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } @@ -1004,7 +1030,11 @@ err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb) { PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ PUTSHORT(l2tp->source_session_id, p); /* Session Id */ - udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } pbuf_free(pb); return ERR_OK; } From 9e021cd1a890c8e42eb014cf3fe3d5d581bb6f2d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 14 Jul 2012 17:25:24 +0200 Subject: [PATCH 242/320] improved PPP default interface management, added ppp_set_default() API call --- src/api/pppapi.c | 20 ++++++++++++++++++++ src/include/lwip/pppapi.h | 1 + src/netif/ppp/ipcp.c | 11 ++++++++++- src/netif/ppp/ipcp.h | 4 +++- src/netif/ppp/ppp.c | 39 ++++----------------------------------- src/netif/ppp/ppp.h | 9 +++++++-- src/netif/ppp/ppp_impl.h | 3 --- 7 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/api/pppapi.c b/src/api/pppapi.c index 07fc0130..7ba587fb 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -58,6 +58,26 @@ ppp_pcb *pppapi_new(void) { } +/** + * Call ppp_set_default() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_set_default(struct pppapi_msg_msg *msg) { + ppp_set_default(msg->ppp); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_default() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void pppapi_set_default(ppp_pcb *pcb) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_default; + msg.msg.ppp = pcb; + TCPIP_PPPAPI(&msg); +} + + /** * Call ppp_set_auth() inside the tcpip_thread context. */ diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index 6b2897a7..3b74c890 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -110,6 +110,7 @@ struct pppapi_msg { /* API for application */ ppp_pcb *pppapi_new(void); +void pppapi_set_default(ppp_pcb *pcb); void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd); #if PPPOS_SUPPORT int pppapi_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index da390b35..1f1e249a 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -619,9 +619,10 @@ static void ipcp_init(ppp_pcb *pcb) { wo->maxslotindex = MAX_STATES - 1; /* really max index */ wo->cflag = 1; +#if 0 /* UNUSED */ /* wanting default route by default */ - /* FIXME: should be configurable */ wo->default_route = 1; +#endif /* UNUSED */ /* max slots and slot-id compression are currently hardwired in */ /* ppp_if.c to 16 and 1, this needs to be changed (among other */ @@ -632,12 +633,14 @@ static void ipcp_init(ppp_pcb *pcb) { ao->maxslotindex = MAX_STATES - 1; ao->cflag = 1; +#if 0 /* UNUSED */ /* * XXX These control whether the user may use the proxyarp * and defaultroute options. */ ao->proxy_arp = 1; ao->default_route = 1; +#endif /* UNUSED */ } @@ -1737,10 +1740,12 @@ ip_demand_conf(u) return 0; if (!sifnpmode(pcb, PPP_IP, NPMODE_QUEUE)) return 0; +#if 0 /* UNUSED */ if (wo->default_route) if (sifdefaultroute(pcb, wo->ouraddr, wo->hisaddr, wo->replace_default_route)) default_route_set[u] = 1; +#endif /* UNUSED */ if (wo->proxy_arp) if (sifproxyarp(pcb, wo->hisaddr)) proxy_arp_set[u] = 1; @@ -1914,11 +1919,13 @@ static void ipcp_up(fsm *f) { #endif sifnpmode(pcb, PPP_IP, NPMODE_PASS); +#if 0 /* UNUSED */ /* assign a default route through the interface if required */ if (wo->default_route) if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, wo->replace_default_route)) pcb->default_route_set = 1; +#endif /* UNUSED */ /* Make a proxy ARP entry if requested. */ if (ho->hisaddr != 0 && wo->proxy_arp) @@ -2020,6 +2027,7 @@ static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t re cifproxyarp(pcb, hisaddr); pcb->proxy_arp_set = 0; } +#if 0 /* UNUSED */ /* If replacedefaultroute, sifdefaultroute will be called soon * with replacedefaultroute set and that will overwrite the current * default route. This is the case only when doing demand, otherwise @@ -2032,6 +2040,7 @@ static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t re cifdefaultroute(pcb, ouraddr, hisaddr); pcb->default_route_set = 0; } +#endif /* UNUSED */ cifaddr(pcb, ouraddr, hisaddr); } diff --git a/src/netif/ppp/ipcp.h b/src/netif/ppp/ipcp.h index ffd1f2eb..5b6f1006 100644 --- a/src/netif/ppp/ipcp.h +++ b/src/netif/ppp/ipcp.h @@ -75,8 +75,10 @@ typedef struct ipcp_options { unsigned int neg_addr :1; /* Negotiate IP Address? */ unsigned int old_addrs :1; /* Use old (IP-Addresses) option? */ unsigned int req_addr :1; /* Ask peer to send IP address? */ +#if 0 /* UNUSED */ unsigned int default_route :1; /* Assign default route through interface? */ unsigned int replace_default_route :1; /* Replace default route through interface? */ +#endif /* UNUSED */ unsigned int proxy_arp :1; /* Make proxy ARP entry for peer? */ unsigned int neg_vj :1; /* Van Jacobson Compression? */ unsigned int old_vj :1; /* use old (short) form of VJ option? */ @@ -85,7 +87,7 @@ typedef struct ipcp_options { unsigned int req_dns1 :1; /* Ask peer to send primary DNS address? */ unsigned int req_dns2 :1; /* Ask peer to send secondary DNS address? */ unsigned int cflag :1; - unsigned int :3; /* 3 bits of padding to round out to 16 bits */ + unsigned int :5; /* 3 bits of padding to round out to 16 bits */ u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 66cccbe7..55f1f4c5 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -294,6 +294,10 @@ ppp_pcb *ppp_new(void) { return pcb; } +void ppp_set_default(ppp_pcb *pcb) { + netif_set_default(&pcb->netif); +} + void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { #if PAP_SUPPORT @@ -2190,41 +2194,6 @@ int netif_get_mtu(ppp_pcb *pcb) { return pcb->mtu; } -/******************************************************************** - * - * sifdefaultroute - assign a default route through the address given. - * - * If the global default_rt_repl_rest flag is set, then this function - * already replaced the original system defaultroute with some other - * route and it should just replace the current defaultroute with - * another one, without saving the current route. Use: demand mode, - * when pppd sets first a defaultroute it it's temporary ppp0 addresses - * and then changes the temporary addresses to the addresses for the real - * ppp connection when it has come up. - */ -int sifdefaultroute(ppp_pcb *pcb, u32_t ouraddr, u32_t gateway, u8_t replace) { - - LWIP_UNUSED_ARG(ouraddr); - LWIP_UNUSED_ARG(gateway); - LWIP_UNUSED_ARG(replace); - - netif_set_default(&pcb->netif); - return 1; -} - -/******************************************************************** - * - * cifdefaultroute - delete a default route through the address given. - */ -int cifdefaultroute(ppp_pcb *pcb, u32_t ouraddr, u32_t gateway) { - - LWIP_UNUSED_ARG(ouraddr); - LWIP_UNUSED_ARG(gateway); - - netif_set_default(NULL); - return 1; -} - /******************************************************************** * * sifproxyarp - Make a proxy ARP entry for the peer. diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 71e2bca6..dfc54750 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -294,7 +294,6 @@ struct ppp_pcb_s { unsigned int if_up :1; /* True when the interface is up. */ unsigned int pcomp :1; /* Does peer accept protocol compression? */ unsigned int accomp :1; /* Does peer accept addr/ctl compression? */ - unsigned int default_route_set :1; /* Have set up a default route */ unsigned int proxy_arp_set :1; /* Have created proxy arp entry */ unsigned int ipcp_is_open :1; /* haven't called np_finished() */ unsigned int ipcp_is_up :1; /* have called ipcp_up() */ @@ -310,7 +309,7 @@ struct ppp_pcb_s { #else unsigned int :1; /* 1 bit of padding */ #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - unsigned int :5; /* 5 bits of padding to round out to 16 bits */ + unsigned int :6; /* 5 bits of padding to round out to 16 bits */ ppp_settings settings; @@ -421,6 +420,12 @@ int ppp_init(void); */ ppp_pcb *ppp_new(void); +/* + * Set a PPP interface as the default network interface + * (used to output all packets for which no specific route is found). + */ +void ppp_set_default(ppp_pcb *pcb); + /* * Set auth helper, optional, you can either fill ppp_pcb->settings. * diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index 4fb95f95..f9bba04b 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -416,9 +416,6 @@ int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode); void netif_set_mtu(ppp_pcb *pcb, int mtu); int netif_get_mtu(ppp_pcb *pcb); -int sifdefaultroute(ppp_pcb *pcb, u32_t ouraddr, u32_t gateway, u8_t replace); -int cifdefaultroute(ppp_pcb *pcb, u32_t ouraddr, u32_t gateway); - int sifproxyarp(ppp_pcb *pcb, u32_t his_adr); int cifproxyarp(ppp_pcb *pcb, u32_t his_adr); From 94c35184a95a512134eb662529549591382aa7b4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 14 Jul 2012 17:47:30 +0200 Subject: [PATCH 243/320] replaced PPPoL2TP printf() used to debug to PPPDEBUG a/o deletion --- src/netif/ppp/pppol2tp.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index a911ba2f..fd85616a 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -239,7 +239,7 @@ static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struc goto free_and_return; } - printf("-----------\nL2TP INPUT, %d\n", p->len); + /* printf("-----------\nL2TP INPUT, %d\n", p->len); */ p = ppp_singlebuf(p); /* L2TP header */ @@ -309,14 +309,16 @@ static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struc INCPTR(offset, inp); } - printf("HLEN = %d\n", hlen); + /* printf("HLEN = %d\n", hlen); */ /* skip L2TP header */ if (pbuf_header(p, -hlen) != 0) { goto free_and_return; } - printf("LEN=%d, TUNNEL_ID=%d, SESSION_ID=%d, NS=%d, NR=%d, OFFSET=%d\n", len, tunnel_id, session_id, ns, nr, offset); + /* printf("LEN=%d, TUNNEL_ID=%d, SESSION_ID=%d, NS=%d, NR=%d, OFFSET=%d\n", len, tunnel_id, session_id, ns, nr, offset); */ + PPPDEBUG(LOG_DEBUG, ("pppol2tp: input packet, len=%"U16_F", tunnel=%"U16_F", session=%"U16_F", ns=%"U16_F", nr=%"U16_F"\n", + len, tunnel_id, session_id, ns, nr)); /* Control packet */ if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { @@ -362,7 +364,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr l2tp->peer_nr = nr; l2tp->peer_ns = ns; - printf("L2TP CTRL INPUT, ns=%d, nr=%d, len=%d\n", ns, nr, p->len); + /* printf("L2TP CTRL INPUT, ns=%d, nr=%d, len=%d\n", ns, nr, p->len); */ /* Handle the special case of the ICCN acknowledge */ if (l2tp->phase == PPPOL2TP_STATE_ICCN_SENT && l2tp->peer_nr > l2tp->our_ns) { @@ -382,7 +384,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr } GETSHORT(avpflags, inp); avplen = avpflags & PPPOL2TP_AVPHEADERFLAG_LENGTHMASK; - printf("AVPLEN = %d\n", avplen); + /* printf("AVPLEN = %d\n", avplen); */ if (p->len < avplen || avplen < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) { goto packet_too_short; } @@ -397,7 +399,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr return; } GETSHORT(messagetype, inp); - printf("Message type = %d\n", messagetype); + /* printf("Message type = %d\n", messagetype); */ switch(messagetype) { /* Start Control Connection Reply */ case PPPOL2TP_MESSAGETYPE_SCCRP: @@ -441,7 +443,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr return; } GETSHORT(l2tp->source_tunnel_id, inp); - printf("Assigned tunnel %d\n", l2tp->source_tunnel_id); + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned tunnel ID %"U16_F"\n", l2tp->source_tunnel_id)); goto nextavp; #if PPPOL2TP_AUTH_SUPPORT case PPPOL2TP_AVPTYPE_CHALLENGE: @@ -493,7 +495,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr return; } GETSHORT(l2tp->source_session_id, inp); - printf("Assigned session %d\n", l2tp->source_session_id); + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned session ID %"U16_F"\n", l2tp->source_session_id)); goto nextavp; } break; @@ -502,7 +504,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr skipavp: INCPTR(avplen, inp); nextavp: - printf("AVP Found, vendor=%d, attribute=%d, len=%d\n", vendorid, attributetype, avplen); + /* printf("AVP Found, vendor=%d, attribute=%d, len=%d\n", vendorid, attributetype, avplen); */ /* next AVP */ if (pbuf_header(p, -avplen - sizeof(avpflags) - sizeof(vendorid) - sizeof(attributetype) ) != 0) { return; From d2b2ae09e68f677cec618a84ce46a1d22569b52d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 15 Jul 2012 14:56:30 +0200 Subject: [PATCH 244/320] saving 14 bytes per PPPoE pbuf; not allocating struct eth_hdr two times per packet --- src/netif/ppp/ppp_oe.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 5a274b72..6026f8c7 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -634,6 +634,14 @@ pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) return ERR_IF; } + /* make room for Ethernet header - should not fail */ + if (pbuf_header(pb, (u16_t)(sizeof(struct eth_hdr))) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_output: could not allocate room for Ethernet header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + LINK_STATS_INC(link.lenerr); + pbuf_free(pb); + return ERR_BUF; + } ethhdr = (struct eth_hdr *)pb->payload; etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; ethhdr->type = htons(etype); @@ -682,15 +690,14 @@ pppoe_send_padi(struct pppoe_softc *sc) LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); - /* FIXME: PBUF_LINK already allocate a eth_hdr */ /* allocate a buffer */ - pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); if (!pb) { return ERR_MEM; } LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + p = (u8_t*)pb->payload; /* fill in pkt */ PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); @@ -935,12 +942,12 @@ pppoe_send_padr(struct pppoe_softc *sc) } LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); if (!pb) { return ERR_MEM; } LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + p = (u8_t*)pb->payload; PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); #ifdef PPPOE_TODO @@ -975,12 +982,13 @@ pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) err_t res; u8_t *p; - pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN, PBUF_RAM); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); if (!pb) { return ERR_MEM; } LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + pbuf_header(pb, sizeof(struct eth_hdr)); ethhdr = (struct eth_hdr *)pb->payload; ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); MEMCPY(ðhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); @@ -1014,12 +1022,12 @@ pppoe_send_pado(struct pppoe_softc *sc) len += 2 + 2 + sizeof(sc); /* include hunique */ len += 2 + 2 + sc->sc_hunique_len; - pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); if (!pb) { return ERR_MEM; } LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + p = (u8_t*)pb->payload; PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); PPPOE_ADD_16(p, sizeof(sc)); @@ -1051,12 +1059,12 @@ pppoe_send_pads(struct pppoe_softc *sc) l1 = strlen(sc->sc_service_name); len += l1; } - pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); if (!pb) { return ERR_MEM; } LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + p = (u8_t*)pb->payload; PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); if (sc->sc_service_name != NULL) { @@ -1088,16 +1096,16 @@ pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) len = pb->tot_len; - /* make room for Ethernet + PPPoE header - should not fail */ - if (pbuf_header(pb, sizeof(struct eth_hdr) + PPPOE_HEADERLEN) != 0) { + /* make room for PPPoE header - should not fail */ + if (pbuf_header(pb, (u16_t)(PPPOE_HEADERLEN)) != 0) { /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for PPPoE header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); LINK_STATS_INC(link.lenerr); pbuf_free(pb); return ERR_BUF; } - p = (u8_t*)pb->payload + sizeof(struct eth_hdr); + p = (u8_t*)pb->payload; PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); return pppoe_output(sc, pb); From 91af8878e14305acd394a278d06031907d8f8435 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 15 Jul 2012 15:07:07 +0200 Subject: [PATCH 245/320] saved some bytes from PPPoE control block, improved PADI retries --- src/include/netif/ppp_oe.h | 14 +++++++------- src/netif/ppp/ppp_oe.c | 15 ++++++--------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index c3021a14..e1feef59 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -148,22 +148,22 @@ struct pppoe_softc { ppp_pcb *pcb; /* PPP PCB */ void (*sc_link_status_cb)(ppp_pcb *pcb, int up); - int sc_state; /* discovery phase or session connected */ struct eth_addr sc_dest; /* hardware address of concentrator */ u16_t sc_session; /* PPPoE session id */ + u8_t sc_state; /* discovery phase or session connected */ #ifdef PPPOE_TODO - char *sc_service_name; /* if != NULL: requested name of service */ - char *sc_concentrator_name; /* if != NULL: requested concentrator id */ + u8_t *sc_service_name; /* if != NULL: requested name of service */ + u8_t *sc_concentrator_name; /* if != NULL: requested concentrator id */ #endif /* PPPOE_TODO */ u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ - size_t sc_ac_cookie_len; /* length of cookie data */ + u8_t sc_ac_cookie_len; /* length of cookie data */ #ifdef PPPOE_SERVER u8_t *sc_hunique; /* content of host unique we must echo back */ - size_t sc_hunique_len; /* length of host unique */ + u8_t sc_hunique_len; /* length of host unique */ #endif - int sc_padi_retried; /* number of PADI retries already done */ - int sc_padr_retried; /* number of PADR retries already done */ + u8_t sc_padi_retried; /* number of PADI retries already done */ + u8_t sc_padr_retried; /* number of PADR retries already done */ }; diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index 6026f8c7..c18f67a2 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -730,7 +730,8 @@ pppoe_send_padi(struct pppoe_softc *sc) static void pppoe_timeout(void *arg) { - int retry_wait, err; + u32_t retry_wait; + int err; struct pppoe_softc *sc = (struct pppoe_softc*)arg; PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); @@ -746,15 +747,9 @@ pppoe_timeout(void *arg) * We only enter slow retry mode if IFF_LINK1 (aka autodial) * is not set. */ - - /* initialize for quick retry mode */ - retry_wait = LWIP_MIN(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), PPPOE_SLOW_RETRY); - - /* prevent sc_padi_retried integer overflow << ~2^31/PPPOE_DISC_TIMEOUT - * FIXME: can be improved - */ - if(sc->sc_padi_retried < 100000) + if (sc->sc_padi_retried < UCHAR_MAX) { sc->sc_padi_retried++; + } if (!sc->pcb->settings.persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { #if 0 if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { @@ -767,6 +762,8 @@ pppoe_timeout(void *arg) return; } } + /* initialize for quick retry mode */ + retry_wait = LWIP_MIN(PPPOE_DISC_TIMEOUT * sc->sc_padi_retried, PPPOE_SLOW_RETRY); if ((err = pppoe_send_padi(sc)) != 0) { sc->sc_padi_retried--; PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); From 936c6c0d5ccbee0892f766cdfa7a193372204370 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 15 Jul 2012 15:12:40 +0200 Subject: [PATCH 246/320] reduced call stack by one when receiving a PPPoE disc packet --- src/netif/ppp/ppp_oe.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index c18f67a2..b78ec301 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -112,9 +112,6 @@ static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN]; -/* input routines */ -static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *); - /* management routines */ static int pppoe_do_disconnect(struct pppoe_softc *); static void pppoe_abort_connect(struct pppoe_softc *); @@ -273,8 +270,8 @@ pppoe_linkstatus_up(struct pppoe_softc *sc) } /* analyze and handle a single received packet while not in session state */ -static void -pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) +void +pppoe_disc_input(struct netif *netif, struct pbuf *pb) { u16_t tag, len; u16_t session, plen; @@ -292,6 +289,12 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) int off, err; struct eth_hdr *ethhdr; + /* don't do anything if there is not a single PPPoE instance */ + if (pppoe_softc_list == NULL) { + pbuf_free(pb); + return; + } + pb = ppp_singlebuf(pb); strcpy(devname, "pppoe"); /* as long as we don't know which instance */ @@ -534,18 +537,6 @@ done: return; } -/* FIXME: is this shit really necessary, why we don't call pppoe_dispatch_disc_pkt() instead !? */ -void -pppoe_disc_input(struct netif *netif, struct pbuf *p) -{ - /* avoid error messages if there is not a single pppoe instance */ - if (pppoe_softc_list != NULL) { - pppoe_dispatch_disc_pkt(netif, p); - } else { - pbuf_free(p); - } -} - void pppoe_data_input(struct netif *netif, struct pbuf *pb) { From a4f6146667f0d7b5889f2416a78ef622389b83d0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 15 Jul 2012 15:57:54 +0200 Subject: [PATCH 247/320] removed some FIXME that are not relevant anymore --- src/netif/ppp/ppp_impl.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/netif/ppp/ppp_impl.h b/src/netif/ppp/ppp_impl.h index f9bba04b..8b82f314 100644 --- a/src/netif/ppp/ppp_impl.h +++ b/src/netif/ppp/ppp_impl.h @@ -208,9 +208,6 @@ struct ppp_idle { }; #endif /* PPP_IDLETIMELIMIT */ -/* FIXME: make endpoint discriminator optional */ -/* FIXME: moved temporarily to ppp.h */ - /* values for epdisc.class */ #define EPD_NULL 0 /* null discriminator, no data */ #define EPD_LOCAL 1 @@ -219,8 +216,6 @@ struct ppp_idle { #define EPD_MAGIC 4 #define EPD_PHONENUM 5 -/* FIXME: global variables per PPP session */ - /* * Global variables. */ From c65883a72758c54d0af5575701a1e6ce5a756a75 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 16 Jul 2012 20:09:49 +0200 Subject: [PATCH 248/320] UCHAR_MAX is defined in limits.h, I do not want to add any system include, replaced to 0xff --- src/netif/ppp/ppp_oe.c | 2 +- src/netif/ppp/pppol2tp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index b78ec301..a9cf063a 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -738,7 +738,7 @@ pppoe_timeout(void *arg) * We only enter slow retry mode if IFF_LINK1 (aka autodial) * is not set. */ - if (sc->sc_padi_retried < UCHAR_MAX) { + if (sc->sc_padi_retried < 0xff) { sc->sc_padi_retried++; } if (!sc->pcb->settings.persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index fd85616a..d8b20832 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -567,7 +567,7 @@ static void pppol2tp_timeout(void *arg) { switch (l2tp->phase) { case PPPOL2TP_STATE_SCCRQ_SENT: /* backoff wait */ - if (l2tp->sccrq_retried < UCHAR_MAX) { + if (l2tp->sccrq_retried < 0xff) { l2tp->sccrq_retried++; } if (!l2tp->ppp->settings.persist && l2tp->sccrq_retried >= PPPOL2TP_MAXSCCRQ) { From 4ea5c1d973a0cf7725bbe6af415e6f3514fee4d7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 21 Jul 2012 00:26:23 +0200 Subject: [PATCH 249/320] improved persist mode, we now clear everything we can in the PPP control block structure, ensuring we start a new session from a clean state --- src/netif/ppp/lcp.c | 2 +- src/netif/ppp/ppp.c | 77 +++++++++++++++++++++++++++++++++------------ src/netif/ppp/ppp.h | 63 ++++++++++++++++++++----------------- 3 files changed, 93 insertions(+), 49 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 9e0f391c..cf5bbef5 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1494,7 +1494,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { */ if (f->state != PPP_FSM_OPENED) { if (looped_back) { - if (++try.numloops >= pcb->lcp_loopbackfail) { + if (++try.numloops >= pcb->settings.lcp_loopbackfail) { int errcode = PPPERR_LOOPBACK; notice("Serial line is looped back."); ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 55f1f4c5..6c689bb0 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -187,6 +187,7 @@ struct protent *protocols[] = { #endif /* PPPOS_SUPPORT */ /* Prototypes for procedures local to this file. */ +static void ppp_clear(ppp_pcb *pcb); static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ @@ -248,24 +249,16 @@ int ppp_init(void) { /* Create a new PPP session. */ ppp_pcb *ppp_new(void) { - int i; ppp_pcb *pcb; - struct protent *protp; pcb = (ppp_pcb*)memp_malloc(MEMP_PPP_PCB); if (pcb == NULL) return NULL; -#if PPP_STATS_SUPPORT - link_stats_valid = 0; -#endif /* PPP_STATS_SUPPORT */ - memset(pcb, 0, sizeof(ppp_pcb)); #if PPP_DEBUG pcb->num = ppp_num++; #endif /* PPP_DEBUG */ - IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); - pcb->lcp_loopbackfail = DEFLOOPBACKFAIL; /* default configuration */ pcb->settings.usepeerdns = 1; @@ -275,14 +268,11 @@ ppp_pcb *ppp_new(void) { pcb->settings.chap_timeout_time = 3; pcb->settings.chap_max_transmits = 10; #endif /* CHAP_SUPPPORT */ + pcb->settings.lcp_loopbackfail = DEFLOOPBACKFAIL; pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; - /* - * Initialize each protocol. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - (*protp->init)(pcb); + ppp_clear(pcb); if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { @@ -294,6 +284,25 @@ ppp_pcb *ppp_new(void) { return pcb; } +/* Set a PPP PCB to its initial state */ +static void ppp_clear(ppp_pcb *pcb) { + struct protent *protp; + int i; + +#if PPP_STATS_SUPPORTs + link_stats_valid = 0; +#endif /* PPP_STATS_SUPPORT */ + + memset(&pcb->phase, 0, sizeof(ppp_pcb) - ( (char*)&((ppp_pcb*)0)->phase - (char*)0 ) ); + IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); + + /* + * Initialize each protocol. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + (*protp->init)(pcb); +} + void ppp_set_default(ppp_pcb *pcb) { netif_set_default(&pcb->netif); } @@ -371,7 +380,6 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s * Start the connection and handle incoming events (packet or timeout). */ PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->num)); - new_phase(pcb, PHASE_INITIALIZE); ppp_start(pcb); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); @@ -430,7 +438,6 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic return PPPERR_OPEN; } - new_phase(pcb, PHASE_INITIALIZE); pppoe_connect(pcb->pppoe_sc); return PPPERR_NONE; } @@ -454,12 +461,12 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; - wo->mru = 1500; /* FIXME: MTU depends we support IP fragmentation or not */ + wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ wo->neg_asyncmap = 0; wo->neg_pcompression = 0; wo->neg_accompression = 0; - ao->mru = 1500; /* FIXME: MTU depends we support IP fragmentation or not */ + ao->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ ao->neg_asyncmap = 0; ao->neg_pcompression = 0; ao->neg_accompression = 0; @@ -468,7 +475,6 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 return PPPERR_OPEN; } - new_phase(pcb, PHASE_INITIALIZE); if(!pppol2tp_connect(pcb->l2tp_pcb, netif, ipaddr, port) != ERR_OK) { return PPPERR_OPEN; } @@ -525,6 +531,7 @@ ppp_sighup(ppp_pcb *pcb) /** Initiate LCP open request */ static void ppp_start(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->num)); + new_phase(pcb, PHASE_INITIALIZE); lcp_open(pcb); /* Start protocol */ lcp_lowerup(pcb); PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); @@ -1817,9 +1824,24 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { /* Reconnect if persist mode is enabled */ if(pcb->settings.persist) { + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + if(pcb->link_status_cb) pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); - new_phase(pcb, PHASE_INITIALIZE); + + ppp_clear(pcb); + + wo->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + wo->neg_asyncmap = 0; + wo->neg_pcompression = 0; + wo->neg_accompression = 0; + + ao->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + ao->neg_asyncmap = 0; + ao->neg_pcompression = 0; + ao->neg_accompression = 0; + pppoe_reconnect(pcb->pppoe_sc); return; } @@ -1860,9 +1882,24 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { /* Reconnect if persist mode is enabled */ if(pcb->settings.persist) { + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + if(pcb->link_status_cb) pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); - new_phase(pcb, PHASE_INITIALIZE); + + ppp_clear(pcb); + + wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ + wo->neg_asyncmap = 0; + wo->neg_pcompression = 0; + wo->neg_accompression = 0; + + ao->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ + ao->neg_asyncmap = 0; + ao->neg_pcompression = 0; + ao->neg_accompression = 0; + pppol2tp_reconnect(pcb->l2tp_pcb); return; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index dfc54750..1ca27b30 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -231,6 +231,8 @@ typedef struct ppp_settings_s { u8_t chap_rechallenge_time; #endif /* CHAP_SUPPPORT */ + u8_t lcp_loopbackfail; /* Number of times we receive our magic number from the peer + before deciding the link is looped-back. */ u8_t lcp_echo_interval; /* Interval between LCP echo-requests */ u8_t lcp_echo_fails; /* Tolerance to unanswered echo-requests */ @@ -281,7 +283,7 @@ typedef struct ppp_pcb_rx_s { u16_t in_protocol; /* The input protocol code. */ u16_t in_fcs; /* Input Frame Check Sequence value. */ - ppp_dev_states in_state; /* The input process state. */ + ppp_dev_states in_state; /* The input process state. */ char in_escaped; /* Escape next character. */ ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ } ppp_pcb_rx; @@ -291,6 +293,35 @@ typedef struct ppp_pcb_rx_s { * PPP interface control block. */ struct ppp_pcb_s { + /* -- below are data that will NOT be cleared between two sessions if persist mode is enabled */ +#if PPP_DEBUG + u8_t num; /* Interface number - only useful for debugging */ +#endif /* PPP_DEBUG */ + ppp_settings settings; +#if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ +#endif /* PPPOS_SUPPORT */ +#if PPPOE_SUPPORT + struct netif *ethif; + struct pppoe_softc *pppoe_sc; +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + pppol2tp_pcb *l2tp_pcb; +#endif /* PPPOL2TP_SUPPORT */ + void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */ + void *link_status_ctx; /* Status change callback optional pointer */ + struct netif netif; /* PPP interface */ + + /* -- below are data that will be cleared between two sessions if persist mode is enabled */ + + /* + * phase must be the first member of cleared members, because it is used to know + * which part must not be cleared. + */ + u8_t phase; /* where the link is at */ + u8_t err_code; /* Code indicating why interface is down. */ + + /* flags */ unsigned int if_up :1; /* True when the interface is up. */ unsigned int pcomp :1; /* Does peer accept protocol compression? */ unsigned int accomp :1; /* Does peer accept addr/ctl compression? */ @@ -311,14 +342,7 @@ struct ppp_pcb_s { #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ unsigned int :6; /* 5 bits of padding to round out to 16 bits */ - ppp_settings settings; - -#if PPP_DEBUG - u8_t num; /* Interface number - only useful for debugging */ -#endif /* PPP_DEBUG */ - #if PPPOS_SUPPORT - sio_fd_t fd; /* File device ID of port. */ /* FIXME: there is probably one superfluous */ ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ ext_accm xmit_accm; /* extended transmit ACCM */ @@ -328,18 +352,6 @@ struct ppp_pcb_s { #endif /* VJ_SUPPORT */ #endif /* PPPOS_SUPPORT */ -#if PPPOE_SUPPORT - struct netif *ethif; - struct pppoe_softc *pppoe_sc; -#endif /* PPPOE_SUPPORT */ - -#if PPPOL2TP_SUPPORT - pppol2tp_pcb *l2tp_pcb; -#endif /* PPPOL2TP_SUPPORT */ - - u8_t phase; /* where the link is at */ - u8_t err_code; /* Code indicating why interface is down. */ - /* FIXME: maybe we should cleanup one of those MTU variables */ u16_t mtu; /* Peer's mru */ u16_t peer_mru; /* currently negotiated peer MRU */ @@ -347,10 +359,6 @@ struct ppp_pcb_s { u32_t last_xmit; /* Time of last transmission. */ struct ppp_addrs addrs; /* PPP addresses */ - struct netif netif; /* PPP interface */ - - void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */ - void *link_status_ctx; /* Status change callback optional pointer */ /* auth data */ #if PPP_SERVER @@ -358,11 +366,11 @@ struct ppp_pcb_s { #endif /* PPP_SERVER */ u16_t auth_pending; /* Records which authentication operations haven't completed yet. */ u16_t auth_done; /* Records which authentication operations have been completed. */ - u8_t num_np_open; /* Number of network protocols which we have opened. */ - u8_t num_np_up; /* Number of network protocols which have come up. */ + u8_t num_np_open; /* Number of network protocols which we have opened. */ + u8_t num_np_up; /* Number of network protocols which have come up. */ #if PAP_SUPPORT - upap_state upap; /* PAP data */ + upap_state upap; /* PAP data */ #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT @@ -383,7 +391,6 @@ struct ppp_pcb_s { lcp_options lcp_hisoptions; /* Options that we ack'd */ u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ u8_t lcp_echo_number; /* ID number of next echo frame */ - u8_t lcp_loopbackfail; fsm ipcp_fsm; /* IPCP fsm structure */ ipcp_options ipcp_wantoptions; /* Options that we want to request */ From bc724ea2066cf5a64bf859eb77196fb683c97cac Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 22 Jul 2012 17:20:40 +0200 Subject: [PATCH 250/320] Do not destroy the PPP control block automatically anymore, added ppp_delete() API function. Without that, PPP user don't know when and how the PPP control block is free()ed, which can lead to hard fault. --- src/netif/ppp/auth.c | 2 +- src/netif/ppp/ppp.c | 122 +++++++++++++++++++++++++++------------ src/netif/ppp/ppp.h | 16 ++++- src/netif/ppp/pppol2tp.c | 2 + 4 files changed, 101 insertions(+), 41 deletions(-) diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 61d08f47..9cc62a5d 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -694,7 +694,7 @@ void link_terminated(ppp_pcb *pcb) { void link_down(ppp_pcb *pcb) { #if PPP_NOTIFY notify(link_down_notifier, 0); -#endif /* #if PPP_NOTIFY */ +#endif /* PPP_NOTIFY */ if (!doing_multilink) { upper_layers_down(pcb); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 6c689bb0..09b5e607 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -229,8 +229,6 @@ static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short pr static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p); #endif /* PPPOL2TP_SUPPORT */ -static void ppp_destroy(ppp_pcb *pcb); - /***********************************/ /*** PUBLIC FUNCTION DEFINITIONS ***/ /***********************************/ @@ -272,8 +270,6 @@ ppp_pcb *ppp_new(void) { pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; - ppp_clear(pcb); - if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { memp_free(MEMP_PPP_PCB, pcb); @@ -281,6 +277,7 @@ ppp_pcb *ppp_new(void) { return NULL; } + new_phase(pcb, PHASE_DEAD); return pcb; } @@ -289,6 +286,8 @@ static void ppp_clear(ppp_pcb *pcb) { struct protent *protp; int i; + LWIP_ASSERT("pcb->phase == PHASE_DEAD", pcb->phase == PHASE_DEAD); + #if PPP_STATS_SUPPORTs link_stats_valid = 0; #endif /* PPP_STATS_SUPPORT */ @@ -357,6 +356,9 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s /* input pbuf left over from last session? */ ppp_free_current_input_packet(&pcb->rx); + ppp_clear(pcb); + new_phase(pcb, PHASE_INITIALIZE); + pcb->fd = fd; pcb->rx.pcb = pcb; @@ -419,6 +421,9 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic if (link_status_cb == NULL) return PPPERR_PARAM; + ppp_clear(pcb); + new_phase(pcb, PHASE_INITIALIZE); + pcb->ethif = ethif; pcb->link_status_cb = link_status_cb; @@ -434,7 +439,7 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic ao->neg_pcompression = 0; ao->neg_accompression = 0; - if(pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { + if (pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { return PPPERR_OPEN; } @@ -458,6 +463,9 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 if (link_status_cb == NULL) return PPPERR_PARAM; + ppp_clear(pcb); + new_phase(pcb, PHASE_INITIALIZE); + pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; @@ -471,20 +479,22 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 ao->neg_pcompression = 0; ao->neg_accompression = 0; - if(pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, secret, secret_len) != ERR_OK) { + if (pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, secret, secret_len) != ERR_OK) { return PPPERR_OPEN; } - if(!pppol2tp_connect(pcb->l2tp_pcb, netif, ipaddr, port) != ERR_OK) { + if (pppol2tp_connect(pcb->l2tp_pcb, netif, ipaddr, port) != ERR_OK) { return PPPERR_OPEN; } return PPPERR_NONE; } #endif /* PPPOL2TP_SUPPORT */ -/* Close a PPP connection and release the descriptor. +/* + * Initiate the end of a PPP connection. * Any outstanding packets in the queues are dropped. - * Return 0 on success, an error code on failure. */ + * Return 0 on success, an error code on failure. + */ int ppp_close(ppp_pcb *pcb) { @@ -495,7 +505,7 @@ ppp_close(ppp_pcb *pcb) /* Disconnect */ #if PPPOE_SUPPORT - if(pcb->ethif) { + if (pcb->ethif) { PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ @@ -525,13 +535,46 @@ ppp_sighup(ppp_pcb *pcb) ppp_hup(pcb); } +/* + * Release the control block. + * + * This can only be called if PPP is in the dead phase. + * + * You must use ppp_close() before if you wish to terminate + * an established PPP session. + * + * Return 0 on success, an error code on failure. + */ +int ppp_delete(ppp_pcb *pcb) { + if (pcb->phase != PHASE_DEAD) { + return PPPERR_PARAM; + } + + PPPDEBUG(LOG_DEBUG, ("ppp_delete: unit %d\n", pcb->num)); + netif_remove(&pcb->netif); + +#if PPPOE_SUPPORT + if (pcb->ethif) { + pppoe_destroy(&pcb->netif); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + pppol2tp_destroy(pcb->l2tp_pcb); + } +#endif /* PPPOL2TP_SUPPORT */ + + memp_free(MEMP_PPP_PCB, pcb); + return 0; +} + /** Initiate LCP open request */ static void ppp_start(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->num)); - new_phase(pcb, PHASE_INITIALIZE); lcp_open(pcb); /* Start protocol */ lcp_lowerup(pcb); PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); @@ -1806,6 +1849,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { /* PPPoE link is established, starting PPP negotiation */ case PPPOE_CB_STATE_UP: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pcb->num)); + new_phase(pcb, PHASE_INITIALIZE); ppp_start(pcb); return; @@ -1827,9 +1871,6 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; - if(pcb->link_status_cb) - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); - ppp_clear(pcb); wo->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ @@ -1842,16 +1883,24 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { ao->neg_pcompression = 0; ao->neg_accompression = 0; + new_phase(pcb, PHASE_HOLDOFF); + + /* Callback must be called after phase changed to holdoff. It prevents + * the user to call ppp_delete() while we are going to reconnect. + */ + if (pcb->link_status_cb) { + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); + } + pppoe_reconnect(pcb->pppoe_sc); return; } ppp_hup(pcb); ppp_stop(pcb); - pppoe_destroy(&pcb->netif); - if(pcb->link_status_cb) + if (pcb->link_status_cb) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); - ppp_destroy(pcb); + } } #endif /* PPPOE_SUPPORT */ @@ -1864,6 +1913,7 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { /* PPPoL2TP link is established, starting PPP negotiation */ case PPPOL2TP_CB_STATE_UP: PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: UP, connecting\n", pcb->num)); + new_phase(pcb, PHASE_INITIALIZE); ppp_start(pcb); return; @@ -1885,9 +1935,6 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; - if(pcb->link_status_cb) - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); - ppp_clear(pcb); wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ @@ -1900,16 +1947,24 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { ao->neg_pcompression = 0; ao->neg_accompression = 0; + new_phase(pcb, PHASE_HOLDOFF); + + /* Callback must be called after phase changed to holdoff. It prevents + * the user to call ppp_delete() while we are going to reconnect. + */ + if (pcb->link_status_cb) { + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); + } + pppol2tp_reconnect(pcb->l2tp_pcb); return; } ppp_hup(pcb); ppp_stop(pcb); - pppol2tp_destroy(pcb->l2tp_pcb); - if(pcb->link_status_cb) + if (pcb->link_status_cb) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); - ppp_destroy(pcb); + } } #endif /* PPPOL2TP_SUPPORT */ @@ -1944,19 +1999,11 @@ void ppp_link_terminated(ppp_pcb *pcb) { if (pcb->link_status_cb) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->link_status_ctx); } - ppp_destroy(pcb); #endif /* PPPOS_SUPPORT */ } PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: finished.\n")); } -static void ppp_destroy(ppp_pcb *pcb) { - - PPPDEBUG(LOG_DEBUG, ("ppp_destroy: unit %d\n", pcb->num)); - netif_remove(&pcb->netif); - memp_free(MEMP_PPP_PCB, pcb); -} - #if LWIP_NETIF_STATUS_CALLBACK /** Set the status callback of a PPP's netif * @@ -1996,9 +2043,11 @@ ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) * new_phase - signal the start of a new phase of pppd's operation. */ void new_phase(ppp_pcb *pcb, int p) { - pcb->phase = p; + pcb->phase = p; + PPPDEBUG(LOG_DEBUG, ("ppp phase changed: unit %d: phase=%d\n", pcb->num, pcb->phase)); + printf("ppp phase changed: phase=%d\n", pcb->phase); #if PPP_NOTIFY - /* The one willing notify support should add here the code to be notified of phase changes */ + /* The one willing notify support should add here the code to be notified of phase changes */ #endif /* PPP_NOTIFY */ } @@ -2179,9 +2228,9 @@ int sifup(ppp_pcb *pcb) { pcb->err_code = PPPERR_NONE; PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); - if (pcb->link_status_cb) + if (pcb->link_status_cb) { pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); - + } return 1; } @@ -2199,9 +2248,6 @@ int sifdown(ppp_pcb *pcb) { /* make sure the netif status callback is called */ netif_set_down(&pcb->netif); PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); - if (pcb->link_status_cb) - pcb->link_status_cb(pcb, PPPERR_CONNECT, pcb->link_status_ctx); - return 1; } diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 1ca27b30..93704c78 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -499,9 +499,9 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 #endif /* PPPOL2TP_SUPPORT */ /* - * Close a PPP connection and release the control block. + * Initiate the end of a PPP connection. * Any outstanding packets in the queues are dropped. - * Return 0 on success, an error code on failure. + * Return 0 on success, an error code on failure. */ int ppp_close(ppp_pcb *pcb); @@ -510,6 +510,18 @@ int ppp_close(ppp_pcb *pcb); */ void ppp_sighup(ppp_pcb *pcb); +/* + * Release the control block. + * + * This can only be called if PPP is in the dead phase. + * + * You must use ppp_close() before if you wish to terminate + * an established PPP session. + * + * Return 0 on success, an error code on failure. + */ +int ppp_delete(ppp_pcb *pcb); + /* * Get and set parameters for the given connection. * Return 0 on success, an error code on failure. diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index d8b20832..53aa52c6 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -192,6 +192,8 @@ void pppol2tp_reconnect(pppol2tp_pcb *l2tp) { static void pppol2tp_do_reconnect(pppol2tp_pcb *l2tp) { err_t err; + /* FIXME: bind to a new source port so that we don't get packet from the previous session ? */ + do { l2tp->remote_tunnel_id = magic(); } while(l2tp->remote_tunnel_id == 0); From a467d21ebaaa501b00aef7cb2f9f5001358ae5bc Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 22 Jul 2012 18:05:19 +0200 Subject: [PATCH 251/320] ppp_close() PPPoL2TP support added --- src/netif/ppp/ppp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 09b5e607..756f403d 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -512,6 +512,14 @@ ppp_close(ppp_pcb *pcb) ppp_stop(pcb); } else #endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); + pcb->err_code = PPPERR_USER; + /* This will leave us at PHASE_DEAD. */ + ppp_stop(pcb); + } else +#endif /* PPPOL2TP_SUPPORT */ { #if PPPOS_SUPPORT PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); From 3c122117fcfe9a46ab9244257aba1817ff2430cd Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 22 Jul 2012 20:53:54 +0200 Subject: [PATCH 252/320] improved PPP API, added ppp_reopen() This is now the user choice to re-establish the session in the link status callback by either calling the ppp_reopen() to re-establish or ppp_delete() to free the PPP control block. Without user intervention, the PPP control block now stay in the dead phase, allowing the user to re-establish or delete the control block later. --- src/api/pppapi.c | 21 +++ src/include/lwip/pppapi.h | 4 + src/include/netif/ppp_oe.h | 10 +- src/include/netif/pppol2tp.h | 11 +- src/netif/ppp/ppp.c | 296 ++++++++++++++++++++--------------- src/netif/ppp/ppp.h | 10 ++ src/netif/ppp/ppp_oe.c | 21 --- src/netif/ppp/pppol2tp.c | 23 +-- 8 files changed, 218 insertions(+), 178 deletions(-) diff --git a/src/api/pppapi.c b/src/api/pppapi.c index 7ba587fb..341a945a 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -205,6 +205,27 @@ int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, #endif /* PPPOL2TP_SUPPORT */ +/** + * Call ppp_reopen() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_reopen(struct pppapi_msg_msg *msg) { + ppp_reopen(msg->ppp, msg->msg.reopen.holdoff); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_reopen() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void pppapi_reopen(ppp_pcb *pcb, u16_t holdoff) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_reopen; + msg.msg.ppp = pcb; + msg.msg.msg.reopen.holdoff = holdoff; + TCPIP_PPPAPI(&msg); +} + + /** * Call ppp_close() inside the tcpip_thread context. */ diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index 3b74c890..ae1e001a 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -80,6 +80,9 @@ struct pppapi_msg_msg { void *link_status_ctx; } l2tpopen; #endif /* PPPOL2TP_SUPPORT */ + struct { + u16_t holdoff; + } reopen; struct { int cmd; void *arg; @@ -125,6 +128,7 @@ int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ +void pppapi_reopen(ppp_pcb *pcb, u16_t holdoff); int pppapi_close(ppp_pcb *pcb); void pppapi_sighup(ppp_pcb *pcb); int pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg); diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index e1feef59..3a5a482c 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -106,11 +106,10 @@ PACK_STRUCT_END #define PPPOE_STATE_INITIAL 0 -#define PPPOE_STATE_HOLDOFF 1 -#define PPPOE_STATE_PADI_SENT 2 -#define PPPOE_STATE_PADR_SENT 3 -#define PPPOE_STATE_SESSION 4 -#define PPPOE_STATE_CLOSING 5 +#define PPPOE_STATE_PADI_SENT 1 +#define PPPOE_STATE_PADR_SENT 2 +#define PPPOE_STATE_SESSION 3 +#define PPPOE_STATE_CLOSING 4 /* passive */ #define PPPOE_STATE_PADO_SENT 1 @@ -173,7 +172,6 @@ err_t pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp err_t pppoe_destroy(struct netif *ifp); int pppoe_connect(struct pppoe_softc *sc); -void pppoe_reconnect(struct pppoe_softc *sc); void pppoe_disconnect(struct pppoe_softc *sc); void pppoe_disc_input(struct netif *netif, struct pbuf *p); diff --git a/src/include/netif/pppol2tp.h b/src/include/netif/pppol2tp.h index c7741431..ddd68e2d 100644 --- a/src/include/netif/pppol2tp.h +++ b/src/include/netif/pppol2tp.h @@ -150,12 +150,11 @@ /* L2TP Session state */ #define PPPOL2TP_STATE_INITIAL 0 -#define PPPOL2TP_STATE_HOLDOFF 1 -#define PPPOL2TP_STATE_SCCRQ_SENT 2 -#define PPPOL2TP_STATE_ICRQ_SENT 3 -#define PPPOL2TP_STATE_ICCN_SENT 4 -#define PPPOL2TP_STATE_DATA 5 -#define PPPOL2TP_STATE_CLOSING 6 +#define PPPOL2TP_STATE_SCCRQ_SENT 1 +#define PPPOL2TP_STATE_ICRQ_SENT 2 +#define PPPOL2TP_STATE_ICCN_SENT 3 +#define PPPOL2TP_STATE_DATA 4 +#define PPPOL2TP_STATE_CLOSING 5 #define PPPOL2TP_CB_STATE_UP 0 /* PPPoL2TP link is UP */ #define PPPOL2TP_CB_STATE_DOWN 1 /* PPPo2TP link is DOWN - normal condition */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 756f403d..6446065a 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -189,16 +189,19 @@ struct protent *protocols[] = { /* Prototypes for procedures local to this file. */ static void ppp_clear(ppp_pcb *pcb); +static void ppp_do_reopen(void *arg); + static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD static void ppp_receive_wakeup(ppp_pcb *pcb); -#endif /* #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ static void ppp_stop(ppp_pcb *pcb); static void ppp_hup(ppp_pcb *pcb); #if PPPOS_SUPPORT +static void ppp_over_serial_reopen(ppp_pcb *pcb); #if PPP_INPROC_OWNTHREAD static void ppp_input_thread(void *arg); #endif /* PPP_INPROC_OWNTHREAD */ @@ -218,12 +221,14 @@ static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol); #if PPPOE_SUPPORT +static void ppp_over_ethernet_reopen(ppp_pcb *pcb); static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol); /* function called by ppp_write() */ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT +static void ppp_over_l2tp_reopen(ppp_pcb *pcb); static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short protocol); /* function called by ppp_write() */ static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p); @@ -247,59 +252,39 @@ int ppp_init(void) { /* Create a new PPP session. */ ppp_pcb *ppp_new(void) { - ppp_pcb *pcb; + ppp_pcb *pcb; - pcb = (ppp_pcb*)memp_malloc(MEMP_PPP_PCB); - if (pcb == NULL) - return NULL; + pcb = (ppp_pcb*)memp_malloc(MEMP_PPP_PCB); + if (pcb == NULL) { + return NULL; + } - memset(pcb, 0, sizeof(ppp_pcb)); + memset(pcb, 0, sizeof(ppp_pcb)); #if PPP_DEBUG - pcb->num = ppp_num++; + pcb->num = ppp_num++; #endif /* PPP_DEBUG */ - /* default configuration */ - pcb->settings.usepeerdns = 1; - pcb->settings.persist = 1; - pcb->settings.holdoff = 30; + /* default configuration */ + pcb->settings.usepeerdns = 1; + pcb->settings.persist = 1; + pcb->settings.holdoff = 30; #if CHAP_SUPPORT - pcb->settings.chap_timeout_time = 3; - pcb->settings.chap_max_transmits = 10; + pcb->settings.chap_timeout_time = 3; + pcb->settings.chap_max_transmits = 10; #endif /* CHAP_SUPPPORT */ - pcb->settings.lcp_loopbackfail = DEFLOOPBACKFAIL; - pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; - pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; + pcb->settings.lcp_loopbackfail = DEFLOOPBACKFAIL; + pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; + pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; - if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, - &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { - memp_free(MEMP_PPP_PCB, pcb); - PPPDEBUG(LOG_ERR, ("ppp_new[%d]: netif_add failed\n", pcb->num)); - return NULL; - } + if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { + memp_free(MEMP_PPP_PCB, pcb); + PPPDEBUG(LOG_ERR, ("ppp_new[%d]: netif_add failed\n", pcb->num)); + return NULL; + } - new_phase(pcb, PHASE_DEAD); - return pcb; -} - -/* Set a PPP PCB to its initial state */ -static void ppp_clear(ppp_pcb *pcb) { - struct protent *protp; - int i; - - LWIP_ASSERT("pcb->phase == PHASE_DEAD", pcb->phase == PHASE_DEAD); - -#if PPP_STATS_SUPPORTs - link_stats_valid = 0; -#endif /* PPP_STATS_SUPPORT */ - - memset(&pcb->phase, 0, sizeof(ppp_pcb) - ( (char*)&((ppp_pcb*)0)->phase - (char*)0 ) ); - IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); - - /* - * Initialize each protocol. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - (*protp->init)(pcb); + new_phase(pcb, PHASE_DEAD); + return pcb; } void ppp_set_default(ppp_pcb *pcb) { @@ -309,19 +294,21 @@ void ppp_set_default(ppp_pcb *pcb) { void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { #if PAP_SUPPORT - if(authtype & PPPAUTHTYPE_PAP) + if (authtype & PPPAUTHTYPE_PAP) { pcb->settings.refuse_pap = 0; - else + } else { pcb->settings.refuse_pap = 1; + } #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT - if(authtype & PPPAUTHTYPE_CHAP) + if (authtype & PPPAUTHTYPE_CHAP) { pcb->settings.refuse_chap = 0; - else + } else { pcb->settings.refuse_chap = 1; + } #if MSCHAP_SUPPORT - if(authtype & PPPAUTHTYPE_MSCHAP) { + if (authtype & PPPAUTHTYPE_MSCHAP) { pcb->settings.refuse_mschap = 0; pcb->settings.refuse_mschap_v2 = 0; } else { @@ -332,17 +319,20 @@ void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { #endif /* CHAP_SUPPORT */ #if EAP_SUPPORT - if(authtype & PPPAUTHTYPE_EAP) + if (authtype & PPPAUTHTYPE_EAP) { pcb->settings.refuse_eap = 0; - else + } else { pcb->settings.refuse_eap = 1; + } #endif /* EAP_SUPPORT */ - if(user) + if (user) { pcb->settings.user = user; + } - if(passwd) + if (passwd) { pcb->settings.passwd = passwd; + } } #if PPPOS_SUPPORT @@ -350,8 +340,9 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ - if (link_status_cb == NULL) + if (link_status_cb == NULL) { return PPPERR_PARAM; + } /* input pbuf left over from last session? */ ppp_free_current_input_packet(&pcb->rx); @@ -418,8 +409,9 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ - if (link_status_cb == NULL) + if (link_status_cb == NULL) { return PPPERR_PARAM; + } ppp_clear(pcb); new_phase(pcb, PHASE_INITIALIZE); @@ -460,8 +452,9 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ - if (link_status_cb == NULL) + if (link_status_cb == NULL) { return PPPERR_PARAM; + } ppp_clear(pcb); new_phase(pcb, PHASE_INITIALIZE); @@ -490,6 +483,32 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 } #endif /* PPPOL2TP_SUPPORT */ +/* + * Open a previously opened PPP connection. + * + * This can only be called if PPP is in the dead phase. + * + * Holdoff is the time to wait (in seconds) before initiating + * the connection. + */ +int ppp_reopen(ppp_pcb *pcb, u16_t holdoff) { + if (pcb->phase != PHASE_DEAD) { + return PPPERR_PARAM; + } + + PPPDEBUG(LOG_DEBUG, ("ppp_reopen() called, holdoff=%d\n", holdoff)); + ppp_clear(pcb); + + if (holdoff == 0) { + ppp_do_reopen(pcb); + return PPPERR_NONE; + } + + new_phase(pcb, PHASE_HOLDOFF); + sys_timeout((u32_t)(holdoff*1000), ppp_do_reopen, pcb); + return PPPERR_NONE; +} + /* * Initiate the end of a PPP connection. * Any outstanding packets in the queues are dropped. @@ -501,7 +520,7 @@ ppp_close(ppp_pcb *pcb) int st = 0; PPPDEBUG(LOG_DEBUG, ("ppp_close() called\n")); - pcb->settings.persist = 0; + pcb->settings.persist = 0; /* FIXME: not necessary anymore since persistence is done through link status callback */ /* Disconnect */ #if PPPOE_SUPPORT @@ -580,6 +599,56 @@ int ppp_delete(ppp_pcb *pcb) { +/************************************/ +/*** PRIVATE FUNCTION DEFINITIONS ***/ +/************************************/ + +/* Set a PPP PCB to its initial state */ +static void ppp_clear(ppp_pcb *pcb) { + struct protent *protp; + int i; + + LWIP_ASSERT("pcb->phase == PHASE_DEAD", pcb->phase == PHASE_DEAD); + +#if PPP_STATS_SUPPORTs + link_stats_valid = 0; +#endif /* PPP_STATS_SUPPORT */ + + memset(&pcb->phase, 0, sizeof(ppp_pcb) - ( (char*)&((ppp_pcb*)0)->phase - (char*)0 ) ); + IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); + + /* + * Initialize each protocol. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + (*protp->init)(pcb); + } +} + +static void ppp_do_reopen(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + + new_phase(pcb, PHASE_INITIALIZE); + +#if PPPOE_SUPPORT + if (pcb->ethif) { + ppp_over_ethernet_reopen(pcb); + return; + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + ppp_over_l2tp_reopen(pcb); + return; + } +#endif /* PPPOL2TP_SUPPORT */ + +#if PPPOS_SUPPORT + ppp_over_serial_reopen(pcb); +#endif /* PPPOS_SUPPORT */ +} + /** Initiate LCP open request */ static void ppp_start(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->num)); @@ -957,7 +1026,13 @@ static err_t ppp_netif_init_cb(struct netif *netif) { /*** LOCAL FUNCTION DEFINITIONS ***/ /**********************************/ -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD +#if PPPOS_SUPPORT +static void ppp_over_serial_reopen(ppp_pcb *pcb) { + +/* FIXME: fill me */ +} + +#if PPP_INPROC_OWNTHREAD /* The main PPP process function. This implements the state machine according * to section 4 of RFC 1661: The Point-To-Point Protocol. */ static void @@ -977,10 +1052,8 @@ ppp_input_thread(void *arg) } } } -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ +#endif /* PPP_INPROC_OWNTHREAD */ - -#if PPPOS_SUPPORT static void pppos_put(ppp_pcb *pcb, struct pbuf *nb) { @@ -1857,7 +1930,6 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { /* PPPoE link is established, starting PPP negotiation */ case PPPOE_CB_STATE_UP: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pcb->num)); - new_phase(pcb, PHASE_INITIALIZE); ppp_start(pcb); return; @@ -1874,42 +1946,30 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { break; } - /* Reconnect if persist mode is enabled */ - if(pcb->settings.persist) { - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - - ppp_clear(pcb); - - wo->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - wo->neg_asyncmap = 0; - wo->neg_pcompression = 0; - wo->neg_accompression = 0; - - ao->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - ao->neg_asyncmap = 0; - ao->neg_pcompression = 0; - ao->neg_accompression = 0; - - new_phase(pcb, PHASE_HOLDOFF); - - /* Callback must be called after phase changed to holdoff. It prevents - * the user to call ppp_delete() while we are going to reconnect. - */ - if (pcb->link_status_cb) { - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); - } - - pppoe_reconnect(pcb->pppoe_sc); - return; - } - ppp_hup(pcb); ppp_stop(pcb); if (pcb->link_status_cb) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); } } + +static void ppp_over_ethernet_reopen(ppp_pcb *pcb) { + + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + + wo->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + wo->neg_asyncmap = 0; + wo->neg_pcompression = 0; + wo->neg_accompression = 0; + + ao->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + ao->neg_asyncmap = 0; + ao->neg_pcompression = 0; + ao->neg_accompression = 0; + + pppoe_connect(pcb->pppoe_sc); +} #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT @@ -1921,7 +1981,6 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { /* PPPoL2TP link is established, starting PPP negotiation */ case PPPOL2TP_CB_STATE_UP: PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: UP, connecting\n", pcb->num)); - new_phase(pcb, PHASE_INITIALIZE); ppp_start(pcb); return; @@ -1938,42 +1997,30 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { break; } - /* Reconnect if persist mode is enabled */ - if(pcb->settings.persist) { - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - - ppp_clear(pcb); - - wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ - wo->neg_asyncmap = 0; - wo->neg_pcompression = 0; - wo->neg_accompression = 0; - - ao->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ - ao->neg_asyncmap = 0; - ao->neg_pcompression = 0; - ao->neg_accompression = 0; - - new_phase(pcb, PHASE_HOLDOFF); - - /* Callback must be called after phase changed to holdoff. It prevents - * the user to call ppp_delete() while we are going to reconnect. - */ - if (pcb->link_status_cb) { - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); - } - - pppol2tp_reconnect(pcb->l2tp_pcb); - return; - } - ppp_hup(pcb); ppp_stop(pcb); if (pcb->link_status_cb) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); } } + +static void ppp_over_l2tp_reopen(ppp_pcb *pcb) { + + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + + wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ + wo->neg_asyncmap = 0; + wo->neg_pcompression = 0; + wo->neg_accompression = 0; + + ao->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ + ao->neg_asyncmap = 0; + ao->neg_pcompression = 0; + ao->neg_accompression = 0; + + pppol2tp_reconnect(pcb->l2tp_pcb); +} #endif /* PPPOL2TP_SUPPORT */ void ppp_link_down(ppp_pcb *pcb) { @@ -2053,7 +2100,6 @@ ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) void new_phase(ppp_pcb *pcb, int p) { pcb->phase = p; PPPDEBUG(LOG_DEBUG, ("ppp phase changed: unit %d: phase=%d\n", pcb->num, pcb->phase)); - printf("ppp phase changed: phase=%d\n", pcb->phase); #if PPP_NOTIFY /* The one willing notify support should add here the code to be notified of phase changes */ #endif /* PPP_NOTIFY */ diff --git a/src/netif/ppp/ppp.h b/src/netif/ppp/ppp.h index 93704c78..0f41ee45 100644 --- a/src/netif/ppp/ppp.h +++ b/src/netif/ppp/ppp.h @@ -498,6 +498,16 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ +/* + * Open a previously opened PPP connection. + * + * This can only be called if PPP is in the dead phase. + * + * Holdoff is the time to wait (in seconds) before initiating + * the connection. + */ +int ppp_reopen(ppp_pcb *pcb, u16_t holdoff); + /* * Initiate the end of a PPP connection. * Any outstanding packets in the queues are dropped. diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index a9cf063a..bd7aa1f7 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -783,10 +783,6 @@ pppoe_timeout(void *arg) case PPPOE_STATE_CLOSING: pppoe_do_disconnect(sc); break; - case PPPOE_STATE_HOLDOFF: - sc->sc_state = PPPOE_STATE_INITIAL; - pppoe_connect(sc); - break; default: return; /* all done, work in peace */ } @@ -822,23 +818,6 @@ pppoe_connect(struct pppoe_softc *sc) return err; } -/* Start a reconnection */ -void pppoe_reconnect(struct pppoe_softc *sc) { - - if (sc->sc_state != PPPOE_STATE_INITIAL) { - return; - } - - if (sc->pcb->settings.holdoff == 0) { - pppoe_connect(sc); - return; - } - - sc->sc_state = PPPOE_STATE_HOLDOFF; - sys_timeout((u32_t)sc->pcb->settings.holdoff*1000, pppoe_timeout, sc); - return; -} - /* disconnect */ void pppoe_disconnect(struct pppoe_softc *sc) diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index 53aa52c6..a197fea8 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -72,7 +72,6 @@ #endif /* PPPOL2TP_AUTH_SUPPORT */ /* Prototypes for procedures local to this file. */ -static void pppol2tp_do_reconnect(pppol2tp_pcb *l2tp); static void pppol2tp_do_disconnect(pppol2tp_pcb *l2tp); static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port, @@ -106,6 +105,7 @@ err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int sta *l2tpptr = NULL; return ERR_MEM; } + udp_recv(udp, pppol2tp_input, l2tp); memset(l2tp, 0, sizeof(pppol2tp_pcb)); l2tp->phase = PPPOL2TP_STATE_INITIAL; @@ -148,7 +148,6 @@ err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipadd * because the L2TP LNS might answer with its own random source port (!= 1701) */ udp_bind(l2tp->udp, IP_ADDR_ANY, 0); - udp_recv(l2tp->udp, pppol2tp_input, l2tp); #if PPPOL2TP_AUTH_SUPPORT /* Generate random vector */ @@ -172,6 +171,7 @@ err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipadd /* Reconnect to a LNS, using previously set L2TP server IP address and port. */ void pppol2tp_reconnect(pppol2tp_pcb *l2tp) { + err_t err; if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { return; @@ -179,20 +179,7 @@ void pppol2tp_reconnect(pppol2tp_pcb *l2tp) { pppol2tp_clear(l2tp); - if (l2tp->ppp->settings.holdoff == 0) { - pppol2tp_do_reconnect(l2tp); - return; - } - - l2tp->phase = PPPOL2TP_STATE_HOLDOFF; - sys_timeout((u32_t)l2tp->ppp->settings.holdoff*1000, pppol2tp_timeout, l2tp); - return; -} - -static void pppol2tp_do_reconnect(pppol2tp_pcb *l2tp) { - err_t err; - - /* FIXME: bind to a new source port so that we don't get packet from the previous session ? */ + udp_bind(l2tp->udp, IP_ADDR_ANY, 0); do { l2tp->remote_tunnel_id = magic(); @@ -625,10 +612,6 @@ static void pppol2tp_timeout(void *arg) { pppol2tp_do_disconnect(l2tp); break; - case PPPOL2TP_STATE_HOLDOFF: - pppol2tp_do_reconnect(l2tp); - break; - default: return; /* all done, work in peace */ } From 5552f082e8c0a3fe2e46f197706b6ca9a8bbb6c9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 22 Jul 2012 21:42:56 +0200 Subject: [PATCH 253/320] handle cases when ppp_close() is called while session is in dead or holdoff phase --- src/netif/ppp/ppp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 6446065a..508ec906 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -519,6 +519,19 @@ ppp_close(ppp_pcb *pcb) { int st = 0; + /* dead phase, nothing to do, call the status callback to be consistent */ + if (pcb->phase == PHASE_DEAD) { + pcb->link_status_cb(pcb, PPPERR_USER, pcb->link_status_ctx); + return PPPERR_NONE; + } + + /* holdoff phase, cancel the reconnection and call the status callback */ + if (pcb->phase == PHASE_HOLDOFF) { + sys_untimeout(ppp_do_reopen, pcb); + pcb->link_status_cb(pcb, PPPERR_USER, pcb->link_status_ctx); + return PPPERR_NONE; + } + PPPDEBUG(LOG_DEBUG, ("ppp_close() called\n")); pcb->settings.persist = 0; /* FIXME: not necessary anymore since persistence is done through link status callback */ From 8ec92b6fe76229dfe6ef543577a7dcc699c159b9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 22 Jul 2012 23:37:35 +0200 Subject: [PATCH 254/320] don't call ppp_hup() and ppp_stop() if PPPoE or PPPoL2TP failed to connect This is useless because PPP is not started yet, it confuses the PPP phase state machine. --- src/netif/ppp/ppp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 508ec906..f9a1cba3 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1950,6 +1950,8 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { case PPPOE_CB_STATE_DOWN: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pcb->num)); pppoe_err_code = PPPERR_CONNECT; + ppp_hup(pcb); + ppp_stop(pcb); break; /* PPPoE link failed to setup (i.e. PADI/PADO timeout) */ @@ -1959,8 +1961,6 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { break; } - ppp_hup(pcb); - ppp_stop(pcb); if (pcb->link_status_cb) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); } @@ -2001,6 +2001,8 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { case PPPOL2TP_CB_STATE_DOWN: PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: DOWN, disconnected\n", pcb->num)); pppol2tp_err_code = PPPERR_CONNECT; + ppp_hup(pcb); + ppp_stop(pcb); break; /* PPPoL2TP link failed to setup (i.e. L2TP timeout) */ @@ -2010,8 +2012,6 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { break; } - ppp_hup(pcb); - ppp_stop(pcb); if (pcb->link_status_cb) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); } From 35c670513fde8839be911c5153f5e0c685356bac Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 22 Jul 2012 23:53:27 +0200 Subject: [PATCH 255/320] fixed some more PPP phase state machine issues The only way PPPoE or PPPoL2TP disconnect it through ppp_link_terminated(), therefore PPP is always already down, so we don't need to ask PPP to hup or stop. --- src/netif/ppp/ppp.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index f9a1cba3..221f961b 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1950,8 +1950,6 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { case PPPOE_CB_STATE_DOWN: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pcb->num)); pppoe_err_code = PPPERR_CONNECT; - ppp_hup(pcb); - ppp_stop(pcb); break; /* PPPoE link failed to setup (i.e. PADI/PADO timeout) */ @@ -2001,8 +1999,6 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { case PPPOL2TP_CB_STATE_DOWN: PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: DOWN, disconnected\n", pcb->num)); pppol2tp_err_code = PPPERR_CONNECT; - ppp_hup(pcb); - ppp_stop(pcb); break; /* PPPoL2TP link failed to setup (i.e. L2TP timeout) */ From e067e84d69ae6684c7d99d1fcb568f64d527ded9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 23 Jul 2012 00:48:27 +0200 Subject: [PATCH 256/320] switch to phase dead if PPPoE or PPPoL2TP failed to connect --- src/netif/ppp/ppp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 221f961b..1e64f680 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1956,6 +1956,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { case PPPOE_CB_STATE_FAILED: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pcb->num)); pppoe_err_code = PPPERR_OPEN; + new_phase(pcb, PHASE_DEAD); break; } @@ -2005,6 +2006,7 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { case PPPOL2TP_CB_STATE_FAILED: PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: FAILED, aborting\n", pcb->num)); pppol2tp_err_code = PPPERR_OPEN; + new_phase(pcb, PHASE_DEAD); break; } From 59567b43b0d95e55aaae037ca528f46109ab1dfe Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 23 Jul 2012 00:55:24 +0200 Subject: [PATCH 257/320] pcb->link_status_cb must be set, we don't need to check each time we use it if not NULL --- src/netif/ppp/ppp.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 1e64f680..bb5ad627 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -519,16 +519,18 @@ ppp_close(ppp_pcb *pcb) { int st = 0; + pcb->err_code = PPPERR_USER; + /* dead phase, nothing to do, call the status callback to be consistent */ if (pcb->phase == PHASE_DEAD) { - pcb->link_status_cb(pcb, PPPERR_USER, pcb->link_status_ctx); + pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); return PPPERR_NONE; } /* holdoff phase, cancel the reconnection and call the status callback */ if (pcb->phase == PHASE_HOLDOFF) { sys_untimeout(ppp_do_reopen, pcb); - pcb->link_status_cb(pcb, PPPERR_USER, pcb->link_status_ctx); + pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); return PPPERR_NONE; } @@ -539,7 +541,6 @@ ppp_close(ppp_pcb *pcb) #if PPPOE_SUPPORT if (pcb->ethif) { PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); - pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ ppp_stop(pcb); } else @@ -547,7 +548,6 @@ ppp_close(ppp_pcb *pcb) #if PPPOL2TP_SUPPORT if (pcb->l2tp_pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); - pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ ppp_stop(pcb); } else @@ -555,7 +555,6 @@ ppp_close(ppp_pcb *pcb) { #if PPPOS_SUPPORT PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); - pcb->err_code = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ ppp_stop(pcb); #if PPP_INPROC_OWNTHREAD @@ -1960,9 +1959,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { break; } - if (pcb->link_status_cb) { - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); - } + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); } static void ppp_over_ethernet_reopen(ppp_pcb *pcb) { @@ -2010,9 +2007,7 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { break; } - if (pcb->link_status_cb) { - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); - } + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); } static void ppp_over_l2tp_reopen(ppp_pcb *pcb) { @@ -2062,9 +2057,7 @@ void ppp_link_terminated(ppp_pcb *pcb) { #endif /* PPP_INPROC_OWNTHREAD */ PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); - if (pcb->link_status_cb) { - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->link_status_ctx); - } + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->link_status_ctx); #endif /* PPPOS_SUPPORT */ } PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: finished.\n")); @@ -2293,9 +2286,7 @@ int sifup(ppp_pcb *pcb) { pcb->err_code = PPPERR_NONE; PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); - if (pcb->link_status_cb) { - pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); - } + pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); return 1; } From c58c27ed8b118e48a785080b95f1213c02cabe67 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 24 Jul 2012 22:50:17 +0200 Subject: [PATCH 258/320] removed time-based PPP phase state machine hacks from PPPoE dans PPPoL2TP Our PPP phase state machine is now clean, we can safely remove time based hacks in PPPoE dans PPPoL2TP. --- src/include/netif/ppp_oe.h | 1 - src/include/netif/pppol2tp.h | 1 - src/netif/ppp/ppp_oe.c | 27 ++++----------------------- src/netif/ppp/pppol2tp.c | 23 ++++++----------------- 4 files changed, 10 insertions(+), 42 deletions(-) diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp_oe.h index 3a5a482c..02006f33 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp_oe.h @@ -109,7 +109,6 @@ PACK_STRUCT_END #define PPPOE_STATE_PADI_SENT 1 #define PPPOE_STATE_PADR_SENT 2 #define PPPOE_STATE_SESSION 3 -#define PPPOE_STATE_CLOSING 4 /* passive */ #define PPPOE_STATE_PADO_SENT 1 diff --git a/src/include/netif/pppol2tp.h b/src/include/netif/pppol2tp.h index ddd68e2d..c7beaaae 100644 --- a/src/include/netif/pppol2tp.h +++ b/src/include/netif/pppol2tp.h @@ -154,7 +154,6 @@ #define PPPOL2TP_STATE_ICRQ_SENT 2 #define PPPOL2TP_STATE_ICCN_SENT 3 #define PPPOL2TP_STATE_DATA 4 -#define PPPOL2TP_STATE_CLOSING 5 #define PPPOL2TP_CB_STATE_UP 0 /* PPPoL2TP link is UP */ #define PPPOL2TP_CB_STATE_DOWN 1 /* PPPo2TP link is DOWN - normal condition */ diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index bd7aa1f7..d61b84bb 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -113,7 +113,6 @@ static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN]; /* management routines */ -static int pppoe_do_disconnect(struct pppoe_softc *); static void pppoe_abort_connect(struct pppoe_softc *); static void pppoe_clear_softc(struct pppoe_softc *, const char *); @@ -780,9 +779,6 @@ pppoe_timeout(void *arg) } sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); break; - case PPPOE_STATE_CLOSING: - pppoe_do_disconnect(sc); - break; default: return; /* all done, work in peace */ } @@ -821,31 +817,16 @@ pppoe_connect(struct pppoe_softc *sc) /* disconnect */ void pppoe_disconnect(struct pppoe_softc *sc) -{ - if (sc->sc_state < PPPOE_STATE_SESSION) { - return; - } - /* - * Do not call pppoe_disconnect here, the upper layer state - * machine gets confused by this. We must return from this - * function and defer disconnecting to the timeout handler. - */ - sc->sc_state = PPPOE_STATE_CLOSING; - sys_timeout(20, pppoe_timeout, sc); -} - -static int -pppoe_do_disconnect(struct pppoe_softc *sc) { int err; if (sc->sc_state < PPPOE_STATE_SESSION) { - err = EBUSY; - } else { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); + return EBUSY; } + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); + /* cleanup softc */ sc->sc_state = PPPOE_STATE_INITIAL; MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index a197fea8..aa595a82 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -72,7 +72,6 @@ #endif /* PPPOL2TP_AUTH_SUPPORT */ /* Prototypes for procedures local to this file. */ -static void pppol2tp_do_disconnect(pppol2tp_pcb *l2tp); static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port, struct pbuf *p, u16_t len, u16_t tunnel_id, u16_t session_id, u16_t ns, u16_t nr); @@ -197,22 +196,12 @@ void pppol2tp_reconnect(pppol2tp_pcb *l2tp) { /* Disconnect */ void pppol2tp_disconnect(pppol2tp_pcb *l2tp) { - if (l2tp->phase == PPPOL2TP_STATE_CLOSING) { + if (l2tp->phase < PPPOL2TP_STATE_DATA) { return; } l2tp->our_ns++; pppol2tp_send_stopccn(l2tp, l2tp->our_ns); - /* - * Do not call pppol2tp_disconnect here, the upper layer state - * machine gets confused by this. We must return from this - * function and defer disconnecting to the timeout handler. - */ - l2tp->phase = PPPOL2TP_STATE_CLOSING; - sys_timeout(20, pppol2tp_timeout, l2tp); -} - -static void pppol2tp_do_disconnect(pppol2tp_pcb *l2tp) { pppol2tp_clear(l2tp); l2tp->link_status_cb(l2tp->ppp, PPPOL2TP_CB_STATE_DOWN); /* notify upper layers */ @@ -410,7 +399,11 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr if (l2tp->phase < PPPOL2TP_STATE_DATA) { pppol2tp_abort_connect(l2tp); } else if (l2tp->phase == PPPOL2TP_STATE_DATA) { - pppol2tp_disconnect(l2tp); + /* Don't disconnect here, we let the LCP Echo/Reply find the fact + * that PPP session is down. Asking the PPP stack to end the session + * require strict checking about the PPP phase to prevent endless + * disconnection loops. + */ } return; } @@ -608,10 +601,6 @@ static void pppol2tp_timeout(void *arg) { sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); break; - case PPPOL2TP_STATE_CLOSING: - pppol2tp_do_disconnect(l2tp); - break; - default: return; /* all done, work in peace */ } From c5c1012dddf7daeae63ec1761e44c9596a971ef0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 17 Aug 2012 23:42:14 +0200 Subject: [PATCH 259/320] removed some compiler warnings in pppoe_disconnect() --- src/netif/ppp/ppp_oe.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/ppp_oe.c index d61b84bb..84a47aeb 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/ppp_oe.c @@ -818,14 +818,12 @@ pppoe_connect(struct pppoe_softc *sc) void pppoe_disconnect(struct pppoe_softc *sc) { - int err; - if (sc->sc_state < PPPOE_STATE_SESSION) { - return EBUSY; + return; } PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); + pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); /* cleanup softc */ sc->sc_state = PPPOE_STATE_INITIAL; @@ -843,7 +841,7 @@ pppoe_disconnect(struct pppoe_softc *sc) sc->sc_padr_retried = 0; sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_DOWN); /* notify upper layers */ - return err; + return; } /* Connection attempt aborted */ From 1adb9005612a1db88c3557a3fa7a44677e65051b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 18 Aug 2012 12:56:59 +0200 Subject: [PATCH 260/320] Moved the include of lwip_md5.h or md5.h into the #if PPP_MD5_RANDM block, as suggested by Ivan Delamer --- src/netif/ppp/magic.c | 7 +++---- src/netif/ppp/magic.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index 49da633e..fd5b159c 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -76,6 +76,9 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ #include "ppp_impl.h" +#include "magic.h" + +#if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */ #if LWIP_INCLUDED_POLARSSL_MD5 #include "polarssl/lwip_md5.h" @@ -83,10 +86,6 @@ #include "polarssl/md5.h" #endif -#include "magic.h" - -#if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */ - #define MAGIC_RANDPOOLSIZE 16 /* Bytes stored in the pool of randomness. */ /*****************************/ diff --git a/src/netif/ppp/magic.h b/src/netif/ppp/magic.h index 5dc34018..4661dea5 100644 --- a/src/netif/ppp/magic.h +++ b/src/netif/ppp/magic.h @@ -105,7 +105,7 @@ u32_t magic(void); /* Returns the next magic number */ * Fill buffer with random bytes * * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using churnRand(). + * random when used faster than randomness is supplied using magic_churnrand(). * Thus it's important to make sure that the results of this are not * published directly because one could predict the next result to at * least some degree. Also, it's important to get a good seed before From 1ddebcc862c3e223448d05ccdfa5946c81058a37 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 18 Aug 2012 22:40:19 +0200 Subject: [PATCH 261/320] Moved PPP headers into include/netif/ppp/, fixing bug #37040. --- src/api/tcpip.c | 2 +- src/core/init.c | 2 +- src/core/memp.c | 5 ++-- src/include/lwip/pppapi.h | 2 +- src/{ => include}/netif/ppp/ccp.h | 0 src/{ => include}/netif/ppp/chap-md5.h | 0 src/{ => include}/netif/ppp/chap-new.h | 0 src/{ => include}/netif/ppp/chap_ms.h | 0 src/{ => include}/netif/ppp/eap.h | 0 src/{ => include}/netif/ppp/ecp.h | 0 src/{ => include}/netif/ppp/eui64.h | 0 src/{ => include}/netif/ppp/fsm.h | 0 src/{ => include}/netif/ppp/ipcp.h | 0 src/{ => include}/netif/ppp/ipv6cp.h | 0 src/{ => include}/netif/ppp/lcp.h | 0 src/{ => include}/netif/ppp/magic.h | 0 .../netif/ppp/polarssl/des.h} | 0 .../netif/ppp/polarssl/md4.h} | 0 .../netif/ppp/polarssl/md5.h} | 0 .../netif/ppp/polarssl/sha1.h} | 0 src/{ => include}/netif/ppp/ppp.h | 4 +-- src/{ => include}/netif/ppp/ppp_impl.h | 0 src/{ => include}/netif/ppp/pppcrypt.h | 0 src/{ => include}/netif/ppp/pppdebug.h | 0 src/include/netif/{ppp_oe.h => ppp/pppoe.h} | 2 +- src/include/netif/{ => ppp}/pppol2tp.h | 0 src/{ => include}/netif/ppp/upap.h | 0 src/{ => include}/netif/ppp/vj.h | 0 src/netif/etharp.c | 2 +- src/netif/ethernetif.c | 2 +- src/netif/ppp/auth.c | 20 ++++++------- src/netif/ppp/ccp.c | 10 +++---- src/netif/ppp/chap-md5.c | 10 +++---- src/netif/ppp/chap-new.c | 8 +++--- src/netif/ppp/chap_ms.c | 20 ++++++------- src/netif/ppp/demand.c | 8 +++--- src/netif/ppp/eap.c | 8 +++--- src/netif/ppp/ecp.c | 6 ++-- src/netif/ppp/eui64.c | 4 +-- src/netif/ppp/fsm.c | 4 +-- src/netif/ppp/ipcp.c | 6 ++-- src/netif/ppp/ipv6cp.c | 10 +++---- src/netif/ppp/lcp.c | 10 +++---- src/netif/ppp/magic.c | 6 ++-- src/netif/ppp/multilink.c | 8 +++--- src/netif/ppp/polarssl/{lwip_des.c => des.c} | 2 +- src/netif/ppp/polarssl/{lwip_md4.c => md4.c} | 2 +- src/netif/ppp/polarssl/{lwip_md5.c => md5.c} | 2 +- .../ppp/polarssl/{lwip_sha1.c => sha1.c} | 2 +- src/netif/ppp/ppp.c | 28 +++++++++---------- src/netif/ppp/pppcrypt.c | 4 +-- src/netif/ppp/{ppp_oe.c => pppoe.c} | 6 ++-- src/netif/ppp/pppol2tp.c | 8 +++--- src/netif/ppp/upap.c | 4 +-- src/netif/ppp/utils.c | 6 ++-- src/netif/ppp/vj.c | 6 ++-- 56 files changed, 115 insertions(+), 114 deletions(-) rename src/{ => include}/netif/ppp/ccp.h (100%) rename src/{ => include}/netif/ppp/chap-md5.h (100%) rename src/{ => include}/netif/ppp/chap-new.h (100%) rename src/{ => include}/netif/ppp/chap_ms.h (100%) rename src/{ => include}/netif/ppp/eap.h (100%) rename src/{ => include}/netif/ppp/ecp.h (100%) rename src/{ => include}/netif/ppp/eui64.h (100%) rename src/{ => include}/netif/ppp/fsm.h (100%) rename src/{ => include}/netif/ppp/ipcp.h (100%) rename src/{ => include}/netif/ppp/ipv6cp.h (100%) rename src/{ => include}/netif/ppp/lcp.h (100%) rename src/{ => include}/netif/ppp/magic.h (100%) rename src/{netif/ppp/polarssl/lwip_des.h => include/netif/ppp/polarssl/des.h} (100%) rename src/{netif/ppp/polarssl/lwip_md4.h => include/netif/ppp/polarssl/md4.h} (100%) rename src/{netif/ppp/polarssl/lwip_md5.h => include/netif/ppp/polarssl/md5.h} (100%) rename src/{netif/ppp/polarssl/lwip_sha1.h => include/netif/ppp/polarssl/sha1.h} (100%) rename src/{ => include}/netif/ppp/ppp.h (99%) rename src/{ => include}/netif/ppp/ppp_impl.h (100%) rename src/{ => include}/netif/ppp/pppcrypt.h (100%) rename src/{ => include}/netif/ppp/pppdebug.h (100%) rename src/include/netif/{ppp_oe.h => ppp/pppoe.h} (99%) rename src/include/netif/{ => ppp}/pppol2tp.h (100%) rename src/{ => include}/netif/ppp/upap.h (100%) rename src/{ => include}/netif/ppp/vj.h (100%) rename src/netif/ppp/polarssl/{lwip_des.c => des.c} (99%) rename src/netif/ppp/polarssl/{lwip_md4.c => md4.c} (99%) rename src/netif/ppp/polarssl/{lwip_md5.c => md5.c} (99%) rename src/netif/ppp/polarssl/{lwip_sha1.c => sha1.c} (99%) rename src/netif/ppp/{ppp_oe.c => pppoe.c} (99%) diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 44fb0989..72794f12 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -47,7 +47,7 @@ #include "lwip/tcpip.h" #include "lwip/init.h" #include "netif/etharp.h" -#include "netif/ppp_oe.h" +#include "netif/ppp/pppoe.h" /* global variables */ static tcpip_init_done_fn tcpip_init_done; diff --git a/src/core/init.c b/src/core/init.c index e3865698..0a9e287a 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -60,7 +60,7 @@ #include "lwip/nd6.h" #include "lwip/mld6.h" #include "lwip/api.h" -#include "ppp.h" +#include "netif/ppp/ppp.h" /* Compile-time sanity checks for configuration errors. * These can be done independently of LWIP_DEBUG, without penalty. diff --git a/src/core/memp.c b/src/core/memp.c index 9db9a5e5..4a55f8f2 100644 --- a/src/core/memp.c +++ b/src/core/memp.c @@ -57,8 +57,9 @@ #include "lwip/snmp_structs.h" #include "lwip/snmp_msg.h" #include "lwip/dns.h" -#include "netif/ppp_oe.h" -#include "netif/pppol2tp.h" +#include "netif/ppp/ppp.h" +#include "netif/ppp/pppoe.h" +#include "netif/ppp/pppol2tp.h" #include "lwip/nd6.h" #include "lwip/ip6_frag.h" #include "lwip/mld6.h" diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index ae1e001a..a4d5b356 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -33,7 +33,7 @@ #if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ #include "lwip/sys.h" -#include "ppp.h" +#include "netif/ppp/ppp.h" #ifdef __cplusplus extern "C" { diff --git a/src/netif/ppp/ccp.h b/src/include/netif/ppp/ccp.h similarity index 100% rename from src/netif/ppp/ccp.h rename to src/include/netif/ppp/ccp.h diff --git a/src/netif/ppp/chap-md5.h b/src/include/netif/ppp/chap-md5.h similarity index 100% rename from src/netif/ppp/chap-md5.h rename to src/include/netif/ppp/chap-md5.h diff --git a/src/netif/ppp/chap-new.h b/src/include/netif/ppp/chap-new.h similarity index 100% rename from src/netif/ppp/chap-new.h rename to src/include/netif/ppp/chap-new.h diff --git a/src/netif/ppp/chap_ms.h b/src/include/netif/ppp/chap_ms.h similarity index 100% rename from src/netif/ppp/chap_ms.h rename to src/include/netif/ppp/chap_ms.h diff --git a/src/netif/ppp/eap.h b/src/include/netif/ppp/eap.h similarity index 100% rename from src/netif/ppp/eap.h rename to src/include/netif/ppp/eap.h diff --git a/src/netif/ppp/ecp.h b/src/include/netif/ppp/ecp.h similarity index 100% rename from src/netif/ppp/ecp.h rename to src/include/netif/ppp/ecp.h diff --git a/src/netif/ppp/eui64.h b/src/include/netif/ppp/eui64.h similarity index 100% rename from src/netif/ppp/eui64.h rename to src/include/netif/ppp/eui64.h diff --git a/src/netif/ppp/fsm.h b/src/include/netif/ppp/fsm.h similarity index 100% rename from src/netif/ppp/fsm.h rename to src/include/netif/ppp/fsm.h diff --git a/src/netif/ppp/ipcp.h b/src/include/netif/ppp/ipcp.h similarity index 100% rename from src/netif/ppp/ipcp.h rename to src/include/netif/ppp/ipcp.h diff --git a/src/netif/ppp/ipv6cp.h b/src/include/netif/ppp/ipv6cp.h similarity index 100% rename from src/netif/ppp/ipv6cp.h rename to src/include/netif/ppp/ipv6cp.h diff --git a/src/netif/ppp/lcp.h b/src/include/netif/ppp/lcp.h similarity index 100% rename from src/netif/ppp/lcp.h rename to src/include/netif/ppp/lcp.h diff --git a/src/netif/ppp/magic.h b/src/include/netif/ppp/magic.h similarity index 100% rename from src/netif/ppp/magic.h rename to src/include/netif/ppp/magic.h diff --git a/src/netif/ppp/polarssl/lwip_des.h b/src/include/netif/ppp/polarssl/des.h similarity index 100% rename from src/netif/ppp/polarssl/lwip_des.h rename to src/include/netif/ppp/polarssl/des.h diff --git a/src/netif/ppp/polarssl/lwip_md4.h b/src/include/netif/ppp/polarssl/md4.h similarity index 100% rename from src/netif/ppp/polarssl/lwip_md4.h rename to src/include/netif/ppp/polarssl/md4.h diff --git a/src/netif/ppp/polarssl/lwip_md5.h b/src/include/netif/ppp/polarssl/md5.h similarity index 100% rename from src/netif/ppp/polarssl/lwip_md5.h rename to src/include/netif/ppp/polarssl/md5.h diff --git a/src/netif/ppp/polarssl/lwip_sha1.h b/src/include/netif/ppp/polarssl/sha1.h similarity index 100% rename from src/netif/ppp/polarssl/lwip_sha1.h rename to src/include/netif/ppp/polarssl/sha1.h diff --git a/src/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h similarity index 99% rename from src/netif/ppp/ppp.h rename to src/include/netif/ppp/ppp.h index 0f41ee45..1bbf4a7e 100644 --- a/src/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -145,10 +145,10 @@ typedef struct ppp_pcb_s ppp_pcb; #endif /* EAP_SUPPORT */ #if PPPOE_SUPPORT -#include "netif/ppp_oe.h" +#include "netif/ppp/pppoe.h" #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT -#include "netif/pppol2tp.h" +#include "netif/ppp/pppol2tp.h" #endif /* PPPOL2TP_SUPPORT */ /* diff --git a/src/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h similarity index 100% rename from src/netif/ppp/ppp_impl.h rename to src/include/netif/ppp/ppp_impl.h diff --git a/src/netif/ppp/pppcrypt.h b/src/include/netif/ppp/pppcrypt.h similarity index 100% rename from src/netif/ppp/pppcrypt.h rename to src/include/netif/ppp/pppcrypt.h diff --git a/src/netif/ppp/pppdebug.h b/src/include/netif/ppp/pppdebug.h similarity index 100% rename from src/netif/ppp/pppdebug.h rename to src/include/netif/ppp/pppdebug.h diff --git a/src/include/netif/ppp_oe.h b/src/include/netif/ppp/pppoe.h similarity index 99% rename from src/include/netif/ppp_oe.h rename to src/include/netif/ppp/pppoe.h index 02006f33..8385d9af 100644 --- a/src/include/netif/ppp_oe.h +++ b/src/include/netif/ppp/pppoe.h @@ -1,5 +1,5 @@ /***************************************************************************** -* ppp_oe.h - PPP Over Ethernet implementation for lwIP. +* pppoe.h - PPP Over Ethernet implementation for lwIP. * * Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. * diff --git a/src/include/netif/pppol2tp.h b/src/include/netif/ppp/pppol2tp.h similarity index 100% rename from src/include/netif/pppol2tp.h rename to src/include/netif/ppp/pppol2tp.h diff --git a/src/netif/ppp/upap.h b/src/include/netif/ppp/upap.h similarity index 100% rename from src/netif/ppp/upap.h rename to src/include/netif/ppp/upap.h diff --git a/src/netif/ppp/vj.h b/src/include/netif/ppp/vj.h similarity index 100% rename from src/netif/ppp/vj.h rename to src/include/netif/ppp/vj.h diff --git a/src/netif/etharp.c b/src/netif/etharp.c index 1b7eb988..dd29ca46 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -58,7 +58,7 @@ #include "lwip/ip6.h" #if PPPOE_SUPPORT -#include "netif/ppp_oe.h" +#include "netif/ppp/pppoe.h" #endif /* PPPOE_SUPPORT */ #include diff --git a/src/netif/ethernetif.c b/src/netif/ethernetif.c index 46900bdb..ad4d2dcb 100644 --- a/src/netif/ethernetif.c +++ b/src/netif/ethernetif.c @@ -54,7 +54,7 @@ #include "lwip/snmp.h" #include "lwip/ethip6.h" #include "netif/etharp.h" -#include "netif/ppp_oe.h" +#include "netif/ppp/pppoe.h" /* Define those to better describe your network interface. */ #define IFNAME0 'e' diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 9cc62a5d..e150ff6b 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -103,28 +103,28 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "lcp.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" #if CCP_SUPPORT -#include "ccp.h" +#include "netif/ppp/ccp.h" #endif /* CCP_SUPPORT */ #if ECP_SUPPORT -#include "ecp.h" +#include "netif/ppp/ecp.h" #endif /* ECP_SUPPORT */ -#include "ipcp.h" +#include "netif/ppp/ipcp.h" #if PAP_SUPPORT -#include "upap.h" +#include "netif/ppp/upap.h" #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT -#include "chap-new.h" +#include "netif/ppp/chap-new.h" #endif /* CHAP_SUPPORT */ #if EAP_SUPPORT -#include "eap.h" +#include "netif/ppp/eap.h" #endif /* EAP_SUPPORT */ #if CBCP_SUPPORT -#include "cbcp.h" +#include "netif/ppp/cbcp.h" #endif #if 0 /* UNUSED */ diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index de1ad4e8..2117fcab 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -34,15 +34,15 @@ #include #include -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "ccp.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/ccp.h" #include #ifdef MPPE -#include "chap_ms.h" /* mppe_xxxx_key, mppe_keys_set */ -#include "lcp.h" /* lcp_close(), lcp_fsm */ +#include "netif/ppp/chap_ms.h" /* mppe_xxxx_key, mppe_keys_set */ +#include "netif/ppp/lcp.h" /* lcp_close(), lcp_fsm */ #endif /* diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 9239723f..5e0fc714 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -36,14 +36,14 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "chap-new.h" -#include "chap-md5.h" -#include "magic.h" +#include "netif/ppp/chap-new.h" +#include "netif/ppp/chap-md5.h" +#include "netif/ppp/magic.h" #if LWIP_INCLUDED_POLARSSL_MD5 -#include "polarssl/lwip_md5.h" +#include "netif/ppp/polarssl/md5.h" #else #include "polarssl/md5.h" #endif diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index f98719e4..242c9163 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -36,16 +36,16 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" #if 0 /* UNUSED */ #include "session.h" #endif /* UNUSED */ -#include "chap-new.h" -#include "chap-md5.h" +#include "netif/ppp/chap-new.h" +#include "netif/ppp/chap-md5.h" #if MSCHAP_SUPPORT -#include "chap_ms.h" +#include "netif/ppp/chap_ms.h" #endif /* Hook for a plugin to validate CHAP challenge */ diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 64762dbc..be5331c1 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -87,27 +87,27 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "chap-new.h" -#include "chap_ms.h" -#include "pppcrypt.h" -#include "magic.h" +#include "netif/ppp/chap-new.h" +#include "netif/ppp/chap_ms.h" +#include "netif/ppp/pppcrypt.h" +#include "netif/ppp/magic.h" #if LWIP_INCLUDED_POLARSSL_MD4 -#include "polarssl/lwip_md4.h" +#include "netif/ppp/polarssl/md4.h" #else #include "polarssl/md4.h" #endif #if LWIP_INCLUDED_POLARSSL_SHA1 -#include "polarssl/lwip_sha1.h" +#include "netif/ppp/polarssl/sha1.h" #else #include "polarssl/sha1.h" #endif #if LWIP_INCLUDED_POLARSSL_DES -#include "polarssl/lwip_des.h" +#include "netif/ppp/polarssl/des.h" #else #include "polarssl/des.h" #endif @@ -150,8 +150,8 @@ static char *mschap_challenge = NULL; static char *mschap2_peer_challenge = NULL; #endif -#include "fsm.h" /* Need to poke MPPE options */ -#include "ccp.h" +#include "netif/ppp/fsm.h" /* Need to poke MPPE options */ +#include "netif/ppp/ccp.h" #include #endif diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index 81d307ec..dbabfa90 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -52,11 +52,11 @@ #include #endif -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "ipcp.h" -#include "lcp.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/ipcp.h" +#include "netif/ppp/lcp.h" char *frame; int framelen; diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index dca92d3c..f213d778 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -46,21 +46,21 @@ #include "lwip/opt.h" #if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" #if LWIP_INCLUDED_POLARSSL_MD5 -#include "polarssl/lwip_md5.h" +#include "netif/ppp/polarssl/md5.h" #else #include "polarssl/md5.h" #endif -#include "eap.h" +#include "netif/ppp/eap.h" #ifdef USE_SRP #include #include #include -#include "pppcrypt.h" +#include "netif/ppp/pppcrypt.h" #endif /* USE_SRP */ #ifndef SHA_DIGESTSIZE diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index 4c469b9a..f2645055 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -62,10 +62,10 @@ #include -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "ecp.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/ecp.h" #if PPP_OPTIONS static option_t ecp_option_list[] = { diff --git a/src/netif/ppp/eui64.c b/src/netif/ppp/eui64.c index aeeaa1a3..e23a34e8 100644 --- a/src/netif/ppp/eui64.c +++ b/src/netif/ppp/eui64.c @@ -38,8 +38,8 @@ #include "lwip/opt.h" #if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp_impl.h" -#include "eui64.h" +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/eui64.h" /* * eui64_ntoa - Make an ascii representation of an interface identifier diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 60daf6ee..4c3cf53a 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -55,9 +55,9 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" +#include "netif/ppp/fsm.h" static void fsm_timeout (void *); static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len); diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index 1f1e249a..b7300f3c 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -59,10 +59,10 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "ipcp.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/ipcp.h" #if 0 /* UNUSED */ /* global vars */ diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c index cfccb7f4..14b83f90 100644 --- a/src/netif/ppp/ipv6cp.c +++ b/src/netif/ppp/ipv6cp.c @@ -163,11 +163,11 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" -#include "fsm.h" -#include "ipcp.h" -#include "ipv6cp.h" -#include "magic.h" +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/ipcp.h" +#include "netif/ppp/ipv6cp.h" +#include "netif/ppp/magic.h" /* global vars */ #if 0 /* UNUSED */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index cf5bbef5..01a889d0 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -53,14 +53,14 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "lcp.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" #if CHAP_SUPPORT -#include "chap-new.h" +#include "netif/ppp/chap-new.h" #endif /* CHAP_SUPPORT */ -#include "magic.h" +#include "netif/ppp/magic.h" /* * When the link comes up we want to be able to wait for a short while, diff --git a/src/netif/ppp/magic.c b/src/netif/ppp/magic.c index fd5b159c..86aef275 100644 --- a/src/netif/ppp/magic.c +++ b/src/netif/ppp/magic.c @@ -75,13 +75,13 @@ #include "lwip/opt.h" #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp_impl.h" -#include "magic.h" +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/magic.h" #if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */ #if LWIP_INCLUDED_POLARSSL_MD5 -#include "polarssl/lwip_md5.h" +#include "netif/ppp/polarssl/md5.h" #else #include "polarssl/md5.h" #endif diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index bb36fbd2..883ecd00 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -49,11 +49,11 @@ #include #include -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "lcp.h" -#include "tdb.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" +#include "netif/ppp/tdb.h" bool endpoint_specified; /* user gave explicit endpoint discriminator */ char *bundle_id; /* identifier for our bundle */ diff --git a/src/netif/ppp/polarssl/lwip_des.c b/src/netif/ppp/polarssl/des.c similarity index 99% rename from src/netif/ppp/polarssl/lwip_des.c rename to src/netif/ppp/polarssl/des.c index 07c00513..e6a7a0dd 100644 --- a/src/netif/ppp/polarssl/lwip_des.c +++ b/src/netif/ppp/polarssl/des.c @@ -42,7 +42,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_DES -#include "lwip_des.h" +#include "netif/ppp/polarssl/des.h" /* * 32-bit integer manipulation macros (big endian) diff --git a/src/netif/ppp/polarssl/lwip_md4.c b/src/netif/ppp/polarssl/md4.c similarity index 99% rename from src/netif/ppp/polarssl/lwip_md4.c rename to src/netif/ppp/polarssl/md4.c index b654542e..aea6ed8f 100644 --- a/src/netif/ppp/polarssl/lwip_md4.c +++ b/src/netif/ppp/polarssl/md4.c @@ -42,7 +42,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_MD4 -#include "lwip_md4.h" +#include "netif/ppp/polarssl/md4.h" /* * 32-bit integer manipulation macros (little endian) diff --git a/src/netif/ppp/polarssl/lwip_md5.c b/src/netif/ppp/polarssl/md5.c similarity index 99% rename from src/netif/ppp/polarssl/lwip_md5.c rename to src/netif/ppp/polarssl/md5.c index 38ad9d41..c5e08a0d 100644 --- a/src/netif/ppp/polarssl/lwip_md5.c +++ b/src/netif/ppp/polarssl/md5.c @@ -41,7 +41,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_MD5 -#include "lwip_md5.h" +#include "netif/ppp/polarssl/md5.h" /* * 32-bit integer manipulation macros (little endian) diff --git a/src/netif/ppp/polarssl/lwip_sha1.c b/src/netif/ppp/polarssl/sha1.c similarity index 99% rename from src/netif/ppp/polarssl/lwip_sha1.c rename to src/netif/ppp/polarssl/sha1.c index 2d62fdfe..f71ec416 100644 --- a/src/netif/ppp/polarssl/lwip_sha1.c +++ b/src/netif/ppp/polarssl/sha1.c @@ -41,7 +41,7 @@ #include "lwip/opt.h" #if LWIP_INCLUDED_POLARSSL_SHA1 -#include "lwip_sha1.h" +#include "netif/ppp/polarssl/sha1.h" /* * 32-bit integer manipulation macros (big endian) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index bb5ad627..c7725658 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -92,40 +92,40 @@ #include "lwip/sys.h" #include "lwip/ip.h" /* for ip_input() */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "magic.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" +#include "netif/ppp/ipcp.h" +#include "netif/ppp/magic.h" #if PAP_SUPPORT -#include "upap.h" +#include "netif/ppp/upap.h" #endif /* PAP_SUPPORT */ #if CHAP_SUPPORT -#include "chap-new.h" +#include "netif/ppp/chap-new.h" #endif /* CHAP_SUPPORT */ #if EAP_SUPPORT -#include "eap.h" +#include "netif/ppp/eap.h" #endif /* EAP_SUPPORT */ #if CCP_SUPPORT -#include "ccp.h" +#include "netif/ppp/ccp.h" #endif /* EAP_SUPPORT */ #if ECP_SUPPORT -#include "ecp.h" +#include "netif/ppp/ecp.h" #endif /* EAP_SUPPORT */ #if VJ_SUPPORT -#include "vj.h" +#include "netif/ppp/vj.h" #endif /* VJ_SUPPORT */ #if PPP_IPV6_SUPPORT -#include "ipv6cp.h" +#include "netif/ppp/ipv6cp.h" #endif /* PPP_IPV6_SUPPORT */ #if PPPOE_SUPPORT -#include "netif/ppp_oe.h" +#include "netif/ppp/pppoe.h" #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT -#include "netif/pppol2tp.h" +#include "netif/ppp/pppol2tp.h" #endif /* PPPOL2TP_SUPPORT */ /* Global variables */ diff --git a/src/netif/ppp/pppcrypt.c b/src/netif/ppp/pppcrypt.c index dd6963e8..097f702b 100644 --- a/src/netif/ppp/pppcrypt.c +++ b/src/netif/ppp/pppcrypt.c @@ -33,9 +33,9 @@ #include "lwip/opt.h" #if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "pppcrypt.h" +#include "netif/ppp/pppcrypt.h" static u_char pppcrypt_get_7bits(u_char *input, int startBit) { diff --git a/src/netif/ppp/ppp_oe.c b/src/netif/ppp/pppoe.c similarity index 99% rename from src/netif/ppp/ppp_oe.c rename to src/netif/ppp/pppoe.c index 84a47aeb..65dd39df 100644 --- a/src/netif/ppp/ppp_oe.c +++ b/src/netif/ppp/pppoe.c @@ -1,5 +1,5 @@ /***************************************************************************** -* ppp_oe.c - PPP Over Ethernet implementation for lwIP. +* pppoe.c - PPP Over Ethernet implementation for lwIP. * * Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. * @@ -80,8 +80,8 @@ #include "lwip/memp.h" #include "lwip/stats.h" -#include "ppp_impl.h" -#include "netif/ppp_oe.h" +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/pppoe.h" /* Add a 16 bit unsigned value to a buffer pointed to by PTR */ #define PPPOE_ADD_16(PTR, VAL) \ diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index aa595a82..3a8eb7d8 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -58,14 +58,14 @@ #include "lwip/netif.h" #include "lwip/udp.h" -#include "ppp_impl.h" -#include "netif/pppol2tp.h" +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/pppol2tp.h" -#include "magic.h" +#include "netif/ppp/magic.h" #if PPPOL2TP_AUTH_SUPPORT #if LWIP_INCLUDED_POLARSSL_MD5 -#include "polarssl/lwip_md5.h" +#include "netif/ppp/polarssl/md5.h" #else #include "polarssl/md5.h" #endif diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index eb55ec11..8f3a44c9 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -52,9 +52,9 @@ #include #endif /* UNUSED */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "upap.h" +#include "netif/ppp/upap.h" #if PPP_OPTIONS /* diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 074f8e94..833a5a76 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -60,10 +60,10 @@ #include /* isdigit() */ -#include "ppp_impl.h" +#include "netif/ppp/ppp_impl.h" -#include "fsm.h" -#include "lcp.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" #if defined(SUNOS4) extern char *strerror(); diff --git a/src/netif/ppp/vj.c b/src/netif/ppp/vj.c index 79752512..792e16c9 100644 --- a/src/netif/ppp/vj.c +++ b/src/netif/ppp/vj.c @@ -31,10 +31,10 @@ #include "lwip/opt.h" #if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp_impl.h" -#include "pppdebug.h" +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/pppdebug.h" -#include "vj.h" +#include "netif/ppp/vj.h" #include From 98c0fcc6599e8bdbeeb96556bd317e902f0de98d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 18 Aug 2012 22:43:23 +0200 Subject: [PATCH 262/320] Added header to ppp_impl.h, this appears to be required, found out by Ivan Delamer. --- src/include/netif/ppp/ppp_impl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h index 8b82f314..0c34c90e 100644 --- a/src/include/netif/ppp/ppp_impl.h +++ b/src/include/netif/ppp/ppp_impl.h @@ -39,6 +39,7 @@ #include /* formats */ #include +#include #include "lwip/netif.h" #include "lwip/def.h" From 0d02b8d1f65b62ca1cfd7054d8c795383cbd1110 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 21 Aug 2012 20:03:57 +0200 Subject: [PATCH 263/320] added to ppp_impl.h, some PPP modules are using strtol() --- src/include/netif/ppp/ppp_impl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h index 0c34c90e..8c69aa6d 100644 --- a/src/include/netif/ppp/ppp_impl.h +++ b/src/include/netif/ppp/ppp_impl.h @@ -40,6 +40,7 @@ #include /* formats */ #include #include +#include /* strtol() */ #include "lwip/netif.h" #include "lwip/def.h" From e9b29184d0a81d11f5232719024cfb5e126a78c8 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 21 Aug 2012 20:21:38 +0200 Subject: [PATCH 264/320] PPP, renamed all functions using common names in utils.c that can conflict with lwIP user code during link operation --- src/include/netif/ppp/ppp_impl.h | 26 +++--- src/netif/ppp/auth.c | 60 ++++++------- src/netif/ppp/chap-new.c | 32 +++---- src/netif/ppp/chap_ms.c | 10 +-- src/netif/ppp/eap.c | 140 +++++++++++++++--------------- src/netif/ppp/fsm.c | 14 +-- src/netif/ppp/ipcp.c | 34 ++++---- src/netif/ppp/ipv6cp.c | 18 ++-- src/netif/ppp/lcp.c | 32 +++---- src/netif/ppp/ppp.c | 12 +-- src/netif/ppp/upap.c | 14 +-- src/netif/ppp/utils.c | 144 +++++++++++++++---------------- 12 files changed, 268 insertions(+), 268 deletions(-) diff --git a/src/include/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h index 8c69aa6d..61ed84c1 100644 --- a/src/include/netif/ppp/ppp_impl.h +++ b/src/include/netif/ppp/ppp_impl.h @@ -491,7 +491,7 @@ void update_link_stats(int u); /* Get stats at link termination */ #define BZERO(s, n) memset(s, 0, n) #define BCMP(s1, s2, l) memcmp(s1, s2, l) -#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); } +#define PRINTMSG(m, l) { ppp_info("Remote message: %0.*v", l, m); } /* * MAKEHEADER - Add Header fields to a packet. @@ -556,19 +556,19 @@ int str_to_epdisc (struct epdisc *, char *); /* endpt disc. from str */ #endif /* Procedures exported from utils.c. */ -void print_string(char *p, int len, void (*printer) (void *, char *, ...), void *arg); /* Format a string for output */ -int slprintf(char *buf, int buflen, char *fmt, ...); /* sprintf++ */ -int vslprintf(char *buf, int buflen, char *fmt, va_list args); /* vsprintf++ */ -size_t strlcpy(char *dest, const char *src, size_t len); /* safe strcpy */ -size_t strlcat(char *dest, const char *src, size_t len); /* safe strncpy */ -void dbglog(char *fmt, ...); /* log a debug message */ -void info(char *fmt, ...); /* log an informational message */ -void notice(char *fmt, ...); /* log a notice-level message */ -void warn(char *fmt, ...); /* log a warning message */ -void error(char *fmt, ...); /* log an error message */ -void fatal(char *fmt, ...); /* log an error message and die(1) */ +void ppp_print_string(char *p, int len, void (*printer) (void *, char *, ...), void *arg); /* Format a string for output */ +int ppp_slprintf(char *buf, int buflen, char *fmt, ...); /* sprintf++ */ +int ppp_vslprintf(char *buf, int buflen, char *fmt, va_list args); /* vsprintf++ */ +size_t ppp_strlcpy(char *dest, const char *src, size_t len); /* safe strcpy */ +size_t ppp_strlcat(char *dest, const char *src, size_t len); /* safe strncpy */ +void ppp_dbglog(char *fmt, ...); /* log a debug message */ +void ppp_info(char *fmt, ...); /* log an informational message */ +void ppp_notice(char *fmt, ...); /* log a notice-level message */ +void ppp_warn(char *fmt, ...); /* log a warning message */ +void ppp_error(char *fmt, ...); /* log an error message */ +void ppp_fatal(char *fmt, ...); /* log an error message and die(1) */ #if PRINTPKT_SUPPORT -void dump_packet(const char *tag, unsigned char *p, int len); +void ppp_dump_packet(const char *tag, unsigned char *p, int len); /* dump packet to debug log if interesting */ #endif /* PRINTPKT_SUPPORT */ diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index e150ff6b..ec41bd99 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -590,9 +590,9 @@ void start_link(unit) * incoming events (reply, timeout, etc.). */ if (ifunit >= 0) - notice("Connect: %s <--> %s", ifname, ppp_devnam); + ppp_notice("Connect: %s <--> %s", ifname, ppp_devnam); else - notice("Starting negotiation on %s", ppp_devnam); + ppp_notice("Starting negotiation on %s", ppp_devnam); add_fd(fd_ppp); new_phase(pcb, PHASE_ESTABLISH); @@ -629,12 +629,12 @@ void link_terminated(ppp_pcb *pcb) { #endif /* UNUSED */ if (!doing_multilink) { - notice("Connection terminated."); + ppp_notice("Connection terminated."); #if PPP_STATS_SUPPORT print_link_stats(); #endif /* PPP_STATS_SUPPORT */ } else - notice("Link terminated."); + ppp_notice("Link terminated."); lcp_lowerdown(pcb); @@ -780,7 +780,7 @@ void link_established(ppp_pcb *pcb) { } else #endif /* PPP_ALLOWED_ADDRS */ if (!wo->neg_upap || uselogin || !null_login(unit)) { - warn("peer refused to authenticate: terminating link"); + ppp_warn("peer refused to authenticate: terminating link"); status = EXIT_PEER_AUTH_FAILED; lcp_close(pcb, "peer refused to authenticate"); return; @@ -854,7 +854,7 @@ static void network_phase(ppp_pcb *pcb) { #if 0 /* UNUSED */ /* Log calling number. */ if (*remote_number) - notice("peer from calling number %q authorized", remote_number); + ppp_notice("peer from calling number %q authorized", remote_number); #endif /* UNUSED */ #if PPP_NOTIFY @@ -1040,7 +1040,7 @@ void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, char *name, break; #endif /* EAP_SUPPORT */ default: - warn("auth_peer_success: unknown protocol %x", protocol); + ppp_warn("auth_peer_success: unknown protocol %x", protocol); return; } @@ -1127,12 +1127,12 @@ void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { break; #endif /* EAP_SUPPORT */ default: - warn("auth_withpeer_success: unknown protocol %x", protocol); + ppp_warn("auth_withpeer_success: unknown protocol %x", protocol); bit = 0; /* no break */ } - notice("%s authentication succeeded", prot); + ppp_notice("%s authentication succeeded", prot); /* Save the authentication method for later. */ pcb->auth_done |= bit; @@ -1251,7 +1251,7 @@ check_maxoctets(arg) break; } if (used > maxoctets) { - notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); + ppp_notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); status = EXIT_TRAFFIC_LIMIT; lcp_close(pcb, "Traffic limit"); #if 0 /* UNUSED */ @@ -1290,7 +1290,7 @@ static void check_idle(void *arg) { if (tlim <= 0) { int errcode = PPPERR_IDLETIMEOUT; /* link is idle: shut it down. */ - notice("Terminating connection due to lack of activity."); + ppp_notice("Terminating connection due to lack of activity."); ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(pcb, "Link inactive"); #if 0 /* UNUSED */ @@ -1309,7 +1309,7 @@ static void check_idle(void *arg) { static void connect_time_expired(void *arg) { int errcode = PPPERR_CONNECTTIME; ppp_pcb *pcb = (ppp_pcb*)arg; - info("Connect time expired"); + ppp_info("Connect time expired"); ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(pcb, "Connect time expired"); /* Close connection */ } @@ -1448,7 +1448,7 @@ auth_check_options() * Early check for remote number authorization. */ if (!auth_number()) { - warn("calling number %q is not authorized", remote_number); + ppp_warn("calling number %q is not authorized", remote_number); exit(EXIT_CNID_AUTH_FAILED); } } @@ -1633,12 +1633,12 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) ret = UPAP_AUTHNAK; f = fopen(filename, "r"); if (f == NULL) { - error("Can't open PAP password file %s: %m", filename); + ppp_error("Can't open PAP password file %s: %m", filename); } else { check_access(f, filename); if (scan_authfile(f, ppp_settings.user, our_name, secret, &addrs, &opts, filename, 0) < 0) { - warn("no PAP secret found for %s", user); + ppp_warn("no PAP secret found for %s", user); } else { /* * If the secret is "@login", it means to check @@ -1653,7 +1653,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) } } else if (session_mgmt) { if (session_check(ppp_settings.user, NULL, devnam, NULL) == 0) { - warn("Peer %q failed PAP Session verification", user); + ppp_warn("Peer %q failed PAP Session verification", user); ret = UPAP_AUTHNAK; } } @@ -1677,7 +1677,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) * On 10'th, drop the connection. */ if (attempts++ >= 10) { - warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); + ppp_warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); lcp_close(pcb, "login failed"); } if (attempts > 3) @@ -1936,7 +1936,7 @@ int get_secret(ppp_pcb *pcb, char *client, char *server, char *secret, int *secr len = (int)strlen(pcb->settings.passwd); if (len > MAXSECRETLEN) { - error("Secret for %s on %s is too long", client, server); + ppp_error("Secret for %s on %s is too long", client, server); len = MAXSECRETLEN; } @@ -1968,7 +1968,7 @@ int get_secret(ppp_pcb *pcb, char *client, char *server, char *secret, int *secr strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf)); } else if (!am_server && chap_passwd_hook) { if ( (*chap_passwd_hook)(client, secbuf) < 0) { - error("Unable to obtain CHAP password for %s on %s from plugin", + ppp_error("Unable to obtain CHAP password for %s on %s from plugin", client, server); return 0; } @@ -1979,7 +1979,7 @@ int get_secret(ppp_pcb *pcb, char *client, char *server, char *secret, int *secr f = fopen(filename, "r"); if (f == NULL) { - error("Can't open chap secret file %s: %m", filename); + ppp_error("Can't open chap secret file %s: %m", filename); return 0; } check_access(f, filename); @@ -1999,7 +1999,7 @@ int get_secret(ppp_pcb *pcb, char *client, char *server, char *secret, int *secr len = strlen(secbuf); if (len > MAXSECRETLEN) { - error("Secret for %s on %s is too long", client, server); + ppp_error("Secret for %s on %s is too long", client, server); len = MAXSECRETLEN; } MEMCPY(secret, secbuf, len); @@ -2038,7 +2038,7 @@ get_srp_secret(unit, client, server, secret, am_server) fp = fopen(filename, "r"); if (fp == NULL) { - error("Can't open srp secret file %s: %m", filename); + ppp_error("Can't open srp secret file %s: %m", filename); return 0; } check_access(fp, filename); @@ -2132,7 +2132,7 @@ set_allowed_addrs(unit, addrs, opts) 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", + ppp_warn("invalid address length %v in auth. address list", ptr_mask+1); continue; } @@ -2142,7 +2142,7 @@ set_allowed_addrs(unit, addrs, opts) ++endp; } if (*endp != 0) { - warn("invalid address length syntax: %v", ptr_mask+1); + ppp_warn("invalid address length syntax: %v", ptr_mask+1); continue; } *ptr_mask = '\0'; @@ -2175,12 +2175,12 @@ set_allowed_addrs(unit, addrs, opts) *ptr_mask = '/'; if (a == (u32_t)-1L) { - warn("unknown host %s in auth. address list", ap->word); + ppp_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", + ppp_warn("interface unit %d too large for subnet %v", ifunit, ptr_word); continue; } @@ -2329,9 +2329,9 @@ check_access(f, filename) struct stat sbuf; if (fstat(fileno(f), &sbuf) < 0) { - warn("cannot stat secret file %s: %m", filename); + ppp_warn("cannot stat secret file %s: %m", filename); } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - warn("Warning - secret file %s has world and/or group access", + ppp_warn("Warning - secret file %s has world and/or group access", filename); } } @@ -2442,12 +2442,12 @@ scan_authfile(f, client, server, secret, addrs, opts, filename, flags) if (word[0] == '@' && word[1] == '/') { strlcpy(atfile, word+1, sizeof(atfile)); if ((sf = fopen(atfile, "r")) == NULL) { - warn("can't open indirect secret file %s", atfile); + ppp_warn("can't open indirect secret file %s", atfile); continue; } check_access(sf, atfile); if (!getword(sf, word, &xxx, atfile)) { - warn("no secret in indirect secret file %s", atfile); + ppp_warn("no secret in indirect secret file %s", atfile); fclose(sf); continue; } diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 242c9163..d462d856 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -172,14 +172,14 @@ void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code) { struct chap_digest_type *dp; if (pcb->chap_server.flags & AUTH_STARTED) { - error("CHAP: peer authentication already started!"); + ppp_error("CHAP: peer authentication already started!"); return; } for (dp = chap_digests; dp != NULL; dp = dp->next) if (dp->code == digest_code) break; if (dp == NULL) - fatal("CHAP digest 0x%x requested but not available", + ppp_fatal("CHAP digest 0x%x requested but not available", digest_code); pcb->chap_server.digest = dp; @@ -203,14 +203,14 @@ void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code) { return; if (pcb->chap_client.flags & AUTH_STARTED) { - error("CHAP: authentication with peer already started!"); + ppp_error("CHAP: authentication with peer already started!"); return; } for (dp = chap_digests; dp != NULL; dp = dp->next) if (dp->code == digest_code) break; if (dp == NULL) - fatal("CHAP digest 0x%x requested but not available", + ppp_fatal("CHAP digest 0x%x requested but not available", digest_code); pcb->chap_client.digest = dp; @@ -310,7 +310,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, name = remote_name; } else { /* Null terminate and clean remote name. */ - slprintf(rname, sizeof(rname), "%.*v", len, name); + ppp_slprintf(rname, sizeof(rname), "%.*v", len, name); name = rname; } @@ -326,7 +326,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, #endif /* UNUSED */ if (!ok) { pcb->chap_server.flags |= AUTH_FAILED; - warn("Peer %q failed CHAP authentication", name); + ppp_warn("Peer %q failed CHAP authentication", name); } } else if ((pcb->chap_server.flags & AUTH_DONE) == 0) return; @@ -366,7 +366,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, if (session_mgmt && session_check(name, NULL, devnam, NULL) == 0) { pcb->chap_server.flags |= AUTH_FAILED; - warn("Peer %q failed CHAP Session verification", name); + ppp_warn("Peer %q failed CHAP Session verification", name); } #endif /* UNUSED */ @@ -403,7 +403,7 @@ static int chap_verify_response(char *name, char *ourname, int id, /* Get the secret that the peer is supposed to know */ if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) { - error("No CHAP secret found for authenticating %q", name); + ppp_error("No CHAP secret found for authenticating %q", name); return 0; } @@ -439,7 +439,7 @@ static void chap_respond(ppp_pcb *pcb, int id, nlen = len - (clen + 1); /* Null terminate and clean remote name. */ - slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); + ppp_slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); #if PPP_REMOTENAME /* Microsoft doesn't send their name back in the PPP packet */ @@ -450,7 +450,7 @@ static void chap_respond(ppp_pcb *pcb, int id, /* get secret for authenticating ourselves with the specified host */ if (!get_secret(pcb, pcb->chap_client.name, rname, 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", rname); + ppp_warn("No CHAP secret found for authenticating us to %q", rname); } outp = p->payload; @@ -500,15 +500,15 @@ static void chap_handle_status(ppp_pcb *pcb, int code, int id, } if (msg) { if (len > 0) - info("%s: %.*v", msg, len, pkt); + ppp_info("%s: %.*v", msg, len, pkt); else - info("%s", msg); + ppp_info("%s", msg); } if (code == CHAP_SUCCESS) auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code); else { pcb->chap_client.flags |= AUTH_FAILED; - error("CHAP authentication failed"); + ppp_error("CHAP authentication failed"); auth_withpeer_fail(pcb, PPP_CHAP); } } @@ -556,7 +556,7 @@ static void chap_protrej(ppp_pcb *pcb) { #endif /* PPP_SERVER */ if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { pcb->chap_client.flags &= ~AUTH_STARTED; - error("CHAP authentication failed due to protocol-reject"); + ppp_error("CHAP authentication failed due to protocol-reject"); auth_withpeer_fail(pcb, PPP_CHAP); } } @@ -605,12 +605,12 @@ static int chap_print_pkt(unsigned char *p, int plen, printer(arg, "%.2x", x); } printer(arg, ">, name = "); - print_string((char *)p, nlen, printer, arg); + ppp_print_string((char *)p, nlen, printer, arg); break; case CHAP_FAILURE: case CHAP_SUCCESS: printer(arg, " "); - print_string((char *)p, len, printer, arg); + ppp_print_string((char *)p, len, printer, arg); break; default: for (clen = len; clen > 0; --clen) { diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index be5331c1..cbbcf53c 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -350,7 +350,7 @@ static int chapms2_check_success(unsigned char *msg, int len, unsigned char *pri if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || strncmp((char *)msg, "S=", 2) != 0) { /* Packet does not start with "S=" */ - error("MS-CHAPv2 Success packet is badly formed."); + ppp_error("MS-CHAPv2 Success packet is badly formed."); return 0; } msg += 2; @@ -358,7 +358,7 @@ static int chapms2_check_success(unsigned char *msg, int len, unsigned char *pri if (len < MS_AUTH_RESPONSE_LENGTH || memcmp(msg, private, MS_AUTH_RESPONSE_LENGTH)) { /* Authenticator Response did not match expected. */ - error("MS-CHAPv2 mutual authentication failed."); + ppp_error("MS-CHAPv2 mutual authentication failed."); return 0; } /* Authenticator Response matches. */ @@ -368,7 +368,7 @@ static int chapms2_check_success(unsigned char *msg, int len, unsigned char *pri msg += 3; /* Eat the delimiter */ } else if (len) { /* Packet has extra text which does not begin " M=" */ - error("MS-CHAPv2 Success packet is badly formed."); + ppp_error("MS-CHAPv2 Success packet is badly formed."); return 0; } return 1; @@ -427,14 +427,14 @@ static void chapms_handle_failure(unsigned char *inp, int len) { break; default: - error("Unknown MS-CHAP authentication failure: %.*v", + ppp_error("Unknown MS-CHAP authentication failure: %.*v", len, inp); return; } } print_msg: if (p != NULL) - error("MS-CHAP authentication failed: %v", p); + ppp_error("MS-CHAP authentication failed: %v", p); } static void ChallengeResponse(u_char *challenge, diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index f213d778..3b32a1e4 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -222,7 +222,7 @@ static void eap_client_timeout(void *arg) { if (!eap_client_active(pcb)) return; - error("EAP: timeout waiting for Request from peer"); + ppp_error("EAP: timeout waiting for Request from peer"); auth_withpeer_fail(pcb, PPP_EAP); pcb->eap.es_client.ea_state = eapBadAuth; } @@ -486,7 +486,7 @@ int status; toffs -= 86400; /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ if (!DesDecrypt(secbuf, clear)) { - dbglog("no DES here; cannot decode " + ppp_dbglog("no DES here; cannot decode " "pseudonym"); return; } @@ -517,11 +517,11 @@ int status; } pcb->eap.es_server.ea_peer[ pcb->eap.es_server.ea_peerlen] = '\0'; - dbglog("decoded pseudonym to \"%.*q\"", + ppp_dbglog("decoded pseudonym to \"%.*q\"", pcb->eap.es_server.ea_peerlen, pcb->eap.es_server.ea_peer); } else { - dbglog("failed to decode real name"); + ppp_dbglog("failed to decode real name"); /* Stay in eapIdentfy state; requery */ break; } @@ -689,9 +689,9 @@ eap_state *esp; if (pcb->eap.es_server.ea_maxrequests > 0 && pcb->eap.es_server.ea_requests >= pcb->eap.es_server.ea_maxrequests) { if (pcb->eap.es_server.ea_responses > 0) - error("EAP: too many Requests sent"); + ppp_error("EAP: too many Requests sent"); else - error("EAP: no response to Requests"); + ppp_error("EAP: no response to Requests"); eap_send_failure(esp); return; } @@ -800,7 +800,7 @@ eap_state *esp; cp += j; /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ if (!DesEncrypt(clear, cipher)) { - dbglog("no DES here; not generating pseudonym"); + ppp_dbglog("no DES here; not generating pseudonym"); break; } BZERO(&b64, sizeof (b64)); @@ -1038,12 +1038,12 @@ static void eap_lowerdown(ppp_pcb *pcb) { static void eap_protrej(ppp_pcb *pcb) { if (eap_client_active(pcb)) { - error("EAP authentication failed due to Protocol-Reject"); + ppp_error("EAP authentication failed due to Protocol-Reject"); auth_withpeer_fail(pcb, PPP_EAP); } #if PPP_SERVER if (eap_server_active(esp)) { - error("EAP authentication of peer failed on Protocol-Reject"); + ppp_error("EAP authentication of peer failed on Protocol-Reject"); auth_peer_fail(pcb, PPP_EAP); } #endif /* PPP_SERVER */ @@ -1234,7 +1234,7 @@ name_of_pn_file() return (NULL); (void) slprintf(path, pl, "%s/%s", user, file); if (!pnlogged) { - dbglog("pseudonym file: %s", path); + ppp_dbglog("pseudonym file: %s", path); pnlogged = 1; } return (path); @@ -1305,22 +1305,22 @@ int len, id; /* Now check that the result is sane */ if (olen <= 0 || *inp + 1 > olen) { - dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp); + ppp_dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp); return; } /* Save it away */ fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC); if (fd < 0) { - dbglog("EAP: error saving pseudonym: %m"); + ppp_dbglog("EAP: error saving pseudonym: %m"); return; } len = write(fd, inp + 1, *inp); if (close(fd) != -1 && len == *inp) { - dbglog("EAP: saved pseudonym"); + ppp_dbglog("EAP: saved pseudonym"); pcb->eap.es_usedpseudo = 0; } else { - dbglog("EAP: failed to save pseudonym"); + ppp_dbglog("EAP: failed to save pseudonym"); remove_pn_file(); } } @@ -1355,7 +1355,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { pcb->eap.es_client.ea_requests++; if (pcb->eap.es_client.ea_maxrequests != 0 && pcb->eap.es_client.ea_requests > pcb->eap.es_client.ea_maxrequests) { - info("EAP: received too many Request messages"); + ppp_info("EAP: received too many Request messages"); if (pcb->eap.es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, pcb); } @@ -1364,7 +1364,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { } if (len <= 0) { - error("EAP: empty Request message discarded"); + ppp_error("EAP: empty Request message discarded"); return; } @@ -1374,7 +1374,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { switch (typenum) { case EAPT_IDENTITY: if (len > 0) - info("EAP: Identity prompt \"%.*q\"", len, inp); + ppp_info("EAP: Identity prompt \"%.*q\"", len, inp); #ifdef USE_SRP if (pcb->eap.es_usepseudo && (pcb->eap.es_usedpseudo == 0 || @@ -1408,7 +1408,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPT_NOTIFICATION: if (len > 0) - info("EAP: Notification \"%.*q\"", len, inp); + ppp_info("EAP: Notification \"%.*q\"", len, inp); eap_send_response(pcb, id, typenum, NULL, 0); break; @@ -1417,20 +1417,20 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { * Avoid the temptation to send Response Nak in reply * to Request Nak here. It can only lead to trouble. */ - warn("EAP: unexpected Nak in Request; ignored"); + ppp_warn("EAP: unexpected Nak in Request; ignored"); /* Return because we're waiting for something real. */ return; case EAPT_MD5CHAP: if (len < 1) { - error("EAP: received MD5-Challenge with no data"); + ppp_error("EAP: received MD5-Challenge with no data"); /* Bogus request; wait for something real. */ return; } GETCHAR(vallen, inp); len--; if (vallen < 8 || vallen > len) { - error("EAP: MD5-Challenge with bad length %d (8..%d)", + ppp_error("EAP: MD5-Challenge with bad length %d (8..%d)", vallen, len); /* Try something better. */ eap_send_nak(pcb, id, EAPT_SRP); @@ -1439,7 +1439,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { /* Not so likely to happen. */ if (vallen >= len + sizeof (rhostname)) { - dbglog("EAP: trimming really long peer name down"); + ppp_dbglog("EAP: trimming really long peer name down"); MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; } else { @@ -1460,7 +1460,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { */ if (!get_secret(pcb, pcb->eap.es_client.ea_name, rhostname, secret, &secret_len, 0)) { - dbglog("EAP: no MD5 secret for auth to %q", rhostname); + ppp_dbglog("EAP: no MD5 secret for auth to %q", rhostname); eap_send_nak(pcb, id, EAPT_SRP); break; } @@ -1478,7 +1478,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { #ifdef USE_SRP case EAPT_SRP: if (len < 1) { - error("EAP: received empty SRP Request"); + ppp_error("EAP: received empty SRP Request"); /* Bogus request; wait for something real. */ return; } @@ -1509,7 +1509,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { GETCHAR(vallen, inp); len--; if (vallen >= len) { - error("EAP: badly-formed SRP Challenge" + ppp_error("EAP: badly-formed SRP Challenge" " (name)"); /* Ignore badly-formed messages */ return; @@ -1537,7 +1537,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { GETCHAR(vallen, inp); len--; if (vallen >= len) { - error("EAP: badly-formed SRP Challenge" + ppp_error("EAP: badly-formed SRP Challenge" " (s)"); /* Ignore badly-formed messages */ return; @@ -1550,7 +1550,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { GETCHAR(vallen, inp); len--; if (vallen > len) { - error("EAP: badly-formed SRP Challenge" + ppp_error("EAP: badly-formed SRP Challenge" " (g)"); /* Ignore badly-formed messages */ return; @@ -1598,7 +1598,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPSRP_SKEY: tc = (struct t_client *)pcb->eap.es_client.ea_session; if (tc == NULL) { - warn("EAP: peer sent Subtype 2 without 1"); + ppp_warn("EAP: peer sent Subtype 2 without 1"); eap_send_nak(pcb, id, EAPT_MD5CHAP); break; } @@ -1608,7 +1608,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { * if it does (but otherwise ignore). */ if (id != pcb->eap.es_client.ea_id) { - warn("EAP: ID changed from %d to %d " + ppp_warn("EAP: ID changed from %d to %d " "in SRP Subtype 2 rexmit", pcb->eap.es_client.ea_id, id); } @@ -1632,7 +1632,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { t_clientgetkey(tc, &Bval); if (pcb->eap.es_client.ea_skey == NULL) { /* Server is rogue; stop now */ - error("EAP: SRP server is rogue"); + ppp_error("EAP: SRP server is rogue"); goto client_failure; } } @@ -1643,7 +1643,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPSRP_SVALIDATOR: tc = (struct t_client *)pcb->eap.es_client.ea_session; if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) { - warn("EAP: peer sent Subtype 3 without 1/2"); + ppp_warn("EAP: peer sent Subtype 3 without 1/2"); eap_send_nak(pcb, id, EAPT_MD5CHAP); break; } @@ -1654,7 +1654,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { */ if (pcb->eap.es_client.ea_state == eapOpen) { if (id != pcb->eap.es_client.ea_id) { - warn("EAP: ID changed from %d to %d " + ppp_warn("EAP: ID changed from %d to %d " "in SRP Subtype 3 rexmit", pcb->eap.es_client.ea_id, id); } @@ -1662,7 +1662,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { len -= sizeof (u32_t) + SHA_DIGESTSIZE; if (len < 0 || t_clientverify(tc, inp + sizeof (u32_t)) != 0) { - error("EAP: SRP server verification " + ppp_error("EAP: SRP server verification " "failed"); goto client_failure; } @@ -1683,7 +1683,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPSRP_LWRECHALLENGE: if (len < 4) { - warn("EAP: malformed Lightweight rechallenge"); + ppp_warn("EAP: malformed Lightweight rechallenge"); return; } SHA1Init(&ctxt); @@ -1700,7 +1700,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { break; default: - error("EAP: unknown SRP Subtype %d", vallen); + ppp_error("EAP: unknown SRP Subtype %d", vallen); eap_send_nak(pcb, id, EAPT_MD5CHAP); break; } @@ -1708,7 +1708,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { #endif /* USE_SRP */ default: - info("EAP: unknown authentication type %d; Naking", typenum); + ppp_info("EAP: unknown authentication type %d; Naking", typenum); eap_send_nak(pcb, id, EAPT_SRP); break; } @@ -1753,7 +1753,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { #endif /* USE_SRP */ if (pcb->eap.es_server.ea_id != id) { - dbglog("EAP: discarding Response %d; expected ID %d", id, + ppp_dbglog("EAP: discarding Response %d; expected ID %d", id, pcb->eap.es_server.ea_id); return; } @@ -1761,7 +1761,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { pcb->eap.es_server.ea_responses++; if (len <= 0) { - error("EAP: empty Response message discarded"); + ppp_error("EAP: empty Response message discarded"); return; } @@ -1771,11 +1771,11 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { switch (typenum) { case EAPT_IDENTITY: if (pcb->eap.es_server.ea_state != eapIdentify) { - dbglog("EAP discarding unwanted Identify \"%.q\"", len, + ppp_dbglog("EAP discarding unwanted Identify \"%.q\"", len, inp); break; } - info("EAP: unauthenticated peer name \"%.*q\"", len, inp); + ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp); if (pcb->eap.es_server.ea_peer != NULL && pcb->eap.es_server.ea_peer != remote_name) free(pcb->eap.es_server.ea_peer); @@ -1792,12 +1792,12 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { break; case EAPT_NOTIFICATION: - dbglog("EAP unexpected Notification; response discarded"); + ppp_dbglog("EAP unexpected Notification; response discarded"); break; case EAPT_NAK: if (len < 1) { - info("EAP: Nak Response with no suggested protocol"); + ppp_info("EAP: Nak Response with no suggested protocol"); eap_figure_next_state(esp, 1); break; } @@ -1823,7 +1823,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { break; default: - dbglog("EAP: peer requesting unknown Type %d", vallen); + ppp_dbglog("EAP: peer requesting unknown Type %d", vallen); switch (pcb->eap.es_server.ea_state) { case eapSRP1: case eapSRP2: @@ -1844,26 +1844,26 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPT_MD5CHAP: if (pcb->eap.es_server.ea_state != eapMD5Chall) { - error("EAP: unexpected MD5-Response"); + ppp_error("EAP: unexpected MD5-Response"); eap_figure_next_state(esp, 1); break; } if (len < 1) { - error("EAP: received MD5-Response with no data"); + ppp_error("EAP: received MD5-Response with no data"); eap_figure_next_state(esp, 1); break; } GETCHAR(vallen, inp); len--; if (vallen != 16 || vallen > len) { - error("EAP: MD5-Response with bad length %d", vallen); + ppp_error("EAP: MD5-Response with bad length %d", vallen); eap_figure_next_state(esp, 1); break; } /* Not so likely to happen. */ if (vallen >= len + sizeof (rhostname)) { - dbglog("EAP: trimming really long peer name down"); + ppp_dbglog("EAP: trimming really long peer name down"); MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; } else { @@ -1882,7 +1882,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { */ if (!get_secret(pcb, rhostname, pcb->eap.es_server.ea_name, secret, &secret_len, 1)) { - dbglog("EAP: no MD5 secret for auth of %q", rhostname); + ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname); eap_send_failure(esp); break; } @@ -1906,7 +1906,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { #ifdef USE_SRP case EAPT_SRP: if (len < 1) { - error("EAP: empty SRP Response"); + ppp_error("EAP: empty SRP Response"); eap_figure_next_state(esp, 1); break; } @@ -1915,7 +1915,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { switch (typenum) { case EAPSRP_CKEY: if (pcb->eap.es_server.ea_state != eapSRP1) { - error("EAP: unexpected SRP Subtype 1 Response"); + ppp_error("EAP: unexpected SRP Subtype 1 Response"); eap_figure_next_state(esp, 1); break; } @@ -1926,7 +1926,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A); if (pcb->eap.es_server.ea_skey == NULL) { /* Client's A value is bogus; terminate now */ - error("EAP: bogus A value from client"); + ppp_error("EAP: bogus A value from client"); eap_send_failure(esp); } else { eap_figure_next_state(esp, 0); @@ -1935,12 +1935,12 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPSRP_CVALIDATOR: if (pcb->eap.es_server.ea_state != eapSRP2) { - error("EAP: unexpected SRP Subtype 2 Response"); + ppp_error("EAP: unexpected SRP Subtype 2 Response"); eap_figure_next_state(esp, 1); break; } if (len < sizeof (u32_t) + SHA_DIGESTSIZE) { - error("EAP: M1 length %d < %d", len, + ppp_error("EAP: M1 length %d < %d", len, sizeof (u32_t) + SHA_DIGESTSIZE); eap_figure_next_state(esp, 1); break; @@ -1949,7 +1949,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { ts = (struct t_server *)pcb->eap.es_server.ea_session; assert(ts != NULL); if (t_serververify(ts, inp)) { - info("EAP: unable to validate client identity"); + ppp_info("EAP: unable to validate client identity"); eap_send_failure(esp); break; } @@ -1958,7 +1958,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPSRP_ACK: if (pcb->eap.es_server.ea_state != eapSRP3) { - error("EAP: unexpected SRP Subtype 3 Response"); + ppp_error("EAP: unexpected SRP Subtype 3 Response"); eap_send_failure(esp); break; } @@ -1975,11 +1975,11 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPSRP_LWRECHALLENGE: if (pcb->eap.es_server.ea_state != eapSRP4) { - info("EAP: unexpected SRP Subtype 4 Response"); + ppp_info("EAP: unexpected SRP Subtype 4 Response"); return; } if (len != SHA_DIGESTSIZE) { - error("EAP: bad Lightweight rechallenge " + ppp_error("EAP: bad Lightweight rechallenge " "response"); return; } @@ -1993,7 +1993,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { pcb->eap.es_server.ea_peerlen); SHA1Final(dig, &ctxt); if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { - error("EAP: failed Lightweight rechallenge"); + ppp_error("EAP: failed Lightweight rechallenge"); eap_send_failure(esp); break; } @@ -2008,7 +2008,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { default: /* This can't happen. */ - error("EAP: unknown Response type %d; ignored", typenum); + ppp_error("EAP: unknown Response type %d; ignored", typenum); return; } @@ -2029,7 +2029,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { */ static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) { if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) { - dbglog("EAP unexpected success message in state %s (%d)", + ppp_dbglog("EAP unexpected success message in state %s (%d)", eap_state_name(pcb->eap.es_client.ea_state), pcb->eap.es_client.ea_state); return; @@ -2053,7 +2053,7 @@ static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) { */ static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) { if (!eap_client_active(pcb)) { - dbglog("EAP unexpected failure message in state %s (%d)", + ppp_dbglog("EAP unexpected failure message in state %s (%d)", eap_state_name(pcb->eap.es_client.ea_state), pcb->eap.es_client.ea_state); } @@ -2069,7 +2069,7 @@ static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) { pcb->eap.es_client.ea_state = eapBadAuth; - error("EAP: peer reports authentication failure"); + ppp_error("EAP: peer reports authentication failure"); auth_withpeer_fail(pcb, PPP_EAP); } @@ -2085,14 +2085,14 @@ static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen) { * drop it. */ if (inlen < EAP_HEADERLEN) { - error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN); + ppp_error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN); return; } GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp); if (len < EAP_HEADERLEN || len > inlen) { - error("EAP: packet has illegal length field %d (%d..%d)", len, + ppp_error("EAP: packet has illegal length field %d (%d..%d)", len, EAP_HEADERLEN, inlen); return; } @@ -2120,7 +2120,7 @@ static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen) { default: /* XXX Need code reject */ /* Note: it's not legal to send EAP Nak here. */ - warn("EAP: unknown code %d received", code); + ppp_warn("EAP: unknown code %d received", code); break; } } @@ -2179,7 +2179,7 @@ static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, case EAPT_NOTIFICATION: if (len > 0) { printer(arg, " "); INCPTR(len, inp); len = 0; @@ -2200,7 +2200,7 @@ static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, len -= vallen; if (len > 0) { printer(arg, " "); INCPTR(len, inp); len = 0; @@ -2223,7 +2223,7 @@ static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, goto truncated; if (vallen > 0) { printer(arg, " "); } else { @@ -2313,7 +2313,7 @@ static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, case EAPT_IDENTITY: if (len > 0) { printer(arg, " "); INCPTR(len, inp); len = 0; @@ -2348,7 +2348,7 @@ static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, len -= vallen; if (len > 0) { printer(arg, " "); INCPTR(len, inp); len = 0; diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 4c3cf53a..89638d61 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -285,7 +285,7 @@ static void fsm_timeout(void *arg) { case PPP_FSM_ACKRCVD: case PPP_FSM_ACKSENT: if (f->retransmits <= 0) { - warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); + ppp_warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); f->state = PPP_FSM_STOPPED; if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) (*f->callbacks->finished)(f); @@ -455,7 +455,7 @@ static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { 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); + ppp_error("Received bad configure-ack: %P", inp, len); return; } f->seen_ack = 1; @@ -513,14 +513,14 @@ static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { treat_as_reject = (f->rnakloops >= f->maxnakloops); if (f->callbacks->nakci == NULL || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) { - error("Received bad configure-nak: %P", inp, len); + ppp_error("Received bad configure-nak: %P", inp, len); return; } } else { f->rnakloops = 0; if (f->callbacks->rejci == NULL || !(ret = f->callbacks->rejci(f, inp, len))) { - error("Received bad configure-rej: %P", inp, len); + ppp_error("Received bad configure-rej: %P", inp, len); return; } } @@ -573,9 +573,9 @@ static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { case PPP_FSM_OPENED: if (len > 0) { - info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); + ppp_info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); } else - info("%s terminated by peer", PROTO_NAME(f)); + ppp_info("%s terminated by peer", PROTO_NAME(f)); f->retransmits = 0; f->state = PPP_FSM_STOPPING; if (f->callbacks->down) @@ -632,7 +632,7 @@ static void fsm_rcoderej(fsm *f, u_char *inp, int len) { } GETCHAR(code, inp); GETCHAR(id, inp); - warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); + ppp_warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); if( f->state == PPP_FSM_ACKRCVD ) f->state = PPP_FSM_REQSENT; diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index b7300f3c..ede4af8f 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -1750,9 +1750,9 @@ ip_demand_conf(u) if (sifproxyarp(pcb, wo->hisaddr)) proxy_arp_set[u] = 1; - notice("local IP address %I", wo->ouraddr); + ppp_notice("local IP address %I", wo->ouraddr); if (wo->hisaddr) - notice("remote IP address %I", wo->hisaddr); + ppp_notice("remote IP address %I", wo->hisaddr); return 1; } @@ -1780,18 +1780,18 @@ static void ipcp_up(fsm *f) { if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) && wo->ouraddr != 0) { - error("Peer refused to agree to our IP address"); + ppp_error("Peer refused to agree to our IP address"); ipcp_close(f->pcb, "Refused our IP address"); return; } if (go->ouraddr == 0) { - error("Could not determine local IP address"); + ppp_error("Could not determine local IP address"); ipcp_close(f->pcb, "Could not determine local IP address"); return; } if (ho->hisaddr == 0 && !pcb->settings.noremoteip) { ho->hisaddr = htonl(0x0a404040); - warn("Could not determine remote IP address: defaulting to %I", + ppp_warn("Could not determine remote IP address: defaulting to %I", ho->hisaddr); } #if 0 /* UNUSED */ @@ -1824,7 +1824,7 @@ static void ipcp_up(fsm *f) { * Check that the peer is allowed to use the IP address it wants. */ if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) { - error("Peer is not authorized to use remote address %I", ho->hisaddr); + ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr); ipcp_close(f->unit, "Unauthorized remote IP address"); return; } @@ -1844,13 +1844,13 @@ static void ipcp_up(fsm *f) { ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr, wo->replace_default_route); if (go->ouraddr != wo->ouraddr) { - warn("Local IP address changed to %I", go->ouraddr); + ppp_warn("Local IP address changed to %I", go->ouraddr); script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); wo->ouraddr = go->ouraddr; } else script_unsetenv("OLDIPLOCAL"); if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) { - warn("Remote IP address changed to %I", ho->hisaddr); + ppp_warn("Remote IP address changed to %I", ho->hisaddr); script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); wo->hisaddr = ho->hisaddr; } else @@ -1860,7 +1860,7 @@ static void ipcp_up(fsm *f) { mask = get_mask(go->ouraddr); if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { #if PPP_DEBUG - warn("Interface configuration failed"); + ppp_warn("Interface configuration failed"); #endif /* PPP_DEBUG */ ipcp_close(f->unit, "Interface configuration failed"); return; @@ -1892,7 +1892,7 @@ static void ipcp_up(fsm *f) { #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { #if PPP_DEBUG - warn("Interface configuration failed"); + ppp_warn("Interface configuration failed"); #endif /* PPP_DEBUG */ ipcp_close(f->pcb, "Interface configuration failed"); return; @@ -1902,7 +1902,7 @@ static void ipcp_up(fsm *f) { /* bring the interface up for IP */ if (!sifup(pcb)) { #if PPP_DEBUG - warn("Interface failed to come up"); + ppp_warn("Interface failed to come up"); #endif /* PPP_DEBUG */ ipcp_close(f->pcb, "Interface configuration failed"); return; @@ -1911,7 +1911,7 @@ static void ipcp_up(fsm *f) { #if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { #if PPP_DEBUG - warn("Interface configuration failed"); + ppp_warn("Interface configuration failed"); #endif /* PPP_DEBUG */ ipcp_close(f->unit, "Interface configuration failed"); return; @@ -1934,13 +1934,13 @@ static void ipcp_up(fsm *f) { wo->ouraddr = go->ouraddr; - notice("local IP address %I", go->ouraddr); + ppp_notice("local IP address %I", go->ouraddr); if (ho->hisaddr != 0) - notice("remote IP address %I", ho->hisaddr); + ppp_notice("remote IP address %I", ho->hisaddr); if (go->dnsaddr[0]) - notice("primary DNS address %I", go->dnsaddr[0]); + ppp_notice("primary DNS address %I", go->dnsaddr[0]); if (go->dnsaddr[1]) - notice("secondary DNS address %I", go->dnsaddr[1]); + ppp_notice("secondary DNS address %I", go->dnsaddr[1]); } #if PPP_STATS_SUPPORT @@ -2176,7 +2176,7 @@ static int ipcp_printpkt(u_char *p, int plen, case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); - print_string((char *)p, len, printer, arg); + ppp_print_string((char *)p, len, printer, arg); p += len; len = 0; } diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c index 14b83f90..5318e2ba 100644 --- a/src/netif/ppp/ipv6cp.c +++ b/src/netif/ppp/ipv6cp.c @@ -1120,9 +1120,9 @@ static int ipv6_demand_conf(int u) { if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) return 0; - notice("ipv6_demand_conf"); - notice("local LL address %s", llv6_ntoa(wo->ourid)); - notice("remote LL address %s", llv6_ntoa(wo->hisid)); + ppp_notice("ipv6_demand_conf"); + ppp_notice("local LL address %s", llv6_ntoa(wo->ourid)); + ppp_notice("remote LL address %s", llv6_ntoa(wo->hisid)); return 1; } @@ -1152,17 +1152,17 @@ static void ipv6cp_up(fsm *f) { if(!no_ifaceid_neg) { #endif /* UNUSED */ if (eui64_iszero(ho->hisid)) { - error("Could not determine remote LL address"); + ppp_error("Could not determine remote LL address"); ipv6cp_close(f->pcb, "Could not determine remote LL address"); return; } if (eui64_iszero(go->ourid)) { - error("Could not determine local LL address"); + ppp_error("Could not determine local LL address"); ipv6cp_close(f->pcb, "Could not determine local LL address"); return; } if (eui64_equals(go->ourid, ho->hisid)) { - error("local and remote LL addresses are equal"); + ppp_error("local and remote LL addresses are equal"); ipv6cp_close(f->pcb, "local and remote LL addresses are equal"); return; } @@ -1228,8 +1228,8 @@ static void ipv6cp_up(fsm *f) { } sifnpmode(f->pcb, PPP_IPV6, NPMODE_PASS); - notice("local LL address %s", llv6_ntoa(go->ourid)); - notice("remote LL address %s", llv6_ntoa(ho->hisid)); + ppp_notice("local LL address %s", llv6_ntoa(go->ourid)); + ppp_notice("remote LL address %s", llv6_ntoa(ho->hisid)); } np_up(f->pcb, PPP_IPV6); @@ -1447,7 +1447,7 @@ static int ipv6cp_printpkt(u_char *p, int plen, case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); - print_string((char *)p, len, printer, arg); + ppp_print_string((char *)p, len, printer, arg); p += len; len = 0; } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 01a889d0..f1445519 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -625,22 +625,22 @@ static void lcp_rprotrej(fsm *f, u_char *inp, int len) { if (protp->protocol == prot && protp->enabled_flag) { #if PPP_PROTOCOLNAME if (pname != NULL) - dbglog("Protocol-Reject for '%s' (0x%x) received", pname, + ppp_dbglog("Protocol-Reject for '%s' (0x%x) received", pname, prot); else #endif /* PPP_PROTOCOLNAME */ - dbglog("Protocol-Reject for 0x%x received", prot); + ppp_dbglog("Protocol-Reject for 0x%x received", prot); (*protp->protrej)(f->pcb); return; } #if PPP_PROTOCOLNAME if (pname != NULL) - warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname, + ppp_warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname, prot); else #endif /* #if PPP_PROTOCOLNAME */ - warn("Protocol-Reject for unsupported protocol 0x%x", prot); + ppp_warn("Protocol-Reject for unsupported protocol 0x%x", prot); } @@ -652,7 +652,7 @@ static void lcp_protrej(ppp_pcb *pcb) { /* * Can't reject LCP! */ - error("Received Protocol-Reject for LCP!"); + ppp_error("Received Protocol-Reject for LCP!"); fsm_protreject(&pcb->lcp_fsm); } @@ -871,7 +871,7 @@ static void lcp_addci(fsm *f, u_char *ucp, int *lenp) { if (ucp - start_ucp != *lenp) { /* this should never happen, because peer_mtu should be 1500 */ - error("Bug in lcp_addci: wrong length"); + ppp_error("Bug in lcp_addci: wrong length"); } } @@ -1303,7 +1303,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { * well, that's just strange. Nobody should do that. */ if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap) - dbglog("Unexpected Conf-Nak for EAP"); + ppp_dbglog("Unexpected Conf-Nak for EAP"); /* * We don't recognize what they're suggesting. @@ -1496,7 +1496,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { if (looped_back) { if (++try.numloops >= pcb->settings.lcp_loopbackfail) { int errcode = PPPERR_LOOPBACK; - notice("Serial line is looped back."); + ppp_notice("Serial line is looped back."); ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(f->pcb, "Loopback detected"); } @@ -1866,7 +1866,7 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { /* * Reject the option if we're not willing to authenticate. */ - dbglog("No auth is possible"); + ppp_dbglog("No auth is possible"); orc = CONFREJ; break; } @@ -2502,7 +2502,7 @@ static int lcp_printpkt(u_char *p, int plen, case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); - print_string((char *)p, len, printer, arg); + ppp_print_string((char *)p, len, printer, arg); p += len; len = 0; } @@ -2534,7 +2534,7 @@ static int lcp_printpkt(u_char *p, int plen, } if (len > 0) { printer(arg, " "); - print_string((char *)p, len, printer, arg); + ppp_print_string((char *)p, len, printer, arg); p += len; len = 0; } @@ -2563,8 +2563,8 @@ static void LcpLinkFailure(fsm *f) { ppp_pcb *pcb = f->pcb; if (f->state == PPP_FSM_OPENED) { int errcode = PPPERR_PEERDEAD; - info("No response to %d echo-requests", pcb->lcp_echos_pending); - notice("Serial link appears to be disconnected."); + ppp_info("No response to %d echo-requests", pcb->lcp_echos_pending); + ppp_notice("Serial link appears to be disconnected."); ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(pcb, "Peer not responding"); } @@ -2585,7 +2585,7 @@ static void LcpEchoCheck(fsm *f) { * Start the timer for the next interval. */ if (pcb->lcp_echo_timer_running) - warn("assertion lcp_echo_timer_running==0 failed"); + ppp_warn("assertion lcp_echo_timer_running==0 failed"); TIMEOUT (LcpEchoTimeout, f, pcb->settings.lcp_echo_interval); pcb->lcp_echo_timer_running = 1; } @@ -2614,13 +2614,13 @@ static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) { /* Check the magic number - don't count replies from ourselves. */ if (len < 4) { - dbglog("lcp: received short Echo-Reply, length %d", len); + ppp_dbglog("lcp: received short Echo-Reply, length %d", len); return; } GETLONG(magic, inp); if (go->neg_magicnumber && magic == go->magicnumber) { - warn("appear to have received our own echo-reply!"); + ppp_warn("appear to have received our own echo-reply!"); return; } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index c7725658..9a6bbd10 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -692,7 +692,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; #if PRINTPKT_SUPPORT - dump_packet("rcvd", pb->payload, pb->len); + ppp_dump_packet("rcvd", pb->payload, pb->len); #endif /* PRINTPKT_SUPPORT */ if(pbuf_header(pb, -(s16_t)sizeof(protocol))) { @@ -708,7 +708,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { * Toss all non-LCP packets unless LCP is OPEN. */ if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) { - dbglog("Discarded non-LCP packet when LCP not open"); + ppp_dbglog("Discarded non-LCP packet when LCP not open"); goto drop; } @@ -731,7 +731,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { || protocol == PPP_EAP #endif /* EAP_SUPPORT */ )) { - dbglog("discarding proto 0x%x in phase %d", + ppp_dbglog("discarding proto 0x%x in phase %d", protocol, pcb->phase); goto drop; } @@ -816,10 +816,10 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { #if PPP_PROTOCOLNAME const char *pname = protocol_name(protocol); if (pname != NULL) - warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); + ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); else #endif /* PPP_PROTOCOLNAME */ - warn("Unsupported protocol 0x%x received", protocol); + ppp_warn("Unsupported protocol 0x%x received", protocol); #endif /* PPP_DEBUG */ if (pbuf_header(pb, (s16_t)sizeof(protocol))) { LWIP_ASSERT("pbuf_header failed\n", 0); @@ -1454,7 +1454,7 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { #endif /* PPPOS_SUPPORT */ #if PRINTPKT_SUPPORT - dump_packet("sent", (unsigned char *)p->payload+2, p->len-2); + ppp_dump_packet("sent", (unsigned char *)p->payload+2, p->len-2); #endif /* PRINTPKT_SUPPORT */ #if PPPOE_SUPPORT diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 8f3a44c9..0de5a57d 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -210,7 +210,7 @@ static void upap_timeout(void *arg) { if (pcb->upap.us_transmits >= pcb->upap.us_maxtransmits) { /* give up in disgust */ - error("No response to PAP authenticate-requests"); + ppp_error("No response to PAP authenticate-requests"); pcb->upap.us_clientstate = UPAPCS_BADAUTH; auth_withpeer_fail(pcb, PPP_PAP); return; @@ -290,12 +290,12 @@ static void upap_lowerdown(ppp_pcb *pcb) { static void upap_protrej(ppp_pcb *pcb) { if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) { - error("PAP authentication failed due to protocol-reject"); + ppp_error("PAP authentication failed due to protocol-reject"); auth_withpeer_fail(pcb, PPP_PAP); } #if PPP_SERVER if (pcb->upap.us_serverstate == UPAPSS_LISTEN) { - error("PAP authentication of peer failed (protocol-reject)"); + ppp_error("PAP authentication of peer failed (protocol-reject)"); auth_peer_fail(pcb, PPP_PAP); } #endif /* PPP_SERVER */ @@ -515,7 +515,7 @@ static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) { pcb->upap.us_clientstate = UPAPCS_BADAUTH; - error("PAP authentication failed"); + ppp_error("PAP authentication failed"); auth_withpeer_fail(pcb, PPP_PAP); } @@ -624,13 +624,13 @@ static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, char *, . p += ulen + wlen + 2; len -= ulen + wlen + 2; printer(arg, " user="); - print_string(user, ulen, printer, arg); + ppp_print_string(user, ulen, printer, arg); printer(arg, " password="); /* FIXME: require ppp_pcb struct as printpkt() argument */ #if 0 if (!pcb->settings.hide_password) #endif - print_string(pwd, wlen, printer, arg); + ppp_print_string(pwd, wlen, printer, arg); #if 0 else printer(arg, ""); @@ -647,7 +647,7 @@ static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, char *, . p += mlen + 1; len -= mlen + 1; printer(arg, " "); - print_string(msg, mlen, printer, arg); + ppp_print_string(msg, mlen, printer, arg); break; } diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 833a5a76..f918ba07 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -69,11 +69,11 @@ extern char *strerror(); #endif -static void logit(int level, char *fmt, va_list args); -static void log_write(int level, char *buf); +static void ppp_logit(int level, char *fmt, va_list args); +static void ppp_log_write(int level, char *buf); #if PRINTPKT_SUPPORT -static void vslp_printer(void *arg, char *fmt, ...); -static void format_packet(u_char *p, int len, +static void ppp_vslp_printer(void *arg, char *fmt, ...); +static void ppp_format_packet(u_char *p, int len, void (*printer) (void *, char *, ...), void *arg); struct buffer_info { @@ -83,10 +83,10 @@ struct buffer_info { #endif /* PRINTPKT_SUPPORT */ /* - * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, + * ppp_strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, * always leaves destination null-terminated (for len > 0). */ -size_t strlcpy(char *dest, const char *src, size_t len) { +size_t ppp_strlcpy(char *dest, const char *src, size_t len) { size_t ret = strlen(src); if (len != 0) { @@ -101,40 +101,40 @@ size_t strlcpy(char *dest, const char *src, size_t len) { } /* - * strlcat - like strcat/strncat, doesn't overflow destination buffer, + * ppp_strlcat - like strcat/strncat, doesn't overflow destination buffer, * always leaves destination null-terminated (for len > 0). */ -size_t strlcat(char *dest, const char *src, size_t len) { +size_t ppp_strlcat(char *dest, const char *src, size_t len) { size_t dlen = strlen(dest); - return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); + return dlen + ppp_strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); } /* - * slprintf - format a message into a buffer. Like sprintf except we + * ppp_slprintf - format a message into a buffer. Like sprintf except we * also specify the length of the output buffer, and we handle * %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(char *buf, int buflen, char *fmt, ...) { +int ppp_slprintf(char *buf, int buflen, char *fmt, ...) { va_list args; int n; va_start(args, fmt); - n = vslprintf(buf, buflen, fmt, args); + n = ppp_vslprintf(buf, buflen, fmt, args); va_end(args); return n; } /* - * vslprintf - like slprintf, takes a va_list instead of a list of args. + * ppp_vslprintf - like ppp_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 ppp_vslprintf(char *buf, int buflen, char *fmt, va_list args) { int c, i, n; int width, prec, fillch; int base, len, neg, quoted; @@ -267,7 +267,7 @@ int vslprintf(char *buf, int buflen, char *fmt, va_list args) { case 'I': ip = va_arg(args, u32_t); ip = ntohl(ip); - slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, + ppp_slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); str = num; break; @@ -275,10 +275,10 @@ int vslprintf(char *buf, int buflen, char *fmt, va_list args) { case 'r': f = va_arg(args, char *); #ifndef __powerpc__ - n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list)); + n = ppp_vslprintf(buf, buflen + 1, f, va_arg(args, va_list)); #else /* On the powerpc, a va_list is an array of 1 structure */ - n = vslprintf(buf, buflen + 1, f, va_arg(args, void *)); + n = ppp_vslprintf(buf, buflen + 1, f, va_arg(args, void *)); #endif buf += n; buflen -= n; @@ -344,7 +344,7 @@ int vslprintf(char *buf, int buflen, char *fmt, va_list args) { bufinfo.len = buflen + 1; p = va_arg(args, unsigned char *); n = va_arg(args, int); - format_packet(p, n, vslp_printer, &bufinfo); + ppp_format_packet(p, n, ppp_vslp_printer, &bufinfo); buf = bufinfo.ptr; buflen = bufinfo.len - 1; continue; @@ -413,14 +413,14 @@ int vslprintf(char *buf, int buflen, char *fmt, va_list args) { /* * vslp_printer - used in processing a %P format */ -static void vslp_printer(void *arg, char *fmt, ...) { +static void ppp_vslp_printer(void *arg, char *fmt, ...) { int n; va_list pvar; struct buffer_info *bi; va_start(pvar, fmt); bi = (struct buffer_info *) arg; - n = vslprintf(bi->ptr, bi->len, fmt, pvar); + n = ppp_vslprintf(bi->ptr, bi->len, fmt, pvar); va_end(pvar); bi->ptr += n; @@ -441,17 +441,17 @@ log_packet(p, len, prefix, level) int level; { init_pr_log(prefix, level); - format_packet(p, len, pr_log, &level); + ppp_format_packet(p, len, pr_log, &level); end_pr_log(); } #endif /* UNUSED */ #if PRINTPKT_SUPPORT /* - * format_packet - make a readable representation of a packet, + * ppp_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, +static void ppp_format_packet(u_char *p, int len, void (*printer) (void *, char *, ...), void *arg) { int i, n; u_short proto; @@ -508,7 +508,7 @@ init_pr_log(prefix, level) { linep = line; if (prefix != NULL) { - strlcpy(line, prefix, sizeof(line)); + ppp_strlcpy(line, prefix, sizeof(line)); linep = line + strlen(line); } llevel = level; @@ -519,7 +519,7 @@ end_pr_log() { if (linep != line) { *linep = 0; - log_write(llevel, line); + ppp_log_write(llevel, line); } } @@ -535,7 +535,7 @@ pr_log (void *arg, char *fmt, ...) char buf[256]; va_start(pvar, fmt); - n = vslprintf(buf, sizeof(buf), fmt, pvar); + n = ppp_vslprintf(buf, sizeof(buf), fmt, pvar); va_end(pvar); p = buf; @@ -553,13 +553,13 @@ pr_log (void *arg, char *fmt, ...) eol = strchr(p, '\n'); } *linep = 0; - log_write(llevel, line); + ppp_log_write(llevel, line); linep = line; } while (eol != NULL) { *eol = 0; - log_write(llevel, p); + ppp_log_write(llevel, p); p = eol + 1; eol = strchr(p, '\n'); } @@ -574,10 +574,10 @@ pr_log (void *arg, char *fmt, ...) #endif /* UNUSED */ /* - * print_string - print a readable representation of a string using + * ppp_print_string - print a readable representation of a string using * printer. */ -void print_string(char *p, int len, void (*printer) (void *, char *, ...), void *arg) { +void ppp_print_string(char *p, int len, void (*printer) (void *, char *, ...), void *arg) { int c; printer(arg, "\""); @@ -608,16 +608,16 @@ void print_string(char *p, int len, void (*printer) (void *, char *, ...), void } /* - * logit - does the hard work for fatal et al. + * ppp_logit - does the hard work for fatal et al. */ -static void logit(int level, char *fmt, va_list args) { +static void ppp_logit(int level, char *fmt, va_list args) { char buf[1024]; - vslprintf(buf, sizeof(buf), fmt, args); - log_write(level, buf); + ppp_vslprintf(buf, sizeof(buf), fmt, args); + ppp_log_write(level, buf); } -static void log_write(int level, char *buf) { +static void ppp_log_write(int level, char *buf) { PPPDEBUG(level, ("%s\n", buf) ); #if 0 if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { @@ -633,13 +633,13 @@ static void log_write(int level, char *buf) { } /* - * fatal - log an error message and die horribly. + * ppp_fatal - log an error message and die horribly. */ -void fatal(char *fmt, ...) { +void ppp_fatal(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); - logit(LOG_ERR, fmt, pvar); + ppp_logit(LOG_ERR, fmt, pvar); va_end(pvar); /* FIXME: find a way to die */ @@ -649,13 +649,13 @@ void fatal(char *fmt, ...) { } /* - * error - log an error message. + * ppp_error - log an error message. */ -void error(char *fmt, ...) { +void ppp_error(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); - logit(LOG_ERR, fmt, pvar); + ppp_logit(LOG_ERR, fmt, pvar); va_end(pvar); #if 0 /* UNUSED */ ++error_count; @@ -663,55 +663,55 @@ void error(char *fmt, ...) { } /* - * warn - log a warning message. + * ppp_warn - log a warning message. */ -void warn(char *fmt, ...) { +void ppp_warn(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); - logit(LOG_WARNING, fmt, pvar); + ppp_logit(LOG_WARNING, fmt, pvar); va_end(pvar); } /* - * notice - log a notice-level message. + * ppp_notice - log a notice-level message. */ -void notice(char *fmt, ...) { +void ppp_notice(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); - logit(LOG_NOTICE, fmt, pvar); + ppp_logit(LOG_NOTICE, fmt, pvar); va_end(pvar); } /* - * info - log an informational message. + * ppp_info - log an informational message. */ -void info(char *fmt, ...) { +void ppp_info(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); - logit(LOG_INFO, fmt, pvar); + ppp_logit(LOG_INFO, fmt, pvar); va_end(pvar); } /* - * dbglog - log a debug message. + * ppp_dbglog - log a debug message. */ -void dbglog(char *fmt, ...) { +void ppp_dbglog(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); - logit(LOG_DEBUG, fmt, pvar); + ppp_logit(LOG_DEBUG, fmt, pvar); va_end(pvar); } #if PRINTPKT_SUPPORT /* - * dump_packet - print out a packet in readable form if it is interesting. + * ppp_dump_packet - print out a packet in readable form if it is interesting. * Assumes len >= PPP_HDRLEN. */ -void dump_packet(const char *tag, unsigned char *p, int len) { +void ppp_dump_packet(const char *tag, unsigned char *p, int len) { int proto; /* @@ -737,7 +737,7 @@ void dump_packet(const char *tag, unsigned char *p, int len) { return; } - dbglog("%s %P", tag, p, len); + ppp_dbglog("%s %P", tag, p, len); } #endif /* PRINTPKT_SUPPORT */ @@ -796,14 +796,14 @@ lock(dev) result = mklock (dev, (void *) 0); if (result == 0) { - strlcpy(lock_file, dev, sizeof(lock_file)); + ppp_strlcpy(lock_file, dev, sizeof(lock_file)); return 0; } if (result > 0) - notice("Device %s is locked by pid %d", dev, result); + ppp_notice("Device %s is locked by pid %d", dev, result); else - error("Can't create lock file %s", lock_file); + ppp_error("Can't create lock file %s", lock_file); return -1; #else /* LOCKLIB */ @@ -815,14 +815,14 @@ lock(dev) struct stat sbuf; if (stat(dev, &sbuf) < 0) { - error("Can't get device number for %s: %m", dev); + ppp_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); + ppp_error("Can't lock %s: not a character device", dev); return -1; } - slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", + ppp_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 @@ -841,12 +841,12 @@ lock(dev) if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); + ppp_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); + ppp_error("Can't create lock file %s: %m", lock_file); break; } @@ -855,7 +855,7 @@ lock(dev) if (fd < 0) { if (errno == ENOENT) /* This is just a timing problem. */ continue; - error("Can't open existing lock file %s: %m", lock_file); + ppp_error("Can't open existing lock file %s: %m", lock_file); break; } #ifndef LOCK_BINARY @@ -866,7 +866,7 @@ lock(dev) close(fd); fd = -1; if (n <= 0) { - error("Can't read pid from lock file %s", lock_file); + ppp_error("Can't read pid from lock file %s", lock_file); break; } @@ -880,12 +880,12 @@ lock(dev) if (pid == 0 || (kill(pid, 0) == -1 && errno == ESRCH)) { if (unlink (lock_file) == 0) { - notice("Removed stale lock on %s (pid %d)", dev, pid); + ppp_notice("Removed stale lock on %s (pid %d)", dev, pid); continue; } - warn("Couldn't remove stale lock on %s", dev); + ppp_warn("Couldn't remove stale lock on %s", dev); } else - notice("Device %s is locked by pid %d", dev, pid); + ppp_notice("Device %s is locked by pid %d", dev, pid); break; } @@ -896,7 +896,7 @@ lock(dev) pid = getpid(); #ifndef LOCK_BINARY - slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); + ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); write (fd, lock_buffer, 11); #else write(fd, &pid, sizeof (pid)); @@ -932,13 +932,13 @@ relock(pid) return -1; fd = open(lock_file, O_WRONLY, 0); if (fd < 0) { - error("Couldn't reopen lock file %s: %m", lock_file); + ppp_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); + ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); write (fd, lock_buffer, 11); #else write(fd, &pid, sizeof(pid)); From 773a2767c7a259618a3f7fe4803b5373d5c2c54c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 21 Aug 2012 20:26:37 +0200 Subject: [PATCH 265/320] PPP, added missing pppapi_delete() thread safe function --- src/api/pppapi.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/api/pppapi.c b/src/api/pppapi.c index 341a945a..f06aa797 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -267,6 +267,27 @@ void pppapi_sighup(ppp_pcb *pcb) { } +/** + * Call ppp_delete() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_delete(struct pppapi_msg_msg *msg) { + msg->err = ppp_delete(msg->ppp); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_delete() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int pppapi_delete(ppp_pcb *pcb) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_delete; + msg.msg.ppp = pcb; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} + + /** * Call ppp_ioctl() inside the tcpip_thread context. */ From 3b939480a48bed390e093bc48a433dad9a9e54e7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 22 Aug 2012 11:41:07 +0200 Subject: [PATCH 266/320] PPP, added missing entry in pppapi.h --- src/include/lwip/pppapi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index a4d5b356..f5713acb 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -131,6 +131,7 @@ int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, void pppapi_reopen(ppp_pcb *pcb, u16_t holdoff); int pppapi_close(ppp_pcb *pcb); void pppapi_sighup(ppp_pcb *pcb); +int pppapi_delete(ppp_pcb *pcb); int pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg); #if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD void ppposapi_input(ppp_pcb *pcb, u_char* data, int len); From 076f1771008a8435ff97b8ddd269f29775b4f1aa Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 22 Aug 2012 17:40:23 +0200 Subject: [PATCH 267/320] Added PPPd follow-up file, so that we can track what is happening on pppd. The lwIP PPP support is based from pppd 2.4.5 (http://ppp.samba.org) with huge changes to match code size and memory requirements for embedded devices. Anyway, pppd has a mature codebase for years and the average commit count is getting low on their Git repositories, meaning that we can follow what is happening on their side and merge what is relevant for lwIP. So, here is the pppd follow up, so that we don't get away too far from pppd. --- src/netif/ppp/PPPD_FOLLOWUP | 170 ++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/netif/ppp/PPPD_FOLLOWUP diff --git a/src/netif/ppp/PPPD_FOLLOWUP b/src/netif/ppp/PPPD_FOLLOWUP new file mode 100644 index 00000000..af899952 --- /dev/null +++ b/src/netif/ppp/PPPD_FOLLOWUP @@ -0,0 +1,170 @@ +The lwIP PPP support is based from pppd 2.4.5 (http://ppp.samba.org) with +huge changes to match code size and memory requirements for embedded devices. + +Anyway, pppd has a mature codebase for years and the average commit count +is getting low on their Git repositories, meaning that we can follow what +is happening on their side and merge what is relevant for lwIP. + +So, here is the pppd follow up, so that we don't get away too far from pppd. + + +== Patch fetched from from pppd Debian packages == + +This has nothing to do with pppd, but we merged some good patch from +Debian and this is a good place to be. + +- LCP adaptive echo, so that we don't send LCP echo request if we + are receiving data from peer, can be enabled by setting PPP_LCP_ADAPTIVE + to true. + +- IPCP no/replace default route option, were added in the early stage of + the ppp port, but it wasn't really helpful and was disabled when adding + the new API ppp_set_default() call, which gives the lwIP user control over + which one is the default interface, it was actually a requirement if you + are doing PPP over PPP (i.e. PPPoL2TP, VPN link, over PPPoE, ADSL link). + +- using rp-pppoe pppd exits with EXIT_OK after receiving a timeout waiting + for PADO due to no modem attached, bug reported to pppd bug tracker, fixed + in Debian but not in the latest (at the time where the port where started) + pppd release. + + +== Commits on pppd == + +2010-03-06 - Document +ipv6 and ipv6cp-accept-local + e7537958aee79b3f653c601e903cb31d78fb7dcc + +Don't care. + + +2010-03-06 - Install pppol2tp plugins with sane permissions + 406215672cfadc03017341fe03802d1c7294b903 + +Don't care. + + +2010-03-07 - pppd: Terminate correctly if lcp_lowerup delayed calling + fsm_lowerup + 3eb9e810cfa515543655659b72dde30c54fea0a5 + +Merged 2012-05-17. + + +2010-03-07 - rp_pppoe: Copy acName and pppd_pppoe_service after option parsing + cab58617fd9d328029fffabc788020264b4fa91f + +Don't care, is a patch for pppd/plugins/rp-pppoe/plugin.c which is not part +of the port. + + +2010-08-23 - set and reset options to control environment variables + for scripts. + 2b6310fd24dba8e0fca8999916a162f0a1842a84 + +We can't fork processes in embedded, therefore all the pppd process run +feature is disabled in the port, so we don't care about the new +"environment variables" pppd feature. + + +2010-08-23 - Nit: use _exit when exec fails and restrict values to 0-255 + per POSIX. + 2b4ea140432eeba5a007c0d4e6236bd0e0c12ba4 + +Again, we are not running as a heavy process, so all exit() or _exit() calls +were removed. + + +2010-08-23 - Fix quote handling in configuration files to be more like shell + quoting. + 3089132cdf5b58dbdfc2daf08ec5c08eb47f8aca + +We are not parsing config file, all the filesystem I/O stuff were disabled +in our port. + + +2010-08-24 - rp-pppoe: allow MTU to be increased up to 1500 + fd1dcdf758418f040da3ed801ab001b5e46854e7 + +Only concern changes on RP-PPPoE plugin, which we don't use. + + +2010-09-11 - chat: Allow TIMEOUT value to come from environment variable + ae80bf833e48a6202f44a935a68083ae52ad3824 + +See 2b6310fd24dba8e0fca8999916a162f0a1842a84. + + +2011-03-05 - pppdump: Fix printfs with insufficient arguments + 7b8db569642c83ba3283745034f2e2c95e459423 + +pppdump is a ppp tool outside pppd source tree. + + +2012-05-06 - pppd: Don't unconditionally disable VJ compression under Linux + d8a66adf98a0e525cf38031b42098d539da6eeb6 + +Patch for sys-linux.c, which we don't use. + + +2012-05-20 - Remove old version of Linux if_pppol2tp.h + c41092dd4c49267f232f6cba3d31c6c68bfdf68d + +Not in the port. + + +2012-05-20 - pppd: Make MSCHAP-v2 cope better with packet loss + 08ef47ca532294eb428238c831616748940e24a2 + +This is an interesting patch. However it consumes much more memory for +MSCHAP and I am not sure if the benefit worth it. The PPP client can +always start the authentication again if it failed for whatever reason. + + +2012-05-20 - scripts: Make poff ignore extra arguments to pppd + 18f515f32c9f5723a9c2c912601e04335106534b + +Again, we are not running scripts. + + +2012-05-20 - rp-pppoe plugin: Print leading zeros in MAC address + f5dda0cfc220c4b52e26144096d729e27b30f0f7 + +Again, we are not using the RP-PPPoE plugin. + + +2012-05-20 - pppd: Notify IPv6 up/down as we do for IPv4 + 845cda8fa18939cf56e60b073f63a7efa65336fc + +This is just a patch that adds plugins hooks for IPv6, the plugin interface +was disabled because we don't have .so plugins in embedded. + + +2012-05-20 - pppd: Enable IPV6 by default and fix some warnings + 0b6118239615e98959f7e0b4e746bdd197533248 + +Change on Makefile for IPv6, warnings were already cleared during port. + + +2012-05-20 - contrib: Fix pppgetpass.gtk compilation + 80a8e2ce257ca12cce723519a0f20ea1d663b14a + +Change on Makefile, don't care. + + +2012-05-20 - pppd: Don't crash if crypt() returns NULL + 04c4348108d847e034dd91066cc6843f60d71731 + +We are using the PolarSSL DES implementation that does not return NULL. + + +2012-05-20 - pppd: Eliminate some warnings + c44ae5e6a7338c96eb463881fe709b2dfaffe568 + +Again, we are handling compilation warnings on our own. + + +2012-05-20 - rp-pppoe plugin: Import some fixes from rp-pppoe-3.10 + 1817d83e51a411044e730ba89ebdb0480e1c8cd4 + +Once more, we are not using the RP-PPPoE plugin. + From 4f8198b298850ae2d2c9052e0867743d6164218e Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 22 Aug 2012 20:14:45 +0200 Subject: [PATCH 268/320] Added ChangeLog entry reporting all the work done in the ppp-new branch. --- CHANGELOG | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index b3f6890f..969325bc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,71 @@ HISTORY ++ New features: + 2012-08-22: Sylvain Rochet + * New PPP stack for lwIP, developed in ppp-new branch. + Based from pppd 2.4.5, released 2009-11-17, with huge changes to match + code size and memory requirements for embedded devices, including: + - Gluing together the previous low-level PPP code in lwIP to pppd 2.4.5, which + is more or less what pppd sys-* files are, so that we get something working + using the unix port. + - Merged some patchs from lwIP Git repository which add interesting features + or fix bugs. + - Merged some patchs from Debian pppd package which add interesting features + or fix bugs. + - Ported PPP timeout handling to the lwIP timers system + - Disabled all the PPP code using filesystem access, replaced in necessary cases + to configuration variables. + - Disabled all the PPP code forking processes. + - Removed IPX support, lwIP does not support IPX. + - Ported and improved random module from the previous PPP port. + - Removed samba TDB (file-driven database) usage, because it needs a filesystem. + - MS-CHAP required a DES implementation, we added the latest PolarSSL DES + implementation which is under a BSD-ish license. + - Also switched to PolarSSL MD4,MD5,SHA1 implementations, which are meant to be + used in embedded devices with reduced memory footprint. + - Removed PPP configuration file parsing support. + - Added macro definition EAP_SUPPORT to make EAP support optional. + - Added macro definition CHAP_SUPPORT to make CHAP support optional. + - Added macro definition MSCHAP_SUPPORT to make MSCHAP support optional. + - Added macro definition PAP_SUPPORT to make PAP support optional. + - Cleared all Linux syscall calls. + - Disabled demand support using a macro, so that it can be ported later. + - Disabled ECP support using a macro, so that it can be ported later. + - Disabled CCP support using a macro, so that it can be ported later. + - Disabled CBCP support using a macro, so that it can be ported later. + - Disabled LQR support using a macro, so that it can be ported later. + - Print packet debug feature optional, through PRINTPKT_SUPPORT + - Removed POSIX signal usage. + - Fully ported PPPoS code from the previous port. + - Fully ported PPPoE code from the previous port. + - Fully ported VJ compression protocol code from the previous port. + - Removed all malloc()/free() use from PPP, replaced by stack usage or PBUF. + - Disabled PPP server support using a macro, so that it can be ported later. + - Switched all PPP debug to lwIP debug system. + - Created PPP Control Block (PPP PCB), removed PPP unit integer everywhere, + removed all global variables everywhere, did everything necessary for + the PPP stack to support more than one PPP session (pppd only support + one session per process). + - Removed the statically allocated output buffer, now using PBUF. + - Improved structure size of all PPP modules, deep analyze of code to reduce + variables size to the bare minimum. Switched all boolean type (char type in + most architecture) to compiler generated bitfields. + - Added PPP IPv6 support, glued lwIP IPv6 support to PPP. + - Now using a persistent netif interface which can then be used in lwIP + functions requiring a netif. + - Now initializing PPP in lwip_init() function. + - Reworked completely the PPP state machine, so that we don't end up in + anymore in inconsistent state, especially with PPPoE. + - Improved the way we handle PPP reconnection after disconnect, cleaning + everything required so that we start the PPP connection again from a + clean state. + - Added PPP holdoff support, allow the lwIP user to wait a little bit before + reconnecting, prevents connection flood, especially when using PPPoL2TP. + - Added PPPoL2TP LAC support (a.k.a. UDP tunnels), adding a VPN client + feature to lwIP, L2TP being a widely used tunnel protocol. + - Switched all used PPP types to lwIP types (u8t, u16t, u32t, ...) + - Added PPP API "sequential" thread-safe API, based from NETIFAPI. + 2012-03-25: Simon Goldschmidt (idea by Mason) * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h which are a simple wrapper to the correct lwIP include files. From ad5f520c68178fbd9e8d1fe19b7c616b7e6354f4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 23 Aug 2012 20:47:14 +0200 Subject: [PATCH 269/320] PPP, updated pppapi_reopen() to follow ppp_reopen() prototype change --- src/api/pppapi.c | 5 +++-- src/include/lwip/pppapi.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/api/pppapi.c b/src/api/pppapi.c index f06aa797..50f8369e 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -209,7 +209,7 @@ int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, * Call ppp_reopen() inside the tcpip_thread context. */ static void pppapi_do_ppp_reopen(struct pppapi_msg_msg *msg) { - ppp_reopen(msg->ppp, msg->msg.reopen.holdoff); + msg->err = ppp_reopen(msg->ppp, msg->msg.reopen.holdoff); TCPIP_PPPAPI_ACK(msg); } @@ -217,12 +217,13 @@ static void pppapi_do_ppp_reopen(struct pppapi_msg_msg *msg) { * Call ppp_reopen() in a thread-safe way by running that function inside the * tcpip_thread context. */ -void pppapi_reopen(ppp_pcb *pcb, u16_t holdoff) { +int pppapi_reopen(ppp_pcb *pcb, u16_t holdoff) { struct pppapi_msg msg; msg.function = pppapi_do_ppp_reopen; msg.msg.ppp = pcb; msg.msg.msg.reopen.holdoff = holdoff; TCPIP_PPPAPI(&msg); + return msg.msg.err; } diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index f5713acb..c889b5bf 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -128,7 +128,7 @@ int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ -void pppapi_reopen(ppp_pcb *pcb, u16_t holdoff); +int pppapi_reopen(ppp_pcb *pcb, u16_t holdoff); int pppapi_close(ppp_pcb *pcb); void pppapi_sighup(ppp_pcb *pcb); int pppapi_delete(ppp_pcb *pcb); From 7920b6e163a99de5f1eeacc20707ef833487ff87 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 25 Aug 2012 16:21:58 +0200 Subject: [PATCH 270/320] PPP, don't allocate twice struct eth_hdr per PPPoE pbuf --- src/include/netif/ppp/pppoe.h | 3 --- src/netif/ppp/ppp.c | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/include/netif/ppp/pppoe.h b/src/include/netif/ppp/pppoe.h index 8385d9af..37a72828 100644 --- a/src/include/netif/ppp/pppoe.h +++ b/src/include/netif/ppp/pppoe.h @@ -178,9 +178,6 @@ void pppoe_data_input(struct netif *netif, struct pbuf *p); err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); -/** used in ppp.c */ -#define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN) - #endif /* PPP_OE_H */ #endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 9a6bbd10..3a8750b7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1307,7 +1307,7 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_shor u16_t tot_len; /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); + pb = pbuf_alloc(PBUF_LINK, PPPOE_HEADERLEN + sizeof(protocol), PBUF_RAM); if(!pb) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); @@ -1315,7 +1315,7 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_shor return ERR_MEM; } - pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + pbuf_header(pb, -(s16_t)PPPOE_HEADERLEN); pcb->last_xmit = sys_jiffies(); @@ -1538,7 +1538,7 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { /* skip address & flags */ pbuf_header(p, -(s16_t)2); - ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN), PBUF_RAM); + ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); if(!ph) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); @@ -1547,7 +1547,7 @@ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { return PPPERR_ALLOC; } - pbuf_header(ph, -(s16_t)PPPOE_HDRLEN); /* hide PPPoE header */ + pbuf_header(ph, -(s16_t)PPPOE_HEADERLEN); /* hide PPPoE header */ pbuf_cat(ph, p); tot_len = ph->tot_len; From 19864a4a085cec256a44134050a6364b1cc1f0ad Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 25 Aug 2012 18:15:15 +0200 Subject: [PATCH 271/320] PPP L2TP, only skip HDLC header if necessary RFC 2661 does not specify whether the PPP frame in the L2TP payload should have a HDLC header or not. We handle both cases for compatibility. --- src/netif/ppp/pppol2tp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index 3a8eb7d8..fe5badf1 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -316,8 +316,16 @@ static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struc PPPDEBUG(LOG_DEBUG, ("pppol2tp: session ID mismatch, assigned=%d, received=%d\n", l2tp->remote_session_id, session_id)); goto free_and_return; } - /* skip address & flags */ - pbuf_header(p, -(s16_t)2); + /* + * skip address & flags if necessary + * + * RFC 2661 does not specify whether the PPP frame in the L2TP payload should + * have a HDLC header or not. We handle both cases for compatibility. + */ + GETSHORT(hflags, inp); + if (hflags == 0xff03) { + pbuf_header(p, -(s16_t)2); + } /* Dispatch the packet thereby consuming it. */ ppp_input(l2tp->ppp, p); return; From 6144deb6b65c0216c7a52559bc8910a0fe698bb7 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 25 Aug 2012 20:30:14 +0200 Subject: [PATCH 272/320] PPP, moved out PPPoS code into their own functions, improved ppp.c readability --- src/netif/ppp/ppp.c | 99 +++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 3a8750b7..694160f4 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -182,28 +182,28 @@ struct protent *protocols[] = { NULL }; -#if PPPOS_SUPPORT -#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & ppp_accm_mask[c & 0x07]) -#endif /* PPPOS_SUPPORT */ - /* Prototypes for procedures local to this file. */ static void ppp_clear(ppp_pcb *pcb); - static void ppp_do_reopen(void *arg); - static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ - -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD -static void ppp_receive_wakeup(ppp_pcb *pcb); -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ - static void ppp_stop(ppp_pcb *pcb); static void ppp_hup(ppp_pcb *pcb); +static err_t ppp_netif_init_cb(struct netif *netif); +static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); +#if PPP_IPV6_SUPPORT +static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr_t *ipaddr); +#endif /* PPP_IPV6_SUPPORT */ +static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol); + #if PPPOS_SUPPORT +#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & ppp_accm_mask[c & 0x07]) static void ppp_over_serial_reopen(ppp_pcb *pcb); +static err_t ppp_netif_output_over_serial(ppp_pcb *pcb, struct pbuf *pb, u_short protocol); +static int ppp_write_over_serial(ppp_pcb *pcb, struct pbuf *p); #if PPP_INPROC_OWNTHREAD static void ppp_input_thread(void *arg); +static void ppp_receive_wakeup(ppp_pcb *pcb); #endif /* PPP_INPROC_OWNTHREAD */ static void ppp_drop(ppp_pcb_rx *pcrx); static void pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l); @@ -213,24 +213,15 @@ static void pppos_input_callback(void *arg); static void ppp_free_current_input_packet(ppp_pcb_rx *pcrx); #endif /* PPPOS_SUPPORT */ -static err_t ppp_netif_init_cb(struct netif *netif); -static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); -#if PPP_IPV6_SUPPORT -static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr_t *ipaddr); -#endif /* PPP_IPV6_SUPPORT */ -static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol); - #if PPPOE_SUPPORT static void ppp_over_ethernet_reopen(ppp_pcb *pcb); static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol); -/* function called by ppp_write() */ static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT static void ppp_over_l2tp_reopen(ppp_pcb *pcb); static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short protocol); -/* function called by ppp_write() */ static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p); #endif /* PPPOL2TP_SUPPORT */ @@ -740,7 +731,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { switch(protocol) { -#if PPPOS_SUPPORT && VJ_SUPPORT +#if VJ_SUPPORT case PPP_VJC_COMP: /* VJ compressed TCP */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->num, pb->len)); /* @@ -768,7 +759,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { /* Something's wrong so drop it. */ PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->num)); break; -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ +#endif /* VJ_SUPPORT */ case PPP_IP: /* Internet Protocol */ PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->num, pb->len)); @@ -1152,11 +1143,6 @@ static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr */ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol) { ppp_pcb *pcb = (ppp_pcb*)netif->state; -#if PPPOS_SUPPORT - u_int fcs_out = PPP_INITFCS; - struct pbuf *head = NULL, *tail = NULL, *p; - u_char c; -#endif /* PPPOS_SUPPORT */ /* Validate parameters. */ /* We let any protocol value go through - it can't hurt us @@ -1192,13 +1178,25 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot #endif /* PPPOL2TP_SUPPORT */ #if PPPOS_SUPPORT + return ppp_netif_output_over_serial(pcb, pb, protocol); +#endif /* PPPOS_SUPPORT */ + + return ERR_OK; +} + +#if PPPOS_SUPPORT +static err_t ppp_netif_output_over_serial(ppp_pcb *pcb, struct pbuf *pb, u_short protocol) { + u_int fcs_out = PPP_INITFCS; + struct pbuf *head = NULL, *tail = NULL, *p; + u_char c; + /* Grab an output buffer. */ head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (head == NULL) { PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: first alloc fail\n", pcb->num)); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); + snmp_inc_ifoutdiscards(&pcb->netif); return ERR_MEM; } @@ -1223,7 +1221,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->num)); LINK_STATS_INC(link.proterr); LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); + snmp_inc_ifoutdiscards(&pcb->netif); pbuf_free(head); return ERR_VAL; } @@ -1286,7 +1284,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot pbuf_free(head); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); - snmp_inc_ifoutdiscards(netif); + snmp_inc_ifoutdiscards(&pcb->netif); return ERR_MEM; } @@ -1294,11 +1292,9 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot PPPDEBUG(LOG_INFO, ("ppp_netif_output[%d]: proto=0x%"X16_F"\n", pcb->num, protocol)); pppos_put(pcb, head); -#endif /* PPPOS_SUPPORT */ - return ERR_OK; } - +#endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol) { @@ -1445,14 +1441,6 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) * -1 Failed to write to device */ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { -#if PPPOS_SUPPORT - u_char *s = p->payload; - int n = p->len; - u_char c; - u_int fcs_out; - struct pbuf *head, *tail; -#endif /* PPPOS_SUPPORT */ - #if PRINTPKT_SUPPORT ppp_dump_packet("sent", (unsigned char *)p->payload+2, p->len-2); #endif /* PRINTPKT_SUPPORT */ @@ -1470,6 +1458,21 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { #endif /* PPPOL2TP_SUPPORT */ #if PPPOS_SUPPORT + return ppp_write_over_serial(pcb, p); +#endif /* PPPOS_SUPPORT */ + + pbuf_free(p); + return PPPERR_NONE; +} + +#if PPPOS_SUPPORT +static int ppp_write_over_serial(ppp_pcb *pcb, struct pbuf *p) { + u_char *s = p->payload; + int n = p->len; + u_char c; + u_int fcs_out; + struct pbuf *head, *tail; + head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (head == NULL) { LINK_STATS_INC(link.memerr); @@ -1524,11 +1527,10 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pcb->num, head->len)); /* "ppp_write[%d]: %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ pppos_put(pcb, head); -#endif /* PPPOS_SUPPORT */ - pbuf_free(p); return PPPERR_NONE; } +#endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { @@ -2032,6 +2034,17 @@ static void ppp_over_l2tp_reopen(ppp_pcb *pcb) { void ppp_link_down(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pcb->num)); +#if PPPOE_SUPPORT + if (pcb->ethif) { + return; + } +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + return; + } +#endif /* PPPOL2TP_SUPPORT */ + #if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD ppp_receive_wakeup(pcb); #endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ From b84ab718b02dfeaa452093592f0c182f0f87b64d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 25 Aug 2012 20:38:54 +0200 Subject: [PATCH 273/320] PPP, ppp_input() code cleaning, removed dead code, fixed indentation --- src/netif/ppp/ppp.c | 154 ++++++++------------------------------------ 1 file changed, 28 insertions(+), 126 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 694160f4..8b4ccbf7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -775,17 +775,17 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { default: { - int i; - struct protent *protp; - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - pb = ppp_singlebuf(pb); - (*protp->input)(pcb, pb->payload, pb->len); - goto out; - } + int i; + struct protent *protp; + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + pb = ppp_singlebuf(pb); + (*protp->input)(pcb, pb->payload, pb->len); + goto out; + } #if 0 /* UNUSED * * This is actually a (hacked?) way for the PPP kernel implementation to pass a @@ -795,31 +795,31 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { * This is only used by CCP, which we cannot support until we have a CCP data * implementation. */ - if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag - && protp->datainput != NULL) { - (*protp->datainput)(pcb, pb->payload, pb->len); - goto out; - } + if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag + && protp->datainput != NULL) { + (*protp->datainput)(pcb, pb->payload, pb->len); + goto out; + } #endif /* UNUSED */ - } + } #if PPP_DEBUG #if PPP_PROTOCOLNAME - const char *pname = protocol_name(protocol); - if (pname != NULL) - ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); - else + const char *pname = protocol_name(protocol); + if (pname != NULL) { + ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); + } else #endif /* PPP_PROTOCOLNAME */ - ppp_warn("Unsupported protocol 0x%x received", protocol); + ppp_warn("Unsupported protocol 0x%x received", protocol); #endif /* PPP_DEBUG */ - if (pbuf_header(pb, (s16_t)sizeof(protocol))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } - lcp_sprotrej(pcb, pb->payload, pb->len); + if (pbuf_header(pb, (s16_t)sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + lcp_sprotrej(pcb, pb->payload, pb->len); } break; - } + } drop: LINK_STATS_INC(link.drop); @@ -829,104 +829,6 @@ out: pbuf_free(pb); magic_randomize(); return; - -#if 0 - /* - * Toss all non-LCP packets unless LCP is OPEN. - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if((lcp_phase[pcb->unit] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { - if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || - (lcp_phase[pcb->unit] != PHASE_AUTHENTICATE)) { - PPPDEBUG(LOG_INFO, ("ppp_input: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pcb->unit])); - goto drop; - } - } - - switch(protocol) { - case PPP_VJC_COMP: /* VJ compressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->unit, pb->len)); - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - if ((vj_uncompress_tcp(&pb, pcb->vj_comp) >= 0) && (pcb->netif.input)) { - pcb->netif.input(pb, pcb->netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->unit)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: drop VJ Comp in %d:%s\n", pcb->unit, pb->len, pb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ -#if PPPOS_SUPPORT && VJ_SUPPORT - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->unit, pb->len)); - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - if ((vj_uncompress_uncomp(pb, pcb->vj_comp) >= 0) && pcb->netif.input) { - pcb->netif.input(pb, pcb->netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->unit)); -#else /* PPPOS_SUPPORT && VJ_SUPPORT */ - /* No handler for this protocol so drop the packet. */ - PPPDEBUG(LOG_INFO, - ("ppp_input[%d]: drop VJ UnComp in %d:.*H\n", - pcb->unit, pb->len, LWIP_MIN(pb->len * 2, 40), pb->payload)); -#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ - break; - - case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->unit, pb->len)); - if (pcb->netif.input) { - pcb->netif.input(pb, pcb->netif); - return; - } - break; - - default: { - struct protent *protp; - int i; - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: %s len=%d\n", pcb->unit, protp->name, pb->len)); - pb = ppp_singlebuf(pb); - (*protp->input)(pcb->unit, pb->payload, pb->len); - PPPDEBUG(LOG_DETAIL, ("ppp_input[%d]: packet processed\n", pcb->unit)); - goto out; - } - } - - /* No handler for this protocol so reject the packet. */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pcb->unit, protocol, pb->len)); - if (pbuf_header(pb, sizeof(protocol))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } -#if BYTE_ORDER == LITTLE_ENDIAN - protocol = htons(protocol); -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - SMEMCPY(pb->payload, &protocol, sizeof(protocol)); - lcp_sprotrej(pcb->unit, pb->payload, pb->len); - } - break; - } -#endif - - } #if PPPOS_SUPPORT From 045ee53468293f961bb4ad7aa3703254283679d5 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 27 Aug 2012 00:47:21 +0200 Subject: [PATCH 274/320] PPP, using PBUF_POOL instead of PBUF_RAM pbufs for PPP negociation packets PPP stack does not handle chained pbuf, but PPP negociation packets are at most ~40 bytes long, so we are only checking if the payload can fit into the allocated pbuf (p->tot_len == p->len). --- src/netif/ppp/chap-new.c | 18 ++++++++++++--- src/netif/ppp/eap.c | 49 ++++++++++++++++++++++++++++++++-------- src/netif/ppp/fsm.c | 13 ++++++++--- src/netif/ppp/lcp.c | 7 +++++- src/netif/ppp/upap.c | 12 ++++++++-- 5 files changed, 81 insertions(+), 18 deletions(-) diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index d462d856..5d71de0b 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -240,9 +240,13 @@ static void chap_timeout(void *arg) { return; } - p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); ppp_write(pcb, p); ++pcb->chap_server.challenge_xmits; @@ -334,9 +338,13 @@ static void chap_handle_response(ppp_pcb *pcb, int id, /* send the response */ mlen = strlen(pcb->chap_server.message); len = CHAP_HDRLEN + mlen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; MAKEHEADER(outp, PPP_CHAP); @@ -427,9 +435,13 @@ static void chap_respond(ppp_pcb *pcb, int id, char rname[MAXNAMELEN+1]; char secret[MAXSECRETLEN+1]; - p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) return; /* not ready */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 3b32a1e4..235c0cd3 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -266,9 +266,13 @@ eap_state *esp; struct pbuf *p; u_char *outp; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; @@ -297,9 +301,13 @@ eap_state *esp; struct pbuf *p; u_char *outp; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; @@ -696,10 +704,13 @@ eap_state *esp; return; } - /* FIXME: improve buffer size */ - p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->peer_mru+PPP_HDRLEN), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PBUF_POOL_BUFSIZE), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; @@ -1059,9 +1070,13 @@ static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, u_char *s int msglen; msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; @@ -1089,9 +1104,13 @@ static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, char *name, msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + namelen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; @@ -1130,9 +1149,13 @@ int lenstr; int msglen; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; @@ -1168,9 +1191,13 @@ u_char *str; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u32_t) + SHA_DIGESTSIZE; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; @@ -1195,9 +1222,13 @@ static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { int msglen; msglen = EAP_HEADERLEN + 2 * sizeof (u_char); - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 89638d61..04f2f26d 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -706,10 +706,13 @@ static void fsm_sconfreq(fsm *f, int retransmit) { f->seen_ack = 0; - /* FIXME: improve buffer size */ - p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->peer_mru+PPP_HDRLEN), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PBUF_POOL_BUFSIZE), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } /* * Make up the request packet @@ -756,9 +759,13 @@ void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { datalen = pcb->peer_mru - HEADERLEN; outlen = datalen + HEADERLEN; - p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; /* if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) -- was only for fsm_sconfreq() */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index f1445519..cb44e687 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1779,9 +1779,14 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { * Process all his options. */ next = inp; - nakp = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->peer_mru), PBUF_RAM); + nakp = pbuf_alloc(PBUF_RAW, (u16_t)(PBUF_POOL_BUFSIZE), PBUF_POOL); if(NULL == nakp) return 0; + if(nakp->tot_len != nakp->len) { + pbuf_free(nakp); + return 0; + } + nakoutp = nakp->payload; rejp = inp; while (l) { diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 0de5a57d..fd470ac8 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -530,9 +530,13 @@ static void upap_sauthreq(ppp_pcb *pcb) { outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + pcb->upap.us_userlen + pcb->upap.us_passwdlen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; MAKEHEADER(outp, PPP_PAP); @@ -563,9 +567,13 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl int outlen; outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PBUF_RAM); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PBUF_POOL); if(NULL == p) return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } outp = p->payload; MAKEHEADER(outp, PPP_PAP); From a1c87f7c49fbb4098ffe871f6de2de9776a56cf6 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 27 Aug 2012 19:10:09 +0200 Subject: [PATCH 275/320] PPP, improved fsm_sconfreq() allocated buffer size --- src/netif/ppp/fsm.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 04f2f26d..8ffc7cfd 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -706,7 +706,17 @@ static void fsm_sconfreq(fsm *f, int retransmit) { f->seen_ack = 0; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PBUF_POOL_BUFSIZE), PBUF_POOL); + /* + * Make up the request packet + */ + if( f->callbacks->cilen && f->callbacks->addci ){ + cilen = (*f->callbacks->cilen)(f); + if( cilen > pcb->peer_mru - HEADERLEN ) + cilen = pcb->peer_mru - HEADERLEN; + } else + cilen = 0; + + p = pbuf_alloc(PBUF_RAW, (u16_t)(cilen + HEADERLEN + PPP_HDRLEN), PBUF_POOL); if(NULL == p) return; if(p->tot_len != p->len) { @@ -714,27 +724,16 @@ static void fsm_sconfreq(fsm *f, int retransmit) { return; } - /* - * Make up the request packet - */ - outp = (u_char*)p->payload + PPP_HDRLEN + HEADERLEN; - if( f->callbacks->cilen && f->callbacks->addci ){ - cilen = (*f->callbacks->cilen)(f); - if( cilen > pcb->peer_mru - HEADERLEN ) - cilen = pcb->peer_mru - HEADERLEN; - if (f->callbacks->addci) - (*f->callbacks->addci)(f, outp, &cilen); - } else - cilen = 0; - /* send the request to our peer */ outp = p->payload; MAKEHEADER(outp, f->protocol); PUTCHAR(CONFREQ, outp); PUTCHAR(f->reqid, outp); PUTSHORT(cilen + HEADERLEN, outp); + if (cilen != 0) { + (*f->callbacks->addci)(f, outp, &cilen); + } - pbuf_realloc(p, cilen + HEADERLEN + PPP_HDRLEN); ppp_write(pcb, p); /* start the retransmit timer */ From dbaefd6126651f44d5a97159cb9a7514264b3cbf Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 1 Sep 2012 14:43:31 +0200 Subject: [PATCH 276/320] PPP, cleaned persist and holdoff features --- src/include/netif/ppp/ppp.h | 6 ++---- src/netif/ppp/ppp.c | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 1bbf4a7e..93384e76 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -206,8 +206,6 @@ typedef struct ppp_settings_s { u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ - u16_t holdoff; /* time to wait (s) before re-initiating the link after it terminates */ - #if PPP_IDLETIMELIMIT u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ #endif /* PPP_IDLETIMELIMIT */ @@ -293,7 +291,7 @@ typedef struct ppp_pcb_rx_s { * PPP interface control block. */ struct ppp_pcb_s { - /* -- below are data that will NOT be cleared between two sessions if persist mode is enabled */ + /* -- below are data that will NOT be cleared between two sessions */ #if PPP_DEBUG u8_t num; /* Interface number - only useful for debugging */ #endif /* PPP_DEBUG */ @@ -312,7 +310,7 @@ struct ppp_pcb_s { void *link_status_ctx; /* Status change callback optional pointer */ struct netif netif; /* PPP interface */ - /* -- below are data that will be cleared between two sessions if persist mode is enabled */ + /* -- below are data that will be cleared between two sessions */ /* * phase must be the first member of cleared members, because it is used to know diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 8b4ccbf7..0e54d389 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -258,7 +258,6 @@ ppp_pcb *ppp_new(void) { /* default configuration */ pcb->settings.usepeerdns = 1; pcb->settings.persist = 1; - pcb->settings.holdoff = 30; #if CHAP_SUPPORT pcb->settings.chap_timeout_time = 3; pcb->settings.chap_max_transmits = 10; @@ -526,7 +525,6 @@ ppp_close(ppp_pcb *pcb) } PPPDEBUG(LOG_DEBUG, ("ppp_close() called\n")); - pcb->settings.persist = 0; /* FIXME: not necessary anymore since persistence is done through link status callback */ /* Disconnect */ #if PPPOE_SUPPORT From fbbde125d9489f07943b3905e77e86fbba061e33 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 1 Sep 2012 15:05:21 +0200 Subject: [PATCH 277/320] PPP, removed unnecessary ethif from ppp_pcb --- src/include/netif/ppp/ppp.h | 1 - src/netif/ppp/ppp.c | 20 +++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 93384e76..22ed321c 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -300,7 +300,6 @@ struct ppp_pcb_s { sio_fd_t fd; /* File device ID of port. */ #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT - struct netif *ethif; struct pppoe_softc *pppoe_sc; #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0e54d389..b453818b 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -406,8 +406,6 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic ppp_clear(pcb); new_phase(pcb, PHASE_INITIALIZE); - pcb->ethif = ethif; - pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; @@ -528,7 +526,7 @@ ppp_close(ppp_pcb *pcb) /* Disconnect */ #if PPPOE_SUPPORT - if (pcb->ethif) { + if (pcb->pppoe_sc) { PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); /* This will leave us at PHASE_DEAD. */ ppp_stop(pcb); @@ -582,7 +580,7 @@ int ppp_delete(ppp_pcb *pcb) { netif_remove(&pcb->netif); #if PPPOE_SUPPORT - if (pcb->ethif) { + if (pcb->pppoe_sc) { pppoe_destroy(&pcb->netif); } #endif /* PPPOE_SUPPORT */ @@ -632,7 +630,7 @@ static void ppp_do_reopen(void *arg) { new_phase(pcb, PHASE_INITIALIZE); #if PPPOE_SUPPORT - if (pcb->ethif) { + if (pcb->pppoe_sc) { ppp_over_ethernet_reopen(pcb); return; } @@ -1066,7 +1064,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot } #if PPPOE_SUPPORT - if(pcb->ethif) { + if(pcb->pppoe_sc) { return ppp_netif_output_over_ethernet(pcb, pb, protocol); } #endif /* PPPOE_SUPPORT */ @@ -1346,7 +1344,7 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { #endif /* PRINTPKT_SUPPORT */ #if PPPOE_SUPPORT - if(pcb->ethif) { + if(pcb->pppoe_sc) { return ppp_write_over_ethernet(pcb, p); } #endif /* PPPOE_SUPPORT */ @@ -1869,12 +1867,12 @@ static void ppp_over_ethernet_reopen(ppp_pcb *pcb) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; - wo->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + wo->mru = pcb->pppoe_sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ wo->neg_asyncmap = 0; wo->neg_pcompression = 0; wo->neg_accompression = 0; - ao->mru = pcb->ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + ao->mru = pcb->pppoe_sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ ao->neg_asyncmap = 0; ao->neg_pcompression = 0; ao->neg_accompression = 0; @@ -1935,7 +1933,7 @@ void ppp_link_down(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pcb->num)); #if PPPOE_SUPPORT - if (pcb->ethif) { + if (pcb->pppoe_sc) { return; } #endif /* PPPOE_SUPPORT */ @@ -1954,7 +1952,7 @@ void ppp_link_terminated(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d\n", pcb->num)); #if PPPOE_SUPPORT - if (pcb->ethif) { + if (pcb->pppoe_sc) { pppoe_disconnect(pcb->pppoe_sc); } else #endif /* PPPOE_SUPPORT */ From 387c778496f0973dd34d29fdc1cff00b5320f657 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 1 Sep 2012 19:29:17 +0200 Subject: [PATCH 278/320] PPP, added PPPoS reopen support --- src/netif/ppp/ppp.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index b453818b..d046d188 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -338,7 +338,6 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s ppp_free_current_input_packet(&pcb->rx); ppp_clear(pcb); - new_phase(pcb, PHASE_INITIALIZE); pcb->fd = fd; @@ -362,7 +361,7 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s /* * Start the connection and handle incoming events (packet or timeout). */ - PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: Connecting\n", pcb->num)); + PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: connecting\n", pcb->num)); ppp_start(pcb); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); @@ -404,7 +403,6 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic } ppp_clear(pcb); - new_phase(pcb, PHASE_INITIALIZE); pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; @@ -445,7 +443,6 @@ int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16 } ppp_clear(pcb); - new_phase(pcb, PHASE_INITIALIZE); pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; @@ -485,7 +482,6 @@ int ppp_reopen(ppp_pcb *pcb, u16_t holdoff) { } PPPDEBUG(LOG_DEBUG, ("ppp_reopen() called, holdoff=%d\n", holdoff)); - ppp_clear(pcb); if (holdoff == 0) { ppp_do_reopen(pcb); @@ -607,7 +603,7 @@ static void ppp_clear(ppp_pcb *pcb) { struct protent *protp; int i; - LWIP_ASSERT("pcb->phase == PHASE_DEAD", pcb->phase == PHASE_DEAD); + LWIP_ASSERT("pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF", pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF); #if PPP_STATS_SUPPORTs link_stats_valid = 0; @@ -622,12 +618,14 @@ static void ppp_clear(ppp_pcb *pcb) { for (i = 0; (protp = protocols[i]) != NULL; ++i) { (*protp->init)(pcb); } + + new_phase(pcb, PHASE_INITIALIZE); } static void ppp_do_reopen(void *arg) { ppp_pcb *pcb = (ppp_pcb*)arg; - new_phase(pcb, PHASE_INITIALIZE); + LWIP_ASSERT("pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF", pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF); #if PPPOE_SUPPORT if (pcb->pppoe_sc) { @@ -930,7 +928,33 @@ static err_t ppp_netif_init_cb(struct netif *netif) { #if PPPOS_SUPPORT static void ppp_over_serial_reopen(ppp_pcb *pcb) { -/* FIXME: fill me */ + /* input pbuf left over from last session? */ + ppp_free_current_input_packet(&pcb->rx); + + ppp_clear(pcb); + + pcb->rx.pcb = pcb; + pcb->rx.fd = pcb->fd; + +#if VJ_SUPPORT + vj_compress_init(&pcb->vj_comp); +#endif /* VJ_SUPPORT */ + + /* + * Default the in and out accm so that escape and flag characters + * are always escaped. + */ + pcb->rx.in_accm[15] = 0x60; /* no need to protect since RX is not running */ + pcb->out_accm[15] = 0x60; + + /* + * Start the connection and handle incoming events (packet or timeout). + */ + PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: connecting\n", pcb->num)); + ppp_start(pcb); +#if PPP_INPROC_OWNTHREAD + sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); +#endif /* PPP_INPROC_OWNTHREAD */ } #if PPP_INPROC_OWNTHREAD @@ -1867,6 +1891,8 @@ static void ppp_over_ethernet_reopen(ppp_pcb *pcb) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; + ppp_clear(pcb); + wo->mru = pcb->pppoe_sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ wo->neg_asyncmap = 0; wo->neg_pcompression = 0; @@ -1915,6 +1941,8 @@ static void ppp_over_l2tp_reopen(ppp_pcb *pcb) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; + ppp_clear(pcb); + wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ wo->neg_asyncmap = 0; wo->neg_pcompression = 0; From af56eebc6a6948591de8e03d55999b6ae7fc2b6c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 1 Sep 2012 19:44:43 +0200 Subject: [PATCH 279/320] PPP, cleaned MTU,MRU variables --- src/include/netif/ppp/ppp.h | 5 +---- src/netif/ppp/ppp.c | 5 ++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 22ed321c..66e711df 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -349,10 +349,6 @@ struct ppp_pcb_s { #endif /* VJ_SUPPORT */ #endif /* PPPOS_SUPPORT */ - /* FIXME: maybe we should cleanup one of those MTU variables */ - u16_t mtu; /* Peer's mru */ - u16_t peer_mru; /* currently negotiated peer MRU */ - u32_t last_xmit; /* Time of last transmission. */ struct ppp_addrs addrs; /* PPP addresses */ @@ -388,6 +384,7 @@ struct ppp_pcb_s { lcp_options lcp_hisoptions; /* Options that we ack'd */ u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ u8_t lcp_echo_number; /* ID number of next echo frame */ + u16_t peer_mru; /* currently negotiated peer MRU */ fsm ipcp_fsm; /* IPCP fsm structure */ ipcp_options ipcp_wantoptions; /* Options that we want to request */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index d046d188..fccda18f 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -2219,7 +2219,6 @@ int sifup(ppp_pcb *pcb) { netif_ip6_addr_set_state(&pcb->netif, 0, IP6_ADDR_PREFERRED); #endif /* PPP_IPV6_SUPPORT */ - pcb->netif.mtu = netif_get_mtu(pcb); netif_set_up(&pcb->netif); pcb->if_up = 1; pcb->err_code = PPPERR_NONE; @@ -2261,7 +2260,7 @@ int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) { */ void netif_set_mtu(ppp_pcb *pcb, int mtu) { - pcb->mtu = mtu; + pcb->netif.mtu = mtu; } /* @@ -2269,7 +2268,7 @@ void netif_set_mtu(ppp_pcb *pcb, int mtu) { */ int netif_get_mtu(ppp_pcb *pcb) { - return pcb->mtu; + return pcb->netif.mtu; } /******************************************************************** From e81f092520bcd567354f6f3209225aeaeca6907a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 27 Sep 2012 23:53:20 +0200 Subject: [PATCH 280/320] PPP, changed all the code enclosed between PPP_SERVER #if macro to our PPP PCB structure, making it easier to support PPP server in the future --- src/include/netif/ppp/chap-new.h | 9 +- src/include/netif/ppp/ppp.h | 5 +- src/include/netif/ppp/upap.h | 2 +- src/netif/ppp/auth.c | 29 ++++-- src/netif/ppp/chap-md5.c | 4 +- src/netif/ppp/chap-new.c | 22 ++--- src/netif/ppp/chap_ms.c | 12 +-- src/netif/ppp/eap.c | 153 +++++++++++++++---------------- src/netif/ppp/upap.c | 44 ++++----- 9 files changed, 143 insertions(+), 137 deletions(-) diff --git a/src/include/netif/ppp/chap-new.h b/src/include/netif/ppp/chap-new.h index d7f42f13..2730a8cb 100644 --- a/src/include/netif/ppp/chap-new.h +++ b/src/include/netif/ppp/chap-new.h @@ -64,6 +64,13 @@ #define MAX_CHALLENGE_LEN 64 #define MAX_RESPONSE_LEN 64 +/* + * These limits apply to challenge and response packets we send. + * The +4 is the +1 that we actually need rounded up. + */ +#define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) +#define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) + /* bitmask of supported algorithms */ #if MSCHAP_SUPPORT #define MDTYPE_MICROSOFT_V2 0x1 @@ -152,7 +159,7 @@ typedef struct chap_client_state { } chap_client_state; #if PPP_SERVER -static struct chap_server_state { +typedef struct chap_server_state { u8_t flags; int id; char *name; diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 66e711df..4676ae63 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -158,8 +158,9 @@ typedef struct ppp_settings_s { #if PPP_SERVER unsigned int auth_required : 1; /* Peer is required to authenticate */ + unsigned int null_login : 1; /* Username of "" and a password of "" are acceptable */ #else - unsigned int :1; /* 1 bit of padding */ + unsigned int :2; /* 2 bits of padding */ #endif /* PPP_SERVER */ #if PPP_REMOTENAME unsigned int explicit_remote : 1; /* remote_name specified with remotename opt */ @@ -202,7 +203,7 @@ typedef struct ppp_settings_s { #else unsigned int :1; /* 1 bit of padding */ #endif - unsigned int :2; /* 2 bits of padding to round out to 16 bits */ + unsigned int :1; /* 1 bit of padding to round out to 16 bits */ u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ diff --git a/src/include/netif/ppp/upap.h b/src/include/netif/ppp/upap.h index 2b58b750..ca051411 100644 --- a/src/include/netif/ppp/upap.h +++ b/src/include/netif/ppp/upap.h @@ -104,7 +104,7 @@ typedef struct upap_state { u8_t us_passwdlen; /* Password length */ u8_t us_clientstate; /* Client state */ #if PPP_SERVER - u8_t us_serverstate /* Server state */ + u8_t us_serverstate; /* Server state */ #endif /* PPP_SERVER */ u8_t us_id; /* Current id */ u8_t us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index ec41bd99..43f172c0 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -729,15 +729,16 @@ void upper_layers_down(ppp_pcb *pcb) { */ void link_established(ppp_pcb *pcb) { int auth; -#if 0 /* UNUSED */ - lcp_options *wo = &lcp_wantoptions[pcb->unit]; -#endif /* UNUSED */ #if PPP_SERVER - lcp_options *go = &lcp_gotoptions[pcb->unit]; -#endif /* #if PPP_SERVER */ + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *go = &pcb->lcp_gotoptions; +#endif /* PPP_SERVER */ lcp_options *ho = &pcb->lcp_hisoptions; int i; struct protent *protp; +#if PPP_SERVER + int errcode; +#endif /* PPP_SERVER */ /* * Tell higher-level protocols that LCP is up. @@ -749,13 +750,13 @@ void link_established(ppp_pcb *pcb) { (*protp->lowerup)(pcb); } -#if 0 /* UNUSED */ +#if PPP_SERVER #if PPP_ALLOWED_ADDRS if (!auth_required && noauth_addrs != NULL) set_allowed_addrs(unit, NULL, NULL); #endif /* PPP_ALLOWED_ADDRS */ - if (auth_required && !(0 + if (pcb->settings.auth_required && !(0 #if PAP_SUPPORT || go->neg_upap #endif /* PAP_SUPPORT */ @@ -779,14 +780,18 @@ void link_established(ppp_pcb *pcb) { set_allowed_addrs(unit, NULL, NULL); } else #endif /* PPP_ALLOWED_ADDRS */ - if (!wo->neg_upap || uselogin || !null_login(unit)) { + if (!wo->neg_upap || !pcb->settings.null_login) { ppp_warn("peer refused to authenticate: terminating link"); +#if 0 /* UNUSED */ status = EXIT_PEER_AUTH_FAILED; +#endif /* UNUSED */ + errcode = PPPERR_AUTHFAIL; + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(pcb, "peer refused to authenticate"); return; } } -#endif /* UNUSED */ +#endif /* PPP_SERVER */ new_phase(pcb, PHASE_AUTHENTICATE); auth = 0; @@ -997,10 +1002,14 @@ void continue_networks(ppp_pcb *pcb) { * The peer has failed to authenticate himself using `protocol'. */ void auth_peer_fail(ppp_pcb *pcb, int protocol) { + int errcode = PPPERR_AUTHFAIL; /* * Authentication failure: take the link down */ +#if 0 /* UNUSED */ status = EXIT_PEER_AUTH_FAILED; +#endif /* UNUSED */ + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(pcb, "Authentication failed"); } @@ -1064,7 +1073,7 @@ void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, char *name, * proceed to the network (or callback) phase. */ if ((pcb->auth_pending &= ~bit) == 0) - network_phase(unit); + network_phase(pcb); } #endif /* PPP_SERVER */ diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 5e0fc714..624e690b 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -83,11 +83,11 @@ static int chap_md5_verify_response(int id, char *name, /* Test if our hash matches the peer's response */ if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { - slprintf(message, message_space, "Access granted"); + ppp_slprintf(message, message_space, "Access granted"); return 1; } } - slprintf(message, message_space, "Access denied"); + ppp_slprintf(message, message_space, "Access denied"); return 0; } #endif /* PPP_SERVER */ diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 5d71de0b..1adf5576 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -69,12 +69,6 @@ static option_t chap_option_list[] = { }; #endif /* PPP_OPTIONS */ -/* - * These limits apply to challenge and response packets we send. - * The +4 is the +1 that we actually need rounded up. - */ -#define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) -#define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) /* Values for flags in chap_client_state and chap_server_state */ #define LOWERUP 1 @@ -168,7 +162,7 @@ static void chap_lowerdown(ppp_pcb *pcb) { * otherwise we wait for the lower layer to come up. */ void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code) { - struct chap_server_state *ss = &server; + struct chap_server_state *ss = &pcb->chap_server; struct chap_digest_type *dp; if (pcb->chap_server.flags & AUTH_STARTED) { @@ -309,10 +303,12 @@ static void chap_handle_response(ppp_pcb *pcb, int id, pcb->chap_server.flags &= ~TIMEOUT_PENDING; UNTIMEOUT(chap_timeout, pcb); } - - if (explicit_remote) { - name = remote_name; - } else { +#if PPP_REMOTENAME + if (pcb->settings.explicit_remote) { + name = pcb->remote_name; + } else +#endif /* PPP_REMOTENAME */ + { /* Null terminate and clean remote name. */ ppp_slprintf(rname, sizeof(rname), "%.*v", len, name); name = rname; @@ -409,12 +405,14 @@ static int chap_verify_response(char *name, char *ourname, int id, unsigned char secret[MAXSECRETLEN]; int secret_len; +/* FIXME: we need a way to check peer secret */ +#if 0 /* Get the secret that the peer is supposed to know */ if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) { ppp_error("No CHAP secret found for authenticating %q", name); return 0; } - +#endif ok = digest->verify_response(id, name, secret, secret_len, challenge, response, message, message_space); memset(secret, 0, sizeof(secret)); diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index cbbcf53c..7c51614a 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -217,7 +217,7 @@ static int chapms_verify_response(int id, char *name, #ifndef MSLANMAN if (!response[MS_CHAP_USENT]) { /* Should really propagate this into the error packet. */ - notice("Peer request for LANMAN auth not supported"); + ppp_notice("Peer request for LANMAN auth not supported"); goto bad; } #endif @@ -236,13 +236,13 @@ static int chapms_verify_response(int id, char *name, MS_CHAP_NTRESP_LEN); if (diff == 0) { - slprintf(message, message_space, "Access granted"); + ppp_slprintf(message, message_space, "Access granted"); return 1; } bad: /* See comments below for MS-CHAP V2 */ - slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", + ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", challenge_len, challenge); return 0; } @@ -288,9 +288,9 @@ static int chapms2_verify_response(int id, char *name, if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], MS_CHAP2_NTRESP_LEN) == 0) { if (response[MS_CHAP2_FLAGS]) - slprintf(message, message_space, "S=%s", saresponse); + ppp_slprintf(message, message_space, "S=%s", saresponse); else - slprintf(message, message_space, "S=%s M=%s", + ppp_slprintf(message, message_space, "S=%s M=%s", saresponse, "Access granted"); return 1; } @@ -317,7 +317,7 @@ static int chapms2_verify_response(int id, char *name, * Basically, this whole bit is useless code, even the small * implementation here is only because of overspecification. */ - slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", + ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", challenge_len, challenge, "Access denied"); return 0; } diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index 235c0cd3..f0df3d08 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -258,11 +258,7 @@ void eap_authwithpeer(ppp_pcb *pcb, char *localname) { * Format a standard EAP Failure message and send it to the peer. * (Server operation) */ -static void -eap_send_failure(esp) -eap_state *esp; -{ - ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; +static void eap_send_failure(ppp_pcb *pcb) { struct pbuf *p; u_char *outp; @@ -293,11 +289,7 @@ eap_state *esp; * Format a standard EAP Success message and send it to the peer. * (Server operation) */ -static void -eap_send_success(esp) -eap_state *esp; -{ - ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; +static void eap_send_success(ppp_pcb *pcb) { struct pbuf *p; u_char *outp; @@ -441,11 +433,7 @@ u_char *outp; * indicates if there was an error in handling the last query. It is * 0 for success and non-zero for failure. */ -static void -eap_figure_next_state(esp, status) -eap_state *esp; -int status; -{ +static void eap_figure_next_state(ppp_pcb *pcb, int status) { #ifdef USE_SRP unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp; struct t_pw tpw; @@ -651,18 +639,14 @@ int status; break; } if (pcb->eap.es_server.ea_state == eapBadAuth) - eap_send_failure(esp); + eap_send_failure(pcb); } /* * Format an EAP Request message and send it to the peer. Message * type depends on current state. (Server operation) */ -static void -eap_send_request(esp) -eap_state *esp; -{ - ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; +static void eap_send_request(ppp_pcb *pcb) { struct pbuf *p; u_char *outp; u_char *lenloc; @@ -682,16 +666,18 @@ eap_state *esp; if (pcb->eap.es_server.ea_state < eapIdentify && pcb->eap.es_server.ea_state != eapInitial) { pcb->eap.es_server.ea_state = eapIdentify; - if (explicit_remote) { +#if PPP_REMOTENAME + if (pcb->settings.explicit_remote) { /* * If we already know the peer's * unauthenticated name, then there's no * reason to ask. Go to next state instead. */ - pcb->eap.es_server.ea_peer = remote_name; - pcb->eap.es_server.ea_peerlen = strlen(remote_name); - eap_figure_next_state(esp, 0); + pcb->eap.es_server.ea_peer = pcb->remote_name; + pcb->eap.es_server.ea_peerlen = strlen(pcb->remote_name); + eap_figure_next_state(pcb, 0); } +#endif /* PPP_REMOTENAME */ } if (pcb->eap.es_server.ea_maxrequests > 0 && @@ -700,7 +686,7 @@ eap_state *esp; ppp_error("EAP: too many Requests sent"); else ppp_error("EAP: no response to Requests"); - eap_send_failure(esp); + eap_send_failure(pcb); return; } @@ -888,7 +874,7 @@ eap_state *esp; return; } - outlen = (outp - p->payload) - PPP_HDRLEN; + outlen = (outp - (unsigned char*)p->payload) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); pbuf_realloc(p, outlen + PPP_HDRLEN); @@ -907,7 +893,6 @@ eap_state *esp; * after eap_lowerup. */ void eap_authpeer(ppp_pcb *pcb, char *localname) { - eap_state *esp = &eap_states[unit]; /* Save the name we're given. */ pcb->eap.es_server.ea_name = localname; @@ -925,7 +910,7 @@ void eap_authpeer(ppp_pcb *pcb, char *localname) { pcb->eap.es_server.ea_state = eapPending; /* ID number not updated here intentionally; hashed into M1 */ - eap_send_request(esp); + eap_send_request(pcb); } /* @@ -935,11 +920,11 @@ void eap_authpeer(ppp_pcb *pcb, char *localname) { static void eap_server_timeout(void *arg) { ppp_pcb *pcb = (ppp_pcb*)arg; - if (!eap_server_active(esp)) + if (!eap_server_active(pcb)) return; /* EAP ID number must not change on timeout. */ - eap_send_request(esp); + eap_send_request(pcb); } /* @@ -947,11 +932,8 @@ static void eap_server_timeout(void *arg) { * called. Once the rechallenge is successful, the response handler * will restart the timer. If it fails, then the link is dropped. */ -static void -eap_rechallenge(arg) -void *arg; -{ - eap_state *esp = (eap_state *)arg; +static void eap_rechallenge(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; if (pcb->eap.es_server.ea_state != eapOpen && pcb->eap.es_server.ea_state != eapSRP4) @@ -959,16 +941,13 @@ void *arg; pcb->eap.es_server.ea_requests = 0; pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(esp, 0); + eap_figure_next_state(pcb, 0); pcb->eap.es_server.ea_id++; - eap_send_request(esp); + eap_send_request(pcb); } -static void -srp_lwrechallenge(arg) -void *arg; -{ - eap_state *esp = (eap_state *)arg; +static void srp_lwrechallenge(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; if (pcb->eap.es_server.ea_state != eapOpen || pcb->eap.es_server.ea_type != EAPT_SRP) @@ -977,7 +956,7 @@ void *arg; pcb->eap.es_server.ea_requests = 0; pcb->eap.es_server.ea_state = eapSRP4; pcb->eap.es_server.ea_id++; - eap_send_request(esp); + eap_send_request(pcb); } #endif /* PPP_SERVER */ @@ -993,8 +972,11 @@ static void eap_lowerup(ppp_pcb *pcb) { /* Discard any (possibly authenticated) peer name. */ #if PPP_SERVER - if (pcb->eap.es_server.ea_peer != NULL && - pcb->eap.es_server.ea_peer != remote_name) + if (pcb->eap.es_server.ea_peer != NULL +#if PPP_REMOTENAME + && pcb->eap.es_server.ea_peer != pcb->remote_name +#endif /* PPP_REMOTENAME */ + ) free(pcb->eap.es_server.ea_peer); pcb->eap.es_server.ea_peer = NULL; #endif /* PPP_SERVER */ @@ -1019,7 +1001,7 @@ static void eap_lowerdown(ppp_pcb *pcb) { UNTIMEOUT(eap_client_timeout, pcb); } #if PPP_SERVER - if (eap_server_active(esp)) { + if (eap_server_active(pcb)) { if (pcb->eap.es_server.ea_timeout > 0) { UNTIMEOUT(eap_server_timeout, pcb); } @@ -1027,11 +1009,11 @@ static void eap_lowerdown(ppp_pcb *pcb) { if ((pcb->eap.es_server.ea_state == eapOpen || pcb->eap.es_server.ea_state == eapSRP4) && pcb->eap.es_rechallenge > 0) { - UNTIMEOUT(eap_rechallenge, (void *)esp); + UNTIMEOUT(eap_rechallenge, (void *)pcb); } if (pcb->eap.es_server.ea_state == eapOpen && pcb->eap.es_lwrechallenge > 0) { - UNTIMEOUT(srp_lwrechallenge, (void *)esp); + UNTIMEOUT(srp_lwrechallenge, (void *)pcb); } } @@ -1053,7 +1035,7 @@ static void eap_protrej(ppp_pcb *pcb) { auth_withpeer_fail(pcb, PPP_EAP); } #if PPP_SERVER - if (eap_server_active(esp)) { + if (eap_server_active(pcb)) { ppp_error("EAP authentication of peer failed on Protocol-Reject"); auth_peer_fail(pcb, PPP_EAP); } @@ -1807,19 +1789,22 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { break; } ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp); - if (pcb->eap.es_server.ea_peer != NULL && - pcb->eap.es_server.ea_peer != remote_name) + if (pcb->eap.es_server.ea_peer != NULL +#if PPP_REMOTENAME + && pcb->eap.es_server.ea_peer != pcb->remote_name +#endif /* PPP_REMOTENAME */ + ) free(pcb->eap.es_server.ea_peer); pcb->eap.es_server.ea_peer = malloc(len + 1); if (pcb->eap.es_server.ea_peer == NULL) { pcb->eap.es_server.ea_peerlen = 0; - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } MEMCPY(pcb->eap.es_server.ea_peer, inp, len); pcb->eap.es_server.ea_peer[len] = '\0'; pcb->eap.es_server.ea_peerlen = len; - eap_figure_next_state(esp, 0); + eap_figure_next_state(pcb, 0); break; case EAPT_NOTIFICATION: @@ -1829,16 +1814,20 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPT_NAK: if (len < 1) { ppp_info("EAP: Nak Response with no suggested protocol"); - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } GETCHAR(vallen, inp); len--; - if (!explicit_remote && pcb->eap.es_server.ea_state == eapIdentify){ + if ( +#if PPP_REMOTENAME + !pcb->explicit_remote && +#endif /* PPP_REMOTENAME */ + pcb->eap.es_server.ea_state == eapIdentify){ /* Peer cannot Nak Identify Request */ - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } @@ -1846,7 +1835,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPT_SRP: /* Run through SRP validator selection again. */ pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(esp, 0); + eap_figure_next_state(pcb, 0); break; case EAPT_MD5CHAP: @@ -1864,7 +1853,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case eapMD5Chall: case eapSRP4: pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(esp, 0); + eap_figure_next_state(pcb, 0); break; default: break; @@ -1876,19 +1865,19 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPT_MD5CHAP: if (pcb->eap.es_server.ea_state != eapMD5Chall) { ppp_error("EAP: unexpected MD5-Response"); - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } if (len < 1) { ppp_error("EAP: received MD5-Response with no data"); - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } GETCHAR(vallen, inp); len--; if (vallen != 16 || vallen > len) { ppp_error("EAP: MD5-Response with bad length %d", vallen); - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } @@ -1902,10 +1891,12 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { rhostname[len - vallen] = '\0'; } +#if PPP_REMOTENAME /* In case the remote doesn't give us his name. */ if (explicit_remote || (remote_name[0] != '\0' && vallen == len)) strlcpy(rhostname, remote_name, sizeof (rhostname)); +#endif /* PPP_REMOTENAME */ /* * Get the secret for authenticating the specified @@ -1914,7 +1905,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { if (!get_secret(pcb, rhostname, pcb->eap.es_server.ea_name, secret, &secret_len, 1)) { ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname); - eap_send_failure(esp); + eap_send_failure(pcb); break; } md5_starts(&mdContext); @@ -1924,21 +1915,21 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen); md5_finish(&mdContext, hash); if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { - eap_send_failure(esp); + eap_send_failure(pcb); break; } pcb->eap.es_server.ea_type = EAPT_MD5CHAP; - eap_send_success(esp); - eap_figure_next_state(esp, 0); + eap_send_success(pcb); + eap_figure_next_state(pcb, 0); if (pcb->eap.es_rechallenge != 0) - TIMEOUT(eap_rechallenge, esp, pcb->eap.es_rechallenge); + TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge); break; #ifdef USE_SRP case EAPT_SRP: if (len < 1) { ppp_error("EAP: empty SRP Response"); - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } GETCHAR(typenum, inp); @@ -1947,7 +1938,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { case EAPSRP_CKEY: if (pcb->eap.es_server.ea_state != eapSRP1) { ppp_error("EAP: unexpected SRP Subtype 1 Response"); - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } A.data = inp; @@ -1958,22 +1949,22 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { if (pcb->eap.es_server.ea_skey == NULL) { /* Client's A value is bogus; terminate now */ ppp_error("EAP: bogus A value from client"); - eap_send_failure(esp); + eap_send_failure(pcb); } else { - eap_figure_next_state(esp, 0); + eap_figure_next_state(pcb, 0); } break; case EAPSRP_CVALIDATOR: if (pcb->eap.es_server.ea_state != eapSRP2) { ppp_error("EAP: unexpected SRP Subtype 2 Response"); - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } if (len < sizeof (u32_t) + SHA_DIGESTSIZE) { ppp_error("EAP: M1 length %d < %d", len, sizeof (u32_t) + SHA_DIGESTSIZE); - eap_figure_next_state(esp, 1); + eap_figure_next_state(pcb, 1); break; } GETLONG(pcb->eap.es_server.ea_keyflags, inp); @@ -1981,10 +1972,10 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { assert(ts != NULL); if (t_serververify(ts, inp)) { ppp_info("EAP: unable to validate client identity"); - eap_send_failure(esp); + eap_send_failure(pcb); break; } - eap_figure_next_state(esp, 0); + eap_figure_next_state(pcb, 0); break; case EAPSRP_ACK: @@ -1994,13 +1985,13 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { break; } pcb->eap.es_server.ea_type = EAPT_SRP; - eap_send_success(esp); - eap_figure_next_state(esp, 0); + eap_send_success(pcb, esp); + eap_figure_next_state(pcb, 0); if (pcb->eap.es_rechallenge != 0) - TIMEOUT(eap_rechallenge, esp, + TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge); if (pcb->eap.es_lwrechallenge != 0) - TIMEOUT(srp_lwrechallenge, esp, + TIMEOUT(srp_lwrechallenge, pcb, pcb->eap.es_lwrechallenge); break; @@ -2025,7 +2016,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { SHA1Final(dig, &ctxt); if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { ppp_error("EAP: failed Lightweight rechallenge"); - eap_send_failure(esp); + eap_send_failure(pcb); break; } pcb->eap.es_server.ea_state = eapOpen; @@ -2050,7 +2041,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { if (pcb->eap.es_server.ea_state != eapBadAuth && pcb->eap.es_server.ea_state != eapOpen) { pcb->eap.es_server.ea_id++; - eap_send_request(esp); + eap_send_request(pcb); } } #endif /* PPP_SERVER */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index fd470ac8..221b9c36 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -120,16 +120,14 @@ struct protent pap_protent = { static void upap_timeout(void *arg); #if PPP_SERVER static void upap_reqtimeout(void *arg); -#endif /* PPP_SERVER */ -#if 0 /* UNUSED */ static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len); -#endif /* UNUSED */ +#endif /* PPP_SERVER */ static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len); static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len); static void upap_sauthreq(ppp_pcb *pcb); -#if 0 /* UNUSED */ +#if PPP_SERVER static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msglen); -#endif /* UNUSED */ +#endif /* PPP_SERVER */ /* @@ -255,7 +253,7 @@ static void upap_lowerup(ppp_pcb *pcb) { else if (pcb->upap.us_serverstate == UPAPSS_PENDING) { pcb->upap.us_serverstate = UPAPSS_LISTEN; if (pcb->upap.us_reqtimeout > 0) - TIMEOUT(upap_reqtimeout, u, pcb->upap.us_reqtimeout); + TIMEOUT(upap_reqtimeout, pcb, pcb->upap.us_reqtimeout); } #endif /* PPP_SERVER */ } @@ -272,7 +270,7 @@ static void upap_lowerdown(ppp_pcb *pcb) { UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */ #if PPP_SERVER if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->upap.us_reqtimeout > 0) - UNTIMEOUT(upap_reqtimeout, u); + UNTIMEOUT(upap_reqtimeout, pcb); #endif /* PPP_SERVER */ pcb->upap.us_clientstate = UPAPCS_INITIAL; @@ -338,9 +336,9 @@ static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) { */ switch (code) { case UPAP_AUTHREQ: -#if 0 /* UNUSED */ +#if PPP_SERVER upap_rauthreq(pcb, inp, id, len); -#endif /* UNUSED */ +#endif /* PPP_SERVER */ break; case UPAP_AUTHACK: @@ -356,7 +354,7 @@ static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) { } } -#if 0 /* UNUSED */ +#if PPP_SERVER /* * upap_rauth - Receive Authenticate. */ @@ -376,11 +374,11 @@ static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) { * supposed to return the same status as for the first request. */ if (pcb->upap.us_serverstate == UPAPSS_OPEN) { - upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ + upap_sresp(pcb, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ return; } if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) { - upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ + upap_sresp(pcb, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ return; } @@ -404,16 +402,18 @@ static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) { UPAPDEBUG(("pap_rauth: rcvd short packet.")); return; } + + /* FIXME: we need a way to check peer secret */ rpasswd = (char *) inp; /* * Check the username and password given. */ +#if 0 retcode = check_passwd(pcb->upap.us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg); BZERO(rpasswd, rpasswdlen); -#if 0 /* UNUSED */ /* * Check remote number authorization. A plugin may have filled in * the remote number or added an allowed number, and rather than @@ -426,30 +426,30 @@ static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) { warn("calling number %q is not authorized", remote_number); } } -#endif /* UNUSED */ +#endif msglen = strlen(msg); if (msglen > 255) msglen = 255; - upap_sresp(u, retcode, id, msg, msglen); + upap_sresp(pcb, retcode, id, msg, msglen); /* Null terminate and clean remote name. */ - slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); + ppp_slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); if (retcode == UPAP_AUTHACK) { pcb->upap.us_serverstate = UPAPSS_OPEN; - notice("PAP peer authentication succeeded for %q", rhostname); + ppp_notice("PAP peer authentication succeeded for %q", rhostname); auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen); } else { pcb->upap.us_serverstate = UPAPSS_BADAUTH; - warn("PAP peer authentication failed for %q", rhostname); + ppp_warn("PAP peer authentication failed for %q", rhostname); auth_peer_fail(pcb, PPP_PAP); } if (pcb->upap.us_reqtimeout > 0) - UNTIMEOUT(upap_reqtimeout, u); + UNTIMEOUT(upap_reqtimeout, pcb); } -#endif /* UNUSED */ +#endif /* PPP_SERVER */ /* * upap_rauthack - Receive Authenticate-Ack. @@ -557,7 +557,7 @@ static void upap_sauthreq(ppp_pcb *pcb) { pcb->upap.us_clientstate = UPAPCS_AUTHREQ; } -#if 0 /* UNUSED */ +#if PPP_SERVER /* * upap_sresp - Send a response (ack or nak). */ @@ -586,7 +586,7 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl ppp_write(pcb, p); } -#endif /* UNUSED */ +#endif /* PPP_SERVER */ #if PRINTPKT_SUPPORT /* From 0eb83f6ee6324c9f1cabfb15816a4ebe0b745816 Mon Sep 17 00:00:00 2001 From: Mark Lakata Date: Fri, 12 Oct 2012 20:17:40 +0200 Subject: [PATCH 281/320] PPP, IAR EWARM won't compile ppp-new due to keyword clash The word "class" is reserved in IAR's EWARM compiler since it looks like c++. This causes a failure to compile in the lcp code. Arguably it is a bug in the compiler, but it is easy to work around with a name change in the lcp.[ch] code. I fixed it by changing "class" to "class_". --- src/include/netif/ppp/lcp.h | 2 +- src/netif/ppp/lcp.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include/netif/ppp/lcp.h b/src/include/netif/ppp/lcp.h index ec5e9a69..00a0f576 100644 --- a/src/include/netif/ppp/lcp.h +++ b/src/include/netif/ppp/lcp.h @@ -97,7 +97,7 @@ /* An endpoint discriminator, used with multilink. */ #define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ struct epdisc { - unsigned char class; + unsigned char class_; /* -- The word "class" is reserved in C++. */ unsigned char length; unsigned char value[MAX_ENDP_LEN]; }; diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index cb44e687..2d01831f 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -866,7 +866,7 @@ static void lcp_addci(fsm *f, u_char *ucp, int *lenp) { ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); #endif ADDCIVOID(CI_SSNHF, go->neg_ssnhf); - ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, + ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_, go->endpoint.value, go->endpoint.length); if (ucp - start_ucp != *lenp) { @@ -1040,7 +1040,7 @@ static int lcp_ackci(fsm *f, u_char *p, int len) { ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); #endif /* HAVE_MULTILINK */ ACKCIVOID(CI_SSNHF, go->neg_ssnhf); - ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, + ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_, go->endpoint.value, go->endpoint.length); /* @@ -1722,7 +1722,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { REJCISHORT(CI_MRRU, neg_mrru, go->mrru); #endif /* HAVE_MULTILINK */ REJCIVOID(CI_SSNHF, neg_ssnhf); - REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class, + REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class_, go->endpoint.value, go->endpoint.length); /* @@ -2154,7 +2154,7 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { GETCHAR(cichar, p); cilen -= CILEN_CHAR; ho->neg_endpoint = 1; - ho->endpoint.class = cichar; + ho->endpoint.class_ = cichar; ho->endpoint.length = cilen; MEMCPY(ho->endpoint.value, p, cilen); INCPTR(cilen, p); From a0298728df3ecae03a6c4b74b8cf814e38b9c6d9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 12 Oct 2012 20:32:05 +0200 Subject: [PATCH 282/320] PPP, disable persist mode by default, so the default behavior does not look like a buggy behavior. Fixes bug #37279. --- src/netif/ppp/ppp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index fccda18f..ba2cc443 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -257,7 +257,6 @@ ppp_pcb *ppp_new(void) { /* default configuration */ pcb->settings.usepeerdns = 1; - pcb->settings.persist = 1; #if CHAP_SUPPORT pcb->settings.chap_timeout_time = 3; pcb->settings.chap_max_transmits = 10; From 9e4aa7927828f7609950c821a6bdeb0eedb25e5a Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 13 Oct 2012 18:38:18 +0200 Subject: [PATCH 283/320] PPP, adding const pragma to struct protent, saving about 200 bytes in .data segment --- src/include/netif/ppp/ccp.h | 2 +- src/include/netif/ppp/chap-new.h | 2 +- src/include/netif/ppp/eap.h | 2 +- src/include/netif/ppp/ecp.h | 2 +- src/include/netif/ppp/ipcp.h | 2 +- src/include/netif/ppp/ipv6cp.h | 2 +- src/include/netif/ppp/lcp.h | 2 +- src/include/netif/ppp/ppp_impl.h | 2 +- src/include/netif/ppp/upap.h | 2 +- src/netif/ppp/auth.c | 8 ++++---- src/netif/ppp/ccp.c | 2 +- src/netif/ppp/chap-new.c | 2 +- src/netif/ppp/demand.c | 10 +++++----- src/netif/ppp/eap.c | 2 +- src/netif/ppp/ecp.c | 2 +- src/netif/ppp/ipcp.c | 2 +- src/netif/ppp/ipv6cp.c | 2 +- src/netif/ppp/lcp.c | 4 ++-- src/netif/ppp/ppp.c | 6 +++--- src/netif/ppp/upap.c | 2 +- src/netif/ppp/utils.c | 2 +- 21 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/include/netif/ppp/ccp.h b/src/include/netif/ppp/ccp.h index b5dee384..f106cb5d 100644 --- a/src/include/netif/ppp/ccp.h +++ b/src/include/netif/ppp/ccp.h @@ -52,6 +52,6 @@ extern ccp_options ccp_gotoptions[]; extern ccp_options ccp_allowoptions[]; extern ccp_options ccp_hisoptions[]; -extern struct protent ccp_protent; +extern const struct protent ccp_protent; #endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/src/include/netif/ppp/chap-new.h b/src/include/netif/ppp/chap-new.h index 2730a8cb..d84e9029 100644 --- a/src/include/netif/ppp/chap-new.h +++ b/src/include/netif/ppp/chap-new.h @@ -192,7 +192,7 @@ extern void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code); extern void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code); /* Represents the CHAP protocol to the main pppd code */ -extern struct protent chap_protent; +extern const struct protent chap_protent; #endif /* CHAP_H */ #endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/include/netif/ppp/eap.h b/src/include/netif/ppp/eap.h index b96be43c..328046c1 100644 --- a/src/include/netif/ppp/eap.h +++ b/src/include/netif/ppp/eap.h @@ -157,7 +157,7 @@ typedef struct eap_state { void eap_authwithpeer(ppp_pcb *pcb, char *localname); void eap_authpeer(ppp_pcb *pcb, char *localname); -extern struct protent eap_protent; +extern const struct protent eap_protent; #ifdef __cplusplus } diff --git a/src/include/netif/ppp/ecp.h b/src/include/netif/ppp/ecp.h index d6887758..cba6678e 100644 --- a/src/include/netif/ppp/ecp.h +++ b/src/include/netif/ppp/ecp.h @@ -45,6 +45,6 @@ extern ecp_options ecp_gotoptions[]; extern ecp_options ecp_allowoptions[]; extern ecp_options ecp_hisoptions[]; -extern struct protent ecp_protent; +extern const struct protent ecp_protent; #endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/src/include/netif/ppp/ipcp.h b/src/include/netif/ppp/ipcp.h index 5b6f1006..b5f2334c 100644 --- a/src/include/netif/ppp/ipcp.h +++ b/src/include/netif/ppp/ipcp.h @@ -101,7 +101,7 @@ typedef struct ipcp_options { char *ip_ntoa (u32_t); #endif /* UNUSED, already defined by lwIP */ -extern struct protent ipcp_protent; +extern const struct protent ipcp_protent; #endif /* IPCP_H */ #endif /* PPP_SUPPORT */ diff --git a/src/include/netif/ppp/ipv6cp.h b/src/include/netif/ppp/ipv6cp.h index 8501d9c0..d6e28a8d 100644 --- a/src/include/netif/ppp/ipv6cp.h +++ b/src/include/netif/ppp/ipv6cp.h @@ -173,7 +173,7 @@ typedef struct ipv6cp_options { eui64_t ourid, hisid; /* Interface identifiers */ } ipv6cp_options; -extern struct protent ipv6cp_protent; +extern const struct protent ipv6cp_protent; #endif /* IPV6CP_H */ #endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/src/include/netif/ppp/lcp.h b/src/include/netif/ppp/lcp.h index 00a0f576..f832a4ee 100644 --- a/src/include/netif/ppp/lcp.h +++ b/src/include/netif/ppp/lcp.h @@ -164,7 +164,7 @@ void lcp_lowerup(ppp_pcb *pcb); void lcp_lowerdown(ppp_pcb *pcb); void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len); /* send protocol reject */ -extern struct protent lcp_protent; +extern const struct protent lcp_protent; /* Default number of times we receive our magic number from the peer before deciding the link is looped-back. */ diff --git a/src/include/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h index 61ed84c1..06d40b6b 100644 --- a/src/include/netif/ppp/ppp_impl.h +++ b/src/include/netif/ppp/ppp_impl.h @@ -295,7 +295,7 @@ struct protent { }; /* Table of pointers to supported protocols */ -extern struct protent *protocols[]; +extern const struct protent* const protocols[]; /* Values for auth_pending, auth_done */ diff --git a/src/include/netif/ppp/upap.h b/src/include/netif/ppp/upap.h index ca051411..3d1075b2 100644 --- a/src/include/netif/ppp/upap.h +++ b/src/include/netif/ppp/upap.h @@ -120,7 +120,7 @@ void upap_authwithpeer(ppp_pcb *pcb, char *user, char *password); void upap_authpeer(ppp_pcb *pcb); #endif /* PPP_SERVER */ -extern struct protent pap_protent; +extern const struct protent pap_protent; #endif /* UPAP_H */ #endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index 43f172c0..d1dc41f8 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -709,7 +709,7 @@ void link_down(ppp_pcb *pcb) { void upper_layers_down(ppp_pcb *pcb) { int i; - struct protent *protp; + const struct protent *protp; for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (!protp->enabled_flag) @@ -735,7 +735,7 @@ void link_established(ppp_pcb *pcb) { #endif /* PPP_SERVER */ lcp_options *ho = &pcb->lcp_hisoptions; int i; - struct protent *protp; + const struct protent *protp; #if PPP_SERVER int errcode; #endif /* PPP_SERVER */ @@ -908,7 +908,7 @@ static void network_phase(ppp_pcb *pcb) { void start_networks(ppp_pcb *pcb) { #if CCP_SUPPORT || ECP_SUPPORT int i; - struct protent *protp; + const struct protent *protp; #endif /* CCP_SUPPORT || ECP_SUPPORT */ #if ECP_SUPPORT int ecp_required; @@ -974,7 +974,7 @@ void start_networks(ppp_pcb *pcb) { void continue_networks(ppp_pcb *pcb) { int i; - struct protent *protp; + const struct protent *protp; /* * Start the "real" network protocols. diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index 2117fcab..a5785329 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -180,7 +180,7 @@ static int ccp_printpkt (u_char *pkt, int len, #endif /* PRINTPKT_SUPPORT */ static void ccp_datainput (int unit, u_char *pkt, int len); -struct protent ccp_protent = { +const struct protent ccp_protent = { PPP_CCP, ccp_init, ccp_input, diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 1adf5576..ec5a3050 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -634,7 +634,7 @@ static int chap_print_pkt(unsigned char *p, int plen, } #endif /* PRINTPKT_SUPPORT */ -struct protent chap_protent = { +const struct protent chap_protent = { PPP_CHAP, chap_init, chap_input, diff --git a/src/netif/ppp/demand.c b/src/netif/ppp/demand.c index dbabfa90..f31a124c 100644 --- a/src/netif/ppp/demand.c +++ b/src/netif/ppp/demand.c @@ -83,7 +83,7 @@ void demand_conf() { int i; - struct protent *protp; + const struct protent *protp; /* framemax = lcp_allowoptions[0].mru; if (framemax < PPP_MRU) */ @@ -128,7 +128,7 @@ void demand_block() { int i; - struct protent *protp; + const struct protent *protp; for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) @@ -145,7 +145,7 @@ demand_discard() { struct packet *pkt, *nextpkt; int i; - struct protent *protp; + const struct protent *protp; for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) @@ -171,7 +171,7 @@ void demand_unblock() { int i; - struct protent *protp; + const struct protent *protp; for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) @@ -436,7 +436,7 @@ active_packet(p, len) int len; { int proto, i; - struct protent *protp; + const struct protent *protp; if (len < PPP_HDRLEN) return 0; diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index f0df3d08..b3106ad3 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -111,7 +111,7 @@ static int eap_printpkt(u_char *inp, int inlen, void (*)(void *arg, char *fmt, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ -struct protent eap_protent = { +const struct protent eap_protent = { PPP_EAP, /* protocol number */ eap_init, /* initialization procedure */ eap_input, /* process a received packet */ diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index f2645055..dc7e3127 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -99,7 +99,7 @@ static int ecp_printpkt (u_char *pkt, int len, static void ecp_datainput (int unit, u_char *pkt, int len); */ -struct protent ecp_protent = { +const struct protent ecp_protent = { PPP_ECP, ecp_init, NULL, /* ecp_input, */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index ede4af8f..efb56a12 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -278,7 +278,7 @@ static int ip_active_pkt (u_char *, int); static void create_resolv (u32_t, u32_t); #endif /* UNUSED */ -struct protent ipcp_protent = { +const struct protent ipcp_protent = { PPP_IPCP, ipcp_init, ipcp_input, diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c index 5318e2ba..96142ce0 100644 --- a/src/netif/ppp/ipv6cp.c +++ b/src/netif/ppp/ipv6cp.c @@ -274,7 +274,7 @@ static int ipv6cp_printpkt(u_char *p, int plen, static int ipv6_active_pkt(u_char *pkt, int len); #endif /* PPP_DEMAND */ -struct protent ipv6cp_protent = { +const struct protent ipv6cp_protent = { PPP_IPV6CP, ipv6cp_init, ipv6cp_input, diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 2d01831f..03783b05 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -272,7 +272,7 @@ static int lcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ -struct protent lcp_protent = { +const struct protent lcp_protent = { PPP_LCP, lcp_init, lcp_input, @@ -592,7 +592,7 @@ static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) { */ static void lcp_rprotrej(fsm *f, u_char *inp, int len) { int i; - struct protent *protp; + const struct protent *protp; u_short prot; #if PPP_PROTOCOLNAME const char *pname; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index ba2cc443..bb7e7add 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -152,7 +152,7 @@ int link_stats_valid; * One entry per supported protocol. * The last entry must be NULL. */ -struct protent *protocols[] = { +const struct protent* const protocols[] = { &lcp_protent, #if PAP_SUPPORT &pap_protent, @@ -599,7 +599,7 @@ int ppp_delete(ppp_pcb *pcb) { /* Set a PPP PCB to its initial state */ static void ppp_clear(ppp_pcb *pcb) { - struct protent *protp; + const struct protent *protp; int i; LWIP_ASSERT("pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF", pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF); @@ -769,7 +769,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { default: { int i; - struct protent *protp; + const struct protent *protp; /* * Upcall the proper protocol input routine. */ diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 221b9c36..5e61a76c 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -89,7 +89,7 @@ static void upap_protrej(ppp_pcb *pcb); static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg); #endif /* PRINTPKT_SUPPORT */ -struct protent pap_protent = { +const struct protent pap_protent = { PPP_PAP, upap_init, upap_input, diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index f918ba07..c7a78c7c 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -455,7 +455,7 @@ static void ppp_format_packet(u_char *p, int len, void (*printer) (void *, char *, ...), void *arg) { int i, n; u_short proto; - struct protent *protp; + const struct protent *protp; if (len >= 2) { GETSHORT(proto, p); From e5a554f0b5f29f3f19dfb6505d4fddb3be820f75 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 13 Oct 2012 18:54:25 +0200 Subject: [PATCH 284/320] PPP, adding const pragma to FSM callbacks, saving about 350 bytes in .data segment --- src/include/netif/ppp/fsm.h | 2 +- src/netif/ppp/ccp.c | 2 +- src/netif/ppp/ecp.c | 2 +- src/netif/ppp/ipcp.c | 2 +- src/netif/ppp/ipv6cp.c | 2 +- src/netif/ppp/lcp.c | 2 +- src/netif/ppp/pppoe.c | 1 + 7 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/include/netif/ppp/fsm.h b/src/include/netif/ppp/fsm.h index dbffd93c..139ff7fb 100644 --- a/src/include/netif/ppp/fsm.h +++ b/src/include/netif/ppp/fsm.h @@ -73,7 +73,7 @@ */ typedef struct fsm { ppp_pcb *pcb; /* PPP Interface */ - struct fsm_callbacks *callbacks; /* Callback routines */ + const struct fsm_callbacks *callbacks; /* Callback routines */ char *term_reason; /* Reason for closing protocol */ u8_t seen_ack; /* Have received valid Ack/Nak/Rej to Req */ /* -- This is our only flag, we might use u_int :1 if we have more flags */ diff --git a/src/netif/ppp/ccp.c b/src/netif/ppp/ccp.c index a5785329..860374bc 100644 --- a/src/netif/ppp/ccp.c +++ b/src/netif/ppp/ccp.c @@ -230,7 +230,7 @@ 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 = { +static const fsm_callbacks ccp_callbacks = { ccp_resetci, ccp_cilen, ccp_addci, diff --git a/src/netif/ppp/ecp.c b/src/netif/ppp/ecp.c index dc7e3127..728fb5fb 100644 --- a/src/netif/ppp/ecp.c +++ b/src/netif/ppp/ecp.c @@ -133,7 +133,7 @@ ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */ ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */ -static fsm_callbacks ecp_callbacks = { +static const fsm_callbacks ecp_callbacks = { NULL, /* ecp_resetci, */ NULL, /* ecp_cilen, */ NULL, /* ecp_addci, */ diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index efb56a12..efe5d708 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -121,7 +121,7 @@ static void ipcp_up(fsm *f); /* We're UP */ static void ipcp_down(fsm *f); /* We're DOWN */ static void ipcp_finished(fsm *f); /* Don't need lower layer */ -static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ +static const 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 */ diff --git a/src/netif/ppp/ipv6cp.c b/src/netif/ppp/ipv6cp.c index 96142ce0..8fb01ada 100644 --- a/src/netif/ppp/ipv6cp.c +++ b/src/netif/ppp/ipv6cp.c @@ -188,7 +188,7 @@ static void ipv6cp_up(fsm *f); /* We're UP */ static void ipv6cp_down(fsm *f); /* We're DOWN */ static void ipv6cp_finished(fsm *f); /* Don't need lower layer */ -static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ +static const fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ ipv6cp_resetci, /* Reset our Configuration Information */ ipv6cp_cilen, /* Length of our Configuration Information */ ipv6cp_addci, /* Add our Configuration Information */ diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 03783b05..76cec49e 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -241,7 +241,7 @@ static void LcpSendEchoRequest(fsm *f); static void LcpLinkFailure(fsm *f); static void LcpEchoCheck(fsm *f); -static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ +static const 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 */ diff --git a/src/netif/ppp/pppoe.c b/src/netif/ppp/pppoe.c index 65dd39df..bf69c680 100644 --- a/src/netif/ppp/pppoe.c +++ b/src/netif/ppp/pppoe.c @@ -106,6 +106,7 @@ #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ #endif +/* FIXME: we should probably remove that, this is only used for debug purposes */ #ifndef PPPOE_ERRORSTRING_LEN #define PPPOE_ERRORSTRING_LEN 64 #endif From 7f97e354b44c1ba61d9bebb411515b67c660ad2f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 14 Oct 2012 02:04:36 +0200 Subject: [PATCH 285/320] PPP, switched chap_digests linked list to a const table in .rodata/flash, saving about 100 bytes in .data segment if chap(md5) and mschap is enabled --- src/include/netif/ppp/chap-md5.h | 2 +- src/include/netif/ppp/chap-new.h | 11 +++------ src/include/netif/ppp/chap_ms.h | 3 ++- src/netif/ppp/chap-md5.c | 6 +---- src/netif/ppp/chap-new.c | 41 +++++++++++++++----------------- src/netif/ppp/chap_ms.c | 12 ++-------- 6 files changed, 28 insertions(+), 47 deletions(-) diff --git a/src/include/netif/ppp/chap-md5.h b/src/include/netif/ppp/chap-md5.h index cb6c56e3..a05a157d 100644 --- a/src/include/netif/ppp/chap-md5.h +++ b/src/include/netif/ppp/chap-md5.h @@ -31,6 +31,6 @@ #include "lwip/opt.h" #if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -extern void chap_md5_init(void); +extern const struct chap_digest_type md5_digest; #endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/include/netif/ppp/chap-new.h b/src/include/netif/ppp/chap-new.h index d84e9029..6846bbf7 100644 --- a/src/include/netif/ppp/chap-new.h +++ b/src/include/netif/ppp/chap-new.h @@ -143,8 +143,6 @@ struct chap_digest_type { unsigned char *priv); int (*check_success)(unsigned char *pkt, int len, unsigned char *priv); void (*handle_failure)(unsigned char *pkt, int len); - - struct chap_digest_type *next; }; /* @@ -154,7 +152,7 @@ struct chap_digest_type { typedef struct chap_client_state { u8_t flags; char *name; - struct chap_digest_type *digest; + const struct chap_digest_type *digest; unsigned char priv[64]; /* private area for digest's use */ } chap_client_state; @@ -163,7 +161,7 @@ typedef struct chap_server_state { u8_t flags; int id; char *name; - struct chap_digest_type *digest; + const struct chap_digest_type *digest; int challenge_xmits; int challenge_pktlen; unsigned char challenge[CHAL_MAX_PKTLEN]; @@ -175,14 +173,11 @@ typedef struct chap_server_state { #if 0 /* UNUSED */ /* Hook for a plugin to validate CHAP challenge */ extern int (*chap_verify_hook)(char *name, char *ourname, int id, - struct chap_digest_type *digest, + const struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space); #endif /* UNUSED */ -/* Called by digest code to register a digest type */ -extern void chap_register_digest(struct chap_digest_type *); - #if PPP_SERVER /* Called by authentication code to start authenticating the peer. */ extern void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code); diff --git a/src/include/netif/ppp/chap_ms.h b/src/include/netif/ppp/chap_ms.h index 7d53dbfd..a366e471 100644 --- a/src/include/netif/ppp/chap_ms.h +++ b/src/include/netif/ppp/chap_ms.h @@ -106,7 +106,8 @@ void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char *rchallenge, char *username, u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]); -void chapms_init(void); +extern const struct chap_digest_type chapms_digest; +extern const struct chap_digest_type chapms2_digest; #define __CHAPMS_INCLUDE__ #endif /* __CHAPMS_INCLUDE__ */ diff --git a/src/netif/ppp/chap-md5.c b/src/netif/ppp/chap-md5.c index 624e690b..f6361314 100644 --- a/src/netif/ppp/chap-md5.c +++ b/src/netif/ppp/chap-md5.c @@ -107,7 +107,7 @@ static void chap_md5_make_response(unsigned char *response, int id, char *our_na response[0] = MD5_HASH_SIZE; } -static struct chap_digest_type md5_digest = { +const struct chap_digest_type md5_digest = { CHAP_MD5, /* code */ #if PPP_SERVER chap_md5_generate_challenge, @@ -118,8 +118,4 @@ static struct chap_digest_type md5_digest = { NULL, /* handle_failure */ }; -void chap_md5_init(void) { - chap_register_digest(&md5_digest); -} - #endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index ec5a3050..19cc8c5d 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -50,7 +50,7 @@ /* Hook for a plugin to validate CHAP challenge */ int (*chap_verify_hook)(char *name, char *ourname, int id, - struct chap_digest_type *digest, + const struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space) = NULL; @@ -90,7 +90,7 @@ static void chap_generate_challenge(ppp_pcb *pcb); static void chap_handle_response(ppp_pcb *pcb, int code, unsigned char *pkt, int len); static int chap_verify_response(char *name, char *ourname, int id, - struct chap_digest_type *digest, + const struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space); #endif /* PPP_SERVER */ @@ -106,7 +106,14 @@ static int chap_print_pkt(unsigned char *p, int plen, #endif /* PRINTPKT_SUPPORT */ /* List of digest types that we know about */ -static struct chap_digest_type *chap_digests; +const static struct chap_digest_type* const chap_digests[] = { + &md5_digest, +#if MSCHAP_SUPPORT + &chapms_digest, + &chapms2_digest, +#endif /* MSCHAP_SUPPORT */ + NULL +}; /* * chap_init - reset to initial state. @@ -117,19 +124,6 @@ static void chap_init(ppp_pcb *pcb) { #if PPP_SERVER memset(&pcb->chap_server, 0, sizeof(chap_server_state)); #endif /* PPP_SERVER */ - - chap_md5_init(); -#if MSCHAP_SUPPORT - chapms_init(); -#endif -} - -/* - * Add a new digest type to the list. - */ -void chap_register_digest(struct chap_digest_type *dp) { - dp->next = chap_digests; - chap_digests = dp; } /* @@ -163,13 +157,14 @@ static void chap_lowerdown(ppp_pcb *pcb) { */ void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code) { struct chap_server_state *ss = &pcb->chap_server; - struct chap_digest_type *dp; + const struct chap_digest_type *dp; + int i; if (pcb->chap_server.flags & AUTH_STARTED) { ppp_error("CHAP: peer authentication already started!"); return; } - for (dp = chap_digests; dp != NULL; dp = dp->next) + for (i = 0; (dp = chap_digests[i]) != NULL; ++i) if (dp->code == digest_code) break; if (dp == NULL) @@ -191,7 +186,8 @@ void chap_auth_peer(ppp_pcb *pcb, char *our_name, int digest_code) { * There isn't much to do until we receive a challenge. */ void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code) { - struct chap_digest_type *dp; + const struct chap_digest_type *dp; + int i; if(NULL == our_name) return; @@ -200,9 +196,10 @@ void chap_auth_with_peer(ppp_pcb *pcb, char *our_name, int digest_code) { ppp_error("CHAP: authentication with peer already started!"); return; } - for (dp = chap_digests; dp != NULL; dp = dp->next) + for (i = 0; (dp = chap_digests[i]) != NULL; ++i) if (dp->code == digest_code) break; + if (dp == NULL) ppp_fatal("CHAP digest 0x%x requested but not available", digest_code); @@ -283,7 +280,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, unsigned char *response, *outp; struct pbuf *p; char *name = NULL; /* initialized to shut gcc up */ - int (*verifier)(char *, char *, int, struct chap_digest_type *, + int (*verifier)(char *, char *, int, const struct chap_digest_type *, unsigned char *, unsigned char *, char *, int); char rname[MAXNAMELEN+1]; @@ -398,7 +395,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, * succeeded), or 0 if it doesn't. */ static int chap_verify_response(char *name, char *ourname, int id, - struct chap_digest_type *digest, + const struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space) { int ok; diff --git a/src/netif/ppp/chap_ms.c b/src/netif/ppp/chap_ms.c index 7c51614a..2467aa54 100644 --- a/src/netif/ppp/chap_ms.c +++ b/src/netif/ppp/chap_ms.c @@ -879,7 +879,7 @@ void set_mppe_enc_types(int policy, int types) { } #endif /* MPPE */ -static struct chap_digest_type chapms_digest = { +const struct chap_digest_type chapms_digest = { CHAP_MICROSOFT, /* code */ #if PPP_SERVER chapms_generate_challenge, @@ -890,7 +890,7 @@ static struct chap_digest_type chapms_digest = { chapms_handle_failure, }; -static struct chap_digest_type chapms2_digest = { +const struct chap_digest_type chapms2_digest = { CHAP_MICROSOFT_V2, /* code */ #if PPP_SERVER chapms2_generate_challenge, @@ -901,12 +901,4 @@ static struct chap_digest_type chapms2_digest = { chapms_handle_failure, }; -void chapms_init(void) { - chap_register_digest(&chapms_digest); - chap_register_digest(&chapms2_digest); -#if PPP_OPTIONS - add_options(chapms_option_list); -#endif /* PPP_OPTIONS */ -} - #endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ From 07e72d2ac8e8cebeb3fc55a881dc328768a1e8c1 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 8 Nov 2012 14:39:30 +0100 Subject: [PATCH 286/320] PPP, correctly cast int to u8_t in PPPCTLS_ERRCODE in ppp_ioctl() --- src/netif/ppp/ppp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index bb7e7add..097c7376 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1318,7 +1318,7 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) case PPPCTLS_ERRCODE: /* Set the PPP error code. */ if (arg) { - pcb->err_code = *(u8_t *)arg; + pcb->err_code = (u8_t)(*(int *)arg); return PPPERR_NONE; } return PPPERR_PARAM; From c68e1ceb644985caad1fc8c50a625afa0f59bc5d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 9 Dec 2012 18:42:06 +0100 Subject: [PATCH 287/320] PPP, using timeouts values defined in opt.h instead of values defined in PPP headers or statically assigned values --- src/include/netif/ppp/fsm.h | 2 ++ src/include/netif/ppp/upap.h | 2 +- src/netif/ppp/fsm.c | 8 ++++---- src/netif/ppp/ppp.c | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/include/netif/ppp/fsm.h b/src/include/netif/ppp/fsm.h index 139ff7fb..d4318c5e 100644 --- a/src/include/netif/ppp/fsm.h +++ b/src/include/netif/ppp/fsm.h @@ -152,10 +152,12 @@ typedef struct fsm_callbacks { /* * Timeouts. */ +#if 0 /* moved to opt.h */ #define DEFTIMEOUT 3 /* 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 */ +#endif /* moved to opt.h */ /* diff --git a/src/include/netif/ppp/upap.h b/src/include/netif/ppp/upap.h index 3d1075b2..d6185da9 100644 --- a/src/include/netif/ppp/upap.h +++ b/src/include/netif/ppp/upap.h @@ -90,8 +90,8 @@ */ #if 0 /* moved to opt.h */ #define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */ -#endif /* moved to opt.h */ #define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif /* moved to opt.h */ /* * Each interface is described by upap structure. diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 8ffc7cfd..ad04dcb9 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -79,10 +79,10 @@ void fsm_init(fsm *f) { f->state = PPP_FSM_INITIAL; f->flags = 0; f->id = 0; /* XXX Start with random id? */ - f->timeouttime = DEFTIMEOUT; - f->maxconfreqtransmits = DEFMAXCONFREQS; - f->maxtermtransmits = DEFMAXTERMREQS; - f->maxnakloops = DEFMAXNAKLOOPS; + f->timeouttime = FSM_DEFTIMEOUT; + f->maxconfreqtransmits = FSM_DEFMAXCONFREQS; + f->maxtermtransmits = FSM_DEFMAXTERMREQS; + f->maxnakloops = FSM_DEFMAXNAKLOOPS; f->term_reason_len = 0; } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 097c7376..fe355cae 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -258,8 +258,8 @@ ppp_pcb *ppp_new(void) { /* default configuration */ pcb->settings.usepeerdns = 1; #if CHAP_SUPPORT - pcb->settings.chap_timeout_time = 3; - pcb->settings.chap_max_transmits = 10; + pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; + pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; #endif /* CHAP_SUPPPORT */ pcb->settings.lcp_loopbackfail = DEFLOOPBACKFAIL; pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; From 63459f65fb981c0d0ace96b2ab32954d96bcf059 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 9 Dec 2012 19:28:53 +0100 Subject: [PATCH 288/320] PPP, moved DEFLOOPBACKFAIL from ppp/lcp.h to lwip/opt.h --- src/include/lwip/opt.h | 6 ++++++ src/include/netif/ppp/lcp.h | 2 ++ src/netif/ppp/ppp.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 8e2be763..70e0d2d9 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1900,6 +1900,12 @@ #define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ #endif +/* Default number of times we receive our magic number from the peer + before deciding the link is looped-back. */ +#ifndef LCP_DEFLOOPBACKFAIL +#define LCP_DEFLOOPBACKFAIL 10 +#endif + /* Interval in seconds between keepalive echo requests, 0 to disable. */ #ifndef LCP_ECHOINTERVAL #define LCP_ECHOINTERVAL 0 diff --git a/src/include/netif/ppp/lcp.h b/src/include/netif/ppp/lcp.h index f832a4ee..8162e257 100644 --- a/src/include/netif/ppp/lcp.h +++ b/src/include/netif/ppp/lcp.h @@ -166,9 +166,11 @@ void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len); /* send protocol reject extern const struct protent lcp_protent; +#if 0 /* moved to opt.h */ /* Default number of times we receive our magic number from the peer before deciding the link is looped-back. */ #define DEFLOOPBACKFAIL 10 +#endif /* moved to opt.h */ #endif /* LCP_H */ #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index fe355cae..880bb4e6 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -261,7 +261,7 @@ ppp_pcb *ppp_new(void) { pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; #endif /* CHAP_SUPPPORT */ - pcb->settings.lcp_loopbackfail = DEFLOOPBACKFAIL; + pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; From defef2222a4712c75f0bb4e0a3dd1c989b7e94b6 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 9 Dec 2012 20:24:22 +0100 Subject: [PATCH 289/320] PPP, improved PAP and CHAP timeout/request/maxrequests configuration values --- src/include/lwip/opt.h | 14 +++++++++++++- src/include/netif/ppp/ppp.h | 8 +++++--- src/include/netif/ppp/upap.h | 2 ++ src/netif/ppp/ppp.c | 3 +++ src/netif/ppp/upap.c | 4 +++- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 70e0d2d9..c20435ee 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1888,18 +1888,30 @@ #define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ #endif +#ifndef UPAP_DEFTRANSMITS +#define UPAP_DEFTRANSMITS 10 /* Maximum number of auth-reqs to send */ +#endif + +#if PPP_SERVER #ifndef UPAP_DEFREQTIME #define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ #endif +#endif /* PPP_SERVER */ #ifndef CHAP_DEFTIMEOUT -#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#define CHAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ #endif #ifndef CHAP_DEFTRANSMITS #define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ #endif +#if PPP_SERVER +#ifndef CHAP_DEFREQTIME +#define CHAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif +#endif /* PPP_SERVER */ + /* Default number of times we receive our magic number from the peer before deciding the link is looped-back. */ #ifndef LCP_DEFLOOPBACKFAIL diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 4676ae63..f589cd18 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -225,9 +225,11 @@ typedef struct ppp_settings_s { #endif /* PPP_REMOTENAME */ #if CHAP_SUPPORT - u8_t chap_timeout_time; - u8_t chap_max_transmits; - u8_t chap_rechallenge_time; + u8_t chap_timeout_time; /* Timeout (seconds) for retransmitting req */ + u8_t chap_max_transmits; /* max # times to send challenge */ +#if PPP_SERVER + u8_t chap_rechallenge_time; /* Time to wait for auth-req from peer */ +#endif /* PPP_SERVER */ #endif /* CHAP_SUPPPORT */ u8_t lcp_loopbackfail; /* Number of times we receive our magic number from the peer diff --git a/src/include/netif/ppp/upap.h b/src/include/netif/ppp/upap.h index d6185da9..940f01d0 100644 --- a/src/include/netif/ppp/upap.h +++ b/src/include/netif/ppp/upap.h @@ -110,7 +110,9 @@ typedef struct upap_state { u8_t us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ u8_t us_transmits; /* Number of auth-reqs sent */ u8_t us_maxtransmits; /* Maximum number of auth-reqs to send */ +#if PPP_SERVER u8_t us_reqtimeout; /* Time to wait for auth-req from peer */ +#endif /* PPP_SERVER */ } upap_state; #endif /* PAP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 880bb4e6..a63779e7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -260,6 +260,9 @@ ppp_pcb *ppp_new(void) { #if CHAP_SUPPORT pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; +#if PPP_SERVER + pcb->settings.chap_rechallenge_time = CHAP_DEFREQTIME; +#endif /* PPP_SERVER */ #endif /* CHAP_SUPPPORT */ pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 5e61a76c..5c8b53c2 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -144,8 +144,10 @@ static void upap_init(ppp_pcb *pcb) { #endif /* PPP_SERVER */ pcb->upap.us_id = 0; pcb->upap.us_timeouttime = UPAP_DEFTIMEOUT; - pcb->upap.us_maxtransmits = 10; + pcb->upap.us_maxtransmits = UPAP_DEFTRANSMITS; +#if PPP_SERVER pcb->upap.us_reqtimeout = UPAP_DEFREQTIME; +#endif /* PPP_SERVER */ } From 31d7293b17da63ed7b0ecb787ae180d02a72c14d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 9 Dec 2012 20:40:41 +0100 Subject: [PATCH 290/320] PPP, moved EAP timeouts and max requests default values to opt.h --- src/include/lwip/opt.h | 18 ++++++++++++++++++ src/include/netif/ppp/eap.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index c20435ee..262b5915 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1912,6 +1912,24 @@ #endif #endif /* PPP_SERVER */ +#ifndef EAP_DEFREQTIME +#define EAP_DEFREQTIME 20 /* Time to wait for peer request */ +#endif + +#ifndef EAP_DEFALLOWREQ +#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ +#endif + +#if PPP_SERVER +#ifndef EAP_DEFTIMEOUT +#define EAP_DEFTIMEOUT 6 /* Timeout (seconds) for rexmit */ +#endif + +#ifndef EAP_DEFTRANSMITS +#define EAP_DEFTRANSMITS 10 /* max # times to transmit */ +#endif +#endif /* PPP_SERVER */ + /* Default number of times we receive our magic number from the peer before deciding the link is looped-back. */ #ifndef LCP_DEFLOOPBACKFAIL diff --git a/src/include/netif/ppp/eap.h b/src/include/netif/ppp/eap.h index 328046c1..112c4e71 100644 --- a/src/include/netif/ppp/eap.h +++ b/src/include/netif/ppp/eap.h @@ -149,10 +149,12 @@ typedef struct eap_state { /* * Timeouts. */ +#if 0 /* moved to opt.h */ #define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ #define EAP_DEFTRANSMITS 10 /* max # times to transmit */ #define EAP_DEFREQTIME 20 /* Time to wait for peer request */ #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ +#endif /* moved to opt.h */ void eap_authwithpeer(ppp_pcb *pcb, char *localname); void eap_authpeer(ppp_pcb *pcb, char *localname); From c719ba7bf34a0d30a32a7cf7f57c8c4174621ae9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 9 Dec 2012 21:22:19 +0100 Subject: [PATCH 291/320] PPP, moved PAP configuration to ppp_settings struct --- src/include/netif/ppp/ppp.h | 8 ++++++++ src/include/netif/ppp/upap.h | 5 ----- src/netif/ppp/ppp.c | 7 +++++++ src/netif/ppp/upap.c | 21 ++++++++------------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index f589cd18..598be16e 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -224,6 +224,14 @@ typedef struct ppp_settings_s { char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ #endif /* PPP_REMOTENAME */ +#if PAP_SUPPORT + u8_t pap_timeout_time; /* Timeout (seconds) for auth-req retrans. */ + u8_t pap_max_transmits; /* Number of auth-reqs sent */ +#if PPP_SERVER + u8_t pap_req_timeout; /* Time to wait for auth-req from peer */ +#endif /* PPP_SERVER */ +#endif /* PAP_SUPPPORT */ + #if CHAP_SUPPORT u8_t chap_timeout_time; /* Timeout (seconds) for retransmitting req */ u8_t chap_max_transmits; /* max # times to send challenge */ diff --git a/src/include/netif/ppp/upap.h b/src/include/netif/ppp/upap.h index 940f01d0..edd3bf45 100644 --- a/src/include/netif/ppp/upap.h +++ b/src/include/netif/ppp/upap.h @@ -107,12 +107,7 @@ typedef struct upap_state { u8_t us_serverstate; /* Server state */ #endif /* PPP_SERVER */ u8_t us_id; /* Current id */ - u8_t us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ u8_t us_transmits; /* Number of auth-reqs sent */ - u8_t us_maxtransmits; /* Maximum number of auth-reqs to send */ -#if PPP_SERVER - u8_t us_reqtimeout; /* Time to wait for auth-req from peer */ -#endif /* PPP_SERVER */ } upap_state; #endif /* PAP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index a63779e7..09d138b7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -257,6 +257,13 @@ ppp_pcb *ppp_new(void) { /* default configuration */ pcb->settings.usepeerdns = 1; +#if PAP_SUPPORT + pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT; + pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS; +#if PPP_SERVER + pcb->settings.pap_req_timeout = UPAP_DEFREQTIME; +#endif /* PPP_SERVER */ +#endif /* PAP_SUPPORT */ #if CHAP_SUPPORT pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 5c8b53c2..9cf0e432 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -143,11 +143,6 @@ static void upap_init(ppp_pcb *pcb) { pcb->upap.us_serverstate = UPAPSS_INITIAL; #endif /* PPP_SERVER */ pcb->upap.us_id = 0; - pcb->upap.us_timeouttime = UPAP_DEFTIMEOUT; - pcb->upap.us_maxtransmits = UPAP_DEFTRANSMITS; -#if PPP_SERVER - pcb->upap.us_reqtimeout = UPAP_DEFREQTIME; -#endif /* PPP_SERVER */ } @@ -194,8 +189,8 @@ void upap_authpeer(ppp_pcb *pcb) { } pcb->upap.us_serverstate = UPAPSS_LISTEN; - if (pcb->upap.us_reqtimeout > 0) - TIMEOUT(upap_reqtimeout, pcb, pcb->upap.us_reqtimeout); + if (pcb->settings.pap_req_timeout > 0) + TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout); } #endif /* PPP_SERVER */ @@ -208,7 +203,7 @@ static void upap_timeout(void *arg) { if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) return; - if (pcb->upap.us_transmits >= pcb->upap.us_maxtransmits) { + if (pcb->upap.us_transmits >= pcb->settings.pap_max_transmits) { /* give up in disgust */ ppp_error("No response to PAP authenticate-requests"); pcb->upap.us_clientstate = UPAPCS_BADAUTH; @@ -254,8 +249,8 @@ static void upap_lowerup(ppp_pcb *pcb) { pcb->upap.us_serverstate = UPAPSS_CLOSED; else if (pcb->upap.us_serverstate == UPAPSS_PENDING) { pcb->upap.us_serverstate = UPAPSS_LISTEN; - if (pcb->upap.us_reqtimeout > 0) - TIMEOUT(upap_reqtimeout, pcb, pcb->upap.us_reqtimeout); + if (pcb->settings.pap_req_timeout > 0) + TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout); } #endif /* PPP_SERVER */ } @@ -271,7 +266,7 @@ static void upap_lowerdown(ppp_pcb *pcb) { if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */ #if PPP_SERVER - if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->upap.us_reqtimeout > 0) + if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->settings.pap_req_timeout > 0) UNTIMEOUT(upap_reqtimeout, pcb); #endif /* PPP_SERVER */ @@ -448,7 +443,7 @@ static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) { auth_peer_fail(pcb, PPP_PAP); } - if (pcb->upap.us_reqtimeout > 0) + if (pcb->settings.pap_req_timeout > 0) UNTIMEOUT(upap_reqtimeout, pcb); } #endif /* PPP_SERVER */ @@ -554,7 +549,7 @@ static void upap_sauthreq(ppp_pcb *pcb) { ppp_write(pcb, p); - TIMEOUT(upap_timeout, pcb, pcb->upap.us_timeouttime); + TIMEOUT(upap_timeout, pcb, pcb->settings.pap_timeout_time); ++pcb->upap.us_transmits; pcb->upap.us_clientstate = UPAPCS_AUTHREQ; } From 6764957d062f10118551a6698a7d997c83bb400e Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 9 Dec 2012 21:45:14 +0100 Subject: [PATCH 292/320] PPP, moved EAP configuration to ppp_settings struct --- src/include/lwip/opt.h | 4 +-- src/include/netif/ppp/eap.h | 2 -- src/include/netif/ppp/ppp.h | 9 +++++++ src/netif/ppp/eap.c | 50 +++++++++++++++++-------------------- src/netif/ppp/ppp.c | 8 ++++++ 5 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 262b5915..fac1bf10 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1913,11 +1913,11 @@ #endif /* PPP_SERVER */ #ifndef EAP_DEFREQTIME -#define EAP_DEFREQTIME 20 /* Time to wait for peer request */ +#define EAP_DEFREQTIME 6 /* Time to wait for peer request */ #endif #ifndef EAP_DEFALLOWREQ -#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ +#define EAP_DEFALLOWREQ 10 /* max # times to accept requests */ #endif #if PPP_SERVER diff --git a/src/include/netif/ppp/eap.h b/src/include/netif/ppp/eap.h index 112c4e71..c92f2dc0 100644 --- a/src/include/netif/ppp/eap.h +++ b/src/include/netif/ppp/eap.h @@ -117,8 +117,6 @@ struct eap_auth { char *ea_peer; /* Peer's name */ void *ea_session; /* Authentication library linkage */ u_char *ea_skey; /* Shared encryption key */ - int ea_timeout; /* Time to wait (for retransmit/fail) */ - int ea_maxrequests; /* Max Requests allowed */ u_short ea_namelen; /* Length of our name */ u_short ea_peerlen; /* Length of peer's name */ enum eap_state_code ea_state; diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 598be16e..8768ae85 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -240,6 +240,15 @@ typedef struct ppp_settings_s { #endif /* PPP_SERVER */ #endif /* CHAP_SUPPPORT */ +#if EAP_SUPPORT + u8_t eap_req_time; /* Time to wait (for retransmit/fail) */ + u8_t eap_allow_req; /* Max Requests allowed */ +#if PPP_SERVER + u8_t eap_timeout_time; /* Time to wait (for retransmit/fail) */ + u8_t eap_max_transmits; /* Max Requests allowed */ +#endif /* PPP_SERVER */ +#endif /* EAP_SUPPORT */ + u8_t lcp_loopbackfail; /* Number of times we receive our magic number from the peer before deciding the link is looped-back. */ u8_t lcp_echo_interval; /* Interval between LCP echo-requests */ diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index b3106ad3..d8b7359f 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -204,12 +204,8 @@ static void eap_init(ppp_pcb *pcb) { BZERO(&pcb->eap, sizeof(eap_state)); #if PPP_SERVER - pcb->eap.es_server.ea_timeout = EAP_DEFTIMEOUT; - pcb->eap.es_server.ea_maxrequests = EAP_DEFTRANSMITS; - pcb->eap.es_server.ea_id = (u_char)(drand48() * 0x100); + pcb->eap.es_server.ea_id = (u_char)(drand48() * 0x100); /* FIXME: use magic.c random function */ #endif /* PPP_SERVER */ - pcb->eap.es_client.ea_timeout = EAP_DEFREQTIME; - pcb->eap.es_client.ea_maxrequests = EAP_DEFALLOWREQ; } /* @@ -248,9 +244,9 @@ void eap_authwithpeer(ppp_pcb *pcb, char *localname) { * Start a timer so that if the other end just goes * silent, we don't sit here waiting forever. */ - if (pcb->eap.es_client.ea_timeout > 0) + if (pcb->settings.eap_req_time > 0) TIMEOUT(eap_client_timeout, pcb, - pcb->eap.es_client.ea_timeout); + pcb->settings.eap_req_time); } #if PPP_SERVER @@ -445,7 +441,7 @@ static void eap_figure_next_state(ppp_pcb *pcb, int status) { struct b64state bs; #endif /* USE_SRP */ - pcb->eap.es_server.ea_timeout = pcb->eap.es_savedtime; + pcb->settings.eap_timeout_time = pcb->eap.es_savedtime; switch (pcb->eap.es_server.ea_state) { case eapBadAuth: return; @@ -544,9 +540,9 @@ static void eap_figure_next_state(ppp_pcb *pcb, int status) { * generator combination, and that will take * a while. Lengthen the timeout here. */ - if (pcb->eap.es_server.ea_timeout > 0 && - pcb->eap.es_server.ea_timeout < 30) - pcb->eap.es_server.ea_timeout = 30; + if (pcb->settings.eap_timeout_time > 0 && + pcb->settings.eap_timeout_time < 30) + pcb->settings.eap_timeout_time = 30; } else { break; } @@ -680,8 +676,8 @@ static void eap_send_request(ppp_pcb *pcb) { #endif /* PPP_REMOTENAME */ } - if (pcb->eap.es_server.ea_maxrequests > 0 && - pcb->eap.es_server.ea_requests >= pcb->eap.es_server.ea_maxrequests) { + if (pcb->settings.eap_max_transmits > 0 && + pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) { if (pcb->eap.es_server.ea_responses > 0) ppp_error("EAP: too many Requests sent"); else @@ -882,8 +878,8 @@ static void eap_send_request(ppp_pcb *pcb) { pcb->eap.es_server.ea_requests++; - if (pcb->eap.es_server.ea_timeout > 0) - TIMEOUT(eap_server_timeout, pcb, pcb->eap.es_server.ea_timeout); + if (pcb->settings.eap_timeout_time > 0) + TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time); } /* @@ -898,7 +894,7 @@ void eap_authpeer(ppp_pcb *pcb, char *localname) { pcb->eap.es_server.ea_name = localname; pcb->eap.es_server.ea_namelen = strlen(localname); - pcb->eap.es_savedtime = pcb->eap.es_server.ea_timeout; + pcb->eap.es_savedtime = pcb->settings.eap_timeout_time; /* Lower layer up yet? */ if (pcb->eap.es_server.ea_state == eapInitial || @@ -997,12 +993,12 @@ static void eap_lowerup(ppp_pcb *pcb) { */ static void eap_lowerdown(ppp_pcb *pcb) { - if (eap_client_active(pcb) && pcb->eap.es_client.ea_timeout > 0) { + if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) { UNTIMEOUT(eap_client_timeout, pcb); } #if PPP_SERVER if (eap_server_active(pcb)) { - if (pcb->eap.es_server.ea_timeout > 0) { + if (pcb->settings.eap_timeout_time > 0) { UNTIMEOUT(eap_server_timeout, pcb); } } else { @@ -1366,10 +1362,10 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { */ pcb->eap.es_client.ea_requests++; - if (pcb->eap.es_client.ea_maxrequests != 0 && - pcb->eap.es_client.ea_requests > pcb->eap.es_client.ea_maxrequests) { + if (pcb->settings.eap_allow_req != 0 && + pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) { ppp_info("EAP: received too many Request messages"); - if (pcb->eap.es_client.ea_timeout > 0) { + if (pcb->settings.eap_req_time > 0) { UNTIMEOUT(eap_client_timeout, pcb); } auth_withpeer_fail(pcb, PPP_EAP); @@ -1726,17 +1722,17 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { break; } - if (pcb->eap.es_client.ea_timeout > 0) { + if (pcb->settings.eap_req_time > 0) { UNTIMEOUT(eap_client_timeout, pcb); TIMEOUT(eap_client_timeout, pcb, - pcb->eap.es_client.ea_timeout); + pcb->settings.eap_req_time); } return; #ifdef USE_SRP client_failure: pcb->eap.es_client.ea_state = eapBadAuth; - if (pcb->eap.es_client.ea_timeout > 0) { + if (pcb->settings.eap_req_time > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } pcb->eap.es_client.ea_session = NULL; @@ -2034,7 +2030,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { return; } - if (pcb->eap.es_server.ea_timeout > 0) { + if (pcb->settings.eap_timeout_time > 0) { UNTIMEOUT(eap_server_timeout, pcb); } @@ -2057,7 +2053,7 @@ static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) { return; } - if (pcb->eap.es_client.ea_timeout > 0) { + if (pcb->settings.eap_req_time > 0) { UNTIMEOUT(eap_client_timeout, pcb); } @@ -2080,7 +2076,7 @@ static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) { pcb->eap.es_client.ea_state); } - if (pcb->eap.es_client.ea_timeout > 0) { + if (pcb->settings.eap_req_time > 0) { UNTIMEOUT(eap_client_timeout, pcb); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 09d138b7..a99980fe 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -271,6 +271,14 @@ ppp_pcb *ppp_new(void) { pcb->settings.chap_rechallenge_time = CHAP_DEFREQTIME; #endif /* PPP_SERVER */ #endif /* CHAP_SUPPPORT */ +#if EAP_SUPPORT + pcb->settings.eap_req_time = EAP_DEFREQTIME; + pcb->settings.eap_allow_req = EAP_DEFALLOWREQ; +#if PPP_SERVER + pcb->settings.eap_timeout_time = EAP_DEFTIMEOUT; + pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS; +#endif /* PPP_SERVER */ +#endif /* EAP_SUPPORT */ pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; From 6751ac497085f95bbe82090f2612ae943b8a5d64 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 9 Dec 2012 22:25:28 +0100 Subject: [PATCH 293/320] PPP, moved FSM configuration to ppp_settings struct --- src/include/netif/ppp/fsm.h | 6 ++---- src/include/netif/ppp/ppp.h | 5 +++++ src/netif/ppp/fsm.c | 29 +++++++++++++++++------------ src/netif/ppp/ppp.c | 9 +++++++++ 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/include/netif/ppp/fsm.h b/src/include/netif/ppp/fsm.h index d4318c5e..cd12075f 100644 --- a/src/include/netif/ppp/fsm.h +++ b/src/include/netif/ppp/fsm.h @@ -82,13 +82,11 @@ typedef struct fsm { u8_t flags; /* Contains option bits */ u8_t id; /* Current id */ u8_t reqid; /* Current request id */ - u8_t timeouttime; /* Timeout time in seconds */ - u8_t maxconfreqtransmits; /* Maximum Configure-Request transmissions */ u8_t retransmits; /* Number of retransmissions left */ - u8_t maxtermtransmits; /* Maximum Terminate-Request transmissions */ u8_t nakloops; /* Number of nak loops since last ack */ u8_t rnakloops; /* Number of naks received */ - u8_t maxnakloops; /* Maximum number of nak loops tolerated */ + u8_t maxnakloops; /* Maximum number of nak loops tolerated + (necessary because IPCP require a custom large max nak loops value) */ u8_t term_reason_len; /* Length of term_reason */ } fsm; diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 8768ae85..30bb67af 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -249,6 +249,11 @@ typedef struct ppp_settings_s { #endif /* PPP_SERVER */ #endif /* EAP_SUPPORT */ + u8_t fsm_timeout_time; /* Timeout time in seconds */ + u8_t fsm_max_conf_req_transmits; /* Maximum Configure-Request transmissions */ + u8_t fsm_max_term_transmits; /* Maximum Terminate-Request transmissions */ + u8_t fsm_max_nak_loops; /* Maximum number of nak loops tolerated */ + u8_t lcp_loopbackfail; /* Number of times we receive our magic number from the peer before deciding the link is looped-back. */ u8_t lcp_echo_interval; /* Interval between LCP echo-requests */ diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index ad04dcb9..896eb7a2 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -76,13 +76,11 @@ static void fsm_sconfreq(fsm *f, int retransmit); * Initialize fsm state. */ void fsm_init(fsm *f) { + ppp_pcb *pcb = f->pcb; f->state = PPP_FSM_INITIAL; f->flags = 0; f->id = 0; /* XXX Start with random id? */ - f->timeouttime = FSM_DEFTIMEOUT; - f->maxconfreqtransmits = FSM_DEFMAXCONFREQS; - f->maxtermtransmits = FSM_DEFMAXTERMREQS; - f->maxnakloops = FSM_DEFMAXNAKLOOPS; + f->maxnakloops = pcb->settings.fsm_max_nak_loops; f->term_reason_len = 0; } @@ -198,13 +196,15 @@ void fsm_open(fsm *f) { * send a terminate-request message as configured. */ static void terminate_layer(fsm *f, int nextstate) { + ppp_pcb *pcb = f->pcb; + if( f->state != PPP_FSM_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 and send Terminate-Request */ - f->retransmits = f->maxtermtransmits; + f->retransmits = pcb->settings.fsm_max_term_transmits; fsm_sdata(f, TERMREQ, f->reqid = ++f->id, (u_char *) f->term_reason, f->term_reason_len); @@ -220,7 +220,7 @@ static void terminate_layer(fsm *f, int nextstate) { return; } - TIMEOUT(fsm_timeout, f, f->timeouttime); + TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); --f->retransmits; f->state = nextstate; @@ -261,6 +261,7 @@ void fsm_close(fsm *f, char *reason) { */ static void fsm_timeout(void *arg) { fsm *f = (fsm *) arg; + ppp_pcb *pcb = f->pcb; switch (f->state) { case PPP_FSM_CLOSING: @@ -276,7 +277,7 @@ static void fsm_timeout(void *arg) { /* 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); + TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); --f->retransmits; } break; @@ -450,6 +451,8 @@ static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) { * fsm_rconfack - Receive Configure-Ack. */ static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { + ppp_pcb *pcb = f->pcb; + if (id != f->reqid || f->seen_ack) /* Expected id? */ return; /* Nope, toss... */ if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): @@ -469,7 +472,7 @@ static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { case PPP_FSM_REQSENT: f->state = PPP_FSM_ACKRCVD; - f->retransmits = f->maxconfreqtransmits; + f->retransmits = pcb->settings.fsm_max_conf_req_transmits; break; case PPP_FSM_ACKRCVD: @@ -482,7 +485,7 @@ static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { case PPP_FSM_ACKSENT: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ f->state = PPP_FSM_OPENED; - f->retransmits = f->maxconfreqtransmits; + f->retransmits = pcb->settings.fsm_max_conf_req_transmits; if (f->callbacks->up) (*f->callbacks->up)(f); /* Inform upper layers */ break; @@ -565,6 +568,8 @@ static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { * fsm_rtermreq - Receive Terminate-Req. */ static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + switch (f->state) { case PPP_FSM_ACKRCVD: case PPP_FSM_ACKSENT: @@ -580,7 +585,7 @@ static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { f->state = PPP_FSM_STOPPING; if (f->callbacks->down) (*f->callbacks->down)(f); /* Inform upper layers */ - TIMEOUT(fsm_timeout, f, f->timeouttime); + TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); break; } @@ -700,7 +705,7 @@ static void fsm_sconfreq(fsm *f, int retransmit) { if( !retransmit ){ /* New request - reset retransmission counter, use new ID */ - f->retransmits = f->maxconfreqtransmits; + f->retransmits = pcb->settings.fsm_max_conf_req_transmits; f->reqid = ++f->id; } @@ -738,7 +743,7 @@ static void fsm_sconfreq(fsm *f, int retransmit) { /* start the retransmit timer */ --f->retransmits; - TIMEOUT(fsm_timeout, f, f->timeouttime); + TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); } diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index a99980fe..4c459b28 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -257,6 +257,7 @@ ppp_pcb *ppp_new(void) { /* default configuration */ pcb->settings.usepeerdns = 1; + #if PAP_SUPPORT pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT; pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS; @@ -264,6 +265,7 @@ ppp_pcb *ppp_new(void) { pcb->settings.pap_req_timeout = UPAP_DEFREQTIME; #endif /* PPP_SERVER */ #endif /* PAP_SUPPORT */ + #if CHAP_SUPPORT pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; @@ -271,6 +273,7 @@ ppp_pcb *ppp_new(void) { pcb->settings.chap_rechallenge_time = CHAP_DEFREQTIME; #endif /* PPP_SERVER */ #endif /* CHAP_SUPPPORT */ + #if EAP_SUPPORT pcb->settings.eap_req_time = EAP_DEFREQTIME; pcb->settings.eap_allow_req = EAP_DEFALLOWREQ; @@ -279,10 +282,16 @@ ppp_pcb *ppp_new(void) { pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS; #endif /* PPP_SERVER */ #endif /* EAP_SUPPORT */ + pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; + pcb->settings.fsm_timeout_time = FSM_DEFTIMEOUT; + pcb->settings.fsm_max_conf_req_transmits = FSM_DEFMAXCONFREQS; + pcb->settings.fsm_max_term_transmits = FSM_DEFMAXTERMREQS; + pcb->settings.fsm_max_nak_loops = FSM_DEFMAXNAKLOOPS; + if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { memp_free(MEMP_PPP_PCB, pcb); From 211a889528ce238fad799b6965ec9d928efb7fd4 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 23 Dec 2012 22:52:58 +0100 Subject: [PATCH 294/320] PPP, fixed some IAR warnings these are the compiler warnings I get with the head of ppp-new. All of them are trivial, [...] (I'm using IAR EWARM 6.4). ppp.c Warning[Pe550]: variable "c" was set but never used lwip\src\netif\ppp\ppp.c 1012 Warning[Pe111]: statement is unreachable lwip\src\netif\ppp\ppp.c 1132 Warning[Pe111]: statement is unreachable lwip\src\netif\ppp\ppp.c 1377 Warning[Pe111]: statement is unreachable lwip\src\netif\ppp\ppp.c 1412 utils.c Warning[Pe186]: pointless comparison of unsigned integer with zero lwip\src\netif\ppp\utils.c 210 --- src/netif/ppp/ppp.c | 11 ++++++----- src/netif/ppp/utils.c | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 4c459b28..c6e29ac7 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1012,7 +1012,8 @@ pppos_put(ppp_pcb *pcb, struct pbuf *nb) int c; for(b = nb; b != NULL; b = b->next) { - if((c = sio_write(pcb->fd, b->payload, b->len)) != b->len) { + c = sio_write(pcb->fd, b->payload, b->len) + if(c != b->len) { PPPDEBUG(LOG_WARNING, ("PPP pppos_put: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pcb->fd, b->len, c, c)); LINK_STATS_INC(link.err); @@ -1129,7 +1130,9 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot return ppp_netif_output_over_serial(pcb, pb, protocol); #endif /* PPPOS_SUPPORT */ +#if !PPPOS_SUPPORT return ERR_OK; +#endif } #if PPPOS_SUPPORT @@ -1368,10 +1371,6 @@ ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) return PPPERR_PARAM; break; #endif /* PPPOS_SUPPORT */ - - default: - return PPPERR_PARAM; - break; } return PPPERR_PARAM; @@ -1409,8 +1408,10 @@ int ppp_write(ppp_pcb *pcb, struct pbuf *p) { return ppp_write_over_serial(pcb, p); #endif /* PPPOS_SUPPORT */ +#if !PPPOS_SUPPORT pbuf_free(p); return PPPERR_NONE; +#endif } #if PPPOS_SUPPORT diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index c7a78c7c..6529a933 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -207,7 +207,7 @@ int ppp_vslprintf(char *buf, int buflen, char *fmt, va_list args) { switch (c) { case 'd': val = va_arg(args, long); - if (val < 0) { + if ((long)val < 0) { neg = 1; val = -val; } From bdfbac2aa677bc415d323137611fcf70548ccf36 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sun, 23 Dec 2012 22:58:52 +0100 Subject: [PATCH 295/320] PPP, added missing semicolon (dammit) --- src/netif/ppp/ppp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index c6e29ac7..88b661dd 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1012,7 +1012,7 @@ pppos_put(ppp_pcb *pcb, struct pbuf *nb) int c; for(b = nb; b != NULL; b = b->next) { - c = sio_write(pcb->fd, b->payload, b->len) + c = sio_write(pcb->fd, b->payload, b->len); if(c != b->len) { PPPDEBUG(LOG_WARNING, ("PPP pppos_put: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pcb->fd, b->len, c, c)); From 13ba8810c774e8e4371690629da3478b6a793d07 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 4 Jan 2013 22:51:13 +0100 Subject: [PATCH 296/320] PPP, fixed one more IAR warnings --- src/netif/ppp/lcp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 76cec49e..29cf2166 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1350,6 +1350,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { */ NAKCICHAR(CI_CALLBACK, neg_cbcp, try.neg_cbcp = 0; + (void)cichar; /* if CHAP support is not compiled, cichar is set but not used, which makes some compilers complaining */ ); /* From de1375201fe1370d28650d13a84ff2b025f068f8 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 4 Jan 2013 23:08:11 +0100 Subject: [PATCH 297/320] PPP, "try" variable used in LCP might conflict with some buggy C++ compiler --- src/netif/ppp/lcp.c | 92 ++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 29cf2166..beab480b 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1072,12 +1072,12 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { u_short cishort; u32_t cilong; lcp_options no; /* options we've seen Naks for */ - lcp_options try; /* options to request next time */ + lcp_options try_; /* options to request next time */ int looped_back = 0; int cilen; BZERO(&no, sizeof(no)); - try = *go; + try_ = *go; /* * Any Nak'd CIs must be in exactly the same order that we sent. @@ -1092,7 +1092,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { len -= CILEN_VOID; \ INCPTR(CILEN_VOID, p); \ no.neg = 1; \ - try.neg = 0; \ + try_.neg = 0; \ } #if CHAP_SUPPORT #define NAKCICHAP(opt, neg, code) \ @@ -1164,7 +1164,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { len -= p[1]; \ INCPTR(p[1], p); \ no.neg = 1; \ - try.neg = 0; \ + try_.neg = 0; \ } /* @@ -1181,7 +1181,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { if (go->neg_mru && go->mru != DEFMRU) { NAKCISHORT(CI_MRU, neg_mru, if (cishort <= wo->mru || cishort <= DEFMRU) - try.mru = cishort; + try_.mru = cishort; ); } @@ -1190,7 +1190,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { */ if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { NAKCILONG(CI_ASYNCMAP, neg_asyncmap, - try.asyncmap = go->asyncmap | cilong; + try_.asyncmap = go->asyncmap | cilong; ); } @@ -1231,14 +1231,14 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { #if EAP_SUPPORT /* If we were asking for EAP, then we need to stop that. */ if (go->neg_eap) - try.neg_eap = 0; + try_.neg_eap = 0; else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT /* If we were asking for CHAP, then we need to stop that. */ if (go->neg_chap) - try.neg_chap = 0; + try_.neg_chap = 0; else #endif /* CHAP_SUPPORT */ @@ -1256,10 +1256,10 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { #if EAP_SUPPORT /* Stop asking for EAP, if we were. */ if (go->neg_eap) { - try.neg_eap = 0; + try_.neg_eap = 0; /* Try to set up to use their suggestion, if possible */ if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) - try.chap_mdtype = CHAP_MDTYPE_D(cichar); + try_.chap_mdtype = CHAP_MDTYPE_D(cichar); } else #endif /* EAP_SUPPORT */ if (go->neg_chap) { @@ -1270,12 +1270,12 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { if (cichar != CHAP_DIGEST(go->chap_mdtype)) { if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) { /* Use their suggestion if we support it ... */ - try.chap_mdtype = CHAP_MDTYPE_D(cichar); + try_.chap_mdtype = CHAP_MDTYPE_D(cichar); } else { /* ... otherwise, try our next-preferred algorithm. */ - try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype)); - if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */ - try.neg_chap = 0; + try_.chap_mdtype &= ~(CHAP_MDTYPE(try_.chap_mdtype)); + if (try_.chap_mdtype == MDTYPE_NONE) /* out of algos */ + try_.neg_chap = 0; } } else { /* @@ -1289,7 +1289,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { * Stop asking for PAP if we were asking for it. */ #if PAP_SUPPORT - try.neg_upap = 0; + try_.neg_upap = 0; #endif /* PAP_SUPPORT */ } @@ -1310,19 +1310,19 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { * Stop asking for what we were asking for. */ if (go->neg_eap) - try.neg_eap = 0; + try_.neg_eap = 0; else #endif /* EAP_SUPPORT */ #if CHAP_SUPPORT if (go->neg_chap) - try.neg_chap = 0; + try_.neg_chap = 0; else #endif /* CHAP_SUPPORT */ #if PAP_SUPPORT if(1) - try.neg_upap = 0; + try_.neg_upap = 0; else #endif /* PAP_SUPPORT */ {} @@ -1339,9 +1339,9 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { */ NAKCILQR(CI_QUALITY, neg_lqr, if (cishort != PPP_LQR) - try.neg_lqr = 0; + try_.neg_lqr = 0; else - try.lqr_period = cilong; + try_.lqr_period = cilong; ); #endif /* LQR_SUPPORT */ @@ -1349,7 +1349,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { * Only implementing CBCP...not the rest of the callback options */ NAKCICHAR(CI_CALLBACK, neg_cbcp, - try.neg_cbcp = 0; + try_.neg_cbcp = 0; (void)cichar; /* if CHAP support is not compiled, cichar is set but not used, which makes some compilers complaining */ ); @@ -1357,7 +1357,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { * Check for a looped-back line. */ NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, - try.magicnumber = magic(); + try_.magicnumber = magic(); looped_back = 1; ); @@ -1377,9 +1377,9 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { if (go->neg_mrru) { NAKCISHORT(CI_MRRU, neg_mrru, if (treat_as_reject) - try.neg_mrru = 0; + try_.neg_mrru = 0; else if (cishort <= wo->mrru) - try.mrru = cishort; + try_.mrru = cishort; ); } #endif /* HAVE_MULTILINK */ @@ -1426,8 +1426,8 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { goto bad; GETSHORT(cishort, p); if (cishort < DEFMRU) { - try.neg_mru = 1; - try.mru = cishort; + try_.neg_mru = 1; + try_.mru = cishort; } break; case CI_ASYNCMAP: @@ -1479,7 +1479,7 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { case CI_SSNHF: if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) goto bad; - try.neg_ssnhf = 1; + try_.neg_ssnhf = 1; break; case CI_EPDISC: if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR) @@ -1495,15 +1495,15 @@ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { */ if (f->state != PPP_FSM_OPENED) { if (looped_back) { - if (++try.numloops >= pcb->settings.lcp_loopbackfail) { + if (++try_.numloops >= pcb->settings.lcp_loopbackfail) { int errcode = PPPERR_LOOPBACK; ppp_notice("Serial line is looped back."); ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); lcp_close(f->pcb, "Loopback detected"); } } else - try.numloops = 0; - *go = try; + try_.numloops = 0; + *go = try_; } return 1; @@ -1529,9 +1529,9 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { u_char cichar; u_short cishort; u32_t cilong; - lcp_options try; /* options to request next time */ + lcp_options try_; /* options to request next time */ - try = *go; + try_ = *go; /* * Any Rejected CIs must be in exactly the same order that we sent. @@ -1545,7 +1545,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { p[0] == opt) { \ len -= CILEN_VOID; \ INCPTR(CILEN_VOID, p); \ - try.neg = 0; \ + try_.neg = 0; \ } #define REJCISHORT(opt, neg, val) \ if (go->neg && \ @@ -1558,7 +1558,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* Check rejected value. */ \ if (cishort != val) \ goto bad; \ - try.neg = 0; \ + try_.neg = 0; \ } #if CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT @@ -1574,8 +1574,8 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* Check rejected value. */ \ if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ goto bad; \ - try.neg = 0; \ - try.neg_eap = try.neg_upap = 0; \ + try_.neg = 0; \ + try_.neg_eap = try_.neg_upap = 0; \ } #endif /* CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT */ @@ -1592,8 +1592,8 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* Check rejected value. */ \ if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ goto bad; \ - try.neg = 0; \ - try.neg_upap = 0; \ + try_.neg = 0; \ + try_.neg_upap = 0; \ } #endif /* CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT */ @@ -1610,8 +1610,8 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* Check rejected value. */ \ if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ goto bad; \ - try.neg = 0; \ - try.neg_eap = 0; \ + try_.neg = 0; \ + try_.neg_eap = 0; \ } #endif /* CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT */ @@ -1628,7 +1628,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* Check rejected value. */ \ if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ goto bad; \ - try.neg = 0; \ + try_.neg = 0; \ } #endif /* CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT */ @@ -1643,7 +1643,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* Check rejected value. */ \ if (cilong != val) \ goto bad; \ - try.neg = 0; \ + try_.neg = 0; \ } #if LQR_SUPPORT #define REJCILQR(opt, neg, val) \ @@ -1658,7 +1658,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* Check rejected value. */ \ if (cishort != PPP_LQR || cilong != val) \ goto bad; \ - try.neg = 0; \ + try_.neg = 0; \ } #endif /* LQR_SUPPORT */ #define REJCICBCP(opt, neg, val) \ @@ -1672,7 +1672,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { /* Check rejected value. */ \ if (cichar != val) \ goto bad; \ - try.neg = 0; \ + try_.neg = 0; \ } #define REJCIENDP(opt, neg, class, val, vlen) \ if (go->neg && \ @@ -1690,7 +1690,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { if (cichar != val[i]) \ goto bad; \ } \ - try.neg = 0; \ + try_.neg = 0; \ } REJCISHORT(CI_MRU, neg_mru, go->mru); @@ -1735,7 +1735,7 @@ static int lcp_rejci(fsm *f, u_char *p, int len) { * Now we can update state. */ if (f->state != PPP_FSM_OPENED) - *go = try; + *go = try_; return 1; bad: From 2fa7e003b190eefcda903b019ac92fb66c28f30f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 31 Jan 2013 15:36:30 +0100 Subject: [PATCH 298/320] PPP, fixed LCP delayed up feature LCP is stealing a bit from fsm->flags struct member for LCP delayed up feature. Bit stealed used to be the 9th bit (0x100) but fsm->flags was reduced to u8_t to save memory, we are now stealing the 8th bit (0x80). --- src/netif/ppp/lcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index beab480b..e11d4371 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -68,7 +68,7 @@ * configure-requests. We do this by delaying the fsm_lowerup call. */ /* steal a bit in fsm flags word */ -#define DELAYED_UP 0x100 +#define DELAYED_UP 0x80 static void lcp_delayed_up(void *arg); From bfe8c15a29b81f3e48cb88e69dfcb58575db287d Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 22 Feb 2013 11:52:44 +0100 Subject: [PATCH 299/320] PPP, fixed return code coherency for ppp_netif_output_*() callbacks (using ERR_* as expected by lwIP core instead of PPPERR_*) --- src/netif/ppp/ppp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 88b661dd..0038bc28 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1252,6 +1252,7 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_shor struct pbuf *pb; int i=0; u16_t tot_len; + err_t err; /* @todo: try to use pbuf_header() here! */ pb = pbuf_alloc(PBUF_LINK, PPPOE_HEADERLEN + sizeof(protocol), PBUF_RAM); @@ -1274,10 +1275,10 @@ static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_shor pbuf_chain(pb, p); tot_len = pb->tot_len; - if(pppoe_xmit(pcb->pppoe_sc, pb) != ERR_OK) { + if( (err = pppoe_xmit(pcb->pppoe_sc, pb)) != ERR_OK) { LINK_STATS_INC(link.err); snmp_inc_ifoutdiscards(&pcb->netif); - return PPPERR_DEVICE; + return err; } snmp_add_ifoutoctets(&pcb->netif, tot_len); @@ -1293,6 +1294,7 @@ static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short pr struct pbuf *pb; int i=0; u16_t tot_len; + err_t err; /* @todo: try to use pbuf_header() here! */ pb = pbuf_alloc(PBUF_TRANSPORT, PPPOL2TP_OUTPUT_DATA_HEADER_LEN + sizeof(protocol), PBUF_RAM); @@ -1315,10 +1317,10 @@ static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short pr pbuf_chain(pb, p); tot_len = pb->tot_len; - if(pppol2tp_xmit(pcb->l2tp_pcb, pb) != ERR_OK) { + if( (err = pppol2tp_xmit(pcb->l2tp_pcb, pb)) != ERR_OK) { LINK_STATS_INC(link.err); snmp_inc_ifoutdiscards(&pcb->netif); - return PPPERR_DEVICE; + return err; } snmp_add_ifoutoctets(&pcb->netif, tot_len); From 58ffa8d526e76d552a1fbc50197bdebc99f00564 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Wed, 27 Feb 2013 22:29:22 +0100 Subject: [PATCH 300/320] PPP, free input pbuf left in ppp_delete() --- src/netif/ppp/ppp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 0038bc28..75216f81 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -613,6 +613,11 @@ int ppp_delete(ppp_pcb *pcb) { } #endif /* PPPOL2TP_SUPPORT */ +#if PPPOS_SUPPORT + /* input pbuf left ? */ + ppp_free_current_input_packet(&pcb->rx); +#endif /* PPPOS_SUPPORT */ + memp_free(MEMP_PPP_PCB, pcb); return 0; } @@ -2020,6 +2025,9 @@ void ppp_link_terminated(ppp_pcb *pcb) { #endif /* PPPOL2TP_SUPPORT */ { #if PPPOS_SUPPORT + /* We cannot call ppp_free_current_input_packet() here because + * rx thread might still call pppos_input_proc() + */ #if PPP_INPROC_OWNTHREAD ppp_receive_wakeup(pcb); #endif /* PPP_INPROC_OWNTHREAD */ From d03d2e6d3dbcd91d9cb6ae9c25320857cb300795 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 22 Apr 2013 21:09:28 +0200 Subject: [PATCH 301/320] PPP, added ppp_addrs() macro to get the pointer of the ppp->addrs struct --- src/include/netif/ppp/ppp.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 30bb67af..7010d2e2 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -569,6 +569,9 @@ void pppos_input(ppp_pcb *pcb, u_char* data, int len); /* Get the PPP netif interface */ #define ppp_netif(ppp) (&(ppp)->netif) +/* Get the PPP addresses */ +#define ppp_addrs(ppp) (&(ppp)->addrs) + #if LWIP_NETIF_STATUS_CALLBACK /* Set an lwIP-style status-callback for the selected PPP device */ void ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback); From bd3ade31fa44d2b57c72f911781dbdf245346041 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 22 Apr 2013 21:16:02 +0200 Subject: [PATCH 302/320] PPP, added define for u_long, u_int, u_short, u_char for compilers or toolchains which don't have them --- src/include/netif/ppp/ppp_impl.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/include/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h index 06d40b6b..19af4429 100644 --- a/src/include/netif/ppp/ppp_impl.h +++ b/src/include/netif/ppp/ppp_impl.h @@ -47,6 +47,14 @@ #include "lwip/timers.h" #include "lwip/sio.h" +/* Type definitions for BSD code. */ +#ifndef __u_char_defined +typedef unsigned long u_long; +typedef unsigned int u_int; +typedef unsigned short u_short; +typedef unsigned char u_char; +#endif + #include "ppp.h" #include "pppdebug.h" From ed294c5945c249636976763f4fd0a088c56b2349 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 22 Apr 2013 21:21:04 +0200 Subject: [PATCH 303/320] PPP, removed ppposapi_input(), unnecessary because pppos_input() is already thread-safe --- src/api/pppapi.c | 24 ------------------------ src/include/lwip/pppapi.h | 9 --------- 2 files changed, 33 deletions(-) diff --git a/src/api/pppapi.c b/src/api/pppapi.c index 50f8369e..274b5ed5 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -312,30 +312,6 @@ int pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg) { } -#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD -/** - * Call pppos_input() inside the tcpip_thread context. - */ -static void pppapi_do_pppos_input(struct pppapi_msg_msg *msg) { - pppos_input(msg->ppp, msg->msg.ppposinput.data, msg->msg.ppposinput.len); - TCPIP_PPPAPI_ACK(msg); -} - -/** - * Call pppos_input() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -void ppposapi_input(ppp_pcb *pcb, u_char* data, int len) { - struct pppapi_msg msg; - msg.function = pppapi_do_pppos_input; - msg.msg.ppp = pcb; - msg.msg.msg.ppposinput.data = data; - msg.msg.msg.ppposinput.len = len; - TCPIP_PPPAPI(&msg); -} -#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ - - #if LWIP_NETIF_STATUS_CALLBACK /** * Call ppp_set_netif_statuscallback() inside the tcpip_thread context. diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index c889b5bf..90518dc3 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -87,12 +87,6 @@ struct pppapi_msg_msg { int cmd; void *arg; } ioctl; -#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD - struct { - u_char *data; - int len; - } ppposinput; -#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ #if LWIP_NETIF_STATUS_CALLBACK struct { netif_status_callback_fn status_callback; @@ -133,9 +127,6 @@ int pppapi_close(ppp_pcb *pcb); void pppapi_sighup(ppp_pcb *pcb); int pppapi_delete(ppp_pcb *pcb); int pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg); -#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD -void ppposapi_input(ppp_pcb *pcb, u_char* data, int len); -#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ #if LWIP_NETIF_STATUS_CALLBACK void pppapi_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback); #endif /* LWIP_NETIF_STATUS_CALLBACK */ From 44b527415f48400c679bf4a9a9e14563a5c4f601 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 22 Apr 2013 23:58:51 +0200 Subject: [PATCH 304/320] PPP, slight API change, great code factorisation Created new ppp_over_X_create() functions which only prepare the PPP session without starting it Removed ppp_reopen() and all of its sub ppp_over_X_reopen() Removed PPPoL2TP reconnect() function, merged to connect() Added ppp_open() able to start or restart any session --- src/api/pppapi.c | 94 +++++++++++++-------------- src/include/lwip/pppapi.h | 16 ++--- src/include/netif/ppp/ppp.h | 16 ++--- src/include/netif/ppp/pppol2tp.h | 10 ++- src/netif/ppp/ppp.c | 108 +++++++------------------------ src/netif/ppp/pppol2tp.c | 41 +++--------- 6 files changed, 98 insertions(+), 187 deletions(-) diff --git a/src/api/pppapi.c b/src/api/pppapi.c index 274b5ed5..e4e198a9 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -104,25 +104,25 @@ void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { #if PPPOS_SUPPORT /** - * Call ppp_over_serial_open() inside the tcpip_thread context. + * Call ppp_over_serial_create() inside the tcpip_thread context. */ -static void pppapi_do_ppp_over_serial_open(struct pppapi_msg_msg *msg) { - msg->err = ppp_over_serial_open(msg->ppp, msg->msg.serialopen.fd, - msg->msg.serialopen.link_status_cb, msg->msg.serialopen.link_status_ctx); +static void pppapi_do_ppp_over_serial_create(struct pppapi_msg_msg *msg) { + msg->err = ppp_over_serial_create(msg->ppp, msg->msg.serialcreate.fd, + msg->msg.serialcreate.link_status_cb, msg->msg.serialcreate.link_status_ctx); TCPIP_PPPAPI_ACK(msg); } /** - * Call ppp_over_serial_open() in a thread-safe way by running that function inside the + * Call ppp_over_serial_create() in a thread-safe way by running that function inside the * tcpip_thread context. */ -int pppapi_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { +int pppapi_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { struct pppapi_msg msg; - msg.function = pppapi_do_ppp_over_serial_open; + msg.function = pppapi_do_ppp_over_serial_create; msg.msg.ppp = pcb; - msg.msg.msg.serialopen.fd = fd; - msg.msg.msg.serialopen.link_status_cb = link_status_cb; - msg.msg.msg.serialopen.link_status_ctx = link_status_ctx; + msg.msg.msg.serialcreate.fd = fd; + msg.msg.msg.serialcreate.link_status_cb = link_status_cb; + msg.msg.msg.serialcreate.link_status_ctx = link_status_ctx; TCPIP_PPPAPI(&msg); return msg.msg.err; } @@ -131,31 +131,31 @@ int pppapi_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn lin #if PPPOE_SUPPORT /** - * Call ppp_over_ethernet_open() inside the tcpip_thread context. + * Call ppp_over_ethernet_create() inside the tcpip_thread context. */ -static void pppapi_do_ppp_over_ethernet_open(struct pppapi_msg_msg *msg) { +static void pppapi_do_ppp_over_ethernet_create(struct pppapi_msg_msg *msg) { - msg->err = ppp_over_ethernet_open(msg->ppp, msg->msg.ethernetopen.ethif, - msg->msg.ethernetopen.service_name, msg->msg.ethernetopen.concentrator_name, - msg->msg.ethernetopen.link_status_cb, msg->msg.ethernetopen.link_status_ctx); + msg->err = ppp_over_ethernet_create(msg->ppp, msg->msg.ethernetcreate.ethif, + msg->msg.ethernetcreate.service_name, msg->msg.ethernetcreate.concentrator_name, + msg->msg.ethernetcreate.link_status_cb, msg->msg.ethernetcreate.link_status_ctx); TCPIP_PPPAPI_ACK(msg); } /** - * Call ppp_over_ethernet_open() in a thread-safe way by running that function inside the + * Call ppp_over_ethernet_create() in a thread-safe way by running that function inside the * tcpip_thread context. */ -int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, +int pppapi_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { struct pppapi_msg msg; - msg.function = pppapi_do_ppp_over_ethernet_open; + msg.function = pppapi_do_ppp_over_ethernet_create; msg.msg.ppp = pcb; - msg.msg.msg.ethernetopen.ethif = ethif; - msg.msg.msg.ethernetopen.service_name = service_name; - msg.msg.msg.ethernetopen.concentrator_name = concentrator_name; - msg.msg.msg.ethernetopen.link_status_cb = link_status_cb; - msg.msg.msg.ethernetopen.link_status_ctx = link_status_ctx; + msg.msg.msg.ethernetcreate.ethif = ethif; + msg.msg.msg.ethernetcreate.service_name = service_name; + msg.msg.msg.ethernetcreate.concentrator_name = concentrator_name; + msg.msg.msg.ethernetcreate.link_status_cb = link_status_cb; + msg.msg.msg.ethernetcreate.link_status_ctx = link_status_ctx; TCPIP_PPPAPI(&msg); return msg.msg.err; } @@ -164,41 +164,41 @@ int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *ser #if PPPOL2TP_SUPPORT /** - * Call ppp_over_l2tp_open() inside the tcpip_thread context. + * Call ppp_over_l2tp_create() inside the tcpip_thread context. */ -static void pppapi_do_ppp_over_l2tp_open(struct pppapi_msg_msg *msg) { +static void pppapi_do_ppp_over_l2tp_create(struct pppapi_msg_msg *msg) { - msg->err = ppp_over_l2tp_open(msg->ppp, - msg->msg.l2tpopen.netif, msg->msg.l2tpopen.ipaddr, msg->msg.l2tpopen.port, + msg->err = ppp_over_l2tp_create(msg->ppp, + msg->msg.l2tpcreate.netif, msg->msg.l2tpcreate.ipaddr, msg->msg.l2tpcreate.port, #if PPPOL2TP_AUTH_SUPPORT - msg->msg.l2tpopen.secret, - msg->msg.l2tpopen.secret_len, + msg->msg.l2tpcreate.secret, + msg->msg.l2tpcreate.secret_len, #else /* PPPOL2TP_AUTH_SUPPORT */ NULL, #endif /* PPPOL2TP_AUTH_SUPPORT */ - msg->msg.l2tpopen.link_status_cb, msg->msg.l2tpopen.link_status_ctx); + msg->msg.l2tpcreate.link_status_cb, msg->msg.l2tpcreate.link_status_ctx); TCPIP_PPPAPI_ACK(msg); } /** - * Call ppp_over_l2tp_open() in a thread-safe way by running that function inside the + * Call ppp_over_l2tp_create() in a thread-safe way by running that function inside the * tcpip_thread context. */ -int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, +int pppapi_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { struct pppapi_msg msg; - msg.function = pppapi_do_ppp_over_l2tp_open; + msg.function = pppapi_do_ppp_over_l2tp_create; msg.msg.ppp = pcb; - msg.msg.msg.l2tpopen.netif = netif; - msg.msg.msg.l2tpopen.ipaddr = ipaddr; - msg.msg.msg.l2tpopen.port = port; + msg.msg.msg.l2tpcreate.netif = netif; + msg.msg.msg.l2tpcreate.ipaddr = ipaddr; + msg.msg.msg.l2tpcreate.port = port; #if PPPOL2TP_AUTH_SUPPORT - msg.msg.msg.l2tpopen.secret = secret; - msg.msg.msg.l2tpopen.secret_len = secret_len; + msg.msg.msg.l2tpcreate.secret = secret; + msg.msg.msg.l2tpcreate.secret_len = secret_len; #endif /* PPPOL2TP_AUTH_SUPPORT */ - msg.msg.msg.l2tpopen.link_status_cb = link_status_cb; - msg.msg.msg.l2tpopen.link_status_ctx = link_status_ctx; + msg.msg.msg.l2tpcreate.link_status_cb = link_status_cb; + msg.msg.msg.l2tpcreate.link_status_ctx = link_status_ctx; TCPIP_PPPAPI(&msg); return msg.msg.err; } @@ -206,22 +206,22 @@ int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, /** - * Call ppp_reopen() inside the tcpip_thread context. + * Call ppp_open() inside the tcpip_thread context. */ -static void pppapi_do_ppp_reopen(struct pppapi_msg_msg *msg) { - msg->err = ppp_reopen(msg->ppp, msg->msg.reopen.holdoff); +static void pppapi_do_ppp_open(struct pppapi_msg_msg *msg) { + msg->err = ppp_open(msg->ppp, msg->msg.open.holdoff); TCPIP_PPPAPI_ACK(msg); } /** - * Call ppp_reopen() in a thread-safe way by running that function inside the + * Call ppp_open() in a thread-safe way by running that function inside the * tcpip_thread context. */ -int pppapi_reopen(ppp_pcb *pcb, u16_t holdoff) { +int pppapi_open(ppp_pcb *pcb, u16_t holdoff) { struct pppapi_msg msg; - msg.function = pppapi_do_ppp_reopen; + msg.function = pppapi_do_ppp_open; msg.msg.ppp = pcb; - msg.msg.msg.reopen.holdoff = holdoff; + msg.msg.msg.open.holdoff = holdoff; TCPIP_PPPAPI(&msg); return msg.msg.err; } diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index 90518dc3..27660cad 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -56,7 +56,7 @@ struct pppapi_msg_msg { sio_fd_t fd; ppp_link_status_cb_fn link_status_cb; void *link_status_ctx; - } serialopen; + } serialcreate; #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT struct { @@ -65,7 +65,7 @@ struct pppapi_msg_msg { const char *concentrator_name; ppp_link_status_cb_fn link_status_cb; void *link_status_ctx; - } ethernetopen; + } ethernetcreate; #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT struct { @@ -78,11 +78,11 @@ struct pppapi_msg_msg { #endif /* PPPOL2TP_AUTH_SUPPORT */ ppp_link_status_cb_fn link_status_cb; void *link_status_ctx; - } l2tpopen; + } l2tpcreate; #endif /* PPPOL2TP_SUPPORT */ struct { u16_t holdoff; - } reopen; + } open; struct { int cmd; void *arg; @@ -110,19 +110,19 @@ ppp_pcb *pppapi_new(void); void pppapi_set_default(ppp_pcb *pcb); void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd); #if PPPOS_SUPPORT -int pppapi_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +int pppapi_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT -int pppapi_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, +int pppapi_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT -int pppapi_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, +int pppapi_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ -int pppapi_reopen(ppp_pcb *pcb, u16_t holdoff); +int pppapi_open(ppp_pcb *pcb, u16_t holdoff); int pppapi_close(ppp_pcb *pcb); void pppapi_sighup(ppp_pcb *pcb); int pppapi_delete(ppp_pcb *pcb); diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 7010d2e2..fc4d2c91 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -488,44 +488,44 @@ typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx); #if PPPOS_SUPPORT /* - * Start a new PPP connection using the given serial I/O device. + * Create a new PPP connection using the given serial I/O device. * * If this port connects to a modem, the modem connection must be * established before calling this. * * Return 0 on success, an error code on failure. */ -int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT /* - * Start a new PPP Over Ethernet (PPPoE) connection. + * Create a new PPP Over Ethernet (PPPoE) connection. * * Return 0 on success, an error code on failure. */ -int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, +int ppp_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT /* - * Open a new PPP Over L2TP (PPPoL2TP) connection. + * Create a new PPP Over L2TP (PPPoL2TP) connection. */ -int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, +int ppp_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); #endif /* PPPOL2TP_SUPPORT */ /* - * Open a previously opened PPP connection. + * Open a PPP connection. * * This can only be called if PPP is in the dead phase. * * Holdoff is the time to wait (in seconds) before initiating * the connection. */ -int ppp_reopen(ppp_pcb *pcb, u16_t holdoff); +int ppp_open(ppp_pcb *pcb, u16_t holdoff); /* * Initiate the end of a PPP connection. diff --git a/src/include/netif/ppp/pppol2tp.h b/src/include/netif/ppp/pppol2tp.h index c7beaaae..5b869ae9 100644 --- a/src/include/netif/ppp/pppol2tp.h +++ b/src/include/netif/ppp/pppol2tp.h @@ -197,21 +197,19 @@ struct pppol2tp_pcb_s { /* Create a new L2TP session. */ -err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int status), - pppol2tp_pcb **l2tpptr, u8_t *secret, u8_t secret_len); +err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int status), pppol2tp_pcb **l2tpptr, + struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len); /* Destroy a L2TP control block */ err_t pppol2tp_destroy(pppol2tp_pcb *l2tp); /* Be a LAC, connect to a LNS. */ -err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipaddr, u16_t port); +err_t pppol2tp_connect(pppol2tp_pcb *l2tp); /* Disconnect */ void pppol2tp_disconnect(pppol2tp_pcb *l2tp); -/* Reconnect to a LNS, using previously set L2TP server IP address and port. */ -void pppol2tp_reconnect(pppol2tp_pcb *l2tp); - /* Data packet from PPP to L2TP */ err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 75216f81..c00a129a 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -184,7 +184,7 @@ const struct protent* const protocols[] = { /* Prototypes for procedures local to this file. */ static void ppp_clear(ppp_pcb *pcb); -static void ppp_do_reopen(void *arg); +static void ppp_do_open(void *arg); static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ static void ppp_stop(ppp_pcb *pcb); static void ppp_hup(ppp_pcb *pcb); @@ -198,7 +198,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot #if PPPOS_SUPPORT #define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & ppp_accm_mask[c & 0x07]) -static void ppp_over_serial_reopen(ppp_pcb *pcb); +static void ppp_over_serial_open(ppp_pcb *pcb); static err_t ppp_netif_output_over_serial(ppp_pcb *pcb, struct pbuf *pb, u_short protocol); static int ppp_write_over_serial(ppp_pcb *pcb, struct pbuf *p); #if PPP_INPROC_OWNTHREAD @@ -214,13 +214,13 @@ static void ppp_free_current_input_packet(ppp_pcb_rx *pcrx); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT -static void ppp_over_ethernet_reopen(ppp_pcb *pcb); +static void ppp_over_ethernet_open(ppp_pcb *pcb); static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol); static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT -static void ppp_over_l2tp_reopen(ppp_pcb *pcb); +static void ppp_over_l2tp_open(ppp_pcb *pcb); static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short protocol); static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p); #endif /* PPPOL2TP_SUPPORT */ @@ -352,7 +352,7 @@ void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { } #if PPPOS_SUPPORT -int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { +int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ @@ -360,39 +360,9 @@ int ppp_over_serial_open(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_s return PPPERR_PARAM; } - /* input pbuf left over from last session? */ - ppp_free_current_input_packet(&pcb->rx); - - ppp_clear(pcb); - pcb->fd = fd; - - pcb->rx.pcb = pcb; - pcb->rx.fd = fd; - -#if VJ_SUPPORT - vj_compress_init(&pcb->vj_comp); -#endif /* VJ_SUPPORT */ - - /* - * Default the in and out accm so that escape and flag characters - * are always escaped. - */ - pcb->rx.in_accm[15] = 0x60; /* no need to protect since RX is not running */ - pcb->out_accm[15] = 0x60; - pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; - - /* - * Start the connection and handle incoming events (packet or timeout). - */ - PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: connecting\n", pcb->num)); - ppp_start(pcb); -#if PPP_INPROC_OWNTHREAD - sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); -#endif /* PPP_INPROC_OWNTHREAD */ - return PPPERR_NONE; } @@ -413,12 +383,9 @@ void ppp_set_xaccm(ppp_pcb *pcb, ext_accm *accm) { #if PPPOE_SUPPORT static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state); -int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, +int ppp_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - LWIP_UNUSED_ARG(service_name); LWIP_UNUSED_ARG(concentrator_name); @@ -428,26 +395,13 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic return PPPERR_PARAM; } - ppp_clear(pcb); - pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; - wo->mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - wo->neg_asyncmap = 0; - wo->neg_pcompression = 0; - wo->neg_accompression = 0; - - ao->mru = ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - ao->neg_asyncmap = 0; - ao->neg_pcompression = 0; - ao->neg_accompression = 0; - if (pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { return PPPERR_OPEN; } - pppoe_connect(pcb->pppoe_sc); return PPPERR_NONE; } #endif /* PPPOE_SUPPORT */ @@ -455,67 +409,49 @@ int ppp_over_ethernet_open(ppp_pcb *pcb, struct netif *ethif, const char *servic #if PPPOL2TP_SUPPORT static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state); -int ppp_over_l2tp_open(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, +int ppp_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ if (link_status_cb == NULL) { return PPPERR_PARAM; } - ppp_clear(pcb); - pcb->link_status_cb = link_status_cb; pcb->link_status_ctx = link_status_ctx; - wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ - wo->neg_asyncmap = 0; - wo->neg_pcompression = 0; - wo->neg_accompression = 0; - - ao->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ - ao->neg_asyncmap = 0; - ao->neg_pcompression = 0; - ao->neg_accompression = 0; - - if (pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, secret, secret_len) != ERR_OK) { + if (pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, netif, ipaddr, port, secret, secret_len) != ERR_OK) { return PPPERR_OPEN; } - if (pppol2tp_connect(pcb->l2tp_pcb, netif, ipaddr, port) != ERR_OK) { - return PPPERR_OPEN; - } return PPPERR_NONE; } #endif /* PPPOL2TP_SUPPORT */ /* - * Open a previously opened PPP connection. + * Open a PPP connection. * * This can only be called if PPP is in the dead phase. * * Holdoff is the time to wait (in seconds) before initiating * the connection. */ -int ppp_reopen(ppp_pcb *pcb, u16_t holdoff) { +int ppp_open(ppp_pcb *pcb, u16_t holdoff) { if (pcb->phase != PHASE_DEAD) { return PPPERR_PARAM; } - PPPDEBUG(LOG_DEBUG, ("ppp_reopen() called, holdoff=%d\n", holdoff)); + PPPDEBUG(LOG_DEBUG, ("ppp_open() called, holdoff=%d\n", holdoff)); if (holdoff == 0) { - ppp_do_reopen(pcb); + ppp_do_open(pcb); return PPPERR_NONE; } new_phase(pcb, PHASE_HOLDOFF); - sys_timeout((u32_t)(holdoff*1000), ppp_do_reopen, pcb); + sys_timeout((u32_t)(holdoff*1000), ppp_do_open, pcb); return PPPERR_NONE; } @@ -539,7 +475,7 @@ ppp_close(ppp_pcb *pcb) /* holdoff phase, cancel the reconnection and call the status callback */ if (pcb->phase == PHASE_HOLDOFF) { - sys_untimeout(ppp_do_reopen, pcb); + sys_untimeout(ppp_do_open, pcb); pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); return PPPERR_NONE; } @@ -653,27 +589,27 @@ static void ppp_clear(ppp_pcb *pcb) { new_phase(pcb, PHASE_INITIALIZE); } -static void ppp_do_reopen(void *arg) { +static void ppp_do_open(void *arg) { ppp_pcb *pcb = (ppp_pcb*)arg; LWIP_ASSERT("pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF", pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF); #if PPPOE_SUPPORT if (pcb->pppoe_sc) { - ppp_over_ethernet_reopen(pcb); + ppp_over_ethernet_open(pcb); return; } #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT if (pcb->l2tp_pcb) { - ppp_over_l2tp_reopen(pcb); + ppp_over_l2tp_open(pcb); return; } #endif /* PPPOL2TP_SUPPORT */ #if PPPOS_SUPPORT - ppp_over_serial_reopen(pcb); + ppp_over_serial_open(pcb); #endif /* PPPOS_SUPPORT */ } @@ -957,7 +893,7 @@ static err_t ppp_netif_init_cb(struct netif *netif) { /**********************************/ #if PPPOS_SUPPORT -static void ppp_over_serial_reopen(ppp_pcb *pcb) { +static void ppp_over_serial_open(ppp_pcb *pcb) { /* input pbuf left over from last session? */ ppp_free_current_input_packet(&pcb->rx); @@ -1920,7 +1856,7 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); } -static void ppp_over_ethernet_reopen(ppp_pcb *pcb) { +static void ppp_over_ethernet_open(ppp_pcb *pcb) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; @@ -1970,7 +1906,7 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); } -static void ppp_over_l2tp_reopen(ppp_pcb *pcb) { +static void ppp_over_l2tp_open(ppp_pcb *pcb) { lcp_options *wo = &pcb->lcp_wantoptions; lcp_options *ao = &pcb->lcp_allowoptions; @@ -1987,7 +1923,7 @@ static void ppp_over_l2tp_reopen(ppp_pcb *pcb) { ao->neg_pcompression = 0; ao->neg_accompression = 0; - pppol2tp_reconnect(pcb->l2tp_pcb); + pppol2tp_connect(pcb->l2tp_pcb); } #endif /* PPPOL2TP_SUPPORT */ diff --git a/src/netif/ppp/pppol2tp.c b/src/netif/ppp/pppol2tp.c index fe5badf1..dad340aa 100644 --- a/src/netif/ppp/pppol2tp.c +++ b/src/netif/ppp/pppol2tp.c @@ -87,8 +87,9 @@ static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns); /* Create a new L2TP session. */ -err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int status), - pppol2tp_pcb **l2tpptr, u8_t *secret, u8_t secret_len) { +err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int status), pppol2tp_pcb **l2tpptr, + struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len) { pppol2tp_pcb *l2tp; struct udp_pcb *udp; @@ -111,7 +112,10 @@ err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int sta l2tp->ppp = ppp; l2tp->udp = udp; l2tp->link_status_cb = link_status_cb; -#if PPPOL2TP_AUTH_SUPPORT + l2tp->netif = netif; + ip_addr_set(&l2tp->remote_ip, ipaddr); + l2tp->remote_port = port; + #if PPPOL2TP_AUTH_SUPPORT l2tp->secret = secret; l2tp->secret_len = secret_len; #endif /* PPPOL2TP_AUTH_SUPPORT */ @@ -132,16 +136,14 @@ err_t pppol2tp_destroy(pppol2tp_pcb *l2tp) { } /* Be a LAC, connect to a LNS. */ -err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipaddr, u16_t port) { +err_t pppol2tp_connect(pppol2tp_pcb *l2tp) { err_t err; if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { return ERR_VAL; } - l2tp->netif = netif; - ip_addr_set(&l2tp->remote_ip, ipaddr); - l2tp->remote_port = l2tp->tunnel_port = port; + pppol2tp_clear(l2tp); /* Listen to a random source port, we need to do that instead of using udp_connect() * because the L2TP LNS might answer with its own random source port (!= 1701) @@ -168,31 +170,6 @@ err_t pppol2tp_connect(pppol2tp_pcb *l2tp, struct netif *netif, ip_addr_t *ipadd return err; } -/* Reconnect to a LNS, using previously set L2TP server IP address and port. */ -void pppol2tp_reconnect(pppol2tp_pcb *l2tp) { - err_t err; - - if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { - return; - } - - pppol2tp_clear(l2tp); - - udp_bind(l2tp->udp, IP_ADDR_ANY, 0); - - do { - l2tp->remote_tunnel_id = magic(); - } while(l2tp->remote_tunnel_id == 0); - /* save state, in case we fail to send SCCRQ */ - l2tp->sccrq_retried = 0; - l2tp->phase = PPPOL2TP_STATE_SCCRQ_SENT; - if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); - } - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - return; -} - /* Disconnect */ void pppol2tp_disconnect(pppol2tp_pcb *l2tp) { From a1555e061550edc523475d20bb11d72b53523080 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 23 Apr 2013 00:19:07 +0200 Subject: [PATCH 305/320] PPP, added ppp_free() Free the control block, clean everything except the PPP PCB itself and the netif, it allows you to change the underlying PPP protocol (eg. from PPPoE to PPPoS to switch from DSL to GPRS) without losing your PPP and netif handlers. --- src/include/netif/ppp/ppp.h | 15 +++++++++ src/netif/ppp/ppp.c | 63 +++++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index fc4d2c91..a2389cd8 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -539,6 +539,21 @@ int ppp_close(ppp_pcb *pcb); */ void ppp_sighup(ppp_pcb *pcb); +/* + * Free the control block, clean everything except the PPP PCB itself + * and the netif, it allows you to change the underlying PPP protocol + * (eg. from PPPoE to PPPoS to switch from DSL to GPRS) without losing + * your PPP and netif handlers. + * + * This can only be called if PPP is in the dead phase. + * + * You must use ppp_close() before if you wish to terminate + * an established PPP session. + * + * Return 0 on success, an error code on failure. + */ +int ppp_free(ppp_pcb *pcb); + /* * Release the control block. * diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index c00a129a..cc0fc121 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -519,6 +519,48 @@ ppp_sighup(ppp_pcb *pcb) ppp_hup(pcb); } +/* + * Free the control block, clean everything except the PPP PCB itself + * and the netif, it allows you to change the underlying PPP protocol + * (eg. from PPPoE to PPPoS to switch from DSL to GPRS) without losing + * your PPP and netif handlers. + * + * This can only be called if PPP is in the dead phase. + * + * You must use ppp_close() before if you wish to terminate + * an established PPP session. + * + * Return 0 on success, an error code on failure. + */ +int ppp_free(ppp_pcb *pcb) { + if (pcb->phase != PHASE_DEAD) { + return PPPERR_PARAM; + } + + PPPDEBUG(LOG_DEBUG, ("ppp_free: unit %d\n", pcb->num)); + +#if PPPOE_SUPPORT + if (pcb->pppoe_sc) { + pppoe_destroy(&pcb->netif); + pcb->pppoe_sc = NULL; + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + pppol2tp_destroy(pcb->l2tp_pcb); + pcb->l2tp_pcb = NULL; + } +#endif /* PPPOL2TP_SUPPORT */ + +#if PPPOS_SUPPORT + /* input pbuf left ? */ + ppp_free_current_input_packet(&pcb->rx); +#endif /* PPPOS_SUPPORT */ + + return 0; +} + /* * Release the control block. * @@ -530,29 +572,18 @@ ppp_sighup(ppp_pcb *pcb) * Return 0 on success, an error code on failure. */ int ppp_delete(ppp_pcb *pcb) { + int err; + if (pcb->phase != PHASE_DEAD) { return PPPERR_PARAM; } PPPDEBUG(LOG_DEBUG, ("ppp_delete: unit %d\n", pcb->num)); + netif_remove(&pcb->netif); - -#if PPPOE_SUPPORT - if (pcb->pppoe_sc) { - pppoe_destroy(&pcb->netif); + if( (err = ppp_free(pcb)) != PPPERR_NONE) { + return err; } -#endif /* PPPOE_SUPPORT */ - -#if PPPOL2TP_SUPPORT - if (pcb->l2tp_pcb) { - pppol2tp_destroy(pcb->l2tp_pcb); - } -#endif /* PPPOL2TP_SUPPORT */ - -#if PPPOS_SUPPORT - /* input pbuf left ? */ - ppp_free_current_input_packet(&pcb->rx); -#endif /* PPPOS_SUPPORT */ memp_free(MEMP_PPP_PCB, pcb); return 0; From f47a93b0c169be47509d29296e1572734517f361 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 26 Apr 2013 14:02:30 +0200 Subject: [PATCH 306/320] PPP, cleared compilation warning about unused variable 'pcb' in ppp_drop() if neither VJ nor SNMP support are enabled --- src/netif/ppp/ppp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index cc0fc121..859558c2 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1547,7 +1547,9 @@ ppp_free_current_input_packet(ppp_pcb_rx *pcrx) static void ppp_drop(ppp_pcb_rx *pcrx) { +#if LWIP_SNMP || VJ_SUPPORT ppp_pcb *pcb = (ppp_pcb*)pcrx->pcb; +#endif /* LWIP_SNMP || VJ_SUPPORT */ if (pcrx->in_head != NULL) { #if 0 PPPDEBUG(LOG_INFO, ("ppp_drop: %d:%.*H\n", pcrx->in_head->len, min(60, pcrx->in_head->len * 2), pcrx->in_head->payload)); From 25f9f55878f008113bc1f4a0068d4827ed4595b9 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 26 Apr 2013 20:30:01 +0200 Subject: [PATCH 307/320] PPP, removed PPP_INPROC_OWNTHREAD feature, which almost only make things harder I consider to remove the PPP_INPROC_OWNTHREAD crap in ppp-new, as said in bugs #37278 and #37353. 1. It requires the ppp_input_thread() function to be modified to match user system, like some did by adding the vTaskDelete(NULL); FreeRTOS call at the end of the function, for example. This is a tiny-tiny fonction that should be, in my opinion, on the user port, like the Ethernet input thread we see in many Ethernet port. 2. It is actually not that thread safe. 2.1. pcb->phase IS modified by the lwIP core thread so it should at least be set to volatile, otherwise the pcb->phase copy may live indefinitely in CPU register. It works because of the sio_read() function call which without doubt flush pcb->phase copy from CPU register. I dont want to set ppp_pcb struct to volatile for obvious performance reasons. 2.2. This function assume PCB still exists whatever is happening, which is not the case after you called ppp_delete() function outside of this thread. If sio_read() is blocking waiting data and pcb destroyed, it is going to read a deallocated pcb which luckily should still have pcb->phase set to 0 (=PHASE_DEAD) due to preallocated "control block" structures of lwIP. Even with sio_read_abort(), there might be timings issue due to a lack of a synchronization mechanism. 3. I dislike the sys_msleep(1), it means that systems should have at least a 11 chr buffer at 115200/10 byte/s, and bigger with higher serial speed, for example with 3G/HSDPA modems accessed through SPI, at 20 Mbits/s this is a ~2000 bytes buffer required to keep incoming data during this sleep, I don't see why we require systems to do so, sio_read() should obviously be a blocking call. I cannot easily remove this sleep because some systems might have wrongfully used this call as a CPU idle feature with a non blocking sio_read() call. --- src/include/lwip/opt.h | 25 -------- src/include/netif/ppp/ppp.h | 49 ++-------------- src/netif/ppp/ppp.c | 111 ++++++------------------------------ 3 files changed, 23 insertions(+), 162 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index fac1bf10..05bc6768 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1309,31 +1309,6 @@ #define SLIPIF_THREAD_PRIO 1 #endif -/** - * PPP_THREAD_NAME: The name assigned to the pppInputThread. - */ -#ifndef PPP_THREAD_NAME -#define PPP_THREAD_NAME "pppInputThread" -#endif - -/** - * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef PPP_THREAD_STACKSIZE -#define PPP_THREAD_STACKSIZE 0 -#endif - -/** - * PPP_THREAD_PRIO: The priority assigned to the pppInputThread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef PPP_THREAD_PRIO -#define PPP_THREAD_PRIO 1 -#endif - /** * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. */ diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index a2389cd8..b005cfda 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -50,34 +50,14 @@ #include "vj.h" -/** PPP_INPROC_MULTITHREADED==1 call ppp_input using tcpip_callback(). - * Set this to 0 if pppos_input_proc is called inside tcpip_thread or with NO_SYS==1. +/** PPP_INPROC_MULTITHREADED==1 call pppos_input using tcpip_callback(). + * Set this to 0 if pppos_input is called inside tcpip_thread or with NO_SYS==1. * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). */ #ifndef PPP_INPROC_MULTITHREADED #define PPP_INPROC_MULTITHREADED (NO_SYS==0) #endif -/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session. - * Default is 1 if PPP_INPROC_MULTITHREADED is enabled. - * If set to 0, call pppos_input() for received raw characters, character - * reception is up to the port. - */ -#ifndef PPP_INPROC_OWNTHREAD -#define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED -#endif - -#if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED - #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1" -#endif - -#if PPPOS_SUPPORT -/** RX buffer size: this may be configured smaller! */ -#ifndef PPPOS_RX_BUFSIZE -#define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN) -#endif -#endif /* PPPOS_SUPPORT */ - /************************* *** PUBLIC DEFINITIONS *** @@ -296,10 +276,6 @@ typedef struct ppp_pcb_rx_s { ppp_pcb *pcb; /** the rx file descriptor */ sio_fd_t fd; - /** receive buffer - encoded data is stored here */ -#if PPP_INPROC_OWNTHREAD - u_char rxbuf[PPPOS_RX_BUFSIZE]; -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ /* The input packet. */ struct pbuf *in_head, *in_tail; @@ -572,14 +548,12 @@ int ppp_delete(ppp_pcb *pcb); */ int ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg); -#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD +#if PPPOS_SUPPORT /* * PPP over Serial: this is the input function to be called for received data. - * If PPP_INPROC_OWNTHREAD==1, a separate input thread using the blocking - * sio_read() is used, so this is deactivated. */ void pppos_input(ppp_pcb *pcb, u_char* data, int len); -#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ +#endif /* PPPOS_SUPPORT */ /* Get the PPP netif interface */ #define ppp_netif(ppp) (&(ppp)->netif) @@ -596,21 +570,6 @@ void ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_ void ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback); #endif /* LWIP_NETIF_LINK_CALLBACK */ - -/* Source code compatibility */ -#if 0 -#define pppAuthType ppp_auth_type -#define pppInit() ppp_init() -#define pppSetAuth(authtype,user,passwd) ppp_set_auth(authtype,user,passwd) -#define pppOpen(fd,cb,ls) ppp_over_serial_open(fd,cb,ls) -#define pppOverSerialOpen(fd,cb,ls) ppp_over_serial_open(fd,cb,ls) -#define pppOverEthernetOpen(ethif,sn,cn,lscb,lsctx) ppp_over_ethernet_open(ethif,sn,cn,lscb,lsctx) -#define pppClose(unit) ppp_close(unit) -#define pppSigHUP(unit) ppp_sigup(unit) -#define pppIOCtl(pd,cmd,arg) ppp_ioctl(pd,cmd,arg) -#define pppMTU(unit) ppp_mtu(unit) -#endif - #endif /* PPP_H */ #endif /* PPP_SUPPORT */ diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 859558c2..09efb140 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -201,12 +201,7 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short prot static void ppp_over_serial_open(ppp_pcb *pcb); static err_t ppp_netif_output_over_serial(ppp_pcb *pcb, struct pbuf *pb, u_short protocol); static int ppp_write_over_serial(ppp_pcb *pcb, struct pbuf *p); -#if PPP_INPROC_OWNTHREAD -static void ppp_input_thread(void *arg); -static void ppp_receive_wakeup(ppp_pcb *pcb); -#endif /* PPP_INPROC_OWNTHREAD */ static void ppp_drop(ppp_pcb_rx *pcrx); -static void pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l); #if PPP_INPROC_MULTITHREADED static void pppos_input_callback(void *arg); #endif /* PPP_INPROC_MULTITHREADED */ @@ -502,9 +497,6 @@ ppp_close(ppp_pcb *pcb) PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); /* This will leave us at PHASE_DEAD. */ ppp_stop(pcb); -#if PPP_INPROC_OWNTHREAD - ppp_receive_wakeup(pcb); -#endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ } @@ -888,16 +880,6 @@ static u_char ppp_accm_mask[] = { 0x40, 0x80 }; - -#if PPP_INPROC_OWNTHREAD -/** Wake up the task blocked in reading from serial line (if any) */ -static void -ppp_receive_wakeup(ppp_pcb *pcb) -{ - PPPDEBUG(LOG_DEBUG, ("ppp_receive_wakeup: unit %d\n", pcb->num)); - sio_read_abort(pcb->fd); -} -#endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ /* @@ -950,33 +932,8 @@ static void ppp_over_serial_open(ppp_pcb *pcb) { */ PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: connecting\n", pcb->num)); ppp_start(pcb); -#if PPP_INPROC_OWNTHREAD - sys_thread_new(PPP_THREAD_NAME, ppp_input_thread, (void*)&pcb->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); -#endif /* PPP_INPROC_OWNTHREAD */ } -#if PPP_INPROC_OWNTHREAD -/* The main PPP process function. This implements the state machine according - * to section 4 of RFC 1661: The Point-To-Point Protocol. */ -static void -ppp_input_thread(void *arg) -{ - int count; - ppp_pcb_rx *pcrx = arg; - ppp_pcb *pcb = pcrx->pcb; - - while (pcb->phase != PHASE_DEAD) { - count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); - if(count > 0) { - pppos_input_proc(pcrx, pcrx->rxbuf, count); - } else { - /* nothing received, give other tasks a chance to run */ - sys_msleep(1); - } - } -} -#endif /* PPP_INPROC_OWNTHREAD */ - static void pppos_put(ppp_pcb *pcb, struct pbuf *nb) { @@ -1565,40 +1522,29 @@ ppp_drop(ppp_pcb_rx *pcrx) snmp_inc_ifindiscards(&pcb->netif); } -#if !PPP_INPROC_OWNTHREAD -/** Pass received raw characters to PPPoS to be decoded. This function is - * thread-safe and can be called from a dedicated RX-thread or from a main-loop. - * - * @param pd PPP descriptor index, returned by pppOpen() - * @param data received data - * @param len length of received data - */ -void -pppos_input(ppp_pcb *pcb, u_char* data, int len) -{ - pppos_input_proc(&pcb->rx, data, len); -} -#endif - #if PPP_INPROC_MULTITHREADED struct ppp_tcpip_callback_header { ppp_pcb *pcb; }; #endif /* PPP_INPROC_MULTITHREADED */ -/** - * Process a received octet string. +/** Pass received raw characters to PPPoS to be decoded. This function is + * thread-safe and can be called from a dedicated RX-thread or from a main-loop. + * + * @param pcb PPP descriptor index, returned by ppp_new() + * @param data received data + * @param len length of received data */ -static void -pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) +void +pppos_input(ppp_pcb *pcb, u_char *s, int l) { - ppp_pcb *pcb = (ppp_pcb*)pcrx->pcb; + ppp_pcb_rx *pcrx = &pcb->rx; struct pbuf *next_pbuf; u_char cur_char; u_char escaped; SYS_ARCH_DECL_PROTECT(lev); - PPPDEBUG(LOG_DEBUG, ("pppos_input_proc[%d]: got %d bytes\n", pcb->num, l)); + PPPDEBUG(LOG_DEBUG, ("pppos_input[%d]: got %d bytes\n", pcb->num, l)); while (l-- > 0) { cur_char = *s++; @@ -1622,14 +1568,14 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) /* If we haven't received the packet header, drop what has come in. */ } else if (pcrx->in_state < PDDATA) { PPPDEBUG(LOG_WARNING, - ("pppos_input_proc[%d]: Dropping incomplete packet %d\n", + ("pppos_input[%d]: Dropping incomplete packet %d\n", pcb->num, pcrx->in_state)); LINK_STATS_INC(link.lenerr); ppp_drop(pcrx); /* If the fcs is invalid, drop the packet. */ } else if (pcrx->in_fcs != PPP_GOODFCS) { PPPDEBUG(LOG_INFO, - ("pppos_input_proc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", + ("pppos_input[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", pcb->num, pcrx->in_fcs, pcrx->in_protocol)); /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ LINK_STATS_INC(link.chkerr); @@ -1670,7 +1616,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) cbhead->pcb = pcb; pbuf_chain(head, inp); if(tcpip_callback_with_block(pppos_input_callback, head, 0) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: tcpip_callback() failed, dropping packet\n", pcb->num)); + PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", pcb->num)); pbuf_free(head); pbuf_free(inp); LINK_STATS_INC(link.drop); @@ -1690,7 +1636,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) * been inserted by the physical layer so here we just drop them. */ } else { PPPDEBUG(LOG_WARNING, - ("pppos_input_proc[%d]: Dropping ACCM char <%d>\n", pcb->num, cur_char)); + ("pppos_input[%d]: Dropping ACCM char <%d>\n", pcb->num, cur_char)); } /* Process other characters. */ } else { @@ -1737,7 +1683,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) #if 0 else { PPPDEBUG(LOG_WARNING, - ("pppos_input_proc[%d]: Invalid control <%d>\n", pcb->num, cur_char)); + ("pppos_input[%d]: Invalid control <%d>\n", pcb->num, cur_char)); pcrx->in_state = PDSTART; } #endif @@ -1773,7 +1719,7 @@ pppos_input_proc(ppp_pcb_rx *pcrx, u_char *s, int l) /* No free buffers. Drop the input packet and let the * higher layers deal with it. Continue processing * the received pbuf chain in case a new packet starts. */ - PPPDEBUG(LOG_ERR, ("pppos_input_proc[%d]: NO FREE MBUFS!\n", pcb->num)); + PPPDEBUG(LOG_ERR, ("pppos_input[%d]: NO FREE MBUFS!\n", pcb->num)); LINK_STATS_INC(link.memerr); ppp_drop(pcrx); pcrx->in_state = PDSTART; /* Wait for flag sequence. */ @@ -1962,21 +1908,6 @@ static void ppp_over_l2tp_open(ppp_pcb *pcb) { void ppp_link_down(ppp_pcb *pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pcb->num)); - -#if PPPOE_SUPPORT - if (pcb->pppoe_sc) { - return; - } -#endif /* PPPOE_SUPPORT */ -#if PPPOL2TP_SUPPORT - if (pcb->l2tp_pcb) { - return; - } -#endif /* PPPOL2TP_SUPPORT */ - -#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD - ppp_receive_wakeup(pcb); -#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ } void ppp_link_terminated(ppp_pcb *pcb) { @@ -1995,12 +1926,8 @@ void ppp_link_terminated(ppp_pcb *pcb) { { #if PPPOS_SUPPORT /* We cannot call ppp_free_current_input_packet() here because - * rx thread might still call pppos_input_proc() + * rx thread might still call pppos_input() */ -#if PPP_INPROC_OWNTHREAD - ppp_receive_wakeup(pcb); -#endif /* PPP_INPROC_OWNTHREAD */ - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->link_status_ctx); #endif /* PPPOS_SUPPORT */ @@ -2011,7 +1938,7 @@ void ppp_link_terminated(ppp_pcb *pcb) { #if LWIP_NETIF_STATUS_CALLBACK /** Set the status callback of a PPP's netif * - * @param pd The PPP descriptor returned by pppOpen() + * @param pcb The PPP descriptor returned by ppp_new() * @param status_callback pointer to the status callback function * * @see netif_set_status_callback @@ -2026,7 +1953,7 @@ ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callb #if LWIP_NETIF_LINK_CALLBACK /** Set the link callback of a PPP's netif * - * @param pd The PPP descriptor returned by pppOpen() + * @param pcb The PPP descriptor returned by ppp_new() * @param link_callback pointer to the link callback function * * @see netif_set_link_callback From 2350d941a510a25c4872e97c43b64b7c9f230287 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 26 Apr 2013 21:51:15 +0200 Subject: [PATCH 308/320] PPP, added PPP_USE_PBUF_RAM compile time option pbuf_type PPP is using for LCP, PAP, CHAP, EAP, IPCP and IP6CP packets. Memory allocated must be single buffered for PPP to works, it requires pbuf that are not going to be chained when allocated. This requires setting PBUF_POOL_BUFSIZE to at least 512 bytes, which is quite huge for small systems. Setting PPP_USE_PBUF_RAM to 1 makes PPP use memory from heap where continuous buffers are required, allowing you to use a smaller PBUF_POOL_BUFSIZE. --- src/include/lwip/opt.h | 14 ++++++++++++++ src/include/netif/ppp/ppp_impl.h | 15 ++++++++++++++- src/netif/ppp/chap-new.c | 6 +++--- src/netif/ppp/eap.c | 16 ++++++++-------- src/netif/ppp/fsm.c | 4 ++-- src/netif/ppp/lcp.c | 2 +- src/netif/ppp/upap.c | 4 ++-- 7 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 05bc6768..e3f6887a 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1707,6 +1707,20 @@ #define LWIP_PPP_API 0 #endif +/** + * pbuf_type PPP is using for LCP, PAP, CHAP, EAP, IPCP and IP6CP packets. + * + * Memory allocated must be single buffered for PPP to works, it requires pbuf + * that are not going to be chained when allocated. This requires setting + * PBUF_POOL_BUFSIZE to at least 512 bytes, which is quite huge for small systems. + * + * Setting PPP_USE_PBUF_RAM to 1 makes PPP use memory from heap where continuous + * buffers are required, allowing you to use a smaller PBUF_POOL_BUFSIZE. + */ +#ifndef PPP_USE_PBUF_RAM +#define PPP_USE_PBUF_RAM 0 +#endif + /** * PPP_FCS_TABLE: Keep a 256*2 byte table to speed up FCS calculation */ diff --git a/src/include/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h index 19af4429..b1d5f9c4 100644 --- a/src/include/netif/ppp/ppp_impl.h +++ b/src/include/netif/ppp/ppp_impl.h @@ -58,6 +58,20 @@ typedef unsigned char u_char; #include "ppp.h" #include "pppdebug.h" +/* + * Memory used for control packets. + * + * PPP_CTRL_PBUF_MAX_SIZE is the amount of memory we allocate when we + * cannot figure out how much we are going to use before filling the buffer. + */ +#if PPP_USE_PBUF_RAM +#define PPP_CTRL_PBUF_TYPE PBUF_RAM +#define PPP_CTRL_PBUF_MAX_SIZE 512 +#else /* PPP_USE_PBUF_RAM */ +#define PPP_CTRL_PBUF_TYPE PBUF_POOL +#define PPP_CTRL_PBUF_MAX_SIZE PBUF_POOL_BUFSIZE +#endif /* PPP_USE_PBUF_RAM */ + /* * Limits. */ @@ -66,7 +80,6 @@ typedef unsigned char u_char; #define MAXNAMELEN 256 /* max length of hostname or name for auth */ #define MAXSECRETLEN 256 /* max length of password or secret */ - /* * The basic PPP frame. */ diff --git a/src/netif/ppp/chap-new.c b/src/netif/ppp/chap-new.c index 19cc8c5d..052b4095 100644 --- a/src/netif/ppp/chap-new.c +++ b/src/netif/ppp/chap-new.c @@ -231,7 +231,7 @@ static void chap_timeout(void *arg) { return; } - p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -331,7 +331,7 @@ static void chap_handle_response(ppp_pcb *pcb, int id, /* send the response */ mlen = strlen(pcb->chap_server.message); len = CHAP_HDRLEN + mlen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -430,7 +430,7 @@ static void chap_respond(ppp_pcb *pcb, int id, char rname[MAXNAMELEN+1]; char secret[MAXSECRETLEN+1]; - p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { diff --git a/src/netif/ppp/eap.c b/src/netif/ppp/eap.c index d8b7359f..4c385d6f 100644 --- a/src/netif/ppp/eap.c +++ b/src/netif/ppp/eap.c @@ -258,7 +258,7 @@ static void eap_send_failure(ppp_pcb *pcb) { struct pbuf *p; u_char *outp; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -289,7 +289,7 @@ static void eap_send_success(ppp_pcb *pcb) { struct pbuf *p; u_char *outp; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -686,7 +686,7 @@ static void eap_send_request(ppp_pcb *pcb) { return; } - p = pbuf_alloc(PBUF_RAW, (u16_t)(PBUF_POOL_BUFSIZE), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -1048,7 +1048,7 @@ static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, u_char *s int msglen; msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -1082,7 +1082,7 @@ static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, char *name, msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + namelen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -1127,7 +1127,7 @@ int lenstr; int msglen; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -1169,7 +1169,7 @@ u_char *str; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u32_t) + SHA_DIGESTSIZE; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -1200,7 +1200,7 @@ static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { int msglen; msglen = EAP_HEADERLEN + 2 * sizeof (u_char); - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { diff --git a/src/netif/ppp/fsm.c b/src/netif/ppp/fsm.c index 896eb7a2..79077444 100644 --- a/src/netif/ppp/fsm.c +++ b/src/netif/ppp/fsm.c @@ -721,7 +721,7 @@ static void fsm_sconfreq(fsm *f, int retransmit) { } else cilen = 0; - p = pbuf_alloc(PBUF_RAW, (u16_t)(cilen + HEADERLEN + PPP_HDRLEN), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(cilen + HEADERLEN + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -763,7 +763,7 @@ void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { datalen = pcb->peer_mru - HEADERLEN; outlen = datalen + HEADERLEN; - p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index e11d4371..9c69dd8f 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -1780,7 +1780,7 @@ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { * Process all his options. */ next = inp; - nakp = pbuf_alloc(PBUF_RAW, (u16_t)(PBUF_POOL_BUFSIZE), PBUF_POOL); + nakp = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE); if(NULL == nakp) return 0; if(nakp->tot_len != nakp->len) { diff --git a/src/netif/ppp/upap.c b/src/netif/ppp/upap.c index 9cf0e432..11dddd3e 100644 --- a/src/netif/ppp/upap.c +++ b/src/netif/ppp/upap.c @@ -527,7 +527,7 @@ static void upap_sauthreq(ppp_pcb *pcb) { outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + pcb->upap.us_userlen + pcb->upap.us_passwdlen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { @@ -564,7 +564,7 @@ static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, char *msg, int msgl int outlen; outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PBUF_POOL); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE); if(NULL == p) return; if(p->tot_len != p->len) { From cf3162cff14365eada20bd4d1196c3ed83160b6b Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 26 Apr 2013 21:55:30 +0200 Subject: [PATCH 309/320] PPP, moved PPP_INPROC_MULTITHREADED compile time option from ppp.h to opt.h --- src/include/lwip/opt.h | 9 +++++++++ src/include/netif/ppp/ppp.h | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index e3f6887a..4c078587 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1700,6 +1700,15 @@ #if PPP_SUPPORT +/** + * PPP_INPROC_MULTITHREADED==1 call ppp_input() using tcpip_callback(). + * Set this to 0 if pppos_input() is called inside tcpip_thread or with NO_SYS==1. + * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). + */ +#ifndef PPP_INPROC_MULTITHREADED +#define PPP_INPROC_MULTITHREADED (NO_SYS==0) +#endif + /** * LWIP_PPP_API==1: Support PPP API (in pppapi.c) */ diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index b005cfda..168d473e 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -50,14 +50,6 @@ #include "vj.h" -/** PPP_INPROC_MULTITHREADED==1 call pppos_input using tcpip_callback(). - * Set this to 0 if pppos_input is called inside tcpip_thread or with NO_SYS==1. - * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). - */ -#ifndef PPP_INPROC_MULTITHREADED -#define PPP_INPROC_MULTITHREADED (NO_SYS==0) -#endif - /************************* *** PUBLIC DEFINITIONS *** From 2ceae6014e138eaa6799b856d9ed49e6d8416f84 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 26 Apr 2013 23:24:08 +0200 Subject: [PATCH 310/320] PPP, reduced by one buffer PPPoS RX requirements in multithreaded context Removed one unecessary allocated PBUF per PPPoS RX packet if PPP_INPROC_MULTITHREADED is set by adding the necessary data for pppos_input_callback() in front of the first pbuf instead of allocating a new buffer. --- src/netif/ppp/ppp.c | 62 +++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 41 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 09efb140..afc225f8 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1522,12 +1522,6 @@ ppp_drop(ppp_pcb_rx *pcrx) snmp_inc_ifindiscards(&pcb->netif); } -#if PPP_INPROC_MULTITHREADED -struct ppp_tcpip_callback_header { - ppp_pcb *pcb; -}; -#endif /* PPP_INPROC_MULTITHREADED */ - /** Pass received raw characters to PPPoS to be decoded. This function is * thread-safe and can be called from a dedicated RX-thread or from a main-loop. * @@ -1583,10 +1577,6 @@ pppos_input(ppp_pcb *pcb, u_char *s, int l) /* Otherwise it's a good packet so pass it on. */ } else { struct pbuf *inp; -#if PPP_INPROC_MULTITHREADED - struct pbuf *head; - struct ppp_tcpip_callback_header *cbhead; -#endif /* PPP_INPROC_MULTITHREADED */ /* Trim off the checksum. */ if(pcrx->in_tail->len > 2) { pcrx->in_tail->len -= 2; @@ -1610,21 +1600,14 @@ pppos_input(ppp_pcb *pcb, u_char *s, int l) pcrx->in_head = NULL; pcrx->in_tail = NULL; #if PPP_INPROC_MULTITHREADED - head = pbuf_alloc(PBUF_RAW, sizeof(struct ppp_tcpip_callback_header), PBUF_POOL); - if(NULL != head) { - cbhead = (struct ppp_tcpip_callback_header*)head->payload; - cbhead->pcb = pcb; - pbuf_chain(head, inp); - if(tcpip_callback_with_block(pppos_input_callback, head, 0) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", pcb->num)); - pbuf_free(head); - pbuf_free(inp); - LINK_STATS_INC(link.drop); - snmp_inc_ifindiscards(&pcb->netif); - } + if(tcpip_callback_with_block(pppos_input_callback, inp, 0) != ERR_OK) { + PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", pcb->num)); + pbuf_free(inp); + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pcb->netif); } #else /* PPP_INPROC_MULTITHREADED */ - ppp_input(pcrx->pcb, inp); + ppp_input(pcb, inp); #endif /* PPP_INPROC_MULTITHREADED */ } @@ -1726,10 +1709,15 @@ pppos_input(ppp_pcb *pcb, u_char *s, int l) break; } if (pcrx->in_head == NULL) { - ((u8_t*)next_pbuf->payload)[0] = pcrx->in_protocol >> 8; - ((u8_t*)next_pbuf->payload)[1] = pcrx->in_protocol & 0xFF; + u8_t *payload = next_pbuf->payload; +#if PPP_INPROC_MULTITHREADED + *((ppp_pcb**)payload) = pcb; + payload += sizeof(ppp_pcb*); + next_pbuf->len += sizeof(ppp_pcb*); +#endif /* PPP_INPROC_MULTITHREADED */ + *(payload++) = pcrx->in_protocol >> 8; + *(payload) = pcrx->in_protocol & 0xFF; next_pbuf->len += sizeof(pcrx->in_protocol); - pcrx->in_head = next_pbuf; } pcrx->in_tail = next_pbuf; @@ -1749,33 +1737,25 @@ pppos_input(ppp_pcb *pcb, u_char *s, int l) #if PPP_INPROC_MULTITHREADED /* PPPoS input callback using one input pointer - * *arg is a pbuf chain of two chained pbuf, the first contains - * a pointer to the PPP PCB structure, the second contains the - * PPP payload */ static void pppos_input_callback(void *arg) { - struct pbuf *hd, *pl; - struct ppp_tcpip_callback_header *cbhead; + struct pbuf *pb = (struct pbuf*)arg; ppp_pcb *pcb; - hd = (struct pbuf *)arg; - cbhead = (struct ppp_tcpip_callback_header *)hd->payload; - pcb = cbhead->pcb; - - pl = hd->next; - pbuf_free(hd); - if(NULL == pl) + pcb = *((ppp_pcb**)pb->payload); + if(pbuf_header(pb, -(s16_t)sizeof(ppp_pcb*))) { + LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; + } /* Dispatch the packet thereby consuming it. */ - ppp_input(pcb, pl); + ppp_input(pcb, pb); return; drop: LINK_STATS_INC(link.drop); snmp_inc_ifindiscards(&pcb->netif); - pbuf_free(pl); - return; + pbuf_free(pb); } #endif /* PPP_INPROC_MULTITHREADED */ #endif /* PPPOS_SUPPORT */ From 4fda366b6744fd0b920a09edd55672e11ba07f17 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 30 Apr 2013 15:16:09 +0200 Subject: [PATCH 311/320] PPP, added PPP notify phase support PPP notify phase support, using compile-time PPP_NOTIFY_PHASE macro. This can be used for example to set a LED pattern depending on the current phase of the PPP session. Callback example: static void ppp_notify_phase_cb(ppp_pcb *pcb, u8_t phase, void *ctx) { switch(phase) { case PPP_PHASE_DEAD: /* Kept off */ case PPP_PHASE_MASTER: /* LED Off */ break; case PPP_PHASE_INITIALIZE: /* Session opened */ /* LED FastBlink */ break; case PPP_PHASE_RUNNING: /* Session running */ /* LED On */ break; default: /* LED SlowBlink */ } } --- src/api/pppapi.c | 41 ++++++++++++++---- src/include/lwip/pppapi.h | 20 ++++++--- src/include/netif/ppp/ppp.h | 39 ++++++++++++++++-- src/include/netif/ppp/ppp_impl.h | 17 -------- src/netif/ppp/auth.c | 32 +++++++------- src/netif/ppp/lcp.c | 4 +- src/netif/ppp/multilink.c | 2 +- src/netif/ppp/ppp.c | 71 ++++++++++++++++++-------------- 8 files changed, 140 insertions(+), 86 deletions(-) diff --git a/src/api/pppapi.c b/src/api/pppapi.c index e4e198a9..f1450a8d 100644 --- a/src/api/pppapi.c +++ b/src/api/pppapi.c @@ -102,13 +102,36 @@ void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { } +#if PPP_NOTIFY_PHASE +/** + * Call ppp_set_notify_phase_callback() inside the tcpip_thread context. + */ +static void pppapi_do_ppp_set_notify_phase_callback(struct pppapi_msg_msg *msg) { + ppp_set_notify_phase_callback(msg->ppp, msg->msg.setnotifyphasecb.notify_phase_cb); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_notify_phase_callback() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) { + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_notify_phase_callback; + msg.msg.ppp = pcb; + msg.msg.msg.setnotifyphasecb.notify_phase_cb = notify_phase_cb; + TCPIP_PPPAPI(&msg); +} +#endif /* PPP_NOTIFY_PHASE */ + + #if PPPOS_SUPPORT /** * Call ppp_over_serial_create() inside the tcpip_thread context. */ static void pppapi_do_ppp_over_serial_create(struct pppapi_msg_msg *msg) { msg->err = ppp_over_serial_create(msg->ppp, msg->msg.serialcreate.fd, - msg->msg.serialcreate.link_status_cb, msg->msg.serialcreate.link_status_ctx); + msg->msg.serialcreate.link_status_cb, msg->msg.serialcreate.ctx_cb); TCPIP_PPPAPI_ACK(msg); } @@ -116,13 +139,13 @@ static void pppapi_do_ppp_over_serial_create(struct pppapi_msg_msg *msg) { * Call ppp_over_serial_create() in a thread-safe way by running that function inside the * tcpip_thread context. */ -int pppapi_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { +int pppapi_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { struct pppapi_msg msg; msg.function = pppapi_do_ppp_over_serial_create; msg.msg.ppp = pcb; msg.msg.msg.serialcreate.fd = fd; msg.msg.msg.serialcreate.link_status_cb = link_status_cb; - msg.msg.msg.serialcreate.link_status_ctx = link_status_ctx; + msg.msg.msg.serialcreate.ctx_cb = ctx_cb; TCPIP_PPPAPI(&msg); return msg.msg.err; } @@ -137,7 +160,7 @@ static void pppapi_do_ppp_over_ethernet_create(struct pppapi_msg_msg *msg) { msg->err = ppp_over_ethernet_create(msg->ppp, msg->msg.ethernetcreate.ethif, msg->msg.ethernetcreate.service_name, msg->msg.ethernetcreate.concentrator_name, - msg->msg.ethernetcreate.link_status_cb, msg->msg.ethernetcreate.link_status_ctx); + msg->msg.ethernetcreate.link_status_cb, msg->msg.ethernetcreate.ctx_cb); TCPIP_PPPAPI_ACK(msg); } @@ -147,7 +170,7 @@ static void pppapi_do_ppp_over_ethernet_create(struct pppapi_msg_msg *msg) { */ int pppapi_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, - void *link_status_ctx) { + void *ctx_cb) { struct pppapi_msg msg; msg.function = pppapi_do_ppp_over_ethernet_create; msg.msg.ppp = pcb; @@ -155,7 +178,7 @@ int pppapi_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *s msg.msg.msg.ethernetcreate.service_name = service_name; msg.msg.msg.ethernetcreate.concentrator_name = concentrator_name; msg.msg.msg.ethernetcreate.link_status_cb = link_status_cb; - msg.msg.msg.ethernetcreate.link_status_ctx = link_status_ctx; + msg.msg.msg.ethernetcreate.ctx_cb = ctx_cb; TCPIP_PPPAPI(&msg); return msg.msg.err; } @@ -176,7 +199,7 @@ static void pppapi_do_ppp_over_l2tp_create(struct pppapi_msg_msg *msg) { #else /* PPPOL2TP_AUTH_SUPPORT */ NULL, #endif /* PPPOL2TP_AUTH_SUPPORT */ - msg->msg.l2tpcreate.link_status_cb, msg->msg.l2tpcreate.link_status_ctx); + msg->msg.l2tpcreate.link_status_cb, msg->msg.l2tpcreate.ctx_cb); TCPIP_PPPAPI_ACK(msg); } @@ -186,7 +209,7 @@ static void pppapi_do_ppp_over_l2tp_create(struct pppapi_msg_msg *msg) { */ int pppapi_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { + ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { struct pppapi_msg msg; msg.function = pppapi_do_ppp_over_l2tp_create; msg.msg.ppp = pcb; @@ -198,7 +221,7 @@ int pppapi_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr msg.msg.msg.l2tpcreate.secret_len = secret_len; #endif /* PPPOL2TP_AUTH_SUPPORT */ msg.msg.msg.l2tpcreate.link_status_cb = link_status_cb; - msg.msg.msg.l2tpcreate.link_status_ctx = link_status_ctx; + msg.msg.msg.l2tpcreate.ctx_cb = ctx_cb; TCPIP_PPPAPI(&msg); return msg.msg.err; } diff --git a/src/include/lwip/pppapi.h b/src/include/lwip/pppapi.h index 27660cad..520b4d7f 100644 --- a/src/include/lwip/pppapi.h +++ b/src/include/lwip/pppapi.h @@ -51,11 +51,16 @@ struct pppapi_msg_msg { char *user; char *passwd; } setauth; +#if PPP_NOTIFY_PHASE + struct { + ppp_notify_phase_cb_fn notify_phase_cb; + } setnotifyphasecb; +#endif /* PPP_NOTIFY_PHASE */ #if PPPOS_SUPPORT struct { sio_fd_t fd; ppp_link_status_cb_fn link_status_cb; - void *link_status_ctx; + void *ctx_cb; } serialcreate; #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT @@ -64,7 +69,7 @@ struct pppapi_msg_msg { const char *service_name; const char *concentrator_name; ppp_link_status_cb_fn link_status_cb; - void *link_status_ctx; + void *ctx_cb; } ethernetcreate; #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT @@ -77,7 +82,7 @@ struct pppapi_msg_msg { u8_t secret_len; #endif /* PPPOL2TP_AUTH_SUPPORT */ ppp_link_status_cb_fn link_status_cb; - void *link_status_ctx; + void *ctx_cb; } l2tpcreate; #endif /* PPPOL2TP_SUPPORT */ struct { @@ -109,18 +114,21 @@ struct pppapi_msg { ppp_pcb *pppapi_new(void); void pppapi_set_default(ppp_pcb *pcb); void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd); +#if PPP_NOTIFY_PHASE +void pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb); +#endif /* PPP_NOTIFY_PHASE */ #if PPPOS_SUPPORT -int pppapi_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +int pppapi_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *ctx_cb); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT int pppapi_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, - void *link_status_ctx); + void *ctx_cb); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT int pppapi_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); + ppp_link_status_cb_fn link_status_cb, void *ctx_cb); #endif /* PPPOL2TP_SUPPORT */ int pppapi_open(ppp_pcb *pcb, u16_t holdoff); int pppapi_close(ppp_pcb *pcb); diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 168d473e..64fb0592 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -61,6 +61,23 @@ #define PPP_HDRLEN 4 /* octets for standard ppp header */ #define PPP_FCSLEN 2 /* octets for FCS */ +/* + * Values for phase. + */ +#define PPP_PHASE_DEAD 0 +#define PPP_PHASE_INITIALIZE 1 +#define PPP_PHASE_SERIALCONN 2 +#define PPP_PHASE_DORMANT 3 +#define PPP_PHASE_ESTABLISH 4 +#define PPP_PHASE_AUTHENTICATE 5 +#define PPP_PHASE_CALLBACK 6 +#define PPP_PHASE_NETWORK 7 +#define PPP_PHASE_RUNNING 8 +#define PPP_PHASE_TERMINATE 9 +#define PPP_PHASE_DISCONNECT 10 +#define PPP_PHASE_HOLDOFF 11 +#define PPP_PHASE_MASTER 12 + /* Error codes. */ #define PPPERR_NONE 0 /* No error. */ #define PPPERR_PARAM 1 /* Invalid parameter. */ @@ -299,7 +316,10 @@ struct ppp_pcb_s { pppol2tp_pcb *l2tp_pcb; #endif /* PPPOL2TP_SUPPORT */ void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */ - void *link_status_ctx; /* Status change callback optional pointer */ +#if PPP_NOTIFY_PHASE + void (*notify_phase_cb)(ppp_pcb *pcb, u8_t phase, void *ctx); /* Notify phase callback */ +#endif /* PPP_NOTIFY_PHASE */ + void *ctx_cb; /* Callbacks optional pointer */ struct netif netif; /* PPP interface */ /* -- below are data that will be cleared between two sessions */ @@ -451,6 +471,17 @@ void ppp_set_default(ppp_pcb *pcb); void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd); +#if PPP_NOTIFY_PHASE +/* + * Set a PPP notify phase callback. + * + * This can be used for example to set a LED pattern depending on the + * current phase of the PPP session. + */ +typedef void (*ppp_notify_phase_cb_fn)(ppp_pcb *pcb, u8_t phase, void *ctx); +void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb); +#endif /* PPP_NOTIFY_PHASE */ + /* Link status callback function prototype */ typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx); @@ -463,7 +494,7 @@ typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx); * * Return 0 on success, an error code on failure. */ -int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); +int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *ctx_cb); #endif /* PPPOS_SUPPORT */ #if PPPOE_SUPPORT @@ -473,7 +504,7 @@ int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link * Return 0 on success, an error code on failure. */ int ppp_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, - ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); + ppp_link_status_cb_fn link_status_cb, void *ctx_cb); #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT @@ -482,7 +513,7 @@ int ppp_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *serv */ int ppp_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *link_status_ctx); + ppp_link_status_cb_fn link_status_cb, void *ctx_cb); #endif /* PPPOL2TP_SUPPORT */ /* diff --git a/src/include/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h index b1d5f9c4..6e02290b 100644 --- a/src/include/netif/ppp/ppp_impl.h +++ b/src/include/netif/ppp/ppp_impl.h @@ -346,23 +346,6 @@ extern const struct protent* const protocols[]; #endif /* MSCHAP_SUPPORT */ #endif /* CHAP_SUPPORT */ -/* - * 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 -#define PHASE_MASTER 12 - /* Supported CHAP protocols */ #if CHAP_SUPPORT #include "chap-new.h" diff --git a/src/netif/ppp/auth.c b/src/netif/ppp/auth.c index d1dc41f8..4cbf0afb 100644 --- a/src/netif/ppp/auth.c +++ b/src/netif/ppp/auth.c @@ -559,7 +559,7 @@ void start_link(unit) char *msg; status = EXIT_NEGOTIATION_FAILED; - new_phase(pcb, PHASE_SERIALCONN); + new_phase(pcb, PPP_PHASE_SERIALCONN); hungup = 0; devfd = the_channel->connect(); @@ -595,18 +595,18 @@ void start_link(unit) ppp_notice("Starting negotiation on %s", ppp_devnam); add_fd(fd_ppp); - new_phase(pcb, PHASE_ESTABLISH); + new_phase(pcb, PPP_PHASE_ESTABLISH); lcp_lowerup(pcb); return; disconnect: - new_phase(pcb, PHASE_DISCONNECT); + new_phase(pcb, PPP_PHASE_DISCONNECT); if (the_channel->disconnect) the_channel->disconnect(); fail: - new_phase(pcb, PHASE_DEAD); + new_phase(pcb, PPP_PHASE_DEAD); if (the_channel->cleanup) (*the_channel->cleanup)(); } @@ -617,9 +617,9 @@ void start_link(unit) * physical layer down. */ void link_terminated(ppp_pcb *pcb) { - if (pcb->phase == PHASE_DEAD || pcb->phase == PHASE_MASTER) + if (pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_MASTER) return; - new_phase(pcb, PHASE_DISCONNECT); + new_phase(pcb, PPP_PHASE_DISCONNECT); #if 0 /* UNUSED */ if (pap_logout_hook) { @@ -638,7 +638,7 @@ void link_terminated(ppp_pcb *pcb) { lcp_lowerdown(pcb); - new_phase(pcb, PHASE_DEAD); + new_phase(pcb, PPP_PHASE_DEAD); ppp_link_terminated(pcb); #if 0 /* @@ -680,11 +680,11 @@ void link_terminated(ppp_pcb *pcb) { if (doing_multilink && multilink_master) { if (!bundle_terminating) - new_phase(pcb, PHASE_MASTER); + new_phase(pcb, PPP_PHASE_MASTER); else mp_bundle_terminated(); } else - new_phase(pcb, PHASE_DEAD); + new_phase(pcb, PPP_PHASE_DEAD); #endif } @@ -698,8 +698,8 @@ void link_down(ppp_pcb *pcb) { if (!doing_multilink) { upper_layers_down(pcb); - if (pcb->phase != PHASE_DEAD && pcb->phase != PHASE_MASTER) - new_phase(pcb, PHASE_ESTABLISH); + if (pcb->phase != PPP_PHASE_DEAD && pcb->phase != PPP_PHASE_MASTER) + new_phase(pcb, PPP_PHASE_ESTABLISH); } /* XXX if doing_multilink, should do something to stop network-layer traffic on the link */ @@ -793,7 +793,7 @@ void link_established(ppp_pcb *pcb) { } #endif /* PPP_SERVER */ - new_phase(pcb, PHASE_AUTHENTICATE); + new_phase(pcb, PPP_PHASE_AUTHENTICATE); auth = 0; #if PPP_SERVER #if EAP_SUPPORT @@ -886,7 +886,7 @@ static void network_phase(ppp_pcb *pcb) { * If we negotiated callback, do it now. */ if (go->neg_cbcp) { - new_phase(pcb, PHASE_CALLBACK); + new_phase(pcb, PPP_PHASE_CALLBACK); (*cbcp_protent.open)(pcb); return; } @@ -917,7 +917,7 @@ void start_networks(ppp_pcb *pcb) { int mppe_required; #endif /* MPPE */ - new_phase(pcb, PHASE_NETWORK); + new_phase(pcb, PPP_PHASE_NETWORK); #ifdef HAVE_MULTILINK if (multilink) { @@ -1167,7 +1167,7 @@ void np_up(ppp_pcb *pcb, int proto) { /* * At this point we consider that the link has come up successfully. */ - new_phase(pcb, PHASE_RUNNING); + new_phase(pcb, PPP_PHASE_RUNNING); #if PPP_IDLETIMELIMIT #if 0 /* UNUSED */ @@ -1219,7 +1219,7 @@ void np_down(ppp_pcb *pcb, int proto) { #ifdef MAXOCTETS UNTIMEOUT(check_maxoctets, NULL); #endif - new_phase(pcb, PHASE_NETWORK); + new_phase(pcb, PPP_PHASE_NETWORK); } } diff --git a/src/netif/ppp/lcp.c b/src/netif/ppp/lcp.c index 9c69dd8f..52f7a50f 100644 --- a/src/netif/ppp/lcp.c +++ b/src/netif/ppp/lcp.c @@ -440,8 +440,8 @@ void lcp_close(ppp_pcb *pcb, char *reason) { fsm *f = &pcb->lcp_fsm; int oldstate; - if (pcb->phase != PHASE_DEAD && pcb->phase != PHASE_MASTER) - new_phase(pcb, PHASE_TERMINATE); + if (pcb->phase != PPP_PHASE_DEAD && pcb->phase != PPP_PHASE_MASTER) + new_phase(pcb, PPP_PHASE_TERMINATE); if (f->flags & DELAYED_UP) { UNTIMEOUT(lcp_delayed_up, f); diff --git a/src/netif/ppp/multilink.c b/src/netif/ppp/multilink.c index 883ecd00..9acbb567 100644 --- a/src/netif/ppp/multilink.c +++ b/src/netif/ppp/multilink.c @@ -295,7 +295,7 @@ void mp_bundle_terminated() tdb_delete(pppdb, key); unlock_db(); - new_phase(PHASE_DEAD); + new_phase(PPP_PHASE_DEAD); doing_multilink = 0; multilink_master = 0; diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index afc225f8..50d5d34b 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -294,7 +294,7 @@ ppp_pcb *ppp_new(void) { return NULL; } - new_phase(pcb, PHASE_DEAD); + new_phase(pcb, PPP_PHASE_DEAD); return pcb; } @@ -346,8 +346,15 @@ void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, char *user, char *passwd) { } } +#if PPP_NOTIFY_PHASE +void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) { + pcb->notify_phase_cb = notify_phase_cb; + notify_phase_cb(pcb, pcb->phase, pcb->ctx_cb); +} +#endif /* PPP_NOTIFY_PHASE */ + #if PPPOS_SUPPORT -int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { +int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ @@ -357,7 +364,7 @@ int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link pcb->fd = fd; pcb->link_status_cb = link_status_cb; - pcb->link_status_ctx = link_status_ctx; + pcb->ctx_cb = ctx_cb; return PPPERR_NONE; } @@ -379,7 +386,7 @@ void ppp_set_xaccm(ppp_pcb *pcb, ext_accm *accm) { static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state); int ppp_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, - ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { + ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { LWIP_UNUSED_ARG(service_name); LWIP_UNUSED_ARG(concentrator_name); @@ -391,7 +398,7 @@ int ppp_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *serv } pcb->link_status_cb = link_status_cb; - pcb->link_status_ctx = link_status_ctx; + pcb->ctx_cb = ctx_cb; if (pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { return PPPERR_OPEN; @@ -406,7 +413,7 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state); int ppp_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *link_status_ctx) { + ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { /* PPP is single-threaded: without a callback, * there is no way to know when the link is up. */ @@ -415,7 +422,7 @@ int ppp_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u } pcb->link_status_cb = link_status_cb; - pcb->link_status_ctx = link_status_ctx; + pcb->ctx_cb = ctx_cb; if (pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, netif, ipaddr, port, secret, secret_len) != ERR_OK) { return PPPERR_OPEN; @@ -434,7 +441,7 @@ int ppp_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u * the connection. */ int ppp_open(ppp_pcb *pcb, u16_t holdoff) { - if (pcb->phase != PHASE_DEAD) { + if (pcb->phase != PPP_PHASE_DEAD) { return PPPERR_PARAM; } @@ -445,7 +452,7 @@ int ppp_open(ppp_pcb *pcb, u16_t holdoff) { return PPPERR_NONE; } - new_phase(pcb, PHASE_HOLDOFF); + new_phase(pcb, PPP_PHASE_HOLDOFF); sys_timeout((u32_t)(holdoff*1000), ppp_do_open, pcb); return PPPERR_NONE; } @@ -463,15 +470,15 @@ ppp_close(ppp_pcb *pcb) pcb->err_code = PPPERR_USER; /* dead phase, nothing to do, call the status callback to be consistent */ - if (pcb->phase == PHASE_DEAD) { - pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); + if (pcb->phase == PPP_PHASE_DEAD) { + pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); return PPPERR_NONE; } /* holdoff phase, cancel the reconnection and call the status callback */ - if (pcb->phase == PHASE_HOLDOFF) { + if (pcb->phase == PPP_PHASE_HOLDOFF) { sys_untimeout(ppp_do_open, pcb); - pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); + pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); return PPPERR_NONE; } @@ -481,21 +488,21 @@ ppp_close(ppp_pcb *pcb) #if PPPOE_SUPPORT if (pcb->pppoe_sc) { PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); - /* This will leave us at PHASE_DEAD. */ + /* This will leave us at PPP_PHASE_DEAD. */ ppp_stop(pcb); } else #endif /* PPPOE_SUPPORT */ #if PPPOL2TP_SUPPORT if (pcb->l2tp_pcb) { PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); - /* This will leave us at PHASE_DEAD. */ + /* This will leave us at PPP_PHASE_DEAD. */ ppp_stop(pcb); } else #endif /* PPPOL2TP_SUPPORT */ { #if PPPOS_SUPPORT PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); - /* This will leave us at PHASE_DEAD. */ + /* This will leave us at PPP_PHASE_DEAD. */ ppp_stop(pcb); #endif /* PPPOS_SUPPORT */ } @@ -525,7 +532,7 @@ ppp_sighup(ppp_pcb *pcb) * Return 0 on success, an error code on failure. */ int ppp_free(ppp_pcb *pcb) { - if (pcb->phase != PHASE_DEAD) { + if (pcb->phase != PPP_PHASE_DEAD) { return PPPERR_PARAM; } @@ -566,7 +573,7 @@ int ppp_free(ppp_pcb *pcb) { int ppp_delete(ppp_pcb *pcb) { int err; - if (pcb->phase != PHASE_DEAD) { + if (pcb->phase != PPP_PHASE_DEAD) { return PPPERR_PARAM; } @@ -593,7 +600,7 @@ static void ppp_clear(ppp_pcb *pcb) { const struct protent *protp; int i; - LWIP_ASSERT("pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF", pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF); + LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF); #if PPP_STATS_SUPPORTs link_stats_valid = 0; @@ -609,13 +616,13 @@ static void ppp_clear(ppp_pcb *pcb) { (*protp->init)(pcb); } - new_phase(pcb, PHASE_INITIALIZE); + new_phase(pcb, PPP_PHASE_INITIALIZE); } static void ppp_do_open(void *arg) { ppp_pcb *pcb = (ppp_pcb*)arg; - LWIP_ASSERT("pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF", pcb->phase == PHASE_DEAD || pcb->phase == PHASE_HOLDOFF); + LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF); #if PPPOE_SUPPORT if (pcb->pppoe_sc) { @@ -691,7 +698,7 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { * Until we get past the authentication phase, toss all packets * except LCP, LQR and authentication packets. */ - if (pcb->phase <= PHASE_AUTHENTICATE + if (pcb->phase <= PPP_PHASE_AUTHENTICATE && !(protocol == PPP_LCP #if LQR_SUPPORT || protocol == PPP_LQR @@ -1808,11 +1815,11 @@ static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { case PPPOE_CB_STATE_FAILED: PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pcb->num)); pppoe_err_code = PPPERR_OPEN; - new_phase(pcb, PHASE_DEAD); + new_phase(pcb, PPP_PHASE_DEAD); break; } - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->link_status_ctx); + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->ctx_cb); } static void ppp_over_ethernet_open(ppp_pcb *pcb) { @@ -1858,11 +1865,11 @@ static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { case PPPOL2TP_CB_STATE_FAILED: PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: FAILED, aborting\n", pcb->num)); pppol2tp_err_code = PPPERR_OPEN; - new_phase(pcb, PHASE_DEAD); + new_phase(pcb, PPP_PHASE_DEAD); break; } - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->link_status_ctx); + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->ctx_cb); } static void ppp_over_l2tp_open(ppp_pcb *pcb) { @@ -1909,7 +1916,7 @@ void ppp_link_terminated(ppp_pcb *pcb) { * rx thread might still call pppos_input() */ PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: link_status_cb=%p err_code=%d\n", pcb->num, pcb->link_status_cb, pcb->err_code)); - pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->link_status_ctx); + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->ctx_cb); #endif /* PPPOS_SUPPORT */ } PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: finished.\n")); @@ -1956,9 +1963,11 @@ ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) void new_phase(ppp_pcb *pcb, int p) { pcb->phase = p; PPPDEBUG(LOG_DEBUG, ("ppp phase changed: unit %d: phase=%d\n", pcb->num, pcb->phase)); -#if PPP_NOTIFY - /* The one willing notify support should add here the code to be notified of phase changes */ -#endif /* PPP_NOTIFY */ +#if PPP_NOTIFY_PHASE + if(NULL != pcb->notify_phase_cb) { + pcb->notify_phase_cb(pcb, p, pcb->ctx_cb); + } +#endif /* PPP_NOTIFY_PHASE */ } /* @@ -2137,7 +2146,7 @@ int sifup(ppp_pcb *pcb) { pcb->err_code = PPPERR_NONE; PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); - pcb->link_status_cb(pcb, pcb->err_code, pcb->link_status_ctx); + pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); return 1; } From 357b28f675ee9b1864b5a72d5b953ad22a4f313f Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 14 Jan 2014 18:20:18 +0100 Subject: [PATCH 312/320] PPP, fixed VJ compression/decompression output IP path --- src/netif/ppp/ppp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 50d5d34b..594d18c5 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -729,8 +729,8 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { * Clip off the VJ header and prepend the rebuilt TCP/IP header and * pass the result to IP. */ - if ((vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) && (pcb->netif.input)) { - pcb->netif.input(pb, &pcb->netif); + if (vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) { + ip_input(pb, &pcb->netif); return; } /* Something's wrong so drop it. */ @@ -743,8 +743,8 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { * Process the TCP/IP header for VJ header compression and then pass * the packet to IP. */ - if ((vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) && pcb->netif.input) { - pcb->netif.input(pb, &pcb->netif); + if (vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) { + ip_input(pb, &pcb->netif); return; } /* Something's wrong so drop it. */ From 08dd32d32dc39e3c42d96bea21ff800dbebb8e57 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 4 Apr 2014 20:42:01 +0200 Subject: [PATCH 313/320] PPP, most PPP headers are using u_long, u_int, u_short and u_char types, moved typedef of those types before we include any PPP header --- src/include/netif/ppp/ppp.h | 12 +++++++++++- src/include/netif/ppp/ppp_impl.h | 8 -------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h index 64fb0592..cda32ba0 100644 --- a/src/include/netif/ppp/ppp.h +++ b/src/include/netif/ppp/ppp.h @@ -48,7 +48,6 @@ #include "lwip/ip6_addr.h" #endif /* PPP_IPV6_SUPPORT */ -#include "vj.h" /************************* @@ -117,6 +116,14 @@ */ typedef struct ppp_pcb_s ppp_pcb; +/* Type definitions for BSD code. */ +#ifndef __u_char_defined +typedef unsigned long u_long; +typedef unsigned int u_int; +typedef unsigned short u_short; +typedef unsigned char u_char; +#endif + #include "fsm.h" #include "lcp.h" #include "ipcp.h" @@ -132,6 +139,9 @@ typedef struct ppp_pcb_s ppp_pcb; #if EAP_SUPPORT #include "eap.h" #endif /* EAP_SUPPORT */ +#if VJ_SUPPORT +#include "vj.h" +#endif /* VJ_SUPPORT */ #if PPPOE_SUPPORT #include "netif/ppp/pppoe.h" diff --git a/src/include/netif/ppp/ppp_impl.h b/src/include/netif/ppp/ppp_impl.h index 6e02290b..595ba3a6 100644 --- a/src/include/netif/ppp/ppp_impl.h +++ b/src/include/netif/ppp/ppp_impl.h @@ -47,14 +47,6 @@ #include "lwip/timers.h" #include "lwip/sio.h" -/* Type definitions for BSD code. */ -#ifndef __u_char_defined -typedef unsigned long u_long; -typedef unsigned int u_int; -typedef unsigned short u_short; -typedef unsigned char u_char; -#endif - #include "ppp.h" #include "pppdebug.h" From 4283ecf7748ccf7ab41fc09b7d6d4acb1f7f4444 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Fri, 11 Apr 2014 22:31:01 +0200 Subject: [PATCH 314/320] PPP, PPPoS, fixed IP forward from PPP to Ethernet by allocating PBUF_LINK instead of PBUF_RAW if IP forwarding is enabled --- src/netif/ppp/ppp.c | 50 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 594d18c5..7e4f6324 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1529,6 +1529,22 @@ ppp_drop(ppp_pcb_rx *pcrx) snmp_inc_ifindiscards(&pcb->netif); } +/** PPPoS input helper struct, must be packed since it is stored + * to pbuf->payload, which might be unaligned. */ +#if PPP_INPROC_MULTITHREADED +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppos_input_header { + PACK_STRUCT_FIELD(ppp_pcb *pcb); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#endif /* PPP_INPROC_MULTITHREADED */ + /** Pass received raw characters to PPPoS to be decoded. This function is * thread-safe and can be called from a dedicated RX-thread or from a main-loop. * @@ -1704,7 +1720,15 @@ pppos_input(ppp_pcb *pcb, u_char *s, int l) } } /* If we haven't started a packet, we need a packet header. */ +#if IP_FORWARD || LWIP_IPV6_FORWARD + /* If IP forwarding is enabled we are using a PBUF_LINK packet type so + * the packet is being allocated with enough header space to be + * forwarded (to Ethernet for example). + */ + next_pbuf = pbuf_alloc(PBUF_LINK, 0, PBUF_POOL); +#else /* IP_FORWARD || LWIP_IPV6_FORWARD */ next_pbuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); +#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */ if (next_pbuf == NULL) { /* No free buffers. Drop the input packet and let the * higher layers deal with it. Continue processing @@ -1716,15 +1740,27 @@ pppos_input(ppp_pcb *pcb, u_char *s, int l) break; } if (pcrx->in_head == NULL) { - u8_t *payload = next_pbuf->payload; + u8_t *payload; + /* pbuf_header() used below is only trying to put PPP headers + * before the current payload pointer if there is enough space + * in the pbuf to do so. Therefore we don't care if it fails, + * but if it fail we have to set len to the size used by PPP headers. + */ #if PPP_INPROC_MULTITHREADED - *((ppp_pcb**)payload) = pcb; - payload += sizeof(ppp_pcb*); - next_pbuf->len += sizeof(ppp_pcb*); + if (pbuf_header(next_pbuf, +sizeof(struct pppos_input_header) +sizeof(pcrx->in_protocol))) { + next_pbuf->len += sizeof(struct pppos_input_header) + sizeof(pcrx->in_protocol); + } + payload = next_pbuf->payload; + ((struct pppos_input_header*)payload)->pcb = pcb; + payload += sizeof(struct pppos_input_header); +#else /* PPP_INPROC_MULTITHREADED */ + if (pbuf_header(next_pbuf, +sizeof(pcrx->in_protocol))) { + next_pbuf->len += sizeof(pcrx->in_protocol); + } + payload = next_pbuf->payload; #endif /* PPP_INPROC_MULTITHREADED */ *(payload++) = pcrx->in_protocol >> 8; *(payload) = pcrx->in_protocol & 0xFF; - next_pbuf->len += sizeof(pcrx->in_protocol); pcrx->in_head = next_pbuf; } pcrx->in_tail = next_pbuf; @@ -1749,8 +1785,8 @@ static void pppos_input_callback(void *arg) { struct pbuf *pb = (struct pbuf*)arg; ppp_pcb *pcb; - pcb = *((ppp_pcb**)pb->payload); - if(pbuf_header(pb, -(s16_t)sizeof(ppp_pcb*))) { + pcb = ((struct pppos_input_header*)pb->payload)->pcb; + if(pbuf_header(pb, -(s16_t)sizeof(struct pppos_input_header))) { LWIP_ASSERT("pbuf_header failed\n", 0); goto drop; } From c0aef7dd6b5bfe9f5f2ac90c1c35b0c4597eff88 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 12 Apr 2014 01:23:57 +0200 Subject: [PATCH 315/320] PPP, VJ compression enabled, fixed IP forward from PPP to Ethernet by allocating a PBUF_LINK instead of a PBUF_RAW if IP forwarding is enabled --- src/netif/ppp/vj.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/netif/ppp/vj.c b/src/netif/ppp/vj.c index 792e16c9..5c195909 100644 --- a/src/netif/ppp/vj.c +++ b/src/netif/ppp/vj.c @@ -593,7 +593,15 @@ vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) struct pbuf *np, *q; u8_t *bufptr; +#if IP_FORWARD + /* If IP forwarding is enabled we are using a PBUF_LINK packet type so + * the packet is being allocated with enough header space to be + * forwarded (to Ethernet for example). + */ + np = pbuf_alloc(PBUF_LINK, n0->len + cs->cs_hlen, PBUF_POOL); +#else /* IP_FORWARD */ np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); +#endif /* IP_FORWARD */ if(!np) { PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n")); goto bad; From f6d56e29378c4e10d7b0a3d576044cff49c94fe0 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 15 Apr 2014 22:34:24 +0200 Subject: [PATCH 316/320] PPP, from PPPD upstream, take out unused %r conversion completely, pppd: Take out unused %r conversion completely This just removes some code surrounded by #if 0/#endif, which Fedora apparently feels the need to patch... --- src/netif/ppp/utils.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index 6529a933..c49c179f 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -271,19 +271,6 @@ int ppp_vslprintf(char *buf, int buflen, char *fmt, va_list args) { (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); str = num; break; -#if 0 /* not used, and breaks on S/390, apparently */ - case 'r': - f = va_arg(args, char *); -#ifndef __powerpc__ - n = ppp_vslprintf(buf, buflen + 1, f, va_arg(args, va_list)); -#else - /* On the powerpc, a va_list is an array of 1 structure */ - n = ppp_vslprintf(buf, buflen + 1, f, va_arg(args, void *)); -#endif - buf += n; - buflen -= n; - continue; -#endif #if 0 /* need port */ case 't': time(&t); From c31b03327f4ee4307ce97db5bfddb592c5d83fe3 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 15 Apr 2014 22:50:53 +0200 Subject: [PATCH 317/320] PPP, from PPPD upstream, Don't crash if NULL pointer passed to vslprintf for %q or %v pppd: Don't crash if NULL pointer passed to vslprintf for %q or %v This is to avoid crashes like that reported in https://bugs.launchpad.net/ubuntu/+source/ppp/+bug/1244714 --- src/netif/ppp/utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/netif/ppp/utils.c b/src/netif/ppp/utils.c index c49c179f..d03f6c25 100644 --- a/src/netif/ppp/utils.c +++ b/src/netif/ppp/utils.c @@ -283,6 +283,8 @@ int ppp_vslprintf(char *buf, int buflen, char *fmt, va_list args) { case 'q': /* quoted string */ quoted = c == 'q'; p = va_arg(args, unsigned char *); + if (p == NULL) + p = (unsigned char *)""; if (fillch == '0' && prec >= 0) { n = prec; } else { From 25e398a8f0184c4342d02b43a9032ac6fc865235 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 15 Apr 2014 22:55:28 +0200 Subject: [PATCH 318/320] PPP, from PPPD upstream, accept IPCP ConfAck packets containing MS-WINS options pppd: Accept IPCP ConfAck packets containing MS-WINS options Since last week I'm seeing IPCP negotiations going like this (and eventually failing) when connecting to my ISP: Jul 11 20:03:25 * pppd[4833]: sent [IPCP ConfReq id=0x2 ] Jul 11 20:03:26 * pppd[4833]: sent [IPCP ConfReq id=0x2 ] Jul 11 20:03:26 * pppd[4833]: rcvd [IPCP ConfNak id=0x2 ] Jul 11 20:03:26 * pppd[4833]: sent [IPCP ConfReq id=0x3 ] Jul 11 20:03:26 * pppd[4833]: rcvd [IPCP ConfAck id=0x3 ] Jul 11 20:03:27 * pppd[4833]: sent [IPCP ConfReq id=0x3 ] ... with the last two lines repeating until the IPCP error limit is reached. As you can see, the peer added two extra fields in the ConfNak reply. This is allowed, and indeed the following sent ConfReq packet reflects this. However, when the ConfAck packet is received, pppd discards it as invalid, because of the ms-wins fields. This fixes it. --- src/netif/ppp/ipcp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c index efe5d708..1944fc86 100644 --- a/src/netif/ppp/ipcp.c +++ b/src/netif/ppp/ipcp.c @@ -970,6 +970,21 @@ static int ipcp_ackci(fsm *f, u_char *p, int len) { goto bad; \ } +#define ACKCIWINS(opt, addr) \ + if (addr) { \ + u_int32_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; \ + } + ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, go->hisaddr); @@ -982,6 +997,10 @@ static int ipcp_ackci(fsm *f, u_char *p, int len) { ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]); + + ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]); + /* * If there are any remaining CIs, then this packet is bad. */ From 3fd7bc8058bb726c1aa0ddb965b36aabb685286c Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Tue, 15 Apr 2014 22:57:59 +0200 Subject: [PATCH 319/320] PPP, updated pppd followup --- src/netif/ppp/PPPD_FOLLOWUP | 146 +++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 1 deletion(-) diff --git a/src/netif/ppp/PPPD_FOLLOWUP b/src/netif/ppp/PPPD_FOLLOWUP index af899952..85ba7deb 100644 --- a/src/netif/ppp/PPPD_FOLLOWUP +++ b/src/netif/ppp/PPPD_FOLLOWUP @@ -25,7 +25,7 @@ Debian and this is a good place to be. - using rp-pppoe pppd exits with EXIT_OK after receiving a timeout waiting for PADO due to no modem attached, bug reported to pppd bug tracker, fixed - in Debian but not in the latest (at the time where the port where started) + in Debian but not in the latest (at the time when the port were started) pppd release. @@ -168,3 +168,147 @@ Again, we are handling compilation warnings on our own. Once more, we are not using the RP-PPPoE plugin. + +2013-01-23 - pppd: Clarify circumstances where DNS1/DNS2 environment variables are set + cf2f5c9538b9400ade23446a194729b0a4113b3a + +Documentation only. + + +2013-02-03 - ppp: ignore unrecognised radiusclient configuration directives + 7f736dde0da3c19855997d9e67370e351e15e923 + +Radius plugin, not in the port. + + +2013-02-03 - pppd: Take out unused %r conversion completely + 356d8d558d844412119aa18c8e5a113bc6459c7b + +Merged 2014-04-15. + + +2013-02-03 - pppd: Arrange to use logwtmp from libutil on Linux + 9617a7eb137f4fee62799a677a9ecf8d834db3f5 + +Patch for sys-linux.c, which we don't use. + + +2013-02-03 - pppdump: Eliminate some compiler warnings + 3e3acf1ba2b3046c072a42c19164788a9e419bd1 + +pppdump is a ppp tool outside pppd source tree. + + +2013-02-03 - chat: Correct spelling errors in the man page + 8dea1b969d266ccbf6f3a8c5474eb6dcd8838e3b + +Documentation only. + + +2013-02-03 - pppd: Fix spelling errors in man page + 9e05a25d76b3f83096c661678010320df673df6b + +Documentation only. + + +2013-02-03 - plugins/passprompt: Fix potential out-of-bounds array reference + 8edb889b753056a691a3e4b217a110a35f9fdedb + +Plugin patch, we do not have plugins. + + +2013-02-03 - chat: Fix *roff errors in the man page + a7c3489eeaf44e83ce592143c7c8a5b5c29f4c48 + +Documentation only. + + +2013-03-02 - pppd: Fix man page description of case when remote IP address isn't known + 224841f4799f4f1e2e71bc490c54448d66740f4f + +Documentation only. + + +2013-03-02 - pppd: Add master_detach option + 398ed2585640d198c53e736ee5bbd67f7ce8168e + +Option for multilink support, we do not support multilink and this option +is about detaching from the terminal, which is out of the embedded scope. + + +2013-03-11 - pppd: Default exit status to EXIT_CONNECT_FAILED during connection phase + 225361d64ae737afdc8cb57579a2f33525461bc9 + +Commented out in our port, and already fixed by a previously applied Debian patch. + + +2013-03-11 - pppstats: Fix undefined macro in man page + d16a3985eade5280b8e171f5dd0670a91cba0d39 + +Documentation only. + + +2013-05-11 - plugins/radius: Handle bindaddr keyword in radiusclient.conf + d883b2dbafeed3ebd9d7a56ab1469373bd001a3b + +Radius plugin, not in the port. + + +2013-06-09 - pppoatm: Remove explicit loading of pppoatm kernel module + 52cd43a84bea524033b918b603698104f221bbb7 + +PPPoATM plugin, not in the port. + + +2013-06-09 - pppd: Fix segfault in update_db_entry() + 37476164f15a45015310b9d4b197c2d7db1f7f8f + +We do not use the samba db. + + +2013-06-09 - chat: Fix some text that was intended to be literal + cd9683676618adcee8add2c3cfa3382341b5a1f6 + +Documentation only. + + +2013-06-09 - README.pppoe: Minor semantic fix + b5b8898af6fd3d44e873cfc66810ace5f1f47e17 + +Documentation only. + + +2013-06-10 - radius: Handle additional attributes + 2f581cd986a56f2ec4a95abad4f8297a1b10d7e2 + +Radius plugin, not in the port. + + +2013-06-10 - chat, pppd: Use \e instead of \\ in man pages + 8d6942415d22f6ca4377340ca26e345c3f5fa5db + +Documentation only. + + +2014-01-02 - pppd: Don't crash if NULL pointer passed to vslprintf for %q or %v + 906814431bddeb2061825fa1ebad1a967b6d87a9 + +Merged 2014-04-15. + + +2014-01-02 - pppd: Accept IPCP ConfAck packets containing MS-WINS options + a243f217f1c6ac1aa7793806bc88590d077f490a + +Merged 2014-04-15. + + +2014-01-02 - config: Update Solaris compiler options and enable CHAPMS and IPV6 + 99c46caaed01b7edba87962aa52b77fad61bfd7b + +Solaris port, don't care. + + +2014-01-02 - Update README and patchlevel for 2.4.6 release + 4043750fca36e7e0eb90d702e048ad1da4929418 + +Just release stuff. From a7745e9a86f5a92b664486ed04e00488c9edf334 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Sat, 19 Apr 2014 23:38:24 +0200 Subject: [PATCH 320/320] PPP, PPPoE, fixed bug #42138, pppoe_destroy() called with wrong pointer, PPPoE control block was never freed --- src/include/netif/ppp/pppoe.h | 2 +- src/netif/ppp/ppp.c | 2 +- src/netif/ppp/pppoe.c | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/include/netif/ppp/pppoe.h b/src/include/netif/ppp/pppoe.h index 37a72828..2fbe3115 100644 --- a/src/include/netif/ppp/pppoe.h +++ b/src/include/netif/ppp/pppoe.h @@ -168,7 +168,7 @@ struct pppoe_softc { #define pppoe_init() /* compatibility define, no initialization needed */ err_t pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp_pcb *pcb, int up), struct pppoe_softc **scptr); -err_t pppoe_destroy(struct netif *ifp); +err_t pppoe_destroy(struct pppoe_softc *sc); int pppoe_connect(struct pppoe_softc *sc); void pppoe_disconnect(struct pppoe_softc *sc); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 7e4f6324..12a57ebd 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -540,7 +540,7 @@ int ppp_free(ppp_pcb *pcb) { #if PPPOE_SUPPORT if (pcb->pppoe_sc) { - pppoe_destroy(&pcb->netif); + pppoe_destroy(pcb->pppoe_sc); pcb->pppoe_sc = NULL; } #endif /* PPPOE_SUPPORT */ diff --git a/src/netif/ppp/pppoe.c b/src/netif/ppp/pppoe.c index bf69c680..a5f4bd30 100644 --- a/src/netif/ppp/pppoe.c +++ b/src/netif/ppp/pppoe.c @@ -165,17 +165,18 @@ pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp_pcb * } err_t -pppoe_destroy(struct netif *ifp) +pppoe_destroy(struct pppoe_softc *sc) { - struct pppoe_softc *sc, *prev = NULL; + struct pppoe_softc *cur, *prev = NULL; - for (sc = pppoe_softc_list; sc != NULL; prev = sc, sc = sc->next) { - if (sc->sc_ethif == ifp) { + /* find previous linked list entry */ + for (cur = pppoe_softc_list; cur != NULL; prev = cur, cur = cur->next) { + if (sc == cur) { break; } } - if(!(sc && (sc->sc_ethif == ifp))) { + if (cur != sc) { return ERR_IF; }