void ipcp_rx()

in netutils/pppd/ipcp.c [129:447]


void ipcp_rx(FAR struct ppp_context_s *ctx, FAR uint8_t * buffer,
             uint16_t count)
{
  FAR uint8_t *bptr = buffer;
  uint16_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, g_ipcplist, buffer, bptr, 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
              ((FAR uint8_t *)&ctx->peer_ip)[0] = *bptr++;
              ((FAR uint8_t *)&ctx->peer_ip)[1] = *bptr++;
              ((FAR uint8_t *)&ctx->peer_ip)[2] = *bptr++;
              ((FAR uint8_t *)&ctx->peer_ip)[3] = *bptr++;

              DEBUG1(("Peer IP "));
              printip(ctx->peer_ip);
              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, (uint16_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, (uint16_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++;
              ((FAR uint8_t *)&ctx->local_ip)[0] = *bptr++;
              ((FAR uint8_t *)&ctx->local_ip)[1] = *bptr++;
              ((FAR uint8_t *)&ctx->local_ip)[2] = *bptr++;
              ((FAR uint8_t *)&ctx->local_ip)[3] = *bptr++;
              break;

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

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

            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(ctx->local_ip);
#ifdef IPCP_GET_PRI_DNS
      printip(ctx->pri_dns_addr);
#endif
#ifdef IPCP_GET_SEC_DNS
      printip(ctx->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++;

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

              netlib_ifup((FAR char *)ctx->ifname);
              netlib_set_ipv4addr((FAR char *)ctx->ifname, &ctx->local_ip);
              break;

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

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

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

      ctx->ppp_id++;

      printip(ctx->local_ip);
#ifdef IPCP_GET_PRI_DNS
      printip(ctx->pri_dns_addr);
#endif
#ifdef IPCP_GET_PRI_DNS
      printip(ctx->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 shouldn't happen 3\n"));
            }
        }
      break;

    default:
      DEBUG1(("-Unknown 4\n"));
    }
}