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 + -
显示快捷键?