📄 ppp.c
字号:
return st;}#if PPPOE_SUPPORTintpppWriteOverEthernet(int pd, const u_char *s, int n){ PPPControl *pc = &pppControl[pd]; struct pbuf *pb; /* skip address & flags */ s += 2; n -= 2; LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); if(!pb) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pc->netif); return PPPERR_ALLOC; } pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); pc->lastXMit = sys_jiffies(); MEMCPY(pb->payload, s, n); 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, (u16_t)n); snmp_inc_ifoutucastpkts(&pc->netif); LINK_STATS_INC(link.xmit); return PPPERR_NONE;}#endif /* PPPOE_SUPPORT *//* * Write n characters to a ppp link. * RETURN: >= 0 Number of characters written * -1 Failed to write to device */intpppWrite(int pd, const u_char *s, int n){ PPPControl *pc = &pppControl[pd];#if PPPOS_SUPPORT u_char c; u_int fcsOut; struct pbuf *headMB, *tailMB;#endif /* PPPOS_SUPPORT */#if PPPOE_SUPPORT if(pc->ethif) { return pppWriteOverEthernet(pd, s, n); }#endif /* PPPOE_SUPPORT */#if PPPOS_SUPPORT headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (headMB == NULL) { LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pc->netif); 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(); fcsOut = PPP_INITFCS; /* 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); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.proterr); snmp_inc_ifoutdiscards(&pc->netif); 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);#endif /* PPPOS_SUPPORT */ return PPPERR_NONE;}/* * ppp_send_config - configure the transmit characteristics of * the ppp interface. */voidppp_send_config( int unit, u16_t mtu, u32_t asyncmap, int pcomp, int accomp){ PPPControl *pc = &pppControl[unit]; int i; pc->mtu = mtu; pc->pcomp = pcomp; pc->accomp = accomp; /* Load the ACCM bits for the 32 control codes. */ for (i = 0; i < 32/8; i++) { pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF); } PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", unit, pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3]));}/* * ppp_set_xaccm - set the extended transmit ACCM for the interface. */voidppp_set_xaccm(int unit, ext_accm *accm){ SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm)); PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n", unit, pppControl[unit].outACCM[0], pppControl[unit].outACCM[1], pppControl[unit].outACCM[2], pppControl[unit].outACCM[3]));}/* * ppp_recv_config - configure the receive-side characteristics of * the ppp interface. */voidppp_recv_config( int unit, int mru, u32_t asyncmap, int pcomp, int accomp){ PPPControl *pc = &pppControl[unit]; int i; SYS_ARCH_DECL_PROTECT(lev); LWIP_UNUSED_ARG(accomp); LWIP_UNUSED_ARG(pcomp); LWIP_UNUSED_ARG(mru); /* Load the ACCM bits for the 32 control codes. */ SYS_ARCH_PROTECT(lev); for (i = 0; i < 32 / 8; i++) { /* @todo: does this work? ext_accm has been modified from pppd! */ pc->rx.inACCM[i] = (u_char)(asyncmap >> (i * 8)); } SYS_ARCH_UNPROTECT(lev); PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", unit, pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3]));}#if 0/* * ccp_test - ask kernel whether a given compression method * is acceptable for use. Returns 1 if the method and parameters * are OK, 0 if the method is known but the parameters are not OK * (e.g. code size should be reduced), or -1 if the method is unknown. */intccp_test( int unit, int opt_len, int for_transmit, u_char *opt_ptr){ return 0; /* XXX Currently no compression. */}/* * ccp_flags_set - inform kernel about the current state of CCP. */voidccp_flags_set(int unit, int isopen, int isup){ /* XXX */}/* * ccp_fatal_error - returns 1 if decompression was disabled as a * result of an error detected after decompression of a packet, * 0 otherwise. This is necessary because of patent nonsense. */intccp_fatal_error(int unit){ /* XXX */ return 0;}#endif/* * get_idle_time - return how long the link has been idle. */intget_idle_time(int u, struct ppp_idle *ip){ /* XXX */ LWIP_UNUSED_ARG(u); LWIP_UNUSED_ARG(ip); return 0;}/* * Return user specified netmask, modified by any mask we might determine * for address `addr' (in network byte order). * Here we scan through the system's list of interfaces, looking for * any non-point-to-point interfaces which might appear to be on the same * network as `addr'. If we find any, we OR in their netmask to the * user-specified netmask. */u32_tGetMask(u32_t addr){ u32_t mask, nmask; htonl(addr); if (IP_CLASSA(addr)) { /* determine network mask for address class */ nmask = IP_CLASSA_NET; } else if (IP_CLASSB(addr)) { nmask = IP_CLASSB_NET; } else { nmask = IP_CLASSC_NET; } /* class D nets are disallowed by bad_ip_adrs */ mask = subnetMask | htonl(nmask); /* XXX * Scan through the system's network interfaces. * Get each netmask and OR them into our mask. */ return mask;}/* * sifvjcomp - config tcp header compression */intsifvjcomp(int pd, int vjcomp, u8_t cidcomp, u8_t maxcid){#if PPPOS_SUPPORT && VJ_SUPPORT PPPControl *pc = &pppControl[pd]; pc->vjEnabled = vjcomp; pc->vjComp.compressSlot = cidcomp; pc->vjComp.maxSlotIndex = maxcid; PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", vjcomp, cidcomp, maxcid));#else /* PPPOS_SUPPORT && VJ_SUPPORT */ LWIP_UNUSED_ARG(pd); LWIP_UNUSED_ARG(vjcomp); LWIP_UNUSED_ARG(cidcomp); LWIP_UNUSED_ARG(maxcid);#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ return 0;}/* * pppifNetifInit - netif init callback */static err_tpppifNetifInit(struct netif *netif){ netif->name[0] = 'p'; netif->name[1] = 'p'; netif->output = pppifOutput; netif->mtu = pppMTU((int)(size_t)netif->state); netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP;#if LWIP_NETIF_HOSTNAME /* @todo: Initialize interface hostname */ /* netif_set_hostname(netif, "lwip"); */#endif /* LWIP_NETIF_HOSTNAME */ return ERR_OK;}/* * sifup - Config the interface up and enable IP packets to pass. */intsifup(int pd){ PPPControl *pc = &pppControl[pd]; int st = 1; if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); } else { netif_remove(&pc->netif); if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, &pc->addrs.his_ipaddr, (void *)(size_t)pd, pppifNetifInit, ip_input)) { netif_set_up(&pc->netif); pc->if_up = 1; pc->errCode = PPPERR_NONE; PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); if (pc->linkStatusCB) { pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); } } else { st = 0; PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pd)); } } return st;}/* * sifnpmode - Set the mode for handling packets for a given NP. */intsifnpmode(int u, int proto, enum NPmode mode){ LWIP_UNUSED_ARG(u); LWIP_UNUSED_ARG(proto); LWIP_UNUSED_ARG(mode); return 0;}/* * sifdown - Config the interface down and disable IP. */intsifdown(int pd){ PPPControl *pc = &pppControl[pd]; int st = 1; if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", pd)); } else { pc->if_up = 0; /* make sure the netif status callback is called */ netif_set_down(&pc->netif); netif_remove(&pc->netif); PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); if (pc->linkStatusCB) { pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL); } } return st;}/** * sifaddr - Config the interface IP addresses and netmask. * @param pd Interface unit ??? * @param o Our IP address ??? * @param h His IP address ??? * @param m IP subnet mask ??? * @param ns1 Primary DNS * @param ns2 Secondary DNS */intsifaddr( int pd, u32_t o, u32_t h, u32_t m, u32_t ns1, u32_t ns2){ PPPControl *pc = &pppControl[pd]; int st = 1; if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); } else { SMEMCPY(&pc->addrs.our_ipaddr, &o, sizeof(o)); SMEMCPY(&pc->addrs.his_ipaddr, &h, sizeof(h)); SMEMCPY(&pc->addrs.netmask, &m, sizeof(m)); SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); } return st;}/** * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. * @param pd Interface unit ??? * @param o Our IP address ??? * @param h IP broadcast address ??? */intcifaddr( int pd, u32_t o, u32_t h){ PPPControl *pc = &pppControl[pd]; int st = 1; LWIP_UNUSED_ARG(o); LWIP_UNUSED_ARG(h); if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); } else { IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); IP4_ADDR(&pc->addrs.netmask, 255,255,255,0); IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); } return st;}/* * sifdefaultroute - assign a default route through the address given. */intsifdefaultroute(int pd, u32_t l, u32_t g){ PPPControl *pc = &pppControl[pd]; int st = 1; LWIP_UNUSED_ARG(l); LWIP_UNUSED_ARG(g); if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); } else { netif_set_default(&pc->netif); } /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */ return st;}/* * cifdefaultroute - delete a default route through the address given. */intcifdefaultroute(int pd, u32_t l, u32_t g){ PPPControl *pc = &pppControl[pd]; int st = 1; LWIP_UNUSED_ARG(l); LWIP_UNUSED_ARG(g); if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { st = 0; PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); } else { netif_set_default(NULL); } return st;}/**********************************//*** LOCAL FUNCTION DEFINITIONS ***//**********************************/#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD/* The main PPP process function. This implements the state machine according * to section 4 of RFC 1661: The Point-To-Point Protocol. */static voidpppInputThread(void *arg){ int count; PPPControlRx *pcrx = arg; while (lcp_phase[pcrx->pd] != PHASE_DEAD) { count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); if(count > 0) { pppInProc(pcrx, pcrx->rxbuf, count); } else { /* nothing received, give other tasks a chance to run */ sys_msleep(1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -