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/ipcp.c b/contiki/ppp/ipcp.c
new file mode 100644
index 0000000..6b1e1de
--- /dev/null
+++ b/contiki/ppp/ipcp.c
@@ -0,0 +1,443 @@
+/*
+ *---------------------------------------------------------------------------
+ * ipcp.c - PPP IPCP (intrnet protocol) Processor/Handler
+ *
+ *---------------------------------------------------------------------------
+ *
+ * Version
+ * 0.1 Original Version Jun 3, 2000
+ *
+ *---------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000, Mycal Labs www.mycal.com
+ *
+ *---------------------------------------------------------------------------
+ */
+/*
+ * 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: ipcp.c,v 1.1 2004/08/20 12:29:54 oliverschmidt Exp $
+ *
+ */
+
+/* */
+/* include files */
+/* */
+
+#define DEBUG1(x) printf x
+
+#include "uip.h"
+/*#include "time.h"*/
+#include "ipcp.h"
+#include "ppp.h"
+#include "ahdlc.h"
+
+#define TIMER_expire()
+#define TIMER_set()
+#define TIMER_timeout(x) 1
+
+#ifdef IPCP_GET_PEER_IP
+uip_ipaddr_t peer_ip_addr;
+#endif
+
+#ifdef IPCP_GET_PRI_DNS
+uip_ipaddr_t pri_dns_addr;
+#endif
+
+#ifdef IPCP_GET_SEC_DNS
+uip_ipaddr_t sec_dns_addr;
+#endif
+
+/*
+ * Local IPCP state
+ */
+u8_t ipcp_state;
+
+/*
+ * in the future add copression protocol and name servers (possibly for servers only)
+ */
+u8_t ipcplist[] = {0x3, 0};
+
+/*---------------------------------------------------------------------------*/
+/*void
+printip(uip_ipaddr_t ip)
+{
+DEBUG1((" %d.%d.%d.%d ",ip.ipb1,ip.ip8[1],ip.ip8[2],ip.ip8[3]));
+ }*/
+#define printip(x)
+/*---------------------------------------------------------------------------*/
+void
+ipcp_init(void)
+{
+ DEBUG1(("ipcp init\n"));
+ ipcp_state = 0;
+ ppp_retry = 0;
+ our_ipaddr.ip16[0] = our_ipaddr.ip16[1] = 0;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * IPCP RX protocol Handler
+ */
+void
+ipcp_rx(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:
+ /* parce request and see if we can ACK it */
+ ++bptr;
+ len = (*bptr++ << 8);
+ len |= *bptr++;
+ /* len-=2; */
+
+ DEBUG1(("check lcplist\n"));
+ if(scan_packet(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
+ peer_ip_addr.ip8[0] = *bptr++;
+ peer_ip_addr.ip8[1] = *bptr++;
+ peer_ip_addr.ip8[2] = *bptr++;
+ peer_ip_addr.ip8[3] = *bptr++;
+ DEBUG1(("Peer IP "));
+ /* printip(peer_ip_addr);*/
+ DEBUG1(("\n"));
+#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.
+ */
+ 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(IPCP, 0, buffer, 0, count /*bptr-buffer*/);
+ DEBUG1(("- End ACK Write frame\n"));
+
+ /* expire the timer to make things happen after a state change */
+ /*timer_expire(); */
+
+ /* } */
+ }
+ 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++;
+ ipaddr.ip8[0] = *bptr++;
+ ipaddr.ip8[1] = *bptr++;
+ ipaddr.ip8[2] = *bptr++;
+ ipaddr.ip8[3] = *bptr++;
+ break;
+ case IPCP_PRIMARY_DNS:
+ bptr++;
+ pri_dns_addr.ip8[0] = *bptr++;
+ pri_dns_addr.ip8[1] = *bptr++;
+ pri_dns_addr.ip8[2] = *bptr++;
+ pri_dns_addr.ip8[3] = *bptr++;
+ break;
+ case IPCP_SECONDARY_DNS:
+ bptr++;
+ sec_dns_addr.ip8[0] = *bptr++;
+ sec_dns_addr.ip8[1] = *bptr++;
+ sec_dns_addr.ip8[2] = *bptr++;
+ sec_dns_addr.ip8[3] = *bptr++;
+ break;
+ default:
+ DEBUG1(("IPCP CONFIG_ACK problem1\n"));
+ }
+ }
+#endif
+ ipcp_state |= IPCP_TX_UP;
+ /*ipcp_state &= ~IPCP_RX_UP;*/
+ DEBUG1(("were up! \n"));
+ printip(our_ipaddr);
+#ifdef IPCP_GET_PRI_DNS
+ printip(pri_dns_addr);
+#endif
+#ifdef IPCP_GET_SEC_DNS
+ printip(sec_dns_addr);
+#endif
+ DEBUG1(("\n"));
+
+ /* expire the timer to make things happen after a state change */
+ TIMER_expire();
+ 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++;
+ our_ipaddr.ip8[0] = *bptr++;
+ our_ipaddr.ip8[1] = *bptr++;
+ our_ipaddr.ip8[2] = *bptr++;
+ our_ipaddr.ip8[3] = *bptr++;
+ break;
+#ifdef IPCP_GET_PRI_DNS
+ case IPCP_PRIMARY_DNS:
+ bptr++;
+ pri_dns_addr.ip8[0] = *bptr++;
+ pri_dns_addr.ip8[1] = *bptr++;
+ pri_dns_addr.ip8[2] = *bptr++;
+ pri_dns_addr.ip8[3] = *bptr++;
+ break;
+#endif
+#ifdef IPCP_GET_SEC_DNS
+ case IPCP_SECONDARY_DNS:
+ bptr++;
+ sec_dns_addr.ip8[0] = *bptr++;
+ sec_dns_addr.ip8[1] = *bptr++;
+ sec_dns_addr.ip8[2] = *bptr++;
+ sec_dns_addr.ip8[3] = *bptr++;
+ break;
+#endif
+ default:
+ DEBUG1(("IPCP CONFIG_ACK problem 2\n"));
+ }
+ }
+ ppp_id++;
+ printip(our_ipaddr);
+#ifdef IPCP_GET_PRI_DNS
+ printip(pri_dns_addr);
+#endif
+#ifdef IPCP_GET_PRI_DNS
+ printip(sec_dns_addr);
+#endif
+ DEBUG1(("\n"));
+ /* expire the timer to make things happen after a state change */
+ TIMER_expire();
+ break;
+ case CONF_REJ: /* Config Reject */
+ DEBUG1(("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++) {
+ case IPCP_IPADDRESS:
+ ipcp_state |= IPCP_IP_BIT;
+ bptr += 5;
+ break;
+#ifdef IPCP_GET_PRI_DNS
+ case IPCP_PRIMARY_DNS:
+ ipcp_state |= IPCP_PRI_DNS_BIT;
+ bptr += 5;
+ break;
+#endif
+#ifdef IPCP_GET_PRI_DNS
+ case IPCP_SECONDARY_DNS:
+ ipcp_state |= IPCP_SEC_DNS_BIT;
+ bptr += 5;
+ break;
+#endif
+ default:
+ DEBUG1(("IPCP this shoudln't happen 3\n"));
+ }
+ }
+ /* expire the timer to make things happen after a state change */
+ /*timer_expire(); */
+ 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;
+ }
+ }
+}
+/*---------------------------------------------------------------------------*/