uIP 1.0 based webserver for LPC1114 + ENC28J60

Dependencies:   mbed TMP102

Files at this revision

API Documentation at this revision

Comitter:
ban4jp
Date:
Mon Jun 30 16:00:08 2014 +0000
Parent:
2:4da9ed411bdc
Commit message:
backported from Contiki 2.7

Changed in this revision

README.txt Show annotated file Show diff for this revision Revisions of this file
apps/webserver/httpd-cgi.cpp Show annotated file Show diff for this revision Revisions of this file
apps/webserver/httpd-fs-data.h Show annotated file Show diff for this revision Revisions of this file
apps/webserver/httpd.cpp Show annotated file Show diff for this revision Revisions of this file
dev-enc28j60/enc28j60.cpp Show annotated file Show diff for this revision Revisions of this file
dev-enc28j60/tapdev.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
uip-conf.h Show annotated file Show diff for this revision Revisions of this file
uip/psock.c Show annotated file Show diff for this revision Revisions of this file
uip/psock.h Show annotated file Show diff for this revision Revisions of this file
uip/pt.h Show annotated file Show diff for this revision Revisions of this file
uip/uip-fw.c Show annotated file Show diff for this revision Revisions of this file
uip/uip-fw.h Show annotated file Show diff for this revision Revisions of this file
uip/uip-neighbor.c Show annotated file Show diff for this revision Revisions of this file
uip/uip-neighbor.h Show annotated file Show diff for this revision Revisions of this file
uip/uip.c Show annotated file Show diff for this revision Revisions of this file
uip/uip.h Show annotated file Show diff for this revision Revisions of this file
uip/uip_arp.c Show annotated file Show diff for this revision Revisions of this file
uip/uip_arp.h Show annotated file Show diff for this revision Revisions of this file
uip/uipopt.h Show annotated file Show diff for this revision Revisions of this file
diff -r 4da9ed411bdc -r a2715e9c7737 README.txt
--- a/README.txt	Sat Jun 21 11:54:24 2014 +0000
+++ b/README.txt	Mon Jun 30 16:00:08 2014 +0000
@@ -8,6 +8,11 @@
   https://github.com/adamdunkels/uip/releases/tag/uip-1-0
   http://dunkels.com/adam/
 
+* Contiki 2.7 [backported about uIP core]  by Adam Dunkels
+
+  http://sourceforge.net/projects/contiki/files/Contiki/Contiki%202.7/
+  http://www.contiki-os.org/
+
 --------------------------------
 ENC28J60 Ethernet Driver
 
diff -r 4da9ed411bdc -r a2715e9c7737 apps/webserver/httpd-cgi.cpp
--- a/apps/webserver/httpd-cgi.cpp	Sat Jun 21 11:54:24 2014 +0000
+++ b/apps/webserver/httpd-cgi.cpp	Mon Jun 30 16:00:08 2014 +0000
@@ -137,12 +137,12 @@
   conn = &uip_conns[s->count];
   return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
 		 "<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\n",
-		 htons(conn->lport),
-		 htons(conn->ripaddr[0]) >> 8,
-		 htons(conn->ripaddr[0]) & 0xff,
-		 htons(conn->ripaddr[1]) >> 8,
-		 htons(conn->ripaddr[1]) & 0xff,
-		 htons(conn->rport),
+		 uip_htons(conn->lport),
+         conn->ripaddr.u8[0],
+         conn->ripaddr.u8[1],
+         conn->ripaddr.u8[2],
+         conn->ripaddr.u8[3],
+		 uip_htons(conn->rport),
 		 states[conn->tcpstateflags & UIP_TS_MASK],
 		 conn->nrtx,
 		 conn->timer,
@@ -190,15 +190,20 @@
   PSOCK_END(&s->sout);
 }
 /*---------------------------------------------------------------------------*/
+static unsigned short
+generate_tmp102_stats(void *arg)
+{
+  struct httpd_state *s = (struct httpd_state *)arg;
+  return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
+		  "%f", tmp102.read());
+}
+
 static
 PT_THREAD(tmp102_stats(struct httpd_state *s, char *ptr))
 {
-  char buff[10];
-  
   PSOCK_BEGIN(&s->sout);
 
-  sprintf(buff, "%f", tmp102.read());
-  PSOCK_SEND_STR(&s->sout, buff);
+  PSOCK_GENERATOR_SEND(&s->sout, generate_tmp102_stats, s);
   
   PSOCK_END(&s->sout);
 }
diff -r 4da9ed411bdc -r a2715e9c7737 apps/webserver/httpd-fs-data.h
--- a/apps/webserver/httpd-fs-data.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/apps/webserver/httpd-fs-data.h	Mon Jun 30 16:00:08 2014 +0000
@@ -257,6 +257,7 @@
 	"<tr><td><pre>\n"
 	"IP           Packets received\n"
 	"             Packets sent\n"
+	"             Packets forwarded\n"
 	"             Packets dropped\n"
 	"IP errors    IP version/header length\n"
 	"             IP length, high byte\n"
@@ -268,6 +269,8 @@
 	"             Packets sent\n"
 	"             Packets dropped\n"
 	"             Type errors\n"
+	"             Checksum errors\n"
+#if UIP_TCP
 	"TCP          Packets received\n"
 	"             Packets sent\n"
 	"             Packets dropped\n"
@@ -277,6 +280,18 @@
 	"             Retransmissions\n"
 	"             No connection avaliable\n"
 	"             Connection attempts to closed ports\n"
+#endif
+#if UIP_UDP
+	"UDP          Packets dropped\n"
+	"             Packets received\n"
+	"             Packets sent\n"
+	"             Checksum errors\n"
+#endif /* UIP_UDP */
+#if UIP_CONF_IPV6
+	"IPv6 ND6     Packets dropped\n"
+	"             Packets received\n"
+	"             Packets sent\n"
+#endif /*UIP_CONF_IPV6*/
 	"</pre></td><td><pre>%! net-stats\n"
 	"</pre></td></tr></table>\n"
 	"</center>\n"
diff -r 4da9ed411bdc -r a2715e9c7737 apps/webserver/httpd.cpp
--- a/apps/webserver/httpd.cpp	Sat Jun 21 11:54:24 2014 +0000
+++ b/apps/webserver/httpd.cpp	Mon Jun 30 16:00:08 2014 +0000
@@ -121,9 +121,14 @@
 next_scriptstate(struct httpd_state *s)
 {
   char *p;
-  p = strchr(s->scriptptr, ISO_nl) + 1;
-  s->scriptlen -= (unsigned short)(p - s->scriptptr);
-  s->scriptptr = p;
+
+  if((p = strchr(s->scriptptr, ISO_nl)) != NULL) {
+    p += 1;
+    s->scriptlen -= (unsigned short)(p - s->scriptptr);
+    s->scriptptr = p;
+  } else {
+    s->scriptlen = 0;
+  }
 }
 /*---------------------------------------------------------------------------*/
 static
@@ -274,7 +279,7 @@
     strncpy(s->filename, http_index_html, sizeof(s->filename));
   } else {
     s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
-    strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
+    strncpy(s->filename, s->inputbuf, sizeof(s->filename));
   }
 
   /*  httpd_log_file(uip_conn->ripaddr, s->filename);*/
@@ -340,7 +345,7 @@
 extern "C" void
 httpd_init(void)
 {
-  uip_listen(HTONS(80));
+  uip_listen(UIP_HTONS(80));
 }
 /*---------------------------------------------------------------------------*/
 /** @} */
diff -r 4da9ed411bdc -r a2715e9c7737 dev-enc28j60/enc28j60.cpp
--- a/dev-enc28j60/enc28j60.cpp	Sat Jun 21 11:54:24 2014 +0000
+++ b/dev-enc28j60/enc28j60.cpp	Mon Jun 30 16:00:08 2014 +0000
@@ -157,7 +157,8 @@
 	// perform system reset
 	this->writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
 	// check CLKRDY bit to see if reset is complete
-	wait_us(50);
+	/* Fix Errata */
+	wait_ms(1);
 	while(!(this->read(ESTAT) & ESTAT_CLKRDY));
 
 	// do bank 0 stuff
@@ -167,6 +168,9 @@
 	NextPacketPtr = RXSTART_INIT;
 	this->write(ERXSTL, RXSTART_INIT&0xFF);
 	this->write(ERXSTH, RXSTART_INIT>>8);
+	// set read pointer address
+	//this->write(ERDPTL, 0);
+	//this->write(ERDPTH, 0);
 	// set receive pointer address
 	this->write(ERXRDPTL, RXSTART_INIT&0xFF);
 	this->write(ERXRDPTH, RXSTART_INIT>>8);
@@ -252,6 +256,7 @@
 {
 	//Errata: Transmit Logic reset
 	this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
+	wait_us(10);
 	this->writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
 
 	// Set the write pointer to start of transmit buffer area
@@ -269,6 +274,11 @@
 	
 	// send the contents of the transmit buffer onto the network
 	this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
+	
+	while(this->readOp(ENC28J60_BIT_FIELD_SET, ECON1) & ECON1_TXRTS)
+	{
+		wait_us(10);
+	}
 }
 
 void ENC28J60::packetSend2(unsigned int len1, unsigned char* packet1, unsigned int len2, unsigned char* packet2)
@@ -302,7 +312,12 @@
 
 	// check if a packet has been received and buffered
 	if( !(this->read(EIR) & EIR_PKTIF) )
-		return 0;
+	{
+		if(this->read(EPKTCNT) == 0)
+		{
+			return 0;
+		}
+	}
 	
 	// Make absolutely certain that any previous packet was discarded	
 	//if( WasDiscarded == FALSE)
@@ -332,11 +347,21 @@
 
 	// Move the RX read pointer to the start of the next received packet
 	// This frees the memory we just read out
-	this->write(ERXRDPTL, (NextPacketPtr));
-	this->write(ERXRDPTH, (NextPacketPtr)>>8);
+	/* Fix Errata */
+	if(NextPacketPtr == RXSTART_INIT)
+	{
+		this->write(ERXRDPTL, (RXSTOP_INIT));
+		this->write(ERXRDPTH, (RXSTOP_INIT)>>8);
+	}
+	else
+	{
+		this->write(ERXRDPTL, (NextPacketPtr));
+		this->write(ERXRDPTH, (NextPacketPtr)>>8);
+	}
 
 	// decrement the packet counter indicate we are done with this packet
 	this->writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
+	wait_us(11);
 
 	return len;
 }
@@ -352,35 +377,35 @@
 {
 	printf("RevID: 0x%x\n", this->read(EREVID));
 
-	printf("Cntrl:\n");
+	printf("Ctrl: ");
 	printf("ECON1=%x ",this->read(ECON1));
 	printf("ECON2=%x ",this->read(ECON2));
 	printf("ESTAT=%x ",this->read(ESTAT));
-	printf("EIR=%x\n",this->read(EIR));
+	printf("EIR=%x ",this->read(EIR));
 	printf("EIE=%x\n",this->read(EIE));
 
-	printf("MAC:\n");
+	printf("MAC:  ");
 	printf("MACON1=%x ",this->read(MACON1));
 	printf("MACON2=%x ",this->read(MACON2));
 	printf("MACON3=%x ",this->read(MACON3));
-	printf("MACON4=%x\n",this->read(MACON4));
+	printf("MACON4=%x ",this->read(MACON4));
 	printf("MAD=%x%x\n",
 		this->read(MAADR5)*0x1000000+this->read(MAADR4)*0x10000+this->read(MAADR3)*0x100+this->read(MAADR2),
 		this->read(MAADR1)*0x1000000+this->read(MAADR0)*0x10000+0xffff);
 
-	printf("Rx:\n");
-	printf("ERXST=%x ",this->read(ERXSTH)*0x100+this->read(ERXSTL));
-	printf("ERXND=%x ",this->read(ERXNDH)*0x100+this->read(ERXNDL));
+	printf("Rx:   ");
+	printf("ERXST=%04x ",this->read(ERXSTH)*0x100+this->read(ERXSTL));
+	printf("ERXND=%04x ",this->read(ERXNDH)*0x100+this->read(ERXNDL));
 	printf("ERXWRPT=%x ",this->read(ERXWRPTH)*0x100+this->read(ERXWRPTL));
-	printf("ERXRDPT=%x\n",this->read(ERXRDPTH)*0x100+this->read(ERXRDPTL));
+	printf("ERXRDPT=%x ",this->read(ERXRDPTH)*0x100+this->read(ERXRDPTL));
 	printf("ERXFCON=%x ",this->read(ERXFCON));
 	printf("EPKTCNT=%x ",this->read(EPKTCNT));
-	printf("MAMXFL=%x ",this->read(MAMXFLH)*0x100+this->read(MAMXFLL));
+	printf("MAMXFL=%x\n",this->read(MAMXFLH)*0x100+this->read(MAMXFLL));
 
-	printf("Tx:\n");
-	printf("ETXST=%x ",this->read(ETXSTH)*0x100+this->read(ETXSTL));
-	printf("ETXND=%x ",this->read(ETXNDH)*0x100+this->read(ETXNDL));
+	printf("Tx:   ");
+	printf("ETXST=%04x ",this->read(ETXSTH)*0x100+this->read(ETXSTL));
+	printf("ETXND=%04x ",this->read(ETXNDH)*0x100+this->read(ETXNDL));
 	printf("MACLCON1=%x ",this->read(MACLCON1));
-	printf("MACLCON2=%x\n",this->read(MACLCON2));
+	printf("MACLCON2=%x ",this->read(MACLCON2));
 	printf("MAPHSUP=%x\n",this->read(MAPHSUP));
 }
diff -r 4da9ed411bdc -r a2715e9c7737 dev-enc28j60/tapdev.cpp
--- a/dev-enc28j60/tapdev.cpp	Sat Jun 21 11:54:24 2014 +0000
+++ b/dev-enc28j60/tapdev.cpp	Mon Jun 30 16:00:08 2014 +0000
@@ -54,6 +54,9 @@
 tapdev_init(void)
 {
 	enc28j60.init();
+
+	//enc28j60.regDump();
+
 }
 /*---------------------------------------------------------------------------*/
 unsigned int
@@ -67,10 +70,14 @@
 void
 tapdev_send(void)
 {
+	enc28j60.packetSend(uip_len, (u8 *)uip_buf);
+	
+	/*
 	if(uip_len <= 40 + UIP_LLH_LEN){
 		enc28j60.packetSend(uip_len, (u8 *)uip_buf);
 	}else{
 		enc28j60.packetSend2(54, (u8 *)uip_buf, uip_len -40 - UIP_LLH_LEN, (u8 *)uip_appdata);
 	}
+	*/
 }
 /*---------------------------------------------------------------------------*/
diff -r 4da9ed411bdc -r a2715e9c7737 main.cpp
--- a/main.cpp	Sat Jun 21 11:54:24 2014 +0000
+++ b/main.cpp	Mon Jun 30 16:00:08 2014 +0000
@@ -18,7 +18,15 @@
     => /dev-enc28j60/tapdev.cpp
 */
 
+//Serial pc(USBTX, USBRX); // tx, rx
+//RawSerial pc(USBTX, USBRX); // tx, rx
+
 int main() {
+  //pc.baud(9600);
+  //pc.baud(115200);
+  
+  wait_ms(100);
+  
   int i;
   uip_ipaddr_t ipaddr;
   Timer periodic_timer, arp_timer;
@@ -37,12 +45,12 @@
   struct uip_eth_addr mac = {UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5};
   uip_setethaddr(mac);
 
-  uip_ipaddr(ipaddr, 192,168,0,12);
-  uip_sethostaddr(ipaddr);
-  uip_ipaddr(ipaddr, 192,168,0,1);
-  uip_setdraddr(ipaddr);
-  uip_ipaddr(ipaddr, 255,255,255,0);
-  uip_setnetmask(ipaddr);
+  uip_ipaddr(&ipaddr, 192,168,0,12);
+  uip_sethostaddr(&ipaddr);
+  uip_ipaddr(&ipaddr, 192,168,0,1);
+  uip_setdraddr(&ipaddr);
+  uip_ipaddr(&ipaddr, 255,255,255,0);
+  uip_setnetmask(&ipaddr);
 
   printf("httpd_init()\n");
   httpd_init();
@@ -77,7 +85,7 @@
     if(uip_len > 0) {
       //printf("recv = %d\n", uip_len);
       
-      if(BUF->type == htons(UIP_ETHTYPE_IP)) {
+      if(BUF->type == UIP_HTONS(UIP_ETHTYPE_IP)) {
         uip_arp_ipin();
         uip_input();
         /* If the above function invocation resulted in data that
@@ -87,7 +95,7 @@
           uip_arp_out();
           tapdev_send();
         }
-      } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
+      } else if(BUF->type == UIP_HTONS(UIP_ETHTYPE_ARP)) {
         uip_arp_arpin();
         /* If the above function invocation resulted in data that
            should be sent out on the network, the global variable
diff -r 4da9ed411bdc -r a2715e9c7737 uip-conf.h
--- a/uip-conf.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip-conf.h	Mon Jun 30 16:00:08 2014 +0000
@@ -104,7 +104,7 @@
  *
  * \hideinitializer
  */
-#define UIP_CONF_BUFFER_SIZE     840
+#define UIP_CONF_BUFFER_SIZE     512
 
 /**
  * CPU byte order.
diff -r 4da9ed411bdc -r a2715e9c7737 uip/psock.c
--- a/uip/psock.c	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/psock.c	Mon Jun 30 16:00:08 2014 +0000
@@ -33,7 +33,6 @@
  * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
  */
 
-#include <stdio.h>
 #include <string.h>
 
 #include "uipopt.h"
@@ -128,22 +127,15 @@
     return BUF_NOT_FOUND;
   }
 
-  while(*datalen > 0) {
-    c = **dataptr;
-    --*datalen;
-    ++*dataptr;
-    
-    if(c == endmarker) {
-      return BUF_FOUND | BUF_FULL;
-    }
-  }
-  
   return BUF_FULL;
 }
 /*---------------------------------------------------------------------------*/
 static char
-send_data(register struct psock *s)
+data_is_sent_and_acked(register struct psock *s)
 {
+  /* If data has previously been sent, and the data has been acked, we
+     increase the send pointer and call send_data() to send more
+     data. */
   if(s->state != STATE_DATA_SENT || uip_rexmit()) {
     if(s->sendlen > uip_mss()) {
       uip_send(s->sendptr, uip_mss());
@@ -151,15 +143,8 @@
       uip_send(s->sendptr, s->sendlen);
     }
     s->state = STATE_DATA_SENT;
-    return 1;
-  }
-  return 0;
-}
-/*---------------------------------------------------------------------------*/
-static char
-data_acked(register struct psock *s)
-{
-  if(s->state == STATE_DATA_SENT && uip_acked()) {
+    return 0;
+  } else if(s->state == STATE_DATA_SENT && uip_acked()) {
     if(s->sendlen > uip_mss()) {
       s->sendlen -= uip_mss();
       s->sendptr += uip_mss();
@@ -195,16 +180,10 @@
   while(s->sendlen > 0) {
 
     /*
-     * The condition for this PT_WAIT_UNTIL is a little tricky: the
-     * protothread will wait here until all data has been acknowledged
-     * (data_acked() returns true) and until all data has been sent
-     * (send_data() returns true). The two functions data_acked() and
-     * send_data() must be called in succession to ensure that all
-     * data is sent. Therefore the & operator is used instead of the
-     * && operator, which would cause only the data_acked() function
-     * to be called when it returns false.
+     * The protothread will wait here until all data has been
+     * acknowledged and sent (data_is_acked_and_send() returns 1).
      */
-    PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+    PT_WAIT_UNTIL(&s->psockpt, data_is_sent_and_acked(s));
   }
 
   s->state = STATE_NONE;
@@ -222,21 +201,24 @@
     PT_EXIT(&s->psockpt);
   }
 
-  /* Call the generator function to generate the data in the
-     uip_appdata buffer. */
-  s->sendlen = generate(arg);
-  s->sendptr = uip_appdata;
-
-  s->state = STATE_NONE;  
+  s->state = STATE_NONE;
   do {
-    /* Call the generator function again if we are called to perform a
-       retransmission. */
-    if(uip_rexmit()) {
-      generate(arg);
+    /* Call the generator function to generate the data in the
+     uip_appdata buffer. */
+    s->sendlen = generate(arg);
+    s->sendptr = uip_appdata;
+
+    if(s->sendlen > uip_mss()) {
+      uip_send(s->sendptr, uip_mss());
+    } else {
+      uip_send(s->sendptr, s->sendlen);
     }
+    s->state = STATE_DATA_SENT;
+
     /* Wait until all data is sent and acknowledged. */
-    PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
-  } while(s->sendlen > 0);
+ // if (!s->sendlen) break;   //useful debugging aid
+    PT_YIELD_UNTIL(&s->psockpt, uip_acked() || uip_rexmit());
+  } while(!uip_acked());
   
   s->state = STATE_NONE;
   
@@ -285,9 +267,9 @@
       psock->readptr = (u8_t *)uip_appdata;
       psock->readlen = uip_datalen();
     }
-  } while((buf_bufto(&psock->buf, c,
-		     &psock->readptr,
-		     &psock->readlen) & BUF_FOUND) == 0);
+  } while(buf_bufto(&psock->buf, c,
+		    &psock->readptr,
+		    &psock->readlen) == BUF_NOT_FOUND);
   
   if(psock_datalen(psock) == 0) {
     psock->state = STATE_NONE;
@@ -296,7 +278,7 @@
   PT_END(&psock->psockpt);
 }
 /*---------------------------------------------------------------------------*/
-PT_THREAD(psock_readbuf(register struct psock *psock))
+PT_THREAD(psock_readbuf_len(register struct psock *psock, uint16_t len))
 {
   PT_BEGIN(&psock->psockpt);
 
@@ -308,15 +290,14 @@
   do {
     if(psock->readlen == 0) {
       PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
-      printf("Waited for newdata\n");
       psock->state = STATE_READ;
       psock->readptr = (u8_t *)uip_appdata;
       psock->readlen = uip_datalen();
     }
   } while(buf_bufdata(&psock->buf, psock->bufsize,
-			 &psock->readptr,
-			 &psock->readlen) != BUF_FULL);
-
+		      &psock->readptr, &psock->readlen) == BUF_NOT_FULL &&
+	  psock_datalen(psock) < len);
+  
   if(psock_datalen(psock) == 0) {
     psock->state = STATE_NONE;
     PT_RESTART(&psock->psockpt);
diff -r 4da9ed411bdc -r a2715e9c7737 uip/psock.h
--- a/uip/psock.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/psock.h	Mon Jun 30 16:00:08 2014 +0000
@@ -234,7 +234,7 @@
  */
 #define PSOCK_CLOSE(psock) uip_close()
 
-PT_THREAD(psock_readbuf(struct psock *psock));
+PT_THREAD(psock_readbuf_len(struct psock *psock, u16_t len));
 /**
  * Read data until the buffer is full.
  *
@@ -247,8 +247,27 @@
  *
  * \hideinitializer
  */
+/*
 #define PSOCK_READBUF(psock)				\
-  PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
+  PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, 1))
+*/
+
+
+/**
+ * Read data until at least len bytes have been read.
+ *
+ * This macro will block waiting for data and read the data into the
+ * input buffer specified with the call to PSOCK_INIT(). Data is read
+ * until the buffer is full or len bytes have been read.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket from which
+ * data should be read.
+ * \param len (uint16_t) The minimum number of bytes to read.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_READBUF_LEN(psock, len)			\
+  PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, len))
 
 PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
 /**
@@ -256,7 +275,7 @@
  *
  * This macro will block waiting for data and read the data into the
  * input buffer specified with the call to PSOCK_INIT(). Data is only
- * read until the specifieed character appears in the data stream.
+ * read until the specified character appears in the data stream.
  *
  * \param psock (struct psock *) A pointer to the protosocket from which
  * data should be read.
@@ -352,7 +371,7 @@
  {
    PSOCK_BEGIN(s);
 
-   PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));
+   PSOCK_WAIT_UNTIL(s, PSOCK_NEWDATA(s) || timer_expired(t));
    
    if(PSOCK_NEWDATA(s)) {
      PSOCK_READTO(s, '\n');
diff -r 4da9ed411bdc -r a2715e9c7737 uip/pt.h
--- a/uip/pt.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/pt.h	Mon Jun 30 16:00:08 2014 +0000
@@ -26,11 +26,10 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * This file is part of the uIP TCP/IP stack
+ * This file is part of the Contiki operating system.
  *
  * Author: Adam Dunkels <adam@sics.se>
  *
- * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
  */
 
 /**
@@ -56,9 +55,9 @@
 };
 
 #define PT_WAITING 0
-#define PT_EXITED  1
-#define PT_ENDED   2
-#define PT_YIELDED 3
+#define PT_YIELDED 1
+#define PT_EXITED  2
+#define PT_ENDED   3
 
 /**
  * \name Initialization
@@ -112,7 +111,7 @@
  *
  * \hideinitializer
  */
-#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; if (PT_YIELD_FLAG) {;} LC_RESUME((pt)->lc)
 
 /**
  * Declare the end of a protothread.
@@ -259,7 +258,7 @@
 /**
  * Schedule a protothread.
  *
- * This function shedules a protothread. The return value of the
+ * This function schedules a protothread. The return value of the
  * function is non-zero if the protothread is running or zero if the
  * protothread has exited.
  *
@@ -268,7 +267,7 @@
  *
  * \hideinitializer
  */
-#define PT_SCHEDULE(f) ((f) == PT_WAITING)
+#define PT_SCHEDULE(f) ((f) < PT_EXITED)
 
 /** @} */
 
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uip-fw.c
--- a/uip/uip-fw.c	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uip-fw.c	Mon Jun 30 16:00:08 2014 +0000
@@ -26,11 +26,10 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * This file is part of the uIP TCP/IP stack
+ * This file is part of the Contiki operating system.
  *
  * Author: Adam Dunkels <adam@sics.se>
  *
- * $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $
  */
 /**
  * \addtogroup uip
@@ -53,11 +52,16 @@
  *
  */
 
+#include <string.h>
+
+#include "uip-conf.h"
+
 #include "uip.h"
 #include "uip_arch.h"
 #include "uip-fw.h"
-
-#include <string.h> /* for memcpy() */
+#ifdef AODV_COMPLIANCE
+#include "uaodv-def.h"
+#endif
 
 /*
  * The list of registered network interfaces.
@@ -71,47 +75,45 @@
 
 struct tcpip_hdr {
   /* IP header. */
-  u8_t vhl,
+  uint8_t vhl,
     tos;
-  u16_t len,
+  uint16_t len,
     ipid,
     ipoffset;
-  u8_t ttl,
+  uint8_t ttl,
     proto;
-  u16_t ipchksum;
-  u16_t srcipaddr[2],
-    destipaddr[2];
+  uint16_t ipchksum;
+  uip_ipaddr_t srcipaddr, destipaddr;
   
   /* TCP header. */
-  u16_t srcport,
+  uint16_t srcport,
     destport;
-  u8_t seqno[4],
+  uint8_t seqno[4],
     ackno[4],
     tcpoffset,
     flags,
     wnd[2];
-  u16_t tcpchksum;
-  u8_t urgp[2];
-  u8_t optdata[4];
+  uint16_t tcpchksum;
+  uint8_t urgp[2];
+  uint8_t optdata[4];
 };
 
 struct icmpip_hdr {
   /* IP header. */
-  u8_t vhl,
+  uint8_t vhl,
     tos,
     len[2],
     ipid[2],
     ipoffset[2],
     ttl,
     proto;
-  u16_t ipchksum;
-  u16_t srcipaddr[2],
-    destipaddr[2];
+  uint16_t ipchksum;
+  uip_ipaddr_t srcipaddr, destipaddr;
   /* ICMP (echo) header. */
-  u8_t type, icode;
-  u16_t icmpchksum;
-  u16_t id, seqno;
-  u8_t payload[1];
+  uint8_t type, icode;
+  uint16_t icmpchksum;
+  uint16_t id, seqno;
+  uint8_t payload[1];
 };
 
 /* ICMP ECHO. */
@@ -135,20 +137,20 @@
  * duplicate packets.
  */
 struct fwcache_entry {
-  u16_t timer;
+  uint16_t timer;
   
-  u16_t srcipaddr[2];
-  u16_t destipaddr[2];
-  u16_t ipid;
-  u8_t proto;
-  u8_t unused;
+  uip_ipaddr_t srcipaddr;
+  uip_ipaddr_t destipaddr;
+  uint16_t ipid;
+  uint8_t proto;
+  uint8_t unused;
 
 #if notdef
-  u16_t payload[2];
+  uint16_t payload[2];
 #endif
 
 #if UIP_REASSEMBLY > 0
-  u16_t len, offset;
+  uint16_t len, offset;
 #endif
 };
 
@@ -204,10 +206,12 @@
  */
 /*------------------------------------------------------------------------------*/
 static unsigned char
-ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask)
+ipaddr_maskcmp(uip_ipaddr_t *ipaddr,
+	       uip_ipaddr_t *netipaddr,
+	       uip_ipaddr_t *netmask)
 {
-  return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
-    (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
+  return (ipaddr->u16[0] & netmask->u16[0]) == (netipaddr->u16[0] & netmask->u16[0]) &&
+    (ipaddr->u16[1] & netmask->u16[1]) == (netipaddr->u16[1] & netmask->u16[1]);
 }
 /*------------------------------------------------------------------------------*/
 /**
@@ -221,15 +225,15 @@
 static void
 time_exceeded(void)
 {
-  u16_t tmp16;
 
-  /* We don't send out ICMP errors for ICMP messages. */
-  if(ICMPBUF->proto == UIP_PROTO_ICMP) {
+  /* We don't send out ICMP errors for ICMP messages (unless they are pings). */
+  if(ICMPBUF->proto == UIP_PROTO_ICMP &&
+     ICMPBUF->type != ICMP_ECHO) {
     uip_len = 0;
     return;
   }
   /* Copy fields from packet header into payload of this ICMP packet. */
-  memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28);
+  memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8);
 
   /* Set the ICMP type and code. */
   ICMPBUF->type = ICMP_TE;
@@ -237,26 +241,20 @@
 
   /* Calculate the ICMP checksum. */
   ICMPBUF->icmpchksum = 0;
-  ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
+  ICMPBUF->icmpchksum = ~uip_chksum((uint16_t *)&(ICMPBUF->type), 36);
 
   /* Set the IP destination address to be the source address of the
      original packet. */
-  tmp16= BUF->destipaddr[0];
-  BUF->destipaddr[0] = BUF->srcipaddr[0];
-  BUF->srcipaddr[0] = tmp16;
-  tmp16 = BUF->destipaddr[1];
-  BUF->destipaddr[1] = BUF->srcipaddr[1];
-  BUF->srcipaddr[1] = tmp16;
+  uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
 
   /* Set our IP address as the source address. */
-  BUF->srcipaddr[0] = uip_hostaddr[0];
-  BUF->srcipaddr[1] = uip_hostaddr[1];
+  uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
 
   /* The size of the ICMP time exceeded packet is 36 + the size of the
      IP header (20) = 56. */
   uip_len = 56;
   ICMPBUF->len[0] = 0;
-  ICMPBUF->len[1] = uip_len;
+  ICMPBUF->len[1] = (uint8_t)uip_len;
 
   /* Fill in the other fields in the IP header. */
   ICMPBUF->vhl = 0x45;
@@ -300,10 +298,8 @@
 
   fw->timer = FW_TIME;
   fw->ipid = BUF->ipid;
-  fw->srcipaddr[0] = BUF->srcipaddr[0];
-  fw->srcipaddr[1] = BUF->srcipaddr[1];
-  fw->destipaddr[0] = BUF->destipaddr[0];
-  fw->destipaddr[1] = BUF->destipaddr[1];
+  uip_ipaddr_copy(&fw->srcipaddr, &BUF->srcipaddr);
+  uip_ipaddr_copy(&fw->destipaddr, &BUF->destipaddr);
   fw->proto = BUF->proto;
 #if notdef
   fw->payload[0] = BUF->srcport;
@@ -327,8 +323,8 @@
   
   /* Walk through every network interface to check for a match. */
   for(netif = netifs; netif != NULL; netif = netif->next) {
-    if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
-		      netif->netmask)) {
+    if(ipaddr_maskcmp(&BUF->destipaddr, &netif->ipaddr,
+		      &netif->netmask)) {
       /* If there was a match, we break the loop. */
       return netif;
     }
@@ -354,10 +350,13 @@
  * function is passed unmodified as a return value.
  */
 /*------------------------------------------------------------------------------*/
-u8_t
+uint8_t
 uip_fw_output(void)
 {
   struct uip_fw_netif *netif;
+#if UIP_BROADCAST
+  const struct uip_udpip_hdr *udp = (void *)BUF;
+#endif /* UIP_BROADCAST */
 
   if(uip_len == 0) {
     return UIP_FW_ZEROLEN;
@@ -367,9 +366,7 @@
 
 #if UIP_BROADCAST
   /* Link local broadcasts go out on all interfaces. */
-  if(/*BUF->proto == UIP_PROTO_UDP &&*/
-     BUF->destipaddr[0] == 0xffff &&
-     BUF->destipaddr[1] == 0xffff) {
+  if(uip_ipaddr_cmp(&udp->destipaddr, &uip_broadcast_addr)) {
     if(defaultnetif != NULL) {
       defaultnetif->output();
     }
@@ -402,22 +399,28 @@
  * the packet should be processed locally.
  */
 /*------------------------------------------------------------------------------*/
-u8_t
+uint8_t
 uip_fw_forward(void)
 {
   struct fwcache_entry *fw;
 
   /* First check if the packet is destined for ourselves and return 0
      to indicate that the packet should be processed locally. */
-  if(BUF->destipaddr[0] == uip_hostaddr[0] &&
-     BUF->destipaddr[1] == uip_hostaddr[1]) {
+  if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
     return UIP_FW_LOCAL;
   }
 
+#ifdef AODV_COMPLIANCE
+#define udp ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
+  if(udp->proto == UIP_PROTO_UDP && udp->destport == UIP_HTONS(UAODV_UDPPORT)) {
+    return UIP_FW_LOCAL;
+  }
+#endif
+
   /* If we use ping IP address configuration, and our IP address is
      not yet configured, we should intercept all ICMP echo packets. */
 #if UIP_PINGADDRCONF
-  if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 &&
+  if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) &&
      BUF->proto == UIP_PROTO_ICMP &&
      ICMPBUF->type == ICMP_ECHO) {
     return UIP_FW_LOCAL;
@@ -434,10 +437,8 @@
        fw->offset == BUF->ipoffset &&
 #endif
        fw->ipid == BUF->ipid &&
-       fw->srcipaddr[0] == BUF->srcipaddr[0] &&
-       fw->srcipaddr[1] == BUF->srcipaddr[1] &&
-       fw->destipaddr[0] == BUF->destipaddr[0] &&
-       fw->destipaddr[1] == BUF->destipaddr[1] &&
+       uip_ipaddr_cmp(&fw->srcipaddr, &BUF->srcipaddr) &&
+       uip_ipaddr_cmp(&fw->destipaddr, &BUF->destipaddr) &&
 #if notdef
        fw->payload[0] == BUF->srcport &&
        fw->payload[1] == BUF->destport &&
@@ -451,9 +452,10 @@
   /* If the TTL reaches zero we produce an ICMP time exceeded message
      in the uip_buf buffer and forward that packet back to the sender
      of the packet. */
+
   if(BUF->ttl <= 1) {
     /* No time exceeded for broadcasts and multicasts! */
-    if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
+    if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
       return UIP_FW_LOCAL;
     }
     time_exceeded();
@@ -463,10 +465,10 @@
   BUF->ttl = BUF->ttl - 1;
   
   /* Update the IP checksum. */
-  if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
-    BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
+  if(BUF->ipchksum >= UIP_HTONS(0xffff - 0x0100)) {
+    BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100) + 1;
   } else {
-    BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
+    BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100);
   }
 
   if(uip_len > 0) {
@@ -475,7 +477,7 @@
   }
 
 #if UIP_BROADCAST
-  if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
+  if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
     return UIP_FW_LOCAL;
   }
 #endif /* UIP_BROADCAST */
@@ -530,3 +532,5 @@
   }
 }
 /*------------------------------------------------------------------------------*/
+/** @} */
+/** @} */
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uip-fw.h
--- a/uip/uip-fw.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uip-fw.h	Mon Jun 30 16:00:08 2014 +0000
@@ -11,37 +11,36 @@
 
 /*
  * Copyright (c) 2004, Swedish Institute of Computer Science.
- * All rights reserved.
+ * 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. Neither the name of the Institute nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
+ * 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
  *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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 uIP TCP/IP stack
- *
+ * This file is part of the Contiki operating system.
+ * 
  * Author: Adam Dunkels <adam@sics.se>
  *
- * $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $
  */
 #ifndef __UIP_FW_H__
 #define __UIP_FW_H__
@@ -54,15 +53,15 @@
 struct uip_fw_netif {
   struct uip_fw_netif *next;  /**< Pointer to the next interface when
 				 linked in a list. */
-  u16_t ipaddr[2];            /**< The IP address of this interface. */
-  u16_t netmask[2];           /**< The netmask of the interface. */
-  u8_t (* output)(void);
+  uip_ipaddr_t ipaddr;            /**< The IP address of this interface. */
+  uip_ipaddr_t netmask;           /**< The netmask of the interface. */
+  uint8_t (* output)(void);
                               /**< A pointer to the function that
 				 sends a packet. */
 };
 
 /**
- * Intantiating macro for a uIP network interface.
+ * Instantiating macro for a uIP network interface.
  *
  * Example:
  \code
@@ -79,8 +78,8 @@
  */
 #define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
         NULL, \
-	{HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \
-	{HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \
+	{ {ip1, ip2, ip3, ip4} }, \
+	{ {nm1, nm2, nm3, nm4} }, \
         outputfunc
 
 /**
@@ -93,8 +92,8 @@
  * \hideinitializer
  */
 #define uip_fw_setipaddr(netif, addr) \
-        do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \
-             (netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0)
+        do { (netif)->ipaddr[0] = ((uint16_t *)(addr))[0]; \
+             (netif)->ipaddr[1] = ((uint16_t *)(addr))[1]; } while(0)
 /**
  * Set the netmask of a network interface.
  *
@@ -105,12 +104,12 @@
  * \hideinitializer
  */
 #define uip_fw_setnetmask(netif, addr) \
-        do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \
-             (netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0)
+        do { (netif)->netmask[0] = ((uint16_t *)(addr))[0]; \
+             (netif)->netmask[1] = ((uint16_t *)(addr))[1]; } while(0)
 
 void uip_fw_init(void);
-u8_t uip_fw_forward(void);
-u8_t uip_fw_output(void);
+uint8_t uip_fw_forward(void);
+uint8_t uip_fw_output(void);
 void uip_fw_register(struct uip_fw_netif *netif);
 void uip_fw_default(struct uip_fw_netif *netif);
 void uip_fw_periodic(void);
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uip-neighbor.c
--- a/uip/uip-neighbor.c	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uip-neighbor.c	Mon Jun 30 16:00:08 2014 +0000
@@ -26,9 +26,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * This file is part of the uIP TCP/IP stack
+ * This file is part of the Contiki operating system.
  *
- * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $
  */
 
 /**
@@ -54,7 +53,7 @@
 struct neighbor_entry {
   uip_ipaddr_t ipaddr;
   struct uip_neighbor_addr addr;
-  u8_t time;
+  uint8_t time;
 };
 static struct neighbor_entry entries[ENTRIES];
 
@@ -82,14 +81,14 @@
 }
 /*---------------------------------------------------------------------------*/
 void
-uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr)
+uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr)
 {
   int i, oldest;
-  u8_t oldest_time;
+  uint8_t oldest_time;
 
-  printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
+  /*  printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
 	 addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3],
-	 addr->addr.addr[4], addr->addr.addr[5]);
+	 addr->addr.addr[4], addr->addr.addr[5]);*/
   
   /* Find the first unused entry or the oldest used entry. */
   oldest_time = 0;
@@ -99,7 +98,7 @@
       oldest = i;
       break;
     }
-    if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) {
+    if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) {
       oldest = i;
       break;
     }
@@ -112,17 +111,17 @@
   /* Use the oldest or first free entry (either pointed to by the
      "oldest" variable). */
   entries[oldest].time = 0;
-  uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr);
+  uip_ipaddr_copy(&entries[oldest].ipaddr, ipaddr);
   memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr));
 }
 /*---------------------------------------------------------------------------*/
 static struct neighbor_entry *
-find_entry(uip_ipaddr_t ipaddr)
+find_entry(uip_ipaddr_t *ipaddr)
 {
   int i;
   
   for(i = 0; i < ENTRIES; ++i) {
-    if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) {
+    if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) {
       return &entries[i];
     }
   }
@@ -130,7 +129,7 @@
 }
 /*---------------------------------------------------------------------------*/
 void
-uip_neighbor_update(uip_ipaddr_t ipaddr)
+uip_neighbor_update(uip_ipaddr_t *ipaddr)
 {
   struct neighbor_entry *e;
 
@@ -141,7 +140,7 @@
 }
 /*---------------------------------------------------------------------------*/
 struct uip_neighbor_addr *
-uip_neighbor_lookup(uip_ipaddr_t ipaddr)
+uip_neighbor_lookup(uip_ipaddr_t *ipaddr)
 {
   struct neighbor_entry *e;
 
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uip-neighbor.h
--- a/uip/uip-neighbor.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uip-neighbor.h	Mon Jun 30 16:00:08 2014 +0000
@@ -26,9 +26,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * This file is part of the uIP TCP/IP stack
+ * This file is part of the Contiki operating system.
  *
- * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $
  */
 
 /**
@@ -53,9 +52,9 @@
 };
 
 void uip_neighbor_init(void);
-void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr);
-void uip_neighbor_update(uip_ipaddr_t ipaddr);
-struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr);
+void uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr);
+void uip_neighbor_update(uip_ipaddr_t *ipaddr);
+struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t *ipaddr);
 void uip_neighbor_periodic(void);
 
 #endif /* __UIP-NEIGHBOR_H__ */
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uip.c
--- a/uip/uip.c	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uip.c	Mon Jun 30 16:00:08 2014 +0000
@@ -1,16 +1,8 @@
 #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
 
 /**
- * \defgroup uip The uIP TCP/IP stack
+ * \addtogroup uip
  * @{
- *
- * uIP is an implementation of the TCP/IP protocol stack intended for
- * small 8-bit and 16-bit microcontrollers.
- *
- * uIP provides the necessary protocols for Internet communication,
- * with a very small code footprint and RAM requirements - the uIP
- * code size is on the order of a few kilobytes and RAM usage is on
- * the order of a few hundred bytes.
  */
 
 /**
@@ -49,7 +41,6 @@
  *
  * This file is part of the uIP TCP/IP stack.
  *
- * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $
  *
  */
 
@@ -81,8 +72,15 @@
 
 #include "uip.h"
 #include "uipopt.h"
+#include "uip_arp.h"
 #include "uip_arch.h"
 
+#if !UIP_CONF_IPV6 /* If UIP_CONF_IPV6 is defined, we compile the
+		      uip6.c file instead of this one. Therefore
+		      this #ifndef removes the entire compilation
+		      output of the uip.c file */
+
+
 #if UIP_CONF_IPV6
 #include "uip-neighbor.h"
 #endif /* UIP_CONF_IPV6 */
@@ -98,47 +96,37 @@
    here. Otherwise, the address */
 #if UIP_FIXEDADDR > 0
 const uip_ipaddr_t uip_hostaddr =
-  {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
-   HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
+  { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 };
 const uip_ipaddr_t uip_draddr =
-  {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
-   HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
+  { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 };
 const uip_ipaddr_t uip_netmask =
-  {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
-   HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
+  { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 };
 #else
 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
 #endif /* UIP_FIXEDADDR */
 
-static const uip_ipaddr_t all_ones_addr =
+const uip_ipaddr_t uip_broadcast_addr =
 #if UIP_CONF_IPV6
-  {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
+  { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
 #else /* UIP_CONF_IPV6 */
-  {0xffff,0xffff};
+  { { 0xff, 0xff, 0xff, 0xff } };
 #endif /* UIP_CONF_IPV6 */
-static const uip_ipaddr_t all_zeroes_addr =
-#if UIP_CONF_IPV6
-  {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
-#else /* UIP_CONF_IPV6 */
-  {0x0000,0x0000};
-#endif /* UIP_CONF_IPV6 */
-
+const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } };
 
 #if UIP_FIXEDETHADDR
-const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
+const uip_lladdr_t uip_lladdr = {{UIP_ETHADDR0,
 					  UIP_ETHADDR1,
 					  UIP_ETHADDR2,
 					  UIP_ETHADDR3,
 					  UIP_ETHADDR4,
 					  UIP_ETHADDR5}};
 #else
-struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};
+uip_lladdr_t uip_lladdr = {{0,0,0,0,0,0}};
 #endif
 
-#ifndef UIP_CONF_EXTERNAL_BUFFER
-u8_t uip_buf[UIP_BUFSIZE + 2];   /* The packet buffer that contains
-				    incoming packets. */
-#endif /* UIP_CONF_EXTERNAL_BUFFER */
+/* The packet buffer that contains incoming packets. */
+uip_buf_t uip_aligned_buf;
 
 void *uip_appdata;               /* The uip_appdata pointer points to
 				    application data. */
@@ -149,15 +137,15 @@
 void *uip_urgdata;               /* The uip_urgdata pointer points to
    				    urgent data (out-of-band data), if
    				    present. */
-u16_t uip_urglen, uip_surglen;
+uint16_t uip_urglen, uip_surglen;
 #endif /* UIP_URGDATA > 0 */
 
-u16_t uip_len, uip_slen;
+uint16_t uip_len, uip_slen;
                              /* The uip_len is either 8 or 16 bits,
 				depending on the maximum packet
 				size. */
 
-u8_t uip_flags;     /* The uip_flags variable is used for
+uint8_t uip_flags;     /* The uip_flags variable is used for
 				communication between the TCP/IP stack
 				and the application program. */
 struct uip_conn *uip_conn;   /* uip_conn always points to the current
@@ -166,7 +154,7 @@
 struct uip_conn uip_conns[UIP_CONNS];
                              /* The uip_conns array holds all TCP
 				connections. */
-u16_t uip_listenports[UIP_LISTENPORTS];
+uint16_t uip_listenports[UIP_LISTENPORTS];
                              /* The uip_listenports list all currently
 				listning ports. */
 #if UIP_UDP
@@ -174,24 +162,24 @@
 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
 #endif /* UIP_UDP */
 
-static u16_t ipid;           /* Ths ipid variable is an increasing
+static uint16_t ipid;           /* Ths ipid variable is an increasing
 				number that is used for the IP ID
 				field. */
 
-void uip_setipid(u16_t id) { ipid = id; }
+void uip_setipid(uint16_t id) { ipid = id; }
 
-static u8_t iss[4];          /* The iss variable is used for the TCP
+static uint8_t iss[4];          /* The iss variable is used for the TCP
 				initial sequence number. */
 
-#if UIP_ACTIVE_OPEN
-static u16_t lastport;       /* Keeps track of the last port used for
+#if UIP_ACTIVE_OPEN || UIP_UDP
+static uint16_t lastport;       /* Keeps track of the last port used for
 				a new connection. */
-#endif /* UIP_ACTIVE_OPEN */
+#endif /* UIP_ACTIVE_OPEN || UIP_UDP */
 
 /* Temporary variables. */
-u8_t uip_acc32[4];
-static u8_t c, opt;
-static u16_t tmp16;
+uint8_t uip_acc32[4];
+static uint8_t c, opt;
+static uint16_t tmp16;
 
 /* Structures and definitions. */
 #define TCP_FIN 0x01
@@ -211,6 +199,9 @@
 #define ICMP_ECHO_REPLY 0
 #define ICMP_ECHO       8
 
+#define ICMP_DEST_UNREACHABLE        3
+#define ICMP_PORT_UNREACHABLE        3
+
 #define ICMP6_ECHO_REPLY             129
 #define ICMP6_ECHO                   128
 #define ICMP6_NEIGHBOR_SOLICITATION  135
@@ -246,7 +237,7 @@
 
 #if ! UIP_ARCH_ADD32
 void
-uip_add32(u8_t *op32, u16_t op16)
+uip_add32(uint8_t *op32, uint16_t op16)
 {
   uip_acc32[3] = op32[3] + (op16 & 0xff);
   uip_acc32[2] = op32[2] + (op16 >> 8);
@@ -276,12 +267,12 @@
 
 #if ! UIP_ARCH_CHKSUM
 /*---------------------------------------------------------------------------*/
-static u16_t
-chksum(u16_t sum, const u8_t *data, u16_t len)
+static uint16_t
+chksum(uint16_t sum, const uint8_t *data, uint16_t len)
 {
-  u16_t t;
-  const u8_t *dataptr;
-  const u8_t *last_byte;
+  uint16_t t;
+  const uint8_t *dataptr;
+  const uint8_t *last_byte;
 
   dataptr = data;
   last_byte = data + len - 1;
@@ -307,34 +298,34 @@
   return sum;
 }
 /*---------------------------------------------------------------------------*/
-u16_t
-uip_chksum(u16_t *data, u16_t len)
+uint16_t
+uip_chksum(uint16_t *data, uint16_t len)
 {
-  return htons(chksum(0, (u8_t *)data, len));
+  return uip_htons(chksum(0, (uint8_t *)data, len));
 }
 /*---------------------------------------------------------------------------*/
 #ifndef UIP_ARCH_IPCHKSUM
-u16_t
+uint16_t
 uip_ipchksum(void)
 {
-  u16_t sum;
+  uint16_t sum;
 
   sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
   DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
-  return (sum == 0) ? 0xffff : htons(sum);
+  return (sum == 0) ? 0xffff : uip_htons(sum);
 }
 #endif
 /*---------------------------------------------------------------------------*/
-static u16_t
-upper_layer_chksum(u8_t proto)
+static uint16_t
+upper_layer_chksum(uint8_t proto)
 {
-  u16_t upper_layer_len;
-  u16_t sum;
+  uint16_t upper_layer_len;
+  uint16_t sum;
   
 #if UIP_CONF_IPV6
-  upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
+  upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]);
 #else /* UIP_CONF_IPV6 */
-  upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
+  upper_layer_len = (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
 #endif /* UIP_CONF_IPV6 */
   
   /* First sum pseudoheader. */
@@ -342,17 +333,17 @@
   /* IP protocol and length fields. This addition cannot carry. */
   sum = upper_layer_len + proto;
   /* Sum IP source and destination addresses. */
-  sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
+  sum = chksum(sum, (uint8_t *)&BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
 
   /* Sum TCP header and data. */
   sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
 	       upper_layer_len);
     
-  return (sum == 0) ? 0xffff : htons(sum);
+  return (sum == 0) ? 0xffff : uip_htons(sum);
 }
 /*---------------------------------------------------------------------------*/
 #if UIP_CONF_IPV6
-u16_t
+uint16_t
 uip_icmp6chksum(void)
 {
   return upper_layer_chksum(UIP_PROTO_ICMP6);
@@ -360,14 +351,14 @@
 }
 #endif /* UIP_CONF_IPV6 */
 /*---------------------------------------------------------------------------*/
-u16_t
+uint16_t
 uip_tcpchksum(void)
 {
   return upper_layer_chksum(UIP_PROTO_TCP);
 }
 /*---------------------------------------------------------------------------*/
 #if UIP_UDP_CHECKSUMS
-u16_t
+uint16_t
 uip_udpchksum(void)
 {
   return upper_layer_chksum(UIP_PROTO_UDP);
@@ -384,9 +375,9 @@
   for(c = 0; c < UIP_CONNS; ++c) {
     uip_conns[c].tcpstateflags = UIP_CLOSED;
   }
-#if UIP_ACTIVE_OPEN
+#if UIP_ACTIVE_OPEN || UIP_UDP
   lastport = 1024;
-#endif /* UIP_ACTIVE_OPEN */
+#endif /* UIP_ACTIVE_OPEN || UIP_UDP */
 
 #if UIP_UDP
   for(c = 0; c < UIP_UDP_CONNS; ++c) {
@@ -404,7 +395,7 @@
 /*---------------------------------------------------------------------------*/
 #if UIP_ACTIVE_OPEN
 struct uip_conn *
-uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
+uip_connect(uip_ipaddr_t *ripaddr, uint16_t rport)
 {
   register struct uip_conn *conn, *cconn;
   
@@ -421,7 +412,7 @@
   for(c = 0; c < UIP_CONNS; ++c) {
     conn = &uip_conns[c];
     if(conn->tcpstateflags != UIP_CLOSED &&
-       conn->lport == htons(lastport)) {
+       conn->lport == uip_htons(lastport)) {
       goto again;
     }
   }
@@ -460,7 +451,7 @@
   conn->rto = UIP_RTO;
   conn->sa = 0;
   conn->sv = 16;   /* Initial value of the RTT variance. */
-  conn->lport = htons(lastport);
+  conn->lport = uip_htons(lastport);
   conn->rport = rport;
   uip_ipaddr_copy(&conn->ripaddr, ripaddr);
   
@@ -470,7 +461,7 @@
 /*---------------------------------------------------------------------------*/
 #if UIP_UDP
 struct uip_udp_conn *
-uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
+uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport)
 {
   register struct uip_udp_conn *conn;
   
@@ -483,7 +474,7 @@
   }
   
   for(c = 0; c < UIP_UDP_CONNS; ++c) {
-    if(uip_udp_conns[c].lport == htons(lastport)) {
+    if(uip_udp_conns[c].lport == uip_htons(lastport)) {
       goto again;
     }
   }
@@ -501,10 +492,10 @@
     return 0;
   }
   
-  conn->lport = HTONS(lastport);
+  conn->lport = UIP_HTONS(lastport);
   conn->rport = rport;
   if(ripaddr == NULL) {
-    memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
+    memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t));
   } else {
     uip_ipaddr_copy(&conn->ripaddr, ripaddr);
   }
@@ -515,7 +506,7 @@
 #endif /* UIP_UDP */
 /*---------------------------------------------------------------------------*/
 void
-uip_unlisten(u16_t port)
+uip_unlisten(uint16_t port)
 {
   for(c = 0; c < UIP_LISTENPORTS; ++c) {
     if(uip_listenports[c] == port) {
@@ -526,7 +517,7 @@
 }
 /*---------------------------------------------------------------------------*/
 void
-uip_listen(u16_t port)
+uip_listen(uint16_t port)
 {
   for(c = 0; c < UIP_LISTENPORTS; ++c) {
     if(uip_listenports[c] == 0) {
@@ -540,22 +531,22 @@
 
 #if UIP_REASSEMBLY && !UIP_CONF_IPV6
 #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
-static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
-static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
-static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
+static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
+static uint8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
+static const uint8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
 				    0x0f, 0x07, 0x03, 0x01};
-static u16_t uip_reasslen;
-static u8_t uip_reassflags;
+static uint16_t uip_reasslen;
+static uint8_t uip_reassflags;
 #define UIP_REASS_FLAG_LASTFRAG 0x01
-static u8_t uip_reasstmr;
+static uint8_t uip_reasstmr;
 
 #define IP_MF   0x20
 
-static u8_t
+static uint8_t
 uip_reass(void)
 {
-  u16_t offset, len;
-  u16_t i;
+  uint16_t offset, len;
+  uint16_t i;
 
   /* If ip_reasstmr is zero, no packet is present in the buffer, so we
      write the IP header of the fragment into the reassembly
@@ -641,7 +632,7 @@
       /* Check the last byte in the bitmap. It should contain just the
 	 right amount of bits. */
       if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
-	 (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
+	 (uint8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
 	goto nullreturn;
       }
 
@@ -669,7 +660,7 @@
 #endif /* UIP_REASSEMBLY */
 /*---------------------------------------------------------------------------*/
 static void
-uip_add_rcv_nxt(u16_t n)
+uip_add_rcv_nxt(uint16_t n)
 {
   uip_add32(uip_conn->rcv_nxt, n);
   uip_conn->rcv_nxt[0] = uip_acc32[0];
@@ -679,7 +670,7 @@
 }
 /*---------------------------------------------------------------------------*/
 void
-uip_process(u8_t flag)
+uip_process(uint8_t flag)
 {
   register struct uip_conn *uip_connr = uip_conn;
 
@@ -699,6 +690,12 @@
 	uip_flags = UIP_POLL;
 	UIP_APPCALL();
 	goto appsend;
+#if UIP_ACTIVE_OPEN && UIP_TCP
+    } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) {
+      /* In the SYN_SENT state, we retransmit out SYN. */
+      BUF->flags = 0;
+      goto tcp_send_syn;
+#endif /* UIP_ACTIVE_OPEN */
     }
     goto drop;
     
@@ -722,6 +719,7 @@
     uip_len = 0;
     uip_slen = 0;
 
+#if UIP_TCP
     /* Check if the connection is in a state in which we simply wait
        for the connection to time out. If so, we increase the
        connection's timer and remove the connection if it times
@@ -736,6 +734,7 @@
       /* If the connection has outstanding data, we increase the
 	 connection's timer and see if it has reached the RTO value
 	 in which case we retransmit. */
+
       if(uip_outstanding(uip_connr)) {
 	if(uip_connr->timer-- == 0) {
 	  if(uip_connr->nrtx == UIP_MAXRTX ||
@@ -806,6 +805,7 @@
 	goto appsend;
       }
     }
+#endif
     goto drop;
   }
 #if UIP_UDP
@@ -889,7 +889,7 @@
   }
 #endif /* UIP_CONF_IPV6 */
 
-  if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
+  if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
     /* If we are configured to use ping IP address configuration and
        hasn't been assigned an IP address yet, we accept all ICMP
        packets. */
@@ -909,16 +909,23 @@
 #if UIP_BROADCAST
     DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
     if(BUF->proto == UIP_PROTO_UDP &&
-       uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
-       /*&&
-	 uip_ipchksum() == 0xffff*/) {
+       (uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) ||
+	(BUF->destipaddr.u8[0] & 224) == 224)) {  /* XXX this is a
+						     hack to be able
+						     to receive UDP
+						     multicast
+						     packets. We check
+						     for the bit
+						     pattern of the
+						     multicast
+						     prefix. */
       goto udp_input;
     }
 #endif /* UIP_BROADCAST */
     
     /* Check if the packet is destined for our IP address. */
 #if !UIP_CONF_IPV6
-    if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
+    if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
       UIP_STAT(++uip_stat.ip.drop);
       goto drop;
     }
@@ -928,8 +935,8 @@
        hosts multicast address, and the solicited-node multicast
        address) as well. However, we will cheat here and accept all
        multicast packets that are sent to the ff02::/16 addresses. */
-    if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
-       BUF->destipaddr[0] != HTONS(0xff02)) {
+    if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) &&
+       BUF->destipaddr.u16[0] != UIP_HTONS(0xff02)) {
       UIP_STAT(++uip_stat.ip.drop);
       goto drop;
     }
@@ -946,11 +953,13 @@
   }
 #endif /* UIP_CONF_IPV6 */
 
+#if UIP_TCP
   if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
 				       proceed with TCP input
 				       processing. */
     goto tcp_input;
   }
+#endif
 
 #if UIP_UDP
   if(BUF->proto == UIP_PROTO_UDP) {
@@ -987,26 +996,26 @@
      the destination IP address of this ping packet and assign it to
      ourself. */
 #if UIP_PINGADDRCONF
-  if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
-    uip_hostaddr[0] = BUF->destipaddr[0];
-    uip_hostaddr[1] = BUF->destipaddr[1];
+  if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
+    uip_hostaddr = BUF->destipaddr;
   }
 #endif /* UIP_PINGADDRCONF */
 
   ICMPBUF->type = ICMP_ECHO_REPLY;
 
-  if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
-    ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
+  if(ICMPBUF->icmpchksum >= UIP_HTONS(0xffff - (ICMP_ECHO << 8))) {
+    ICMPBUF->icmpchksum += UIP_HTONS(ICMP_ECHO << 8) + 1;
   } else {
-    ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
+    ICMPBUF->icmpchksum += UIP_HTONS(ICMP_ECHO << 8);
   }
 
   /* Swap IP addresses. */
-  uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
-  uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+  uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
+  uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
 
   UIP_STAT(++uip_stat.icmp.sent);
-  goto send;
+  BUF->ttl = UIP_TTL;
+  goto ip_send_nolen;
 
   /* End of IPv4 input header processing code. */
 #else /* !UIP_CONF_IPV6 */
@@ -1027,11 +1036,11 @@
   /* If we get a neighbor solicitation for our address we should send
      a neighbor advertisement message back. */
   if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
-    if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
+    if(uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr)) {
 
       if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
 	/* Save the sender's address in our neighbor list. */
-	uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
+	uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
       }
       
       /* We should now send a neighbor advertisement back to where the
@@ -1041,13 +1050,14 @@
       
       ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
       
-      uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
-      uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
+      uip_ipaddr_copy(&ICMPBUF->destipaddr, &ICMPBUF->srcipaddr);
+      uip_ipaddr_copy(&ICMPBUF->srcipaddr, &uip_hostaddr);
       ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
       ICMPBUF->options[1] = 1;  /* Options length, 1 = 8 bytes. */
-      memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
+      memcpy(&(ICMPBUF->options[2]), &uip_lladdr, sizeof(uip_lladdr));
       ICMPBUF->icmpchksum = 0;
       ICMPBUF->icmpchksum = ~uip_icmp6chksum();
+      
       goto send;
       
     }
@@ -1059,8 +1069,8 @@
 
     ICMPBUF->type = ICMP6_ECHO_REPLY;
     
-    uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
-    uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+    uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
+    uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
     ICMPBUF->icmpchksum = 0;
     ICMPBUF->icmpchksum = ~uip_icmp6chksum();
     
@@ -1098,6 +1108,12 @@
   uip_len = uip_len - UIP_IPUDPH_LEN;
 #endif /* UIP_UDP_CHECKSUMS */
 
+  /* Make sure that the UDP destination port number is not zero. */
+  if(UDPBUF->destport == 0) {
+    UIP_LOG("udp: zero port.");
+    goto drop;
+  }
+
   /* Demultiplex this UDP packet between the UDP "connections". */
   for(uip_udp_conn = &uip_udp_conns[0];
       uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
@@ -1113,14 +1129,44 @@
        UDPBUF->destport == uip_udp_conn->lport &&
        (uip_udp_conn->rport == 0 ||
         UDPBUF->srcport == uip_udp_conn->rport) &&
-       (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
-	uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
-	uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
+       (uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) ||
+	uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) ||
+	uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
       goto udp_found;
     }
   }
   UIP_LOG("udp: no matching connection found");
+#if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6
+  /* Copy fields from packet header into payload of this ICMP packet. */
+  memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8);
+
+  /* Set the ICMP type and code. */
+  ICMPBUF->type = ICMP_DEST_UNREACHABLE;
+  ICMPBUF->icode = ICMP_PORT_UNREACHABLE;
+
+  /* Calculate the ICMP checksum. */
+  ICMPBUF->icmpchksum = 0;
+  ICMPBUF->icmpchksum = ~uip_chksum((uint16_t *)&(ICMPBUF->type), 36);
+
+  /* Set the IP destination address to be the source address of the
+     original packet. */
+  uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
+
+  /* Set our IP address as the source address. */
+  uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
+
+  /* The size of the ICMP destination unreachable packet is 36 + the
+     size of the IP header (20) = 56. */
+  uip_len = 36 + UIP_IPH_LEN;
+  ICMPBUF->len[0] = 0;
+  ICMPBUF->len[1] = (uint8_t)uip_len;
+  ICMPBUF->ttl = UIP_TTL;
+  ICMPBUF->proto = UIP_PROTO_ICMP;
+
+  goto ip_send_nolen;
+#else /* UIP_CONF_ICMP_DEST_UNREACH */
   goto drop;
+#endif /* UIP_CONF_ICMP_DEST_UNREACH */
   
  udp_found:
   uip_conn = NULL;
@@ -1128,6 +1174,7 @@
   uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
   uip_slen = 0;
   UIP_UDP_APPCALL();
+
  udp_send:
   if(uip_slen == 0) {
     goto drop;
@@ -1147,14 +1194,14 @@
   BUF->ttl = uip_udp_conn->ttl;
   BUF->proto = UIP_PROTO_UDP;
 
-  UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
+  UDPBUF->udplen = UIP_HTONS(uip_slen + UIP_UDPH_LEN);
   UDPBUF->udpchksum = 0;
 
   BUF->srcport  = uip_udp_conn->lport;
   BUF->destport = uip_udp_conn->rport;
 
-  uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
-  uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
+  uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
+  uip_ipaddr_copy(&BUF->destipaddr, &uip_udp_conn->ripaddr);
    
   uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
 
@@ -1170,6 +1217,7 @@
 #endif /* UIP_UDP */
   
   /* TCP input processing. */
+#if UIP_TCP
  tcp_input:
   UIP_STAT(++uip_stat.tcp.recv);
 
@@ -1182,7 +1230,12 @@
     UIP_LOG("tcp: bad checksum.");
     goto drop;
   }
-  
+
+  /* Make sure that the TCP port number is not zero. */
+  if(BUF->destport == 0 || BUF->srcport == 0) {
+    UIP_LOG("tcp: zero port.");
+    goto drop;
+  }
   
   /* Demultiplex this segment. */
   /* First check any active connections. */
@@ -1191,7 +1244,7 @@
     if(uip_connr->tcpstateflags != UIP_CLOSED &&
        BUF->destport == uip_connr->lport &&
        BUF->srcport == uip_connr->rport &&
-       uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
+       uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->ripaddr)) {
       goto found;
     }
   }
@@ -1207,14 +1260,15 @@
   tmp16 = BUF->destport;
   /* Next, check listening connections. */
   for(c = 0; c < UIP_LISTENPORTS; ++c) {
-    if(tmp16 == uip_listenports[c])
+    if(tmp16 == uip_listenports[c]) {
       goto found_listen;
+    }
   }
   
   /* No matching connection found, so we send a RST packet. */
   UIP_STAT(++uip_stat.tcp.synrst);
+
  reset:
-
   /* We do not send resets in response to resets. */
   if(BUF->flags & TCP_RST) {
     goto drop;
@@ -1260,8 +1314,8 @@
   BUF->destport = tmp16;
   
   /* Swap IP addresses. */
-  uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
-  uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+  uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
+  uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
   
   /* And send out the RST packet! */
   goto tcp_send_noconn;
@@ -1307,7 +1361,7 @@
   uip_connr->nrtx = 0;
   uip_connr->lport = BUF->destport;
   uip_connr->rport = BUF->srcport;
-  uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
+  uip_ipaddr_copy(&uip_connr->ripaddr, &BUF->srcipaddr);
   uip_connr->tcpstateflags = UIP_SYN_RCVD;
 
   uip_connr->snd_nxt[0] = iss[0];
@@ -1336,8 +1390,8 @@
       } else if(opt == TCP_OPT_MSS &&
 		uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
 	/* An MSS option with the right option length. */
-	tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
-	  (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
+	tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
+	  (uint16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
 	uip_connr->initialmss = uip_connr->mss =
 	  tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
 	
@@ -1393,7 +1447,7 @@
     UIP_APPCALL();
     goto drop;
   }
-  /* Calculated the length of the data, if the application has sent
+  /* Calculate the length of the data, if the application has sent
      any data to us. */
   c = (BUF->tcpoffset >> 4) << 2;
   /* uip_len will contain the length of the actual TCP data. This is
@@ -1403,9 +1457,13 @@
 
   /* First, check if the sequence number of the incoming packet is
      what we're expecting next. If not, we send out an ACK with the
-     correct numbers in. */
-  if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
-       ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
+     correct numbers in, unless we are in the SYN_RCVD state and
+     receive a SYN, in which case we should retransmit our SYNACK
+     (which is done futher down). */
+  if(!((((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
+	((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))) ||
+       (((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_RCVD) &&
+	((BUF->flags & TCP_CTL) == TCP_SYN)))) {
     if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
        (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
 	BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
@@ -1432,7 +1490,6 @@
       uip_connr->snd_nxt[2] = uip_acc32[2];
       uip_connr->snd_nxt[3] = uip_acc32[3];
 	
-
       /* Do RTT estimation, unless we have done retransmissions. */
       if(uip_connr->nrtx == 0) {
 	signed char m;
@@ -1482,6 +1539,10 @@
       UIP_APPCALL();
       goto appsend;
     }
+    /* We need to retransmit the SYNACK */
+    if((BUF->flags & TCP_CTL) == TCP_SYN) {
+      goto tcp_send_synack;
+    }
     goto drop;
 #if UIP_ACTIVE_OPEN
   case UIP_SYN_SENT:
@@ -1618,7 +1679,7 @@
        and the application will retransmit it. This is called the
        "persistent timer" and uses the retransmission mechanim.
     */
-    tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
+    tmp16 = ((uint16_t)BUF->wnd[0] << 8) + (uint16_t)BUF->wnd[1];
     if(tmp16 > uip_connr->initialmss ||
        tmp16 == 0) {
       tmp16 = uip_connr->initialmss;
@@ -1785,20 +1846,22 @@
   }
   goto drop;
   
-
   /* We jump here when we are ready to send the packet, and just want
      to set the appropriate TCP sequence numbers in the TCP header. */
  tcp_send_ack:
   BUF->flags = TCP_ACK;
+  
  tcp_send_nodata:
   uip_len = UIP_IPTCPH_LEN;
+
  tcp_send_noopts:
   BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
- tcp_send:
+
   /* We're done with the input processing. We are now ready to send a
      reply. Our job is to fill in all the fields of the TCP and IP
      headers before calculating the checksum and finally send the
      packet. */
+ tcp_send:
   BUF->ackno[0] = uip_connr->rcv_nxt[0];
   BUF->ackno[1] = uip_connr->rcv_nxt[1];
   BUF->ackno[2] = uip_connr->rcv_nxt[2];
@@ -1814,8 +1877,8 @@
   BUF->srcport  = uip_connr->lport;
   BUF->destport = uip_connr->rport;
 
-  uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
-  uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);
+  uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
+  uip_ipaddr_copy(&BUF->destipaddr, &uip_connr->ripaddr);
 
   if(uip_connr->tcpstateflags & UIP_STOPPED) {
     /* If the connection has issued uip_stop(), we advertise a zero
@@ -1825,7 +1888,7 @@
     BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
     BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
   }
-
+  
  tcp_send_noconn:
   BUF->ttl = UIP_TTL;
 #if UIP_CONF_IPV6
@@ -1843,9 +1906,9 @@
   /* Calculate TCP checksum. */
   BUF->tcpchksum = 0;
   BUF->tcpchksum = ~(uip_tcpchksum());
-  
+#endif
+
  ip_send_nolen:
-
 #if UIP_CONF_IPV6
   BUF->vtc = 0x60;
   BUF->tcflow = 0x00;
@@ -1861,10 +1924,11 @@
   BUF->ipchksum = 0;
   BUF->ipchksum = ~(uip_ipchksum());
   DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
+#endif /* UIP_CONF_IPV6 */   
+  UIP_STAT(++uip_stat.tcp.sent);
+#if UIP_CONF_IPV6
+ send:
 #endif /* UIP_CONF_IPV6 */
-   
-  UIP_STAT(++uip_stat.tcp.sent);
- send:
   DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
 	       (BUF->len[0] << 8) | BUF->len[1]);
   
@@ -1872,26 +1936,39 @@
   /* Return and let the caller do the actual transmission. */
   uip_flags = 0;
   return;
+
  drop:
   uip_len = 0;
   uip_flags = 0;
   return;
 }
 /*---------------------------------------------------------------------------*/
-u16_t
-htons(u16_t val)
+uint16_t
+uip_htons(uint16_t val)
 {
-  return HTONS(val);
+  return UIP_HTONS(val);
+}
+
+uint32_t
+uip_htonl(uint32_t val)
+{
+  return UIP_HTONL(val);
 }
 /*---------------------------------------------------------------------------*/
 void
 uip_send(const void *data, int len)
 {
-  if(len > 0) {
-    uip_slen = len;
+  int copylen;
+#define MIN(a,b) ((a) < (b)? (a): (b))
+  copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
+		(int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
+  if(copylen > 0) {
+    uip_slen = copylen;
     if(data != uip_sappdata) {
       memcpy(uip_sappdata, (data), uip_slen);
     }
   }
 }
+/*---------------------------------------------------------------------------*/
 /** @} */
+#endif /* UIP_CONF_IPV6 */
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uip.h
--- a/uip/uip.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uip.h	Mon Jun 30 16:00:08 2014 +0000
@@ -7,7 +7,9 @@
 /**
  * \file
  * Header file for the uIP TCP/IP stack.
- * \author Adam Dunkels <adam@dunkels.com>
+ * \author  Adam Dunkels <adam@dunkels.com>
+ * \author  Julien Abeille <jabeille@cisco.com> (IPv6 related code)
+ * \author  Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
  *
  * The uIP TCP/IP stack header file contains definitions for a number
  * of C macros that are used by uIP programs as well as internal uIP
@@ -15,7 +17,6 @@
  *
  */
 
-
 /*
  * Copyright (c) 2001-2003, Adam Dunkels.
  * All rights reserved.
@@ -46,7 +47,6 @@
  *
  * This file is part of the uIP TCP/IP stack.
  *
- * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $
  *
  */
 
@@ -56,23 +56,73 @@
 #include "uipopt.h"
 
 /**
- * Repressentation of an IP address.
+ * Representation of an IP address.
  *
  */
-typedef u16_t uip_ip4addr_t[2];
-typedef u16_t uip_ip6addr_t[8];
+typedef union uip_ip4addr_t {
+  uint8_t  u8[4];			/* Initializer, must come first. */
+  uint16_t u16[2];
+} uip_ip4addr_t;
+
+typedef union uip_ip6addr_t {
+  uint8_t  u8[16];			/* Initializer, must come first. */
+  uint16_t u16[8];
+} uip_ip6addr_t;
+
 #if UIP_CONF_IPV6
 typedef uip_ip6addr_t uip_ipaddr_t;
 #else /* UIP_CONF_IPV6 */
 typedef uip_ip4addr_t uip_ipaddr_t;
 #endif /* UIP_CONF_IPV6 */
 
+
+/*---------------------------------------------------------------------------*/
+
+/** \brief 16 bit 802.15.4 address */
+typedef struct uip_802154_shortaddr {
+  uint8_t addr[2];
+} uip_802154_shortaddr;
+/** \brief 64 bit 802.15.4 address */
+typedef struct uip_802154_longaddr {
+  uint8_t addr[8];
+} uip_802154_longaddr;
+
+/** \brief 802.11 address */
+typedef struct uip_80211_addr {
+  uint8_t addr[6];
+} uip_80211_addr;
+
+/** \brief 802.3 address */
+typedef struct uip_eth_addr {
+  uint8_t addr[6];
+} uip_eth_addr;
+
+
+#if UIP_CONF_LL_802154
+/** \brief 802.15.4 address */
+typedef uip_802154_longaddr uip_lladdr_t;
+#define UIP_802154_SHORTADDR_LEN 2
+#define UIP_802154_LONGADDR_LEN  8
+#define UIP_LLADDR_LEN UIP_802154_LONGADDR_LEN
+#else /*UIP_CONF_LL_802154*/
+#if UIP_CONF_LL_80211
+/** \brief 802.11 address */
+typedef uip_80211_addr uip_lladdr_t;
+#define UIP_LLADDR_LEN 6
+#else /*UIP_CONF_LL_80211*/
+/** \brief Ethernet address */
+typedef uip_eth_addr uip_lladdr_t;
+#define UIP_LLADDR_LEN 6
+#endif /*UIP_CONF_LL_80211*/
+#endif /*UIP_CONF_LL_802154*/
+
+//#include "tcpip.h"
+
 /*---------------------------------------------------------------------------*/
 /* First, the functions that should be called from the
- * system. Initialization, the periodic timer and incoming packets are
+ * system. Initialization, the periodic timer, and incoming packets are
  * handled by the following three functions.
  */
-
 /**
  * \defgroup uipconffunc uIP configuration functions
  * @{
@@ -103,7 +153,7 @@
  *
  * \hideinitializer
  */
-#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))
+#define uip_sethostaddr(addr) uip_ipaddr_copy(&uip_hostaddr, (addr))
 
 /**
  * Get the IP address of this host.
@@ -123,7 +173,7 @@
  *
  * \hideinitializer
  */
-#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr)
+#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), &uip_hostaddr)
 
 /**
  * Set the default router's IP address.
@@ -135,7 +185,7 @@
  *
  * \hideinitializer
  */
-#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
+#define uip_setdraddr(addr) uip_ipaddr_copy(&uip_draddr, (addr))
 
 /**
  * Set the netmask.
@@ -147,7 +197,7 @@
  *
  * \hideinitializer
  */
-#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))
+#define uip_setnetmask(addr) uip_ipaddr_copy(&uip_netmask, (addr))
 
 
 /**
@@ -158,7 +208,7 @@
  *
  * \hideinitializer
  */
-#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)
+#define uip_getdraddr(addr) uip_ipaddr_copy((addr), &uip_draddr)
 
 /**
  * Get the netmask.
@@ -168,7 +218,7 @@
  *
  * \hideinitializer
  */
-#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask)
+#define uip_getnetmask(addr) uip_ipaddr_copy((addr), &uip_netmask)
 
 /** @} */
 
@@ -192,7 +242,7 @@
  *
  * This function may be used at boot time to set the initial ip_id.
  */
-void uip_setipid(u16_t id);
+void uip_setipid(uint16_t id);
 
 /** @} */
 
@@ -220,13 +270,13 @@
  * The usual way of calling the function is presented by the source
  * code below.
  \code
-  uip_len = devicedriver_poll();
-  if(uip_len > 0) {
-    uip_input();
-    if(uip_len > 0) {
-      devicedriver_send();
-    }
-  }
+ uip_len = devicedriver_poll();
+ if(uip_len > 0) {
+ uip_input();
+ if(uip_len > 0) {
+ devicedriver_send();
+ }
+ }
  \endcode
  *
  * \note If you are writing a uIP device driver that needs ARP
@@ -234,28 +284,29 @@
  * Ethernet, you will need to call the uIP ARP code before calling
  * this function:
  \code
-  #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
-  uip_len = ethernet_devicedrver_poll();
-  if(uip_len > 0) {
-    if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
-      uip_arp_ipin();
-      uip_input();
-      if(uip_len > 0) {
-        uip_arp_out();
-	ethernet_devicedriver_send();
-      }
-    } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
-      uip_arp_arpin();
-      if(uip_len > 0) {
-	ethernet_devicedriver_send();
-      }
-    }
+ #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+ uip_len = ethernet_devicedrver_poll();
+ if(uip_len > 0) {
+ if(BUF->type == UIP_HTONS(UIP_ETHTYPE_IP)) {
+ uip_arp_ipin();
+ uip_input();
+ if(uip_len > 0) {
+ uip_arp_out();
+ ethernet_devicedriver_send();
+ }
+ } else if(BUF->type == UIP_HTONS(UIP_ETHTYPE_ARP)) {
+ uip_arp_arpin();
+ if(uip_len > 0) {
+ ethernet_devicedriver_send();
+ }
+ }
  \endcode
  *
  * \hideinitializer
  */
 #define uip_input()        uip_process(UIP_DATA)
 
+
 /**
  * Periodic processing for a connection identified by its number.
  *
@@ -269,15 +320,15 @@
  * variable is set to a value larger than zero. The device driver
  * should be called to send out the packet.
  *
- * The ususal way of calling the function is through a for() loop like
+ * The usual way of calling the function is through a for() loop like
  * this:
  \code
-  for(i = 0; i < UIP_CONNS; ++i) {
-    uip_periodic(i);
-    if(uip_len > 0) {
-      devicedriver_send();
-    }
-  }
+ for(i = 0; i < UIP_CONNS; ++i) {
+ uip_periodic(i);
+ if(uip_len > 0) {
+ devicedriver_send();
+ }
+ }
  \endcode
  *
  * \note If you are writing a uIP device driver that needs ARP
@@ -285,21 +336,22 @@
  * Ethernet, you will need to call the uip_arp_out() function before
  * calling the device driver:
  \code
-  for(i = 0; i < UIP_CONNS; ++i) {
-    uip_periodic(i);
-    if(uip_len > 0) {
-      uip_arp_out();
-      ethernet_devicedriver_send();
-    }
-  }
+ for(i = 0; i < UIP_CONNS; ++i) {
+ uip_periodic(i);
+ if(uip_len > 0) {
+ uip_arp_out();
+ ethernet_devicedriver_send();
+ }
+ }
  \endcode
  *
  * \param conn The number of the connection which is to be periodically polled.
  *
  * \hideinitializer
  */
-#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
-                                uip_process(UIP_TIMER); } while (0)
+#if UIP_TCP
+#define uip_periodic(conn) do { uip_conn = &uip_conns[conn];    \
+    uip_process(UIP_TIMER); } while (0)
 
 /**
  *
@@ -320,11 +372,11 @@
  *
  * \hideinitializer
  */
-#define uip_periodic_conn(conn) do { uip_conn = conn; \
-                                     uip_process(UIP_TIMER); } while (0)
+#define uip_periodic_conn(conn) do { uip_conn = conn;   \
+    uip_process(UIP_TIMER); } while (0)
 
 /**
- * Reuqest that a particular connection should be polled.
+ * Request that a particular connection should be polled.
  *
  * Similar to uip_periodic_conn() but does not perform any timer
  * processing. The application is polled for new data.
@@ -334,9 +386,10 @@
  *
  * \hideinitializer
  */
-#define uip_poll_conn(conn) do { uip_conn = conn; \
-                                 uip_process(UIP_POLL_REQUEST); } while (0)
+#define uip_poll_conn(conn) do { uip_conn = conn;       \
+    uip_process(UIP_POLL_REQUEST); } while (0)
 
+#endif /* UIP_TCP */
 
 #if UIP_UDP
 /**
@@ -346,24 +399,24 @@
  * UDP connections. It is called in a similar fashion as the
  * uip_periodic() function:
  \code
-  for(i = 0; i < UIP_UDP_CONNS; i++) {
-    uip_udp_periodic(i);
-    if(uip_len > 0) {
-      devicedriver_send();
-    }
-  }
+ for(i = 0; i < UIP_UDP_CONNS; i++) {
+ uip_udp_periodic(i);
+ if(uip_len > 0) {
+ devicedriver_send();
+ }
+ }
  \endcode
  *
  * \note As for the uip_periodic() function, special care has to be
  * taken when using uIP together with ARP and Ethernet:
  \code
-  for(i = 0; i < UIP_UDP_CONNS; i++) {
-    uip_udp_periodic(i);
-    if(uip_len > 0) {
-      uip_arp_out();
-      ethernet_devicedriver_send();
-    }
-  }
+ for(i = 0; i < UIP_UDP_CONNS; i++) {
+ uip_udp_periodic(i);
+ if(uip_len > 0) {
+ uip_arp_out();
+ ethernet_devicedriver_send();
+ }
+ }
  \endcode
  *
  * \param conn The number of the UDP connection to be processed.
@@ -371,7 +424,7 @@
  * \hideinitializer
  */
 #define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
-                                uip_process(UIP_UDP_TIMER); } while (0)
+    uip_process(UIP_UDP_TIMER); } while(0)
 
 /**
  * Periodic processing for a UDP connection identified by a pointer to
@@ -387,11 +440,12 @@
  *
  * \hideinitializer
  */
