Update UC3 platform driver support to use the bitmasks defined in the header files...
[pub/USBasp.git] / Projects / Webserver / Lib / uip / uip.c
index ee88514..94171ad 100644 (file)
@@ -1,16 +1,8 @@
 #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
 
 /**
 #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,7 @@
  *
  * This file is part of the uIP TCP/IP stack.
  *
  *
  * This file is part of the uIP TCP/IP stack.
  *
- * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $
+ * $Id: uip.c,v 1.15 2008/10/15 08:08:32 adamdunkels Exp $
  *
  */
 
  *
  */
 
@@ -61,7 +53,7 @@
  * statement. While it would be possible to break the uip_process()
  * function into many smaller functions, this would increase the code
  * size because of the overhead of parameter passing and the fact that
  * statement. While it would be possible to break the uip_process()
  * function into many smaller functions, this would increase the code
  * size because of the overhead of parameter passing and the fact that
- * the optimier would not be as efficient.
+ * the optimiser would not be as efficient.
  *
  * The principle is that we have a small buffer, called the uip_buf,
  * in which the device driver puts an incoming packet. The TCP/IP
  *
  * The principle is that we have a small buffer, called the uip_buf,
  * in which the device driver puts an incoming packet. The TCP/IP
 
 #include "uip.h"
 #include "uipopt.h"
 
 #include "uip.h"
 #include "uipopt.h"
-#include "uip_arch.h"
+#include "uip_arp.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
 
 #if UIP_CONF_IPV6
-#include "uip-neighbor.h"
+#include "net/uip-neighbor.h"
 #endif /* UIP_CONF_IPV6 */
 
 #include <string.h>
 #endif /* UIP_CONF_IPV6 */
 
 #include <string.h>
    here. Otherwise, the address */
 #if UIP_FIXEDADDR > 0
 const uip_ipaddr_t uip_hostaddr =
    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 =
 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 =
 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 */
 
 #else
 uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
 #endif /* UIP_FIXEDADDR */
 
