⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipcp.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * FILENAME: ipcp.c
 *
 * Copyright 1997- 2001 By InterNiche Technologies Inc. All rights reserved
 *
 * PPP IP Control Protocol
 *
 * MODULE: PPP
 *
 * ROUTINES: ipcp_resetci(), ipcp_addci(), ipcp_ackci(), 
 * ROUTINES: ipcp_nakci(), ipcp_rejci(), ipcp_reqci(), ipcp_up(), 
 * ROUTINES: ipcp_down(), ipcp_started(), ipcp_finished
 *
 * PORTABLE: yes
 */

/* Additional Copyrights: */

/* 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 IPCP_DEBUG        0
#if IPCP_DEBUG > 0
#include "ZPrint.h"
#endif
int   allow_ipset = TRUE;


/* Lengths of configuration options. */
#define  CILEN_VOID        2
#define  CILEN_COMPRESS    4  /* min length for compression protocol opt. */
#define  CILEN_VJ          6  /* length for RFC1332 Van-Jacobson opt. */
#define  CILEN_ADDR        6  /* new-style single address option */
#define  CILEN_ADDRS       10 /* old-style dual address option */
#define  CILEN_DNSADDR     6  /* RFC 1877 domain name server address length */


#define CODENAME(x)   ((x) == CONFACK ? "ACK" : \
          (x) == CONFNAK ? "NAK" : "REJ")


/* FUNCTION: ipcp_resetci()
 *
 * ipcp_resetci - Reset our CI.
 *
 * 
 * PARAM1: M_PPP mppp
 *
 * RETURNS: 
 */

void
ipcp_resetci(M_PPP mppp)
{
   ipcp_options * wo = &mppp->ipcp_wantoptions;

   /* Fill in the ipcp_options we will try for */
   wo->neg_addr = 1;
   wo->old_addrs = 0;
   if(mppp->ifp)
      wo->ouraddr = mppp->ifp->n_ipaddr;   /* in net endian */
   else
      wo->ouraddr = 0;
   wo->hisaddr = 0;
   wo->old_vj = 0;
   wo->vj_protocol = IPCP_VJ_COMP;
   wo->maxslotindex = MAX_STATES - 1;  /* really max index */
   wo->cflag = 1;

#ifdef PPP_VJC
   wo->neg_vj = 1;      /* ask for VJ compression if build supports it */
#else
   wo->neg_vj = 0;      /* else don't ask */
#endif

#if defined (USE_PPPOE) && defined (PPP_VJC)
   if(mppp->line.lower_type == LN_PPPOE)
   {
      /* VJ over PPPOE is legal, but it's really slow */
      //ConPrintf("Disabling VJ over PPPOE link %lx\n", mppp);
      wo->neg_vj = 0;
   }
#endif   /* USE_PPPOE */

   wo->req_addr = wo->neg_addr;

   /* allow our IP address to be set if it is 0.0.0.0 OR we are client */
   if ((wo->ouraddr == 0) || ((mppp->pppflags & PPP_SERVER) == FALSE ))
   {
      wo->accept_local = 1;
   }

   if (wo->hisaddr == 0)
      wo->accept_remote = 1;
   MEMCPY(&mppp->ipcp_gotoptions, wo, sizeof(*wo));
   mppp->cis_received[IPCP_STATE] = 0;
}



/* FUNCTION: ipcp_addci()
 *
 * ipcp_addci - Build our desired CIs in mppp->lastci buffer. The buffer
 * should be at least MAX_CILEN long. 
 *
 * PARAM1: M_PPP mppp
 *
 * RETURNS: length of config option string
 */


#ifdef NPDEBUG
/* Macro to make sure passed buffer has room for this option */
#define CHECK_CI_LEN(cilen) \
      if (len < cilen) {dtrap("ipcp 1\n"); goto addci_done; }
#else
#define CHECK_CI_LEN(fu)  /* define away to nothing */
#endif /* NPDEBUG */

