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

📄 ppp.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 4 页
字号:
  }}#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */#if PPPOE_SUPPORTvoidpppOverEthernetInitFailed(int pd){  PPPControl* pc;  pppHup(pd);  pppStop(pd);  pc = &pppControl[pd];  pppoe_destroy(&pc->netif);  pc->openFlag = 0;  if(pc->linkStatusCB) {    pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);  }}static voidpppOverEthernetLinkStatusCB(int pd, int up){  if(up) {    PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd));    pppStart(pd);  } else {    pppOverEthernetInitFailed(pd);  }}#endif /* PPPOE_SUPPORT */struct pbuf *pppSingleBuf(struct pbuf *p){  struct pbuf *q, *b;  u_char *pl;  if(p->tot_len == p->len) {    return p;  }  q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);  if(!q) {    PPPDEBUG(LOG_ERR,             ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len));    return p; /* live dangerously */  }  for(b = p, pl = q->payload; b != NULL; b = b->next) {    MEMCPY(pl, b->payload, b->len);    pl += b->len;  }  pbuf_free(p);  return q;}struct pppInputHeader {  int unit;  u16_t proto;};/* * Pass the processed input packet to the appropriate handler. * This function and all handlers run in the context of the tcpip_thread */static voidpppInput(void *arg){  struct pbuf *nb = (struct pbuf *)arg;  u16_t protocol;  int pd;  pd = ((struct pppInputHeader *)nb->payload)->unit;  protocol = ((struct pppInputHeader *)nb->payload)->proto;      if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) {    LWIP_ASSERT("pbuf_header failed\n", 0);    goto drop;  }  LINK_STATS_INC(link.recv);  snmp_inc_ifinucastpkts(&pppControl[pd].netif);  snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len);  /*   * Toss all non-LCP packets unless LCP is OPEN.   * Until we get past the authentication phase, toss all packets   * except LCP, LQR and authentication packets.   */  if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) {    if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) ||        (lcp_phase[pd] != PHASE_AUTHENTICATE)) {      PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd]));      goto drop;    }  }  switch(protocol) {    case PPP_VJC_COMP:      /* VJ compressed TCP */#if PPPOS_SUPPORT && VJ_SUPPORT      PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len));      /*       * Clip off the VJ header and prepend the rebuilt TCP/IP header and       * pass the result to IP.       */      if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) {        pppControl[pd].netif.input(nb, &pppControl[pd].netif);        return;      }      /* Something's wrong so drop it. */      PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd));#else  /* PPPOS_SUPPORT && VJ_SUPPORT */      /* No handler for this protocol so drop the packet. */      PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload));#endif /* PPPOS_SUPPORT && VJ_SUPPORT */      break;    case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */#if PPPOS_SUPPORT && VJ_SUPPORT      PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len));      /*       * Process the TCP/IP header for VJ header compression and then pass       * the packet to IP.       */      if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) {        pppControl[pd].netif.input(nb, &pppControl[pd].netif);        return;      }      /* Something's wrong so drop it. */      PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd));#else  /* PPPOS_SUPPORT && VJ_SUPPORT */      /* No handler for this protocol so drop the packet. */      PPPDEBUG(LOG_INFO,               ("pppInput[%d]: drop VJ UnComp in %d:.*H\n",                 pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload));#endif /* PPPOS_SUPPORT && VJ_SUPPORT */      break;    case PPP_IP:            /* Internet Protocol */      PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));      if (pppControl[pd].netif.input) {        pppControl[pd].netif.input(nb, &pppControl[pd].netif);        return;      }      break;    default: {      struct protent *protp;      int i;      /*       * Upcall the proper protocol input routine.       */      for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) {        if (protp->protocol == protocol && protp->enabled_flag) {          PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len));          nb = pppSingleBuf(nb);          (*protp->input)(pd, nb->payload, nb->len);          PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd));          goto out;        }      }      /* No handler for this protocol so reject the packet. */      PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len));      if (pbuf_header(nb, sizeof(protocol))) {        LWIP_ASSERT("pbuf_header failed\n", 0);        goto drop;      }#if BYTE_ORDER == LITTLE_ENDIAN      protocol = htons(protocol);#endif /* BYTE_ORDER == LITTLE_ENDIAN */      SMEMCPY(nb->payload, &protocol, sizeof(protocol));      lcp_sprotrej(pd, nb->payload, nb->len);    }    break;  }drop:  LINK_STATS_INC(link.drop);  snmp_inc_ifindiscards(&pppControl[pd].netif);out:  pbuf_free(nb);  return;}#if PPPOS_SUPPORT/* * Drop the input packet. */static voidpppDrop(PPPControlRx *pcrx){  if (pcrx->inHead != NULL) {#if 0    PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload));#endif    PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead));    if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) {      pbuf_free(pcrx->inTail);    }    pbuf_free(pcrx->inHead);    pcrx->inHead = NULL;    pcrx->inTail = NULL;  }#if VJ_SUPPORT  vj_uncompress_err(&pppControl[pcrx->pd].vjComp);#endif /* VJ_SUPPORT */  LINK_STATS_INC(link.drop);  snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif);}/** Pass received raw characters to PPPoS to be decoded. This function is * thread-safe and can be called from a dedicated RX-thread or from a main-loop. * * @param pd PPP descriptor index, returned by pppOpen() * @param data received data * @param len length of received data */voidpppos_input(int pd, u_char* data, int len){  pppInProc(&pppControl[pd].rx, data, len);}/** * Process a received octet string. */static voidpppInProc(PPPControlRx *pcrx, u_char *s, int l){  struct pbuf *nextNBuf;  u_char curChar;  u_char escaped;  SYS_ARCH_DECL_PROTECT(lev);  PPPDEBUG(LOG_DEBUG, ("pppInProc[%d]: got %d bytes\n", pcrx->pd, l));  while (l-- > 0) {    curChar = *s++;    SYS_ARCH_PROTECT(lev);    escaped = ESCAPE_P(pcrx->inACCM, curChar);    SYS_ARCH_UNPROTECT(lev);    /* Handle special characters. */    if (escaped) {      /* Check for escape sequences. */      /* XXX Note that this does not handle an escaped 0x5d character which       * would appear as an escape character.  Since this is an ASCII ']'       * and there is no reason that I know of to escape it, I won't complicate       * the code to handle this case. GLL */      if (curChar == PPP_ESCAPE) {        pcrx->inEscaped = 1;      /* Check for the flag character. */      } else if (curChar == PPP_FLAG) {        /* If this is just an extra flag character, ignore it. */        if (pcrx->inState <= PDADDRESS) {          /* ignore it */;        /* If we haven't received the packet header, drop what has come in. */        } else if (pcrx->inState < PDDATA) {          PPPDEBUG(LOG_WARNING,                   ("pppInProc[%d]: Dropping incomplete packet %d\n",                     pcrx->pd, pcrx->inState));          LINK_STATS_INC(link.lenerr);          pppDrop(pcrx);        /* If the fcs is invalid, drop the packet. */        } else if (pcrx->inFCS != PPP_GOODFCS) {          PPPDEBUG(LOG_INFO,                   ("pppInProc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n",                     pcrx->pd, pcrx->inFCS, pcrx->inProtocol));          /* Note: If you get lots of these, check for UART frame errors or try different baud rate */          LINK_STATS_INC(link.chkerr);          pppDrop(pcrx);        /* Otherwise it's a good packet so pass it on. */        } else {          struct pbuf *inp;          /* Trim off the checksum. */          if(pcrx->inTail->len >= 2) {            pcrx->inTail->len -= 2;            pcrx->inTail->tot_len = pcrx->inTail->len;            if (pcrx->inTail != pcrx->inHead) {              pbuf_cat(pcrx->inHead, pcrx->inTail);            }          } else {            pcrx->inTail->tot_len = pcrx->inTail->len;            if (pcrx->inTail != pcrx->inHead) {              pbuf_cat(pcrx->inHead, pcrx->inTail);            }            pbuf_realloc(pcrx->inHead, pcrx->inHead->tot_len - 2);          }          /* Dispatch the packet thereby consuming it. */          inp = pcrx->inHead;          /* Packet consumed, release our references. */          pcrx->inHead = NULL;          pcrx->inTail = NULL;#if PPP_INPROC_MULTITHREADED          if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) {            PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd));            pbuf_free(inp);            LINK_STATS_INC(link.drop);            snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif);          }#else /* PPP_INPROC_MULTITHREADED */          pppInput(inp);#endif /* PPP_INPROC_MULTITHREADED */        }        /* Prepare for a new packet. */        pcrx->inFCS = PPP_INITFCS;        pcrx->inState = PDADDRESS;        pcrx->inEscaped = 0;      /* Other characters are usually control characters that may have       * been inserted by the physical layer so here we just drop them. */      } else {        PPPDEBUG(LOG_WARNING,                 ("pppInProc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, curChar));      }    /* Process other characters. */    } else {      /* Unencode escaped characters. */      if (pcrx->inEscaped) {        pcrx->inEscaped = 0;        curChar ^= PPP_TRANS;      }      /* Process character relative to current state. */      switch(pcrx->inState) {        case PDIDLE:                    /* Idle state - waiting. */          /* Drop the character if it's not 0xff           * we would have processed a flag character above. */          if (curChar != PPP_ALLSTATIONS) {            break;          }        /* Fall through */        case PDSTART:                   /* Process start flag. */          /* Prepare for a new packet. */          pcrx->inFCS = PPP_INITFCS;        /* Fall through */        case PDADDRESS:                 /* Process address field. */          if (curChar == PPP_ALLSTATIONS) {            pcrx->inState = PDCONTROL;            break;          }          /* Else assume compressed address and control fields so           * fall through to get the protocol... */        case PDCONTROL:                 /* Process control field. */          /* If we don't get a valid control code, restart. */          if (curChar == PPP_UI) {            pcrx->inState = PDPROTOCOL1;            break;          }#if 0          else {            PPPDEBUG(LOG_WARNING,                     ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar));            pcrx->inState = PDSTART;          }#endif        case PDPROTOCOL1:               /* Process protocol field 1. */          /* If the lower bit is set, this is the end of the protocol           * field. */          if (curChar & 1) {            pcrx->inProtocol = curChar;            pcrx->inState = PDDATA;          } else {            pcrx->inProtocol = (u_int)curChar << 8;            pcrx->inState = PDPROTOCOL2;          }          break;        case PDPROTOCOL2:               /* Process protocol field 2. */          pcrx->inProtocol |= curChar;          pcrx->inState = PDDATA;          break;        case PDDATA:                    /* Process data byte. */          /* Make space to receive processed data. */          if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) {            if (pcrx->inTail != NULL) {              pcrx->inTail->tot_len = pcrx->inTail->len;              if (pcrx->inTail != pcrx->inHead) {                pbuf_cat(pcrx->inHead, pcrx->inTail);                /* give up the inTail reference now */                pcrx->inTail = NULL;              }            }            /* If we haven't started a packet, we need a packet header. */            nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);            if (nextNBuf == NULL) {              /* No free buffers.  Drop the input packet and let the               * higher layers deal with it.  Continue processing               * the received pbuf chain in case a new packet starts. */              PPPDEBUG(LOG_ERR, ("pppInProc[%d]: NO FREE MBUFS!\n", pcrx->pd));              LINK_STATS_INC(link.memerr);              pppDrop(pcrx);              pcrx->inState = PDSTART;  /* Wait for flag sequence. */              break;            }            if (pcrx->inHead == NULL) {              struct pppInputHeader *pih = nextNBuf->payload;              pih->unit = pcrx->pd;              pih->proto = pcrx->inProtocol;              nextNBuf->len += sizeof(*pih);              pcrx->inHead = nextNBuf;            }            pcrx->inTail = nextNBuf;          }          /* Load character into buffer. */          ((u_char*)pcrx->inTail->payload)[pcrx->inTail->len++] = curChar;          break;      }      /* update the frame check sequence number. */      pcrx->inFCS = PPP_FCS(pcrx->inFCS, curChar);    }  } /* while (l-- > 0), all bytes processed */  avRandomize();}#endif /* PPPOS_SUPPORT */#if PPPOE_SUPPORTvoidpppInProcOverEthernet(int pd, struct pbuf *pb){  struct pppInputHeader *pih;  u16_t inProtocol;  if(pb->len < sizeof(inProtocol)) {    PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n"));    goto drop;  }  inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1];  /* make room for pppInputHeader - should not fail */  if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) {    PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n"));    goto drop;  }  pih = pb->payload;  pih->unit = pd;  pih->proto = inProtocol;  /* Dispatch the packet thereby consuming it. */  pppInput(pb);  return;drop:  LINK_STATS_INC(link.drop);  snmp_inc_ifindiscards(&pppControl[pd].netif);  pbuf_free(pb);  return;}#endif /* PPPOE_SUPPORT */#if LWIP_NETIF_STATUS_CALLBACK/** Set the status callback of a PPP's netif * * @param pd The PPP descriptor returned by pppOpen() * @param status_callback pointer to the status callback function * * @see netif_set_status_callback */voidppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback){  netif_set_status_callback(&pppControl[pd].netif, status_callback); }#endif /* LWIP_NETIF_STATUS_CALLBACK */#if LWIP_NETIF_LINK_CALLBACK/** Set the link callback of a PPP's netif * * @param pd The PPP descriptor returned by pppOpen() * @param link_callback pointer to the link callback function * * @see netif_set_link_callback */voidppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback){  netif_set_link_callback(&pppControl[pd].netif, link_callback); }#endif /* LWIP_NETIF_LINK_CALLBACK */#endif /* PPP_SUPPORT */

⌨️ 快捷键说明

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