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:
Sylvain Rochet 2012-05-16 02:02:02 +02:00
parent b56a1501d2
commit eb75ae05c6
80 changed files with 33979 additions and 10684 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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

File diff suppressed because it is too large Load Diff

52
src/netif/ppp/ccp.h Normal file
View 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
View 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
View 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
View 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
View 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;

View File

@ -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 */

View File

@ -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
View 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
View 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__ */

View File

@ -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 */

View File

@ -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
View 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

File diff suppressed because it is too large Load Diff

158
src/netif/ppp/eap.h Normal file
View 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
View 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
View 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
View 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__ */

File diff suppressed because it is too large Load Diff

View File

@ -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) */

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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 é 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

File diff suppressed because it is too large Load Diff

94
src/netif/ppp/ipxcp.h Normal file
View 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;

File diff suppressed because it is too large Load Diff

View File

@ -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

View 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_ */

View 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

View 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 */

View 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_ */

View File

@ -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

View File

@ -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
View 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
View 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)***********************************/

View File

@ -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) ********************************
*/

View File

@ -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
View 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
View 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
View 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_ */

View 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 */

View 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
View 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 */

View 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_ */

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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 */

View File

@ -0,0 +1,2 @@
#define VERSION "2.4.5"
#define DATE "17 November 2009"

65
src/netif/ppp/pathnames.h Normal file
View 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 */

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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 */

View File

@ -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
View 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
View 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
View 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__ */

View File

@ -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

File diff suppressed because it is too large Load Diff

121
src/netif/ppp/pppmy.h Normal file
View 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_ */

View File

@ -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 */

View File

@ -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 */

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

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
View 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

File diff suppressed because it is too large Load Diff

684
src/netif/ppp/upap.c Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

View File

@ -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 */