mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-02-22 03:40:48 +00:00
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.
This commit is contained in:
parent
b56a1501d2
commit
eb75ae05c6
2694
src/netif/ppp/auth.c
2694
src/netif/ppp/auth.c
File diff suppressed because it is too large
Load Diff
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-04 Guy Lancaster <lancasterg@acm.org>, 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 */
|
26
src/netif/ppp/cbcp.h
Normal file
26
src/netif/ppp/cbcp.h
Normal file
@ -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
|
1680
src/netif/ppp/ccp.c
Normal file
1680
src/netif/ppp/ccp.c
Normal file
File diff suppressed because it is too large
Load Diff
52
src/netif/ppp/ccp.h
Normal file
52
src/netif/ppp/ccp.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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;
|
119
src/netif/ppp/chap-md5.c
Normal file
119
src/netif/ppp/chap-md5.c
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#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);
|
||||
}
|
31
src/netif/ppp/chap-md5.h
Normal file
31
src/netif/ppp/chap-md5.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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);
|
658
src/netif/ppp/chap-new.c
Normal file
658
src/netif/ppp/chap-new.c
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#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 */
|
||||
};
|
130
src/netif/ppp/chap-new.h
Normal file
130
src/netif/ppp/chap-new.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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;
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-04 Guy Lancaster <lancasterg@acm.org>, 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 <string.h>
|
||||
|
||||
#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 */
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-03 Guy Lancaster <lancasterg@acm.org>, 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 */
|
943
src/netif/ppp/chap_ms.c
Normal file
943
src/netif/ppp/chap_ms.c
Normal file
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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 <net/ppp-comp.h>
|
||||
#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=<auth_string> M=<message>"
|
||||
* where
|
||||
* <auth_string> is the Authenticator Response (mutual auth)
|
||||
* <message> is a text message
|
||||
*
|
||||
* However, some versions of Windows (win98 tested) do not know
|
||||
* about the M=<message> 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 <say@real.kharkov.ua> 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=<message> part (if any). For MS-CHAP we're not really supposed
|
||||
* to use M=<message>, 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=<message> field found. */
|
||||
p += 3;
|
||||
} else {
|
||||
/* No M=<message>; 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 */
|
109
src/netif/ppp/chap_ms.h
Normal file
109
src/netif/ppp/chap_ms.h
Normal file
@ -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__ */
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-08 Guy Lancaster <lancasterg@acm.org>, 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 <string.h>
|
||||
|
||||
|
||||
/*************************/
|
||||
/*** 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 */
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 98-01-30 Guy Lancaster <lancasterg@acm.org>, 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 */
|
366
src/netif/ppp/demand.c
Normal file
366
src/netif/ppp/demand.c
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef PPP_FILTER
|
||||
#include <pcap-bpf.h>
|
||||
#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 !!?? */
|
||||
}
|
2430
src/netif/ppp/eap.c
Normal file
2430
src/netif/ppp/eap.c
Normal file
File diff suppressed because it is too large
Load Diff
158
src/netif/ppp/eap.h
Normal file
158
src/netif/ppp/eap.h
Normal file
@ -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 */
|
||||
|
175
src/netif/ppp/ecp.c
Normal file
175
src/netif/ppp/ecp.c
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
45
src/netif/ppp/ecp.h
Normal file
45
src/netif/ppp/ecp.h
Normal file
@ -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;
|
114
src/netif/ppp/eui64.h
Normal file
114
src/netif/ppp/eui64.h
Normal file
@ -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
|
||||
* <Tommi.Komulainen@iki.fi>".
|
||||
*
|
||||
* 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 <netinet/in.h>
|
||||
|
||||
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__ */
|
||||
|
1284
src/netif/ppp/fsm.c
1284
src/netif/ppp/fsm.c
File diff suppressed because it is too large
Load Diff
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-11-05 Guy Lancaster <glanca@gesn.com>, 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) */
|
||||
|
3122
src/netif/ppp/ipcp.c
3122
src/netif/ppp/ipcp.c
File diff suppressed because it is too large
Load Diff
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-04 Guy Lancaster <glanca@gesn.com>, 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;
|
||||
|
171
src/netif/ppp/ipv6cp.h
Normal file
171
src/netif/ppp/ipv6cp.h
Normal file
@ -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
|
||||
* <Tommi.Komulainen@iki.fi>".
|
||||
*
|
||||
* 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;
|
1600
src/netif/ppp/ipxcp.c
Normal file
1600
src/netif/ppp/ipxcp.c
Normal file
File diff suppressed because it is too large
Load Diff
94
src/netif/ppp/ipxcp.h
Normal file
94
src/netif/ppp/ipxcp.h
Normal file
@ -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;
|
3584
src/netif/ppp/lcp.c
3584
src/netif/ppp/lcp.c
File diff suppressed because it is too large
Load Diff
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-11-05 Guy Lancaster <glanca@gesn.com>, 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
|
||||
|
178
src/netif/ppp/linux/if_ppp.h
Normal file
178
src/netif/ppp/linux/if_ppp.h
Normal file
@ -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_ */
|
65
src/netif/ppp/linux/if_pppol2tp.h
Normal file
65
src/netif/ppp/linux/if_pppol2tp.h
Normal file
@ -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 <asm/types.h>
|
||||
|
||||
/* 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
|
213
src/netif/ppp/linux/ppp-comp.h
Normal file
213
src/netif/ppp/linux/ppp-comp.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 */
|
195
src/netif/ppp/linux/ppp_defs.h
Normal file
195
src/netif/ppp/linux/ppp_defs.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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_ */
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-04 Guy Lancaster <lancasterg@acm.org>, 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#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
|
||||
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-04 Guy Lancaster <glanca@gesn.com>, 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));
|
||||
|
301
src/netif/ppp/md4.c
Normal file
301
src/netif/ppp/md4.c
Normal file
@ -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 <stdio.h>
|
||||
#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<<S) | (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)***********************************/
|
64
src/netif/ppp/md4.h
Normal file
64
src/netif/ppp/md4.h
Normal file
@ -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)***********************************/
|
@ -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 <string.h>
|
||||
#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) ********************************
|
||||
*/
|
||||
|
@ -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__ */
|
||||
|
121
src/netif/ppp/mppe.h
Normal file
121
src/netif/ppp/mppe.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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)
|
595
src/netif/ppp/multilink.c
Normal file
595
src/netif/ppp/multilink.c
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
156
src/netif/ppp/net/if_ppp.h
Normal file
156
src/netif/ppp/net/if_ppp.h
Normal file
@ -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_ */
|
179
src/netif/ppp/net/ppp-comp.h
Normal file
179
src/netif/ppp/net/ppp-comp.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 */
|
197
src/netif/ppp/net/ppp_defs.h
Normal file
197
src/netif/ppp/net/ppp_defs.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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_ */
|
107
src/netif/ppp/net/pppio.h
Normal file
107
src/netif/ppp/net/pppio.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 */
|
148
src/netif/ppp/net/slcompress.h
Normal file
148
src/netif/ppp/net/slcompress.h
Normal file
@ -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_ */
|
@ -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_ */
|
1627
src/netif/ppp/options.c
Normal file
1627
src/netif/ppp/options.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-12 Guy Lancaster <lancasterg@acm.org>, 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 <string.h>
|
||||
|
||||
#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 */
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-12-04 Guy Lancaster <glanca@gesn.com>, 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 */
|
2
src/netif/ppp/patchlevel.h
Normal file
2
src/netif/ppp/patchlevel.h
Normal file
@ -0,0 +1,2 @@
|
||||
#define VERSION "2.4.5"
|
||||
#define DATE "17 November 2009"
|
65
src/netif/ppp/pathnames.h
Normal file
65
src/netif/ppp/pathnames.h
Normal file
@ -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 <paths.h>
|
||||
|
||||
#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 */
|
3832
src/netif/ppp/ppp.c
3832
src/netif/ppp/ppp.c
File diff suppressed because it is too large
Load Diff
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-11-05 Guy Lancaster <glanca@gesn.com>, 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 */
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-11-05 Guy Lancaster <glanca@gesn.com>, 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 */
|
@ -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 <string.h>
|
||||
#include <stdio.h>
|
||||
@ -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");
|
||||
|
195
src/netif/ppp/pppcrypt.c
Normal file
195
src/netif/ppp/pppcrypt.c
Normal file
@ -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 <errno.h>
|
||||
#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 */
|
48
src/netif/ppp/pppcrypt.h
Normal file
48
src/netif/ppp/pppcrypt.h
Normal file
@ -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 <crypt.h>
|
||||
#endif
|
||||
|
||||
#ifndef USE_CRYPT
|
||||
#include <des.h>
|
||||
#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 */
|
913
src/netif/ppp/pppd.h
Normal file
913
src/netif/ppp/pppd.h
Normal file
@ -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 <stdio.h> /* for FILE */
|
||||
#include <limits.h> /* for NGROUPS_MAX */
|
||||
#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
|
||||
#include <sys/types.h> /* for u_int32_t, if defined */
|
||||
#include <sys/time.h> /* for struct timeval */
|
||||
#include <net/ppp_defs.h>
|
||||
#include "patchlevel.h"
|
||||
|
||||
#if defined(__STDC__)
|
||||
#include <stdarg.h>
|
||||
#define __V(x) x
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#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__ */
|
@ -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 */
|
||||
|
1110
src/netif/ppp/pppmy.c
Normal file
1110
src/netif/ppp/pppmy.c
Normal file
File diff suppressed because it is too large
Load Diff
121
src/netif/ppp/pppmy.h
Normal file
121
src/netif/ppp/pppmy.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* pppmy.h
|
||||
*
|
||||
* Created on: May 12, 2012
|
||||
* Author: gradator
|
||||
*/
|
||||
|
||||
#ifndef PPPMY_H_
|
||||
#define PPPMY_H_
|
||||
|
||||
#include <syslog.h> /* 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_ */
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 98-06-03 Guy Lancaster <lancasterg@acm.org>, 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 <string.h>
|
||||
|
||||
#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 */
|
@ -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 <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 98-05-29 Guy Lancaster <glanca@gesn.com>, 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 */
|
@ -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.
|
||||
|
423
src/netif/ppp/session.c
Normal file
423
src/netif/ppp/session.c
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <crypt.h>
|
||||
#ifdef HAS_SHADOW
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <utmp.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "pppd.h"
|
||||
#include "session.h"
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#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;
|
||||
}
|
||||
}
|
91
src/netif/ppp/session.h
Normal file
91
src/netif/ppp/session.h
Normal file
@ -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
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* 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
|
172
src/netif/ppp/sha1.c
Normal file
172
src/netif/ppp/sha1.c
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
|
||||
*
|
||||
* SHA-1 in C
|
||||
* By Steve Reid <steve@edmweb.com>
|
||||
* 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 <string.h>
|
||||
#include <netinet/in.h> /* htonl() */
|
||||
#include <net/ppp_defs.h>
|
||||
#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
|
||||
}
|
||||
|
31
src/netif/ppp/sha1.h
Normal file
31
src/netif/ppp/sha1.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* sha1.h */
|
||||
|
||||
/* If OpenSSL is in use, then use that version of SHA-1 */
|
||||
#ifdef OPENSSL
|
||||
#include <t_sha.h>
|
||||
#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_ */
|
||||
|
476
src/netif/ppp/spinlock.c
Normal file
476
src/netif/ppp/spinlock.c
Normal file
@ -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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#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
|
59
src/netif/ppp/spinlock.h
Normal file
59
src/netif/ppp/spinlock.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef __SPINLOCK_H__
|
||||
#define __SPINLOCK_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#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
|
2922
src/netif/ppp/sys-linux.c
Normal file
2922
src/netif/ppp/sys-linux.c
Normal file
File diff suppressed because it is too large
Load Diff
2011
src/netif/ppp/tdb.c
Normal file
2011
src/netif/ppp/tdb.c
Normal file
File diff suppressed because it is too large
Load Diff
164
src/netif/ppp/tdb.h
Normal file
164
src/netif/ppp/tdb.h
Normal file
@ -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 */
|
1264
src/netif/ppp/tty.c
Normal file
1264
src/netif/ppp/tty.c
Normal file
File diff suppressed because it is too large
Load Diff
684
src/netif/ppp/upap.c
Normal file
684
src/netif/ppp/upap.c
Normal file
@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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, "<hidden>");
|
||||
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;
|
||||
}
|
110
src/netif/ppp/upap.h
Normal file
110
src/netif/ppp/upap.h
Normal file
@ -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;
|
1056
src/netif/ppp/utils.c
Normal file
1056
src/netif/ppp/utils.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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 <string.h>
|
||||
|
||||
#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 */
|
Loading…
x
Reference in New Issue
Block a user