-static const uip_ipaddr_t all_ones_addr =
-#if UIP_CONF_IPV6
-  {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
-#else /* UIP_CONF_IPV6 */
-  {0xffff,0xffff};
-#endif /* UIP_CONF_IPV6 */
-static const uip_ipaddr_t all_zeroes_addr =
+const uip_ipaddr_t uip_broadcast_addr =
 #if UIP_CONF_IPV6
 #if UIP_CONF_IPV6
-  {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
+  { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
 #else /* UIP_CONF_IPV6 */
 #else /* UIP_CONF_IPV6 */
-  {0x0000,0x0000};
+  { { 0xff, 0xff, 0xff, 0xff } };
 #endif /* UIP_CONF_IPV6 */
 #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,
 
 #if UIP_FIXEDETHADDR
 const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
@@ -168,7 +158,7 @@ struct uip_conn uip_conns[UIP_CONNS];
                                connections. */
 u16_t uip_listenports[UIP_LISTENPORTS];
                              /* The uip_listenports list all currently
                                connections. */
 u16_t uip_listenports[UIP_LISTENPORTS];
                              /* The uip_listenports list all currently
-                               listning ports. */
+                               listening ports. */
 #if UIP_UDP
 struct uip_udp_conn *uip_udp_conn;
 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
 #if UIP_UDP
 struct uip_udp_conn *uip_udp_conn;
 struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
@@ -211,6 +201,9 @@ static u16_t tmp16;
 #define ICMP_ECHO_REPLY 0
 #define ICMP_ECHO       8
 
 #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
 #define ICMP6_ECHO_REPLY             129
 #define ICMP6_ECHO                   128
 #define ICMP6_NEIGHBOR_SOLICITATION  135
@@ -252,15 +245,15 @@ uip_add32(u8_t *op32, u16_t op16)
   uip_acc32[2] = op32[2] + (op16 >> 8);
   uip_acc32[1] = op32[1];
   uip_acc32[0] = op32[0];
   uip_acc32[2] = op32[2] + (op16 >> 8);
   uip_acc32[1] = op32[1];
   uip_acc32[0] = op32[0];
-  
+
   if(uip_acc32[2] < (op16 >> 8)) {
     ++uip_acc32[1];
     if(uip_acc32[1] == 0) {
       ++uip_acc32[0];
     }
   }
   if(uip_acc32[2] < (op16 >> 8)) {
     ++uip_acc32[1];
     if(uip_acc32[1] == 0) {
       ++uip_acc32[0];
     }
   }
-  
-  
+
+
   if(uip_acc32[3] < (op16 & 0xff)) {
     ++uip_acc32[2];
     if(uip_acc32[2] == 0) {
   if(uip_acc32[3] < (op16 & 0xff)) {
     ++uip_acc32[2];
     if(uip_acc32[2] == 0) {
@@ -285,7 +278,7 @@ chksum(u16_t sum, const u8_t *data, u16_t len)
 
   dataptr = data;
   last_byte = data + len - 1;
 
   dataptr = data;
   last_byte = data + len - 1;
-  
+
   while(dataptr < last_byte) { /* At least two more bytes */
     t = (dataptr[0] << 8) + dataptr[1];
     sum += t;
   while(dataptr < last_byte) { /* At least two more bytes */
     t = (dataptr[0] << 8) + dataptr[1];
     sum += t;
@@ -294,7 +287,7 @@ chksum(u16_t sum, const u8_t *data, u16_t len)
     }
     dataptr += 2;
   }
     }
     dataptr += 2;
   }
-  
+
   if(dataptr == last_byte) {
     t = (dataptr[0] << 8) + 0;
     sum += t;
   if(dataptr == last_byte) {
     t = (dataptr[0] << 8) + 0;
     sum += t;
@@ -330,24 +323,24 @@ upper_layer_chksum(u8_t proto)
 {
   u16_t upper_layer_len;
   u16_t sum;
 {
   u16_t upper_layer_len;
   u16_t sum;
-  
+
 #if UIP_CONF_IPV6
   upper_layer_len = (((u16_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;
 #endif /* UIP_CONF_IPV6 */
 #if UIP_CONF_IPV6
   upper_layer_len = (((u16_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;
 #endif /* UIP_CONF_IPV6 */
-  
+
   /* First sum pseudoheader. */
   /* First sum pseudoheader. */
-  
+
   /* IP protocol and length fields. This addition cannot carry. */
   sum = upper_layer_len + proto;
   /* Sum IP source and destination addresses. */
   /* 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, (u8_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);
 
   /* 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 : htons(sum);
 }
 /*---------------------------------------------------------------------------*/
@@ -356,7 +349,7 @@ u16_t
 uip_icmp6chksum(void)
 {
   return upper_layer_chksum(UIP_PROTO_ICMP6);
 uip_icmp6chksum(void)
 {
   return upper_layer_chksum(UIP_PROTO_ICMP6);
-  
+
 }
 #endif /* UIP_CONF_IPV6 */
 /*---------------------------------------------------------------------------*/
 }
 #endif /* UIP_CONF_IPV6 */
 /*---------------------------------------------------------------------------*/
@@ -393,7 +386,7 @@ uip_init(void)
     uip_udp_conns[c].lport = 0;
   }
 #endif /* UIP_UDP */
     uip_udp_conns[c].lport = 0;
   }
 #endif /* UIP_UDP */
-  
+
 
   /* IPv4 initialization. */
 #if UIP_FIXEDADDR == 0
 
   /* IPv4 initialization. */
 #if UIP_FIXEDADDR == 0
@@ -407,7 +400,7 @@ struct uip_conn *
 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
 {
   register struct uip_conn *conn, *cconn;
 uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
 {
   register struct uip_conn *conn, *cconn;
-  
+
   /* Find an unused local port. */
  again:
   ++lastport;
   /* Find an unused local port. */
  again:
   ++lastport;
@@ -444,7 +437,7 @@ uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
   if(conn == 0) {
     return 0;
   }
   if(conn == 0) {
     return 0;
   }
-  
+
   conn->tcpstateflags = UIP_SYN_SENT;
 
   conn->snd_nxt[0] = iss[0];
   conn->tcpstateflags = UIP_SYN_SENT;
 
   conn->snd_nxt[0] = iss[0];
@@ -453,7 +446,7 @@ uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
   conn->snd_nxt[3] = iss[3];
 
   conn->initialmss = conn->mss = UIP_TCP_MSS;
   conn->snd_nxt[3] = iss[3];
 
   conn->initialmss = conn->mss = UIP_TCP_MSS;
-  
+
   conn->len = 1;   /* TCP length of the SYN is one. */
   conn->nrtx = 0;
   conn->timer = 1; /* Send the SYN next time around. */
   conn->len = 1;   /* TCP length of the SYN is one. */
   conn->nrtx = 0;
   conn->timer = 1; /* Send the SYN next time around. */
@@ -463,17 +456,17 @@ uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
   conn->lport = htons(lastport);
   conn->rport = rport;
   uip_ipaddr_copy(&conn->ripaddr, ripaddr);
   conn->lport = htons(lastport);
   conn->rport = rport;
   uip_ipaddr_copy(&conn->ripaddr, ripaddr);
-  
+
   return conn;
 }
 #endif /* UIP_ACTIVE_OPEN */
 /*---------------------------------------------------------------------------*/
 #if UIP_UDP
 struct uip_udp_conn *
   return conn;
 }
 #endif /* UIP_ACTIVE_OPEN */
 /*---------------------------------------------------------------------------*/
 #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, u16_t rport)
 {
   register struct uip_udp_conn *conn;
 {
   register struct uip_udp_conn *conn;
-  
+
   /* Find an unused local port. */
  again:
   ++lastport;
   /* Find an unused local port. */
  again:
   ++lastport;
@@ -481,7 +474,7 @@ uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
   if(lastport >= 32000) {
     lastport = 4096;
   }
   if(lastport >= 32000) {
     lastport = 4096;
   }
-  
+
   for(c = 0; c < UIP_UDP_CONNS; ++c) {
     if(uip_udp_conns[c].lport == htons(lastport)) {
       goto again;
   for(c = 0; c < UIP_UDP_CONNS; ++c) {
     if(uip_udp_conns[c].lport == htons(lastport)) {
       goto again;
@@ -500,16 +493,16 @@ uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
   if(conn == 0) {
     return 0;
   }
   if(conn == 0) {
     return 0;
   }
-  
+
   conn->lport = HTONS(lastport);
   conn->rport = rport;
   if(ripaddr == NULL) {
   conn->lport = 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);
   }
   conn->ttl = UIP_TTL;
   } else {
     uip_ipaddr_copy(&conn->ripaddr, ripaddr);
   }
   conn->ttl = UIP_TTL;
-  
+
   return conn;
 }
 #endif /* UIP_UDP */
   return conn;
 }
 #endif /* UIP_UDP */
@@ -594,18 +587,18 @@ uip_reass(void)
     memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
           (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
           len);
     memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
           (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
           len);
-      
+
     /* Update the bitmap. */
     if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
       /* If the two endpoints are in the same byte, we only update
         that byte. */
     /* Update the bitmap. */
     if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
       /* If the two endpoints are in the same byte, we only update
         that byte. */
-            
+
       uip_reassbitmap[offset / (8 * 8)] |=
             bitmap_bits[(offset / 8 ) & 7] &
             ~bitmap_bits[((offset + len) / 8 ) & 7];
     } else {
       /* If the two endpoints are in different bytes, we update the
       uip_reassbitmap[offset / (8 * 8)] |=
             bitmap_bits[(offset / 8 ) & 7] &
             ~bitmap_bits[((offset + len) / 8 ) & 7];
     } else {
       /* If the two endpoints are in different bytes, we update the
-        bytes in the endpoints and fill the stuff inbetween with
+        bytes in the endpoints and fill the stuff in-between with
         0xff. */
       uip_reassbitmap[offset / (8 * 8)] |=
        bitmap_bits[(offset / 8 ) & 7];
         0xff. */
       uip_reassbitmap[offset / (8 * 8)] |=
        bitmap_bits[(offset / 8 ) & 7];
@@ -615,7 +608,7 @@ uip_reass(void)
       uip_reassbitmap[(offset + len) / (8 * 8)] |=
        ~bitmap_bits[((offset + len) / 8 ) & 7];
     }
       uip_reassbitmap[(offset + len) / (8 * 8)] |=
        ~bitmap_bits[((offset + len) / 8 ) & 7];
     }
-    
+
     /* If this fragment has the More Fragments flag set to zero, we
        know that this is the last fragment, so we can calculate the
        size of the entire packet. We also set the
     /* If this fragment has the More Fragments flag set to zero, we
        know that this is the last fragment, so we can calculate the
        size of the entire packet. We also set the
@@ -626,7 +619,7 @@ uip_reass(void)
       uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
       uip_reasslen = offset + len;
     }
       uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
       uip_reasslen = offset + len;
     }
-    
+
     /* Finally, we check if we have a full packet in the buffer. We do
        this by checking if we have the last fragment and if all bits
        in the bitmap are set. */
     /* Finally, we check if we have a full packet in the buffer. We do
        this by checking if we have the last fragment and if all bits
        in the bitmap are set. */
@@ -688,7 +681,7 @@ uip_process(u8_t flag)
     goto udp_send;
   }
 #endif /* UIP_UDP */
     goto udp_send;
   }
 #endif /* UIP_UDP */
-  
+
   uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
 
   /* Check if we were invoked because of a poll request for a
   uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
 
   /* Check if we were invoked because of a poll request for a
@@ -696,13 +689,14 @@ uip_process(u8_t flag)
   if(flag == UIP_POLL_REQUEST) {
     if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
        !uip_outstanding(uip_connr)) {
   if(flag == UIP_POLL_REQUEST) {
     if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
        !uip_outstanding(uip_connr)) {
+       uip_len = uip_slen = 0;
        uip_flags = UIP_POLL;
        UIP_APPCALL();
        goto appsend;
     }
     goto drop;
        uip_flags = UIP_POLL;
        UIP_APPCALL();
        goto appsend;
     }
     goto drop;
-    
-    /* Check if we were invoked because of the perodic timer fireing. */
+
+    /* Check if we were invoked because of the periodic timer firing. */
   } else if(flag == UIP_TIMER) {
 #if UIP_REASSEMBLY
     if(uip_reasstmr != 0) {
   } else if(flag == UIP_TIMER) {
 #if UIP_REASSEMBLY
     if(uip_reasstmr != 0) {
@@ -755,12 +749,12 @@ uip_process(u8_t flag)
            goto tcp_send_nodata;
          }
 
            goto tcp_send_nodata;
          }
 
-         /* Exponential backoff. */
+         /* Exponential back-off. */
          uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
                                         4:
                                         uip_connr->nrtx);
          ++(uip_connr->nrtx);
          uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
                                         4:
                                         uip_connr->nrtx);
          ++(uip_connr->nrtx);
-         
+
          /* Ok, so we need to retransmit. We do this differently
             depending on which state we are in. In ESTABLISHED, we
             call upon the application so that it may prepare the
          /* Ok, so we need to retransmit. We do this differently
             depending on which state we are in. In ESTABLISHED, we
             call upon the application so that it may prepare the
@@ -773,14 +767,14 @@ uip_process(u8_t flag)
            /* In the SYN_RCVD state, we should retransmit our
                SYNACK. */
            goto tcp_send_synack;
            /* In the SYN_RCVD state, we should retransmit our
                SYNACK. */
            goto tcp_send_synack;
-           
+
 #if UIP_ACTIVE_OPEN
          case UIP_SYN_SENT:
            /* In the SYN_SENT state, we retransmit out SYN. */
            BUF->flags = 0;
            goto tcp_send_syn;
 #endif /* UIP_ACTIVE_OPEN */
 #if UIP_ACTIVE_OPEN
          case UIP_SYN_SENT:
            /* In the SYN_SENT state, we retransmit out SYN. */
            BUF->flags = 0;
            goto tcp_send_syn;
 #endif /* UIP_ACTIVE_OPEN */
-           
+
          case UIP_ESTABLISHED:
            /* In the ESTABLISHED state, we call upon the application
                to do the actual retransmit after which we jump into
          case UIP_ESTABLISHED:
            /* In the ESTABLISHED state, we call upon the application
                to do the actual retransmit after which we jump into
@@ -789,18 +783,19 @@ uip_process(u8_t flag)
            uip_flags = UIP_REXMIT;
            UIP_APPCALL();
            goto apprexmit;
            uip_flags = UIP_REXMIT;
            UIP_APPCALL();
            goto apprexmit;
-           
+
          case UIP_FIN_WAIT_1:
          case UIP_CLOSING:
          case UIP_LAST_ACK:
            /* In all these states we should retransmit a FINACK. */
            goto tcp_send_finack;
          case UIP_FIN_WAIT_1:
          case UIP_CLOSING:
          case UIP_LAST_ACK:
            /* In all these states we should retransmit a FINACK. */
            goto tcp_send_finack;
-           
+
          }
        }
       } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
        /* If there was no need for a retransmission, we poll the
            application for new data. */
          }
        }
       } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
        /* If there was no need for a retransmission, we poll the
            application for new data. */
+       uip_len = uip_slen = 0;
        uip_flags = UIP_POLL;
        UIP_APPCALL();
        goto appsend;
        uip_flags = UIP_POLL;
        UIP_APPCALL();
        goto appsend;
@@ -827,7 +822,7 @@ uip_process(u8_t flag)
   UIP_STAT(++uip_stat.ip.recv);
 
   /* Start of IP input header processing code. */
   UIP_STAT(++uip_stat.ip.recv);
 
   /* Start of IP input header processing code. */
-  
+
 #if UIP_CONF_IPV6
   /* Check validity of the IP header. */
   if((BUF->vtc & 0xf0) != 0x60)  { /* IP version and header length. */
 #if UIP_CONF_IPV6
   /* Check validity of the IP header. */
   if((BUF->vtc & 0xf0) != 0x60)  { /* IP version and header length. */
@@ -845,7 +840,7 @@ uip_process(u8_t flag)
     goto drop;
   }
 #endif /* UIP_CONF_IPV6 */
     goto drop;
   }
 #endif /* UIP_CONF_IPV6 */
-  
+
   /* Check the size of the packet. If the size reported to us in
      uip_len is smaller the size reported in the IP header, we assume
      that the packet has been corrupted in transit. If the size of
   /* Check the size of the packet. If the size reported to us in
      uip_len is smaller the size reported in the IP header, we assume
      that the packet has been corrupted in transit. If the size of
@@ -889,7 +884,7 @@ uip_process(u8_t flag)
   }
 #endif /* UIP_CONF_IPV6 */
 
   }
 #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. */
     /* 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 +904,18 @@ uip_process(u8_t flag)
 #if UIP_BROADCAST
     DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
     if(BUF->proto == UIP_PROTO_UDP &&
 #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*/) {
-      goto udp_input;
+       uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr))
+       {
+               if (uip_ipaddr_cmp(&BUF->srcipaddr, &uip_all_zeroes_addr))
+                 uip_ipaddr_copy(&BUF->srcipaddr, &uip_broadcast_addr);
+
+               goto udp_input;
     }
 #endif /* UIP_BROADCAST */
     }
 #endif /* UIP_BROADCAST */
-    
+
     /* Check if the packet is destined for our IP address. */
 #if !UIP_CONF_IPV6
     /* 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;
     }
       UIP_STAT(++uip_stat.ip.drop);
       goto drop;
     }
@@ -928,8 +925,8 @@ uip_process(u8_t flag)
        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. */
        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] != HTONS(0xff02)) {
       UIP_STAT(++uip_stat.ip.drop);
       goto drop;
     }
       UIP_STAT(++uip_stat.ip.drop);
       goto drop;
     }
@@ -985,11 +982,10 @@ uip_process(u8_t flag)
 
   /* If we are configured to use ping IP address assignment, we use
      the destination IP address of this ping packet and assign it to
 
   /* If we are configured to use ping IP address assignment, we use
      the destination IP address of this ping packet and assign it to
-     ourself. */
+     yourself. */
 #if UIP_PINGADDRCONF
 #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 */
 
   }
 #endif /* UIP_PINGADDRCONF */
 
@@ -1002,11 +998,12 @@ uip_process(u8_t flag)
   }
 
   /* Swap IP addresses. */
   }
 
   /* 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);
 
   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 */
 
   /* End of IPv4 input header processing code. */
 #else /* !UIP_CONF_IPV6 */
@@ -1027,29 +1024,30 @@ uip_process(u8_t flag)
   /* If we get a neighbor solicitation for our address we should send
      a neighbor advertisement message back. */
   if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
   /* 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. */
 
       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
       /* We should now send a neighbor advertisement back to where the
-        neighbor solicication came from. */
+        neighbor solicitation came from. */
       ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
       ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
       ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
       ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
-      
+
       ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
       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));
       ICMPBUF->icmpchksum = 0;
       ICMPBUF->icmpchksum = ~uip_icmp6chksum();
       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));
       ICMPBUF->icmpchksum = 0;
       ICMPBUF->icmpchksum = ~uip_icmp6chksum();
+
       goto send;
       goto send;
-      
+
     }
     goto drop;
   } else if(ICMPBUF->type == ICMP6_ECHO) {
     }
     goto drop;
   } else if(ICMPBUF->type == ICMP6_ECHO) {
@@ -1058,12 +1056,12 @@ uip_process(u8_t flag)
        ICMP checksum before we return the packet. */
 
     ICMPBUF->type = ICMP6_ECHO_REPLY;
        ICMP checksum before we return the packet. */
 
     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();
     ICMPBUF->icmpchksum = 0;
     ICMPBUF->icmpchksum = ~uip_icmp6chksum();
-    
+
     UIP_STAT(++uip_stat.icmp.sent);
     goto send;
   } else {
     UIP_STAT(++uip_stat.icmp.sent);
     goto send;
   } else {
@@ -1075,7 +1073,7 @@ uip_process(u8_t flag)
   }
 
   /* End of IPv6 ICMP processing. */
   }
 
   /* End of IPv6 ICMP processing. */
