Imported initial version of PPP.
The original author is Mike Johnson. Adam Dunkels modified the code to better fit it into the Contiki world. I tried to glue it into the Contiki framework.
This version could - as far as I understand - work theoretically but certainly isn't supposed to.
diff --git a/contiki/ppp/ppp.c b/contiki/ppp/ppp.c
new file mode 100644
index 0000000..d0da4e5
--- /dev/null
+++ b/contiki/ppp/ppp.c
@@ -0,0 +1,446 @@
+/*
+ *---------------------------------------------------------------------------
+ * ppp.c - PPP Processor/Handler -
+ * -
+ *---------------------------------------------------------------------------
+ *
+ * Version -
+ * 0.1 Original Version Jun 3, 2000 -
+ * -
+ *---------------------------------------------------------------------------
+ */
+/*
+ * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mike Johnson/Mycal Labs
+ * www.mycal.net.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the Mycal Modified uIP TCP/IP stack.
+ *
+ * $Id: ppp.c,v 1.1 2004/08/20 12:29:54 oliverschmidt Exp $
+ *
+ */
+
+/* */
+/* include files */
+/* */
+
+
+#include "lcp.h"
+#include "pap.h"
+#include "ipcp.h"
+/*#include "time.h"*/
+/*#include "mip.h"*/
+
+#define DEBUG1(x) printf x
+
+/*
+ Set the debug message level
+*/
+#define PACKET_RX_DEBUG 1
+#define DEBUG_LV1 1
+#define DEBUG_LV2 2
+
+#if PACKET_RX_DEBUG
+#include <stdio.h>
+#endif
+
+/*
+ Include stuff
+*/
+/*#include "mTypes.h"*/
+#include "ppp.h"
+#include "ahdlc.h"
+#include "ipcp.h"
+#include "lcp.h"
+
+
+/*
+ Buffers that this layer needs (this can be optimized out)
+*/
+u8_t ppp_rx_buffer[PPP_RX_BUFFER_SIZE];
+/*u8_t ppp_tx_buffer[PPP_TX_BUFFER_SIZE];*/
+
+/*
+ * IP addr set by PPP server
+ */
+uip_ipaddr_t our_ipaddr;
+
+/*
+ * Other state storage (this can be placed in a struct and this could could
+ * support multiple PPP connections, would have to embedded the other ppp
+ * module state also)
+ */
+u8_t ppp_flags;
+u8_t ppp_id;
+u8_t ppp_retry;
+
+u8_t *ppp_username;
+u8_t *ppp_password;
+
+#if PACKET_RX_DEBUG
+u16_t ppp_rx_frame_count=0;
+u16_t ppp_rx_tobig_error;
+u8_t done; /* temporary variable */
+#endif
+
+/*---------------------------------------------------------------------------*/
+static u8_t
+check_ppp_errors(void)
+{
+ u8_t ret = 0;
+
+ /* Check Errors */
+ if(lcp_state & LCP_TX_TIMEOUT) {
+ ret = 1;
+ }
+ if(lcp_state & LCP_RX_TIMEOUT) {
+ ret = 2;
+ }
+
+ if(pap_state & PAP_TX_AUTH_FAIL) {
+ ret = 3;
+ }
+ if(pap_state & PAP_RX_AUTH_FAIL) {
+ ret = 4;
+ }
+
+ if(pap_state & PAP_TX_TIMEOUT) {
+ ret = 5;
+ }
+ if(pap_state & PAP_RX_TIMEOUT) {
+ ret = 6;
+ }
+
+ if(ipcp_state & IPCP_TX_TIMEOUT) {
+ ret = 7;
+ }
+
+ return ret;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * 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);
+}
+/*---------------------------------------------------------------------------*/
+#if PACKET_RX_DEBUG
+void
+dump_ppp_packet(u8_t *buffer, u16_t len)
+{
+ int i;
+
+ for(i = 0;i < len; ++i) {
+ if((i & 0x1f) == 0x10) {
+ printf("\n");
+ }
+ printf("%x ",buffer[i]);
+ }
+ printf("\n");
+}
+#endif
+/*---------------------------------------------------------------------------*/
+/* Initialize and start PPP engine. This just sets things up to
+ * starting values. This can stay a private method.
+ */
+/*---------------------------------------------------------------------------*/
+void
+ppp_init()
+{
+#if PACKET_RX_DEBUG
+ ppp_rx_frame_count = 0;
+ done = 0;
+#endif
+ ppp_flags = 0;
+ pap_init();
+ ipcp_init();
+ lcp_init();
+ ppp_flags = 0;
+
+ ahdlc_init(ppp_rx_buffer, PPP_RX_BUFFER_SIZE);
+ ahdlc_rx_ready();
+}
+/*---------------------------------------------------------------------------*/
+/* raise_ppp() - This routine will try to bring up a PPP connection,
+ * It is blocking. In the future we probably want to pass a
+ * structure with all the options on bringing up a PPP link, like
+ * server/client, DSN server, username password for PAP... +++ for
+ * now just use config and bit defines
+ */
+/*---------------------------------------------------------------------------*/
+#if 0
+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;
+}
+#endif
+/*---------------------------------------------------------------------------*/
+void
+ppp_connect(u8_t *username, u8_t *password)
+{
+ /* Initialize PPP engine */
+ /* init_ppp(); */
+ pap_init();
+ ipcp_init();
+ lcp_init();
+
+ /* Enable PPP */
+ ppp_flags = PPP_RX_READY;
+
+ ppp_username = username;
+ ppp_password = password;
+}
+/*---------------------------------------------------------------------------*/
+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_appdata, 40, uip_len - 40);
+ }
+}
+/*---------------------------------------------------------------------------*/
+void
+ppp_poll(void)
+{
+ u8_t c;
+
+ uip_len = 0;
+
+ while(uip_len == 0 && ppp_arch_getchar(&c)) {
+ ahdlc_rx(c);
+ }
+
+ /* If IPCP came up then our link should be up. */
+ if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) {
+ return;
+ }
+
+ /* call the lcp task to bring up the LCP layer */
+ lcp_task(uip_buf);
+
+ /* 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(uip_buf, ppp_username, ppp_password);
+ } else {
+ ipcp_task(uip_buf);
+ }
+ }
+}
+/*---------------------------------------------------------------------------*/
+/* ppp_upcall() - this is where valid PPP frames from the ahdlc layer are
+ * sent to be processed and demuxed.
+ */
+/*---------------------------------------------------------------------------*/
+void
+ppp_upcall(u16_t protocol, u8_t *buffer, u16_t len)
+{
+#if PACKET_RX_DEBUG
+ ++ppp_rx_frame_count;
+ /* DEBUG1(("\n<<<<<<<<<<<<<<-----------\n"));
+ dump_ppp_packet(buffer, len);
+ DEBUG1(("\n<<<<<<<<<<<<<<-----------\n")); */
+ if(ppp_rx_frame_count > 18) {
+ done = 1;
+ }
+#endif
+
+ /* check to see if we have a packet waiting to be processed */
+ if(ppp_flags & PPP_RX_READY) {
+ /* demux on protocol field */
+ switch(protocol) {
+ case LCP: /* We must support some level of LCP */
+ DEBUG1(("LCP Packet - "));
+ lcp_rx(buffer, len);
+ DEBUG1(("\n"));
+ break;
+ case PAP: /* PAP should be compile in optional */
+ DEBUG1(("PAP Packet - "));
+ pap_rx(buffer, len);
+ DEBUG1(("\n"));
+ break;
+ case IPCP: /* IPCP should be compile in optional. */
+ DEBUG1(("IPCP Packet - "));
+ ipcp_rx(buffer, len);
+ DEBUG1(("\n"));
+ break;
+ case IPV4: /* We must support IPV4 */
+ DEBUG1(("IPV4 Packet---\n"));
+ memcpy(uip_buf, buffer, len);
+ uip_len = len;
+ DEBUG1(("\n"));
+ break;
+ default:
+ DEBUG1(("Unknown PPP Packet Type %x - ",protocol));
+ ppp_reject_protocol(protocol, buffer, len);
+ DEBUG1(("\n"));
+ break;
+ }
+ }
+}
+/*---------------------------------------------------------------------------*/
+/* 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 %x\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;
+}
+/*---------------------------------------------------------------------------*/