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;
+}
+/*---------------------------------------------------------------------------*/