-  
+
 #endif /* !UIP_CONF_IPV6 */
 
 #if UIP_UDP
 #endif /* !UIP_CONF_IPV6 */
 
 #if UIP_UDP
@@ -1113,21 +1111,52 @@ uip_process(u8_t flag)
        UDPBUF->destport == uip_udp_conn->lport &&
        (uip_udp_conn->rport == 0 ||
         UDPBUF->srcport == uip_udp_conn->rport) &&
        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");
       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((u16_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] = (u8_t)uip_len;
+  ICMPBUF->ttl = UIP_TTL;
+  ICMPBUF->proto = UIP_PROTO_ICMP;
+
+  goto ip_send_nolen;
+#else /* UIP_CONF_ICMP_DEST_UNREACH */
   goto drop;
   goto drop;
-  
+#endif /* UIP_CONF_ICMP_DEST_UNREACH */
+
  udp_found:
   uip_conn = NULL;
   uip_flags = UIP_NEWDATA;
   uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
   uip_slen = 0;
   UIP_UDP_APPCALL();
  udp_found:
   uip_conn = NULL;
   uip_flags = UIP_NEWDATA;
   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;
  udp_send:
   if(uip_slen == 0) {
     goto drop;
@@ -1153,9 +1182,9 @@ uip_process(u8_t flag)
   BUF->srcport  = uip_udp_conn->lport;
   BUF->destport = uip_udp_conn->rport;
 
   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];
 
 #if UIP_UDP_CHECKSUMS
   uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
 
 #if UIP_UDP_CHECKSUMS
@@ -1165,16 +1194,16 @@ uip_process(u8_t flag)
     UDPBUF->udpchksum = 0xffff;
   }
 #endif /* UIP_UDP_CHECKSUMS */
     UDPBUF->udpchksum = 0xffff;
   }
 #endif /* UIP_UDP_CHECKSUMS */
-  
+
   goto ip_send_nolen;
 #endif /* UIP_UDP */
   goto ip_send_nolen;
 #endif /* UIP_UDP */
-  
+
   /* TCP input processing. */
  tcp_input:
   UIP_STAT(++uip_stat.tcp.recv);
 
   /* Start of TCP input header processing code. */
   /* TCP input processing. */
  tcp_input:
   UIP_STAT(++uip_stat.tcp.recv);
 
   /* Start of TCP input header processing code. */
-  
+
   if(uip_tcpchksum() != 0xffff) {   /* Compute and check the TCP
                                       checksum. */
     UIP_STAT(++uip_stat.tcp.drop);
   if(uip_tcpchksum() != 0xffff) {   /* Compute and check the TCP
                                       checksum. */
     UIP_STAT(++uip_stat.tcp.drop);
@@ -1182,8 +1211,7 @@ uip_process(u8_t flag)
     UIP_LOG("tcp: bad checksum.");
     goto drop;
   }
     UIP_LOG("tcp: bad checksum.");
     goto drop;
   }
-  
-  
+
   /* Demultiplex this segment. */
   /* First check any active connections. */
   for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
   /* Demultiplex this segment. */
   /* First check any active connections. */
   for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
@@ -1191,7 +1219,7 @@ uip_process(u8_t flag)
     if(uip_connr->tcpstateflags != UIP_CLOSED &&
        BUF->destport == uip_connr->lport &&
        BUF->srcport == uip_connr->rport &&
     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;
     }
   }
       goto found;
     }
   }
@@ -1203,25 +1231,26 @@ uip_process(u8_t flag)
   if((BUF->flags & TCP_CTL) != TCP_SYN) {
     goto reset;
   }
   if((BUF->flags & TCP_CTL) != TCP_SYN) {
     goto reset;
   }
-  
+
   tmp16 = BUF->destport;
   /* Next, check listening connections. */
   for(c = 0; c < UIP_LISTENPORTS; ++c) {
   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;
       goto found_listen;
+    }
   }
   }
-  
+
   /* No matching connection found, so we send a RST packet. */
   UIP_STAT(++uip_stat.tcp.synrst);
   /* No matching connection found, so we send a RST packet. */
   UIP_STAT(++uip_stat.tcp.synrst);
- reset:
 
 
+ reset:
   /* We do not send resets in response to resets. */
   if(BUF->flags & TCP_RST) {
     goto drop;
   }
 
   UIP_STAT(++uip_stat.tcp.rst);
   /* We do not send resets in response to resets. */
   if(BUF->flags & TCP_RST) {
     goto drop;
   }
 
   UIP_STAT(++uip_stat.tcp.rst);
-  
+
   BUF->flags = TCP_RST | TCP_ACK;
   uip_len = UIP_IPTCPH_LEN;
   BUF->tcpoffset = 5 << 4;
   BUF->flags = TCP_RST | TCP_ACK;
   uip_len = UIP_IPTCPH_LEN;
   BUF->tcpoffset = 5 << 4;
@@ -1230,15 +1259,15 @@ uip_process(u8_t flag)
   c = BUF->seqno[3];
   BUF->seqno[3] = BUF->ackno[3];
   BUF->ackno[3] = c;
   c = BUF->seqno[3];
   BUF->seqno[3] = BUF->ackno[3];
   BUF->ackno[3] = c;
-  
+
   c = BUF->seqno[2];
   BUF->seqno[2] = BUF->ackno[2];
   BUF->ackno[2] = c;
   c = BUF->seqno[2];
   BUF->seqno[2] = BUF->ackno[2];
   BUF->ackno[2] = c;
-  
+
   c = BUF->seqno[1];
   BUF->seqno[1] = BUF->ackno[1];
   BUF->ackno[1] = c;
   c = BUF->seqno[1];
   BUF->seqno[1] = BUF->ackno[1];
   BUF->ackno[1] = c;
-  
+
   c = BUF->seqno[0];
   BUF->seqno[0] = BUF->ackno[0];
   BUF->ackno[0] = c;
   c = BUF->seqno[0];
   BUF->seqno[0] = BUF->ackno[0];
   BUF->ackno[0] = c;
@@ -1253,16 +1282,16 @@ uip_process(u8_t flag)
       }
     }
   }
       }
     }
   }
+
   /* Swap port numbers. */
   tmp16 = BUF->srcport;
   BUF->srcport = BUF->destport;
   BUF->destport = tmp16;
   /* Swap port numbers. */
   tmp16 = BUF->srcport;
   BUF->srcport = BUF->destport;
   BUF->destport = tmp16;
-  
+
   /* Swap IP addresses. */
   /* 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;
 
   /* And send out the RST packet! */
   goto tcp_send_noconn;
 
@@ -1270,7 +1299,7 @@ uip_process(u8_t flag)
      with a connection in LISTEN. In that case, we should create a new
      connection and send a SYNACK in return. */
  found_listen:
      with a connection in LISTEN. In that case, we should create a new
      connection and send a SYNACK in return. */
  found_listen:
-  /* First we check if there are any connections avaliable. Unused
+  /* First we check if there are any connections available. Unused
      connections are kept in the same table as used connections, but
      unused ones have the tcpstate set to CLOSED. Also, connections in
      TIME_WAIT are kept track of and we'll use the oldest one if no
      connections are kept in the same table as used connections, but
      unused ones have the tcpstate set to CLOSED. Also, connections in
      TIME_WAIT are kept track of and we'll use the oldest one if no
@@ -1299,7 +1328,7 @@ uip_process(u8_t flag)
     goto drop;
   }
   uip_conn = uip_connr;
     goto drop;
   }
   uip_conn = uip_connr;
-  
+
   /* Fill in the necessary fields for the new connection. */
   uip_connr->rto = uip_connr->timer = UIP_RTO;
   uip_connr->sa = 0;
   /* Fill in the necessary fields for the new connection. */
   uip_connr->rto = uip_connr->timer = UIP_RTO;
   uip_connr->sa = 0;
@@ -1307,7 +1336,7 @@ uip_process(u8_t flag)
   uip_connr->nrtx = 0;
   uip_connr->lport = BUF->destport;
   uip_connr->rport = BUF->srcport;
   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];
   uip_connr->tcpstateflags = UIP_SYN_RCVD;
 
   uip_connr->snd_nxt[0] = iss[0];
@@ -1340,7 +1369,7 @@ uip_process(u8_t flag)
          (u16_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;
          (u16_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;
-       
+
        /* And we are done processing options. */
        break;
       } else {
        /* And we are done processing options. */
        break;
       } else {
@@ -1355,19 +1384,19 @@ uip_process(u8_t flag)
       }
     }
   }
       }
     }
   }
-  
+
   /* Our response will be a SYNACK. */
 #if UIP_ACTIVE_OPEN
  tcp_send_synack:
   BUF->flags = TCP_ACK;
   /* Our response will be a SYNACK. */
 #if UIP_ACTIVE_OPEN
  tcp_send_synack:
   BUF->flags = TCP_ACK;
-  
+
  tcp_send_syn:
   BUF->flags |= TCP_SYN;
 #else /* UIP_ACTIVE_OPEN */
  tcp_send_synack:
   BUF->flags = TCP_SYN | TCP_ACK;
 #endif /* UIP_ACTIVE_OPEN */
  tcp_send_syn:
   BUF->flags |= TCP_SYN;
 #else /* UIP_ACTIVE_OPEN */
  tcp_send_synack:
   BUF->flags = TCP_SYN | TCP_ACK;
 #endif /* UIP_ACTIVE_OPEN */
