📄 ppp.c
字号:
} ++pcb->naks; if(pcb->naks == PPP_MAX_FAILURE) { pcb->state = PPP_LCP_CLOSED; PPP_EVENT_CONNECTED(pcb, ERR_CONN, ret); break; } while(len > 0) { cfghdr = p->payload; //pbuf_header(p, -PPP_CFGHDR_LEN); //len -= PPP_CFGHDR_LEN; switch(cfghdr->type) { case LCP_CFG_MRU: /* Maximum receive unit that the implementation can receive is not accepted */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: NAK, MRU = %d\n", ntohs(((u16_t *)p->payload)[1]))); if(PPP_IN_MRU > ntohs(((u16_t *)p->payload)[1])) { pcb->mru = ntohs(((u16_t *)p->payload)[1]); } else { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: MRU negotiation failed\n")); ppp_disconnect(pcb); /* MRU negotiation failed */ return; } break; case LCP_CFG_ACCM: pcb->outaccm = ntohl(*((u32_t *)(((u16_t *)p->payload) + 1))); LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: NAK, ACCM\n")); break; case LCP_CFG_AUTH: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: NAK, AUTH\n")); /* Check if authentication option was in request */ if(pcb->lcpopt & LCP_CFG_OPT_PAP) { //TODO: Remote PPP uses an authentication protocol that we do not understand. What to do??? } else { /* Configuration option is requested to be in next request */ pcb->lcpopt |= LCP_CFG_OPT_PAP; } break;#if PPP_PHDR_COMP case LCP_CFG_P_COMP: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: NAK, P_COMP\n")); pcb->lcpopt &= ~LCP_CFG_OPT_PFC; break;#endif /* PPP_PHDR_COMP */#if PPP_ACHDR_COMP case LCP_CFG_AC_COMP: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: NAK, AC_COMP\n")); pcb->lcpopt &= ~LCP_CFG_OPT_ACFC; break;#endif /* PPP_ACHDR_COMP */ default: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: NAK, ?\n")); /* Silently discard configuration option */ break; } /* switch */ pbuf_header(p, -cfghdr->len); len -= cfghdr->len; } /* while */ s = lcp_cfg_req(pcb, r); ppp_cp_output(pcb, PPP_LCP, LCP_CFG_REQ, ppp_next_id(), s); break; case LCP_CFG_REJ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_CFG_REJ\n")); if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN) { /* A terminate-ack is sent to indicate that we are in a closed state */ ppp_cp_output(pcb, PPP_LCP, LCP_TERM_ACK, ppp_next_id(), NULL); break; } while(len > 0) { cfghdr = p->payload; //pbuf_header(p, -PPP_CFGHDR_LEN); //len -= PPP_CFGHDR_LEN; switch(cfghdr->type) { case LCP_CFG_MRU: pcb->lcpopt &= ~LCP_CFG_OPT_MRU; break; case LCP_CFG_ACCM: pcb->lcpopt &= ~LCP_CFG_OPT_ACCM; break; case LCP_CFG_AUTH: pcb->lcpopt &= ~LCP_CFG_OPT_PAP; break;#if PPP_PHDR_COMP case LCP_CFG_P_COMP: pcb->lcpopt &= ~LCP_CFG_OPT_PFC; break;#endif /* PPP_PHDR_COMP */#if PPP_ACHDR_COMP case LCP_CFG_AC_COMP: pcb->lcpopt &= ~LCP_CFG_OPT_ACFC; break;#endif /* PPP_ACHDR_COMP */ default: break; } /* switch */ pbuf_header(p, -cfghdr->len); len -= cfghdr->len; } /* while */ s = lcp_cfg_req(pcb, NULL); ppp_cp_output(pcb, PPP_LCP, LCP_CFG_REQ, ppp_next_id(), s); break; case LCP_TERM_REQ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_TERM_REQ\n")); LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: Connection terminate request\n")); ppp_pbuf_ref_chain(p); /* Increase reference count so that ppp_cp_output don't free it */ ppp_cp_output(pcb, PPP_LCP, LCP_TERM_ACK, cphdr->id, p); if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN) { /* We are already closed */ break; } pcb->state = PPP_LCP_CLOSED; PPP_EVENT_DISCONNECTED(pcb, ERR_OK, PPP_LCP, ret); break; case LCP_TERM_ACK: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_TERM_ACK\n")); if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN) { break; /* Term-acks are silently discarded in this state to avoid creating a loop */ } pcb->state = PPP_LCP_CLOSED; PPP_EVENT_DISCONNECTED(pcb, ERR_OK, PPP_LCP, ret); break; case LCP_CODE_REJ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_CODE_REJ\n")); if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN) { break; /* Silently discarded */ } /* Handle a code reject depending on what code was rejected */ switch(*((u8_t *)p->payload)) { case LCP_CFG_REQ: case LCP_CFG_ACK: case LCP_CFG_NAK: case LCP_CFG_REJ: pcb->state = PPP_LCP_CLOSED; PPP_EVENT_CONNECTED(pcb, ERR_VAL, ret); break; case LCP_TERM_REQ: pcb->state = PPP_LCP_CLOSED; PPP_EVENT_DISCONNECTED(pcb, ERR_VAL, PPP_LCP, ret); break; case LCP_ECHO_REQ: PPP_EVENT_ECHO_RSP(pcb, ERR_VAL, ret); break; default: /* Silently discard packet */ break; } case LCP_PROTO_REJ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_CODE_REJ\n")); /* All rejections are catastrophic to this implementation */ if(pcb->state == PPP_LCP_OPEN) { ppp_cp_output(pcb, PPP_LCP, LCP_TERM_REQ, ppp_next_id(), NULL); pcb->state = PPP_LCP_CLOSING; } else { pcb->state = PPP_LCP_CLOSED; PPP_EVENT_DISCONNECTED(pcb, ERR_VAL, *((u16_t *)p->payload), ret); } break; case LCP_ECHO_REQ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_ECHO_REQ\n")); if(pcb->state < PPP_LCP_OPEN && pcb->state > PPP_IPCP_OPEN) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: Echo request silently discarded. State = %d\n", pcb->state)); break; /* Silently discarded */ } LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: Send echo response\n")); pbuf_ref(p); ppp_cp_output(pcb, PPP_LCP, LCP_ECHO_RSP, cphdr->id, p); /* Send echo reply */ break; case LCP_ECHO_RSP: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_ECHO_RSP\n")); PPP_EVENT_ECHO_RSP(pcb, ERR_OK, ret); break; case LCP_DISCARD_REQ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_DISCARD_REQ\n")); /* Silently discard packet */ break; default: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_UNKNOWN\n")); /* Code reject */ pbuf_header(p, 4); /* The data field in the reject packet begin with the information field */ ppp_pbuf_ref_chain(p); /* Increase reference count so that ppp_cp_output don't free it */ ppp_cp_output(pcb, PPP_LCP, LCP_CODE_REJ, cphdr->id, p); break; }}/*-----------------------------------------------------------------------------------*//* * ppp_process_ipcp(): * * Parses the received IPCP packet and handles it. *//*-----------------------------------------------------------------------------------*/voidppp_process_ipcp(struct ppp_pcb *pcb, struct pbuf *p){ struct ppp_cp_hdr *cphdr; struct pbuf *r, *s; struct ppp_cfg_hdr *cfghdr; struct ppp_req *req; u8_t rspstate = IPCP_CFG_ACK; u8_t ipaddropt = 0; /* Used in IPCP config requests to check if we have received an ip address option. If not, we append it to a NAK since configuration about the remote IP-address is required */ err_t ret; //struct ppp_pcb *tpcb; u16_t len; LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp\n")); /* Check if the remote IP-address should have been negotiated */ //for(tpcb = ppp_active_pcbs; tpcb != NULL; tpcb = tpcb->next) { // if(pcb->rfcommpcb == tpcb->rfcommpcb) { // break; /* We are serving a client that should request an IP-address from us */ // } //} cphdr = p->payload; pbuf_header(p, -PPP_CPHDR_LEN); cphdr->len = ntohs(cphdr->len); len = cphdr->len - PPP_CPHDR_LEN; if(cphdr->code == IPCP_CFG_ACK || cphdr->code == IPCP_CFG_NAK || cphdr->code == IPCP_CFG_REJ || cphdr->code == IPCP_CODE_REJ || cphdr->code == IPCP_TERM_ACK) { for(req = pcb->reqs; req != NULL; req = req->next) { /* Remove any matching request */ if(cphdr->id == req->id) { PPP_REQ_RMV(&(pcb->reqs), req); pbuf_free(req->p); LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: Free memory for request with code 0x%x***********\n", req->id)); lwbt_memp_free(MEMP_PPP_REQ, req); } } } LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: cphdr->code = 0x%x\n", cphdr->code)); /*{struct pbuf *q; for(q = p; q != NULL; q = q->next) { u16_t i; for(i = 0; i < q->len; ++i) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: 0x%x\n", ((u8_t *)q->payload)[i])); } LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: q->len == %d q->tot_len == %d\n", q->len, q->tot_len)); }} */ r = NULL; switch(cphdr->code) { case IPCP_CFG_REQ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_CFG_REQ\n")); if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN || pcb->state == PPP_LCP_CFG || pcb->state == PPP_LCP_CLOSING) { /* A terminate-ack is sent to indicate that ipcp is in a closed state */ ppp_cp_output(pcb, PPP_IPCP, IPCP_TERM_ACK, ppp_next_id(), NULL); break; } pcb->state = PPP_IPCP_CFG; while(len > 0) { cfghdr = p->payload; //pbuf_header(p, -PPP_CFGHDR_LEN); //len -= PPP_CFGHDR_LEN; switch(cfghdr->type) {#if PPP_VJ_COMP case IPCP_CFG_COMP: //TODO: IMPLEMENT pcb->ipcpcfg |= IPCP_CFG_IN_VJ; /* NAK - Parameter not acceptable */ /* if(rspstate == IPCP_CFG_ACK) { if(r != NULL) { pbuf_free(r); r = NULL; } r = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)r->payload, (u8_t *)p->payload, PPP_CFGHDR_LEN); *((u32_t *)(((u16_t *)r->payload)+1)) = 0; rspstate = IPCP_CFG_NAK; } else if (rspstate == IPCP_CFG_NAK) { s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)s->payload, (u8_t *)p->payload, PPP_CFGHDR_LEN); *((u32_t *)(((u16_t *)r->payload)+1)) = 0; if(r == NULL) { r = s; } else { pbuf_chain(r, s); pbuf_free(s); } }*/ /* if rspstate == IPCP_CFG_REJ do not add packet to outgoing pbuf */ break;#endif /* PPP_VJ_COMP */ case IPCP_CFG_IPADDR: ipaddropt = 1; //if(tpcb == NULL) { if(pcb->pppcfg & PPP_IR) { /* We are a client and the remote server has given us its ip-address */ pcb->bluetoothif->gw.addr = *((u32_t *)(((u16_t *)p->payload) + 1)); LWIP_DEBUGF(LWBT_PPP_DEBUG, ("We are a client and the remote server has given us its ip-address\nppp_process_ipcp: Remote IP address: %d.%d.%d.%d %ld\n", (u8_t)(ntohl(pcb->bluetoothif->gw.addr) >> 24) & 0xff, (u8_t)(ntohl(pcb->bluetoothif->gw.addr) >> 16) & 0xff, (u8_t)(ntohl(pcb->bluetoothif->gw.addr) >> 8) & 0xff, (u8_t)ntohl(pcb->bluetoothif->gw.addr) & 0xff, pcb->bluetoothif->gw.addr)); /* ACK - Parameter accepted */ if(rspstate == IPCP_CFG_ACK) { s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len); if(r == NULL) { r = s; } else { pbuf_chain(r, s); pbuf_free(s); } } } else { /* We are serving a client that we provide with an ip-address */ if(*((u32_t *)(((u16_t *)p->payload) + 1)) == pcb->bluetoothif->gw.addr) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("We are serving a client that we have provided with an ip-address: %d.%d.%d.%d %ld\n", (u8_t)(ntohl(pcb->bluetoothif->gw.addr) >> 24) & 0xff, (u8_t)(ntohl(pcb->bluetoothif->gw.addr) >> 16) & 0xff, (u8_t)(ntohl(pcb->bluetoothif->gw.addr) >> 8) & 0xff, (u8_t)ntohl(pcb->bluetoothif->gw.addr) & 0xff, pcb->bluetoothif->gw.addr)); /* ACK - Parameter accepted */ if(rspstate == IPCP_CFG_ACK) { s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len); if(r == NULL) { r = s; } else { pbuf_chain(r, s); pbuf_free(s); } } } else { /* NAK - Parameter not acceptable */ if(rspstate == IPCP_CFG_ACK) { if(r != NULL) { pbuf_free(r); r = NULL; } r = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)r->payload, (u8_t *)p->payload, PPP_CFGHDR_LEN); *((u32_t *)(((u16_t *)r->payload)+1)) = pcb->bluetoothif->gw.addr; rspstate = IPCP_CFG_NAK; } else if (rspstate == IPCP_CFG_NAK) { s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)s->payload, (u8_t *)p->payload, PPP_CFGHDR_LEN); *((u32_t *)(((u16_t *)s->payload)+1)) = pcb->bluetoothif->gw.addr; if(r == NULL) { r = s; } else { pbuf_chain(r, s); pbuf_free(s); } } /* if rspstate == IPCP_CFG_REJ do not add packet to outgoing pbuf */ } } break; case IPCP_CFG_PDNS: if(*((u32_t *)(((u16_t *)p->payload) + 1)) == PPP_IPCP_PDNS) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_CFG_PDNS ACK\n")); /* ACK - Parameter accepted */ if(rspstate == IPCP_CFG_ACK) { s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len); if(r == NULL) { r = s; } else { pbuf_chain(r, s); pbuf_free(s); } } } else { /* NAK - Parameter not acceptable */ if(rspstate == IPCP_CFG_ACK) { if(r != NULL) { pbuf_free(r); r = NULL; } r = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)r->payload, (u8_t *)p->payload, PPP_CFGHDR_LEN); *((u32_t *)(((u16_t *)r->payload)+1)) = PPP_IPCP_PDNS; rspstate = IPCP_CFG_NAK; } else if (rspstate == IPCP_CFG_NAK) { s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)s->payload, (u8_t *)p->payload, PPP_CFGHDR_LEN); *((u32_t *)(((u16_t *)s->payload)+1)) = PPP_IPCP_PDNS; if(r == NULL) { r = s; } else { pbuf_chain(r, s); pbuf_free(s); } } /* if rspstate == IPCP_CFG_REJ do not add packet to outgoing pbuf */ } break; case IPCP_CFG_PNBNS: if(*((u32_t *)(((u16_t *)p->payload) + 1)) == PPP_IPCP_NBNS) { /* ACK - Parameter accepted */ if(rspstate == IPCP_CFG_ACK) { s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM); memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len); if(r == NULL) { r = s; } else { pbuf_chain(r, s); pbuf_free(s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -