📄 ppp.c
字号:
} } } 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_NBNS; 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_NBNS; 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_SDNS: if(*((u32_t *)(((u16_t *)p->payload) + 1)) == PPP_IPCP_SDNS) { /* 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_SDNS; 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_SDNS; 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_SNBNS: if(*((u32_t *)(((u16_t *)p->payload) + 1)) == PPP_IPCP_SNBNS) { /* 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_SNBNS; 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_SNBNS; 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; default: /* Reject parameter */ if(rspstate != IPCP_CFG_REJ) { rspstate = IPCP_CFG_REJ; if(r != NULL) { pbuf_free(r); r = NULL; } } 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); } break; } pbuf_header(p, -cfghdr->len); len -= cfghdr->len; } /* while */ /* Check if we are serving a client that should have requested an IP-address from us */ //if(!ipaddropt && tpcb != NULL) { if(!ipaddropt && !(pcb->pppcfg & PPP_IR)) { /* NAK - the remote IP-address must be negotiated */ if(rspstate == IPCP_CFG_ACK) { if(r != NULL) { pbuf_free(r); } r = pbuf_alloc(PBUF_RAW, PPP_CFGHDR_LEN + 4, PBUF_RAM); cfghdr = r->payload; cfghdr->type = IPCP_CFG_IPADDR; cfghdr->len = PPP_CFGHDR_LEN + 4; *((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, PPP_CFGHDR_LEN + 4, PBUF_RAM); cfghdr = s->payload; cfghdr->type = IPCP_CFG_IPADDR; cfghdr->len = PPP_CFGHDR_LEN + 4; *((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 */ } if(!(pcb->pppcfg & PPP_IR) && !(pcb->ipcpcfg & IPCP_CFG_OUT_REQ)) { /* Send an IPCP configure request for outgoing link if it hasnt been configured */ ipcp_cfg_req(pcb); pcb->ipcpcfg |= IPCP_CFG_OUT_REQ; } /* Send response to configuration request */ ppp_cp_output(pcb, PPP_IPCP, rspstate, cphdr->id, r); if(rspstate == IPCP_CFG_ACK) { pcb->ipcpcfg |= IPCP_CFG_OUT_ACK; /* IPCP connection established if a configuration ack has been sent */ if(pcb->ipcpcfg & IPCP_CFG_IN_ACK) { /* IPCP connection established, notify upper layer that connection is open */ pcb->state = PPP_IPCP_OPEN; PPP_EVENT_CONNECTED(pcb, ERR_OK, ret); } } break; case IPCP_CFG_ACK: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_CFG_ACK\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->ipcpcfg |= IPCP_CFG_IN_ACK; pcb->naks = 0; 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_OUT_VJ; break;#endif /* PPP_VJ_COMP */ default: /* Silently discard option */ break; } /* switch */ pbuf_header(p, -(cfghdr->len)); len -= cfghdr->len; } /* while */ /* IPCP connection established if a configuration ack has been sent */ if(pcb->ipcpcfg & IPCP_CFG_OUT_ACK) { /* IPCP connection established, notify upper layer that connection is open */ pcb->state = PPP_IPCP_OPEN; PPP_EVENT_CONNECTED(pcb, ERR_OK, ret); } break; case IPCP_CFG_NAK: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_CFG_NAK\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->naks; if(pcb->naks == PPP_MAX_FAILURE) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: ipcp negotiation failed\n")); ppp_disconnect(pcb); /* IPCP configuration attempt failed. Disconnect LCP */ 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) {#if PPP_VJ_COMP case IPCP_CFG_COMP: //TODO: IMPLEMENT pcb->ipcpopt &= ~IPCP_CFG_OPT_VJ; break;#endif /* PPP_VJ_COMP */ case IPCP_CFG_IPADDR: /* We have been given a local ip address by the remote host */ pcb->bluetoothif->ip_addr.addr = *((u32_t *)(((u16_t *)p->payload) + 1)); LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: Local IP address: %d.%d.%d.%d %ld\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, pcb->bluetoothif->ip_addr.addr)); break; default: /* Silently discard configuration option */ break; } /* switch */ pbuf_header(p, -cfghdr->len); len -= cfghdr->len; } /* while */ ipcp_cfg_req(pcb); /* Send new ipcp configuration request */ break; case IPCP_CFG_REJ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_CFG_REJ\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; } 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: pcb->ipcpopt &= ~IPCP_CFG_OPT_VJ; break;#endif /* PPP_VJ_COMP */ case IPCP_CFG_IPADDR: pcb->ipcpopt &= ~IPCP_CFG_OPT_IP; break; default: /* Silently discard configuration option */ break; } /* switch */ pbuf_header(p, -cfghdr->len); len -= cfghdr->len; } /* while */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: Send new ipcp configuration request\n")); ipcp_cfg_req(pcb); /* Send new ipcp configuration request */ break; case IPCP_TERM_REQ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_TERM_REQ\n")); ppp_pbuf_ref_chain(p); /* Increase reference count so that ppp_cp_output don't delete the buffer */ ppp_cp_output(pcb, PPP_IPCP, IPCP_TERM_ACK, cphdr->id, p); if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN || pcb->state == PPP_LCP_CFG || pcb->state == PPP_LCP_CLOSING) { /* We are already closed */ break; } pcb->state = PPP_LCP_OPEN; PPP_EVENT_DISCONNECTED(pcb, ERR_OK, PPP_IPCP, ret); break; case IPCP_TERM_ACK: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_TERM_ACK\n")); if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN || pcb->state == PPP_LCP_CFG || pcb->state == PPP_LCP_CLOSING) { break; /* Term-acks are silently discarded in this state to avoid creating a loop */ } pcb->state = PPP_LCP_OPEN; PPP_EVENT_DISCONNECTED(pcb, ERR_OK, PPP_IPCP, ret); break; case IPCP_CODE_REJ: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_CODE_REJ\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; } /* Handle a code reject depending on what code was rejected */ switch(*((u8_t *)p->payload)) { case IPCP_CFG_REQ: case IPCP_CFG_ACK: case IPCP_CFG_NAK: case IPCP_CFG_REJ: pcb->state = PPP_LCP_OPEN; PPP_EVENT_CONNECTED(pcb, ERR_VAL, ret); break; case IPCP_TERM_REQ: pcb->state = PPP_LCP_OPEN; PPP_EVENT_DISCONNECTED(pcb, ERR_VAL, PPP_IPCP, ret); break; default: /* Silently discard */ break; } break; default: LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_ipcp: IPCP_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_IPCP, IPCP_CODE_REJ, cphdr->id, p); break; }}/*-----------------------------------------------------------------------------------*//* * ppp_process_pap(): * * Parses the received PAP packet and handles it. *//*-----------------------------------------------------------------------------------*/voidppp_process_pap(struct ppp_pcb *pcb, struct pbuf *p) { //TODO: Implement LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_pap: not implemented yet!\n"));}/*-----------------------------------------------------------------------------------*//* * ppp_input(): * * Called by the lower layer. Reassembles and unstuffs the packet, does a frame check, * parses the header and forward it to the upper layer, LCP, IPCP or PAP handler. *//*-----------------------------------------------------------------------------------*/err_tppp_input(void *arg, struct rfcomm_pcb *rfcommpcb, struct pbuf *p, err_t err){ struct ppp_pcb *pcb; u16_t proto; struct pbuf *q, *r; u8_t *payload; err_t ret; u16_t i; /* Search active pcbs for matching connection */ for(pcb = ppp_active_pcbs; pcb != NULL; pcb = pcb->next) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Found matching connection\n")); if(pcb->rfcommpcb == rfcommpcb) { break; } } if(pcb == NULL) { for(pcb = ppp_listen_pcbs; pcb != NULL; pcb = pcb->next) { if(pcb->rfcommpcb == rfcommpcb) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Found matching listening connection\n")); break; } } if(pcb == NULL) { /* Silently discard incoming data not belonging to any RFCOMM connection */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Silently discard incoming data not belonging to any RFCOMM connection\n")); pbuf_free(p); return ERR_OK; } } for(q = p; q != NULL; q = q->next) { payload = (u8_t *)q->payload; for(i = 0; i < q->len; ++i) { if(pcb->p == NULL) { /* Alloc new pbuf. LwIP will handle dealloc */ LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Pbuf == NULL. Allocate and add new head\n")); if((pcb->p = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL)) == NULL) { LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_input: Could not allocate memory for pbuf pcb->p\n")); pbuf_free(p); return ERR_MEM; /* Could not allocate memory for pbuf */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -