lcp.c
来自「在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LE」· C语言 代码 · 共 1,350 行 · 第 1/3 页
C
1,350 行
/*
* FILENAME: lcp.c
*
* Copyright 1997- 2001 By InterNiche Technologies Inc. All rights reserved
*
* PPP Link Control Protocol.
*
* MODULE: PPP
*
* ROUTINES: lcp_up(), lcp_down(), lcp_extcode(), lcp_resetci(),
* ROUTINES: lcp_addci(), lcp_ackci(), lcp_nakci(), lcp_rejci(), lcp_reqci(),
* ROUTINES: lcp_finished(), lcp_starting(),
*
*
* PORTABLE: yes
*/
/* Additional Copyrights: */
/* Portions Copyright (C) ARM Limited 1998,1999. All rights reserved.
* Portions Copyright 1996 by NetPort Software.
* Portions 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 "ipport.h"
#ifdef USE_PPP /* whole C file can be ifdeffed */
#include "ppp_port.h"
#include "mppp.h"
#define LCP_DEBUG 0
#if LCP_DEBUG > 0
#include "ZPrint.h"
#endif
/* Length of each type of configuration option (in octets) */
#define CILEN_VOID 2
#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */
#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */
#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */
#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */
#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
(x) == CONFNAK ? "NAK" : "REJ")
/* Set a static global default asyncmap which can be over-written by
* the application.
*/
u_long ppp_asyncmap_default = 0x000A0000;
/* overwritable globals */
int lcp_warnloops = 3;
int ppp_allow_ml = TRUE; /* enable multilink by default */
#ifndef NO_CONPRINTF
char * lcp_opts[] = {
"??",
"MRU",
"ASYNCMAP",
"AUTHTYPE",
"QUALITY",
"MAGIC",
"KEEPALIVE",
"PCOMP",
"ACCOMP", /* 8 */
#ifdef PPP_MULTILINK
"??", /* 9 */
"??", /* 10 */
"??", /* 11 */
"??", /* 12 */
"??", /* 13 */
"??", /* 14 */
"??", /* 15 */
"??", /* 16 */
"ML_MRU", /* 17 - Multilink MRU option */
"ML_SSN", /* 18 - Multilink Short Sequence Numbers */
"ML_ENDP", /* 19 - Multilink Endpoint ID */
#endif /* PPP_MULTILINK */
};
#endif /* NO_CONPRINTF */
/* FUNCTION: lcp_up()
*
* lcp_up - LCP has come UP.
* Start UPAP, IPCP, etc.
*
* PARAM1: M_PPP mppp
*
* RETURNS: void
*/
void
lcp_up(M_PPP mppp)
{
lcp_options * ho = &mppp->lcp_hisoptions;
/* set some mppp states from our negotiated LCP option set */
if (ho->neg_mru)
{
mppp->peer_mru = ho->mru;
if(mppp->ifp) /* an ML link will not always have an iface */
mppp->ifp->n_mtu = ho->mru; /* his MRU is our MTU */
}
if(mppp->lcp_gotoptions.neg_accompression) /* allow AC compression? */
mppp->sc_flags &= ~SC_REJ_COMP_AC; /* clear the reject bit */
/* if we negotiated async maps then overwrite the defaults */
if(mppp->lcp_gotoptions.neg_asyncmap)
{
mppp->his_asyncmap = mppp->lcp_hisoptions.asyncmap;
mppp->my_asyncmap = mppp->lcp_gotoptions.asyncmap;
}
#ifdef PAP_SUPPORT
/* If either side negotiated upap then set it as the auth protocol
* for this link.
*/
if((mppp->lcp_hisoptions.neg_upap) ||
(mppp->lcp_gotoptions.neg_upap))
{
mppp->auth = &upap_authtable;
}
#endif /* PAP_SUPPORT */
#ifdef CHAP_SUPPORT
/* If he negotiated CHAP then set it as the default authentication for this link.
* If we are server and negtiated CHAP also set it as default auth. This supports
* the case where we dialed in and negotiated CHAP, however he negotiated UPAP.
* Since he's the server, we must initiate a UPAP transaction before proceeding
* to IPCP. If this case the fact we negotiated CHAP is essentially a no-op.
*/
if(mppp->lcp_hisoptions.neg_chap)
{
mppp->auth = &ChapAuthTable;
}
else if((mppp->lcp_gotoptions.neg_chap) &&
(mppp->pppflags & PPP_SERVER))
{
mppp->auth = &ChapAuthTable;
}
#endif /* CHAP_SUPPORT */
/* if we will be using authentication, start it now, else
* start the IPCP layer
*/
if(mppp->auth)
{
/* kick off the auth protocol. These don't need an open call. */
ppp_lowerup(mppp, AUTH_STATE);
}
else /* No authentication, go direct to IPCP */
{
ppp_lowerup(mppp, IPCP_STATE);
}
return;
}
/* FUNCTION: lcp_down()
*
* lcp_down - LCP has gone DOWN.
* Alert other protocols.
*
* PARAM1: fsm *f
*
* RETURNS:
*/
void
lcp_down(M_PPP mppp)
{
//ConPrintf("LCP down.");
#if LCP_DEBUG
Printu("lcp_down\r\n");
#endif
/* If IPCP is currently negitiating or open then shut it down */
if(mppp->states[IPCP_STATE] >= ST_CLOSED)
{
#ifdef PPP_MULTILINK
/* This may just be Multilink Bundle LCP closing. If there are
* still other links in the bundle then don't shut down IPCP.
*/
if((mppp->pppflags & (ML_IPCP | ML_LCP)) == ML_LCP)
{
M_PPP bundle = mppp->ml_ipcp;
pppml_unlink(mppp); /* remove link from bundle */
mppp->pppflags &= ~ ML_LCP; /* link dead, remove link flag */
/* If master bundle IPCP still has links then return, else
* fall into code to give it a lowerdown.
*/
if(bundle->ml_links != NULL)
return;
mppp = bundle; /* set bundle for lowerdown call */
}
#endif /* PPP_MULTILINK */
ppp_close(mppp, IPCP_STATE);
ppp_lowerdown(mppp, IPCP_STATE);
}
else if(mppp->auth) /* else shut down auth layer */
{
mppp->auth->auth_lowerdown(mppp);
}
ppp_ifdown(mppp); /* interface is down */
/* if line is connected (or connecting, disconnecting, etc.) then
* start the disconnect:
*/
if((mppp->line.ln_state >= LN_CONNECTING) && (mppp->line.ln_disconnect))
mppp->line.ln_disconnect(&mppp->line);
return;
}
/* FUNCTION: lcp_extcode()
*
* lcp_extcode - Handle a LCP-specific code.
*
*
* PARAM1: M_PPP
* PARAM2: u_char code
* PARAM3: u_char id
* PARAM4: u_char * inp
* PARAM5: int len
*
* RETURNS:
*/
int
lcp_extcode(M_PPP mppp,
u_char code,
u_char id,
u_char * inp,
int len)
{
switch ( code )
{
case PROTREJ:
dtrap("lcp 0\n"); /* can a protocol reject still get here? later -JB- */
/*
lcp_rprotrej(mppp, inp, len);
*/
break;
case PECHOREQ:
if ( mppp->states[LCP_STATE] != ST_OPENED )
break;
//ConPrintf("lcp: Echo-Request, Rcvd id %d", id);
if ( len >= 4 )
{
/*
* replace the peer's magic number with ours, or with 0
* if we haven't negotiatied a magic number
*/
if ( mppp->lcp_gotoptions.neg_magicnumber )
ppp_putlong(inp, mppp->lcp_gotoptions.magicnumber);
else
ppp_putlong(inp, 0);
}
/* send the echo reply */
ppp_sendctl(mppp, LCP_STATE, PECHOREP,
inp, len, mppp->in_ids[LCP_STATE]);
break;
case PECHOREP:
case DISCREQ:
break;
default:
return 0;
}
return 1;
}
/* FUNCTION: lcp_resetci()
*
* lcp_resetci - Reset our CI to default values.
*
*
* PARAM1: fsm *f
*
* RETURNS: void
*/
void
lcp_resetci(M_PPP mppp)
{
lcp_options * lcp_wo = &mppp->lcp_wantoptions;
#if LCP_DEBUG
Printu("lcp_resetci\r\n");
#endif
/* fill in the lcp_options we will try for */
lcp_wo->passive = 0;
lcp_wo->silent = 0;
/* Set restart to non-zero in multi-line implementations */
lcp_wo->restart = 3;
lcp_wo->neg_mru = 1;
lcp_wo->mru = (short)ppp_mru;
lcp_wo->neg_asyncmap = 1;
lcp_wo->asyncmap = ppp_asyncmap_default;
/* If we are a server set up to ask for authentication, else don't */
if(mppp->pppflags & PPP_SERVER)
{
lcp_wo->neg_chap = 1; // ppp_debug
lcp_wo->neg_upap = 1; /// ppp_debug
lcp_wo->chap_mdtype = 5; /* CHAP_DIGEST_MD5; */
}
else
{
lcp_wo->neg_chap = 0;
lcp_wo->neg_upap = 0;
}
lcp_wo->neg_magicnumber = 1;
lcp_wo->neg_pcompression = 1;
lcp_wo->neg_accompression = 1;
lcp_wo->neg_lqr = 0;
#ifdef PPP_MULTILINK
if(mppp->pppflags |= ALLOW_ML)
{
lcp_wo->neg_ml_mru = 1;
lcp_wo->neg_ml_ssn = 0;
lcp_wo->neg_ml_endp = 1;
lcp_wo->neg_pcompression = 0;
lcp_wo->neg_accompression = 0;
lcp_wo->ml_mru = (u_short)ppp_mru;
}
else
{
lcp_wo->neg_ml_mru = 0;
lcp_wo->neg_ml_ssn = 0;
lcp_wo->neg_ml_endp = 0;
lcp_wo->ml_mru = 0;
}
#endif /* PPP_MULTILINK */
#ifdef USE_PPPOE /* hardcode some PPPOE requirements/limitations */
if(mppp->line.lower_type == LN_PPPOE)
{
lcp_wo->neg_asyncmap = 0; /* RFC disallows hdlc stuff */
lcp_wo->asyncmap = mppp->lcp_hisoptions.asyncmap = 0;
lcp_wo->neg_pcompression = 0; /* RFC disallows A & P compression */
lcp_wo->neg_accompression = 0;
lcp_wo->mru = min((short)ppp_mru, 1492); /* max MRU value from RFC */
}
#endif /* USE_PPPOE */
mppp->lcp_wantoptions.numloops = 0;
/* initialize "gotoptions" with a copy of "wantoptions" */
MEMCPY(&mppp->lcp_gotoptions, &mppp->lcp_wantoptions, sizeof(mppp->lcp_wantoptions));
mppp->peer_mru = (unshort)ppp_mtu;
}
/* FUNCTION: lcp_addci()
*
* lcp_addci - Add our desired CIs to a packet.
*
*
* PARAM1: mppp - our PPP connection
* PARAM2: u_char* ucp - next buyte in pkt
* PARAM3: int *lenp - length of ucp
*
* RETURNS: length of data in mppp->lastci[]
*/
int
lcp_addci(M_PPP mppp)
{
lcp_options * go = &mppp->lcp_gotoptions;
u_char * ucp; /* pointer to CONFREQ buffer */
int len;
#if LCP_DEBUG
Printu("lcp_addci\r\n");
#endif
ucp = &mppp->lastci[0];
if(go->neg_mru)
{
*ucp++ = CI_MRU;
*ucp++ = CILEN_SHORT;
ucp = ppp_putshort(ucp, go->mru);
}
if(go->neg_asyncmap)
{
*ucp++ = CI_ASYNCMAP;
*ucp++ = CILEN_LONG;
ucp = ppp_putlong(ucp, go->asyncmap);
}
#ifdef CHAP_SUPPORT
if(go->neg_chap)
{
*ucp++ = CI_AUTHTYPE;
*ucp++ = CILEN_CHAP;
ucp = ppp_putshort(ucp, PPP_CHAP);
*ucp++ = go->chap_mdtype;
}
#endif /* CHAP_SUPPORT */
#ifdef PAP_SUPPORT
if(!go->neg_chap && go->neg_upap)
{
*ucp++ = CI_AUTHTYPE;
*ucp++ = CILEN_SHORT;
ucp = ppp_putshort(ucp, PPP_UPAP);
}
#endif /* PAP_SUPPORT */
#ifdef PPP_MULTILINK
if(mppp->pppflags & ALLOW_ML)
{
if(go->neg_ml_mru) /* this signals ML ability too */
{
*ucp++ = CI_ML_MRU;
*ucp++ = 4; /* length of option field */
ucp = ppp_putshort(ucp, go->ml_mru);
}
if(go->neg_ml_ssn)
{
*ucp++ = CI_ML_SSN;
*ucp++ = 2; /* length of option field */
}
if(go->neg_ml_endp)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?