?? ppp.c
字號:
pc->errCode = 0; pc->inState = PDIDLE; pc->inHead = NULL; pc->inTail = NULL; pc->inEscaped = 0; pc->lastXMit = 0;#if VJ_SUPPORT > 0 pc->vjEnabled = 0; vj_compress_init(&pc->vjComp);#endif /* * 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(pppMain, (void*)pd, 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;}/* 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. */int pppClose(int pd){ PPPControl *pc = &pppControl[pd]; int st = 0; /* Disconnect */ pc->kill_link = !0; pppMainWakeup(pd); 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. */void pppSigHUP(int pd){ PPPControl *pc = &pppControl[pd]; pc->sig_hup = 1; pppMainWakeup(pd);}static void nPut(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));#if LINK_STATS lwip_stats.link.err++;#endif /* LINK_STATS */ pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */ break; } } pbuf_free(nb);#if LINK_STATS lwip_stats.link.xmit++;#endif /* LINK_STATS */}/* * 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; }#if LINK_STATS else { lwip_stats.link.memerr++; }#endif /* LINK_STATS */ 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;}/* Send a packet on the given connection. */static err_t pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr){ int pd = (int)netif->state; u_short protocol = PPP_IP; PPPControl *pc = &pppControl[pd]; u_int fcsOut = PPP_INITFCS; struct pbuf *headMB = NULL, *tailMB = NULL, *p; u_char c; (void)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));#if LINK_STATS lwip_stats.link.opterr++; lwip_stats.link.drop++;#endif 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));#if LINK_STATS lwip_stats.link.rterr++; lwip_stats.link.drop++;#endif return ERR_RTE; } /* 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));#if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++;#endif /* LINK_STATS */ return ERR_MEM; } #if VJ_SUPPORT > 0 /* * 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));#if LINK_STATS lwip_stats.link.proterr++; lwip_stats.link.drop++;#endif pbuf_free(headMB); return ERR_VAL; } }#endif 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);#if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++;#endif return ERR_MEM; } /* Send it. */ PPPDEBUG((LOG_INFO, "pppifOutput[%d]: proto=0x%04X\n", pd, protocol)); nPut(pc, headMB); return ERR_OK;}/* Get and set parameters for the given connection. * Return 0 on success, an error code on failure. */int pppIOCtl(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; case PPPCTLG_FD: if (arg) *(sio_fd_t *)arg = pc->fd; else st = PPPERR_PARAM; break; default: st = PPPERR_PARAM; break; } } return st;}/* * Return the Maximum Transmission Unit for the given PPP connection. */u_int pppMTU(int pd){ PPPControl *pc = &pppControl[pd]; u_int st; /* Validate parameters. */ if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) st = 0; else st = pc->mtu; return st;}/* * Write n characters to a ppp link. * RETURN: >= 0 Number of characters written * -1 Failed to write to device */int pppWrite(int pd, const u_char *s, int n){ PPPControl *pc = &pppControl[pd]; u_char c; u_int fcsOut = PPP_INITFCS; struct pbuf *headMB = NULL, *tailMB; headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (headMB == NULL) {#if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.proterr++;#endif /* LINK_STATS */ return PPPERR_ALLOC; } tailMB = headMB; /* If the link has been idle, we'll send a fresh flag character to * flush any noise. */ if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) tailMB = pppAppend(PPP_FLAG, tailMB, NULL); pc->lastXMit = sys_jiffies(); /* Load output buffer. */ while (n-- > 0) { c = *s++; /* 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. * Otherwise send it. */ if (!tailMB) { PPPDEBUG((LOG_WARNING, "pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len));/* "pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ pbuf_free(headMB);#if LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.proterr++;#endif /* LINK_STATS */ return PPPERR_ALLOC; } PPPDEBUG((LOG_INFO, "pppWrite[%d]: len=%d\n", pd, headMB->len));/* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ nPut(pc, headMB); return PPPERR_NONE;}/* * ppp_send_config - configure the transmit characteristics of * the ppp interface.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -