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

📄 pppfsm.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 3 页
字号:
   /* Initially, don't let line driver auto-decompress incoming 
    * comp/ac bytes. 
    */
   mppp->sc_flags |= SC_REJ_COMP_AC;   /* set reject bit */

   /* Clear settings from previous connections on this structure */
   mppp->bad_fcs = 0;
   mppp->io_errors = 0;
   mppp->tmo_tick = 0;
   mppp->tmr_sets = 0;
   mppp->tmr_cleared = 0;
   mppp->tmr_fired = 0;
   mppp->bytes_in = 0;
   mppp->pkts_in = 0;
   mppp->bytes_out = 0;
   mppp->pkts_out = 0;
   mppp->pppflags = 0;
   mppp->auth = NULL;

   return;
}

/* FUNCTION: ppp_sendctl()
 * 
 * PPP control packet send routine 
 * copy code & data to packet buffer and send via link 
 *
 * PARAM1: M_PPP mppp      - session on which to send
 * PARAM2: int pcode       - protocol to send (LCP, ICMP, etc)
 * PARAM3: u_char code     - packet code (CONREQ, CONFNAK, etc)
 * PARAM4: u_char * data   - data to attach or NULL if none.
 * PARAM5: int len         - length of data if data in non-NULL
 * PARAM6: u_char Id       - Id of packet to send
 *
 * RETURNS: 0 if OK or ENP_  error code
 */


unshort ppp_prots[2] = 
{
   PPP_LCP,
   PPP_IPCP,
};

   
int
ppp_sendctl(M_PPP mppp, int pcode, u_char code, u_char * data, int len, u_char Id)
{
   PACKET   pkt;
   u_char * p;

   /* get a packet big enough for data and various headers */
   LOCK_NET_RESOURCE(FREEQ_RESID);
   pkt = pk_alloc(len + 6 + MaxLnh);
   UNLOCK_NET_RESOURCE(FREEQ_RESID);
   if(!pkt)
      return ENP_NOBUFFER;

   /* build the PPP header in the send packet. Auth pprotocols build
    * their own headers, so skip them.
    */
   p = (u_char*)pkt->nb_prot;    /* build packet in send buffer */
   if(pcode != AUTH_STATE)
   {
      p = ppp_putshort(p, ppp_prots[pcode]);
      *p++ = code;
      *p++ = Id;
      p = ppp_putshort(p, (unshort)(len + 4));
      pkt->nb_plen = 6;          /* pkt now has 6 bytes of  header */
   }
   if(data)                      /* copy in any data passed, like */
   {
      MEMCPY(p, data, len);      /* the CI option string or auth pkt */
      pkt->nb_plen += len;
   }

   putq(&mppp->fastq, (qp)pkt);  /* Into the control pkt output queue */
   return(ppp_allpktsend(mppp));
}


/* FUNCTION: ppp_allpktsend()
 * 
 * ppp_allpktsend - Try to initiate the next send operation for the ppp
 * link. This should be called each time a packet is placed in one of the 
 * PPP send queues and also whenever a send completes.
 *
 * PARAM1: M_PPP mppp
 *
 * RETURNS: 0 if OK or ENP_ error code.
 */

