/* * Unknown Protocol Handler, sends reject */ static void ppp_reject_protocol(u16_t protocol, u8_t *buffer, u16_t count) { u16_t i; u8_t *dptr, *sptr; LCPPKT *pkt; /* first copy rejected packet back, start from end and work forward, +++ Pay attention to buffer managment when updated. Assumes fixed PPP blocks. */ DEBUG1(("Rejecting Protocol\n")); if((count + 6) > PPP_RX_BUFFER_SIZE) { /* This is a fatal error +++ do somthing about it. */ DEBUG1(("Cannot Reject Protocol, PKT to big\n")); return; } dptr = buffer + count + 6; sptr = buffer + count; for(i = 0; i < count; ++i) { *dptr-- = *sptr--; } pkt = (LCPPKT *)buffer; pkt->code = PROT_REJ; /* Write Conf_rej */ /*pkt->id = tid++;*/ /* write tid */ pkt->len = htons(count + 6); *((u16_t *)(&pkt->data[0])) = htons(protocol); ahdlc_tx(LCP, buffer, 0, (u16_t)(count + 6), 0); }
/* scan_packet(list,buffer,len) * * list = list of supported ID's * *buffer pointer to the first code in the packet * length of the codespace */ u16_t scan_packet(u16_t protocol, u8_t *list, u8_t *buffer, u8_t *options, u16_t len) { u8_t *tlist, *bptr; u8_t *tptr; u8_t bad = 0; u8_t i, j, good; bptr = tptr = options; /* scan through the packet and see if it has any unsupported codes */ while(bptr < options + len) { /* get code and see if it matches somwhere in the list, if not we don't support it */ i = *bptr++; /* DEBUG2("%x - ",i);*/ tlist = list; good = 0; while(*tlist) { /* DEBUG2("%x ",*tlist);*/ if(i == *tlist++) { good = 1; break; } } if(!good) { /* we don't understand it, write it back */ DEBUG1(("We don't understand option 0x%02x\n",i)); bad = 1; *tptr++ = i; j = *tptr++ = *bptr++; for(i = 0; i < j - 2; ++i) { *tptr++ = *bptr++; } } else { /* advance over to next option */ bptr += *bptr - 1; } } /* Bad? if we we need to send a config Reject */ if(bad) { /* write the config Rej packet we've built above, take on the header */ bptr = buffer; *bptr++ = CONF_REJ; /* Write Conf_rej */ bptr++; /* skip over ID */ *bptr++ = 0; *bptr = tptr - buffer; /* length right here? */ /* write the reject frame */ DEBUG1(("Writing Reject frame --\n")); ahdlc_tx(protocol, buffer, 0, (u16_t)(tptr - buffer), 0); DEBUG1(("\nEnd writing reject \n")); } return bad; }
/*---------------------------------------------------------------------------*/ void ppp_send(void) { /* If IPCP came up then our link should be up. */ if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) { ahdlc_tx(IPV4, &uip_buf[ UIP_LLH_LEN ], uip_appdata, UIP_TCPIP_HLEN, uip_len - UIP_TCPIP_HLEN); } }
void lcp_disconnect(struct ppp_context_s *ctx, u8_t id) { u8_t buffer[4]; u8_t *bptr = buffer; *bptr++ = TERM_REQ; *bptr++ = id; *bptr++ = 0; *bptr++ = 4; ahdlc_tx(ctx, LCP, 0, buffer, 0, bptr - buffer); }
void lcp_echo_request(struct ppp_context_s *ctx, u8_t *buffer) { u8_t *bptr; u16_t t; LCPPKT *pkt; if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP)) { if ((ppp_arch_clock_seconds() - ctx->lcp_prev_seconds) > LCP_ECHO_INTERVAL) { ctx->lcp_prev_seconds = ppp_arch_clock_seconds(); pkt = (LCPPKT *)buffer; /* Configure-Request only here, write id */ pkt->code = ECHO_REQ; pkt->id = ctx->ppp_id; bptr = pkt->data; *bptr++ = 0; *bptr++ = 0; *bptr++ = 0; *bptr++ = 0; /* Write length */ t = bptr - buffer; pkt->len = htons(t); /* length here - code and ID + */ DEBUG1((" len %d\n",t)); /* Send packet */ /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ DEBUG1(("\nWriting ECHO-REQUEST frame \n")); ahdlc_tx(ctx, LCP, 0, buffer, 0, t); DEBUG1(("- end ECHO-REQUEST Write frame\n")); } } }
/*---------------------------------------------------------------------------*/ void ipv6cp_task(u8_t *buffer) { u8_t *bptr; u16_t t; IPCPPKT *pkt; /* IPCP tx not up and hasn't timed out then lets see if we need to send a request */ if(!(ipv6cp_state & IPV6CP_TX_UP) && !(ipv6cp_state & IPV6CP_TX_TIMEOUT)) { /* Check if we have a request pending */ /*t=get_seconds()-ipv6cp_tx_time;*/ #if 1//0//phlb modify if(TIMER_timeout(IPV6CP_TIMEOUT)) { #else if((clock_seconds() - prev_ipv6cp_seconds) > IPV6CP_TIMEOUT) { prev_ipv6cp_seconds = clock_seconds(); #endif /* * No pending request, lets build one */ pkt=(IPCPPKT *)buffer; /* Configure-Request only here, write id */ pkt->code = CONF_REQ; pkt->id = ppp_id; bptr = (u8_t*)&pkt->data; /* * Write options, we want IP address, and DNS addresses if set. */ /* Write zeros for IP address the first time */ *bptr++ = 0x01;//IPV6CP_IPADDRESS; *bptr++ = 0x0a;//10 *bptr++ = ((u8_t*)uip_hostaddr.u8)[8]; *bptr++ = ((u8_t*)uip_hostaddr.u8)[9]; *bptr++ = ((u8_t*)uip_hostaddr.u8)[10]; *bptr++ = ((u8_t*)uip_hostaddr.u8)[11]; *bptr++ = ((u8_t*)uip_hostaddr.u8)[12]; *bptr++ = ((u8_t*)uip_hostaddr.u8)[13]; *bptr++ = ((u8_t*)uip_hostaddr.u8)[14]; *bptr++ = ((u8_t*)uip_hostaddr.u8)[15]; #ifdef IPV6CP_GET_PRI_DNS if(!(ipv6cp_state & IPCP_PRI_DNS_BIT)) { /* Write zeros for IP address the first time */ *bptr++ = IPV6CP_PRIMARY_DNS; *bptr++ = 0x6; *bptr++ = ((u8_t*)pri_dns_addr.u8)[0]; *bptr++ = ((u8_t*)pri_dns_addr.u8)[1]; *bptr++ = ((u8_t*)pri_dns_addr.u8)[2]; *bptr++ = ((u8_t*)pri_dns_addr.u8)[3]; } #endif #ifdef IPV6CP_GET_SEC_DNS if(!(ipv6cp_state & IPV6CP_SEC_DNS_BIT)) { /* Write zeros for IP address the first time */ *bptr++ = IPV6CP_SECONDARY_DNS; *bptr++ = 0x6; *bptr++ = ((u8_t*)sec_dns_addr)[0]; *bptr++ = ((u8_t*)sec_dns_addr)[1]; *bptr++ = ((u8_t*)sec_dns_addr)[2]; *bptr++ = ((u8_t*)sec_dns_addr)[3]; } #endif /* Write length */ t = bptr - buffer; /* length here - code and ID + */ pkt->len = uip_htons(t); ANNOTATE("\n**Sending IPV6CP Request packet\n"); /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(IPV6CP, 0, buffer, 0, t); /* Set timer */ /*ipv6cp_tx_time=get_seconds();*/ TIMER_set(); /* Inc retry */ /*ipv6cp_retry++;*/ // ppp_retry++; /* * Have we timed out? (combide the timers?) */ if(ppp_retry > IPV6CP_RETRY_COUNT) ipv6cp_state |= IPV6CP_TX_TIMEOUT; } } }
/* * IPCP RX protocol Handler */ void ipv6cp_rx(u8_t *buffer, u16_t count) { u8_t *bptr = buffer; // IPCPPKT *pkt=(IPCPPKT *)buffer; u16_t len; ANNOTATE("IPV6CP len %d\n",count); switch(*bptr++) { case CONF_REQ: /* parce request and see if we can ACK it */ ++bptr; len = (*bptr++ << 8); len |= *bptr++; /* len-=2; */ ANNOTATE("check lcplist\n"); if(scan_packet(IPV6CP, ipv6cplist, buffer, bptr, (u16_t)(len - 4))) { UIP_LOG("option was bad\n"); } else { ANNOTATE("IPV6CP options are good\n"); /* * Parse out the results */ /* lets try to implement what peer wants */ /* Reject any protocol not */ /* Error? if we we need to send a config Reject ++++ this is good for a subroutine*/ //GD-2011-09-15 None of the IPv6CP options are supported with current implementation. #if 0 #warning option implementation example based on IPCP IPv4 address configuration. /* All we should get is the peer IP address */ if(IPV6CP_IPADDRESS == *bptr++) { /* dump length */ ++bptr; #ifdef IPV6CP_GET_PEER_IP ((u8_t*)peer_ip_addr.u8)[0] = *bptr++; ((u8_t*)peer_ip_addr.u8)[1] = *bptr++; ((u8_t*)peer_ip_addr.u8)[2] = *bptr++; ((u8_t*)peer_ip_addr.u8)[3] = *bptr++; ANNOTATE("Peer IP "); /* printip(peer_ip_addr);*/ ANNOTATE("\n"); #else bptr += 18; #endif } else { UIP_LOG("HMMMM this shouldn't happen IPV6CP1\n"); } #endif #if 0 if(error) { /* write the config NAK packet we've built above, take on the header */ bptr = buffer; *bptr++ = CONF_NAK; /* Write Conf_rej */ *bptr++; /*tptr++;*/ /* skip over ID */ /* Write new length */ *bptr++ = 0; *bptr = tptr - buffer; /* write the reject frame */ UIP_LOG("Writing NAK frame \n"); ahdlc_tx(IPV6CP, buffer, (u16_t)(tptr - buffer)); ANNOTATE("- End NAK Write frame\n"); } else { } #endif /* * If we get here then we are OK, lets send an ACK and tell the rest * of our modules our negotiated config. */ ipv6cp_state |= IPV6CP_RX_UP; ipv6cp_state &= ~IPV6CP_TX_UP;//phlb force send request with ipv6cp task ANNOTATE("Send IPV6CP ACK!\n"); bptr = buffer; *bptr++ = CONF_ACK; /* Write Conf_ACK */ bptr++; /* Skip ID (send same one) */ /* * Set stuff */ ppp_flags |= tflag; ANNOTATE("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer)); /* write the ACK frame */ ANNOTATE("Writing ACK frame \n"); /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(IPV6CP, 0, buffer, 0, count /*bptr-buffer*/); ANNOTATE("- End ACK Write frame\n"); /* expire the timer to make things happen after a state change */ TIMER_expire(); //timer_expire(); //modify phlb uncomment /* } */ } break; // case CONF_ACK: /* config Ack */ ANNOTATE("CONF ACK\n"); /* * Parse out the results * * Dump the ID and get the length. */ /* dump the ID */ bptr++; /* get the length */ len = (*bptr++ << 8); len |= *bptr++; #if 0 //modify phlb /* Parse ACK and set data */ while(bptr < buffer + len) { switch(*bptr++) { case IPV6CP_IPADDRESS: /* dump length */ bptr++; ((u8_t*)ipaddr)[0] = *bptr++; ((u8_t*)ipaddr)[1] = *bptr++; ((u8_t*)ipaddr)[2] = *bptr++; ((u8_t*)ipaddr)[3] = *bptr++; break; case IPV6CP_PRIMARY_DNS: bptr++; ((u8_t*)pri_dns_addr)[0] = *bptr++; ((u8_t*)pri_dns_addr)[1] = *bptr++; ((u8_t*)pri_dns_addr)[2] = *bptr++; ((u8_t*)pri_dns_addr)[3] = *bptr++; break; case IPV6CP_SECONDARY_DNS: bptr++; ((u8_t*)sec_dns_addr)[0] = *bptr++; ((u8_t*)sec_dns_addr)[1] = *bptr++; ((u8_t*)sec_dns_addr)[2] = *bptr++; ((u8_t*)sec_dns_addr)[3] = *bptr++; break; default: UIP_LOG("IPV6CP CONFIG_ACK problem1\n"); } } #endif ipv6cp_state |= IPV6CP_TX_UP; //ipv6cp_state &= ~IPV6CP_RX_UP; ANNOTATE("were up! \n"); printip(pppif.ipaddr); #ifdef IPV6CP_GET_PRI_DNS printip(pri_dns_addr); #endif #ifdef IPV6CP_GET_SEC_DNS printip(sec_dns_addr); #endif ANNOTATE("\n"); /* expire the timer to make things happen after a state change */ TIMER_expire(); break; // case CONF_NAK: /* Config Nack */ UIP_LOG("CONF NAK\n"); /* dump the ID */ bptr++; /* get the length */ len = (*bptr++ << 8); len |= *bptr++; /* Parse ACK and set data */ while(bptr < buffer + len) { switch(*bptr++) { #if 0 #warning option implementation example based on IPCP IPv4 address configuration. case IPV6CP_IPADDRESS: /* dump length */ bptr++; ((u8_t*)pppif.ipaddr.u8)[0] = *bptr++; ((u8_t*)pppif.ipaddr.u8)[1] = *bptr++; ((u8_t*)pppif.ipaddr.u8)[2] = *bptr++; ((u8_t*)pppif.ipaddr.u8)[3] = *bptr++; uip_fw_register( &pppif ); ANNOTATE("My PPP-ipno: (%d.%d.%d.%d)\n", ((u8_t*)pppif.ipaddr.u8)[0], ((u8_t*)pppif.ipaddr.u8)[1], ((u8_t*)pppif.ipaddr.u8)[2], ((u8_t*)pppif.ipaddr.u8)[3]); break; #endif #ifdef IPV6CP_GET_PRI_DNS case IPV6CP_PRIMARY_DNS: bptr++; ((u8_t*)pri_dns_addr)[0] = *bptr++; ((u8_t*)pri_dns_addr)[1] = *bptr++; ((u8_t*)pri_dns_addr)[2] = *bptr++; ((u8_t*)pri_dns_addr)[3] = *bptr++; break; #endif #ifdef IPV6CP_GET_SEC_DNS case IPV6CP_SECONDARY_DNS: bptr++; ((u8_t*)sec_dns_addr)[0] = *bptr++; ((u8_t*)sec_dns_addr)[1] = *bptr++; ((u8_t*)sec_dns_addr)[2] = *bptr++; ((u8_t*)sec_dns_addr)[3] = *bptr++; break; #endif // default: UIP_LOG("IPCP CONFIG_ACK problem 2\n"); } } ppp_id++; printip(pppif.ipaddr); #ifdef IPV6CP_GET_PRI_DNS printip(pri_dns_addr); #endif #ifdef IPV6CP_GET_PRI_DNS printip(sec_dns_addr); #endif ANNOTATE("\n"); /* expire the timer to make things happen after a state change */ TIMER_expire(); break; case CONF_REJ: /* Config Reject */ ANNOTATE("CONF REJ\n"); /* Remove the offending options*/ ppp_id++; /* dump the ID */ bptr++; /* get the length */ len = (*bptr++ << 8); len |= *bptr++; /* Parse ACK and set data */ while(bptr < buffer + len) { switch(*bptr++) { #if 0 #warning option implementation example based on IPCP IPv4 address configuration. case IPV6CP_IPADDRESS: ipv6cp_state |= IPV6CP_IP_BIT; bptr += 5; break; #endif #ifdef IPV6CP_GET_PRI_DNS case IPV6CP_PRIMARY_DNS: ipv6cp_state |= IPV6CP_PRI_DNS_BIT; bptr += 5; break; #endif #ifdef IPV6CP_GET_PRI_DNS case IPV6CP_SECONDARY_DNS: ipv6cp_state |= IPV6CP_SEC_DNS_BIT; bptr += 5; break; #endif default: UIP_LOG("IPV6CP this shoudln't happen 3\n"); } } /* expire the timer to make things happen after a state change */ /*timer_expire(); */ break; default: UIP_LOG("-Unknown 4\n"); } }
/*---------------------------------------------------------------------------*/ void pap_task(u8_t *buffer) { u8_t *bptr; u16_t t; PAPPKT *pkt; /* If LCP is up and PAP negotiated, try to bring up PAP */ if(!(pap_state & PAP_TX_UP) && !(pap_state & PAP_TX_TIMEOUT)) { /* Do we need to send a PAP auth packet? Check if we have a request pending*/ if(1 == TIMER_timeout(PAP_TIMEOUT)) { /* Check if we have a request pending */ /* t=get_seconds()-pap_tx_time; if( t > pap_timeout) { */ /* We need to send a PAP authentication request */ DEBUG1(("\nSending PAP Request packet - ")); /* Build a PAP request packet */ pkt = (PAPPKT *)buffer; /* Configure-Request only here, write id */ pkt->code = CONF_REQ; pkt->id = ppp_id; bptr = pkt->data; /* Write options */ t = strlen(pap_username); /* Write peer length */ *bptr++ = (u8_t)t; bptr = memcpy(bptr, pap_username, t); t = strlen(pap_password); *bptr++ = (u8_t)t; bptr = memcpy(bptr, pap_password, t); /* Write length */ t = bptr - buffer; /* length here - code and ID + */ pkt->len = htons(t); DEBUG1((" Len %d\n",t)); /* Send packet */ ahdlc_tx(PAP, buffer, 0, t, 0); /* Set timer */ TIMER_set(); ppp_retry++; /* Have we failed? */ if(ppp_retry > 3) { DEBUG1(("PAP - timout\n")); pap_state &= PAP_TX_TIMEOUT; } } } }
void ipcp_task(struct ppp_context_s *ctx, u8_t *buffer) { u8_t *bptr; u16_t t; IPCPPKT *pkt; /* IPCP tx not up and hasn't timed out then lets see if we need to send a request */ if (!(ctx->ipcp_state & IPCP_TX_UP) && !(ctx->ipcp_state & IPCP_TX_TIMEOUT)) { /* Check if we have a request pending */ if ((ppp_arch_clock_seconds() - ctx->ipcp_prev_seconds) > IPCP_TIMEOUT) { ctx->ipcp_prev_seconds = ppp_arch_clock_seconds(); /* No pending request, lets build one */ pkt=(IPCPPKT *)buffer; /* Configure-Request only here, write id */ pkt->code = CONF_REQ; pkt->id = ctx->ppp_id; bptr = pkt->data; /* Write options, we want IP address, and DNS addresses if set. */ /* Write zeros for IP address the first time */ *bptr++ = IPCP_IPADDRESS; *bptr++ = 0x6; *bptr++ = (u8_t)((u8_t*)&ctx->local_ip)[0]; *bptr++ = (u8_t)((u8_t*)&ctx->local_ip)[1]; *bptr++ = (u8_t)((u8_t*)&ctx->local_ip)[2]; *bptr++ = (u8_t)((u8_t*)&ctx->local_ip)[3]; #ifdef IPCP_GET_PRI_DNS if (!(ppp_ipcp_state & IPCP_PRI_DNS_BIT)) { /* Write zeros for IP address the first time */ *bptr++ = IPCP_PRIMARY_DNS; *bptr++ = 0x6; *bptr++ = ((u8_t*)&ctx->pri_dns_addr)[0]; *bptr++ = ((u8_t*)&ctx->pri_dns_addr)[1]; *bptr++ = ((u8_t*)&ctx->pri_dns_addr)[2]; *bptr++ = ((u8_t*)&ctx->pri_dns_addr)[3]; } #endif #ifdef IPCP_GET_SEC_DNS if (!(ppp_ipcp_state & IPCP_SEC_DNS_BIT)) { /* Write zeros for IP address the first time */ *bptr++ = IPCP_SECONDARY_DNS; *bptr++ = 0x6; *bptr++ = ((u8_t*)&ctx->sec_dns_addr)[0]; *bptr++ = ((u8_t*)&ctx->sec_dns_addr)[1]; *bptr++ = ((u8_t*)&ctx->sec_dns_addr)[2]; *bptr++ = ((u8_t*)&ctx->sec_dns_addr)[3]; } #endif /* Write length */ t = bptr - buffer; /* length here - code and ID + */ pkt->len = htons(t); DEBUG1(("\n**Sending IPCP Request packet\n")); /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(ctx, IPCP, 0, buffer, 0, t); /* Inc retry */ ctx->ipcp_retry++; /* Have we timed out? (combine the timers?) */ if (ctx->ipcp_retry > IPCP_RETRY_COUNT) { ctx->ipcp_state &= IPCP_TX_TIMEOUT; } } } }
void ipcp_rx(struct ppp_context_s *ctx, u8_t *buffer, u16_t count) { u8_t *bptr = buffer; //IPCPPKT *pkt=(IPCPPKT *)buffer; u16_t len; DEBUG1(("IPCP len %d\n",count)); switch (*bptr++) { case CONF_REQ: /* Parse request and see if we can ACK it */ ++bptr; len = (*bptr++ << 8); len |= *bptr++; /* len-=2; */ DEBUG1(("check lcplist\n")); if (scan_packet(ctx, IPCP, ipcplist, buffer, bptr, (u16_t)(len - 4))) { DEBUG1(("option was bad\n")); } else { DEBUG1(("IPCP options are good\n")); /* Parse out the results */ /* lets try to implement what peer wants */ /* Reject any protocol not */ /* Error? if we we need to send a config Reject ++++ this is good for a subroutine*/ /* All we should get is the peer IP address */ if (IPCP_IPADDRESS == *bptr++) { /* Dump length */ ++bptr; #ifdef IPCP_GET_PEER_IP ((u8_t*)&ctx->peer_ip)[0] = *bptr++; ((u8_t*)&ctx->peer_ip)[1] = *bptr++; ((u8_t*)&ctx->peer_ip)[2] = *bptr++; ((u8_t*)&ctx->peer_ip)[3] = *bptr++; DEBUG1(("Peer IP ")); /* printip(peer_ip_addr); */ DEBUG1(("\n")); netlib_set_dripv4addr((char*)ctx->ifname, &ctx->peer_ip); #else bptr += 4; #endif } else { DEBUG1(("HMMMM this shouldn't happen IPCP1\n")); } #if 0 if (error) { /* Write the config NAK packet we've built above, take on the header */ bptr = buffer; *bptr++ = CONF_NAK; /* Write Conf_rej */ *bptr++; /*tptr++;*/ /* skip over ID */ /* Write new length */ *bptr++ = 0; *bptr = tptr - buffer; /* Write the reject frame */ DEBUG1(("Writing NAK frame \n")); ahdlc_tx(IPCP, buffer, (u16_t)(tptr - buffer)); DEBUG1(("- End NAK Write frame\n")); } else { } #endif /* If we get here then we are OK, lets send an ACK and tell the rest * of our modules our negotiated config. */ ctx->ipcp_state |= IPCP_RX_UP; DEBUG1(("Send IPCP ACK!\n")); bptr = buffer; *bptr++ = CONF_ACK; /* Write Conf_ACK */ bptr++; /* Skip ID (send same one) */ /* Set stuff */ /* ppp_flags |= tflag; */ DEBUG1(("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr - buffer))); /* Write the ACK frame */ DEBUG1(("Writing ACK frame \n")); /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(ctx, IPCP, 0, buffer, 0, count /*bptr-buffer*/); DEBUG1(("- End ACK Write frame\n")); } break; case CONF_ACK: /* config Ack */ DEBUG1(("CONF ACK\n")); /* Parse out the results * * Dump the ID and get the length. */ /* Dump the ID */ bptr++; /* Get the length */ len = (*bptr++ << 8); len |= *bptr++; #if 0 /* Parse ACK and set data */ while (bptr < buffer + len) { switch (*bptr++) { case IPCP_IPADDRESS: /* Dump length */ bptr++; ((u8_t*)ipaddr)[0] = *bptr++; ((u8_t*)ipaddr)[1] = *bptr++; ((u8_t*)ipaddr)[2] = *bptr++; ((u8_t*)ipaddr)[3] = *bptr++; break; case IPCP_PRIMARY_DNS: bptr++; ((u8_t*)pri_dns_addr)[0] = *bptr++; ((u8_t*)pri_dns_addr)[1] = *bptr++; ((u8_t*)pri_dns_addr)[2] = *bptr++; ((u8_t*)pri_dns_addr)[3] = *bptr++; break; case IPCP_SECONDARY_DNS: bptr++; ((u8_t*)sec_dns_addr)[0] = *bptr++; ((u8_t*)sec_dns_addr)[1] = *bptr++; ((u8_t*)sec_dns_addr)[2] = *bptr++; ((u8_t*)sec_dns_addr)[3] = *bptr++; break; default: DEBUG1(("IPCP CONFIG_ACK problem1\n")); } } #endif ctx->ipcp_state |= IPCP_TX_UP; /*ppp_ipcp_state &= ~IPCP_RX_UP;*/ DEBUG1(("were up! \n")); //printip(pppif.ipaddr); #ifdef IPCP_GET_PRI_DNS printip(pri_dns_addr); #endif #ifdef IPCP_GET_SEC_DNS printip(sec_dns_addr); #endif DEBUG1(("\n")); break; case CONF_NAK: /* Config Nack */ DEBUG1(("CONF NAK\n")); /* Dump the ID */ bptr++; /* Get the length */ len = (*bptr++ << 8); len |= *bptr++; /* Parse ACK and set data */ while (bptr < buffer + len) { switch (*bptr++) { case IPCP_IPADDRESS: /* dump length */ bptr++; ((u8_t*)&ctx->local_ip)[0] = (char)*bptr++; ((u8_t*)&ctx->local_ip)[1] = (char)*bptr++; ((u8_t*)&ctx->local_ip)[2] = (char)*bptr++; ((u8_t*)&ctx->local_ip)[3] = (char)*bptr++; netlib_ifup((char*)ctx->ifname); netlib_set_ipv4addr((char*)ctx->ifname, &ctx->local_ip); //DEBUG1(("My PPP-ipno: (%d.%d.%d.%d)\n", ((u8_t*)pppif.ipaddr)[0], ((u8_t*)pppif.ipaddr)[1], ((u8_t*)pppif.ipaddr)[2], ((u8_t*)pppif.ipaddr)[3])); break; #ifdef IPCP_GET_PRI_DNS case IPCP_PRIMARY_DNS: bptr++; ((u8_t*)&ctx->pri_dns_addr)[0] = *bptr++; ((u8_t*)&ctx->pri_dns_addr)[1] = *bptr++; ((u8_t*)&ctx->pri_dns_addr)[2] = *bptr++; ((u8_t*)&ctx->pri_dns_addr)[3] = *bptr++; break; #endif #ifdef IPCP_GET_SEC_DNS case IPCP_SECONDARY_DNS: bptr++; ((u8_t*)&ctx->sec_dns_addr)[0] = *bptr++; ((u8_t*)&ctx->sec_dns_addr)[1] = *bptr++; ((u8_t*)&ctx->sec_dns_addr)[2] = *bptr++; ((u8_t*)&ctx->sec_dns_addr)[3] = *bptr++; break; #endif default: DEBUG1(("IPCP CONFIG_ACK problem 2\n")); } } ctx->ppp_id++; printip(pppif.ipaddr); #ifdef IPCP_GET_PRI_DNS printip(pri_dns_addr); #endif #ifdef IPCP_GET_PRI_DNS printip(sec_dns_addr); #endif DEBUG1(("\n")); break; case CONF_REJ: /* Config Reject */ DEBUG1(("CONF REJ\n")); /* Remove the offending options*/ ctx->ppp_id++; /* Dump the ID */ bptr++; /* Get the length */ len = (*bptr++ << 8); len |= *bptr++; /* Parse ACK and set data */ while (bptr < buffer + len) { switch (*bptr++) { case IPCP_IPADDRESS: ctx->ipcp_state |= IPCP_IP_BIT; bptr += 5; break; #ifdef IPCP_GET_PRI_DNS case IPCP_PRIMARY_DNS: ctx->ipcp_state |= IPCP_PRI_DNS_BIT; bptr += 5; break; #endif #ifdef IPCP_GET_PRI_DNS case IPCP_SECONDARY_DNS: ctx->ipcp_state |= IPCP_SEC_DNS_BIT; bptr += 5; break; #endif default: DEBUG1(("IPCP this shoudln't happen 3\n")); } } break; default: DEBUG1(("-Unknown 4\n")); } }
/*---------------------------------------------------------------------------*/ void ipcp_task(u8_t *buffer) { u8_t *bptr; u16_t t; IPCPPKT *pkt; /* IPCP tx not up and hasn't timed out then lets see if we need to send a request */ if(!(ipcp_state & IPCP_TX_UP) && !(ipcp_state & IPCP_TX_TIMEOUT)) { /* Check if we have a request pending */ /*t=get_seconds()-ipcp_tx_time;*/ if(TIMER_timeout(IPCP_TIMEOUT)) { /* * No pending request, lets build one */ pkt=(IPCPPKT *)buffer; /* Configure-Request only here, write id */ pkt->code = CONF_REQ; pkt->id = ppp_id; bptr = pkt->data; /* * Write options, we want IP address, and DNS addresses if set. */ /* Write zeros for IP address the first time */ *bptr++ = IPCP_IPADDRESS; *bptr++ = 0x6; *bptr++ = our_ipaddr.ip8[0]; *bptr++ = our_ipaddr.ip8[1]; *bptr++ = our_ipaddr.ip8[2]; *bptr++ = our_ipaddr.ip8[3]; #ifdef IPCP_GET_PRI_DNS if(!(ipcp_state & IPCP_PRI_DNS_BIT)) { /* Write zeros for IP address the first time */ *bptr++ = IPCP_PRIMARY_DNS; *bptr++ = 0x6; *bptr++ = pri_dns_addr.ip8[0]; *bptr++ = pri_dns_addr.ip8[1]; *bptr++ = pri_dns_addr.ip8[2]; *bptr++ = pri_dns_addr.ip8[3]; } #endif #ifdef IPCP_GET_SEC_DNS if(!(ipcp_state & IPCP_SEC_DNS_BIT)) { /* Write zeros for IP address the first time */ *bptr++ = IPCP_SECONDARY_DNS; *bptr++ = 0x6; *bptr++ = sec_dns_addr.ip8[0]; *bptr++ = sec_dns_addr.ip8[1]; *bptr++ = sec_dns_addr.ip8[2]; *bptr++ = sec_dns_addr.ip8[3]; } #endif /* Write length */ t = bptr - buffer; /* length here - code and ID + */ pkt->len = htons(t); DEBUG1(("\n**Sending IPCP Request packet\n")); /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(IPCP, 0, buffer, 0, t); /* Set timer */ /*ipcp_tx_time=get_seconds();*/ TIMER_set(); /* Inc retry */ /*ipcp_retry++;*/ ppp_retry++; /* * Have we timed out? (combide the timers?) */ if(ppp_retry > IPCP_RETRY_COUNT) ipcp_state &= IPCP_TX_TIMEOUT; } } }
/*---------------------------------------------------------------------------*/ void ipcp_tx_confreq(u8_t *buffer){ u8_t *bptr; u16_t t; IPCPPKT *pkt; /* * No pending request, lets build one */ pkt=(IPCPPKT *)buffer; /* Configure-Request only here, write id */ pkt->code = CONF_REQ; pkt->id = ppp_id; bptr = (u8_t*)&pkt->data; /* * Write options, we want IP address, and DNS addresses if set. */ /* Write zeros for IP address the first time */ *bptr++ = IPCP_IPADDRESS; *bptr++ = 0x6; *bptr++ = ((u8_t*)pppif.ipaddr.u8)[0]; *bptr++ = ((u8_t*)pppif.ipaddr.u8)[1]; *bptr++ = ((u8_t*)pppif.ipaddr.u8)[2]; *bptr++ = ((u8_t*)pppif.ipaddr.u8)[3]; #ifdef IPCP_GET_PRI_DNS if(!(ipcp_state & IPCP_PRI_DNS_BIT)) { /* Write zeros for IP address the first time */ *bptr++ = IPCP_PRIMARY_DNS; *bptr++ = 0x6; *bptr++ = ((u8_t*)pri_dns_addr.u8)[0]; *bptr++ = ((u8_t*)pri_dns_addr.u8)[1]; *bptr++ = ((u8_t*)pri_dns_addr.u8)[2]; *bptr++ = ((u8_t*)pri_dns_addr.u8)[3]; } #endif #ifdef IPCP_GET_SEC_DNS if(!(ipcp_state & IPCP_SEC_DNS_BIT)) { /* Write zeros for IP address the first time */ *bptr++ = IPCP_SECONDARY_DNS; *bptr++ = 0x6; *bptr++ = sec_dns_addr.u8[0]; *bptr++ = sec_dns_addr.u8[1]; *bptr++ = sec_dns_addr.u8[2]; *bptr++ = sec_dns_addr.u8[3]; } #endif /* Write length */ t = bptr - buffer; /* length here - code and ID + */ pkt->len = uip_htons(t); ANNOTATE("\n**Sending IPCP Request packet\n"); /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(IPCP, 0, buffer, 0, t); }
void lcp_task(struct ppp_context_s *ctx, u8_t *buffer) { u8_t *bptr; u16_t t; LCPPKT *pkt; /* lcp tx not up and hasn't timed out then lets see if we need to send a * request */ if (!(ctx->lcp_state & LCP_TX_UP) && !(ctx->lcp_state & LCP_TX_TIMEOUT)) { /* Check if we have a request pending */ if ((ppp_arch_clock_seconds() - ctx->lcp_prev_seconds) > LCP_TIMEOUT) { ctx->lcp_prev_seconds = ppp_arch_clock_seconds(); DEBUG1(("\nSending LCP request packet - ")); /* No pending request, lets build one */ pkt = (LCPPKT *)buffer; /* Configure-Request only here, write id */ pkt->code = CONF_REQ; pkt->id = ctx->ppp_id; bptr = pkt->data; /* Write options */ *bptr++ = LPC_ACCM; *bptr++ = 0x6; *bptr++ = 0xff; *bptr++ = 0xff; *bptr++ = 0xff; *bptr++ = 0xff; #if 0 /* Write magic number */ DEBUG1(("LPC_MAGICNUMBER -")); *bptr++ = LPC_MAGICNUMBER; *bptr++ = 0x6; /* *bptr++ = random_rand() & 0xff; *bptr++ = random_rand() & 0xff; *bptr++ = random_rand() & 0xff; *bptr++ = random_rand() & 0xff; */ *bptr++ = 0x11; *bptr++ = 0x11; *bptr++ = 0x11; *bptr++ = 0x11; #endif #if 0 /* Authentication protocol */ if ((lcp_tx_options & LCP_OPT_AUTH) && 0) { /* If turned on, we only negotiate PAP */ *bptr++ = LPC_AUTH; *bptr++ = 0x4; *bptr++ = 0xc0; *bptr++ = 0x23; } /* PFC */ if ((lcp_tx_options & LCP_OPT_PFC) && 0) { /* If turned on, we only negotiate PAP */ *bptr++ = LPC_PFC; *bptr++ = 0x2; } /* ACFC */ if ((lcp_tx_options & LCP_OPT_ACFC) && 0) { /* If turned on, we only negotiate PAP */ *bptr++ = LPC_ACFC; *bptr++ = 0x2; } #endif /* Write length */ t = bptr - buffer; pkt->len = htons(t); /* length here - code and ID + */ DEBUG1((" len %d\n",t)); /* Send packet */ /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(ctx, LCP, 0, buffer, 0, t); /* Inc retry */ ctx->lcp_retry++; /* Have we timed out? */ if (ctx->lcp_retry > LCP_RETRY_COUNT) { ctx->lcp_state &= LCP_TX_TIMEOUT; } } } }
void lcp_rx(struct ppp_context_s *ctx, u8_t *buffer, u16_t count) { u8_t *bptr = buffer, *tptr; u8_t error = 0; u8_t id; u16_t len, j; switch (*bptr++) { case CONF_REQ: /* config request */ /* Parse request and see if we can ACK it */ id = *bptr++; len = (*bptr++ << 8); len |= *bptr++; /*len -= 2;*/ /* In case of new peer connection */ ipcp_init(ctx); ctx->lcp_state &= ~LCP_TX_UP; DEBUG1(("received [LCP Config Request id %u\n", id)); if (scan_packet(ctx, (u16_t)LCP, lcplist, buffer, bptr, (u16_t)(len-4))) { /* Must do the -4 here, !scan packet */ DEBUG1((" options were rejected\n")); } else { /* Lets try to implement what peer wants */ tptr = bptr = buffer; bptr += 4; /* skip code, id, len */ error = 0; /* First scan for unknown values */ while(bptr < (buffer + len)) { switch (*bptr++) { case LPC_MRU: /* mru */ j = *bptr++; j -= 2; if (j == 2) { ctx->ppp_tx_mru = ((int)*bptr++) << 8; ctx->ppp_tx_mru |= *bptr++; DEBUG1(("<mru %d> ", ctx->ppp_tx_mru)); } else { DEBUG1(("<mru ?? > ")); } break; case LPC_ACCM: bptr++; /* skip length */ j = *bptr++; j += *bptr++; j += *bptr++; j += *bptr++; if (j==0) { // ok DEBUG1(("<asyncmap sum=0x%04x>",j)); //ahdlc_flags |= PPP_TX_ASYNC_MAP; } else if (j!=0) { // ok DEBUG1(("<asyncmap sum=0x%04x>, assume 0xffffffff",j)); } else { /* Fail. We only support default or all zeros */ DEBUG1(("We only support default or all zeros for ACCM ")); error = 1; *tptr++ = LPC_ACCM; *tptr++ = 0x6; *tptr++ = 0; *tptr++ = 0; *tptr++ = 0; *tptr++ = 0; } break; case LPC_AUTH: bptr++; if ((*bptr++ == 0xc0) && (*bptr++ == 0x23)) { /* Negotiate PAP */ if (strlen((char*)ctx->pap_username) > 0) { DEBUG1(("<auth pap> ")); ctx->lcp_state |= LCP_RX_AUTH; } else { DEBUG1(("<rej auth pap> ")); *tptr++ = CONF_REJ; tptr++; // Keep ID *tptr++ = 0; *tptr++ = 8; *tptr++ = LPC_AUTH; *tptr++ = 0x4; *tptr++ = 0xc0; *tptr++ = 0x23; ahdlc_tx(ctx, LCP, 0, buffer, 0, (u16_t)(tptr-buffer)); return; } } else { /* We only support PAP */ DEBUG1(("<auth ?? >")); error = 1; *tptr++ = LPC_AUTH; *tptr++ = 0x4; *tptr++ = 0xc0; *tptr++ = 0x23; } break; case LPC_MAGICNUMBER: DEBUG1(("<magic > ")); /* Compare incoming number to our number (not implemented) */ bptr++; /* For now just dump */ bptr++; bptr++; bptr++; bptr++; break; case LPC_PFC: bptr++; DEBUG1(("<pcomp> ")); /*tflag|=PPP_PFC;*/ break; case LPC_ACFC: bptr++; DEBUG1(("<accomp> ")); /*tflag|=PPP_ACFC;*/ break; } } /* Error? if we we need to send a config Reject ++++ this is good * for a subroutine. */ if (error) { /* Write the config NAK packet we've built above, take on the * header */ bptr = buffer; *bptr++ = CONF_NAK; /* Write Conf_rej */ bptr++;/*tptr++;*/ /* skip over ID */ /* Write new length */ *bptr++ = 0; *bptr = tptr - buffer; /* Write the reject frame */ DEBUG1(("\nWriting NAK frame \n")); // Send packet ahdlc_txz(procol,header,data,headerlen,datalen); ahdlc_tx(ctx, LCP, 0, buffer, 0, (u16_t)(tptr-buffer)); DEBUG1(("- end NAK Write frame\n")); } else { /* If we get here then we are OK, lets send an ACK and tell the rest * of our modules our negotiated config. */ DEBUG1(("\nSend ACK!\n")); bptr = buffer; *bptr++ = CONF_ACK; /* Write Conf_ACK */ bptr++; /* Skip ID (send same one) */ /* Set stuff */ /*ppp_flags|=tflag;*/ /* DEBUG2("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer)); */ /* Write the ACK frame */ DEBUG2(("Writing ACK frame \n")); /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(ctx, LCP, 0, buffer, 0, count /*bptr-buffer*/); DEBUG2(("- end ACK Write frame\n")); ctx->lcp_state |= LCP_RX_UP; } } break; case CONF_ACK: /* config Ack Anytime we do an ack reset the timer to force send. */ DEBUG1(("LCP-ACK - ")); /* Check that ID matches one sent */ if (*bptr++ == ctx->ppp_id) { /* Change state to PPP up. */ DEBUG1((">>>>>>>> good ACK id up! %d\n", ctx->ppp_id)); /* Copy negotiated values over */ ctx->lcp_state |= LCP_TX_UP; } else { DEBUG1(("*************++++++++++ bad id %d\n", ctx->ppp_id)); } break; case CONF_NAK: /* Config Nack */ DEBUG1(("LCP-CONF NAK\n")); ctx->ppp_id++; break; case CONF_REJ: /* Config Reject */ DEBUG1(("LCP-CONF REJ\n")); ctx->ppp_id++; break; case TERM_REQ: /* Terminate Request */ DEBUG1(("LCP-TERM-REQ -")); bptr = buffer; *bptr++ = TERM_ACK; /* Write TERM_ACK */ /* Write the reject frame */ DEBUG1(("Writing TERM_ACK frame \n")); /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ ahdlc_tx(ctx, LCP, 0, buffer, 0, count); ctx->lcp_state &= ~LCP_TX_UP; ctx->lcp_state |= LCP_TERM_PEER; break; case TERM_ACK: DEBUG1(("LCP-TERM ACK\n")); break; case ECHO_REQ: if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP)) { bptr = buffer; *bptr++ = ECHO_REP; /* Write ECHO-REPLY */ bptr += 3; /* Skip id and length */ *bptr++ = 0; /* Zero Magic */ *bptr++ = 0; *bptr++ = 0; *bptr++ = 0; /* Write the echo reply frame */ DEBUG1(("\nWriting ECHO-REPLY frame \n")); // Send packet ahdlc_txz(procol,header,data,headerlen,datalen); ahdlc_tx(ctx, LCP, 0, buffer, 0, count); DEBUG1(("- end ECHO-REPLY Write frame\n")); } break; case ECHO_REP: DEBUG1(("LCP-ECHO REPLY\n")); if ((ctx->lcp_state & LCP_TX_UP) && (ctx->lcp_state & LCP_RX_UP)) { ctx->ppp_id++; } break; default: DEBUG1(("LCP unknown packet: %02x", *(bptr-1))); break; } }