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

📄 ppp.c

📁 最新的lwip 1.3.0版本在ucos平台上的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
/* The main PPP process function.  This implements the state machine according * to section 4 of RFC 1661: The Point-To-Point Protocol. */static voidpppMain(void *arg){  int pd = (int)arg;  struct pbuf *p;  PPPControl* pc;  int c;  pc = &pppControl[pd];  p = pbuf_alloc(PBUF_RAW, PPP_MRU+PPP_HDRLEN, PBUF_RAM);  if (!p) {    LWIP_ASSERT("p != NULL", p);    pc->errCode = PPPERR_ALLOC;    goto out;  }  /*   * Start the connection and handle incoming events (packet or timeout).   */  PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd));  tcpip_callback(pppStartCB, arg);  while (lcp_phase[pd] != PHASE_DEAD) {    if (pc->kill_link) {      PPPDEBUG((LOG_DEBUG, "pppMain: unit %d kill_link -> pppStopCB\n", pd));      pc->errCode = PPPERR_USER;      /* This will leave us at PHASE_DEAD. */      tcpip_callback(pppStopCB, arg);      pc->kill_link = 0;    } else if (pc->sig_hup) {      PPPDEBUG((LOG_DEBUG, "pppMain: unit %d sig_hup -> pppHupCB\n", pd));      pc->sig_hup = 0;      tcpip_callback(pppHupCB, arg);    } else {      c = sio_read(pc->fd, p->payload, p->len);      if(c > 0) {        pppInProc(pd, p->payload, c);      } else {        PPPDEBUG((LOG_DEBUG, "pppMain: unit %d sio_read len=%d returned %d\n", pd, p->len, c));        sys_msleep(1); /* give other tasks a chance to run */      }    }  }  PPPDEBUG((LOG_INFO, "pppMain: unit %d: PHASE_DEAD\n", pd));  pppDrop(pc); /* bug fix #17726 */  pbuf_free(p);out:  PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));  if(pc->linkStatusCB) {    pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);  }  pc->openFlag = 0;}#endif /* PPPOS_SUPPORT */#if PPPOE_SUPPORTvoidpppOverEthernetInitFailed(void* arg){  PPPControl* pc;  int pd = (int)arg;  pppHupCB(arg);  pppStopCB(arg);  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, "pppMain: unit %d: Connecting\n", pd));    tcpip_callback(pppStartCB, (void*)pd);  } else {    PPPControl* pc;    pc = &pppControl[pd];    tcpip_callback(pppOverEthernetInitFailed, (void*)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);  /*   * 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%04X in phase %d\n", protocol, lcp_phase[pd]));      goto drop;    }  }  switch(protocol) {    case PPP_VJC_COMP:      /* VJ compressed TCP */#if 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  /* 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 /* VJ_SUPPORT */      break;    case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */#if 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  /* 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 /* 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);          goto out;        }      }      /* No handler for this protocol so reject the packet. */      PPPDEBUG((LOG_INFO, "pppInput[%d]: rejecting unsupported proto 0x%04X 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);      SMEMCPY(nb->payload, &protocol, sizeof(protocol));#endif /* BYTE_ORDER == LITTLE_ENDIAN */      lcp_sprotrej(pd, nb->payload, nb->len);    }    break;  }drop:  LINK_STATS_INC(link.drop);out:  pbuf_free(nb);  return;}#if PPPOS_SUPPORT/* * Drop the input packet. */static voidpppDrop(PPPControl *pc){  if (pc->inHead != NULL) {#if 0    PPPDEBUG((LOG_INFO, "pppDrop: %d:%.*H\n", pc->inHead->len, min(60, pc->inHead->len * 2), pc->inHead->payload));#endif    PPPDEBUG((LOG_INFO, "pppDrop: pbuf len=%d\n", pc->inHead->len));    if (pc->inTail && (pc->inTail != pc->inHead)) {      pbuf_free(pc->inTail);    }    pbuf_free(pc->inHead);    pc->inHead = NULL;    pc->inTail = NULL;  }#if VJ_SUPPORT  vj_uncompress_err(&pc->vjComp);#endif /* VJ_SUPPORT */  LINK_STATS_INC(link.drop);}/** * Process a received octet string. */static voidpppInProc(int pd, u_char *s, int l){  PPPControl *pc = &pppControl[pd];  struct pbuf *nextNBuf;  u_char curChar;  PPPDEBUG((LOG_DEBUG, "pppInProc[%d]: got %d bytes\n", pd, l));  while (l-- > 0) {    curChar = *s++;        /* Handle special characters. */    if (ESCAPE_P(pc->inACCM, curChar)) {      /* 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) {        pc->inEscaped = 1;      /* Check for the flag character. */      } else if (curChar == PPP_FLAG) {         /* If this is just an extra flag character, ignore it. */         if (pc->inState <= PDADDRESS) {           /* ignore it */;         /* If we haven't received the packet header, drop what has come in. */         } else if (pc->inState < PDDATA) {           PPPDEBUG((LOG_WARNING,                    "pppInProc[%d]: Dropping incomplete packet %d\n",                      pd, pc->inState));           LINK_STATS_INC(link.lenerr);           pppDrop(pc);         /* If the fcs is invalid, drop the packet. */         } else if (pc->inFCS != PPP_GOODFCS) {           PPPDEBUG((LOG_INFO,                    "pppInProc[%d]: Dropping bad fcs 0x%04X proto=0x%04X\n",                      pd, pc->inFCS, pc->inProtocol));           LINK_STATS_INC(link.chkerr);           pppDrop(pc);         /* Otherwise it's a good packet so pass it on. */         } else {           /* Trim off the checksum. */           if(pc->inTail->len >= 2) {             pc->inTail->len -= 2;             pc->inTail->tot_len = pc->inTail->len;             if (pc->inTail != pc->inHead) {               pbuf_cat(pc->inHead, pc->inTail);             }           } else {             pc->inTail->tot_len = pc->inTail->len;             if (pc->inTail != pc->inHead) {               pbuf_cat(pc->inHead, pc->inTail);             }             pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2);           }           /* Dispatch the packet thereby consuming it. */           if(tcpip_callback(pppInput, pc->inHead) != ERR_OK) {             PPPDEBUG((LOG_ERR, "pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pd));             pbuf_free(pc->inHead);             LINK_STATS_INC(link.drop);           }           pc->inHead = NULL;           pc->inTail = NULL;         }         /* Prepare for a new packet. */         pc->inFCS = PPP_INITFCS;         pc->inState = PDADDRESS;         pc->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", pd, curChar));      }    /* Process other characters. */    } else {      /* Unencode escaped characters. */      if (pc->inEscaped) {        pc->inEscaped = 0;        curChar ^= PPP_TRANS;      }      /* Process character relative to current state. */      switch(pc->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. */          pc->inFCS = PPP_INITFCS;        /* Fall through */        case PDADDRESS:                 /* Process address field. */          if (curChar == PPP_ALLSTATIONS) {            pc->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) {            pc->inState = PDPROTOCOL1;            break;          }#if 0          else {            PPPDEBUG((LOG_WARNING,                     "pppInProc[%d]: Invalid control <%d>\n", pd, curChar));                      pc->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) {            pc->inProtocol = curChar;            pc->inState = PDDATA;          } else {            pc->inProtocol = (u_int)curChar << 8;            pc->inState = PDPROTOCOL2;          }          break;        case PDPROTOCOL2:               /* Process protocol field 2. */          pc->inProtocol |= curChar;          pc->inState = PDDATA;          break;        case PDDATA:                    /* Process data byte. */          /* Make space to receive processed data. */          if (pc->inTail == NULL || pc->inTail->len == PBUF_POOL_BUFSIZE) {            if(pc->inTail) {              pc->inTail->tot_len = pc->inTail->len;              if (pc->inTail != pc->inHead) {                pbuf_cat(pc->inHead, pc->inTail);              }            }            /* 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", pd));              LINK_STATS_INC(link.memerr);              pppDrop(pc);              pc->inState = PDSTART;  /* Wait for flag sequence. */              break;            }            if (pc->inHead == NULL) {              struct pppInputHeader *pih = nextNBuf->payload;              pih->unit = pd;              pih->proto = pc->inProtocol;              nextNBuf->len += sizeof(*pih);              pc->inHead = nextNBuf;            }            pc->inTail = nextNBuf;          }          /* Load character into buffer. */          ((u_char*)pc->inTail->payload)[pc->inTail->len++] = curChar;          break;      }      /* update the frame check sequence number. */      pc->inFCS = PPP_FCS(pc->inFCS, curChar);    }  }  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. */  if(tcpip_callback(pppInput, pb) != ERR_OK) {    PPPDEBUG((LOG_ERR, "pppInProcOverEthernet[%d]: tcpip_callback() failed, dropping packet\n", pd));    goto drop;  }  return;drop:  LINK_STATS_INC(link.drop);  pbuf_free(pb);  return;}#endif /* PPPOE_SUPPORT */#endif /* PPP_SUPPORT */

⌨️ 快捷键说明

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