-  
+
   /* We send out the TCP Maximum Segment Size option with our
      SYNACK. */
   BUF->optdata[0] = TCP_OPT_MSS;
   /* We send out the TCP Maximum Segment Size option with our
      SYNACK. */
   BUF->optdata[0] = TCP_OPT_MSS;
@@ -1384,7 +1413,7 @@ uip_process(u8_t flag)
   uip_flags = 0;
   /* We do a very naive form of TCP reset processing; we just accept
      any RST and kill our connection. We should in fact check if the
   uip_flags = 0;
   /* We do a very naive form of TCP reset processing; we just accept
      any RST and kill our connection. We should in fact check if the
-     sequence number of this reset is wihtin our advertised window
+     sequence number of this reset is within our advertised window
      before we accept the reset. */
   if(BUF->flags & TCP_RST) {
     uip_connr->tcpstateflags = UIP_CLOSED;
      before we accept the reset. */
   if(BUF->flags & TCP_RST) {
     uip_connr->tcpstateflags = UIP_CLOSED;
@@ -1393,7 +1422,7 @@ uip_process(u8_t flag)
     UIP_APPCALL();
     goto drop;
   }
     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
      any data to us. */
   c = (BUF->tcpoffset >> 4) << 2;
   /* uip_len will contain the length of the actual TCP data. This is
@@ -1431,7 +1460,6 @@ uip_process(u8_t flag)
       uip_connr->snd_nxt[1] = uip_acc32[1];
       uip_connr->snd_nxt[2] = uip_acc32[2];
       uip_connr->snd_nxt[3] = uip_acc32[3];
       uip_connr->snd_nxt[1] = uip_acc32[1];
       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) {
 
       /* Do RTT estimation, unless we have done retransmissions. */
       if(uip_connr->nrtx == 0) {
@@ -1456,7 +1484,7 @@ uip_process(u8_t flag)
       /* Reset length of outstanding data. */
       uip_connr->len = 0;
     }
       /* Reset length of outstanding data. */
       uip_connr->len = 0;
     }
-    
+
   }
 
   /* Do different things depending on in what state the connection is. */
   }
 
   /* Do different things depending on in what state the connection is. */
@@ -1544,7 +1572,7 @@ uip_process(u8_t flag)
     uip_conn->tcpstateflags = UIP_CLOSED;
     goto reset;
 #endif /* UIP_ACTIVE_OPEN */
     uip_conn->tcpstateflags = UIP_CLOSED;
     goto reset;
 #endif /* UIP_ACTIVE_OPEN */