-#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
-                                         uip_process(UIP_UDP_TIMER); } while (0)
+#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn;   \
+    uip_process(UIP_UDP_TIMER); } while(0)
+#endif /* UIP_UDP */
 
-
-#endif /* UIP_UDP */
+/** \brief Abandon the reassembly of the current packet */
+void uip_reass_over(void);
 
 /**
  * The uIP packet buffer.
@@ -409,17 +463,25 @@
  void
  devicedriver_send(void)
  {
-    hwsend(&uip_buf[0], UIP_LLH_LEN);
-    if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
-      hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
-    } else {
-      hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
-      hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
-    }
+ hwsend(&uip_buf[0], UIP_LLH_LEN);
+ if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
+ hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
+ } else {
+ hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
+ hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
+ }
  }
  \endcode
- */
-extern u8_t uip_buf[UIP_BUFSIZE+2];
+*/
+
+typedef union {
+  uint32_t u32[(UIP_BUFSIZE + 3) / 4];
+  uint8_t u8[UIP_BUFSIZE];
+} uip_buf_t;
+
+CCIF extern uip_buf_t uip_aligned_buf;
+#define uip_buf (uip_aligned_buf.u8)
+
 
 /** @} */
 
@@ -427,7 +489,7 @@
 /* Functions that are used by the uIP application program. Opening and
  * closing connections, sending and receiving data, etc. is all
  * handled by the functions below.
-*/
+ */
 /**
  * \defgroup uipappfunc uIP application functions
  * @{
@@ -439,55 +501,55 @@
  * Start listening to the specified port.
  *
  * \note Since this function expects the port number in network byte
- * order, a conversion using HTONS() or htons() is necessary.
+ * order, a conversion using UIP_HTONS() or uip_htons() is necessary.
  *
  \code
- uip_listen(HTONS(80));
+ uip_listen(UIP_HTONS(80));
  \endcode
  *
  * \param port A 16-bit port number in network byte order.
  */
-void uip_listen(u16_t port);
+void uip_listen(uint16_t port);
 
 /**
  * Stop listening to the specified port.
  *
  * \note Since this function expects the port number in network byte
- * order, a conversion using HTONS() or htons() is necessary.
+ * order, a conversion using UIP_HTONS() or uip_htons() is necessary.
  *
  \code
- uip_unlisten(HTONS(80));
+ uip_unlisten(UIP_HTONS(80));
  \endcode
  *
  * \param port A 16-bit port number in network byte order.
  */
-void uip_unlisten(u16_t port);
+void uip_unlisten(uint16_t port);
 
 /**
  * Connect to a remote host using TCP.
  *
  * This function is used to start a new connection to the specified
- * port on the specied host. It allocates a new connection identifier,
+ * port on the specified host. It allocates a new connection identifier,
  * sets the connection to the SYN_SENT state and sets the
  * retransmission timer to 0. This will cause a TCP SYN segment to be
  * sent out the next time this connection is periodically processed,
  * which usually is done within 0.5 seconds after the call to
  * uip_connect().
  *
- * \note This function is avaliable only if support for active open
+ * \note This function is available only if support for active open
  * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
  *
  * \note Since this function requires the port number to be in network
- * byte order, a conversion using HTONS() or htons() is necessary.
+ * byte order, a conversion using UIP_HTONS() or uip_htons() is necessary.
  *
  \code
  uip_ipaddr_t ipaddr;
 
  uip_ipaddr(&ipaddr, 192,168,1,2);
- uip_connect(&ipaddr, HTONS(80));
+ uip_connect(&ipaddr, UIP_HTONS(80));
  \endcode
  *
- * \param ripaddr The IP address of the remote hot.
+ * \param ripaddr The IP address of the remote host.
  *
  * \param port A 16-bit port number in network byte order.
  *
@@ -495,7 +557,7 @@
  * or NULL if no connection could be allocated.
  *
  */
-struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);
+struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, uint16_t port);
 
 
 
@@ -518,7 +580,7 @@
  * processing can send data.
  *
  * The amount of data that actually is sent out after a call to this
- * funcion is determined by the maximum amount of data TCP allows. uIP
+ * function is determined by the maximum amount of data TCP allows. uIP
  * will automatically crop the data so that only the appropriate
  * amount of data is sent. The function uip_mss() can be used to query
  * uIP for the amount of data that actually will be sent.
@@ -535,10 +597,10 @@
  *
  * \hideinitializer
  */
-void uip_send(const void *data, int len);
+CCIF void uip_send(const void *data, int len);
 
 /**
- * The length of any incoming data that is currently avaliable (if avaliable)
+ * The length of any incoming data that is currently available (if available)
  * in the uip_appdata buffer.
  *
  * The test function uip_data() must first be used to check if there
@@ -573,7 +635,7 @@
  * Abort the current connection.
  *
  * This function will abort (reset) the current connection, and is
- * usually used when an error has occured that prevents using the
+ * usually used when an error has occurred that prevents using the
  * uip_close() function.
  *
  * \hideinitializer
@@ -607,9 +669,9 @@
  *
  * \hideinitializer
  */
-#define uip_restart()         do { uip_flags |= UIP_NEWDATA; \
-                                   uip_conn->tcpstateflags &= ~UIP_STOPPED; \
-                              } while(0)
+#define uip_restart()         do { uip_flags |= UIP_NEWDATA;    \
+    uip_conn->tcpstateflags &= ~UIP_STOPPED;                    \
+  } while(0)
 
 
 /* uIP tests that can be made to determine in what state the current
@@ -630,7 +692,7 @@
  *
  * Will reduce to non-zero if there is new data for the application
  * present at the uip_appdata pointer. The size of the data is
- * avaliable through the uip_len variable.
+ * available through the uip_len variable.
  *
  * \hideinitializer
  */
@@ -716,7 +778,7 @@
 #define uip_poll()       (uip_flags & UIP_POLL)
 
 /**
- * Get the initial maxium segment size (MSS) of the current
+ * Get the initial maximum segment size (MSS) of the current
  * connection.
  *
  * \hideinitializer
@@ -724,10 +786,10 @@
 #define uip_initialmss()             (uip_conn->initialmss)
 
 /**
- * Get the current maxium segment size that can be sent on the current
+ * Get the current maximum segment size that can be sent on the current
  * connection.
  *
- * The current maxiumum segment size that can be sent on the
+ * The current maximum segment size that can be sent on the
  * connection is computed from the receiver's window and the MSS of
  * the connection (which also is available by calling
  * uip_initialmss()).
@@ -751,22 +813,22 @@
  struct uip_udp_conn *c;
  
  uip_ipaddr(&addr, 192,168,2,1);
- c = uip_udp_new(&addr, HTONS(12345));
+ c = uip_udp_new(&addr, UIP_HTONS(12345));
  if(c != NULL) {
-   uip_udp_bind(c, HTONS(12344));
+ uip_udp_bind(c, UIP_HTONS(12344));
  }
  \endcode
  * \param ripaddr The IP address of the remote host.
  *
  * \param rport The remote port number in network byte order.
  *
- * \return The uip_udp_conn structure for the new connection or NULL
+ * \return The uip_udp_conn structure for the new connection, or NULL
  * if no connection could be allocated.
  */
-struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);
+struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
 
 /**
- * Removed a UDP connection.
+ * Remove a UDP connection.
  *
  * \param conn A pointer to the uip_udp_conn structure for the connection.
  *
@@ -812,6 +874,20 @@
  */
  
 /**
+ * Convert an IP address to four bytes separated by commas.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ printf("ipaddr=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&ipaddr));
+ \endcode
+ *
+ * \param a A pointer to a uip_ipaddr_t.
+ * \hideinitializer
+ */
+#define uip_ipaddr_to_quad(a) (a)->u8[0],(a)->u8[1],(a)->u8[2],(a)->u8[3]
+
+/**
  * Construct an IP address from four bytes.
  *
  * This function constructs an IP address of the type that uIP handles
@@ -824,7 +900,7 @@
  struct uip_conn *c;
  
  uip_ipaddr(&ipaddr, 192,168,1,2);
- c = uip_connect(&ipaddr, HTONS(80));
+ c = uip_connect(&ipaddr, UIP_HTONS(80));
  \endcode
  *
  * \param addr A pointer to a uip_ipaddr_t variable that will be
@@ -837,10 +913,12 @@
  *
  * \hideinitializer
  */
-#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
-                     ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \
-                     ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \
-                  } while(0)
+#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do {  \
+    (addr)->u8[0] = addr0;                              \
+    (addr)->u8[1] = addr1;                              \
+    (addr)->u8[2] = addr2;                              \
+    (addr)->u8[3] = addr3;                              \
+  } while(0)
 
 /**
  * Construct an IPv6 address from eight 16-bit words.
@@ -850,18 +928,45 @@
  * \hideinitializer
  */
 #define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \
-                     ((u16_t *)(addr))[0] = HTONS((addr0)); \
-                     ((u16_t *)(addr))[1] = HTONS((addr1)); \
-                     ((u16_t *)(addr))[2] = HTONS((addr2)); \
-                     ((u16_t *)(addr))[3] = HTONS((addr3)); \
-                     ((u16_t *)(addr))[4] = HTONS((addr4)); \
-                     ((u16_t *)(addr))[5] = HTONS((addr5)); \
-                     ((u16_t *)(addr))[6] = HTONS((addr6)); \
-                     ((u16_t *)(addr))[7] = HTONS((addr7)); \
-                  } while(0)
+    (addr)->u16[0] = UIP_HTONS(addr0);                                      \
+    (addr)->u16[1] = UIP_HTONS(addr1);                                      \
+    (addr)->u16[2] = UIP_HTONS(addr2);                                      \
+    (addr)->u16[3] = UIP_HTONS(addr3);                                      \
+    (addr)->u16[4] = UIP_HTONS(addr4);                                      \
+    (addr)->u16[5] = UIP_HTONS(addr5);                                      \
+    (addr)->u16[6] = UIP_HTONS(addr6);                                      \
+    (addr)->u16[7] = UIP_HTONS(addr7);                                      \
+  } while(0)
 
 /**
- * Copy an IP address to another IP address.
+ * Construct an IPv6 address from sixteen 8-bit words.
+ *
+ * This function constructs an IPv6 address.
+ *
+ * \hideinitializer
+ */
+#define uip_ip6addr_u8(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7,addr8,addr9,addr10,addr11,addr12,addr13,addr14,addr15) do { \
+    (addr)->u8[0] = addr0;                                       \
+    (addr)->u8[1] = addr1;                                       \
+    (addr)->u8[2] = addr2;                                       \
+    (addr)->u8[3] = addr3;                                       \
+    (addr)->u8[4] = addr4;                                       \
+    (addr)->u8[5] = addr5;                                       \
+    (addr)->u8[6] = addr6;                                       \
+    (addr)->u8[7] = addr7;                                       \
+    (addr)->u8[8] = addr8;                                       \
+    (addr)->u8[9] = addr9;                                       \
+    (addr)->u8[10] = addr10;                                     \
+    (addr)->u8[11] = addr11;                                     \
+    (addr)->u8[12] = addr12;                                     \
+    (addr)->u8[13] = addr13;                                     \
+    (addr)->u8[14] = addr14;                                     \
+    (addr)->u8[15] = addr15;                                     \
+  } while(0)
+
+
+/**
+ * Copy an IP address from one place to another.
  *
  * Copies an IP address from one place to another.
  *
@@ -878,14 +983,15 @@
  *
  * \hideinitializer
  */
-#if !UIP_CONF_IPV6
-#define uip_ipaddr_copy(dest, src) do { \
-                     ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \
-                     ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \
-                  } while(0)
-#else /* !UIP_CONF_IPV6 */
-#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
-#endif /* !UIP_CONF_IPV6 */
+#ifndef uip_ipaddr_copy
+#define uip_ipaddr_copy(dest, src) (*(dest) = *(src))
+#endif
+#ifndef uip_ip4addr_copy
+#define uip_ip4addr_copy(dest, src) (*(dest) = *(src))
+#endif
+#ifndef uip_ip6addr_copy
+#define uip_ip6addr_copy(dest, src) (*(dest) = *(src))
+#endif
 
 /**
  * Compare two IP addresses
@@ -898,7 +1004,7 @@
 
  uip_ipaddr(&ipaddr1, 192,16,1,2);
  if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
-    printf("They are the same");
+  printf("They are the same");
  }
  \endcode
  *
@@ -907,12 +1013,15 @@
  *
  * \hideinitializer
  */
-#if !UIP_CONF_IPV6
-#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \
-				      ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1])
-#else /* !UIP_CONF_IPV6 */
-#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
-#endif /* !UIP_CONF_IPV6 */
+#define uip_ip4addr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \
+				      (addr1)->u16[1] == (addr2)->u16[1])
+#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
+
+#if UIP_CONF_IPV6
+#define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2)
+#else /* UIP_CONF_IPV6 */
+#define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2)
+#endif /* UIP_CONF_IPV6 */
 
 /**
  * Compare two IP addresses with netmasks
@@ -928,7 +1037,7 @@
  uip_ipaddr(&ipaddr1, 192,16,1,2);
  uip_ipaddr(&ipaddr2, 192,16,1,3);
  if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {
-    printf("They are the same");
+ printf("They are the same");
  }
  \endcode
  *
@@ -938,11 +1047,33 @@
  *
  * \hideinitializer
  */
-#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
-                          (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \
-                            (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \
-                           ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \
-                            (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))
+
+#define uip_ipaddr_maskcmp(addr1, addr2, mask)          \
+  (((((uint16_t *)addr1)[0] & ((uint16_t *)mask)[0]) ==       \
+    (((uint16_t *)addr2)[0] & ((uint16_t *)mask)[0])) &&      \
+   ((((uint16_t *)addr1)[1] & ((uint16_t *)mask)[1]) ==       \
+    (((uint16_t *)addr2)[1] & ((uint16_t *)mask)[1])))
+
+#define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0)
+
+
+
+/**
+ * Check if an address is a broadcast address for a network.
+ *
+ * Checks if an address is the broadcast address for a network. The
+ * network is defined by an IP address that is on the network and the
+ * network's netmask.
+ *
+ * \param addr The IP address.
+ * \param netaddr The network's IP address.
+ * \param netmask The network's netmask.
+ *
+ * \hideinitializer
+ */
+/*#define uip_ipaddr_isbroadcast(addr, netaddr, netmask)
+  ((uip_ipaddr_t *)(addr)).u16 & ((uip_ipaddr_t *)(addr)).u16*/
+
 
 
 /**
@@ -969,10 +1100,10 @@
  *
  * \hideinitializer
  */
-#define uip_ipaddr_mask(dest, src, mask) do { \
-                     ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \
-                     ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \
-                  } while(0)
+#define uip_ipaddr_mask(dest, src, mask) do {                           \
+    ((uint16_t *)dest)[0] = ((uint16_t *)src)[0] & ((uint16_t *)mask)[0];        \
+    ((uint16_t *)dest)[1] = ((uint16_t *)src)[1] & ((uint16_t *)mask)[1];        \
+  } while(0)
 
 /**
  * Pick the first octet of an IP address.
@@ -982,7 +1113,7 @@
  * Example:
  \code
  uip_ipaddr_t ipaddr;
- u8_t octet;
+ uint8_t octet;
 
  uip_ipaddr(&ipaddr, 1,2,3,4);
  octet = uip_ipaddr1(&ipaddr);
@@ -992,7 +1123,7 @@
  *
  * \hideinitializer
  */
-#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8)
+#define uip_ipaddr1(addr) ((addr)->u8[0])
 
 /**
  * Pick the second octet of an IP address.
@@ -1002,7 +1133,7 @@
  * Example:
  \code
  uip_ipaddr_t ipaddr;
- u8_t octet;
+ uint8_t octet;
 
  uip_ipaddr(&ipaddr, 1,2,3,4);
  octet = uip_ipaddr2(&ipaddr);
@@ -1012,7 +1143,7 @@
  *
  * \hideinitializer
  */
-#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff)
+#define uip_ipaddr2(addr) ((addr)->u8[1])
 
 /**
  * Pick the third octet of an IP address.
@@ -1022,7 +1153,7 @@
  * Example:
  \code
  uip_ipaddr_t ipaddr;
- u8_t octet;
+ uint8_t octet;
 
  uip_ipaddr(&ipaddr, 1,2,3,4);
  octet = uip_ipaddr3(&ipaddr);
@@ -1032,7 +1163,7 @@
  *
  * \hideinitializer
  */
-#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8)
+#define uip_ipaddr3(addr) ((addr)->u8[2])
 
 /**
  * Pick the fourth octet of an IP address.
@@ -1042,7 +1173,7 @@
  * Example:
  \code
  uip_ipaddr_t ipaddr;
- u8_t octet;
+ uint8_t octet;
 
  uip_ipaddr(&ipaddr, 1,2,3,4);
  octet = uip_ipaddr4(&ipaddr);
@@ -1052,39 +1183,48 @@
  *
  * \hideinitializer
  */
-#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff)
+#define uip_ipaddr4(addr) ((addr)->u8[3])
 
 /**
  * Convert 16-bit quantity from host byte order to network byte order.
  *
  * This macro is primarily used for converting constants from host
  * byte order to network byte order. For converting variables to
- * network byte order, use the htons() function instead.
+ * network byte order, use the uip_htons() function instead.
  *
  * \hideinitializer
  */
-#ifndef HTONS
+#ifndef UIP_HTONS
 #   if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
-#      define HTONS(n) (n)
+#      define UIP_HTONS(n) (n)
+#      define UIP_HTONL(n) (n)
 #   else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
-#      define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
+#      define UIP_HTONS(n) (uint16_t)((((uint16_t) (n)) << 8) | (((uint16_t) (n)) >> 8))
+#      define UIP_HTONL(n) (((uint32_t)UIP_HTONS(n) << 16) | UIP_HTONS((uint32_t)(n) >> 16))
 #   endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
 #else
-#error "HTONS already defined!"
-#endif /* HTONS */
+#error "UIP_HTONS already defined!"
+#endif /* UIP_HTONS */
 
 /**
- * Convert 16-bit quantity from host byte order to network byte order.
+ * Convert a 16-bit quantity from host byte order to network byte order.
  *
  * This function is primarily used for converting variables from host
  * byte order to network byte order. For converting constants to
- * network byte order, use the HTONS() macro instead.
+ * network byte order, use the UIP_HTONS() macro instead.
  */
-#ifndef htons
-u16_t htons(u16_t val);
-#endif /* htons */
-#ifndef ntohs
-#define ntohs htons
+#ifndef uip_htons
+CCIF uint16_t uip_htons(uint16_t val);
+#endif /* uip_htons */
+#ifndef uip_ntohs
+#define uip_ntohs uip_htons
+#endif
+
+#ifndef uip_htonl
+CCIF uint32_t uip_htonl(uint32_t val);
+#endif /* uip_htonl */
+#ifndef uip_ntohl
+#define uip_ntohl uip_htonl
 #endif
 
 /** @} */
@@ -1096,10 +1236,10 @@
  * called. If the application wishes to send data, the application may
  * use this space to write the data into before calling uip_send().
  */
-extern void *uip_appdata;
+CCIF extern void *uip_appdata;
 
 #if UIP_URGDATA > 0
-/* u8_t *uip_urgdata:
+/* uint8_t *uip_urgdata:
  *
  * This pointer points to any urgent data that has been received. Only
  * present if compiled with support for urgent data (UIP_URGDATA).
@@ -1131,12 +1271,16 @@
  * packet.
  *
  */
-extern u16_t uip_len;
+CCIF extern uint16_t uip_len;
 
+/**
+ * The length of the extension headers
+ */
+extern uint8_t uip_ext_len;
 /** @} */
 
 #if UIP_URGDATA > 0
-extern u16_t uip_urglen, uip_surglen;
+extern uint16_t uip_urglen, uip_surglen;
 #endif /* UIP_URGDATA > 0 */
 
 
@@ -1145,7 +1289,7 @@
  *
  * The uip_conn structure is used for identifying a connection. All
  * but one field in the structure are to be considered read-only by an
- * application. The only exception is the appstate field whos purpose
+ * application. The only exception is the appstate field whose purpose
  * is to let the application store application-specific state (e.g.,
  * file pointers) for the connection. The type of this field is
  * configured in the "uipopt.h" header file.
@@ -1153,27 +1297,27 @@
 struct uip_conn {
   uip_ipaddr_t ripaddr;   /**< The IP address of the remote host. */
   
-  u16_t lport;        /**< The local TCP port, in network byte order. */
-  u16_t rport;        /**< The local remote TCP port, in network byte
+  uint16_t lport;        /**< The local TCP port, in network byte order. */
+  uint16_t rport;        /**< The local remote TCP port, in network byte
 			 order. */
   
-  u8_t rcv_nxt[4];    /**< The sequence number that we expect to
+  uint8_t rcv_nxt[4];    /**< The sequence number that we expect to
 			 receive next. */
-  u8_t snd_nxt[4];    /**< The sequence number that was last sent by
+  uint8_t snd_nxt[4];    /**< The sequence number that was last sent by
                          us. */
-  u16_t len;          /**< Length of the data that was previously sent. */
-  u16_t mss;          /**< Current maximum segment size for the
+  uint16_t len;          /**< Length of the data that was previously sent. */
+  uint16_t mss;          /**< Current maximum segment size for the
 			 connection. */
-  u16_t initialmss;   /**< Initial maximum segment size for the
+  uint16_t initialmss;   /**< Initial maximum segment size for the
 			 connection. */
-  u8_t sa;            /**< Retransmission time-out calculation state
+  uint8_t sa;            /**< Retransmission time-out calculation state
 			 variable. */
-  u8_t sv;            /**< Retransmission time-out calculation state
+  uint8_t sv;            /**< Retransmission time-out calculation state
 			 variable. */
-  u8_t rto;           /**< Retransmission time-out. */
-  u8_t tcpstateflags; /**< TCP state and flags. */
-  u8_t timer;         /**< The retransmission timer. */
-  u8_t nrtx;          /**< The number of retransmissions for the last
+  uint8_t rto;           /**< Retransmission time-out. */
+  uint8_t tcpstateflags; /**< TCP state and flags. */
+  uint8_t timer;         /**< The retransmission timer. */
+  uint8_t nrtx;          /**< The number of retransmissions for the last
 			 segment sent. */
 
   /** The application state. */
@@ -1187,9 +1331,13 @@
  * The uip_conn pointer can be used to access the current TCP
  * connection.
  */
-extern struct uip_conn *uip_conn;
+
+CCIF extern struct uip_conn *uip_conn;
+#if UIP_TCP
 /* The array containing all uIP connections. */
-extern struct uip_conn uip_conns[UIP_CONNS];
+CCIF extern struct uip_conn uip_conns[UIP_CONNS];
+#endif
+
 /**
  * \addtogroup uiparch
  * @{
@@ -1198,8 +1346,7 @@
 /**
  * 4-byte array used for the 32-bit sequence number calculations.
  */
-extern u8_t uip_acc32[4];
-
+extern uint8_t uip_acc32[4];
 /** @} */
 
 
@@ -1209,9 +1356,9 @@
  */
 struct uip_udp_conn {
   uip_ipaddr_t ripaddr;   /**< The IP address of the remote peer. */
-  u16_t lport;        /**< The local port number in network byte order. */
-  u16_t rport;        /**< The remote port number in network byte order. */
-  u8_t  ttl;          /**< Default time-to-live. */
+  uint16_t lport;        /**< The local port number in network byte order. */
+  uint16_t rport;        /**< The remote port number in network byte order. */
+  uint8_t  ttl;          /**< Default time-to-live. */
 
   /** The application state. */
   uip_udp_appstate_t appstate;
@@ -1224,6 +1371,30 @@
 extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
 #endif /* UIP_UDP */
 
+struct uip_fallback_interface {
+  void (*init)(void);
+  void (*output)(void);
+};
+
+#if UIP_CONF_ICMP6
+struct uip_icmp6_conn {
+  uip_icmp6_appstate_t appstate;
+};
+extern struct uip_icmp6_conn uip_icmp6_conns;
+#endif /*UIP_CONF_ICMP6*/
+
+/**
+ * The uIP TCP/IP statistics.
+ *
+ * This is the variable in which the uIP TCP/IP statistics are gathered.
+ */
+#if UIP_STATISTICS == 1
+extern struct uip_stats uip_stat;
+#define UIP_STAT(s) s
+#else
+#define UIP_STAT(s)
+#endif /* UIP_STATISTICS == 1 */
+
 /**
  * The structure holding the TCP/IP statistics that are gathered if
  * UIP_STATISTICS is set to 1.
@@ -1231,47 +1402,53 @@
  */
 struct uip_stats {
   struct {
-    uip_stats_t drop;     /**< Number of dropped packets at the IP
-			     layer. */
     uip_stats_t recv;     /**< Number of received packets at the IP
 			     layer. */
     uip_stats_t sent;     /**< Number of sent packets at the IP
 			     layer. */
+    uip_stats_t forwarded;/**< Number of forwarded packets at the IP 
+			     layer. */
+    uip_stats_t drop;     /**< Number of dropped packets at the IP
+			     layer. */
     uip_stats_t vhlerr;   /**< Number of packets dropped due to wrong
 			     IP version or header length. */
     uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
 			     IP length, high byte. */
     uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
 			     IP length, low byte. */
-    uip_stats_t fragerr;  /**< Number of packets dropped since they
+    uip_stats_t fragerr;  /**< Number of packets dropped because they
 			     were IP fragments. */
     uip_stats_t chkerr;   /**< Number of packets dropped due to IP
 			     checksum errors. */
-    uip_stats_t protoerr; /**< Number of packets dropped since they
+    uip_stats_t protoerr; /**< Number of packets dropped because they
 			     were neither ICMP, UDP nor TCP. */
   } ip;                   /**< IP statistics. */
   struct {
-    uip_stats_t drop;     /**< Number of dropped ICMP packets. */
     uip_stats_t recv;     /**< Number of received ICMP packets. */
     uip_stats_t sent;     /**< Number of sent ICMP packets. */
+    uip_stats_t drop;     /**< Number of dropped ICMP packets. */
     uip_stats_t typeerr;  /**< Number of ICMP packets with a wrong
 			     type. */
+    uip_stats_t chkerr;   /**< Number of ICMP packets with a bad
+			     checksum. */
   } icmp;                 /**< ICMP statistics. */
+#if UIP_TCP
   struct {
-    uip_stats_t drop;     /**< Number of dropped TCP segments. */
     uip_stats_t recv;     /**< Number of recived TCP segments. */
     uip_stats_t sent;     /**< Number of sent TCP segments. */
+    uip_stats_t drop;     /**< Number of dropped TCP segments. */
     uip_stats_t chkerr;   /**< Number of TCP segments with a bad
 			     checksum. */
     uip_stats_t ackerr;   /**< Number of TCP segments with a bad ACK
 			     number. */
-    uip_stats_t rst;      /**< Number of recevied TCP RST (reset) segments. */
+    uip_stats_t rst;      /**< Number of received TCP RST (reset) segments. */
     uip_stats_t rexmit;   /**< Number of retransmitted TCP segments. */
-    uip_stats_t syndrop;  /**< Number of dropped SYNs due to too few
-			     connections was avaliable. */
+    uip_stats_t syndrop;  /**< Number of dropped SYNs because too few
+			     connections were available. */
     uip_stats_t synrst;   /**< Number of SYNs for closed ports,
 			     triggering a RST. */
   } tcp;                  /**< TCP statistics. */
+#endif
 #if UIP_UDP
   struct {
     uip_stats_t drop;     /**< Number of dropped UDP segments. */
@@ -1281,33 +1458,36 @@
 			     checksum. */
   } udp;                  /**< UDP statistics. */
 #endif /* UIP_UDP */
+#if UIP_CONF_IPV6
+  struct {
+    uip_stats_t drop;     /**< Number of dropped ND6 packets. */
+    uip_stats_t recv;     /**< Number of recived ND6 packets */
+    uip_stats_t sent;     /**< Number of sent ND6 packets */
+  } nd6;
+#endif /*UIP_CONF_IPV6*/
 };
 
-/**
- * The uIP TCP/IP statistics.
- *
- * This is the variable in which the uIP TCP/IP statistics are gathered.
- */
-extern struct uip_stats uip_stat;
-
 
 /*---------------------------------------------------------------------------*/
 /* All the stuff below this point is internal to uIP and should not be
  * used directly by an application or by a device driver.
  */
 /*---------------------------------------------------------------------------*/
-/* u8_t uip_flags:
+
+
+
+/* uint8_t uip_flags:
  *
  * When the application is called, uip_flags will contain the flags
  * that are defined in this file. Please read below for more
- * infomation.
+ * information.
  */
-extern u8_t uip_flags;
+CCIF extern uint8_t uip_flags;
 
 /* The following flags may be set in the global variable uip_flags
    before calling the application callback. The UIP_ACKDATA,
    UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time,
-   whereas the others are mutualy exclusive. Note that these flags
+   whereas the others are mutually exclusive. Note that these flags
    should *NOT* be accessed directly, but only through the uIP
    functions/macros. */
 
@@ -1340,18 +1520,28 @@
 #define UIP_TIMEDOUT  128   /* The connection has been aborted due to
 			       too many retransmissions. */
 
+
+/**
+ * \brief process the options within a hop by hop or destination option header
+ * \retval 0: nothing to send,
+ * \retval 1: drop pkt
+ * \retval 2: ICMP error message to send
+*/
+/*static uint8_t
+uip_ext_hdr_options_process(); */
+
 /* uip_process(flag):
  *
  * The actual uIP function which does all the work.
  */
-void uip_process(u8_t flag);
-
-/* The following flags are passed as an argument to the uip_process()
+void uip_process(uint8_t flag);
+  
+  /* The following flags are passed as an argument to the uip_process()
    function. They are used to distinguish between the two cases where
    uip_process() is called. It can be called either because we have
    incoming data that should be processed, or because the periodic
    timer has fired. These values are never used directly, but only in
-   the macrose defined in this file. */
+   the macros defined in this file. */
  
 #define UIP_DATA          1     /* Tells uIP that there is incoming
 				   data in the uip_buf buffer. The
@@ -1386,72 +1576,67 @@
 struct uip_tcpip_hdr {
 #if UIP_CONF_IPV6
   /* IPv6 header. */
-  u8_t vtc,
+  uint8_t vtc,
     tcflow;
-  u16_t flow;
-  u8_t len[2];
-  u8_t proto, ttl;
+  uint16_t flow;
+  uint8_t len[2];
+  uint8_t proto, ttl;
   uip_ip6addr_t srcipaddr, destipaddr;
 #else /* UIP_CONF_IPV6 */
   /* IPv4 header. */
-  u8_t vhl,
+  uint8_t vhl,
     tos,
     len[2],
     ipid[2],
     ipoffset[2],
     ttl,
     proto;
-  u16_t ipchksum;
-  u16_t srcipaddr[2],
-    destipaddr[2];
+  uint16_t ipchksum;
+  uip_ipaddr_t srcipaddr, destipaddr;
 #endif /* UIP_CONF_IPV6 */
   
   /* TCP header. */
-  u16_t srcport,
+  uint16_t srcport,
     destport;
-  u8_t seqno[4],
+  uint8_t seqno[4],
     ackno[4],
     tcpoffset,
     flags,
     wnd[2];
-  u16_t tcpchksum;
-  u8_t urgp[2];
-  u8_t optdata[4];
+  uint16_t tcpchksum;
+  uint8_t urgp[2];
+  uint8_t optdata[4];
 };
 
 /* The ICMP and IP headers. */
 struct uip_icmpip_hdr {
 #if UIP_CONF_IPV6
   /* IPv6 header. */
-  u8_t vtc,
+  uint8_t vtc,
     tcf;
-  u16_t flow;
-  u8_t len[2];
-  u8_t proto, ttl;
+  uint16_t flow;
+  uint8_t len[2];
+  uint8_t proto, ttl;
   uip_ip6addr_t srcipaddr, destipaddr;
 #else /* UIP_CONF_IPV6 */
   /* IPv4 header. */
-  u8_t vhl,
+  uint8_t vhl,
     tos,
     len[2],
     ipid[2],
     ipoffset[2],
     ttl,
     proto;
-  u16_t ipchksum;
-  u16_t srcipaddr[2],
-    destipaddr[2];
+  uint16_t ipchksum;
+  uip_ipaddr_t srcipaddr, destipaddr;
 #endif /* UIP_CONF_IPV6 */
   
-  /* ICMP (echo) header. */
-  u8_t type, icode;
-  u16_t icmpchksum;
+  /* ICMP header. */
+  uint8_t type, icode;
+  uint16_t icmpchksum;
 #if !UIP_CONF_IPV6
-  u16_t id, seqno;
-#else /* !UIP_CONF_IPV6 */
-  u8_t flags, reserved1, reserved2, reserved3;
-  u8_t icmp6data[16];
-  u8_t options[1];
+  uint16_t id, seqno;
+  uint8_t payload[1];
 #endif /* !UIP_CONF_IPV6 */
 };
 
@@ -1460,34 +1645,181 @@
 struct uip_udpip_hdr {
 #if UIP_CONF_IPV6
   /* IPv6 header. */
-  u8_t vtc,
+  uint8_t vtc,
     tcf;
-  u16_t flow;
-  u8_t len[2];
-  u8_t proto, ttl;
+  uint16_t flow;
+  uint8_t len[2];
+  uint8_t proto, ttl;
   uip_ip6addr_t srcipaddr, destipaddr;
 #else /* UIP_CONF_IPV6 */
   /* IP header. */
-  u8_t vhl,
+  uint8_t vhl,
+    tos,
+    len[2],
+    ipid[2],
+    ipoffset[2],
+    ttl,
+    proto;
+  uint16_t ipchksum;
+  uip_ipaddr_t srcipaddr, destipaddr;
+#endif /* UIP_CONF_IPV6 */
+  
+  /* UDP header. */
+  uint16_t srcport,
+    destport;
+  uint16_t udplen;
+  uint16_t udpchksum;
+};
+
+/*
+ * In IPv6 the length of the L3 headers before the transport header is
+ * not fixed, due to the possibility to include extension option headers
+ * after the IP header. hence we split here L3 and L4 headers
+ */
+/* The IP header */
+struct uip_ip_hdr {
+#if UIP_CONF_IPV6
+  /* IPV6 header */
+  uint8_t vtc;
+  uint8_t tcflow;
+  uint16_t flow;
+  uint8_t len[2];
+  uint8_t proto, ttl;
+  uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+  /* IPV4 header */
+  uint8_t vhl,
     tos,
     len[2],
     ipid[2],
     ipoffset[2],
     ttl,
     proto;
-  u16_t ipchksum;
-  u16_t srcipaddr[2],
-    destipaddr[2];
+  uint16_t ipchksum;
+  uip_ipaddr_t srcipaddr, destipaddr;
 #endif /* UIP_CONF_IPV6 */
-  
-  /* UDP header. */
-  u16_t srcport,
-    destport;
-  u16_t udplen;
-  u16_t udpchksum;
 };
 
 
+/*
+ * IPv6 extension option headers: we are able to process
+ * the 4 extension headers defined in RFC2460 (IPv6):
+ * - Hop by hop option header, destination option header:
+ *   These two are not used by any core IPv6 protocol, hence
+ *   we just read them and go to the next. They convey options,
+ *   the options defined in RFC2460 are Pad1 and PadN, which do
+ *   some padding, and that we do not need to read (the length
+ *   field in the header is enough)
+ * - Routing header: this one is most notably used by MIPv6,
+ *   which we do not implement, hence we just read it and go
+ *   to the next
+ * - Fragmentation header: we read this header and are able to
+ *   reassemble packets
+ *
+ * We do not offer any means to send packets with extension headers
+ *
+ * We do not implement Authentication and ESP headers, which are
+ * used in IPSec and defined in RFC4302,4303,4305,4385
+ */
+/* common header part */
+typedef struct uip_ext_hdr {
+  uint8_t next;
+  uint8_t len;
+} uip_ext_hdr;
+
+/* Hop by Hop option header */
+typedef struct uip_hbho_hdr {
+  uint8_t next;
+  uint8_t len;
+} uip_hbho_hdr;
+
+/* destination option header */
+typedef struct uip_desto_hdr {
+  uint8_t next;
+  uint8_t len;
+} uip_desto_hdr;
+
+/* We do not define structures for PAD1 and PADN options */
+
+/*
+ * routing header
+ * the routing header as 4 common bytes, then routing header type
+ * specific data there are several types of routing header. Type 0 was
+ * deprecated as per RFC5095 most notable other type is 2, used in
+ * RFC3775 (MIPv6) here we do not implement MIPv6, so we just need to
+ * parse the 4 first bytes
+ */
+typedef struct uip_routing_hdr {
+  uint8_t next;
+  uint8_t len;
+  uint8_t routing_type;
+  uint8_t seg_left;
+} uip_routing_hdr;
+
+/* fragmentation header */
+typedef struct uip_frag_hdr {
+  uint8_t next;
+  uint8_t res;
+  uint16_t offsetresmore;
+  uint32_t id;
+} uip_frag_hdr;
+
+/*
+ * an option within the destination or hop by hop option headers
+ * it contains type an length, which is true for all options but PAD1
+ */
+typedef struct uip_ext_hdr_opt {
+  uint8_t type;
+  uint8_t len;
+} uip_ext_hdr_opt;
+
+/* PADN option */
+typedef struct uip_ext_hdr_opt_padn {
+  uint8_t opt_type;
+  uint8_t opt_len;
+} uip_ext_hdr_opt_padn;
+
+/* RPL option */
+typedef struct uip_ext_hdr_opt_rpl {
+  uint8_t opt_type;
+  uint8_t opt_len;
+  uint8_t flags;
+  uint8_t instance;
+  uint16_t senderrank;
+} uip_ext_hdr_opt_rpl;
+
+/* TCP header */
+struct uip_tcp_hdr {
+  uint16_t srcport;
+  uint16_t destport;
+  uint8_t seqno[4];
+  uint8_t ackno[4];
+  uint8_t tcpoffset;
+  uint8_t flags;
+  uint8_t  wnd[2];
+  uint16_t tcpchksum;
+  uint8_t urgp[2];
+  uint8_t optdata[4];
+};
+
+/* The ICMP headers. */
+struct uip_icmp_hdr {
+  uint8_t type, icode;
+  uint16_t icmpchksum;
+#if !UIP_CONF_IPV6
+  uint16_t id, seqno;
+#endif /* !UIP_CONF_IPV6 */
+};
+
+
+/* The UDP headers. */
+struct uip_udp_hdr {
+  uint16_t srcport;
+  uint16_t destport;
+  uint16_t udplen;
+  uint16_t udpchksum;
+};
+
 
 /**
  * The buffer size available for user data in the \ref uip_buf buffer.
@@ -1504,44 +1836,306 @@
  * \hideinitializer
  */
 #define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
-
+#define UIP_APPDATA_PTR (void *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]
 
 #define UIP_PROTO_ICMP  1
 #define UIP_PROTO_TCP   6
 #define UIP_PROTO_UDP   17
 #define UIP_PROTO_ICMP6 58
 
+
+#if UIP_CONF_IPV6
+/** @{ */
+/** \brief  extension headers types */
+#define UIP_PROTO_HBHO        0
+#define UIP_PROTO_DESTO       60
+#define UIP_PROTO_ROUTING     43
+#define UIP_PROTO_FRAG        44
+#define UIP_PROTO_NONE        59
+/** @} */
+
+/** @{ */
+/** \brief  Destination and Hop By Hop extension headers option types */
+#define UIP_EXT_HDR_OPT_PAD1  0
+#define UIP_EXT_HDR_OPT_PADN  1
+#define UIP_EXT_HDR_OPT_RPL   0x63
+
+/** @} */
+
+/** @{ */
+/**
+ * \brief Bitmaps for extension header processing
+ *
+ * When processing extension headers, we should record somehow which one we
+ * see, because you cannot have twice the same header, except for destination
+ * We store all this in one uint8_t bitmap one bit for each header expected. The
+ * order in the bitmap is the order recommended in RFC2460
+ */
+#define UIP_EXT_HDR_BITMAP_HBHO 0x01
+#define UIP_EXT_HDR_BITMAP_DESTO1 0x02
+#define UIP_EXT_HDR_BITMAP_ROUTING 0x04
+#define UIP_EXT_HDR_BITMAP_FRAG 0x08
+#define UIP_EXT_HDR_BITMAP_AH 0x10
+#define UIP_EXT_HDR_BITMAP_ESP 0x20
+#define UIP_EXT_HDR_BITMAP_DESTO2 0x40
+/** @} */
+
+
+#endif /* UIP_CONF_IPV6 */
+
+
 /* Header sizes. */
 #if UIP_CONF_IPV6
 #define UIP_IPH_LEN    40
+#define UIP_FRAGH_LEN  8
 #else /* UIP_CONF_IPV6 */
 #define UIP_IPH_LEN    20    /* Size of IP header */
 #endif /* UIP_CONF_IPV6 */
+
 #define UIP_UDPH_LEN    8    /* Size of UDP header */
 #define UIP_TCPH_LEN   20    /* Size of TCP header */
+#ifdef UIP_IPH_LEN
+#define UIP_ICMPH_LEN   4    /* Size of ICMP header */
+#endif
 #define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN)    /* Size of IP +
-							  UDP
-							  header */
+                        * UDP
+							   * header */
 #define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN)    /* Size of IP +
-							  TCP
-							  header */
+							   * TCP
+							   * header */
 #define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
+#define UIP_IPICMPH_LEN (UIP_IPH_LEN + UIP_ICMPH_LEN) /* size of ICMP
+                                                         + IP header */
+#define UIP_LLIPH_LEN (UIP_LLH_LEN + UIP_IPH_LEN)    /* size of L2
+                                                        + IP header */
+#if UIP_CONF_IPV6
+/**
+ * The sums below are quite used in ND. When used for uip_buf, we
+ * include link layer length when used for uip_len, we do not, hence
+ * we need values with and without LLH_LEN we do not use capital
+ * letters as these values are variable
+ */
+#define uip_l2_l3_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len)
+#define uip_l2_l3_icmp_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
+#define uip_l3_hdr_len (UIP_IPH_LEN + uip_ext_len)
+#define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
+#endif /*UIP_CONF_IPV6*/
 
 
 #if UIP_FIXEDADDR
-extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+CCIF extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
 #else /* UIP_FIXEDADDR */
-extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+CCIF extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
 #endif /* UIP_FIXEDADDR */
+CCIF extern const uip_ipaddr_t uip_broadcast_addr;
+CCIF extern const uip_ipaddr_t uip_all_zeroes_addr;
+
+#if UIP_FIXEDETHADDR
+CCIF extern const uip_lladdr_t uip_lladdr;
+#else
+CCIF extern uip_lladdr_t uip_lladdr;
+#endif
+
 
 
 
+#if UIP_CONF_IPV6
+/** Length of the link local prefix */
+#define UIP_LLPREF_LEN     10
+
 /**
- * Representation of a 48-bit Ethernet address.
+ * \brief Is IPv6 address a the unspecified address
+ * a is of type uip_ipaddr_t
+ */
+#define uip_is_addr_loopback(a)                  \
+  ((((a)->u16[0]) == 0) &&                       \
+   (((a)->u16[1]) == 0) &&                       \
+   (((a)->u16[2]) == 0) &&                       \
+   (((a)->u16[3]) == 0) &&                       \
+   (((a)->u16[4]) == 0) &&                       \
+   (((a)->u16[5]) == 0) &&                       \
+   (((a)->u16[6]) == 0) &&                       \
+   (((a)->u8[14]) == 0) &&                       \
+   (((a)->u8[15]) == 0x01))
+/**
+ * \brief Is IPv6 address a the unspecified address
+ * a is of type uip_ipaddr_t
+ */
+#define uip_is_addr_unspecified(a)               \
+  ((((a)->u16[0]) == 0) &&                       \
+   (((a)->u16[1]) == 0) &&                       \
+   (((a)->u16[2]) == 0) &&                       \
+   (((a)->u16[3]) == 0) &&                       \
+   (((a)->u16[4]) == 0) &&                       \
+   (((a)->u16[5]) == 0) &&                       \
+   (((a)->u16[6]) == 0) &&                       \
+   (((a)->u16[7]) == 0))
+
+/** \brief Is IPv6 address a the link local all-nodes multicast address */
+#define uip_is_addr_linklocal_allnodes_mcast(a)     \
+  ((((a)->u8[0]) == 0xff) &&                        \
+   (((a)->u8[1]) == 0x02) &&                        \
+   (((a)->u16[1]) == 0) &&                          \
+   (((a)->u16[2]) == 0) &&                          \
+   (((a)->u16[3]) == 0) &&                          \
+   (((a)->u16[4]) == 0) &&                          \
+   (((a)->u16[5]) == 0) &&                          \
+   (((a)->u16[6]) == 0) &&                          \
+   (((a)->u8[14]) == 0) &&                          \
+   (((a)->u8[15]) == 0x01))
+
+/** \brief Is IPv6 address a the link local all-routers multicast address */
+#define uip_is_addr_linklocal_allrouters_mcast(a)     \
+  ((((a)->u8[0]) == 0xff) &&                        \
+   (((a)->u8[1]) == 0x02) &&                        \
+   (((a)->u16[1]) == 0) &&                          \
+   (((a)->u16[2]) == 0) &&                          \
+   (((a)->u16[3]) == 0) &&                          \
+   (((a)->u16[4]) == 0) &&                          \
+   (((a)->u16[5]) == 0) &&                          \
+   (((a)->u16[6]) == 0) &&                          \
+   (((a)->u8[14]) == 0) &&                          \
+   (((a)->u8[15]) == 0x02))
+
+/**
+ * \brief Checks whether the address a is link local.
+ * a is of type uip_ipaddr_t
+ */
+#define uip_is_addr_linklocal(a)                 \
+  ((a)->u8[0] == 0xfe &&                         \
+   (a)->u8[1] == 0x80)
+
+/** \brief set IP address a to unspecified */
+#define uip_create_unspecified(a) uip_ip6addr(a, 0, 0, 0, 0, 0, 0, 0, 0)
+
+/** \brief set IP address a to the link local all-nodes multicast address */
+#define uip_create_linklocal_allnodes_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001)
+
+/** \brief set IP address a to the link local all-routers multicast address */
+#define uip_create_linklocal_allrouters_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002)
+#define uip_create_linklocal_prefix(addr) do { \
+    (addr)->u16[0] = UIP_HTONS(0xfe80);            \
+    (addr)->u16[1] = 0;                        \
+    (addr)->u16[2] = 0;                        \
+    (addr)->u16[3] = 0;                        \
+  } while(0)
+
+/**
+ * \brief  is addr (a) a solicited node multicast address, see RFC3513
+ *  a is of type uip_ipaddr_t*
  */
-struct uip_eth_addr {
-  u8_t addr[6];
-};
+#define uip_is_addr_solicited_node(a)          \
+  ((((a)->u8[0])  == 0xFF) &&                  \
+   (((a)->u8[1])  == 0x02) &&                  \
+   (((a)->u16[1]) == 0x00) &&                  \
+   (((a)->u16[2]) == 0x00) &&                  \
+   (((a)->u16[3]) == 0x00) &&                  \
+   (((a)->u16[4]) == 0x00) &&                  \
+   (((a)->u8[10]) == 0x00) &&                  \
+   (((a)->u8[11]) == 0x01) &&                  \
+   (((a)->u8[12]) == 0xFF))
+
+/**
+ * \briefput in b the solicited node address corresponding to address a
+ * both a and b are of type uip_ipaddr_t*
+ * */
+#define uip_create_solicited_node(a, b)    \
+  (((b)->u8[0]) = 0xFF);                        \
+  (((b)->u8[1]) = 0x02);                        \
+  (((b)->u16[1]) = 0);                          \
+  (((b)->u16[2]) = 0);                          \
+  (((b)->u16[3]) = 0);                          \
+  (((b)->u16[4]) = 0);                          \
+  (((b)->u8[10]) = 0);                          \
+  (((b)->u8[11]) = 0x01);                       \
+  (((b)->u8[12]) = 0xFF);                       \
+  (((b)->u8[13]) = ((a)->u8[13]));              \
+  (((b)->u16[7]) = ((a)->u16[7]))
+
+/**
+ * \brief is addr (a) a link local unicast address, see RFC3513
+ *  i.e. is (a) on prefix FE80::/10
+ *  a is of type uip_ipaddr_t*
+ */
+#define uip_is_addr_link_local(a) \
+  ((((a)->u8[0]) == 0xFE) && \
+  (((a)->u8[1]) == 0x80))
+
+/**
+ * \brief was addr (a) forged based on the mac address m
+ * a type is uip_ipaddr_t
+ * m type is uiplladdr_t
+ */
+#if UIP_CONF_LL_802154
+#define uip_is_addr_mac_addr_based(a, m) \
+  ((((a)->u8[8])  == (((m)->addr[0]) ^ 0x02)) &&   \
+   (((a)->u8[9])  == (m)->addr[1]) &&            \
+   (((a)->u8[10]) == (m)->addr[2]) &&            \
+   (((a)->u8[11]) == (m)->addr[3]) &&            \
+   (((a)->u8[12]) == (m)->addr[4]) &&            \
+   (((a)->u8[13]) == (m)->addr[5]) &&            \
+   (((a)->u8[14]) == (m)->addr[6]) &&            \
+   (((a)->u8[15]) == (m)->addr[7]))
+#else
+
+#define uip_is_addr_mac_addr_based(a, m) \
+  ((((a)->u8[8])  == (((m)->addr[0]) | 0x02)) &&   \
+   (((a)->u8[9])  == (m)->addr[1]) &&            \
+   (((a)->u8[10]) == (m)->addr[2]) &&            \
+   (((a)->u8[11]) == 0xff) &&            \
+   (((a)->u8[12]) == 0xfe) &&            \
+   (((a)->u8[13]) == (m)->addr[3]) &&            \
+   (((a)->u8[14]) == (m)->addr[4]) &&            \
+   (((a)->u8[15]) == (m)->addr[5]))
+   
+#endif /*UIP_CONF_LL_802154*/
+
+/**
+ * \brief is address a multicast address, see RFC 3513
+ * a is of type uip_ipaddr_t*
+ * */
+#define uip_is_addr_mcast(a)                    \
+  (((a)->u8[0]) == 0xFF)
+
+/**
+ * \brief is group-id of multicast address a
+ * the all nodes group-id
+ */
+#define uip_is_mcast_group_id_all_nodes(a) \
+  ((((a)->u16[1])  == 0) &&                 \
+   (((a)->u16[2])  == 0) &&                 \
+   (((a)->u16[3])  == 0) &&                 \
+   (((a)->u16[4])  == 0) &&                 \
+   (((a)->u16[5])  == 0) &&                 \
+   (((a)->u16[6])  == 0) &&                 \
+   (((a)->u8[14])  == 0) &&                 \
+   (((a)->u8[15])  == 1))
+
+/**
+ * \brief is group-id of multicast address a
+ * the all routers group-id
+ */
+#define uip_is_mcast_group_id_all_routers(a) \
+  ((((a)->u16[1])  == 0) &&                 \
+   (((a)->u16[2])  == 0) &&                 \
+   (((a)->u16[3])  == 0) &&                 \
+   (((a)->u16[4])  == 0) &&                 \
+   (((a)->u16[5])  == 0) &&                 \
+   (((a)->u16[6])  == 0) &&                 \
+   (((a)->u8[14])  == 0) &&                 \
+   (((a)->u8[15])  == 2))
+
+
+/**
+ * \brief are last three bytes of both addresses equal?
+ * This is used to compare solicited node multicast addresses
+ */
+#define uip_are_solicited_bytes_equal(a, b)             \
+  ((((a)->u8[13])  == ((b)->u8[13])) &&                 \
+   (((a)->u8[14])  == ((b)->u8[14])) &&                 \
+   (((a)->u8[15])  == ((b)->u8[15])))
+
+#endif /*UIP_CONF_IPV6*/
 
 /**
  * Calculate the Internet checksum over a buffer.
@@ -1559,7 +2153,7 @@
  *
  * \return The Internet checksum of the buffer.
  */
-u16_t uip_chksum(u16_t *buf, u16_t len);
+uint16_t uip_chksum(uint16_t *buf, uint16_t len);
 
 /**
  * Calculate the IP header checksum of the packet header in uip_buf.
@@ -1570,7 +2164,7 @@
  * \return The IP header checksum of the IP header in the uip_buf
  * buffer.
  */
-u16_t uip_ipchksum(void);
+uint16_t uip_ipchksum(void);
 
 /**
  * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
@@ -1581,7 +2175,7 @@
  * \return The TCP checksum of the TCP segment in uip_buf and pointed
  * to by uip_appdata.
  */
-u16_t uip_tcpchksum(void);
+uint16_t uip_tcpchksum(void);
 
 /**
  * Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
@@ -1592,7 +2186,14 @@
  * \return The UDP checksum of the UDP segment in uip_buf and pointed
  * to by uip_appdata.
  */
-u16_t uip_udpchksum(void);
+uint16_t uip_udpchksum(void);
+
+/**
+ * Calculate the ICMP checksum of the packet in uip_buf.
+ *
+ * \return The ICMP checksum of the ICMP packet in uip_buf
+ */
+uint16_t uip_icmp6chksum(void);
 
 
 #endif /* __UIP_H__ */
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uip_arp.c
--- a/uip/uip_arp.c	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uip_arp.c	Mon Jun 30 16:00:08 2014 +0000
@@ -54,7 +54,6 @@
  *
  * This file is part of the uIP TCP/IP stack.
  *
- * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $
  *
  */
 
@@ -65,30 +64,29 @@
 
 struct arp_hdr {
   struct uip_eth_hdr ethhdr;
-  u16_t hwtype;
-  u16_t protocol;
-  u8_t hwlen;
-  u8_t protolen;
-  u16_t opcode;
+  uint16_t hwtype;
+  uint16_t protocol;
+  uint8_t hwlen;
+  uint8_t protolen;
+  uint16_t opcode;
   struct uip_eth_addr shwaddr;
-  u16_t sipaddr[2];
+  uip_ipaddr_t sipaddr;
   struct uip_eth_addr dhwaddr;
-  u16_t dipaddr[2];
+  uip_ipaddr_t dipaddr;
 };
 
 struct ethip_hdr {
   struct uip_eth_hdr ethhdr;
   /* IP header. */
-  u8_t vhl,
+  uint8_t vhl,
     tos,
     len[2],
     ipid[2],
     ipoffset[2],
     ttl,
     proto;
-  u16_t ipchksum;
-  u16_t srcipaddr[2],
-    destipaddr[2];
+  uint16_t ipchksum;
+  uip_ipaddr_t srcipaddr, destipaddr;
 };
 
 #define ARP_REQUEST 1
@@ -97,24 +95,33 @@
 #define ARP_HWTYPE_ETH 1
 
 struct arp_entry {
-  u16_t ipaddr[2];
+  uip_ipaddr_t ipaddr;
   struct uip_eth_addr ethaddr;
-  u8_t time;
+  uint8_t time;
 };
 
 static const struct uip_eth_addr broadcast_ethaddr =
   {{0xff,0xff,0xff,0xff,0xff,0xff}};
-static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
+static const uint16_t broadcast_ipaddr[2] = {0xffff,0xffff};
 
 static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
-static u16_t ipaddr[2];
-static u8_t i, c;
+static uip_ipaddr_t ipaddr;
+static uint8_t i, c;
 
-static u8_t arptime;
-static u8_t tmpage;
+static uint8_t arptime;
+static uint8_t tmpage;
 
 #define BUF   ((struct arp_hdr *)&uip_buf[0])
 #define IPBUF ((struct ethip_hdr *)&uip_buf[0])
+
+#define DEBUG 0
+#if DEBUG
+#include <stdio.h>
+#define PRINTF(...) printf(__VA_ARGS__)
+#else
+#define PRINTF(...)
+#endif
+
 /*-----------------------------------------------------------------------------------*/
 /**
  * Initialize the ARP module.
@@ -125,7 +132,7 @@
 uip_arp_init(void)
 {
   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
-    memset(arp_table[i].ipaddr, 0, 4);
+    memset(&arp_table[i].ipaddr, 0, 4);
   }
 }
 /*-----------------------------------------------------------------------------------*/
@@ -146,32 +153,32 @@
   ++arptime;
   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
     tabptr = &arp_table[i];
-    if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
+    if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) &&
        arptime - tabptr->time >= UIP_ARP_MAXAGE) {
-      memset(tabptr->ipaddr, 0, 4);
+      memset(&tabptr->ipaddr, 0, 4);
     }
   }
 
 }