int
ppp_allpktsend(M_PPP mppp)
{
   PACKET      pkt;
   int         datapkt;    /* bool for control or data */
   unshort     prot;
   struct ip * pip;

   if(mppp->pppflags & PPP_SENDING)    /* currently sending on this link? */
      return 0;

   /* check queues for packets to send. First check the "fast" queue,
    * where the control (LCP, IPCP) packets get queued for sending and
    * send from this queue first. If there are no control packet then
    * check for data (IP) packets. Before sending data packets make
    * sure IPCP has come up on the link. Also try to VJ compress them
    * at this point.
    */

   if(mppp->fastq.q_len)
   {
      pkt = (PACKET)getq(&mppp->fastq);
      datapkt = FALSE;
   }
   else if(mppp->dataq.q_len)   /* got IP? */
   {
      /* handle case where the link is still connecting */
      if(mppp->states[IPCP_STATE] != ST_OPENED)
         return ENP_SEND_PENDING;   /* can't send IP pkt yet */

      datapkt = TRUE;
      pkt = (PACKET)getq(&mppp->dataq);
      pip = (struct ip *)(pkt->nb_prot + 2);
      prot = ppp_getshort((u_char*)pkt->nb_prot);  /* get PPP prot */

      /* Handle case where DHCP is still trying to get an IP address */
      if(mppp->ifp->n_ipaddr == 0)
      {
         /* put non broadcast pkts back in the queue; fall though
          * to send broadcasts (maybe DHCP pkts)
          */
         if((pip->ip_dest != 0xFFFFFFFF) &&
            (pip->ip_dest != mppp->ifp->n_netbr42))
         {
         //   ConPrintf("allpktsend - DHCP pending?\n");
            putq(&mppp->dataq, (qp)pkt);     /* return pkt to dataq */
            return ENP_SEND_PENDING;
         }
      }

      /* Handle case where the dequeued IP packet originated on this machine
       * before the link was up and thus was assigned a source IP address of 
       * zero.
       */
      if(pip->ip_src == 0)       /* if src IP is zero... */
         ppp_set_ipaddr(pkt);    /* stuff ifaces IP as source */

#ifdef USE_MODEM
      /* Save IP info of this packet to assist in detecting
       * looped-back modems, VJ decisions, and DHCP packets.
       */
      if(prot == PPP_IP)
      {
         mppp->last_ip_src = pip->ip_src;
         mppp->last_ip_dest = pip->ip_dest;
         mppp->last_ip_id = pip->ip_id;
      }
#endif   /* USE_MODEM */
      
#ifdef PPP_VJC
      /* see if we should do VJ compression on this pkt */
      if((mppp->sc_flags & SC_COMP_TCP) &&   /* link doing VJ? */
         (prot == PPP_IP) &&                 /* pkt is IP? */
         (pip->ip_prot == 6))                /* is next layer TCP? */
      {
         pkt->nb_prot += 2;      /* bump pkt past prot code to IP */
         pkt->nb_plen -= 2;
         prot = vj_compress_tcp((u_char**)(&(pkt->nb_prot)),
            &(pkt->nb_plen),
            (struct vj_ip*)pip,
            &mppp->sc_comp,
            !(mppp->sc_flags & SC_NO_TCP_CCID));

         pkt->nb_prot -= 2;      /* bump pkt back to prot code slot */
         pkt->nb_plen += 2;      /* include code in size */
         ppp_putshort((u_char*)pkt->nb_prot, prot);   /* install VJ prot code */
      }
#endif   /* PPP_VJC */
   }
   else
      return 0;  /* nothing to do... */

   /* see if we need to dump pkt to log */
   //ConPrintf("link %p sending:", mppp);
   ppp_hexdump((u_char*)pkt->nb_prot, pkt->nb_plen);

#ifdef LOSSY_IO
   if(NDEBUG & LOSSY_TX)
   {
      if(in_lastloss++ == in_lossrate)
      {
         //ConPrintf("PPP LOSSY_IO dropping TX (link %p)\n", mppp);
         LOCK_NET_RESOURCE(FREEQ_RESID);
         pk_free(pkt);                 /* punt packet */
         UNLOCK_NET_RESOURCE(FREEQ_RESID);
         in_lastloss = (int)(cticks & 0x07) - 4;  /* pseudo random reset */
         return 0;                     /* act as if we sent OK */
      }
   }
#endif   /* LOSSY_IO */

   if(mppp->line.ln_state != LN_CONNECTED)
   {
      //ConPrintf("ppp_allpktsend (%p): lost line\n", mppp);
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free(pkt);
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
      return ENP_SENDERR;
   }

#ifdef PPP_MULTILINK
   /* for multilink connections see if we should fragment it */
   if((mppp->pppflags & ML_IPCP) &&    /* It's a ML bundle */
      (datapkt) &&                     /* and it's not a control pkt */
      (mppp->ml_numlinks > 1) &&       /* and we have multile links up */
      (pkt->nb_plen > mppp->ml_frag_size))   /* and it's a big pkt */
   {
      return( pppml_sendpkt(mppp, pkt) );
   }
#else
   USE_ARG(datapkt);
#endif /* PPP_MULTILINK */

   return(ppp_lower_send(mppp, pkt));

}

/* FUNCTION: ppp_lower_send()
 * 
 * lowest level pkt oriented send routine. ML can use this to 
 * send fragments. This either passed the packet to the line pkt
 * sender or to the PPP HDLC-like char code handler.
 *
 * PARAM1: M_PPP mppp
 * PARAM2: PACKET pkt
 *
 * RETURNS: 0 if OK, or error code from line call.
 */

int
ppp_lower_send(M_PPP mppp, PACKET pkt)
{
   int err;

   /* send packet. If the line supports a packet send routine then use it, 
    * else send it a byte at a time and free the packet.
    */
   #if PPPFSM_DEBUG
   Printu("\r\n=======ppp_lower_send======\r\n");
   PrintString('x',pkt->nb_prot,pkt->nb_plen);
   Printu("\r\n================================\r\n");
   #endif
   mppp->pppflags |= PPP_SENDING;      /* set sending flag bit */

   if(mppp->line.ln_write)
      err = mppp->line.ln_write(&mppp->line, pkt);
   else
   {
#ifdef PPP_CHARIO
      err = ppp_sendchars(mppp, pkt);
#else
      dtrap("pppfsm 4\n");    /* bad configuration */
      err = ENP_LOGIC;
#endif   /* PPP_CHARIO */
   }
   
   if(err == 0)
   {
      mppp->pkts_out++;
      mppp->bytes_out += pkt->nb_plen;
   }

   mppp->pppflags &= ~PPP_SENDING;      /* clear sending flag bit */   
   return err;   /* OK return */
}

/* externally callable PPP FSM state change routines */

/* FUNCTION: ppp_lowerup()
 * 
 * PARAM1: M_PPP mppp   - session for state change
 * PARAM2: int pcode    - code for protocol we want to start.
 *
 * RETURNS: void
 */


void
ppp_lowerup(M_PPP mppp, int pcode)
{
   //ConPrintf("lowerup: (link %p) %s\n", mppp, prots[pcode]);
   
   switch (pcode)
   {
   
   case IPCP_STATE:
        //break;/////ppp_debug
     /* this handles complicating conditions like us being the server
      * and membership in a multilink bundle.
      */
#ifdef PPP_MULTILINK
      /* See if this is LCP joining an existing Multilink Bundle. */
      if(mppp->lcp_hisoptions.neg_ml_mru)
      {
         /* Add link to bundle. If it joined an existing bundle then 
          * don't start IPCP on this mppp.
          */
         if(pppml_link(mppp) != 0)     
            return;
      }
#endif   /* PPP_MULTILINK */

      ppp_fsm(mppp, pcode, EV_UP, NULL, 0);

      /* If we're server then do the open too. */
      if(mppp->pppflags & PPP_SERVER)
         ppp_open(mppp, IPCP_STATE);

#ifdef PPP_MAKEPEERADDR
      /* If we don't have an address for the peer,
       * then make one up in case that we can hand out if asked.
       * We do this by making a delta of one from our IP interface's 
       * IP address -- +1 if that won't lead to an all-ones host address,
       * else -1.
       * This may not be the right thing to do, so use it with care!
       * ...but it sometimes works well for point-to-point links.
       */
      if ((mppp->pppflags & PPP_SERVER) &&
          (mppp->ipcp_wantoptions.hisaddr == 0) &&
          (mppp->ifp) && (mppp->ifp->n_ipaddr))
      {
         ip_addr tmpip = ntohl(mppp->ifp->n_ipaddr);

         if ((tmpip & 0x000000ff) > 253)
            mppp->ipcp_wantoptions.hisaddr = htonl(tmpip - 1);
         else
            mppp->ipcp_wantoptions.hisaddr = htonl(tmpip + 1);
      }
#endif   /* PPP_MAKEPEERADDR */

      break;
   case AUTH_STATE:
      /* Authentication protocls have their own state machines.
       * start the authentication now. When complete this will do the
       * lowerup call for IPCP.
       */
      mppp->auth->auth_init(mppp);
      mppp->auth->auth_lowerup(mppp);

      if(mppp->pppflags & PPP_SERVER)
         mppp->auth->auth_peer(mppp);
      else
         mppp->auth->auth_with_peer(mppp);
      break;
   case LCP_STATE:
      ppp_fsm(mppp, pcode, EV_UP, NULL, 0);
      break;
   default:
      dtrap("pppfsm 5\n");    /* bad protocol index code */
   }
   return;
}


/* FUNCTION: ppp_lowerdown()
 * 
 * PARAM1: M_PPP mppp   - session for state change
 * PARAM2: int pcode    - code for protocol we want to shut down.
 *
 * RETURNS: void
 */

void
ppp_lowerdown(M_PPP mppp, int pcode)
{
   //ConPrintf("lowerdown (link %p): %s\n", mppp, prots[pcode]);

   /* do this layer's FSM actions for lowerdown */
   ppp_fsm(mppp, pcode, EV_DOWN, NULL, 0);
}

/* FUNCTION: ppp_open()
 * 
 * PARAM1: M_PPP mppp   - session for state change
 * PARAM2: int pcode    - code for protocol we want to open.
 *
 * RETURNS: void
 */

void
ppp_open(M_PPP mppp, int pcode)
{
   //ConPrintf("open (link %p): %s\n", mppp, prots[pcode]);

#ifdef PPP_MULTILINK
   /* if this is an IPCP open and the link is a multilink slave, 
    * then ignore this and don't open the IPCP layer.
    */
   if((pcode == IPCP_STATE) && 
      ((mppp->pppflags & (ALLOW_ML|ML_IPCP|ML_LCP)) == (ALLOW_ML|ML_LCP)))
   {
      return;
   }
#endif

   /* do this layer's FSM actions for open */
   ppp_fsm(mppp, pcode, EV_OPEN, NULL, 0);
}


/* FUNCTION: ppp_close()
 * 
 * PARAM1: M_PPP mppp   - session for state change
 * PARAM2: int pcode    - code for protocol we want to close.
 *
 * RETURNS: void
 */

void
ppp_close(M_PPP mppp, int pcode)
{
   //ConPrintf("close (link %p): %s\n", mppp, prots[pcode]);

   /* flush any packets stuck in the data queue */
   while(mppp->dataq.q_head)
   {
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free((PACKET)getq(&mppp->dataq));
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
   }

   /* clear the sending flag in case he thinks he's sending. */
   mppp->pppflags &= ~PPP_SENDING;

   /* do this layer's FSM actions for close */
   ppp_fsm(mppp, pcode, EV_CLOSE, NULL, 0);
}


/* FUNCTION: ppp_hexdump()
 * 
 * PARAM1: u_char *b
 * PARAM2: int l
 *
 * RETURNS: void
 */

int  ppp_hexmax = 100;      /* MAX length of debug hexdumps */

void
ppp_hexdump(u_char * b, int length)
{
#ifndef PPP_NOHEXDUMP
   if(ppp_hexmax == 0)
      return;
   if(length > ppp_hexmax)
      length = ppp_hexmax;

   /* If logging is on then ConPrintf hexdump of the pkt */
   if((PPPDEBUG & (PPPD_CONS | PPPD_FILE)) != 0)
   {
      while(length--) ;
      //   ConPrintf("%02x ", *b++);
      //ConPrintf("\n");
   }
#else
   USE_ARG(b);
#endif   /* PPP_NOHEXDUMP */
}


#endif /*  USE_PPP  whole file */


⌨️ 快捷键说明

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