u16_t ppp_raise(u8_t config, u8_t *username, u8_t *password) { u16_t status = 0; /* Initialize PPP engine */ /* init_ppp(); */ pap_init(); ipcp_init(); lcp_init(); /* Enable PPP */ ppp_flags = PPP_RX_READY; /* Try to bring up the layers */ while(status == 0) { #ifdef SYSTEM_POLLER /* If the the serial interrupt is not hooked to ahdlc_rx, or the system needs to handle other stuff while were blocking, call the system poller.*/ system_poller(); #endif /* call the lcp task to bring up the LCP layer */ lcp_task(ppp_tx_buffer); /* If LCP is up, neg next layer */ if(lcp_state & LCP_TX_UP) { /* If LCP wants PAP, try to authenticate, else bring up IPCP */ if((lcp_state & LCP_RX_AUTH) && (!(pap_state & PAP_TX_UP))) { pap_task(ppp_tx_buffer,username,password); } else { ipcp_task(ppp_tx_buffer); } } /* If IPCP came up then our link should be up. */ if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) { break; } status = check_ppp_errors(); } return status; }
/*---------------------------------------------------------------------------*/ void ppp_init() { ppp_rx_frame_count = 0; #if PACKET_RX_DEBUG done = 0; #endif ppp_flags = 0; pap_init(); // #if UIP_CONF_IPV6 ipv6cp_init(); #else ipcp_init(); #endif // lcp_init(); ppp_flags = 0; ahdlc_init(ppp_rx_buffer, PPP_RX_BUFFER_SIZE); ahdlc_rx_ready(); }
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; } }
/** * Initialize the npppd_ppp instance * Set npppd_ppp#mru and npppd_ppp#phy_label before call this function. */ int ppp_init(npppd *pppd, npppd_ppp *_this) { PPP_ASSERT(_this != NULL); PPP_ASSERT(strlen(_this->phy_label) > 0); _this->id = -1; _this->ifidx = -1; _this->has_acf = 1; _this->recv_packet = ppp_recv_packet; _this->id = ppp_seq++; _this->pppd = pppd; lcp_init(&_this->lcp, _this); _this->mru = ppp_config_int(_this, "lcp.mru", DEFAULT_MRU); if (_this->outpacket_buf == NULL) { _this->outpacket_buf = malloc(_this->mru + 64); if (_this->outpacket_buf == NULL){ log_printf(LOG_ERR, "malloc() failed in %s(): %m", __func__); return -1; } } _this->adjust_mss = ppp_config_str_equal(_this, "ip.adjust_mss", "true", 0); #ifdef USE_NPPPD_PIPEX _this->use_pipex = ppp_config_str_equal(_this, "pipex.enabled", "true", 1); #endif /* load the logging configuration */ _this->log_dump_in = ppp_config_str_equal(_this, "log.in.pktdump", "true", 0); _this->log_dump_out = ppp_config_str_equal(_this, "log.out.pktdump", "true", 0); _this->ingress_filter = ppp_config_str_equal(_this, "ingress_filter", "true", 0); #ifdef USE_NPPPD_MPPE mppe_init(&_this->mppe, _this); #endif ccp_init(&_this->ccp, _this); ipcp_init(&_this->ipcp, _this); pap_init(&_this->pap, _this); chap_init(&_this->chap, _this); /* load the idle timer configuration */ _this->timeout_sec = ppp_config_int(_this, "idle_timeout", 0); if (!evtimer_initialized(&_this->idle_event)) evtimer_set(&_this->idle_event, ppp_idle_timeout, _this); _this->auth_timeout = ppp_config_int(_this, "auth.timeout", DEFAULT_AUTH_TIMEOUT); _this->lcp.echo_interval = ppp_config_int(_this, "lcp.echo_interval", DEFAULT_LCP_ECHO_INTERVAL); _this->lcp.echo_max_retries = ppp_config_int(_this, "lcp.echo_max_retries", DEFAULT_LCP_ECHO_MAX_RETRIES); _this->lcp.echo_retry_interval = ppp_config_int(_this, "lcp.echo_retry_interval", DEFAULT_LCP_ECHO_RETRY_INTERVAL); return 0; }