📄 ppp.c
字号:
pcb->q = pcb->p; /* Make q the pointer to the last pbuf which initially is the first */ pcb->psize = 0; pcb->qsize = 0; } switch(payload[i]) { case PPP_END: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: PPP_END i = %d pcb->psize = %d\n", i, pcb->psize)); if(pcb->psize > 0) { /* Packet received */ /* Do a frame check */ if((fcs16_crc_check(pcb->p, pcb->psize))) { /* Silently discard frame */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: FCS failed pcb->psize = %d\n", pcb->psize)); pbuf_free(pcb->p); pcb->p = NULL; break; } pbuf_realloc(pcb->p, pcb->psize - 2); /* Remove the FCS field and adjust packet size */ /* Have address and control field been compressed? */ if(ntohs(*((u16_t *)pcb->p->payload)) != PPP_ADDRCTRL) { if(!(pcb->lcpcfg & LCP_CFG_IN_ACCOMP)) { /* Silently discard frame */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Discard frame without address and control field when no compression negotiated i = %d pcb->psize = %d\n", i, pcb->psize)); pbuf_free(pcb->p); pcb->p = NULL; break; } } else { pbuf_header(pcb->p, -2); /* Hide address and control field */ } /* Check if least significant bit of octet is a '1' and if protocol compression is in use */ if(*((u8_t *)pcb->p->payload) & 1 && pcb->lcpcfg & LCP_CFG_IN_PCOMP) { proto = *((u8_t *)pcb->p->payload); pbuf_header(pcb->p, -1); } else { proto = ntohs(*((u16_t *)pcb->p->payload)); pbuf_header(pcb->p, -2); } /* Check that size of incoming packet does not exceed MRU */ if(pcb->p->tot_len > pcb->mru) { /* Silently discard frame */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Size of incoming packet exceed MRU, %d, %d\n", i, pcb->psize)); pbuf_free(pcb->p); pcb->p = NULL; break; } switch(proto) { //struct ppp_cp_hdr *cphdr; case PPP_LCP: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: PPP_LCP i = %d pcb->psize = %d code = 0x%x\n", i, pcb->psize, ((u8_t *)pcb->p)[0])); ppp_process_lcp(pcb, pcb->p); pbuf_free(pcb->p); pcb->p = NULL; break; case PPP_PAP: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: PPP_PAP i = %d pcb->psize = %d\n", i, pcb->psize)); ppp_process_pap(pcb, pcb->p); pbuf_free(pcb->p); pcb->p = NULL; break; case PPP_IPCP: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: PPP_IPCP i = %d pcb->psize = %d\n", i, pcb->psize)); ppp_process_ipcp(pcb, pcb->p); pbuf_free(pcb->p); pcb->p = NULL; break; case PPP_IP_DATA: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: PPP_IP_DATA i = %d pcb->psize = %d pcb->p->tot_len = %d\n", i, pcb->psize, pcb->p->tot_len)); for(r = pcb->p; r != NULL; r = r->next) { u16_t j; for(j = 0; j < r->len; ++j) { LWIP_DEBUGF(TCP_DEBUG, ("IN: 0x%x\n", ((u8_t *)r->payload)[j])); } LWIP_DEBUGF(TCP_DEBUG, ("\n")); } //for(r = pcb->p; r != NULL; r = r->next) { // u16_t j; // for(j = 0; j < r->len; ++j) { //LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: 0x%x\n", ((u8_t *)r->payload)[j])); // } //LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: r->len == %d r->tot_len == %d\n", r->len, r->tot_len)); //} PPP_EVENT_RECV(pcb,ret); pcb->p = NULL; /* Upper layer will dealloc pbuf. Delete any reference to it so we don't overwrite it */ break; default: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Unknown protocol, proto == %d, %d, %d\n", proto, i, pcb->psize)); r = pbuf_alloc(PBUF_RAW, 2, PBUF_RAM); *((u16_t *)r->payload) = htons(proto); pbuf_chain(r, pcb->p); pbuf_free(pcb->p); pcb->p = NULL; ppp_cp_output(pcb, PPP_LCP, LCP_PROTO_REJ, ppp_next_id(), r); //cphdr = pcb->p->payload; //ppp_cp_output(pcb, proto, LCP_CFG_ACK, cphdr->id, NULL); break; } } break; case PPP_ESC: if(i < q->len-1) { ++i; /* Move to next element in buffer */ } else { if(q->next != NULL) { q = q->next; /* Move to next buffer in chain */ i = 0; payload = (u8_t *)q->payload; } else { /* Last character in receive buffer is an escape character */ //TODO: Is this a problem? LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Last character in receive buffer is an escape character!!!\n")); break; /* No more data in buffer */ } } payload[i] ^= 0x20; /* Character following an escape character is exclusive-ord with 0x20 */ /* FALLTHROUGH */ default: ((u8_t *)pcb->q->payload)[pcb->qsize] = payload[i]; ++pcb->psize; ++pcb->qsize; if(pcb->qsize == pcb->q->len) { /* Pbuf full. Allocate and add new tail to chain */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Pbuf full. Allocate and add new tail to chain\n")); pcb->qsize = 0; if((pcb->q = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL)) == NULL) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Could not allocate memory for pbuf pcb->q\n")); pbuf_free(p); return ERR_MEM; /* Could not allocate memory for pbuf */ } pbuf_chain(pcb->p, pcb->q); pbuf_free(pcb->q); } if(pcb->psize > PPP_MAX_SIZE) { /* PPP packet too big. Drop */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: PPP packet too big. Drop, i = %d pcb->psize = %d\n", i, pcb->psize)); pbuf_free(pcb->p); pcb->p = NULL; } break; } } } pbuf_free(p); return ERR_OK;}/*-----------------------------------------------------------------------------------*//* * ppp_new(): * * Creates a new PPP protocol control block but doesn't place it on * any of the PPP PCB lists. *//*-----------------------------------------------------------------------------------*/struct ppp_pcb *ppp_new(struct rfcomm_pcb *rfcommpcb) { struct ppp_pcb *pcb; pcb = lwbt_memp_malloc(MEMP_PPP_PCB); if(pcb != NULL) { memset(pcb, 0, sizeof(struct ppp_pcb)); pcb->rfcommpcb = rfcommpcb; pcb->state = PPP_LCP_CLOSED; pcb->mru = LCP_DEFAULT_MRU; pcb->outaccm = LCP_DEFAULT_ACCM; pcb->lcpopt = PPP_LCP_OPT; pcb->ipcpopt = PPP_IPCP_OPT; return pcb; } LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_new: Could not allocate a new pcb\n")); return NULL;}/*-----------------------------------------------------------------------------------*//* * ppp_close(): * * Closes the PPP protocol control block. *//*-----------------------------------------------------------------------------------*/err_tppp_close(struct ppp_pcb *pcb) { struct ppp_req *req; err_t err; /* Remove any outstanding requests */ for(req = pcb->reqs; req != NULL; req = req->next) { PPP_REQ_RMV(&(pcb->reqs), req); if(req->p != NULL) { pbuf_free(req->p); } LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_close: Free memory for request with ID 0x%x***********\n", req->id)); lwbt_memp_free(MEMP_PPP_REQ, req); } /* Remove PCB from its list */ switch(pcb->state) { case PPP_LCP_LISTEN: PPP_RMV(&(ppp_listen_pcbs), pcb); break; default: PPP_RMV(&(ppp_active_pcbs), pcb); break; } err = ERR_OK; if(pcb->p != NULL) {//&& pcb->p->ref) { pbuf_free(pcb->p); /* Make sure we have freed any incoming packet */ pcb->p = NULL; } lwbt_memp_free(MEMP_PPP_PCB, pcb); pcb = NULL; return err;}/*-----------------------------------------------------------------------------------*//* * ppp_reset_all(): * * Closes all active PPP protocol control blocks. *//*-----------------------------------------------------------------------------------*/voidppp_reset_all(void) { struct ppp_pcb *pcb, *tpcb; for(pcb = ppp_active_pcbs; pcb != NULL;) { tpcb = pcb->next; ppp_close(pcb); pcb = tpcb; } for(pcb = ppp_listen_pcbs; pcb != NULL;) { tpcb = pcb->next; ppp_close(pcb); pcb = tpcb; } ppp_init();}/*-----------------------------------------------------------------------------------*//* * lcp_cfg_req(): * * Assembles but do not send a LCP configuration request. The Options field is * filled with any desired changes to the link defaults. *//*-----------------------------------------------------------------------------------*/struct pbuf *lcp_cfg_req(struct ppp_pcb *pcb, struct pbuf *options){ struct pbuf *p, *q; struct ppp_cfg_hdr *cfghdr; p = NULL; if(pcb->lcpopt & LCP_CFG_OPT_MRU) { if(PPP_IN_MRU != LCP_DEFAULT_MRU) { p = pbuf_alloc(PBUF_RAW, PPP_CFGHDR_LEN + 2, PBUF_RAM); cfghdr = p->payload; cfghdr->type = LCP_CFG_MRU; cfghdr->len = p->len; ((u16_t *)p->payload)[1] = htons(PPP_IN_MRU); } } if(pcb->lcpopt & LCP_CFG_OPT_ACCM) { /* Add ACCM for outgoing packets */ if(PPP_ACCM != LCP_DEFAULT_ACCM) { q = pbuf_alloc(PBUF_RAW, PPP_CFGHDR_LEN + 4, PBUF_RAM); cfghdr = q->payload; cfghdr->type = LCP_CFG_ACCM; cfghdr->len = q->len; *((u32_t *)(((u16_t *)q->payload)+1)) = htonl(PPP_ACCM); if(p == NULL) { p = q; } else { pbuf_chain(p, q); pbuf_free(q); } } } if(pcb->lcpopt & LCP_CFG_OPT_PAP) { //TODO: IMPLEMENT PAP configuration request }#if PPP_PHDR_COMP if(pcb->lcpopt & LCP_CFG_OPT_PFC) { q = pbuf_alloc(PBUF_RAW, PPP_CFGHDR_LEN, PBUF_RAM); cfghdr = q->payload; cfghdr->type = LCP_CFG_P_COMP; cfghdr->len = q->len; if(p == NULL) { p = q; } else { pbuf_chain(p, q); pbuf_free(q); } }#endif /* PPP_PHDR_COMP */#if PPP_ACHDR_COMP if(pcb->lcpopt & LCP_CFG_OPT_ACFC) { q = pbuf_alloc(PBUF_RAW, PPP_CFGHDR_LEN, PBUF_RAM); cfghdr = q->payload; cfghdr->type = LCP_CFG_AC_COMP; cfghdr->len = q->len; if(p == NULL) { p = q; } else { pbuf_chain(p, q); pbuf_free(q); } }#endif /* PPP_ACHDR_COMP */ if(options != NULL) { pbuf_chain(p, options); pbuf_free(options); } return p;}/*-----------------------------------------------------------------------------------*//* * ipcp_cfg_req(): * * Sends a IPCP configuration request to open an IPCP connection. The Options field * is filled with any desired changes to the link defaults. *//*-----------------------------------------------------------------------------------*/err_tipcp_cfg_req(struct ppp_pcb *pcb){ struct pbuf *p = NULL; struct ppp_cfg_hdr *cfghdr; if(pcb->ipcpopt & IPCP_CFG_OPT_IP) { if((p = pbuf_alloc(PBUF_RAW, PPP_CFGHDR_LEN + 4, PBUF_RAM)) == NULL) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ipcp_cfg_req: Could not allocate memory for pbuf\n")); return ERR_MEM; /* Could not allocate memory for pbuf */ } cfghdr = p->payload; cfghdr->type = IPCP_CFG_IPADDR; cfghdr->len = p->len; *((u32_t *)(((u16_t *)p->payload)+1)) = pcb->bluetoothif->ip_addr.addr; LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ipcp_cfg_req: Local IP address: %d.%d.%d.%d\n", (u8_t)(ntohl(pcb->bluetoothif->ip_addr.addr) >> 24) & 0xff, (u8_t)(ntohl(pcb->bluetoothif->ip_addr.addr) >> 16) & 0xff, (u8_t)(ntohl(pcb->bluetoothif->ip_addr.addr) >> 8) & 0xff, (u8_t)ntohl(pcb->bluetoothif->ip_addr.addr) & 0xff)); }#if PPP_VJ_COMP if(pcb->ipcpopt & IPCP_CFG_OPT_VJ) { if((q = pbuf_alloc(PBUF_RAW, PPP_CFGHDR_LEN + 4, PBUF_RAM)) == NULL) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ipcp_cfg_req: Could not allocate memory for pbuf\n")); return ERR_MEM; /* Could not allocate memory for pbuf */ } cfghdr = q->payload; cfghdr->type = IPCP_CFG_COMP; cfghdr->len = q->len; ((u16_t *)q->payload)[1] = PPP_VJ_TYPE; ((u8_t *)q->payload)[4] = PPP_MAXSLOT_ID; ((u8_t *)q->payload)[5] = PPP_COMPSLOT_ID; if(p == NULL) { p = q; } else { pbuf_chain(p, q); pbuf_free(q); } }#endif /* PPP_VJ_COMP */ return ppp_cp_output(pcb, PPP_IPCP, IPCP_CFG_REQ, ppp_next_id(), p);}/*-----------------------------------------------------------------------------------*//* * ppp_connect(): * * Initiates a connection attempt (LCP and IPCP) and specify the function to be * called when both LCP and IPCP has been connected. *//*-----------------------------------------------------------------------------------*/err_t //INITIATORppp_connect(struct ppp_pcb *pcb, err_t (* connected)(void *arg, struct ppp_pcb *tpcb, err_t err)){ struct pbuf *p; err_t ret = ERR_OK; LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_connect\n")); pcb->connected = connected; pcb->pppcfg |= PPP_IR; /* We are the initiator */ if(pcb->state == PPP_LCP_OPEN) { if((ret = ipcp_cfg_req(pcb)) == ERR_OK) { pcb->state = PPP_IPCP_CFG; } } else { PPP_REG(&ppp_active_pcbs, pcb);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -