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

📄 lcp.c

📁 LWIP在STM32裸机上的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif
        orc = CONFREJ;
        break;
      
      default:
#if TRACELCP
        snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype);
        traceNdx = strlen(traceBuf);
#endif
        orc = CONFREJ;
        break;
    }

  endswitch:
#if TRACELCP
    if (traceNdx >= 80 - 32) {
      LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd%s\n", traceBuf));
      traceNdx = 0;
    }
#endif
    if (orc == CONFACK && /* Good CI */
        rc != CONFACK) {  /*  but prior CI wasnt? */
      continue;           /* Don't send this one */
    }

    if (orc == CONFNAK) {     /* Nak this CI? */
      if (reject_if_disagree  /* Getting fed up with sending NAKs? */
          && citype != CI_MAGICNUMBER) {
        orc = CONFREJ;        /* Get tough if so */
      } else {
        if (rc == CONFREJ) {  /* Rejecting prior CI? */
          continue;           /* Don't send this one */
        }
        rc = CONFNAK;
      }
    }
    if (orc == CONFREJ) {        /* Reject this CI */
      rc = CONFREJ;
      if (cip != rejp) {         /* Need to move rejected CI? */
        BCOPY(cip, rejp, cilen); /* Move it */
      }
      INCPTR(cilen, rejp);       /* Update output pointer */
    }
  }

  /*
   * If we wanted to send additional NAKs (for unsent CIs), the
   * code would go here.  The extra NAKs would go at *nakp.
   * At present there are no cases where we want to ask the
   * peer to negotiate an option.
   */

  switch (rc) {
    case CONFACK:
      *lenp = (int)(next - inp);
      break;
    case CONFNAK:
      /*
       * Copy the Nak'd options from the nak_buffer to the caller's buffer.
       */
      *lenp = (int)(nakp - nak_buffer);
      BCOPY(nak_buffer, inp, *lenp);
      break;
    case CONFREJ:
      *lenp = (int)(rejp - inp);
      break;
  }

#if TRACELCP > 0
  if (traceNdx > 0) {
    LCPDEBUG((LOG_INFO, "lcp_reqci: %s\n", traceBuf));
  }
#endif
  LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.\n", CODENAME(rc)));
  return (rc);      /* Return final code */
}


/*
 * lcp_up - LCP has come UP.
 */
static void
lcp_up(fsm *f)
{
  lcp_options *wo = &lcp_wantoptions[f->unit];
  lcp_options *ho = &lcp_hisoptions[f->unit];
  lcp_options *go = &lcp_gotoptions[f->unit];
  lcp_options *ao = &lcp_allowoptions[f->unit];

  if (!go->neg_magicnumber) {
    go->magicnumber = 0;
  }
  if (!ho->neg_magicnumber) {
    ho->magicnumber = 0;
  }

  /*
   * Set our MTU to the smaller of the MTU we wanted and
   * the MRU our peer wanted.  If we negotiated an MRU,
   * set our MRU to the larger of value we wanted and
   * the value we got in the negotiation.
   */
  ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
                 (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl),
                  ho->neg_pcompression, ho->neg_accompression);
  /*
   * If the asyncmap hasn't been negotiated, we really should
   * set the receive asyncmap to ffffffff, but we set it to 0
   * for backwards contemptibility.
   */
  ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU),
                 (go->neg_asyncmap? go->asyncmap: 0x00000000),
                  go->neg_pcompression, go->neg_accompression);

  if (ho->neg_mru) {
    peer_mru[f->unit] = ho->mru;
  }

  lcp_echo_lowerup(f->unit); /* Enable echo messages */

  link_established(f->unit);
}


/*
 * lcp_down - LCP has gone DOWN.
 *
 * Alert other protocols.
 */
static void
lcp_down(fsm *f)
{
  lcp_options *go = &lcp_gotoptions[f->unit];

  lcp_echo_lowerdown(f->unit);

  link_down(f->unit);

  ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0);
  ppp_recv_config(f->unit, PPP_MRU,
                  (go->neg_asyncmap? go->asyncmap: 0x00000000),
                   go->neg_pcompression, go->neg_accompression);
  peer_mru[f->unit] = PPP_MRU;
}


/*
 * lcp_starting - LCP needs the lower layer up.
 */
static void
lcp_starting(fsm *f)
{
  link_required(f->unit);
}


/*
 * lcp_finished - LCP has finished with the lower layer.
 */
static void
lcp_finished(fsm *f)
{
  link_terminated(f->unit);
}


#if 0
/*
 * print_string - print a readable representation of a string using
 * printer.
 */
static void
print_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg)
{
  int c;
  
  printer(arg, "\"");
  for (; len > 0; --len) {
    c = *p++;
    if (' ' <= c && c <= '~') {
        if (c == '\\' || c == '"') {
          printer(arg, "\\");
        }
        printer(arg, "%c", c);
    } else {
      switch (c) {
        case '\n':
          printer(arg, "\\n");
          break;
        case '\r':
          printer(arg, "\\r");
          break;
        case '\t':
          printer(arg, "\\t");
          break;
        default:
          printer(arg, "\\%.3o", c);
        }
    }
  }
  printer(arg, "\"");
}


/*
 * lcp_printpkt - print the contents of an LCP packet.
 */
static char *lcp_codenames[] = {
  "ConfReq", "ConfAck", "ConfNak", "ConfRej",
  "TermReq", "TermAck", "CodeRej", "ProtRej",
  "EchoReq", "EchoRep", "DiscReq"
};

static int
lcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
{
  int code, id, len, olen;
  u_char *pstart, *optend;
  u_short cishort;
  u32_t cilong;

  if (plen < HEADERLEN) {
    return 0;
  }
  pstart = p;
  GETCHAR(code, p);
  GETCHAR(id, p);
  GETSHORT(len, p);
  if (len < HEADERLEN || len > plen) {
    return 0;
  }

  if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) {
    printer(arg, " %s", lcp_codenames[code-1]);
  } else {
    printer(arg, " code=0x%x", code);
  }
  printer(arg, " id=0x%x", id);
  len -= HEADERLEN;
  switch (code) {
    case CONFREQ:
    case CONFACK:
    case CONFNAK:
    case CONFREJ:
      /* print option list */
      while (len >= 2) {
        GETCHAR(code, p);
        GETCHAR(olen, p);
        p -= 2;
        if (olen < 2 || olen > len) {
          break;
        }
        printer(arg, " <");
        len -= olen;
        optend = p + olen;
        switch (code) {
          case CI_MRU:
            if (olen == CILEN_SHORT) {
              p += 2;
              GETSHORT(cishort, p);
              printer(arg, "mru %d", cishort);
            }
            break;
          case CI_ASYNCMAP:
            if (olen == CILEN_LONG) {
              p += 2;
              GETLONG(cilong, p);
              printer(arg, "asyncmap 0x%lx", cilong);
            }
            break;
          case CI_AUTHTYPE:
            if (olen >= CILEN_SHORT) {
              p += 2;
              printer(arg, "auth ");
              GETSHORT(cishort, p);
              switch (cishort) {
                case PPP_PAP:
                  printer(arg, "pap");
                  break;
                case PPP_CHAP:
                  printer(arg, "chap");
                  break;
                default:
                  printer(arg, "0x%x", cishort);
              }
            }
            break;
          case CI_QUALITY:
            if (olen >= CILEN_SHORT) {
              p += 2;
              printer(arg, "quality ");
              GETSHORT(cishort, p);
              switch (cishort) {
                case PPP_LQR:
                  printer(arg, "lqr");
                  break;
                default:
                  printer(arg, "0x%x", cishort);
              }
            }
            break;
          case CI_CALLBACK:
            if (olen >= CILEN_CHAR) {
              p += 2;
              printer(arg, "callback ");
              GETSHORT(cishort, p);
              switch (cishort) {
                case CBCP_OPT:
                  printer(arg, "CBCP");
                  break;
                default:
                  printer(arg, "0x%x", cishort);
              }
            }
            break;
          case CI_MAGICNUMBER:
            if (olen == CILEN_LONG) {
              p += 2;
              GETLONG(cilong, p);
              printer(arg, "magic 0x%x", cilong);
            }
            break;
          case CI_PCOMPRESSION:
            if (olen == CILEN_VOID) {
              p += 2;
              printer(arg, "pcomp");
            }
            break;
          case CI_ACCOMPRESSION:
            if (olen == CILEN_VOID) {
              p += 2;
              printer(arg, "accomp");
            }
            break;
        }
        while (p < optend) {
          GETCHAR(code, p);
          printer(arg, " %.2x", code);
        }
        printer(arg, ">");
      }
      break;
    
    case TERMACK:
    case TERMREQ:
      if (len > 0 && *p >= ' ' && *p < 0x7f) {
        printer(arg, " ");
        print_string((char*)p, len, printer, arg);
        p += len;
        len = 0;
      }
      break;
    
    case ECHOREQ:
    case ECHOREP:
    case DISCREQ:
      if (len >= 4) {
        GETLONG(cilong, p);
        printer(arg, " magic=0x%x", cilong);
        p += 4;
        len -= 4;
      }
      break;
  }

  /* print the rest of the bytes in the packet */
  for (; len > 0; --len) {
    GETCHAR(code, p);
    printer(arg, " %.2x", code);
  }

  return (int)(p - pstart);
}
#endif

/*
 * Time to shut down the link because there is nothing out there.
 */
static void
LcpLinkFailure (fsm *f)
{
  if (f->state == LS_OPENED) {
    LCPDEBUG((LOG_INFO, "No response to %d echo-requests\n", lcp_echos_pending));
    LCPDEBUG((LOG_NOTICE, "Serial link appears to be disconnected.\n"));
    lcp_close(f->unit, "Peer not responding");
  }
}

/*
 * Timer expired for the LCP echo requests from this process.
 */
static void
LcpEchoCheck (fsm *f)
{
  LcpSendEchoRequest (f);

  /*
   * Start the timer for the next interval.
   */
  LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0);

  TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
  lcp_echo_timer_running = 1;
}

/*
 * LcpEchoTimeout - Timer expired on the LCP echo
 */
static void
LcpEchoTimeout (void *arg)
{
  if (lcp_echo_timer_running != 0) {
    lcp_echo_timer_running = 0;
    LcpEchoCheck ((fsm *) arg);
  }
}

/*
 * LcpEchoReply - LCP has received a reply to the echo
 */
static void
lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
{
  u32_t magic;

  LWIP_UNUSED_ARG(id);

  /* Check the magic number - don't count replies from ourselves. */
  if (len < 4) {
    LCPDEBUG((LOG_WARNING, "lcp: received short Echo-Reply, length %d\n", len));
    return;
  }
  GETLONG(magic, inp);
  if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) {
    LCPDEBUG((LOG_WARNING, "appear to have received our own echo-reply!\n"));
    return;
  }
  
  /* Reset the number of outstanding echo frames */
  lcp_echos_pending = 0;
}

/*
 * LcpSendEchoRequest - Send an echo request frame to the peer
 */
static void
LcpSendEchoRequest (fsm *f)
{
  u32_t lcp_magic;
  u_char pkt[4], *pktp;

  /*
   * Detect the failure of the peer at this point.
   */
  if (lcp_echo_fails != 0) {
    if (lcp_echos_pending++ >= lcp_echo_fails) {
      LcpLinkFailure(f);
      lcp_echos_pending = 0;
    }
  }

  /*
   * Make and send the echo request frame.
   */
  if (f->state == LS_OPENED) {
    lcp_magic = lcp_gotoptions[f->unit].magicnumber;
    pktp = pkt;
    PUTLONG(lcp_magic, pktp);
    fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));
  }
}

/*
 * lcp_echo_lowerup - Start the timer for the LCP frame
 */

static void
lcp_echo_lowerup (int unit)
{
  fsm *f = &lcp_fsm[unit];

  /* Clear the parameters for generating echo frames */
  lcp_echos_pending      = 0;
  lcp_echo_number        = 0;
  lcp_echo_timer_running = 0;

  /* If a timeout interval is specified then start the timer */
  if (lcp_echo_interval != 0) {
    LcpEchoCheck (f);
  }
}

/*
 * lcp_echo_lowerdown - Stop the timer for the LCP frame
 */

static void
lcp_echo_lowerdown (int unit)
{
  fsm *f = &lcp_fsm[unit];

  if (lcp_echo_timer_running != 0) {
    UNTIMEOUT (LcpEchoTimeout, f);
    lcp_echo_timer_running = 0;
  }
}

#endif /* PPP_SUPPORT */

⌨️ 快捷键说明

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