int
ipcp_addci(M_PPP mppp)
{
   int      len;     /* space left in passed buffer */
   int      optlen;  /* length of current option string */
   u_char   opt;
   u_char * ucp;
   u_long   longval;

   ipcp_options * go = &mppp->ipcp_gotoptions;
   #if IPCP_DEBUG
   Printu("ipcp_addci\r\n");
   #endif
#ifdef PPP_OLDFORMS
   ipcp_options * wo = &mppp->ipcp_wantoptions;
   ipcp_options * ho = &mppp->ipcp_hisoptions;

   /*
    * First see if we want to change our options to the old
    * forms because we have received old forms from the peer.
    */
   if (wo->neg_addr && !go->neg_addr && !go->old_addrs) 
   {
      /* use the old style of address negotiation */
      go->neg_addr = 1;
      go->old_addrs = 1;
   }
   if (wo->neg_vj && !go->neg_vj && !go->old_vj) 
   {
      /* try an older style of VJ negotiation */
      if (mppp->cis_received[IPCP_STATE] == 0) 
      {
         /* keep trying the new style until we see some CI from the peer */
         go->neg_vj = 1;
      }
      else 
      {
         /* use the old style only if the peer did */
         if (ho->neg_vj && ho->old_vj) 
         {
            go->neg_vj = 1;
            go->old_vj = 1;
            go->vj_protocol = ho->vj_protocol;
         }
      }
   }
   if (go->old_addrs)
   {
      /* set up for older form of addr option */
      opt = CI_ADDRS;
      optlen = CILEN_ADDRS;
   }
   else
#endif   /* PPP_OLDFORMS */
   {
      /* set up for current form of addr option */
      opt = CI_ADDR;
      optlen = CILEN_ADDR;
   }

   /* build reply in mppp's scratch buffer */
   ucp = mppp->lastci;
   len = MAX_CILEN;

   if (go->ouraddr == 0L) { /*ConPrintf("ipcp_addci: ouraddr==0.0.0.0\n");*/ }

   /* start building the IPCP ci list in passed buffer. Address first.
    * "optlen" was set above.
    */
   if (go->neg_addr) 
   {
      CHECK_CI_LEN(optlen);
      *ucp++ = opt;
      *ucp++ = (u_char)optlen;
      /* convert IP address to local endian for putlong() call */
      longval = ntohl(go->ouraddr);
      ppp_putlong(ucp, longval);
      ucp += 4;
#ifdef PPP_OLDFORMS
      if (go->old_addrs) 
      {
         longval = ntohl(go->hisaddr);
         ppp_putlong(ucp, longval);
         ucp += 4;
      }
#endif   /* PPP_OLDFORMS */
      len -= optlen;
   }


   if(go->neg_vj)
   {
#ifdef PPP_OLDFORMS
      optlen = go->old_vj? CILEN_COMPRESS : CILEN_VJ;
#else
      optlen = CILEN_VJ;
#endif
      CHECK_CI_LEN(optlen);
      *ucp++ = CI_COMPRESSTYPE;
      *ucp++ = (u_char)optlen;
      ppp_putshort(ucp, go->vj_protocol);
      ucp += 2;
      if (!go->old_vj)
      {
         *ucp++ = go->maxslotindex;
         *ucp++ = go->cflag;
      }
      len -= optlen;
   }


#ifdef PPP_DNS
   if (go->neg_dnsaddr_pri)
   {
      CHECK_CI_LEN(CILEN_DNSADDR);
      *ucp++ = CI_DNSADDR_PRI;
      *ucp++ = CILEN_DNSADDR;
      longval = ntohl(go->dnsaddr_pri);
      ppp_putlong(ucp, longval);
      ucp += 4;
      len -= CILEN_DNSADDR;
   }

   if (go->neg_dnsaddr_sec)
   {
      CHECK_CI_LEN(CILEN_DNSADDR);
      *ucp++ = CI_DNSADDR_SEC;
      *ucp++ = CILEN_DNSADDR;
      longval = ntohl(go->dnsaddr_sec);
      ppp_putlong(ucp, longval);
      ucp += 4;
      len -= CILEN_DNSADDR;
   }
#endif   /* PPP_DNS */

#ifdef NPDEBUG
addci_done:
#endif

#ifdef NPDEBUG
   if(len > MAX_CILEN)
   {
      dtrap("ipcp 0\n");    /* reserved mppp->lastci[] buffer too small */
   }
#endif
   
   return(MAX_CILEN - len);   /* size of options */
}


/* FUNCTION: ipcp_ackci()
 *
 * ipcp_ackci - Check an Ack our our previous CIs.
 *
 * 
 * PARAM1: M_PPP mppp
 * PARAM2: u_char * p
 * PARAM3: int len
 *
 * RETURNS:  0 - Ack was good, or 1 - Ack was bad.
 */

int
ipcp_ackci(M_PPP mppp, u_char * p, int len)
{

  if(MEMCMP(p, mppp->lastci, len) == 0) 
   
      return 0;
   
  
   else
      return 1;
}


/* FUNCTION: ipcp_nakci()
 *
 * ipcp_nakci - Peer has sent a NAK for some of our CIs.
 * This should not modify any state if the Nak is bad
 * or if IPCP is in the OPENED state.
 *
 * PARAM1: M_PPP mppp
 * PARAM2: u_char * p
 * PARAM3: int len
 *
 * RETURNS:  0 if Nak was good or 1 if Nak was bad.
 */

int
ipcp_nakci(M_PPP mppp, u_char * p, int len)
{
   u_char   cimaxslotindex =  0;
   u_char   cicflag  =  0;
   u_char   cilen;
   u_short  cishort;
   u_long   ciaddr1;
   u_long   ciaddr2;
   ulong    longval;
   ipcp_options tryfor;   /* options to request next time */
   /* options we have currently (i.e. got last time) */
   ipcp_options * go = &mppp->ipcp_gotoptions;

   #if IPCP_DEBUG
   Printu("ipcp_nakci\r\n");
   #endif
   MEMCPY(&tryfor, go, sizeof(*go) );   /* init "tryfor" to "go" */

   while(len > 0)
   {
      cilen = *(p + 1);
      switch(*p)
      {
      case CI_ADDR:
         if(go->neg_addr == 0)
            tryfor.neg_addr = 1;
         /* Accept the peer's idea of {our,his} address, if different
          * from our idea, only if the accept_{local,remote} flag is set.
          */
         longval = ppp_getlong(p + 2); /* extract our address */
         /* convert getlong() result back to net endian for storage */
         ciaddr1 = htonl(longval);
        #if IPCP_DEBUG
	 Printu("ciaddr1:%xc\tilen:%x\r\n",ciaddr1,cilen);
	 #endif
#ifdef PPP_OLDFORMS
         if (go->old_addrs)         /* old address command? */
         {
            tryfor.old_addrs = 1;
            longval = ppp_getlong(p);
            p += 4;
            ciaddr2 = htonl(longval);  /* extract his address */
            if(cilen != CILEN_ADDRS)
               return 1;   /* bad packet */
         }
         else   /* new address command, sets our address only */
#endif   /* PPP_OLDFORMS */
         {
            if(cilen != CILEN_ADDR)
               return 1;   /* bad packet */
            ciaddr2 = 0;   /* flag his as 0 for now */
         }

         if (ciaddr1 && go->accept_local) /* Will we allow this? */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -