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

📄 ppp.c

📁 最新的lwip 1.3.0版本在ucos平台上的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
intpppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx){  PPPControl *pc;  int pd;  /* Find a free PPP session descriptor. Critical region? */  for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);  if (pd >= NUM_PPP) {    pd = PPPERR_OPEN;  } else {    pppControl[pd].openFlag = !0;  }  /* Launch a deamon thread. */  if (pd >= 0) {    pppControl[pd].openFlag = 1;    lcp_init(pd);    pc = &pppControl[pd];    pc->fd = fd;#if PPPOE_SUPPORT    pc->ethif= NULL;#endif /* PPPOE_SUPPORT */    pc->kill_link = 0;    pc->sig_hup = 0;    pc->if_up = 0;    pc->errCode = 0;    pc->inState = PDIDLE;    pc->inHead = NULL;    pc->inTail = NULL;    pc->inEscaped = 0;    pc->lastXMit = 0;#if VJ_SUPPORT    pc->vjEnabled = 0;    vj_compress_init(&pc->vjComp);#endif /* VJ_SUPPORT */    /*      * Default the in and out accm so that escape and flag characters     * are always escaped.      */    memset(pc->inACCM, 0, sizeof(ext_accm));    pc->inACCM[15] = 0x60;    memset(pc->outACCM, 0, sizeof(ext_accm));    pc->outACCM[15] = 0x60;    pc->linkStatusCB = linkStatusCB;    pc->linkStatusCtx = linkStatusCtx;    sys_thread_new(PPP_THREAD_NAME, pppMain, (void*)pd, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO);    if(!linkStatusCB) {      while(pd >= 0 && !pc->if_up) {        sys_msleep(500);        if (lcp_phase[pd] == PHASE_DEAD) {          pppClose(pd);          if (pc->errCode) {            pd = pc->errCode;          } else {            pd = PPPERR_CONNECT;          }        }      }    }  }  return pd;}#endif /* PPPOS_SUPPORT */#if PPPOE_SUPPORTstatic void pppOverEthernetLinkStatusCB(int pd, int up);voidpppOverEthernetClose(int pd){  PPPControl* pc = &pppControl[pd];  /* *TJL* There's no lcp_deinit */  lcp_close(pd, NULL);  pppoe_destroy(&pc->netif);}int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx){  PPPControl *pc;  int pd;  LWIP_UNUSED_ARG(service_name);  LWIP_UNUSED_ARG(concentrator_name);  /* Find a free PPP session descriptor. Critical region? */  for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);  if (pd >= NUM_PPP) {    pd = PPPERR_OPEN;  } else {    pppControl[pd].openFlag = !0;  }  /* Launch a deamon thread. */  if (pd >= 0) {    pppControl[pd].openFlag = 1;    lcp_init(pd);    lcp_wantoptions[pd].mru = PPPOE_MAXMTU;    lcp_wantoptions[pd].neg_asyncmap = 0;    lcp_wantoptions[pd].neg_pcompression = 0;    lcp_wantoptions[pd].neg_accompression = 0;    lcp_allowoptions[pd].mru = PPPOE_MAXMTU;    lcp_allowoptions[pd].neg_asyncmap = 0;    lcp_allowoptions[pd].neg_pcompression = 0;    lcp_allowoptions[pd].neg_accompression = 0;    pc = &pppControl[pd];    pc->if_up = 0;    pc->errCode = 0;    pc->lastXMit = 0;#if PPPOS_SUPPORT    pc->kill_link = 0;    pc->sig_hup = 0;    pc->inState = PDIDLE;    pc->inHead = NULL;    pc->inTail = NULL;    pc->inEscaped = 0;#if VJ_SUPPORT    pc->vjEnabled = 0;#endif /* VJ_SUPPORT */#endif /* PPPOS_SUPPORT */    pc->ethif= ethif;    memset(pc->inACCM,  0, sizeof(ext_accm));    memset(pc->outACCM, 0, sizeof(ext_accm));    pc->linkStatusCB  = linkStatusCB;    pc->linkStatusCtx = linkStatusCtx;    if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) {      pc->openFlag = 0;      return PPPERR_OPEN;    }    pppoe_connect(pc->pppoe_sc);    if(!linkStatusCB) {      while(pd >= 0 && !pc->if_up) {        sys_msleep(500);        if (lcp_phase[pd] == PHASE_DEAD) {          pppClose(pd);          if (pc->errCode) {            pd = pc->errCode;          } else {            pd = PPPERR_CONNECT;          }        }      }    }  }  return pd;}#endif /* PPPOE_SUPPORT *//* Close a PPP connection and release the descriptor.  * Any outstanding packets in the queues are dropped. * Return 0 on success, an error code on failure. */intpppClose(int pd){  PPPControl *pc = &pppControl[pd];  int st = 0;  /* Disconnect */#if PPPOE_SUPPORT  if(pc->ethif) {    PPPDEBUG((LOG_DEBUG, "pppClose: unit %d kill_link -> pppStopCB\n", pd));    pc->errCode = PPPERR_USER;    /* This will leave us at PHASE_DEAD. */    tcpip_callback(pppStopCB, (void*)pd);  } else#endif /* PPPOE_SUPPORT */  {#if PPPOS_SUPPORT    pc->kill_link = !0;    pppMainWakeup(pd);#endif /* PPPOS_SUPPORT */  }  if(!pc->linkStatusCB) {    while(st >= 0 && lcp_phase[pd] != PHASE_DEAD) {      sys_msleep(500);      break;    }  }  return st;}/* This function is called when carrier is lost on the PPP channel. */voidpppSigHUP(int pd){  PPPControl *pc = &pppControl[pd];#if PPPOE_SUPPORT  if(pc->ethif) {    PPPDEBUG((LOG_DEBUG, "pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));    tcpip_callback(pppHupCB, (void*)pd);  } else#endif /* PPPOE_SUPPORT */  {#if PPPOS_SUPPORT    pc->sig_hup = 1;    pppMainWakeup(pd);#endif /* PPPOS_SUPPORT */  }}#if PPPOS_SUPPORTstatic voidnPut(PPPControl *pc, struct pbuf *nb){  struct pbuf *b;  int c;  for(b = nb; b != NULL; b = b->next) {    if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) {      PPPDEBUG((LOG_WARNING,               "PPP nPut: incomplete sio_write(%d,, %u) = %d\n", pc->fd, b->len, c));      LINK_STATS_INC(link.err);      pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */      break;    }  }  pbuf_free(nb);  LINK_STATS_INC(link.xmit);}/*  * pppAppend - append given character to end of given pbuf.  If outACCM * is not NULL and the character needs to be escaped, do so. * If pbuf is full, append another. * Return the current pbuf. */static struct pbuf *pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM){  struct pbuf *tb = nb;    /* Make sure there is room for the character and an escape code.   * Sure we don't quite fill the buffer if the character doesn't   * get escaped but is one character worth complicating this? */  /* Note: We assume no packet header. */  if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) {    tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);    if (tb) {      nb->next = tb;    } else {      LINK_STATS_INC(link.memerr);    }    nb = tb;  }  if (nb) {    if (outACCM && ESCAPE_P(*outACCM, c)) {      *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE;      *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS;    } else {      *((u_char*)nb->payload + nb->len++) = c;    }  }  return tb;}#endif /* PPPOS_SUPPORT */#if PPPOE_SUPPORTstatic err_tpppifOutputOverEthernet(int pd, struct pbuf *p){  PPPControl *pc = &pppControl[pd];  struct pbuf *pb;  u_short protocol = PPP_IP;  int i=0;  pb = pbuf_alloc(PBUF_LINK, pppoe_hdrlen + sizeof(protocol), PBUF_RAM);  if(!pb) {    LINK_STATS_INC(link.memerr);    LINK_STATS_INC(link.proterr);    return ERR_MEM;  }  pbuf_header(pb, -pppoe_hdrlen);  pc->lastXMit = sys_jiffies();  if (!pc->pcomp || protocol > 0xFF) {    *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF;  }  *((u_char*)pb->payload + i) = protocol & 0xFF;  pbuf_chain(pb, p);  if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) {    LINK_STATS_INC(link.err);    return PPPERR_DEVICE;  }  LINK_STATS_INC(link.xmit);  return ERR_OK;}#endif /* PPPOE_SUPPORT *//* Send a packet on the given connection. */static err_tpppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr){  int pd = (int)netif->state;  u_short protocol = PPP_IP;  PPPControl *pc = &pppControl[pd];#if PPPOS_SUPPORT  u_int fcsOut = PPP_INITFCS;  struct pbuf *headMB = NULL, *tailMB = NULL, *p;  u_char c;#endif /* PPPOS_SUPPORT */  LWIP_UNUSED_ARG(ipaddr);  /* Validate parameters. */  /* We let any protocol value go through - it can't hurt us   * and the peer will just drop it if it's not accepting it. */  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {    PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad parms prot=%d pb=%p\n",              pd, protocol, pb));    LINK_STATS_INC(link.opterr);    LINK_STATS_INC(link.drop);    return ERR_ARG;  }  /* Check that the link is up. */  if (lcp_phase[pd] == PHASE_DEAD) {    PPPDEBUG((LOG_ERR, "pppifOutput[%d]: link not up\n", pd));    LINK_STATS_INC(link.rterr);    LINK_STATS_INC(link.drop);    return ERR_RTE;  }#if PPPOE_SUPPORT  if(pc->ethif) {    return pppifOutputOverEthernet(pd, pb);  }#endif /* PPPOE_SUPPORT */#if PPPOS_SUPPORT  /* Grab an output buffer. */  headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);  if (headMB == NULL) {    PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: first alloc fail\n", pd));    LINK_STATS_INC(link.memerr);    LINK_STATS_INC(link.drop);    return ERR_MEM;  }#if VJ_SUPPORT  /*    * Attempt Van Jacobson header compression if VJ is configured and   * this is an IP packet.    */  if (protocol == PPP_IP && pc->vjEnabled) {    switch (vj_compress_tcp(&pc->vjComp, pb)) {      case TYPE_IP:        /* No change...           protocol = PPP_IP_PROTOCOL; */        break;      case TYPE_COMPRESSED_TCP:        protocol = PPP_VJC_COMP;        break;      case TYPE_UNCOMPRESSED_TCP:        protocol = PPP_VJC_UNCOMP;        break;      default:        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad IP packet\n", pd));        LINK_STATS_INC(link.proterr);        LINK_STATS_INC(link.drop);        pbuf_free(headMB);        return ERR_VAL;    }  }#endif /* VJ_SUPPORT */  tailMB = headMB;  /* Build the PPP header. */  if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) {    tailMB = pppAppend(PPP_FLAG, tailMB, NULL);  }  pc->lastXMit = sys_jiffies();  if (!pc->accomp) {    fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);    tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);    fcsOut = PPP_FCS(fcsOut, PPP_UI);    tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);  }  if (!pc->pcomp || protocol > 0xFF) {    c = (protocol >> 8) & 0xFF;    fcsOut = PPP_FCS(fcsOut, c);    tailMB = pppAppend(c, tailMB, &pc->outACCM);  }  c = protocol & 0xFF;  fcsOut = PPP_FCS(fcsOut, c);  tailMB = pppAppend(c, tailMB, &pc->outACCM);  /* Load packet. */  for(p = pb; p; p = p->next) {    int n;    u_char *sPtr;    sPtr = (u_char*)p->payload;    n = p->len;    while (n-- > 0) {      c = *sPtr++;      /* Update FCS before checking for special characters. */      fcsOut = PPP_FCS(fcsOut, c);            /* Copy to output buffer escaping special characters. */      tailMB = pppAppend(c, tailMB, &pc->outACCM);    }  }  /* Add FCS and trailing flag. */  c = ~fcsOut & 0xFF;  tailMB = pppAppend(c, tailMB, &pc->outACCM);  c = (~fcsOut >> 8) & 0xFF;  tailMB = pppAppend(c, tailMB, &pc->outACCM);  tailMB = pppAppend(PPP_FLAG, tailMB, NULL);  /* If we failed to complete the packet, throw it away. */  if (!tailMB) {    PPPDEBUG((LOG_WARNING,             "pppifOutput[%d]: Alloc err - dropping proto=%d\n",               pd, protocol));    pbuf_free(headMB);    LINK_STATS_INC(link.memerr);    LINK_STATS_INC(link.drop);    return ERR_MEM;  }  /* Send it. */  PPPDEBUG((LOG_INFO, "pppifOutput[%d]: proto=0x%04X\n", pd, protocol));  nPut(pc, headMB);#endif /* PPPOS_SUPPORT */  return ERR_OK;}/* Get and set parameters for the given connection. * Return 0 on success, an error code on failure. */intpppIOCtl(int pd, int cmd, void *arg){  PPPControl *pc = &pppControl[pd];  int st = 0;  if (pd < 0 || pd >= NUM_PPP) {    st = PPPERR_PARAM;  } else {    switch(cmd) {    case PPPCTLG_UPSTATUS:      /* Get the PPP up status. */      if (arg) {        *(int *)arg = (int)(pc->if_up);      } else {        st = PPPERR_PARAM;      }      break;    case PPPCTLS_ERRCODE:       /* Set the PPP error code. */      if (arg) {        pc->errCode = *(int *)arg;      } else {        st = PPPERR_PARAM;      }      break;    case PPPCTLG_ERRCODE:       /* Get the PPP error code. */      if (arg) {        *(int *)arg = (int)(pc->errCode);      } else {        st = PPPERR_PARAM;      }      break;#if PPPOS_SUPPORT    case PPPCTLG_FD:      if (arg) {

⌨️ 快捷键说明

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