Пример #1
0
void ipcp_rx(struct ppp_context_s *ctx, u8_t *buffer, u16_t count)
{
  u8_t *bptr = buffer;
  //IPCPPKT *pkt=(IPCPPKT *)buffer;
  u16_t len;

  DEBUG1(("IPCP len %d\n",count));

  switch (*bptr++)
  {
  case CONF_REQ:
    /* Parse request and see if we can ACK it */

    ++bptr;
    len = (*bptr++ << 8);
    len |= *bptr++;
    /* len-=2; */

    DEBUG1(("check lcplist\n"));
    if (scan_packet(ctx, IPCP, ipcplist, buffer, bptr, (u16_t)(len - 4)))
      {
        DEBUG1(("option was bad\n"));
      }
    else
      {
        DEBUG1(("IPCP options are good\n"));

        /* Parse out the results */
        /* lets try to implement what peer wants */
        /* Reject any protocol not */
        /* Error? if we we need to send a config Reject ++++ this is good for a subroutine*/
        /* All we should get is the peer IP address */

        if (IPCP_IPADDRESS == *bptr++)
          {
            /* Dump length */

            ++bptr;
#ifdef IPCP_GET_PEER_IP
            ((u8_t*)&ctx->peer_ip)[0] = *bptr++;
            ((u8_t*)&ctx->peer_ip)[1] = *bptr++;
            ((u8_t*)&ctx->peer_ip)[2] = *bptr++;
            ((u8_t*)&ctx->peer_ip)[3] = *bptr++;

            DEBUG1(("Peer IP "));
            /* printip(peer_ip_addr); */
            DEBUG1(("\n"));

            netlib_set_dripv4addr((char*)ctx->ifname, &ctx->peer_ip);
#else
            bptr += 4;
#endif
          }
        else
          {
            DEBUG1(("HMMMM this shouldn't happen IPCP1\n"));
          }

#if 0
        if (error)
          {
            /* Write the config NAK packet we've built above, take on the header */

            bptr = buffer;
            *bptr++ = CONF_NAK;        /* Write Conf_rej */
            *bptr++;
            /*tptr++;*/  /* skip over ID */

            /* Write new length */

            *bptr++ = 0;
            *bptr = tptr - buffer;

            /* Write the reject frame */

            DEBUG1(("Writing NAK frame \n"));
            ahdlc_tx(IPCP, buffer, (u16_t)(tptr - buffer));
            DEBUG1(("- End NAK Write frame\n"));
          }
        else
          {
          }
#endif
        /* If we get here then we are OK, lets send an ACK and tell the rest
         * of our modules our negotiated config.
         */

        ctx->ipcp_state |= IPCP_RX_UP;
        DEBUG1(("Send IPCP ACK!\n"));
        bptr = buffer;
        *bptr++ = CONF_ACK; /* Write Conf_ACK */
        bptr++;             /* Skip ID (send same one) */

        /* Set stuff */

        /* ppp_flags |= tflag; */
        DEBUG1(("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr - buffer)));

        /* Write the ACK frame */

        DEBUG1(("Writing ACK frame \n"));

        /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */

        ahdlc_tx(ctx, IPCP, 0, buffer, 0, count /*bptr-buffer*/);
        DEBUG1(("- End ACK Write frame\n"));
      }
    break;

  case CONF_ACK: /* config Ack */
    DEBUG1(("CONF ACK\n"));
    /* Parse out the results
     *
     * Dump the ID and get the length.
     */

    /* Dump the ID */

    bptr++;

    /* Get the length */

    len = (*bptr++ << 8);
    len |= *bptr++;

#if 0
    /* Parse ACK and set data */

    while (bptr < buffer + len)
      {
        switch (*bptr++)
        {
        case IPCP_IPADDRESS:
          /* Dump length */

          bptr++;
          ((u8_t*)ipaddr)[0] = *bptr++;
          ((u8_t*)ipaddr)[1] = *bptr++;
          ((u8_t*)ipaddr)[2] = *bptr++;
          ((u8_t*)ipaddr)[3] = *bptr++;
          break;

        case IPCP_PRIMARY_DNS:
          bptr++;
          ((u8_t*)pri_dns_addr)[0] = *bptr++;
          ((u8_t*)pri_dns_addr)[1] = *bptr++;
          ((u8_t*)pri_dns_addr)[2] = *bptr++;
          ((u8_t*)pri_dns_addr)[3] = *bptr++;
          break;

        case IPCP_SECONDARY_DNS:
          bptr++;
          ((u8_t*)sec_dns_addr)[0] = *bptr++;
          ((u8_t*)sec_dns_addr)[1] = *bptr++;
          ((u8_t*)sec_dns_addr)[2] = *bptr++;
          ((u8_t*)sec_dns_addr)[3] = *bptr++;
          break;

        default:
           DEBUG1(("IPCP CONFIG_ACK problem1\n"));
        }
      }
#endif

    ctx->ipcp_state |= IPCP_TX_UP;
    /*ppp_ipcp_state &= ~IPCP_RX_UP;*/

    DEBUG1(("were up! \n"));
    //printip(pppif.ipaddr);
#ifdef IPCP_GET_PRI_DNS
    printip(pri_dns_addr);
#endif
#ifdef IPCP_GET_SEC_DNS
    printip(sec_dns_addr);
#endif
    DEBUG1(("\n"));
    break;

  case CONF_NAK: /* Config Nack */
    DEBUG1(("CONF NAK\n"));

    /* Dump the ID */

    bptr++;

    /* Get the length */

    len = (*bptr++ << 8);
    len |= *bptr++;

    /* Parse ACK and set data */

    while (bptr < buffer + len)
      {
        switch (*bptr++)
        {
        case IPCP_IPADDRESS:
          /* dump length */
          bptr++;

          ((u8_t*)&ctx->local_ip)[0] = (char)*bptr++;
          ((u8_t*)&ctx->local_ip)[1] = (char)*bptr++;
          ((u8_t*)&ctx->local_ip)[2] = (char)*bptr++;
          ((u8_t*)&ctx->local_ip)[3] = (char)*bptr++;

          netlib_ifup((char*)ctx->ifname);
          netlib_set_ipv4addr((char*)ctx->ifname, &ctx->local_ip);
          //DEBUG1(("My PPP-ipno: (%d.%d.%d.%d)\n", ((u8_t*)pppif.ipaddr)[0], ((u8_t*)pppif.ipaddr)[1], ((u8_t*)pppif.ipaddr)[2], ((u8_t*)pppif.ipaddr)[3]));
          break;

#ifdef IPCP_GET_PRI_DNS
        case IPCP_PRIMARY_DNS:
          bptr++;
          ((u8_t*)&ctx->pri_dns_addr)[0] = *bptr++;
          ((u8_t*)&ctx->pri_dns_addr)[1] = *bptr++;
          ((u8_t*)&ctx->pri_dns_addr)[2] = *bptr++;
          ((u8_t*)&ctx->pri_dns_addr)[3] = *bptr++;
          break;
#endif

#ifdef IPCP_GET_SEC_DNS
        case IPCP_SECONDARY_DNS:
          bptr++;
          ((u8_t*)&ctx->sec_dns_addr)[0] = *bptr++;
          ((u8_t*)&ctx->sec_dns_addr)[1] = *bptr++;
          ((u8_t*)&ctx->sec_dns_addr)[2] = *bptr++;
          ((u8_t*)&ctx->sec_dns_addr)[3] = *bptr++;
          break;
#endif

        default:
          DEBUG1(("IPCP CONFIG_ACK problem 2\n"));
        }
      }

    ctx->ppp_id++;

    printip(pppif.ipaddr);
#ifdef IPCP_GET_PRI_DNS
    printip(pri_dns_addr);
#endif
#ifdef IPCP_GET_PRI_DNS
    printip(sec_dns_addr);
#endif
    DEBUG1(("\n"));
    break;

  case CONF_REJ: /* Config Reject */
    DEBUG1(("CONF REJ\n"));

    /* Remove the offending options*/

    ctx->ppp_id++;

    /* Dump the ID */

    bptr++;

    /* Get the length */

    len = (*bptr++ << 8);
    len |= *bptr++;

    /* Parse ACK and set data */

    while (bptr < buffer + len)
      {
        switch (*bptr++)
        {
        case IPCP_IPADDRESS:
          ctx->ipcp_state |= IPCP_IP_BIT;
          bptr += 5;
          break;

#ifdef IPCP_GET_PRI_DNS
        case IPCP_PRIMARY_DNS:
          ctx->ipcp_state |= IPCP_PRI_DNS_BIT;
          bptr += 5;
          break;
#endif

#ifdef IPCP_GET_PRI_DNS
        case IPCP_SECONDARY_DNS:
          ctx->ipcp_state |= IPCP_SEC_DNS_BIT;
          bptr += 5;
          break;
#endif

        default:
          DEBUG1(("IPCP this shoudln't happen 3\n"));
        }
      }
    break;

  default:
    DEBUG1(("-Unknown 4\n"));
  }
}
/*
 * IPCP RX protocol Handler
 */
void
ipv6cp_rx(u8_t *buffer, u16_t count)
{
  u8_t *bptr = buffer;
//  IPCPPKT *pkt=(IPCPPKT *)buffer;
  u16_t len;

  ANNOTATE("IPV6CP len %d\n",count);
	
  switch(*bptr++) {

  case CONF_REQ:
    /* parce request and see if we can ACK it */
    ++bptr;
    len = (*bptr++ << 8);
    len |= *bptr++;
    /* len-=2; */

    ANNOTATE("check lcplist\n");
    if(scan_packet(IPV6CP, ipv6cplist, buffer, bptr, (u16_t)(len - 4))) {
      UIP_LOG("option was bad\n");
    } else {
      ANNOTATE("IPV6CP options are good\n");
      /*
       * Parse out the results
       */
      /* lets try to implement what peer wants */
      /* Reject any protocol not */
      /* Error? if we we need to send a config Reject ++++ this is
	 good for a subroutine*/
      //GD-2011-09-15 None of the IPv6CP options are supported with current implementation.
#if 0
#warning option implementation example based on IPCP IPv4 address configuration.
      /* All we should get is the peer IP address */
      if(IPV6CP_IPADDRESS == *bptr++) {
	         /* dump length */
	         ++bptr;
         #ifdef IPV6CP_GET_PEER_IP
	         ((u8_t*)peer_ip_addr.u8)[0] = *bptr++;
	         ((u8_t*)peer_ip_addr.u8)[1] = *bptr++;
	         ((u8_t*)peer_ip_addr.u8)[2] = *bptr++;
	         ((u8_t*)peer_ip_addr.u8)[3] = *bptr++;
	         ANNOTATE("Peer IP ");
	         /*	printip(peer_ip_addr);*/
	         ANNOTATE("\n");
         #else
	         bptr += 18;
         #endif
      } else {
	      UIP_LOG("HMMMM this shouldn't happen IPV6CP1\n");
      }
#endif
      
#if 0			
      if(error) {
	      /* write the config NAK packet we've built above, take on the header */
	      bptr = buffer;
	      *bptr++ = CONF_NAK;		/* Write Conf_rej */
	      *bptr++;
	      /*tptr++;*/  /* skip over ID */

	      /* Write new length */
	      *bptr++ = 0;
	      *bptr = tptr - buffer;
	      
	      /* write the reject frame */
	      UIP_LOG("Writing NAK frame \n");
	      ahdlc_tx(IPV6CP, buffer, (u16_t)(tptr - buffer));
	      ANNOTATE("- End NAK Write frame\n");
	      
      } else {
      }
#endif
         /*
          * If we get here then we are OK, lets send an ACK and tell the rest
          * of our modules our negotiated config.
          */
         ipv6cp_state |= IPV6CP_RX_UP;
         ipv6cp_state &= ~IPV6CP_TX_UP;//phlb force send request with ipv6cp task
         ANNOTATE("Send IPV6CP ACK!\n");
         bptr = buffer;
         *bptr++ = CONF_ACK;		/* Write Conf_ACK */
         bptr++;				/* Skip ID (send same one) */
         /*
          * Set stuff
          */
         ppp_flags |= tflag;
         ANNOTATE("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer));
	   
         /* write the ACK frame */
         ANNOTATE("Writing ACK frame \n");
         /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen);	*/
         ahdlc_tx(IPV6CP, 0, buffer, 0, count /*bptr-buffer*/);
         ANNOTATE("- End ACK Write frame\n");
	   
         /* expire the timer to make things happen after a state change */
         TIMER_expire(); //timer_expire(); //modify phlb uncomment
	   
         /*			} */
    }
    break;
    
    //
  case CONF_ACK:			/* config Ack */
       ANNOTATE("CONF ACK\n");
       /*
        * Parse out the results
        *
        * Dump the ID and get the length.
        */
       /* dump the ID */
       bptr++;

       /* get the length */
       len = (*bptr++ << 8);
       len |= *bptr++;
   #if 0 //modify phlb 
       /* Parse ACK and set data */
       while(bptr < buffer + len) {
         switch(*bptr++) {
         case IPV6CP_IPADDRESS:
	   /* dump length */
	   bptr++;		
	   ((u8_t*)ipaddr)[0] = *bptr++;
	   ((u8_t*)ipaddr)[1] = *bptr++;
	   ((u8_t*)ipaddr)[2] = *bptr++;
	   ((u8_t*)ipaddr)[3] = *bptr++;
	   break;
         case IPV6CP_PRIMARY_DNS:
	   bptr++;
	   ((u8_t*)pri_dns_addr)[0] = *bptr++;
	   ((u8_t*)pri_dns_addr)[1] = *bptr++;
	   ((u8_t*)pri_dns_addr)[2] = *bptr++;
	   ((u8_t*)pri_dns_addr)[3] = *bptr++;
	   break;
         case IPV6CP_SECONDARY_DNS:
	   bptr++;
	   ((u8_t*)sec_dns_addr)[0] = *bptr++;
	   ((u8_t*)sec_dns_addr)[1] = *bptr++;
	   ((u8_t*)sec_dns_addr)[2] = *bptr++;
	   ((u8_t*)sec_dns_addr)[3] = *bptr++;
	   break;
         default:
	   UIP_LOG("IPV6CP CONFIG_ACK problem1\n");
         }
       }
   #endif
       ipv6cp_state |= IPV6CP_TX_UP;
       //ipv6cp_state &= ~IPV6CP_RX_UP;
       ANNOTATE("were up! \n");
       printip(pppif.ipaddr);
   #ifdef IPV6CP_GET_PRI_DNS
       printip(pri_dns_addr);
   #endif
   #ifdef IPV6CP_GET_SEC_DNS
       printip(sec_dns_addr);
   #endif
       ANNOTATE("\n");
		   
       /* expire the timer to make things happen after a state change */
       TIMER_expire();
    break;

    //
  case CONF_NAK:			/* Config Nack */
    UIP_LOG("CONF NAK\n");
    /* dump the ID */
    bptr++;
    /* get the length */
    len = (*bptr++ << 8);
    len |= *bptr++;

    /* Parse ACK and set data */
    while(bptr < buffer + len) {
      switch(*bptr++) {
#if 0
#warning option implementation example based on IPCP IPv4 address configuration.
               case IPV6CP_IPADDRESS:
	         /* dump length */
	         bptr++;
	         ((u8_t*)pppif.ipaddr.u8)[0] = *bptr++;
	         ((u8_t*)pppif.ipaddr.u8)[1] = *bptr++;
	         ((u8_t*)pppif.ipaddr.u8)[2] = *bptr++;
	         ((u8_t*)pppif.ipaddr.u8)[3] = *bptr++;
	         uip_fw_register( &pppif );
	         ANNOTATE("My PPP-ipno: (%d.%d.%d.%d)\n", ((u8_t*)pppif.ipaddr.u8)[0], ((u8_t*)pppif.ipaddr.u8)[1], ((u8_t*)pppif.ipaddr.u8)[2], ((u8_t*)pppif.ipaddr.u8)[3]); 
	         break;
#endif
         #ifdef IPV6CP_GET_PRI_DNS
               case IPV6CP_PRIMARY_DNS:
	         bptr++;
	         ((u8_t*)pri_dns_addr)[0] = *bptr++;
	         ((u8_t*)pri_dns_addr)[1] = *bptr++;
	         ((u8_t*)pri_dns_addr)[2] = *bptr++;
	         ((u8_t*)pri_dns_addr)[3] = *bptr++;
	         break;
         #endif
         #ifdef IPV6CP_GET_SEC_DNS
               case IPV6CP_SECONDARY_DNS:
	         bptr++;
	         ((u8_t*)sec_dns_addr)[0] = *bptr++;
	         ((u8_t*)sec_dns_addr)[1] = *bptr++;
	         ((u8_t*)sec_dns_addr)[2] = *bptr++;
	         ((u8_t*)sec_dns_addr)[3] = *bptr++;
	         break;
         #endif

            //
            default:
	            UIP_LOG("IPCP CONFIG_ACK problem 2\n");
          }
       }
       ppp_id++;
       printip(pppif.ipaddr);
   #ifdef IPV6CP_GET_PRI_DNS
       printip(pri_dns_addr);
   #endif
   #ifdef IPV6CP_GET_PRI_DNS
       printip(sec_dns_addr);
   #endif
       ANNOTATE("\n");
       /* expire the timer to make things happen after a state change */
       TIMER_expire();
       break;

     case CONF_REJ:			/* Config Reject */
       ANNOTATE("CONF REJ\n");
       /* Remove the offending options*/
       ppp_id++;
       /* dump the ID */
       bptr++;
       /* get the length */
       len = (*bptr++ << 8);
       len |= *bptr++;

       /* Parse ACK and set data */
       while(bptr < buffer + len) {
         switch(*bptr++) {
#if 0
#warning option implementation example based on IPCP IPv4 address configuration.
            case IPV6CP_IPADDRESS:
	         ipv6cp_state |= IPV6CP_IP_BIT;
	         bptr += 5;
	         break;
#endif

         #ifdef IPV6CP_GET_PRI_DNS
            case IPV6CP_PRIMARY_DNS:
	         ipv6cp_state |= IPV6CP_PRI_DNS_BIT;
	         bptr += 5;
	         break;
         #endif

         #ifdef IPV6CP_GET_PRI_DNS
             case IPV6CP_SECONDARY_DNS:
	         ipv6cp_state |= IPV6CP_SEC_DNS_BIT;
	         bptr += 5;
	         break;
         #endif

            default:
	         UIP_LOG("IPV6CP this shoudln't happen 3\n");
         }
    }
    /* expire the timer to make things happen after a state change */
    /*timer_expire(); */
    break;

    default:
      UIP_LOG("-Unknown 4\n");
  }
}
Пример #3
0
void lcp_rx(struct ppp_context_s *ctx, u8_t *buffer, u16_t count)
{
  u8_t *bptr = buffer, *tptr;
  u8_t error = 0;
  u8_t id;
  u16_t len, j;

  switch (*bptr++)
  {
  case CONF_REQ: /* config request */
    /* Parse request and see if we can ACK it */

    id = *bptr++;
    len = (*bptr++ << 8);
    len |= *bptr++;
    /*len -= 2;*/

    /* In case of new peer connection */

    ipcp_init(ctx);
    ctx->lcp_state &= ~LCP_TX_UP;

    DEBUG1(("received [LCP Config Request id %u\n", id));
    if (scan_packet(ctx, (u16_t)LCP, lcplist, buffer, bptr, (u16_t)(len-4)))
      {
        /* Must do the -4 here, !scan packet */

        DEBUG1((" options were rejected\n"));
      }
    else
      {
        /* Lets try to implement what peer wants */

        tptr = bptr = buffer;
        bptr += 4;            /* skip code, id, len */
        error = 0;

        /* First scan for unknown values */

        while(bptr < (buffer + len))
          {
            switch (*bptr++)
            {
            case LPC_MRU: /* mru */
              j = *bptr++;
              j -= 2;

              if (j == 2)
                {
                  ctx->ppp_tx_mru = ((int)*bptr++) << 8;
                  ctx->ppp_tx_mru |= *bptr++;
                  DEBUG1(("<mru %d> ", ctx->ppp_tx_mru));
                }
              else
                {
                  DEBUG1(("<mru ?? > "));
                }
              break;

            case LPC_ACCM:
              bptr++;  /* skip length */
              j = *bptr++;
              j += *bptr++;
              j += *bptr++;
              j += *bptr++;

              if (j==0)
                {
                  // ok
                  DEBUG1(("<asyncmap sum=0x%04x>",j));
                  //ahdlc_flags |= PPP_TX_ASYNC_MAP;
                }
              else if (j!=0)
                {
                  // ok
                  DEBUG1(("<asyncmap sum=0x%04x>, assume 0xffffffff",j));
                }
              else
                {
                  /* Fail.  We only support default or all zeros */

                  DEBUG1(("We only support default or all zeros for ACCM "));
                  error = 1;
                  *tptr++ = LPC_ACCM;
                  *tptr++ = 0x6;
                  *tptr++ = 0;
                  *tptr++ = 0;
                  *tptr++ = 0;
                  *tptr++ = 0;
                }
              break;

            case LPC_AUTH:
              bptr++;
              if ((*bptr++ == 0xc0) && (*bptr++ == 0x23))
                {
                  /* Negotiate PAP */

                  if (strlen((char*)ctx->pap_username) > 0)
                    {
                      DEBUG1(("<auth pap> "));
                      ctx->lcp_state |= LCP_RX_AUTH;
                    }
                  else
                    {
                      DEBUG1(("<rej auth pap> "));

                      *tptr++ = CONF_REJ;
                      tptr++;             // Keep ID
                      *tptr++ = 0;
                      *tptr++ = 8;
                      *tptr++ = LPC_AUTH;
                      *tptr++ = 0x4;
                      *tptr++ = 0xc0;
                      *tptr++ = 0x23;
                      ahdlc_tx(ctx, LCP, 0, buffer, 0, (u16_t)(tptr-buffer));
                      return;
                    }
                }
              else
                {
                  /* We only support PAP */

                  DEBUG1(("<auth ?? >"));
                  error = 1;
                  *tptr++ = LPC_AUTH;
                  *tptr++ = 0x4;
                  *tptr++ = 0xc0;
                  *tptr++ = 0x23;
                }
              break;

            case LPC_MAGICNUMBER:
              DEBUG1(("<magic > "));

              /* Compare incoming number to our number (not implemented) */

              bptr++; /* For now just dump */
              bptr++;
              bptr++;
              bptr++;
              bptr++;
              break;

            case LPC_PFC:
              bptr++;
              DEBUG1(("<pcomp> "));
              /*tflag|=PPP_PFC;*/
              break;

            case LPC_ACFC:
              bptr++;
              DEBUG1(("<accomp> "));
              /*tflag|=PPP_ACFC;*/
              break;
            }
          }

        /* Error? if we we need to send a config Reject ++++ this is good
         * for a subroutine.
         */

        if (error)
          {
            /* Write the config NAK packet we've built above, take on the
             * header
             */

            bptr = buffer;
            *bptr++ = CONF_NAK;        /* Write Conf_rej */
            bptr++;/*tptr++;*/        /* skip over ID */

            /* Write new length */

            *bptr++ = 0;
            *bptr = tptr - buffer;

            /* Write the reject frame */

            DEBUG1(("\nWriting NAK frame \n"));
            // Send packet ahdlc_txz(procol,header,data,headerlen,datalen);
            ahdlc_tx(ctx, LCP, 0, buffer, 0, (u16_t)(tptr-buffer));
            DEBUG1(("- end NAK Write frame\n"));
          }
        else
          {
            /* If we get here then we are OK, lets send an ACK and tell the rest
             * of our modules our negotiated config.
             */

            DEBUG1(("\nSend ACK!\n"));
            bptr = buffer;
            *bptr++ = CONF_ACK;  /* Write Conf_ACK */
            bptr++;              /* Skip ID (send same one) */

            /* Set stuff */

            /*ppp_flags|=tflag;*/
            /* DEBUG2("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer)); */

            /* Write the ACK frame */

            DEBUG2(("Writing ACK frame \n"));

            /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */

            ahdlc_tx(ctx, LCP, 0, buffer, 0, count /*bptr-buffer*/);
            DEBUG2(("- end ACK Write frame\n"));
            ctx->lcp_state |= LCP_RX_UP;
          }
      }
    break;

  case CONF_ACK: /* config Ack   Anytime we do an ack reset the timer to force send. */
    DEBUG1(("LCP-ACK - "));

    /* Check that ID matches one sent */

    if (*bptr++ == ctx->ppp_id)
      {
        /* Change state to PPP up. */

        DEBUG1((">>>>>>>> good ACK id up! %d\n", ctx->ppp_id));

        /* Copy negotiated values over */

        ctx->lcp_state |= LCP_TX_UP;
      }
    else
      {
        DEBUG1(("*************++++++++++ bad id %d\n", ctx->ppp_id));
      }
    break;

  case CONF_NAK: /* Config Nack */
    DEBUG1(("LCP-CONF NAK\n"));
    ctx->ppp_id++;
    break;

  case CONF_REJ: /* Config Reject */
    DEBUG1(("LCP-CONF REJ\n"));
    ctx->ppp_id++;
    break;

  case TERM_REQ: /* Terminate Request */
    DEBUG1(("LCP-TERM-REQ -"));
    bptr = buffer;
    *bptr++ = TERM_ACK; /* Write TERM_ACK */

    /* Write the reject frame */

    DEBUG1(("Writing TERM_ACK frame \n"));

    /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */

    ahdlc_tx(ctx, LCP, 0, buffer, 0, count);

    ctx->lcp_state &= ~LCP_TX_UP;
    ctx->lcp_state |= LCP_TERM_PEER;
    break;

  case TERM_ACK:
    DEBUG1(("LCP-TERM ACK\n"));
    break;

  case ECHO_REQ:
    if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP))
      {
        bptr = buffer;
        *bptr++ = ECHO_REP;   /* Write ECHO-REPLY */

        bptr += 3;            /* Skip id and length */

        *bptr++ = 0;          /* Zero Magic */
        *bptr++ = 0;
        *bptr++ = 0;
        *bptr++ = 0;

        /* Write the echo reply frame */

        DEBUG1(("\nWriting ECHO-REPLY frame \n"));
        // Send packet ahdlc_txz(procol,header,data,headerlen,datalen);
        ahdlc_tx(ctx, LCP, 0, buffer, 0, count);
        DEBUG1(("- end ECHO-REPLY Write frame\n"));
      }
    break;

  case ECHO_REP:
    DEBUG1(("LCP-ECHO REPLY\n"));
    if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP))
      {
        ctx->ppp_id++;
      }
    break;

  default:
    DEBUG1(("LCP unknown packet: %02x", *(bptr-1)));
    break;
  }
}