+
 /*-----------------------------------------------------------------------------------*/
 static void
-uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
+uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr)
 {
-  register struct arp_entry *tabptr;
+  register struct arp_entry *tabptr = arp_table;
+
   /* Walk through the ARP mapping table and try to find an entry to
      update. If none is found, the IP -> MAC address mapping is
      inserted in the ARP table. */
   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+    tabptr = &arp_table[i];
 
-    tabptr = &arp_table[i];
     /* Only check those entries that are actually in use. */
-    if(tabptr->ipaddr[0] != 0 &&
-       tabptr->ipaddr[1] != 0) {
+    if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
 
       /* Check if the source IP address of the incoming packet matches
          the IP address in this ARP table entry. */
-      if(ipaddr[0] == tabptr->ipaddr[0] &&
-	 ipaddr[1] == tabptr->ipaddr[1]) {
+      if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) {
 	 
 	/* An old entry found, update this and return. */
 	memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
@@ -180,6 +187,7 @@
 	return;
       }
     }
+	tabptr++;
   }
 
   /* If we get here, no existing ARP table entry was found, so we
@@ -188,8 +196,7 @@
   /* First, we try to find an unused entry in the ARP table. */
   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
     tabptr = &arp_table[i];
-    if(tabptr->ipaddr[0] == 0 &&
-       tabptr->ipaddr[1] == 0) {
+    if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
       break;
     }
   }
@@ -212,7 +219,7 @@
 
   /* Now, i is the ARP table entry which we will fill with the new
      information. */
-  memcpy(tabptr->ipaddr, ipaddr, 4);
+  uip_ipaddr_copy(&tabptr->ipaddr, ipaddr);
   memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
   tabptr->time = arptime;
 }
@@ -285,37 +292,41 @@
   uip_len = 0;
   
   switch(BUF->opcode) {
-  case HTONS(ARP_REQUEST):
+  case UIP_HTONS(ARP_REQUEST):
     /* ARP request. If it asked for our address, we send out a
        reply. */
-    if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+    /*    if(BUF->dipaddr[0] == uip_hostaddr[0] &&
+	  BUF->dipaddr[1] == uip_hostaddr[1]) {*/
+    PRINTF("uip_arp_arpin: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n",
+	   BUF->dipaddr.u8[0], BUF->dipaddr.u8[1],
+	   BUF->dipaddr.u8[2], BUF->dipaddr.u8[3],
+	   uip_hostaddr.u8[0], uip_hostaddr.u8[1],
+	   uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
+    if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
       /* First, we register the one who made the request in our ARP
 	 table, since it is likely that we will do more communication
 	 with this host in the future. */
-      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+      uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
       
-      /* The reply opcode is 2. */
-      BUF->opcode = HTONS(2);
+      BUF->opcode = UIP_HTONS(ARP_REPLY);
 
       memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
-      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
-      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+      memcpy(BUF->shwaddr.addr, uip_lladdr.addr, 6);
+      memcpy(BUF->ethhdr.src.addr, uip_lladdr.addr, 6);
       memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
       
-      BUF->dipaddr[0] = BUF->sipaddr[0];
-      BUF->dipaddr[1] = BUF->sipaddr[1];
-      BUF->sipaddr[0] = uip_hostaddr[0];
-      BUF->sipaddr[1] = uip_hostaddr[1];
+      uip_ipaddr_copy(&BUF->dipaddr, &BUF->sipaddr);
+      uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
 
-      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+      BUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);
       uip_len = sizeof(struct arp_hdr);
     }
     break;
-  case HTONS(ARP_REPLY):
+  case UIP_HTONS(ARP_REPLY):
     /* ARP reply. We insert or update the ARP table if it was meant
        for us. */
-    if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
-      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+    if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
+      uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
     }
     break;
   }
@@ -353,7 +364,7 @@
 void
 uip_arp_out(void)
 {
-  struct arp_entry *tabptr;
+  struct arp_entry *tabptr = arp_table;
   
   /* Find the destination IP address in the ARP table and construct
      the Ethernet header. If the destination IP addres isn't on the
@@ -363,25 +374,32 @@
      packet with an ARP request for the IP address. */
 
   /* First check if destination is a local broadcast. */
-  if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
+  if(uip_ipaddr_cmp(&IPBUF->destipaddr, &uip_broadcast_addr)) {
     memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
+  } else if(IPBUF->destipaddr.u8[0] == 224) {
+    /* Multicast. */
+    IPBUF->ethhdr.dest.addr[0] = 0x01;
+    IPBUF->ethhdr.dest.addr[1] = 0x00;
+    IPBUF->ethhdr.dest.addr[2] = 0x5e;
+    IPBUF->ethhdr.dest.addr[3] = IPBUF->destipaddr.u8[1];
+    IPBUF->ethhdr.dest.addr[4] = IPBUF->destipaddr.u8[2];
+    IPBUF->ethhdr.dest.addr[5] = IPBUF->destipaddr.u8[3];
   } else {
     /* Check if the destination address is on the local network. */
-    if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
+    if(!uip_ipaddr_maskcmp(&IPBUF->destipaddr, &uip_hostaddr, &uip_netmask)) {
       /* Destination address was not on the local network, so we need to
 	 use the default router's IP address instead of the destination
 	 address when determining the MAC address. */
-      uip_ipaddr_copy(ipaddr, uip_draddr);
+      uip_ipaddr_copy(&ipaddr, &uip_draddr);
     } else {
       /* Else, we use the destination IP address. */
-      uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
+      uip_ipaddr_copy(&ipaddr, &IPBUF->destipaddr);
     }
-      
     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
-      tabptr = &arp_table[i];
-      if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
+      if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) {
 	break;
       }
+	  tabptr++;
     }
 
     if(i == UIP_ARPTAB_SIZE) {
@@ -390,17 +408,17 @@
 
       memset(BUF->ethhdr.dest.addr, 0xff, 6);
       memset(BUF->dhwaddr.addr, 0x00, 6);
-      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
-      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+      memcpy(BUF->ethhdr.src.addr, uip_lladdr.addr, 6);
+      memcpy(BUF->shwaddr.addr, uip_lladdr.addr, 6);
     
-      uip_ipaddr_copy(BUF->dipaddr, ipaddr);
-      uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
-      BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
-      BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
-      BUF->protocol = HTONS(UIP_ETHTYPE_IP);
+      uip_ipaddr_copy(&BUF->dipaddr, &ipaddr);
+      uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
+      BUF->opcode = UIP_HTONS(ARP_REQUEST); /* ARP request. */
+      BUF->hwtype = UIP_HTONS(ARP_HWTYPE_ETH);
+      BUF->protocol = UIP_HTONS(UIP_ETHTYPE_IP);
       BUF->hwlen = 6;
       BUF->protolen = 4;
-      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+      BUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);
 
       uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
     
@@ -411,9 +429,9 @@
     /* Build an ethernet header. */
     memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
   }
-  memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+  memcpy(IPBUF->ethhdr.src.addr, uip_lladdr.addr, 6);
   
-  IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
+  IPBUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_IP);
 
   uip_len += sizeof(struct uip_eth_hdr);
 }
@@ -421,3 +439,4 @@
 
 /** @} */
 /** @} */
+
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uip_arp.h
--- a/uip/uip_arp.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uip_arp.h	Mon Jun 30 16:00:08 2014 +0000
@@ -45,7 +45,6 @@
  *
  * This file is part of the uIP TCP/IP stack.
  *
- * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $
  *
  */
 
@@ -55,7 +54,6 @@
 #include "uip.h"
 
 
-extern struct uip_eth_addr uip_ethaddr;
 
 /**
  * The Ethernet header.
@@ -63,12 +61,12 @@
 struct uip_eth_hdr {
   struct uip_eth_addr dest;
   struct uip_eth_addr src;
-  u16_t type;
+  uint16_t type;
 };
 
-#define UIP_ETHTYPE_ARP 0x0806
-#define UIP_ETHTYPE_IP  0x0800
-#define UIP_ETHTYPE_IP6 0x86dd
+#define UIP_ETHTYPE_ARP  0x0806
+#define UIP_ETHTYPE_IP   0x0800
+#define UIP_ETHTYPE_IPV6 0x86dd
 
 
 /* The uip_arp_init() function must be called before any of the other
@@ -131,14 +129,15 @@
  *
  * \hideinitializer
  */
-#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
-                              uip_ethaddr.addr[1] = eaddr.addr[1];\
-                              uip_ethaddr.addr[2] = eaddr.addr[2];\
-                              uip_ethaddr.addr[3] = eaddr.addr[3];\
-                              uip_ethaddr.addr[4] = eaddr.addr[4];\
-                              uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
+#define uip_setethaddr(eaddr) do {uip_lladdr.addr[0] = eaddr.addr[0]; \
+                              uip_lladdr.addr[1] = eaddr.addr[1];\
+                              uip_lladdr.addr[2] = eaddr.addr[2];\
+                              uip_lladdr.addr[3] = eaddr.addr[3];\
+                              uip_lladdr.addr[4] = eaddr.addr[4];\
+                              uip_lladdr.addr[5] = eaddr.addr[5];} while(0)
 
 /** @} */
-/** @} */
+
 
 #endif /* __UIP_ARP_H__ */
+/** @} */
diff -r 4da9ed411bdc -r a2715e9c7737 uip/uipopt.h
--- a/uip/uipopt.h	Sat Jun 21 11:54:24 2014 +0000
+++ b/uip/uipopt.h	Mon Jun 30 16:00:08 2014 +0000
@@ -69,6 +69,9 @@
 
 #include "uip-conf.h"
 
+#define CCIF
+#define CLIF
+
 /*------------------------------------------------------------------------------*/
 
 /**
@@ -79,11 +82,11 @@
  * settings statically, but only if UIP_FIXEDADDR is set to 1. The
  * configuration options for a specific node includes IP address,
  * netmask and default router as well as the Ethernet address. The
- * netmask, default router and Ethernet address are appliciable only
+ * netmask, default router and Ethernet address are applicable only
  * if uIP should be run over Ethernet.
  *
  * All of these should be changed to suit your project.
-*/
+ */
 
 /**
  * Determines if uIP should use a fixed IP address or not.
@@ -97,7 +100,7 @@
 #define UIP_FIXEDADDR    0
 
 /**
- * Ping IP address asignment.
+ * Ping IP address assignment.
  *
  * uIP uses a "ping" packets for setting its own IP address if this
  * option is set. If so, uIP will start with an empty IP address and
@@ -144,7 +147,7 @@
  * Turn on support for IP packet reassembly.
  *
  * uIP supports reassembly of fragmented IP packets. This features
- * requires an additonal amount of RAM to hold the reassembly buffer
+ * requires an additional amount of RAM to hold the reassembly buffer
  * and the reassembly code size is approximately 700 bytes.  The
  * reassembly buffer is of the same size as the uip_buf buffer
  * (configured by UIP_BUFSIZE).
@@ -171,7 +174,7 @@
  */
 
 /**
- * Toggles wether UDP support should be compiled in or not.
+ * Toggles whether UDP support should be compiled in or not.
  *
  * \hideinitializer
  */
@@ -221,11 +224,22 @@
  */
 
 /**
+ * Toggles whether TCP support should be compiled in or not.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_TCP
+#define UIP_TCP (UIP_CONF_TCP)
+#else /* UIP_CONF_TCP */
+#define UIP_TCP           1
+#endif /* UIP_CONF_TCP */
+
+/**
  * Determines if support for opening connections from uIP should be
  * compiled in.
  *
  * If the applications that are running on top of uIP for this project
- * do not need to open outgoing TCP connections, this configration
+ * do not need to open outgoing TCP connections, this configuration
  * option can be turned off to reduce the code size of uIP.
  *
  * \hideinitializer
@@ -237,7 +251,7 @@
  *
  * Since the TCP connections are statically allocated, turning this
  * configuration knob down results in less RAM used. Each TCP
- * connection requires approximatly 30 bytes of memory.
+ * connection requires approximately 30 bytes of memory.
  *
  * \hideinitializer
  */
@@ -307,7 +321,7 @@
 /**
  * The size of the advertised receiver's window.
  *
- * Should be set low (i.e., to the size of the uip_buf buffer) is the
+ * Should be set low (i.e., to the size of the uip_buf buffer) if the
  * application is slow to process incoming data, or high (32768 bytes)
  * if the application processes data quickly.
  *
@@ -350,7 +364,7 @@
 #endif
 
 /**
- * The maxium age of ARP table entries measured in 10ths of seconds.
+ * The maximum age of ARP table entries measured in 10ths of seconds.
  *
  * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
  * default).
@@ -479,7 +493,7 @@
 /*------------------------------------------------------------------------------*/
 
 /**
- * \name Appication specific configurations
+ * \name Application specific configurations
  * @{
  *
  * An uIP application is implemented using a single application