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

📄 ppp.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 4 页
字号:
    ppp_settings.user[0] = '\0';  }  if(passwd) {    strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1);    ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0';  } else {    ppp_settings.passwd[0] = '\0';  }}#if PPPOS_SUPPORT/** Open a new PPP connection using the given I/O device. * This initializes the PPP control block but does not * attempt to negotiate the LCP session.  If this port * connects to a modem, the modem connection must be * established before calling this. * Return a new PPP connection descriptor on success or * an error code (negative) on failure. * * pppOpen() is directly defined to this function. */intpppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx){  PPPControl *pc;  int pd;  if (linkStatusCB == NULL) {    /* PPP is single-threaded: without a callback,     * there is no way to know when the link is up. */    return PPPERR_PARAM;  }  /* Find a free PPP session descriptor. */  for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);  if (pd >= NUM_PPP) {    pd = PPPERR_OPEN;  } else {    pc = &pppControl[pd];    /* @todo: is this correct or do I overwrite something? */    memset(pc, 0, sizeof(PPPControl));    pc->rx.pd = pd;    pc->rx.fd = fd;    pc->openFlag = 1;    pc->fd = fd;#if VJ_SUPPORT    vj_compress_init(&pc->vjComp);#endif /* VJ_SUPPORT */    /*      * Default the in and out accm so that escape and flag characters     * are always escaped.      */    pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */    pc->outACCM[15] = 0x60;    pc->linkStatusCB = linkStatusCB;    pc->linkStatusCtx = linkStatusCtx;    /*     * Start the connection and handle incoming events (packet or timeout).     */    PPPDEBUG(LOG_INFO, ("pppOverSerialOpen: unit %d: Connecting\n", pd));    pppStart(pd);#if PPP_INPROC_OWNTHREAD    sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO);#endif  }  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);  if (linkStatusCB == NULL) {    /* PPP is single-threaded: without a callback,     * there is no way to know when the link is up. */    return PPPERR_PARAM;  }  /* 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 {    pc = &pppControl[pd];    memset(pc, 0, sizeof(PPPControl));    pc->openFlag = 1;    pc->ethif = ethif;    pc->linkStatusCB  = linkStatusCB;    pc->linkStatusCtx = linkStatusCtx;    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;    if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) {      pc->openFlag = 0;      return PPPERR_OPEN;    }    pppoe_connect(pc->pppoe_sc);  }  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;  PPPDEBUG(LOG_DEBUG, ("pppClose() called\n"));  /* Disconnect */#if PPPOE_SUPPORT  if(pc->ethif) {    PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd));    pc->errCode = PPPERR_USER;    /* This will leave us at PHASE_DEAD. */    pppStop(pd);  } else#endif /* PPPOE_SUPPORT */  {#if PPPOS_SUPPORT    PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd));    pc->errCode = PPPERR_USER;    /* This will leave us at PHASE_DEAD. */    pppStop(pd);    pppRecvWakeup(pd);#endif /* PPPOS_SUPPORT */  }  return st;}/* This function is called when carrier is lost on the PPP channel. */voidpppSigHUP(int pd){  PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));  pppHup(pd);}#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(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c));      LINK_STATS_INC(link.err);      pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */      snmp_inc_ifoutdiscards(&pc->netif);      pbuf_free(nb);      return;    }  }  snmp_add_ifoutoctets(&pc->netif, nb->tot_len);  snmp_inc_ifoutucastpkts(&pc->netif);  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;  u16_t tot_len;  /* @todo: try to use pbuf_header() here! */  pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM);  if(!pb) {    LINK_STATS_INC(link.memerr);    LINK_STATS_INC(link.proterr);    snmp_inc_ifoutdiscards(&pc->netif);    return ERR_MEM;  }  pbuf_header(pb, -(s16_t)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);  tot_len = pb->tot_len;  if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) {    LINK_STATS_INC(link.err);    snmp_inc_ifoutdiscards(&pc->netif);    return PPPERR_DEVICE;  }  snmp_add_ifoutoctets(&pc->netif, tot_len);  snmp_inc_ifoutucastpkts(&pc->netif);  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, ip_addr_t *ipaddr){  int pd = (int)(size_t)netif->state;  PPPControl *pc = &pppControl[pd];#if PPPOS_SUPPORT  u_short protocol = PPP_IP;  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, PPP_IP, pb));    LINK_STATS_INC(link.opterr);    LINK_STATS_INC(link.drop);    snmp_inc_ifoutdiscards(netif);    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);    snmp_inc_ifoutdiscards(netif);    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);    snmp_inc_ifoutdiscards(netif);    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);        snmp_inc_ifoutdiscards(netif);        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);    snmp_inc_ifoutdiscards(netif);    return ERR_MEM;  }  /* Send it. */  PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\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:            /* Get the fd associated with the ppp */      if (arg) {        *(sio_fd_t *)arg = pc->fd;      } else {        st = PPPERR_PARAM;      }      break;#endif /* PPPOS_SUPPORT */    default:      st = PPPERR_PARAM;      break;    }  }  return st;}/* * Return the Maximum Transmission Unit for the given PPP connection. */u_shortpppMTU(int pd){  PPPControl *pc = &pppControl[pd];  u_short st;  /* Validate parameters. */  if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {    st = 0;  } else {    st = pc->mtu;  }

⌨️ 快捷键说明

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