-    
+
   case UIP_ESTABLISHED:
     /* In the ESTABLISHED state, we call upon the application to feed
     data into the uip_buf. If the UIP_ACKDATA flag is set, the
   case UIP_ESTABLISHED:
     /* In the ESTABLISHED state, we call upon the application to feed
     data into the uip_buf. If the UIP_ACKDATA flag is set, the
@@ -1616,7 +1644,7 @@ uip_process(u8_t flag)
        the initial MSS so that the application will send an entire MSS
        of data. This data will not be acknowledged by the receiver,
        and the application will retransmit it. This is called the
        the initial MSS so that the application will send an entire MSS
        of data. This data will not be acknowledged by the receiver,
        and the application will retransmit it. This is called the
-       "persistent timer" and uses the retransmission mechanim.
+       "persistent timer" and uses the retransmission mechanism.
     */
     tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
     if(tmp16 > uip_connr->initialmss ||
     */
     tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
     if(tmp16 > uip_connr->initialmss ||
@@ -1646,7 +1674,7 @@ uip_process(u8_t flag)
       UIP_APPCALL();
 
     appsend:
       UIP_APPCALL();
 
     appsend:
-      
+
       if(uip_flags & UIP_ABORT) {
        uip_slen = 0;
        uip_connr->tcpstateflags = UIP_CLOSED;
       if(uip_flags & UIP_ABORT) {
        uip_slen = 0;
        uip_connr->tcpstateflags = UIP_CLOSED;
@@ -1698,7 +1726,7 @@ uip_process(u8_t flag)
       uip_connr->nrtx = 0;
     apprexmit:
       uip_appdata = uip_sappdata;
       uip_connr->nrtx = 0;
     apprexmit:
       uip_appdata = uip_sappdata;
-      
+
       /* If the application has data to be sent, or if the incoming
          packet had new data in it, we must send out a packet. */
       if(uip_slen > 0 && uip_connr->len > 0) {
       /* If the application has data to be sent, or if the incoming
          packet had new data in it, we must send out a packet. */
       if(uip_slen > 0 && uip_connr->len > 0) {
@@ -1727,7 +1755,7 @@ uip_process(u8_t flag)
       UIP_APPCALL();
     }
     break;
       UIP_APPCALL();
     }
     break;
-    
+
   case UIP_FIN_WAIT_1:
     /* The application has closed the connection, but the remote host
        hasn't closed its end yet. Thus we do nothing but wait for a
   case UIP_FIN_WAIT_1:
     /* The application has closed the connection, but the remote host
        hasn't closed its end yet. Thus we do nothing but wait for a
@@ -1756,7 +1784,7 @@ uip_process(u8_t flag)
       goto tcp_send_ack;
     }
     goto drop;
       goto tcp_send_ack;
     }
     goto drop;
-      
+
   case UIP_FIN_WAIT_2:
     if(uip_len > 0) {
       uip_add_rcv_nxt(uip_len);
   case UIP_FIN_WAIT_2:
     if(uip_len > 0) {
       uip_add_rcv_nxt(uip_len);
@@ -1776,7 +1804,7 @@ uip_process(u8_t flag)
 
   case UIP_TIME_WAIT:
     goto tcp_send_ack;
 
   case UIP_TIME_WAIT:
     goto tcp_send_ack;
-    
+
   case UIP_CLOSING:
     if(uip_flags & UIP_ACKDATA) {
       uip_connr->tcpstateflags = UIP_TIME_WAIT;
   case UIP_CLOSING:
     if(uip_flags & UIP_ACKDATA) {
       uip_connr->tcpstateflags = UIP_TIME_WAIT;
@@ -1784,38 +1812,40 @@ uip_process(u8_t flag)
     }
   }
   goto drop;
     }
   }
   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;
 
   /* 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_nodata:
   uip_len = UIP_IPTCPH_LEN;
+
  tcp_send_noopts:
   BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
  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. */
   /* 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];
   BUF->ackno[3] = uip_connr->rcv_nxt[3];
   BUF->ackno[0] = uip_connr->rcv_nxt[0];
   BUF->ackno[1] = uip_connr->rcv_nxt[1];
   BUF->ackno[2] = uip_connr->rcv_nxt[2];
   BUF->ackno[3] = uip_connr->rcv_nxt[3];
-  
+
   BUF->seqno[0] = uip_connr->snd_nxt[0];
   BUF->seqno[1] = uip_connr->snd_nxt[1];
   BUF->seqno[2] = uip_connr->snd_nxt[2];
   BUF->seqno[3] = uip_connr->snd_nxt[3];
 
   BUF->proto = UIP_PROTO_TCP;
   BUF->seqno[0] = uip_connr->snd_nxt[0];
   BUF->seqno[1] = uip_connr->snd_nxt[1];
   BUF->seqno[2] = uip_connr->snd_nxt[2];
   BUF->seqno[3] = uip_connr->snd_nxt[3];
 
   BUF->proto = UIP_PROTO_TCP;
-  
+
   BUF->srcport  = uip_connr->lport;
   BUF->destport = uip_connr->rport;
 
   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
 
   if(uip_connr->tcpstateflags & UIP_STOPPED) {
     /* If the connection has issued uip_stop(), we advertise a zero
@@ -1839,13 +1869,12 @@ uip_process(u8_t flag)
 #endif /* UIP_CONF_IPV6 */
 
   BUF->urgp[0] = BUF->urgp[1] = 0;
 #endif /* UIP_CONF_IPV6 */
 
   BUF->urgp[0] = BUF->urgp[1] = 0;
-  
+
   /* Calculate TCP checksum. */
   BUF->tcpchksum = 0;
   BUF->tcpchksum = ~(uip_tcpchksum());
   /* Calculate TCP checksum. */
   BUF->tcpchksum = 0;
   BUF->tcpchksum = ~(uip_tcpchksum());
-  
- ip_send_nolen:
 
 
+ ip_send_nolen:
 #if UIP_CONF_IPV6
   BUF->vtc = 0x60;
   BUF->tcflow = 0x00;
 #if UIP_CONF_IPV6
   BUF->vtc = 0x60;
   BUF->tcflow = 0x00;
@@ -1862,16 +1891,18 @@ uip_process(u8_t flag)
   BUF->ipchksum = ~(uip_ipchksum());
   DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
 #endif /* UIP_CONF_IPV6 */
   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);
   UIP_STAT(++uip_stat.tcp.sent);
+#if UIP_CONF_IPV6
  send:
  send:
+#endif /* UIP_CONF_IPV6 */
   DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
               (BUF->len[0] << 8) | BUF->len[1]);
   DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
               (BUF->len[0] << 8) | BUF->len[1]);
-  
+
   UIP_STAT(++uip_stat.ip.sent);
   /* Return and let the caller do the actual transmission. */
   uip_flags = 0;
   return;
   UIP_STAT(++uip_stat.ip.sent);
   /* Return and let the caller do the actual transmission. */
   uip_flags = 0;
   return;
+
  drop:
   uip_len = 0;
   uip_flags = 0;
  drop:
   uip_len = 0;
   uip_flags = 0;
@@ -1883,15 +1914,28 @@ htons(u16_t val)
 {
   return HTONS(val);
 }
 {
   return HTONS(val);
 }
+
+u32_t
+htonl(u32_t val)
+{
+  return HTONL(val);
+}
 /*---------------------------------------------------------------------------*/
 void
 uip_send(const void *data, int len)
 {
 /*---------------------------------------------------------------------------*/
 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);
     }
   }
 }
     if(data != uip_sappdata) {
       memcpy(uip_sappdata, (data), uip_slen);
     }
   }
 }
+/*---------------------------------------------------------------------------*/
 /** @} */
 /** @} */
+#endif /* UIP_CONF_IPV6 */
+