--- /dev/null
+--- a/common/cmd_net.c
++++ b/common/cmd_net.c
+@@ -43,6 +43,18 @@ U_BOOT_CMD(
+ "[loadAddress] [[hostIPaddr:]bootfilename]"
+ );
+
++#if defined(CONFIG_CMD_HTTPD)
++int do_httpd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ return NetLoopHttpd();
++}
++
++U_BOOT_CMD(
++ httpd, 1, 1, do_httpd,
++ "httpd\t- start webserver", ""
++);
++#endif
++
+ int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+ {
+ return netboot_common (TFTP, cmdtp, argc, argv);
+--- /dev/null
++++ b/include/httpd.h
+@@ -0,0 +1,17 @@
++#ifndef _UIP_HTTPD_H__
++#define _UIP_HTTPD_H__
++
++void HttpdStart (void);
++void HttpdHandler (void);
++
++/* board specific implementation */
++extern int do_http_upgrade(const unsigned char *data, const ulong size);
++
++#define HTTP_PROGRESS_START 0
++#define HTTP_PROGRESS_TIMEOUT 1
++#define HTTP_PROGRESS_UPLOAD_READY 2
++#define HTTP_PROGRESS_UGRADE_READY 3
++#define HTTP_PROGRESS_UGRADE_FAILED 4
++extern int do_http_progress(const int state);
++
++#endif
+--- a/include/net.h
++++ b/include/net.h
+@@ -383,7 +383,8 @@ extern int NetTimeOffset; /* offset ti
+
+ /* Initialize the network adapter */
+ extern int NetLoop(proto_t);
+-
++extern int NetLoopHttpd(void);
++extern void NetSendHttpd(void);
+ /* Shutdown adapters and cleanup */
+ extern void NetStop(void);
+
+--- a/net/Makefile
++++ b/net/Makefile
+@@ -26,6 +26,8 @@ include $(TOPDIR)/config.mk
+ # CFLAGS += -DDEBUG
+
+ LIB = $(obj)libnet.a
++UIPDIR = uip-0.9
++$(shell mkdir -p $(obj)$(UIPDIR))
+
+ COBJS-$(CONFIG_CMD_NET) += bootp.o
+ COBJS-$(CONFIG_CMD_DNS) += dns.o
+@@ -36,6 +40,8 @@ COBJS-$(CONFIG_CMD_NET) += rarp.o
+ COBJS-$(CONFIG_CMD_SNTP) += sntp.o
+ COBJS-$(CONFIG_CMD_NET) += tftp.o
+
++COBJS-$(CONFIG_CMD_HTTPD) += httpd.o $(UIPDIR)/fs.o $(UIPDIR)/httpd.o $(UIPDIR)/uip_arp.o $(UIPDIR)/uip_arch.o $(UIPDIR)/uip.o
++
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+ OBJS := $(addprefix $(obj),$(COBJS))
+--- /dev/null
++++ b/net/httpd.c
+@@ -0,0 +1,52 @@
++/*
++ * Copyright 1994, 1995, 2000 Neil Russell.
++ * (See License)
++ * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
++ */
++
++#include <common.h>
++#include <command.h>
++#include <net.h>
++#include "uip-0.9/uipopt.h"
++#include "uip-0.9/uip.h"
++#include "uip-0.9/uip_arp.h"
++
++
++#if defined(CONFIG_CMD_HTTPD)
++
++#define TIMEOUT 5
++
++static int arptimer = 0;
++
++void
++HttpdHandler (void)
++{
++ int i;
++ for(i = 0; i < UIP_CONNS; i++) {
++ uip_periodic(i);
++ if(uip_len > 0) {
++ uip_arp_out();
++ NetSendHttpd();
++ }
++ }
++ if(++arptimer == 20) {
++ uip_arp_timer();
++ arptimer = 0;
++ }
++}
++
++static void
++HttpdTimeout (void)
++{
++ puts ("T ");
++ NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
++}
++
++void
++HttpdStart (void)
++{
++ uip_init();
++ httpd_init();
++}
++
++#endif
+--- a/net/net.c
++++ b/net/net.c
+@@ -95,6 +95,19 @@
+ #if defined(CONFIG_CMD_DNS)
+ #include "dns.h"
+ #endif
++#if defined(CONFIG_CMD_HTTPD)
++#include "httpd.h"
++#include "uip-0.9/uipopt.h"
++#include "uip-0.9/uip.h"
++#include "uip-0.9/uip_arp.h"
++static int https_running = 0;
++int httpd_upload_complete = 0;
++unsigned char *httpd_upload_data = 0;
++extern int upload_running;
++void NetReceiveHttpd(volatile uchar * inpkt, int len);
++void NetSendHttpd(void);
++extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
++#endif
+
+ DECLARE_GLOBAL_DATA_PTR;
+
+@@ -1308,6 +1321,13 @@ NetReceive(volatile uchar * inpkt, int l
+
+ debug("packet received\n");
+
++#if defined(CONFIG_CMD_HTTPD)
++ if(https_running) {
++ NetReceiveHttpd(inpkt, len);
++ return;
++ }
++#endif
++
+ NetRxPacket = inpkt;
+ NetRxPacketLen = len;
+ et = (Ethernet_t *)inpkt;
+@@ -1922,3 +1942,162 @@ ushort getenv_VLAN(char *var)
+ {
+ return (string_to_VLAN(getenv(var)));
+ }
++
++#if defined(CONFIG_CMD_HTTPD)
++
++void
++NetSendHttpd(void)
++{
++ volatile uchar *tmpbuf = NetTxPacket;
++ int i;
++
++ for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
++ tmpbuf[i] = uip_buf[i];
++ }
++
++ for(; i < uip_len; i++) {
++ tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
++ }
++ eth_send(NetTxPacket, uip_len);
++}
++
++#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
++
++void
++NetReceiveHttpd(volatile uchar * inpkt, int len)
++{
++ memcpy(uip_buf, inpkt, len);
++ uip_len = len;
++ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
++ uip_arp_ipin();
++ uip_input();
++ if(uip_len > 0) {
++ uip_arp_out();
++ NetSendHttpd();
++ }
++ } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
++ uip_arp_arpin();
++ if(uip_len > 0) {
++ NetSendHttpd();
++ }
++ }
++}
++
++int
++NetLoopHttpd(void)
++{
++ unsigned long long tout = 0;
++ bd_t *bd = gd->bd;
++ unsigned short int ip[2];
++
++#ifdef CONFIG_NET_MULTI
++ NetRestarted = 0;
++ NetDevExists = 0;
++#endif
++
++ /* XXX problem with bss workaround */
++ NetArpWaitPacketMAC = NULL;
++ NetArpWaitTxPacket = NULL;
++ NetArpWaitPacketIP = 0;
++ NetArpWaitReplyIP = 0;
++ NetArpWaitTxPacket = NULL;
++ NetTxPacket = NULL;
++ NetTryCount = 1;
++
++ if (!NetTxPacket) {
++ int i;
++ /*
++ * Setup packet buffers, aligned correctly.
++ */
++ NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
++ NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
++ for (i = 0; i < PKTBUFSRX; i++) {
++ NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
++ }
++ }
++
++ if (!NetArpWaitTxPacket) {
++ NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
++ NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
++ NetArpWaitTxPacketSize = 0;
++ }
++
++restart:
++
++ eth_halt();
++#ifdef CONFIG_NET_MULTI
++ eth_set_current();
++#endif
++ if (eth_init(bd) < 0) {
++ eth_halt();
++ return(-1);
++ }
++
++#ifdef CONFIG_NET_MULTI
++ memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);
++#else
++ eth_getenv_enetaddr("ethaddr", NetOurEther);
++#endif
++
++ NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
++ NetOurGatewayIP = getenv_IPaddr ("gatewayip");
++ NetOurSubnetMask= getenv_IPaddr ("netmask");
++ NetOurVLAN = getenv_VLAN("vlan");
++ NetOurNativeVLAN = getenv_VLAN("nvlan");
++
++ printf("starting httpd server from server %ld.%ld.%ld.%ld\n",
++ (bd->bi_ip_addr & 0xff000000) >> 24,
++ (bd->bi_ip_addr & 0x00ff0000) >> 16,
++ (bd->bi_ip_addr & 0x0000ff00) >> 8,
++ (bd->bi_ip_addr & 0x000000ff));
++
++ HttpdStart();
++
++ ip[0] = ((bd->bi_ip_addr & 0xffff0000) >> 16);
++ ip[1] = (bd->bi_ip_addr & 0x0000ffff);
++ uip_sethostaddr(ip);
++
++ do_http_progress(HTTP_PROGRESS_START);
++
++ https_running = 1;
++ for (;;) {
++ unsigned long long t1;
++ WATCHDOG_RESET();
++ if(eth_rx() > 0) {
++ HttpdHandler();
++ } else {
++ t1 = get_ticks();
++ if(t1 - tout > 1000) {
++ do_http_progress(HTTP_PROGRESS_TIMEOUT);
++ tout = t1;
++ }
++ }
++ if(!httpd_upload_complete)
++ continue;
++ printf("Bytes transferred = %ld (%lx hex)\n",
++ NetBootFileXferSize,
++ NetBootFileXferSize);
++ eth_halt();
++ do_http_progress(HTTP_PROGRESS_UPLOAD_READY);
++ if(do_http_upgrade(&httpd_upload_data[0], NetBootFileXferSize) == 0) {
++ do_http_progress(HTTP_PROGRESS_UGRADE_READY);
++ udelay(1000 * 10);
++ do_reset (0,0,0,0);
++ return 0;
++ }
++ break;
++ }
++ https_running = 0;
++ NetBootFileXferSize = 0;
++ httpd_upload_complete = 0;
++ upload_running = 0;
++// free(httpd_upload_data);
++
++ do_http_progress(HTTP_PROGRESS_UGRADE_FAILED);
++
++ goto restart;
++
++ return -1;
++}
++
++#endif
+--- /dev/null
++++ b/net/uip-0.9/Makefile
+@@ -0,0 +1,54 @@
++# Copyright (c) 2001, Adam Dunkels.
++# All rights reserved.
++#
++# Redistribution and use in source and binary forms, with or without
++# modification, are permitted provided that the following conditions
++# are met:
++# 1. Redistributions of source code must retain the above copyright
++# notice, this list of conditions and the following disclaimer.
++# 2. Redistributions in binary form must reproduce the above copyright
++# notice, this list of conditions and the following disclaimer in the
++# documentation and/or other materials provided with the distribution.
++# 3. All advertising materials mentioning features or use of this software
++# must display the following acknowledgement:
++# This product includes software developed by Adam Dunkels.
++# 4. The name of the author may not be used to endorse or promote
++# products derived from this software without specific prior
++# written permission.
++#
++# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++#
++# This file is part of the uIP TCP/IP stack.
++#
++# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $
++#
++
++CC=gcc
++CFLAGS=-Wall -fpack-struct -DDUMP=0
++
++all: uip
++
++uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o
++ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
++
++%.o: %.c
++ $(CC) $(CFLAGS) -c $^ -o $@
++
++clean:
++ rm -f *.o *~ *core uip
++
++
++
++
++
++
+--- /dev/null
++++ b/net/uip-0.9/fs.c
+@@ -0,0 +1,154 @@
++/**
++ * \addtogroup httpd
++ * @{
++ */
++
++/**
++ * \file
++ * HTTP server read-only file system code.
++ * \author Adam Dunkels <adam@dunkels.com>
++ *
++ * A simple read-only filesystem.
++ */
++
++/*
++ * Copyright (c) 2001, Swedish Institute of Computer Science.
++ * 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.
++ *
++ * 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 lwIP TCP/IP stack.
++ *
++ * Author: Adam Dunkels <adam@sics.se>
++ *
++ * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $
++ */
++
++#include "uip.h"
++#include "httpd.h"
++#include "fs.h"
++#include "fsdata.h"
++
++#include "fsdata.c"
++
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++static u16_t count[FS_NUMFILES];
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++
++/*-----------------------------------------------------------------------------------*/
++static u8_t
++fs_strcmp(const char *str1, const char *str2)
++{
++ u8_t i;
++ i = 0;
++ loop:
++
++ if(str2[i] == 0 ||
++ str1[i] == '\r' ||
++ str1[i] == '\n') {
++ return 0;
++ }
++
++ if(str1[i] != str2[i]) {
++ return 1;
++ }
++
++
++ ++i;
++ goto loop;
++}
++/*-----------------------------------------------------------------------------------*/
++int
++fs_open(const char *name, struct fs_file *file)
++{
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++ u16_t i = 0;
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++ struct fsdata_file_noconst *f;
++
++ for(f = (struct fsdata_file_noconst *)FS_ROOT;
++ f != NULL;
++ f = (struct fsdata_file_noconst *)f->next) {
++
++ if(fs_strcmp(name, f->name) == 0) {
++ file->data = f->data;
++ file->len = f->len;
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++ ++count[i];
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++ return 1;
++ }
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++ ++i;
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++
++ }
++ return 0;
++}
++/*-----------------------------------------------------------------------------------*/
++void
++fs_init(void)
++{
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++ u16_t i;
++ for(i = 0; i < FS_NUMFILES; i++) {
++ count[i] = 0;
++ }
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++}
++/*-----------------------------------------------------------------------------------*/
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++u16_t fs_count
++(char *name)
++{
++ struct fsdata_file_noconst *f;
++ u16_t i;
++
++ i = 0;
++ for(f = (struct fsdata_file_noconst *)FS_ROOT;
++ f != NULL;
++ f = (struct fsdata_file_noconst *)f->next) {
++
++ if(fs_strcmp(name, f->name) == 0) {
++ return count[i];
++ }
++ ++i;
++ }
++ return 0;
++}
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++/*-----------------------------------------------------------------------------------*/
+--- /dev/null
++++ b/net/uip-0.9/fs.h
+@@ -0,0 +1,80 @@
++/**
++ * \addtogroup httpd
++ * @{
++ */
++
++/**
++ * \file
++ * HTTP server read-only file system header file.
++ * \author Adam Dunkels <adam@dunkels.com>
++ */
++
++/*
++ * Copyright (c) 2001, Swedish Institute of Computer Science.
++ * 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.
++ *
++ * 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 lwIP TCP/IP stack.
++ *
++ * Author: Adam Dunkels <adam@sics.se>
++ *
++ * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $
++ */
++#ifndef __FS_H__
++#define __FS_H__
++
++#include "uip.h"
++
++/**
++ * An open file in the read-only file system.
++ */
++struct fs_file {
++ char *data; /**< The actual file data. */
++ int len; /**< The length of the file data. */
++};
++
++/**
++ * Open a file in the read-only file system.
++ *
++ * \param name The name of the file.
++ *
++ * \param file The file pointer, which must be allocated by caller and
++ * will be filled in by the function.
++ */
++int fs_open(const char *name, struct fs_file *file);
++
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++u16_t fs_count(char *name);
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++
++/**
++ * Initialize the read-only file system.
++ */
++void fs_init(void);
++
++#endif /* __FS_H__ */
+--- /dev/null
++++ b/net/uip-0.9/fsdata.c
+@@ -0,0 +1,199 @@
++static const char data_flashing_html[] = {
++ /* /flashing.html */
++ 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
++ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
++ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
++ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
++ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
++ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
++ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
++ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
++ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
++ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
++ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
++ 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
++ 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
++ 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
++ 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
++ 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
++ 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
++ 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
++ 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
++ 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
++ 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
++ 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
++ 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
++ 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
++ 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
++ 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
++
++static const char data_fail_html[] = {
++ /* /fail.html */
++ 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
++ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
++ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
++ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
++ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
++ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
++ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
++ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
++ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
++ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
++ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
++ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
++ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
++ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
++ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
++ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
++ 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
++ 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
++ 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
++ 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
++ 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
++ 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
++ 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
++ 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
++ 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
++ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
++ 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
++ 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
++ 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
++ 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
++ 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
++ 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
++ 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
++ 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
++ 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
++ 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
++ 0x3e, 0xa, };
++
++static const char data_404_html[] = {
++ /* /404.html */
++ 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
++ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
++ 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
++ 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
++ 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
++ 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
++ 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
++ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
++ 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
++ 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
++ 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
++ 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
++ 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
++ 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
++ 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
++ 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
++ 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
++ 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
++ 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
++ 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
++ 0x6c, 0x3e, };
++
++static const char data_index_html[] = {
++ /* /index.html */
++ 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
++ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
++ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
++ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
++ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
++ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
++ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
++ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
++ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
++ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
++ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
++ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
++ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
++ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
++ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
++ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
++ 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
++ 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
++ 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
++ 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
++ 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
++ 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
++ 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
++ 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
++ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
++ 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
++ 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
++ 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
++ 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
++ 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
++ 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
++ 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
++ 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
++ 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
++ 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
++ 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
++ 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
++ 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
++ 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
++ 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
++ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
++ 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
++ 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
++
++static const char data_flash_html[] = {
++ /* /flash.html */
++ 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
++ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
++ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
++ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
++ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
++ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
++ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
++ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
++ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
++ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
++ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
++ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
++ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
++ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
++ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
++ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
++ 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
++ 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
++ 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
++ 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
++ 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
++ 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
++ 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
++ 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
++ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
++ 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
++ 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
++ 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
++ 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
++ 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
++ 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
++ 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
++ 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
++ 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
++ 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
++ 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
++ 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
++ 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
++ 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
++ 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
++ 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
++ 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
++ 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
++ 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
++
++const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
++
++const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
++
++const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
++
++const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
++
++const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
++
++#define FS_ROOT file_flash_html
++
++#define FS_NUMFILES 5
+\ No newline at end of file
+--- /dev/null
++++ b/net/uip-0.9/fsdata.h
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (c) 2001, Swedish Institute of Computer Science.
++ * 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.
++ *
++ * 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 lwIP TCP/IP stack.
++ *
++ * Author: Adam Dunkels <adam@sics.se>
++ *
++ * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $
++ */
++#ifndef __FSDATA_H__
++#define __FSDATA_H__
++
++#include "uipopt.h"
++
++struct fsdata_file {
++ const struct fsdata_file *next;
++ const char *name;
++ const char *data;
++ const int len;
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++ u16_t count;
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++};
++
++struct fsdata_file_noconst {
++ struct fsdata_file *next;
++ char *name;
++ char *data;
++ int len;
++#ifdef FS_STATISTICS
++#if FS_STATISTICS == 1
++ u16_t count;
++#endif /* FS_STATISTICS */
++#endif /* FS_STATISTICS */
++};
++
++#endif /* __FSDATA_H__ */
+--- /dev/null
++++ b/net/uip-0.9/httpd.c
+@@ -0,0 +1,278 @@
++#include "uip.h"
++#include "httpd.h"
++#include "fs.h"
++#include "fsdata.h"
++#include <asm/addrspace.h>
++
++#define HTTP_NONE 0
++#define HTTP_FILE 1
++#define HTTP_FIRMWARE 2
++
++#define PRINT(x) printf("%s", x)
++#define PRINTLN(x) printf("%s\n", x)
++
++extern unsigned long do_http_tmp_address(void);
++
++struct httpd_state *hs;
++
++extern const struct fsdata_file file_index_html;
++extern const struct fsdata_file file_404_html;
++extern const struct fsdata_file file_flash_html;
++extern int httpd_upload_complete;
++extern unsigned char *httpd_upload_data;
++unsigned char *upload_data;
++extern ulong NetBootFileXferSize;
++int upload_running = 0;
++
++#define ISO_G 0x47
++#define ISO_E 0x45
++#define ISO_T 0x54
++#define ISO_P 0x50
++#define ISO_O 0x4f
++#define ISO_S 0x53
++#define ISO_T 0x54
++#define ISO_slash 0x2f
++#define ISO_c 0x63
++#define ISO_g 0x67
++#define ISO_i 0x69
++#define ISO_space 0x20
++#define ISO_nl 0x0a
++#define ISO_cr 0x0d
++#define ISO_a 0x61
++#define ISO_t 0x74
++#define ISO_hash 0x23
++#define ISO_period 0x2e
++
++static char eol[3] = { 0x0d, 0x0a, 0x00 };
++static char eol2[5] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00 };
++static char boundary[128];
++static int boundary_len = 0;
++
++/* we use this so that we can do without the ctype library */
++#define is_digit(c) ((c) >= '0' && (c) <= '9')
++static int atoi(const char *s)
++{
++ int i=0;
++
++ while (is_digit(*s))
++ i = i*10 + *(s++) - '0';
++ return i;
++}
++
++void
++httpd_init(void)
++{
++ fs_init();
++ uip_listen(HTONS(80));
++}
++
++void
++httpd_appcall(void)
++{
++ struct fs_file fsfile;
++ u8_t i;
++ switch(uip_conn->lport) {
++ case HTONS(80):
++ hs = (struct httpd_state *)(uip_conn->appstate);
++ if(uip_connected())
++ {
++ hs->state = HTTP_NONE;
++ hs->count = 0;
++ return;
++ } else if(uip_poll())
++ {
++ if(hs->count++ >= 1000) {
++ uip_abort();
++ }
++ return;
++ } else if(uip_newdata() && hs->state == HTTP_NONE)
++ {
++ if(uip_appdata[0] == ISO_G &&
++ uip_appdata[1] == ISO_E &&
++ uip_appdata[2] == ISO_T &&
++ uip_appdata[3] == ISO_space)
++ {
++ hs->state = HTTP_FILE;
++ }
++ if(uip_appdata[0] == ISO_P &&
++ uip_appdata[1] == ISO_O &&
++ uip_appdata[2] == ISO_S &&
++ uip_appdata[3] == ISO_T &&
++ uip_appdata[4] == ISO_space)
++ {
++ hs->state = HTTP_FIRMWARE;
++ }
++ if(hs->state == HTTP_NONE)
++ {
++ uip_abort();
++ return;
++ }
++ if(hs->state == HTTP_FILE)
++ {
++ for(i = 4; i < 40; ++i)
++ {
++ if(uip_appdata[i] == ISO_space ||
++ uip_appdata[i] == ISO_cr ||
++ uip_appdata[i] == ISO_nl)
++ {
++ uip_appdata[i] = 0;
++ break;
++ }
++ }
++
++ PRINT("request for file ");
++ PRINTLN(&uip_appdata[4]);
++ if(uip_appdata[4] == ISO_slash &&
++ uip_appdata[5] == 0)
++ {
++ fs_open(file_index_html.name, &fsfile);
++ } else {
++ if(!fs_open((const char *)&uip_appdata[4], &fsfile))
++ {
++ PRINTLN("couldn't open file");
++ fs_open(file_index_html.name, &fsfile);
++ }
++ }
++ hs->script = 0;
++ hs->state = HTTP_FILE;
++ hs->dataptr = fsfile.data;
++ hs->count = fsfile.len;
++ }
++ if(hs->state == HTTP_FIRMWARE)
++ {
++ unsigned char *start = (unsigned char*)uip_appdata;
++ char *clen = strstr(start, "Content-Length:");
++ int len = 0;
++ unsigned char *next, *end;
++ unsigned char *boundary_start;
++ int i;
++ uip_appdata[uip_len] = '\0';
++ if(clen)
++ {
++ clen += sizeof("Content-Length:");
++ next = strstr(clen, eol);
++ if(next)
++ {
++ len = atoi(clen);
++ next++;
++ printf("expecting %d bytes\n", len);
++ upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
++ printf("received data will be stored at 0x%08X\n", upload_data);
++ if(!upload_data)
++ {
++ printf("failed to allocate memory\n");
++ uip_close();
++ return;
++ }
++ } else {
++ uip_close();
++ return;
++ }
++ }
++ if(len < 4 * 1024)
++ {
++ uip_close();
++ return;
++ }
++ boundary_start = strstr(next, "---");
++ if(!boundary_start)
++ {
++ uip_close();
++ return;
++ }
++ end = strstr(boundary_start, eol);
++ if(!eol)
++ {
++ uip_close();
++ return;
++ }
++ boundary_len = end - boundary_start;
++ memcpy(boundary, boundary_start, boundary_len);
++ boundary[boundary_len] = 0;
++ next = strstr(boundary_start, "name=\"firmware\";");
++ if(!next)
++ {
++ uip_close();
++ return;
++ }
++ next = strstr(next, eol2);
++ if(!next)
++ {
++ printf("could not find start of data\n");
++ uip_close();
++ return;
++ }
++ next += 4;
++ hs->script = 0;
++ hs->state = HTTP_FIRMWARE;
++ hs->upload = uip_len - (next - start);
++ hs->upload_total = len - (int)(next - boundary_start);
++ hs->upload_total -= (strlen(boundary) + 6);
++ //printf("storing %d bytes at %p\n", (int)hs->upload, upload_data);
++ for(i = 0; i < hs->upload; i++)
++ upload_data[i] = next[i];
++ upload_data += (int)hs->upload;
++ printf("%d / %d\n", (int)hs->upload, hs->upload_total);
++ uip_slen = 0;
++ return;
++ }
++ }
++
++ if(hs->state == HTTP_FIRMWARE)
++ {
++ if(uip_newdata())
++ {
++ int i;
++ hs->count = 0;
++ uip_appdata[uip_len] = '\0';
++ hs->upload += uip_len;
++ //printf("storing %d bytes at %p\n", uip_len, upload_data);
++ printf("%d / %d\n", (int)hs->upload, hs->upload_total);
++ for(i = 0; i < uip_len; i++)
++ upload_data[i] = uip_appdata[i];
++ upload_data += uip_len;
++ uip_slen = 0;
++ if(hs->upload >= hs->upload_total)
++ {
++ upload_running = 1;
++ NetBootFileXferSize = hs->upload_total;
++ fs_open(file_flash_html.name, &fsfile);
++ hs->script = 0;
++ hs->state = HTTP_FILE;
++ hs->dataptr = fsfile.data;
++ hs->count = fsfile.len;
++ }
++ }
++ }
++ if(hs->state == HTTP_FILE)
++ {
++ if(uip_acked())
++ {
++ if(hs->count >= uip_conn->len)
++ {
++ hs->count -= uip_conn->len;
++ hs->dataptr += uip_conn->len;
++ } else {
++ hs->count = 0;
++ }
++ if(hs->count == 0)
++ {
++ if(upload_running)
++ {
++ int i;
++ httpd_upload_complete = 1;
++ // for(i = 0; i < hs->upload_total; i++)
++ // printf("%c", httpd_upload_data[i]);
++ }
++ uip_close();
++ }
++ }
++ uip_send(hs->dataptr, hs->count);
++ }
++ break;
++
++ default:
++ uip_abort();
++ break;
++ }
++}
+--- /dev/null
++++ b/net/uip-0.9/httpd.h
+@@ -0,0 +1,83 @@
++/**
++ * \addtogroup httpd
++ * @{
++ */
++
++/**
++ * \file
++ * HTTP server header file.
++ * \author Adam Dunkels <adam@dunkels.com>
++ */
++
++/*
++ * Copyright (c) 2001, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $
++ *
++ */
++
++#ifndef __HTTPD_H__
++#define __HTTPD_H__
++
++void httpd_init(void);
++void httpd_appcall(void);
++
++/* UIP_APPCALL: the name of the application function. This function
++ must return void and take no arguments (i.e., C type "void
++ appfunc(void)"). */
++#ifndef UIP_APPCALL
++#define UIP_APPCALL httpd_appcall
++#endif
++
++struct httpd_state {
++ u8_t state;
++ u16_t count;
++ char *dataptr;
++ char *script;
++ unsigned int upload;
++ unsigned int upload_total;
++};
++
++
++/* UIP_APPSTATE_SIZE: The size of the application-specific state
++ stored in the uip_conn structure. */
++#ifndef UIP_APPSTATE_SIZE
++#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
++#endif
++
++#define FS_STATISTICS 1
++
++extern struct httpd_state *hs;
++
++
++/* we copy the data to RAM+10MB */
++#define TMP_DATA 0x8A100000
++
++#endif /* __HTTPD_H__ */
+--- /dev/null
++++ b/net/uip-0.9/main.c
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (c) 2001-2003, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $
++ *
++ */
++
++
++#include "uip.h"
++#include "uip_arp.h"
++#include "tapdev.h"
++#include "httpd.h"
++
++#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
++
++#ifndef NULL
++#define NULL (void *)0
++#endif /* NULL */
++
++/*-----------------------------------------------------------------------------------*/
++int
++main(void)
++{
++ u8_t i, arptimer;
++ tapdev_init();
++ uip_init();
++ httpd_init();
++ arptimer = 0;
++ while(1) {
++ uip_len = tapdev_read();
++ if(uip_len == 0) {
++ for(i = 0; i < UIP_CONNS; i++) {
++ uip_periodic(i);
++ if(uip_len > 0) {
++ uip_arp_out();
++ tapdev_send();
++ }
++ }
++
++ if(++arptimer == 20) {
++ uip_arp_timer();
++ arptimer = 0;
++ }
++ } else {
++ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
++ uip_arp_ipin();
++ uip_input();
++ if(uip_len > 0) {
++ uip_arp_out();
++ tapdev_send();
++ }
++ } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
++ uip_arp_arpin();
++ if(uip_len > 0) {
++ tapdev_send();
++ }
++ }
++ }
++ }
++ return 0;
++}
+--- /dev/null
++++ b/net/uip-0.9/tapdev.c
+@@ -0,0 +1,192 @@
++/*
++ * Copyright (c) 2001, Swedish Institute of Computer Science.
++ * 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.
++ *
++ * 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.
++ *
++ * Author: Adam Dunkels <adam@sics.se>
++ *
++ * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $
++ */
++
++
++#include <fcntl.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <unistd.h>
++#include <string.h>
++#include <sys/ioctl.h>
++#include <sys/socket.h>
++#include <sys/types.h>
++#include <sys/time.h>
++#include <sys/uio.h>
++#include <sys/socket.h>
++
++#ifdef linux
++#include <sys/ioctl.h>
++#include <linux/if.h>
++#include <linux/if_tun.h>
++#define DEVTAP "/dev/net/tun"
++#else /* linux */
++#define DEVTAP "/dev/tap0"
++#endif /* linux */
++
++#include "uip.h"
++
++static int fd;
++
++static unsigned long lasttime;
++static struct timezone tz;
++
++/*-----------------------------------------------------------------------------------*/
++void
++tapdev_init(void)
++{
++ char buf[1024];
++
++ fd = open(DEVTAP, O_RDWR);
++ if(fd == -1) {
++ perror("tapdev: tapdev_init: open");
++ exit(1);
++ }
++
++#ifdef linux
++ {
++ struct ifreq ifr;
++ memset(&ifr, 0, sizeof(ifr));
++ ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
++ if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
++ perror(buf);
++ exit(1);
++ }
++ }
++#endif /* Linux */
++
++ snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
++ UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);
++ system(buf);
++
++ lasttime = 0;
++}
++
++void dump_mem(int type, int len)
++{
++#if DUMP == 1
++ int i;
++ for(i = 0; i < len; i++)
++ printf("%c", uip_buf[i]);
++ if(type)
++ {
++ printf("\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01");
++ printf("\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01");
++ } else {
++ printf("\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02");
++ printf("\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02");
++ }
++ fflush(stdout);
++#endif
++}
++
++/*-----------------------------------------------------------------------------------*/
++unsigned int
++tapdev_read(void)
++{
++ fd_set fdset;
++ struct timeval tv, now;
++ int ret;
++
++ if(lasttime >= 500000) {
++ lasttime = 0;
++ return 0;
++ }
++
++ tv.tv_sec = 0;
++ tv.tv_usec = 500000 - lasttime;
++
++
++ FD_ZERO(&fdset);
++ FD_SET(fd, &fdset);
++
++ gettimeofday(&now, &tz);
++ ret = select(fd + 1, &fdset, NULL, NULL, &tv);
++ if(ret == 0) {
++ lasttime = 0;
++ return 0;
++ }
++ ret = read(fd, uip_buf, UIP_BUFSIZE);
++ if(ret == -1) {
++ perror("tap_dev: tapdev_read: read");
++ }
++ gettimeofday(&tv, &tz);
++ lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
++ dump_mem(0, ret);
++ return ret;
++}
++/*-----------------------------------------------------------------------------------*/
++void
++tapdev_send(void)
++{
++ int ret;
++ struct iovec iov[2];
++
++#ifdef linux
++ {
++ char tmpbuf[UIP_BUFSIZE];
++ int i;
++
++ for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
++ tmpbuf[i] = uip_buf[i];
++ }
++
++ for(; i < uip_len; i++) {
++ tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
++ }
++
++ ret = write(fd, tmpbuf, uip_len);
++ }
++#else
++
++ if(uip_len < 40 + UIP_LLH_LEN) {
++ ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN);
++ } else {
++ iov[0].iov_base = uip_buf;
++ iov[0].iov_len = 40 + UIP_LLH_LEN;
++ iov[1].iov_base = (char *)uip_appdata;
++ iov[1].iov_len = uip_len - (40 + UIP_LLH_LEN);
++
++ ret = writev(fd, iov, 2);
++ }
++#endif
++ dump_mem(1, ret);
++
++ if(ret == -1) {
++ perror("tap_dev: tapdev_send: writev");
++ exit(1);
++ }
++}
++/*-----------------------------------------------------------------------------------*/
+--- /dev/null
++++ b/net/uip-0.9/tapdev.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2001, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: tapdev.h,v 1.1.2.1 2003/10/04 22:54:17 adam Exp $
++ *
++ */
++
++#ifndef __TAPDEV_H__
++#define __TAPDEV_H__
++
++void tapdev_init(void);
++unsigned int tapdev_read(void);
++void tapdev_send(void);
++
++#endif /* __TAPDEV_H__ */
+--- /dev/null
++++ b/net/uip-0.9/uip.c
+@@ -0,0 +1,1503 @@
++/**
++ * \addtogroup uip
++ * @{
++ */
++
++/**
++ * \file
++ * The uIP TCP/IP stack code.
++ * \author Adam Dunkels <adam@dunkels.com>
++ */
++
++/*
++ * Copyright (c) 2001-2003, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
++ *
++ */
++
++/*
++This is a small implementation of the IP and TCP protocols (as well as
++some basic ICMP stuff). The implementation couples the IP, TCP and the
++application layers very tightly. To keep the size of the compiled code
++down, this code also features heavy usage of the goto statement.
++
++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 stack
++parses the headers in the packet, and calls upon the application. If
++the remote host has sent data to the application, this data is present
++in the uip_buf and the application read the data from there. It is up
++to the application to put this data into a byte stream if needed. The
++application will not be fed with data that is out of sequence.
++
++If the application whishes to send data to the peer, it should put its
++data into the uip_buf, 40 bytes from the start of the buffer. The
++TCP/IP stack will calculate the checksums, and fill in the necessary
++header fields and finally send the packet back to the peer.
++*/
++
++#include "uip.h"
++#include "uipopt.h"
++#include "uip_arch.h"
++
++/*-----------------------------------------------------------------------------------*/
++/* Variable definitions. */
++
++
++/* The IP address of this host. If it is defined to be fixed (by setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set here. Otherwise, the address */
++#if UIP_FIXEDADDR > 0
++const unsigned short int uip_hostaddr[2] =
++ {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
++ HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
++const unsigned short int uip_arp_draddr[2] =
++ {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
++ HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
++const unsigned short int uip_arp_netmask[2] =
++ {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
++ HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
++#else
++unsigned short int uip_hostaddr[2];
++unsigned short int uip_arp_draddr[2], uip_arp_netmask[2];
++#endif /* UIP_FIXEDADDR */
++
++u8_t uip_buf[UIP_BUFSIZE+2]; /* The packet buffer that contains
++ incoming packets. */
++volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
++ application data. */
++volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to the
++ application data which is to be sent. */
++#if UIP_URGDATA > 0
++volatile u8_t *uip_urgdata; /* The uip_urgdata pointer points to
++ urgent data (out-of-band data), if
++ present. */
++volatile u8_t uip_urglen, uip_surglen;
++#endif /* UIP_URGDATA > 0 */
++
++volatile unsigned short int uip_len, uip_slen;
++ /* The uip_len is either 8 or 16 bits,
++ depending on the maximum packet
++ size. */
++
++volatile u8_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
++ connection. */
++
++struct uip_conn uip_conns[UIP_CONNS];
++ /* The uip_conns array holds all TCP
++ connections. */
++unsigned short int uip_listenports[UIP_LISTENPORTS];
++ /* The uip_listenports list all currently
++ listning ports. */
++#if UIP_UDP
++struct uip_udp_conn *uip_udp_conn;
++struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
++#endif /* UIP_UDP */
++
++
++static unsigned short int ipid; /* Ths ipid variable is an increasing
++ number that is used for the IP ID
++ field. */
++
++static u8_t iss[4]; /* The iss variable is used for the TCP
++ initial sequence number. */
++
++#if UIP_ACTIVE_OPEN
++static unsigned short int lastport; /* Keeps track of the last port used for
++ a new connection. */
++#endif /* UIP_ACTIVE_OPEN */
++
++/* Temporary variables. */
++volatile u8_t uip_acc32[4];
++static u8_t c, opt;
++static unsigned short int tmp16;
++
++/* Structures and definitions. */
++#define TCP_FIN 0x01
++#define TCP_SYN 0x02
++#define TCP_RST 0x04
++#define TCP_PSH 0x08
++#define TCP_ACK 0x10
++#define TCP_URG 0x20
++#define TCP_CTL 0x3f
++
++#define ICMP_ECHO_REPLY 0
++#define ICMP_ECHO 8
++
++/* Macros. */
++#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
++#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
++#define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
++#define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
++
++#if UIP_STATISTICS == 1
++struct uip_stats uip_stat;
++#define UIP_STAT(s) s
++#else
++#define UIP_STAT(s)
++#endif /* UIP_STATISTICS == 1 */
++
++#if UIP_LOGGING == 1
++extern void puts(const char *s);
++#define UIP_LOG(m) puts(m)
++#else
++#define UIP_LOG(m)
++#endif /* UIP_LOGGING == 1 */
++
++/*-----------------------------------------------------------------------------------*/
++void
++uip_init(void)
++{
++ for(c = 0; c < UIP_LISTENPORTS; ++c) {
++ uip_listenports[c] = 0;
++ }
++ for(c = 0; c < UIP_CONNS; ++c) {
++ uip_conns[c].tcpstateflags = CLOSED;
++ }
++#if UIP_ACTIVE_OPEN
++ lastport = 1024;
++#endif /* UIP_ACTIVE_OPEN */
++
++#if UIP_UDP
++ for(c = 0; c < UIP_UDP_CONNS; ++c) {
++ uip_udp_conns[c].lport = 0;
++ }
++#endif /* UIP_UDP */
++
++
++ /* IPv4 initialization. */
++#if UIP_FIXEDADDR == 0
++ uip_hostaddr[0] = uip_hostaddr[1] = 0;
++#endif /* UIP_FIXEDADDR */
++
++}
++/*-----------------------------------------------------------------------------------*/
++#if UIP_ACTIVE_OPEN
++struct uip_conn *
++uip_connect(unsigned short int *ripaddr, unsigned short int rport)
++{
++ register struct uip_conn *conn, *cconn;
++
++ /* Find an unused local port. */
++ again:
++ ++lastport;
++
++ if(lastport >= 32000) {
++ lastport = 4096;
++ }
++
++ /* Check if this port is already in use, and if so try to find
++ another one. */
++ for(c = 0; c < UIP_CONNS; ++c) {
++ conn = &uip_conns[c];
++ if(conn->tcpstateflags != CLOSED &&
++ conn->lport == htons(lastport)) {
++ goto again;
++ }
++ }
++
++
++ conn = 0;
++ for(c = 0; c < UIP_CONNS; ++c) {
++ cconn = &uip_conns[c];
++ if(cconn->tcpstateflags == CLOSED) {
++ conn = cconn;
++ break;
++ }
++ if(cconn->tcpstateflags == TIME_WAIT) {
++ if(conn == 0 ||
++ cconn->timer > uip_conn->timer) {
++ conn = cconn;
++ }
++ }
++ }
++
++ if(conn == 0) {
++ return 0;
++ }
++
++ conn->tcpstateflags = SYN_SENT;
++
++ conn->snd_nxt[0] = iss[0];
++ conn->snd_nxt[1] = iss[1];
++ conn->snd_nxt[2] = iss[2];
++ 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->rto = UIP_RTO;
++ conn->sa = 0;
++ conn->sv = 16;
++ conn->lport = htons(lastport);
++ conn->rport = rport;
++ conn->ripaddr[0] = ripaddr[0];
++ conn->ripaddr[1] = ripaddr[1];
++
++ return conn;
++}
++#endif /* UIP_ACTIVE_OPEN */
++/*-----------------------------------------------------------------------------------*/
++#if UIP_UDP
++struct uip_udp_conn *
++uip_udp_new(unsigned short int *ripaddr, unsigned short int rport)
++{
++ register struct uip_udp_conn *conn;
++
++ /* Find an unused local port. */
++ again:
++ ++lastport;
++
++ if(lastport >= 32000) {
++ lastport = 4096;
++ }
++
++ for(c = 0; c < UIP_UDP_CONNS; ++c) {
++ if(uip_udp_conns[c].lport == lastport) {
++ goto again;
++ }
++ }
++
++
++ conn = 0;
++ for(c = 0; c < UIP_UDP_CONNS; ++c) {
++ if(uip_udp_conns[c].lport == 0) {
++ conn = &uip_udp_conns[c];
++ break;
++ }
++ }
++
++ if(conn == 0) {
++ return 0;
++ }
++
++ conn->lport = HTONS(lastport);
++ conn->rport = HTONS(rport);
++ conn->ripaddr[0] = ripaddr[0];
++ conn->ripaddr[1] = ripaddr[1];
++
++ return conn;
++}
++#endif /* UIP_UDP */
++/*-----------------------------------------------------------------------------------*/
++void
++uip_unlisten(unsigned short int port)
++{
++ for(c = 0; c < UIP_LISTENPORTS; ++c) {
++ if(uip_listenports[c] == port) {
++ uip_listenports[c] = 0;
++ return;
++ }
++ }
++}
++/*-----------------------------------------------------------------------------------*/
++void
++uip_listen(unsigned short int port)
++{
++ for(c = 0; c < UIP_LISTENPORTS; ++c) {
++ if(uip_listenports[c] == 0) {
++ uip_listenports[c] = port;
++ return;
++ }
++ }
++}
++/*-----------------------------------------------------------------------------------*/
++/* XXX: IP fragment reassembly: not well-tested. */
++
++#if UIP_REASSEMBLY
++#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,
++ 0x0f, 0x07, 0x03, 0x01};
++static unsigned short int uip_reasslen;
++static u8_t uip_reassflags;
++#define UIP_REASS_FLAG_LASTFRAG 0x01
++static u8_t uip_reasstmr;
++
++#define IP_HLEN 20
++#define IP_MF 0x20
++
++static u8_t
++uip_reass(void)
++{
++ unsigned short int offset, len;
++ unsigned short int 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
++ buffer. The timer is updated with the maximum age. */
++ if(uip_reasstmr == 0) {
++ memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
++ uip_reasstmr = UIP_REASS_MAXAGE;
++ uip_reassflags = 0;
++ /* Clear the bitmap. */
++ memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
++ }
++
++ /* Check if the incoming fragment matches the one currently present
++ in the reasembly buffer. If so, we proceed with copying the
++ fragment into the buffer. */
++ if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
++ BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
++ BUF->destipaddr[0] == FBUF->destipaddr[0] &&
++ BUF->destipaddr[1] == FBUF->destipaddr[1] &&
++ BUF->ipid[0] == FBUF->ipid[0] &&
++ BUF->ipid[1] == FBUF->ipid[1]) {
++
++ len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
++ offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
++
++ /* If the offset or the offset + fragment length overflows the
++ reassembly buffer, we discard the entire packet. */
++ if(offset > UIP_REASS_BUFSIZE ||
++ offset + len > UIP_REASS_BUFSIZE) {
++ uip_reasstmr = 0;
++ goto nullreturn;
++ }
++
++ /* Copy the fragment into the reassembly buffer, at the right
++ offset. */
++ memcpy(&uip_reassbuf[IP_HLEN + 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. */
++
++ 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
++ 0xff. */
++ uip_reassbitmap[offset / (8 * 8)] |=
++ bitmap_bits[(offset / 8 ) & 7];
++ for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
++ uip_reassbitmap[i] = 0xff;
++ }
++ 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
++ IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
++ the final fragment. */
++
++ if((BUF->ipoffset[0] & IP_MF) == 0) {
++ 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. */
++ if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
++ /* Check all bytes up to and including all but the last byte in
++ the bitmap. */
++ for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
++ if(uip_reassbitmap[i] != 0xff) {
++ goto nullreturn;
++ }
++ }
++ /* 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]) {
++ goto nullreturn;
++ }
++
++ /* If we have come this far, we have a full packet in the
++ buffer, so we allocate a pbuf and copy the packet into it. We
++ also reset the timer. */
++ uip_reasstmr = 0;
++ memcpy(BUF, FBUF, uip_reasslen);
++
++ /* Pretend to be a "normal" (i.e., not fragmented) IP packet
++ from now on. */
++ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
++ BUF->len[0] = uip_reasslen >> 8;
++ BUF->len[1] = uip_reasslen & 0xff;
++ BUF->ipchksum = 0;
++ BUF->ipchksum = ~(uip_ipchksum());
++
++ return uip_reasslen;
++ }
++ }
++
++ nullreturn:
++ return 0;
++}
++#endif /* UIP_REASSEMBL */
++/*-----------------------------------------------------------------------------------*/
++static void
++uip_add_rcv_nxt(unsigned short int n)
++{
++ uip_add32(uip_conn->rcv_nxt, n);
++ uip_conn->rcv_nxt[0] = uip_acc32[0];
++ uip_conn->rcv_nxt[1] = uip_acc32[1];
++ uip_conn->rcv_nxt[2] = uip_acc32[2];
++ uip_conn->rcv_nxt[3] = uip_acc32[3];
++}
++/*-----------------------------------------------------------------------------------*/
++void
++uip_process(u8_t flag)
++{
++ register struct uip_conn *uip_connr = uip_conn;
++
++ uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
++
++
++ /* Check if we were invoked because of the perodic timer fireing. */
++ if(flag == UIP_TIMER) {
++#if UIP_REASSEMBLY
++ if(uip_reasstmr != 0) {
++ --uip_reasstmr;
++ }
++#endif /* UIP_REASSEMBLY */
++ /* Increase the initial sequence number. */
++ if(++iss[3] == 0) {
++ if(++iss[2] == 0) {
++ if(++iss[1] == 0) {
++ ++iss[0];
++ }
++ }
++ }
++ uip_len = 0;
++ if(uip_connr->tcpstateflags == TIME_WAIT ||
++ uip_connr->tcpstateflags == FIN_WAIT_2) {
++ ++(uip_connr->timer);
++ if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
++ uip_connr->tcpstateflags = CLOSED;
++ }
++ } else if(uip_connr->tcpstateflags != CLOSED) {
++ /* 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 ||
++ ((uip_connr->tcpstateflags == SYN_SENT ||
++ uip_connr->tcpstateflags == SYN_RCVD) &&
++ uip_connr->nrtx == UIP_MAXSYNRTX)) {
++ uip_connr->tcpstateflags = CLOSED;
++
++ /* We call UIP_APPCALL() with uip_flags set to
++ UIP_TIMEDOUT to inform the application that the
++ connection has timed out. */
++ uip_flags = UIP_TIMEDOUT;
++ UIP_APPCALL();
++
++ /* We also send a reset packet to the remote host. */
++ BUF->flags = TCP_RST | TCP_ACK;
++ goto tcp_send_nodata;
++ }
++
++ /* Exponential backoff. */
++ 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
++ data for the retransmit. In SYN_RCVD, we resend the
++ SYNACK that we sent earlier and in LAST_ACK we have to
++ retransmit our FINACK. */
++ UIP_STAT(++uip_stat.tcp.rexmit);
++ switch(uip_connr->tcpstateflags & TS_MASK) {
++ case SYN_RCVD:
++ /* In the SYN_RCVD state, we should retransmit our
++ SYNACK. */
++ goto tcp_send_synack;
++
++#if UIP_ACTIVE_OPEN
++ case SYN_SENT:
++ /* In the SYN_SENT state, we retransmit out SYN. */
++ BUF->flags = 0;
++ goto tcp_send_syn;
++#endif /* UIP_ACTIVE_OPEN */
++
++ case ESTABLISHED:
++ /* In the ESTABLISHED state, we call upon the application
++ to do the actual retransmit after which we jump into
++ the code for sending out the packet (the apprexmit
++ label). */
++ uip_len = 0;
++ uip_slen = 0;
++ uip_flags = UIP_REXMIT;
++ UIP_APPCALL();
++ goto apprexmit;
++
++ case FIN_WAIT_1:
++ case CLOSING:
++ case LAST_ACK:
++ /* In all these states we should retransmit a FINACK. */
++ goto tcp_send_finack;
++
++ }
++ }
++ } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
++ /* If there was no need for a retransmission, we poll the
++ application for new data. */
++ uip_len = 0;
++ uip_slen = 0;
++ uip_flags = UIP_POLL;
++ UIP_APPCALL();
++ goto appsend;
++ }
++ }
++ goto drop;
++ }
++#if UIP_UDP
++ if(flag == UIP_UDP_TIMER) {
++ if(uip_udp_conn->lport != 0) {
++ uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
++ uip_len = uip_slen = 0;
++ uip_flags = UIP_POLL;
++ UIP_UDP_APPCALL();
++ goto udp_send;
++ } else {
++ goto drop;
++ }
++ }
++#endif
++
++ /* This is where the input processing starts. */
++ UIP_STAT(++uip_stat.ip.recv);
++
++
++ /* Start of IPv4 input header processing code. */
++
++ /* Check validity of the IP header. */
++ if(BUF->vhl != 0x45) { /* IP version and header length. */
++ UIP_STAT(++uip_stat.ip.drop);
++ UIP_STAT(++uip_stat.ip.vhlerr);
++ UIP_LOG("ip: invalid version or header length.");
++ goto drop;
++ }
++
++ /* Check the size of the packet. If the size reported to us in
++ uip_len doesn't match the size reported in the IP header, there
++ has been a transmission error and we drop the packet. */
++
++ if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
++ uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
++ }
++ if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
++ uip_len = (uip_len & 0xff00) | BUF->len[1];
++ }
++
++ /* Check the fragment flag. */
++ if((BUF->ipoffset[0] & 0x3f) != 0 ||
++ BUF->ipoffset[1] != 0) {
++#if UIP_REASSEMBLY
++ uip_len = uip_reass();
++ if(uip_len == 0) {
++ goto drop;
++ }
++#else
++ UIP_STAT(++uip_stat.ip.drop);
++ UIP_STAT(++uip_stat.ip.fragerr);
++ UIP_LOG("ip: fragment dropped.");
++ goto drop;
++#endif /* UIP_REASSEMBLY */
++ }
++
++ /* 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 UIP_PINGADDRCONF
++ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
++ if(BUF->proto == UIP_PROTO_ICMP) {
++ UIP_LOG("ip: possible ping config packet received.");
++ goto icmp_input;
++ } else {
++ UIP_LOG("ip: packet dropped since no address assigned.");
++ goto drop;
++ }
++ }
++#endif /* UIP_PINGADDRCONF */
++
++ /* Check if the packet is destined for our IP address. */
++ if(BUF->destipaddr[0] != uip_hostaddr[0]) {
++ UIP_STAT(++uip_stat.ip.drop);
++ UIP_LOG("ip: packet not for us.");
++ goto drop;
++ }
++ if(BUF->destipaddr[1] != uip_hostaddr[1]) {
++ UIP_STAT(++uip_stat.ip.drop);
++ UIP_LOG("ip: packet not for us.");
++ goto drop;
++ }
++
++ if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
++ checksum. */
++ UIP_STAT(++uip_stat.ip.drop);
++ UIP_STAT(++uip_stat.ip.chkerr);
++ UIP_LOG("ip: bad checksum.");
++ goto drop;
++ }
++
++ if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump
++ to the tcp_input label. */
++ goto tcp_input;
++
++#if UIP_UDP
++ if(BUF->proto == UIP_PROTO_UDP)
++ goto udp_input;
++#endif /* UIP_UDP */
++
++ if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
++ here. */
++ UIP_STAT(++uip_stat.ip.drop);
++ UIP_STAT(++uip_stat.ip.protoerr);
++ UIP_LOG("ip: neither tcp nor icmp.");
++ goto drop;
++ }
++
++ //icmp_input:
++ UIP_STAT(++uip_stat.icmp.recv);
++
++ /* ICMP echo (i.e., ping) processing. This is simple, we only change
++ the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
++ checksum before we return the packet. */
++ if(ICMPBUF->type != ICMP_ECHO) {
++ UIP_STAT(++uip_stat.icmp.drop);
++ UIP_STAT(++uip_stat.icmp.typeerr);
++ UIP_LOG("icmp: not icmp echo.");
++ goto drop;
++ }
++
++ /* 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. */
++#if UIP_PINGADDRCONF
++ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
++ uip_hostaddr[0] = BUF->destipaddr[0];
++ uip_hostaddr[1] = BUF->destipaddr[1];
++ }
++#endif /* UIP_PINGADDRCONF */
++
++ ICMPBUF->type = ICMP_ECHO_REPLY;
++
++ if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
++ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
++ } else {
++ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
++ }
++
++ /* Swap IP addresses. */
++ 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_STAT(++uip_stat.icmp.sent);
++ goto send;
++
++ /* End of IPv4 input header processing code. */
++
++
++#if UIP_UDP
++ /* UDP input processing. */
++ udp_input:
++ /* UDP processing is really just a hack. We don't do anything to the
++ UDP/IP headers, but let the UDP application do all the hard
++ work. If the application sets uip_slen, it has a packet to
++ send. */
++#if UIP_UDP_CHECKSUMS
++ if(uip_udpchksum() != 0xffff) {
++ UIP_STAT(++uip_stat.udp.drop);
++ UIP_STAT(++uip_stat.udp.chkerr);
++ UIP_LOG("udp: bad checksum.");
++ goto drop;
++ }
++#endif /* UIP_UDP_CHECKSUMS */
++
++ /* 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];
++ ++uip_udp_conn) {
++ if(uip_udp_conn->lport != 0 &&
++ UDPBUF->destport == uip_udp_conn->lport &&
++ (uip_udp_conn->rport == 0 ||
++ UDPBUF->srcport == uip_udp_conn->rport) &&
++ BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
++ BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
++ goto udp_found;
++ }
++ }
++ goto drop;
++
++ udp_found:
++ uip_len = uip_len - 28;
++ uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
++ uip_flags = UIP_NEWDATA;
++ uip_slen = 0;
++ UIP_UDP_APPCALL();
++ udp_send:
++ if(uip_slen == 0) {
++ goto drop;
++ }
++ uip_len = uip_slen + 28;
++
++ BUF->len[0] = (uip_len >> 8);
++ BUF->len[1] = (uip_len & 0xff);
++
++ BUF->proto = UIP_PROTO_UDP;
++
++ UDPBUF->udplen = HTONS(uip_slen + 8);
++ UDPBUF->udpchksum = 0;
++#if UIP_UDP_CHECKSUMS
++ /* Calculate UDP checksum. */
++ UDPBUF->udpchksum = ~(uip_udpchksum());
++ if(UDPBUF->udpchksum == 0) {
++ UDPBUF->udpchksum = 0xffff;
++ }
++#endif /* UIP_UDP_CHECKSUMS */
++
++ BUF->srcport = uip_udp_conn->lport;
++ BUF->destport = uip_udp_conn->rport;
++
++ BUF->srcipaddr[0] = uip_hostaddr[0];
++ BUF->srcipaddr[1] = uip_hostaddr[1];
++ BUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
++ BUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
++
++ uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
++ 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. */
++
++ if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
++ checksum. */
++ UIP_STAT(++uip_stat.tcp.drop);
++ UIP_STAT(++uip_stat.tcp.chkerr);
++ 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]; ++uip_connr) {
++ if(uip_connr->tcpstateflags != CLOSED &&
++ BUF->destport == uip_connr->lport &&
++ BUF->srcport == uip_connr->rport &&
++ BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
++ BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
++ goto found;
++ }
++ }
++
++ /* If we didn't find and active connection that expected the packet,
++ either this packet is an old duplicate, or this is a SYN packet
++ destined for a connection in LISTEN. If the SYN flag isn't set,
++ it is an old packet and we send a RST. */
++ if((BUF->flags & TCP_CTL) != TCP_SYN)
++ goto reset;
++
++ tmp16 = BUF->destport;
++ /* Next, check listening connections. */
++ for(c = 0; c < 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;
++
++ UIP_STAT(++uip_stat.tcp.rst);
++
++ BUF->flags = TCP_RST | TCP_ACK;
++ uip_len = 40;
++ BUF->tcpoffset = 5 << 4;
++
++ /* Flip the seqno and ackno fields in the TCP header. */
++ 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[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;
++
++ /* We also have to increase the sequence number we are
++ acknowledging. If the least significant byte overflowed, we need
++ to propagate the carry to the other bytes as well. */
++ if(++BUF->ackno[3] == 0) {
++ if(++BUF->ackno[2] == 0) {
++ if(++BUF->ackno[1] == 0) {
++ ++BUF->ackno[0];
++ }
++ }
++ }
++
++ /* Swap port numbers. */
++ tmp16 = BUF->srcport;
++ BUF->srcport = BUF->destport;
++ BUF->destport = tmp16;
++
++ /* Swap IP addresses. */
++ 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;
++
++
++ /* And send out the RST packet! */
++ goto tcp_send_noconn;
++
++ /* This label will be jumped to if we matched the incoming packet
++ 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
++ 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
++ CLOSED connections are found. Thanks to Eddie C. Dost for a very
++ nice algorithm for the TIME_WAIT search. */
++ uip_connr = 0;
++ for(c = 0; c < UIP_CONNS; ++c) {
++ if(uip_conns[c].tcpstateflags == CLOSED) {
++ uip_connr = &uip_conns[c];
++ break;
++ }
++ if(uip_conns[c].tcpstateflags == TIME_WAIT) {
++ if(uip_connr == 0 ||
++ uip_conns[c].timer > uip_connr->timer) {
++ uip_connr = &uip_conns[c];
++ }
++ }
++ }
++
++ if(uip_connr == 0) {
++ /* All connections are used already, we drop packet and hope that
++ the remote end will retransmit the packet at a time when we
++ have more spare connections. */
++ UIP_STAT(++uip_stat.tcp.syndrop);
++ UIP_LOG("tcp: found no unused connections.");
++ 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;
++ uip_connr->sv = 4;
++ uip_connr->nrtx = 0;
++ uip_connr->lport = BUF->destport;
++ uip_connr->rport = BUF->srcport;
++ uip_connr->ripaddr[0] = BUF->srcipaddr[0];
++ uip_connr->ripaddr[1] = BUF->srcipaddr[1];
++ uip_connr->tcpstateflags = SYN_RCVD;
++
++ uip_connr->snd_nxt[0] = iss[0];
++ uip_connr->snd_nxt[1] = iss[1];
++ uip_connr->snd_nxt[2] = iss[2];
++ uip_connr->snd_nxt[3] = iss[3];
++ uip_connr->len = 1;
++
++ /* rcv_nxt should be the seqno from the incoming packet + 1. */
++ uip_connr->rcv_nxt[3] = BUF->seqno[3];
++ uip_connr->rcv_nxt[2] = BUF->seqno[2];
++ uip_connr->rcv_nxt[1] = BUF->seqno[1];
++ uip_connr->rcv_nxt[0] = BUF->seqno[0];
++ uip_add_rcv_nxt(1);
++
++ /* Parse the TCP MSS option, if present. */
++ if((BUF->tcpoffset & 0xf0) > 0x50) {
++ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
++ opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
++ if(opt == 0x00) {
++ /* End of options. */
++ break;
++ } else if(opt == 0x01) {
++ ++c;
++ /* NOP option. */
++ } else if(opt == 0x02 &&
++ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
++ /* An MSS option with the right option length. */
++ tmp16 = ((unsigned short int)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
++ (unsigned short int)uip_buf[40 + 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 {
++ /* All other options have a length field, so that we easily
++ can skip past them. */
++ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
++ /* If the length field is zero, the options are malformed
++ and we don't process them further. */
++ break;
++ }
++ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
++ }
++ }
++ }
++
++ /* 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 */
++
++ /* We send out the TCP Maximum Segment Size option with our
++ SYNACK. */
++ BUF->optdata[0] = 2;
++ BUF->optdata[1] = 4;
++ BUF->optdata[2] = (UIP_TCP_MSS) / 256;
++ BUF->optdata[3] = (UIP_TCP_MSS) & 255;
++ uip_len = 44;
++ BUF->tcpoffset = 6 << 4;
++ goto tcp_send;
++
++ /* This label will be jumped to if we found an active connection. */
++ found:
++ uip_conn = uip_connr;
++ 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
++ before we accept the reset. */
++ if(BUF->flags & TCP_RST) {
++ uip_connr->tcpstateflags = CLOSED;
++ UIP_LOG("tcp: got reset, aborting connection.");
++ uip_flags = UIP_ABORT;
++ UIP_APPCALL();
++ goto drop;
++ }
++ /* Calculated 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
++ calculated by subtracing the length of the TCP header (in
++ c) and the length of the IP header (20 bytes). */
++ uip_len = uip_len - c - 20;
++
++ /* 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_len > 0 &&
++ (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
++ BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
++ BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
++ BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
++ goto tcp_send_ack;
++ }
++
++ /* Next, check if the incoming segment acknowledges any outstanding
++ data. If so, we update the sequence number, reset the length of
++ the outstanding data, calculate RTT estimations, and reset the
++ retransmission timer. */
++ if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
++ uip_add32(uip_connr->snd_nxt, uip_connr->len);
++ if(BUF->ackno[0] == uip_acc32[0] &&
++ BUF->ackno[1] == uip_acc32[1] &&
++ BUF->ackno[2] == uip_acc32[2] &&
++ BUF->ackno[3] == uip_acc32[3]) {
++ /* Update sequence number. */
++ uip_connr->snd_nxt[0] = uip_acc32[0];
++ 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) {
++ signed char m;
++ m = uip_connr->rto - uip_connr->timer;
++ /* This is taken directly from VJs original code in his paper */
++ m = m - (uip_connr->sa >> 3);
++ uip_connr->sa += m;
++ if(m < 0) {
++ m = -m;
++ }
++ m = m - (uip_connr->sv >> 2);
++ uip_connr->sv += m;
++ uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
++
++ }
++ /* Set the acknowledged flag. */
++ uip_flags = UIP_ACKDATA;
++ /* Reset the retransmission timer. */
++ uip_connr->timer = uip_connr->rto;
++ }
++
++ }
++
++ /* Do different things depending on in what state the connection is. */
++ switch(uip_connr->tcpstateflags & TS_MASK) {
++ /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
++ implemented, since we force the application to close when the
++ peer sends a FIN (hence the application goes directly from
++ ESTABLISHED to LAST_ACK). */
++ case SYN_RCVD:
++ /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
++ we are waiting for an ACK that acknowledges the data we sent
++ out the last time. Therefore, we want to have the UIP_ACKDATA
++ flag set. If so, we enter the ESTABLISHED state. */
++ if(uip_flags & UIP_ACKDATA) {
++ uip_connr->tcpstateflags = ESTABLISHED;
++ uip_flags = UIP_CONNECTED;
++ uip_connr->len = 0;
++ if(uip_len > 0) {
++ uip_flags |= UIP_NEWDATA;
++ uip_add_rcv_nxt(uip_len);
++ }
++ uip_slen = 0;
++ UIP_APPCALL();
++ goto appsend;
++ }
++ goto drop;
++#if UIP_ACTIVE_OPEN
++ case SYN_SENT:
++ /* In SYN_SENT, we wait for a SYNACK that is sent in response to
++ our SYN. The rcv_nxt is set to sequence number in the SYNACK
++ plus one, and we send an ACK. We move into the ESTABLISHED
++ state. */
++ if((uip_flags & UIP_ACKDATA) &&
++ BUF->flags == (TCP_SYN | TCP_ACK)) {
++
++ /* Parse the TCP MSS option, if present. */
++ if((BUF->tcpoffset & 0xf0) > 0x50) {
++ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
++ opt = uip_buf[40 + UIP_LLH_LEN + c];
++ if(opt == 0x00) {
++ /* End of options. */
++ break;
++ } else if(opt == 0x01) {
++ ++c;
++ /* NOP option. */
++ } else if(opt == 0x02 &&
++ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
++ /* An MSS option with the right option length. */
++ tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
++ uip_buf[UIP_TCPIP_HLEN + 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 {
++ /* All other options have a length field, so that we easily
++ can skip past them. */
++ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
++ /* If the length field is zero, the options are malformed
++ and we don't process them further. */
++ break;
++ }
++ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
++ }
++ }
++ }
++ uip_connr->tcpstateflags = ESTABLISHED;
++ uip_connr->rcv_nxt[0] = BUF->seqno[0];
++ uip_connr->rcv_nxt[1] = BUF->seqno[1];
++ uip_connr->rcv_nxt[2] = BUF->seqno[2];
++ uip_connr->rcv_nxt[3] = BUF->seqno[3];
++ uip_add_rcv_nxt(1);
++ uip_flags = UIP_CONNECTED | UIP_NEWDATA;
++ uip_connr->len = 0;
++ uip_len = 0;
++ uip_slen = 0;
++ UIP_APPCALL();
++ goto appsend;
++ }
++ goto reset;
++#endif /* UIP_ACTIVE_OPEN */
++
++ case 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
++ application should put new data into the buffer, otherwise we are
++ retransmitting an old segment, and the application should put that
++ data into the buffer.
++
++ If the incoming packet is a FIN, we should close the connection on
++ this side as well, and we send out a FIN and enter the LAST_ACK
++ state. We require that there is no outstanding data; otherwise the
++ sequence numbers will be screwed up. */
++
++ if(BUF->flags & TCP_FIN) {
++ if(uip_outstanding(uip_connr)) {
++ goto drop;
++ }
++ uip_add_rcv_nxt(1 + uip_len);
++ uip_flags = UIP_CLOSE;
++ if(uip_len > 0) {
++ uip_flags |= UIP_NEWDATA;
++ }
++ UIP_APPCALL();
++ uip_connr->len = 1;
++ uip_connr->tcpstateflags = LAST_ACK;
++ uip_connr->nrtx = 0;
++ tcp_send_finack:
++ BUF->flags = TCP_FIN | TCP_ACK;
++ goto tcp_send_nodata;
++ }
++
++ /* Check the URG flag. If this is set, the segment carries urgent
++ data that we must pass to the application. */
++ if(BUF->flags & TCP_URG) {
++#if UIP_URGDATA > 0
++ uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
++ if(uip_urglen > uip_len) {
++ /* There is more urgent data in the next segment to come. */
++ uip_urglen = uip_len;
++ }
++ uip_add_rcv_nxt(uip_urglen);
++ uip_len -= uip_urglen;
++ uip_urgdata = uip_appdata;
++ uip_appdata += uip_urglen;
++ } else {
++ uip_urglen = 0;
++#endif /* UIP_URGDATA > 0 */
++ uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
++ uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
++ }
++
++
++ /* If uip_len > 0 we have TCP data in the packet, and we flag this
++ by setting the UIP_NEWDATA flag and update the sequence number
++ we acknowledge. If the application has stopped the dataflow
++ using uip_stop(), we must not accept any data packets from the
++ remote host. */
++ if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
++ uip_flags |= UIP_NEWDATA;
++ uip_add_rcv_nxt(uip_len);
++ }
++
++ /* Check if the available buffer space advertised by the other end
++ is smaller than the initial MSS for this connection. If so, we
++ set the current MSS to the window size to ensure that the
++ application does not send more data than the other end can
++ handle.
++
++ If the remote host advertises a zero window, we set the MSS to
++ 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.
++ */
++ tmp16 = ((unsigned short int)BUF->wnd[0] << 8) + (unsigned short int)BUF->wnd[1];
++ if(tmp16 > uip_connr->initialmss ||
++ tmp16 == 0) {
++ tmp16 = uip_connr->initialmss;
++ }
++ uip_connr->mss = tmp16;
++
++ /* If this packet constitutes an ACK for outstanding data (flagged
++ by the UIP_ACKDATA flag, we should call the application since it
++ might want to send more data. If the incoming packet had data
++ from the peer (as flagged by the UIP_NEWDATA flag), the
++ application must also be notified.
++
++ When the application is called, the global variable uip_len
++ contains the length of the incoming data. The application can
++ access the incoming data through the global pointer
++ uip_appdata, which usually points 40 bytes into the uip_buf
++ array.
++
++ If the application wishes to send any data, this data should be
++ put into the uip_appdata and the length of the data should be
++ put into uip_len. If the application don't have any data to
++ send, uip_len must be set to 0. */
++ if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
++ uip_slen = 0;
++ UIP_APPCALL();
++
++ appsend:
++
++ if(uip_flags & UIP_ABORT) {
++ uip_slen = 0;
++ uip_connr->tcpstateflags = CLOSED;
++ BUF->flags = TCP_RST | TCP_ACK;
++ goto tcp_send_nodata;
++ }
++
++ if(uip_flags & UIP_CLOSE) {
++ uip_slen = 0;
++ uip_connr->len = 1;
++ uip_connr->tcpstateflags = FIN_WAIT_1;
++ uip_connr->nrtx = 0;
++ BUF->flags = TCP_FIN | TCP_ACK;
++ goto tcp_send_nodata;
++ }
++
++ /* If uip_slen > 0, the application has data to be sent. */
++ if(uip_slen > 0) {
++
++ /* If the connection has acknowledged data, the contents of
++ the ->len variable should be discarded. */
++ if((uip_flags & UIP_ACKDATA) != 0) {
++ uip_connr->len = 0;
++ }
++
++ /* If the ->len variable is non-zero the connection has
++ already data in transit and cannot send anymore right
++ now. */
++ if(uip_connr->len == 0) {
++
++ /* The application cannot send more than what is allowed by
++ the mss (the minumum of the MSS and the available
++ window). */
++ if(uip_slen > uip_connr->mss) {
++ uip_slen = uip_connr->mss;
++ }
++
++ /* Remember how much data we send out now so that we know
++ when everything has been acknowledged. */
++ uip_connr->len = uip_slen;
++ } else {
++
++ /* If the application already had unacknowledged data, we
++ make sure that the application does not send (i.e.,
++ retransmit) out more than it previously sent out. */
++ uip_slen = uip_connr->len;
++ }
++ } else {
++ uip_connr->len = 0;
++ }
++ 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) {
++ /* Add the length of the IP and TCP headers. */
++ uip_len = uip_connr->len + UIP_TCPIP_HLEN;
++ /* We always set the ACK flag in response packets. */
++ BUF->flags = TCP_ACK | TCP_PSH;
++ /* Send the packet. */
++ goto tcp_send_noopts;
++ }
++ /* If there is no data to send, just send out a pure ACK if
++ there is newdata. */
++ if(uip_flags & UIP_NEWDATA) {
++ uip_len = UIP_TCPIP_HLEN;
++ BUF->flags = TCP_ACK;
++ goto tcp_send_noopts;
++ }
++ }
++ goto drop;
++ case LAST_ACK:
++ /* We can close this connection if the peer has acknowledged our
++ FIN. This is indicated by the UIP_ACKDATA flag. */
++ if(uip_flags & UIP_ACKDATA) {
++ uip_connr->tcpstateflags = CLOSED;
++ uip_flags = UIP_CLOSE;
++ UIP_APPCALL();
++ }
++ break;
++
++ case 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
++ FIN from the other side. */
++ if(uip_len > 0) {
++ uip_add_rcv_nxt(uip_len);
++ }
++ if(BUF->flags & TCP_FIN) {
++ if(uip_flags & UIP_ACKDATA) {
++ uip_connr->tcpstateflags = TIME_WAIT;
++ uip_connr->timer = 0;
++ uip_connr->len = 0;
++ } else {
++ uip_connr->tcpstateflags = CLOSING;
++ }
++ uip_add_rcv_nxt(1);
++ uip_flags = UIP_CLOSE;
++ UIP_APPCALL();
++ goto tcp_send_ack;
++ } else if(uip_flags & UIP_ACKDATA) {
++ uip_connr->tcpstateflags = FIN_WAIT_2;
++ uip_connr->len = 0;
++ goto drop;
++ }
++ if(uip_len > 0) {
++ goto tcp_send_ack;
++ }
++ goto drop;
++
++ case FIN_WAIT_2:
++ if(uip_len > 0) {
++ uip_add_rcv_nxt(uip_len);
++ }
++ if(BUF->flags & TCP_FIN) {
++ uip_connr->tcpstateflags = TIME_WAIT;
++ uip_connr->timer = 0;
++ uip_add_rcv_nxt(1);
++ uip_flags = UIP_CLOSE;
++ UIP_APPCALL();
++ goto tcp_send_ack;
++ }
++ if(uip_len > 0) {
++ goto tcp_send_ack;
++ }
++ goto drop;
++
++ case TIME_WAIT:
++ goto tcp_send_ack;
++
++ case CLOSING:
++ if(uip_flags & UIP_ACKDATA) {
++ uip_connr->tcpstateflags = TIME_WAIT;
++ uip_connr->timer = 0;
++ }
++ }
++ 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 = 40;
++ tcp_send_noopts:
++ BUF->tcpoffset = 5 << 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. */
++ 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->srcport = uip_connr->lport;
++ BUF->destport = uip_connr->rport;
++
++ BUF->srcipaddr[0] = uip_hostaddr[0];
++ BUF->srcipaddr[1] = uip_hostaddr[1];
++ BUF->destipaddr[0] = uip_connr->ripaddr[0];
++ BUF->destipaddr[1] = uip_connr->ripaddr[1];
++
++
++ if(uip_connr->tcpstateflags & UIP_STOPPED) {
++ /* If the connection has issued uip_stop(), we advertise a zero
++ window so that the remote host will stop sending data. */
++ BUF->wnd[0] = BUF->wnd[1] = 0;
++ } else {
++ BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
++ BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
++ }
++
++ tcp_send_noconn:
++
++ BUF->len[0] = (uip_len >> 8);
++ BUF->len[1] = (uip_len & 0xff);
++
++ /* Calculate TCP checksum. */
++ BUF->tcpchksum = 0;
++ BUF->tcpchksum = ~(uip_tcpchksum());
++
++ //ip_send_nolen:
++
++ BUF->vhl = 0x45;
++ BUF->tos = 0;
++ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
++ BUF->ttl = UIP_TTL;
++ ++ipid;
++ BUF->ipid[0] = ipid >> 8;
++ BUF->ipid[1] = ipid & 0xff;
++
++ /* Calculate IP checksum. */
++ BUF->ipchksum = 0;
++ BUF->ipchksum = ~(uip_ipchksum());
++
++ UIP_STAT(++uip_stat.tcp.sent);
++ send:
++ UIP_STAT(++uip_stat.ip.sent);
++ /* Return and let the caller do the actual transmission. */
++ return;
++ drop:
++ uip_len = 0;
++ return;
++}
++/*-----------------------------------------------------------------------------------*/
++/*unsigned short int
++htons(unsigned short int val)
++{
++ return HTONS(val);
++}*/
++/*-----------------------------------------------------------------------------------*/
++/** @} */
+--- /dev/null
++++ b/net/uip-0.9/uip.h
+@@ -0,0 +1,1066 @@
++/**
++ * \addtogroup uip
++ * @{
++ */
++
++/**
++ * \file
++ * Header file for the uIP TCP/IP stack.
++ * \author Adam Dunkels <adam@dunkels.com>
++ *
++ * 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
++ * structures, TCP/IP header structures and function declarations.
++ *
++ */
++
++
++/*
++ * Copyright (c) 2001-2003, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $
++ *
++ */
++
++#ifndef __UIP_H__
++#define __UIP_H__
++#include <linux/types.h>
++#include <linux/string.h>
++#include <linux/ctype.h>
++#include <malloc.h>
++#include <common.h>
++
++
++#include "uipopt.h"
++
++/*-----------------------------------------------------------------------------------*/
++/* First, the functions that should be called from the
++ * system. Initialization, the periodic timer and incoming packets are
++ * handled by the following three functions.
++ */
++
++/**
++ * \defgroup uipconffunc uIP configuration functions
++ * @{
++ *
++ * The uIP configuration functions are used for setting run-time
++ * parameters in uIP such as IP addresses.
++ */
++
++/**
++ * Set the IP address of this host.
++ *
++ * The IP address is represented as a 4-byte array where the first
++ * octet of the IP address is put in the first member of the 4-byte
++ * array.
++ *
++ * \param addr A pointer to a 4-byte representation of the IP address.
++ *
++ * \hideinitializer
++ */
++#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \
++ uip_hostaddr[1] = addr[1]; } while(0)
++
++/**
++ * Get the IP address of this host.
++ *
++ * The IP address is represented as a 4-byte array where the first
++ * octet of the IP address is put in the first member of the 4-byte
++ * array.
++ *
++ * \param addr A pointer to a 4-byte array that will be filled in with
++ * the currently configured IP address.
++ *
++ * \hideinitializer
++ */
++#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \
++ addr[1] = uip_hostaddr[1]; } while(0)
++
++/** @} */
++
++/**
++ * \defgroup uipinit uIP initialization functions
++ * @{
++ *
++ * The uIP initialization functions are used for booting uIP.
++ */
++
++/**
++ * uIP initialization function.
++ *
++ * This function should be called at boot up to initilize the uIP
++ * TCP/IP stack.
++ */
++void uip_init(void);
++
++/** @} */
++
++/**
++ * \defgroup uipdevfunc uIP device driver functions
++ * @{
++ *
++ * These functions are used by a network device driver for interacting
++ * with uIP.
++ */
++
++/**
++ * Process an incoming packet.
++ *
++ * This function should be called when the device driver has received
++ * a packet from the network. The packet from the device driver must
++ * be present in the uip_buf buffer, and the length of the packet
++ * should be placed in the uip_len variable.
++ *
++ * When the function returns, there may be an outbound packet placed
++ * in the uip_buf packet buffer. If so, the uip_len variable is set to
++ * the length of the packet. If no packet is to be sent out, the
++ * uip_len variable is set to 0.
++ *
++ * 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();
++ }
++ }
++ \endcode
++ *
++ * \note If you are writing a uIP device driver that needs ARP
++ * (Address Resolution Protocol), e.g., when running uIP over
++ * 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();
++ }
++ }
++ \endcode
++ *
++ * \hideinitializer
++ */
++#define uip_input() uip_process(UIP_DATA)
++
++/**
++ * Periodic processing for a connection identified by its number.
++ *
++ * This function does the necessary periodic processing (timers,
++ * polling) for a uIP TCP conneciton, and should be called when the
++ * periodic uIP timer goes off. It should be called for every
++ * connection, regardless of whether they are open of closed.
++ *
++ * When the function returns, it may have an outbound packet waiting
++ * for service in the uIP packet buffer, and if so the uip_len
++ * 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
++ * this:
++ \code
++ 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
++ * (Address Resolution Protocol), e.g., when running uIP over
++ * 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();
++ }
++ }
++ \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)
++
++/**
++ * Periodic processing for a connection identified by a pointer to its structure.
++ *
++ * Same as uip_periodic() but takes a pointer to the actual uip_conn
++ * struct instead of an integer as its argument. This function can be
++ * used to force periodic processing of a specific connection.
++ *
++ * \param conn A pointer to the uip_conn struct for the connection to
++ * be processed.
++ *
++ * \hideinitializer
++ */
++#define uip_periodic_conn(conn) do { uip_conn = conn; \
++ uip_process(UIP_TIMER); } while (0)
++
++#if UIP_UDP
++/**
++ * Periodic processing for a UDP connection identified by its number.
++ *
++ * This function is essentially the same as uip_prerioic(), but for
++ * 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();
++ }
++ }
++ \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();
++ }
++ }
++ \endcode
++ *
++ * \param conn The number of the UDP connection to be processed.
++ *
++ * \hideinitializer
++ */
++#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
++ uip_process(UIP_UDP_TIMER); } while (0)
++
++/**
++ * Periodic processing for a UDP connection identified by a pointer to
++ * its structure.
++ *
++ * Same as uip_udp_periodic() but takes a pointer to the actual
++ * uip_conn struct instead of an integer as its argument. This
++ * function can be used to force periodic processing of a specific
++ * connection.
++ *
++ * \param conn A pointer to the uip_udp_conn struct for the connection
++ * to be processed.
++ *
++ * \hideinitializer
++ */
++#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
++ uip_process(UIP_UDP_TIMER); } while (0)
++
++
++#endif /* UIP_UDP */
++
++/**
++ * The uIP packet buffer.
++ *
++ * The uip_buf array is used to hold incoming and outgoing
++ * packets. The device driver should place incoming data into this
++ * buffer. When sending data, the device driver should read the link
++ * level headers and the TCP/IP headers from this buffer. The size of
++ * the link level headers is configured by the UIP_LLH_LEN define.
++ *
++ * \note The application data need not be placed in this buffer, so
++ * the device driver must read it from the place pointed to by the
++ * uip_appdata pointer as illustrated by the following example:
++ \code
++ void
++ devicedriver_send(void)
++ {
++ hwsend(&uip_buf[0], UIP_LLH_LEN);
++ hwsend(&uip_buf[UIP_LLH_LEN], 40);
++ hwsend(uip_appdata, uip_len - 40 - UIP_LLH_LEN);
++ }
++ \endcode
++ */
++extern u8_t uip_buf[UIP_BUFSIZE+2];
++
++/** @} */
++
++/*-----------------------------------------------------------------------------------*/
++/* 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
++ * @{
++ *
++ * Functions used by an application running of top of uIP.
++ */
++
++/**
++ * 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.
++ *
++ \code
++ uip_listen(HTONS(80));
++ \endcode
++ *
++ * \param port A 16-bit port number in network byte order.
++ */
++void uip_listen(u16_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.
++ *
++ \code
++ uip_unlisten(HTONS(80));
++ \endcode
++ *
++ * \param port A 16-bit port number in network byte order.
++ */
++void uip_unlisten(u16_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,
++ * 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
++ * 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 convertion using HTONS() or htons() is necessary.
++ *
++ \code
++ u16_t ipaddr[2];
++
++ uip_ipaddr(ipaddr, 192,168,1,2);
++ uip_connect(ipaddr, HTONS(80));
++ \endcode
++ *
++ * \param ripaddr A pointer to a 4-byte array representing the IP
++ * address of the remote hot.
++ *
++ * \param port A 16-bit port number in network byte order.
++ *
++ * \return A pointer to the uIP connection identifier for the new connection,
++ * or NULL if no connection could be allocated.
++ *
++ */
++struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
++
++
++
++/**
++ * \internal
++ *
++ * Check if a connection has outstanding (i.e., unacknowledged) data.
++ *
++ * \param conn A pointer to the uip_conn structure for the connection.
++ *
++ * \hideinitializer
++ */
++#define uip_outstanding(conn) ((conn)->len)
++
++/**
++ * Send data on the current connection.
++ *
++ * This function is used to send out a single segment of TCP
++ * data. Only applications that have been invoked by uIP for event
++ * 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
++ * 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.
++ *
++ * \note This function does not guarantee that the sent data will
++ * arrive at the destination. If the data is lost in the network, the
++ * application will be invoked with the uip_rexmit() event being
++ * set. The application will then have to resend the data using this
++ * function.
++ *
++ * \param data A pointer to the data which is to be sent.
++ *
++ * \param len The maximum amount of data bytes to be sent.
++ *
++ * \hideinitializer
++ */
++#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0)
++
++/**
++ * The length of any incoming data that is currently avaliable (if avaliable)
++ * in the uip_appdata buffer.
++ *
++ * The test function uip_data() must first be used to check if there
++ * is any data available at all.
++ *
++ * \hideinitializer
++ */
++#define uip_datalen() uip_len
++
++/**
++ * The length of any out-of-band data (urgent data) that has arrived
++ * on the connection.
++ *
++ * \note The configuration parameter UIP_URGDATA must be set for this
++ * function to be enabled.
++ *
++ * \hideinitializer
++ */
++#define uip_urgdatalen() uip_urglen
++
++/**
++ * Close the current connection.
++ *
++ * This function will close the current connection in a nice way.
++ *
++ * \hideinitializer
++ */
++#define uip_close() (uip_flags = UIP_CLOSE)
++
++/**
++ * 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
++ * uip_close() function.
++ *
++ * \hideinitializer
++ */
++#define uip_abort() (uip_flags = UIP_ABORT)
++
++/**
++ * Tell the sending host to stop sending data.
++ *
++ * This function will close our receiver's window so that we stop
++ * receiving data for the current connection.
++ *
++ * \hideinitializer
++ */
++#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
++
++/**
++ * Find out if the current connection has been previously stopped with
++ * uip_stop().
++ *
++ * \hideinitializer
++ */
++#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
++
++/**
++ * Restart the current connection, if is has previously been stopped
++ * with uip_stop().
++ *
++ * This function will open the receiver's window again so that we
++ * start receiving data for the current connection.
++ *
++ * \hideinitializer
++ */
++#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
++ connection is, and what the application function should do. */
++
++/**
++ * Is new incoming data available?
++ *
++ * 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.
++ *
++ * \hideinitializer
++ */
++#define uip_newdata() (uip_flags & UIP_NEWDATA)
++
++/**
++ * Has previously sent data been acknowledged?
++ *
++ * Will reduce to non-zero if the previously sent data has been
++ * acknowledged by the remote host. This means that the application
++ * can send new data.
++ *
++ * \hideinitializer
++ */
++#define uip_acked() (uip_flags & UIP_ACKDATA)
++
++/**
++ * Has the connection just been connected?
++ *
++ * Reduces to non-zero if the current connection has been connected to
++ * a remote host. This will happen both if the connection has been
++ * actively opened (with uip_connect()) or passively opened (with
++ * uip_listen()).
++ *
++ * \hideinitializer
++ */
++#define uip_connected() (uip_flags & UIP_CONNECTED)
++
++/**
++ * Has the connection been closed by the other end?
++ *
++ * Is non-zero if the connection has been closed by the remote
++ * host. The application may then do the necessary clean-ups.
++ *
++ * \hideinitializer
++ */
++#define uip_closed() (uip_flags & UIP_CLOSE)
++
++/**
++ * Has the connection been aborted by the other end?
++ *
++ * Non-zero if the current connection has been aborted (reset) by the
++ * remote host.
++ *
++ * \hideinitializer
++ */
++#define uip_aborted() (uip_flags & UIP_ABORT)
++
++/**
++ * Has the connection timed out?
++ *
++ * Non-zero if the current connection has been aborted due to too many
++ * retransmissions.
++ *
++ * \hideinitializer
++ */
++#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
++
++/**
++ * Do we need to retransmit previously data?
++ *
++ * Reduces to non-zero if the previously sent data has been lost in
++ * the network, and the application should retransmit it. The
++ * application should send the exact same data as it did the last
++ * time, using the uip_send() function.
++ *
++ * \hideinitializer
++ */
++#define uip_rexmit() (uip_flags & UIP_REXMIT)
++
++/**
++ * Is the connection being polled by uIP?
++ *
++ * Is non-zero if the reason the application is invoked is that the
++ * current connection has been idle for a while and should be
++ * polled.
++ *
++ * The polling event can be used for sending data without having to
++ * wait for the remote host to send data.
++ *
++ * \hideinitializer
++ */
++#define uip_poll() (uip_flags & UIP_POLL)
++
++/**
++ * Get the initial maxium segment size (MSS) of the current
++ * connection.
++ *
++ * \hideinitializer
++ */
++#define uip_initialmss() (uip_conn->initialmss)
++
++/**
++ * Get the current maxium segment size that can be sent on the current
++ * connection.
++ *
++ * The current maxiumum 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()).
++ *
++ * \hideinitializer
++ */
++#define uip_mss() (uip_conn->mss)
++
++/**
++ * Set up a new UDP connection.
++ *
++ * \param ripaddr A pointer to a 4-byte structure representing 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
++ * if no connection could be allocated.
++ */
++struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
++
++/**
++ * Removed a UDP connection.
++ *
++ * \param conn A pointer to the uip_udp_conn structure for the connection.
++ *
++ * \hideinitializer
++ */
++#define uip_udp_remove(conn) (conn)->lport = 0
++
++/**
++ * Send a UDP datagram of length len on the current connection.
++ *
++ * This function can only be called in response to a UDP event (poll
++ * or newdata). The data must be present in the uip_buf buffer, at the
++ * place pointed to by the uip_appdata pointer.
++ *
++ * \param len The length of the data in the uip_buf buffer.
++ *
++ * \hideinitializer
++ */
++#define uip_udp_send(len) uip_slen = (len)
++
++/** @} */
++
++/* uIP convenience and converting functions. */
++
++/**
++ * \defgroup uipconvfunc uIP conversion functions
++ * @{
++ *
++ * These functions can be used for converting between different data
++ * formats used by uIP.
++ */
++
++/**
++ * Pack an IP address into a 4-byte array which is used by uIP to
++ * represent IP addresses.
++ *
++ * Example:
++ \code
++ u16_t ipaddr[2];
++
++ uip_ipaddr(&ipaddr, 192,168,1,2);
++ \endcode
++ *
++ * \param addr A pointer to a 4-byte array that will be filled in with
++ * the IP addres.
++ * \param addr0 The first octet of the IP address.
++ * \param addr1 The second octet of the IP address.
++ * \param addr2 The third octet of the IP address.
++ * \param addr3 The forth octet of the IP address.
++ *
++ * \hideinitializer
++ */
++#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
++ (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \
++ (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \
++ } while(0)
++
++/**
++ * 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.
++ *
++ * \hideinitializer
++ */
++#ifndef HTONS
++# if BYTE_ORDER == BIG_ENDIAN
++# define HTONS(n) (n)
++# else /* BYTE_ORDER == BIG_ENDIAN */
++# define HTONS(n) ((((u16_t)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))
++# endif /* BYTE_ORDER == BIG_ENDIAN */
++#endif /* HTONS */
++
++/**
++ * Convert 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.
++ */
++#ifndef htons
++u16_t htons(u16_t val);
++#endif /* htons */
++
++/** @} */
++
++/**
++ * Pointer to the application data in the packet buffer.
++ *
++ * This pointer points to the application data when the application is
++ * called. If the application wishes to send data, the application may
++ * use this space to write the data into before calling uip_send().
++ */
++extern volatile u8_t *uip_appdata;
++extern volatile u8_t *uip_sappdata;
++
++#if UIP_URGDATA > 0
++/* u8_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).
++ */
++extern volatile u8_t *uip_urgdata;
++#endif /* UIP_URGDATA > 0 */
++
++
++/* u[8|16]_t uip_len:
++ *
++ * When the application is called, uip_len contains the length of any
++ * new data that has been received from the remote host. The
++ * application should set this variable to the size of any data that
++ * the application wishes to send. When the network device driver
++ * output function is called, uip_len should contain the length of the
++ * outgoing packet.
++ */
++extern volatile u16_t uip_len, uip_slen;
++
++#if UIP_URGDATA > 0
++extern volatile u8_t uip_urglen, uip_surglen;
++#endif /* UIP_URGDATA > 0 */
++
++
++/**
++ * Representation of a uIP TCP connection.
++ *
++ * 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
++ * is to let the application store application-specific state (e.g.,
++ * file pointers) for the connection. The size of this field is
++ * configured in the "uipopt.h" header file.
++ */
++struct uip_conn {
++ u16_t ripaddr[2]; /**< 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
++ order. */
++
++ u8_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
++ us. */
++ u16_t len; /**< Length of the data that was previously sent. */
++ u16_t mss; /**< Current maximum segment size for the
++ connection. */
++ u16_t initialmss; /**< Initial maximum segment size for the
++ connection. */
++ u8_t sa; /**< Retransmission time-out calculation state
++ variable. */
++ u8_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
++ segment sent. */
++
++ /** The application state. */
++ u8_t appstate[UIP_APPSTATE_SIZE];
++};
++
++
++/* Pointer to the current connection. */
++extern struct uip_conn *uip_conn;
++/* The array containing all uIP connections. */
++extern struct uip_conn uip_conns[UIP_CONNS];
++/**
++ * \addtogroup uiparch
++ * @{
++ */
++
++/**
++ * 4-byte array used for the 32-bit sequence number calculations.
++ */
++extern volatile u8_t uip_acc32[4];
++
++/** @} */
++
++
++#if UIP_UDP
++/**
++ * Representation of a uIP UDP connection.
++ */
++struct uip_udp_conn {
++ u16_t ripaddr[2]; /**< 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. */
++};
++
++extern struct uip_udp_conn *uip_udp_conn;
++extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
++#endif /* UIP_UDP */
++
++/**
++ * The structure holding the TCP/IP statistics that are gathered if
++ * UIP_STATISTICS is set to 1.
++ *
++ */
++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 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
++ 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
++ 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 typeerr; /**< Number of ICMP packets with a wrong
++ type. */
++ } icmp; /**< ICMP statistics. */
++ 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 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 rexmit; /**< Number of retransmitted TCP segments. */
++ uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
++ connections was avaliable. */
++ uip_stats_t synrst; /**< Number of SYNs for closed ports,
++ triggering a RST. */
++ } tcp; /**< TCP statistics. */
++};
++
++/**
++ * 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:
++ *
++ * When the application is called, uip_flags will contain the flags
++ * that are defined in this file. Please read below for more
++ * infomation.
++ */
++extern volatile u8_t uip_flags;
++
++/* The following flags may be set in the global variable uip_flags
++ before calling the application callback. The UIP_ACKDATA and
++ UIP_NEWDATA flags may both be set at the same time, whereas the
++ others are mutualy exclusive. Note that these flags should *NOT* be
++ accessed directly, but through the uIP functions/macros. */
++
++#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
++ acked and the application should send
++ out new data instead of retransmitting
++ the last data. */
++#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
++ us new data. */
++#define UIP_REXMIT 4 /* Tells the application to retransmit the
++ data that was last sent. */
++#define UIP_POLL 8 /* Used for polling the application, to
++ check if the application has data that
++ it wants to send. */
++#define UIP_CLOSE 16 /* The remote host has closed the
++ connection, thus the connection has
++ gone away. Or the application signals
++ that it wants to close the
++ connection. */
++#define UIP_ABORT 32 /* The remote host has aborted the
++ connection, thus the connection has
++ gone away. Or the application signals
++ that it wants to abort the
++ connection. */
++#define UIP_CONNECTED 64 /* We have got a connection from a remote
++ host and have set up a new connection
++ for it, or an active connection has
++ been successfully established. */
++
++#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
++ too many retransmissions. */
++
++
++/* 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()
++ 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. */
++
++#define UIP_DATA 1 /* Tells uIP that there is incoming data in
++ the uip_buf buffer. The length of the
++ data is stored in the global variable
++ uip_len. */
++#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
++ fired. */
++#if UIP_UDP
++#define UIP_UDP_TIMER 3
++#endif /* UIP_UDP */
++
++/* The TCP states used in the uip_conn->tcpstateflags. */
++#define CLOSED 0
++#define SYN_RCVD 1
++#define SYN_SENT 2
++#define ESTABLISHED 3
++#define FIN_WAIT_1 4
++#define FIN_WAIT_2 5
++#define CLOSING 6
++#define TIME_WAIT 7
++#define LAST_ACK 8
++#define TS_MASK 15
++
++#define UIP_STOPPED 16
++
++#define UIP_TCPIP_HLEN 40
++
++/* The TCP and IP headers. */
++typedef struct {
++ /* IP header. */
++ u8_t vhl,
++ tos,
++ len[2],
++ ipid[2],
++ ipoffset[2],
++ ttl,
++ proto;
++ u16_t ipchksum;
++ u16_t srcipaddr[2],
++ destipaddr[2];
++
++ /* TCP header. */
++ u16_t srcport,
++ destport;
++ u8_t seqno[4],
++ ackno[4],
++ tcpoffset,
++ flags,
++ wnd[2];
++ u16_t tcpchksum;
++ u8_t urgp[2];
++ u8_t optdata[4];
++} uip_tcpip_hdr;
++
++/* The ICMP and IP headers. */
++typedef struct {
++ /* IP header. */
++ u8_t vhl,
++ tos,
++ len[2],
++ ipid[2],
++ ipoffset[2],
++ ttl,
++ proto;
++ u16_t ipchksum;
++ u16_t srcipaddr[2],
++ destipaddr[2];
++ /* ICMP (echo) header. */
++ u8_t type, icode;
++ u16_t icmpchksum;
++ u16_t id, seqno;
++} uip_icmpip_hdr;
++
++
++/* The UDP and IP headers. */
++typedef struct {
++ /* IP header. */
++ u8_t vhl,
++ tos,
++ len[2],
++ ipid[2],
++ ipoffset[2],
++ ttl,
++ proto;
++ u16_t ipchksum;
++ u16_t srcipaddr[2],
++ destipaddr[2];
++
++ /* UDP header. */
++ u16_t srcport,
++ destport;
++ u16_t udplen;
++ u16_t udpchksum;
++} uip_udpip_hdr;
++
++#define UIP_PROTO_ICMP 1
++#define UIP_PROTO_TCP 6
++#define UIP_PROTO_UDP 17
++
++#if UIP_FIXEDADDR
++extern const u16_t uip_hostaddr[2];
++#else /* UIP_FIXEDADDR */
++extern u16_t uip_hostaddr[2];
++#endif /* UIP_FIXEDADDR */
++
++#endif /* __UIP_H__ */
++
++
++/** @} */
++
+--- /dev/null
++++ b/net/uip-0.9/uip_arch.c
+@@ -0,0 +1,145 @@
++/*
++ * Copyright (c) 2001, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
++ *
++ */
++
++
++#include "uip.h"
++#include "uip_arch.h"
++
++#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
++#define IP_PROTO_TCP 6
++
++/*-----------------------------------------------------------------------------------*/
++void
++uip_add32(u8_t *op32, u16_t op16)
++{
++
++ uip_acc32[3] = op32[3] + (op16 & 0xff);
++ 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[3] < (op16 & 0xff)) {
++ ++uip_acc32[2];
++ if(uip_acc32[2] == 0) {
++ ++uip_acc32[1];
++ if(uip_acc32[1] == 0) {
++ ++uip_acc32[0];
++ }
++ }
++ }
++}
++/*-----------------------------------------------------------------------------------*/
++u16_t
++uip_chksum(u16_t *sdata, u16_t len)
++{
++ u16_t acc;
++
++ for(acc = 0; len > 1; len -= 2) {
++ acc += *sdata;
++ if(acc < *sdata) {
++ /* Overflow, so we add the carry to acc (i.e., increase by
++ one). */
++ ++acc;
++ }
++ ++sdata;
++ }
++
++ /* add up any odd byte */
++ if(len == 1) {
++ acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
++ if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
++ ++acc;
++ }
++ }
++
++ return acc;
++}
++/*-----------------------------------------------------------------------------------*/
++u16_t
++uip_ipchksum(void)
++{
++ return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
++}
++/*-----------------------------------------------------------------------------------*/
++u16_t
++uip_tcpchksum(void)
++{
++ u16_t hsum, sum;
++
++
++ /* Compute the checksum of the TCP header. */
++ hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
++
++ /* Compute the checksum of the data in the TCP packet and add it to
++ the TCP header checksum. */
++ sum = uip_chksum((u16_t *)uip_appdata,
++ (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
++
++ if((sum += hsum) < hsum) {
++ ++sum;
++ }
++
++ if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
++ ++sum;
++ }
++ if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
++ ++sum;
++ }
++ if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
++ ++sum;
++ }
++ if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
++ ++sum;
++ }
++ if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
++ ++sum;
++ }
++
++ hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
++
++ if((sum += hsum) < hsum) {
++ ++sum;
++ }
++
++ return sum;
++}
++/*-----------------------------------------------------------------------------------*/
+--- /dev/null
++++ b/net/uip-0.9/uip_arch.h
+@@ -0,0 +1,130 @@
++/**
++ * \defgroup uiparch Architecture specific uIP functions
++ * @{
++ *
++ * The functions in the architecture specific module implement the IP
++ * check sum and 32-bit additions.
++ *
++ * The IP checksum calculation is the most computationally expensive
++ * operation in the TCP/IP stack and it therefore pays off to
++ * implement this in efficient assembler. The purpose of the uip-arch
++ * module is to let the checksum functions to be implemented in
++ * architecture specific assembler.
++ *
++ */
++
++/**
++ * \file
++ * Declarations of architecture specific functions.
++ * \author Adam Dunkels <adam@dunkels.com>
++ */
++
++/*
++ * Copyright (c) 2001, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $
++ *
++ */
++
++#ifndef __UIP_ARCH_H__
++#define __UIP_ARCH_H__
++
++#include "uip.h"
++
++/**
++ * Carry out a 32-bit addition.
++ *
++ * Because not all architectures for which uIP is intended has native
++ * 32-bit arithmetic, uIP uses an external C function for doing the
++ * required 32-bit additions in the TCP protocol processing. This
++ * function should add the two arguments and place the result in the
++ * global variable uip_acc32.
++ *
++ * \note The 32-bit integer pointed to by the op32 parameter and the
++ * result in the uip_acc32 variable are in network byte order (big
++ * endian).
++ *
++ * \param op32 A pointer to a 4-byte array representing a 32-bit
++ * integer in network byte order (big endian).
++ *
++ * \param op16 A 16-bit integer in host byte order.
++ */
++void uip_add32(u8_t *op32, u16_t op16);
++
++/**
++ * Calculate the Internet checksum over a buffer.
++ *
++ * The Internet checksum is the one's complement of the one's
++ * complement sum of all 16-bit words in the buffer.
++ *
++ * See RFC1071.
++ *
++ * \note This function is not called in the current version of uIP,
++ * but future versions might make use of it.
++ *
++ * \param buf A pointer to the buffer over which the checksum is to be
++ * computed.
++ *
++ * \param len The length of the buffer over which the checksum is to
++ * be computed.
++ *
++ * \return The Internet checksum of the buffer.
++ */
++u16_t uip_chksum(u16_t *buf, u16_t len);
++
++/**
++ * Calculate the IP header checksum of the packet header in uip_buf.
++ *
++ * The IP header checksum is the Internet checksum of the 20 bytes of
++ * the IP header.
++ *
++ * \return The IP header checksum of the IP header in the uip_buf
++ * buffer.
++ */
++u16_t uip_ipchksum(void);
++
++/**
++ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
++ *
++ * The TCP checksum is the Internet checksum of data contents of the
++ * TCP segment, and a pseudo-header as defined in RFC793.
++ *
++ * \note The uip_appdata pointer that points to the packet data may
++ * point anywhere in memory, so it is not possible to simply calculate
++ * the Internet checksum of the contents of the uip_buf buffer.
++ *
++ * \return The TCP checksum of the TCP segment in uip_buf and pointed
++ * to by uip_appdata.
++ */
++u16_t uip_tcpchksum(void);
++
++/** @} */
++
++#endif /* __UIP_ARCH_H__ */
+--- /dev/null
++++ b/net/uip-0.9/uip_arp.c
+@@ -0,0 +1,421 @@
++/**
++ * \addtogroup uip
++ * @{
++ */
++
++/**
++ * \defgroup uiparp uIP Address Resolution Protocol
++ * @{
++ *
++ * The Address Resolution Protocol ARP is used for mapping between IP
++ * addresses and link level addresses such as the Ethernet MAC
++ * addresses. ARP uses broadcast queries to ask for the link level
++ * address of a known IP address and the host which is configured with
++ * the IP address for which the query was meant, will respond with its
++ * link level address.
++ *
++ * \note This ARP implementation only supports Ethernet.
++ */
++
++/**
++ * \file
++ * Implementation of the ARP Address Resolution Protocol.
++ * \author Adam Dunkels <adam@dunkels.com>
++ *
++ */
++
++/*
++ * Copyright (c) 2001-2003, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $
++ *
++ */
++
++
++#include "uip_arp.h"
++
++struct arp_hdr {
++ struct uip_eth_hdr ethhdr;
++ u16_t hwtype;
++ u16_t protocol;
++ u8_t hwlen;
++ u8_t protolen;
++ u16_t opcode;
++ struct uip_eth_addr shwaddr;
++ u16_t sipaddr[2];
++ struct uip_eth_addr dhwaddr;
++ u16_t dipaddr[2];
++};
++
++struct ethip_hdr {
++ struct uip_eth_hdr ethhdr;
++ /* IP header. */
++ u8_t vhl,
++ tos,
++ len[2],
++ ipid[2],
++ ipoffset[2],
++ ttl,
++ proto;
++ u16_t ipchksum;
++ u16_t srcipaddr[2],
++ destipaddr[2];
++};
++
++#define ARP_REQUEST 1
++#define ARP_REPLY 2
++
++#define ARP_HWTYPE_ETH 1
++
++struct arp_entry {
++ u16_t ipaddr[2];
++ struct uip_eth_addr ethaddr;
++ u8_t time;
++};
++
++struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
++ UIP_ETHADDR1,
++ UIP_ETHADDR2,
++ UIP_ETHADDR3,
++ UIP_ETHADDR4,
++ UIP_ETHADDR5}};
++
++static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
++static u16_t ipaddr[2];
++static u8_t i, c;
++
++static u8_t arptime;
++static u8_t tmpage;
++
++#define BUF ((struct arp_hdr *)&uip_buf[0])
++#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
++/*-----------------------------------------------------------------------------------*/
++/**
++ * Initialize the ARP module.
++ *
++ */
++/*-----------------------------------------------------------------------------------*/
++void
++uip_arp_init(void)
++{
++ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
++ memset(arp_table[i].ipaddr, 0, 4);
++ }
++}
++/*-----------------------------------------------------------------------------------*/
++/**
++ * Periodic ARP processing function.
++ *
++ * This function performs periodic timer processing in the ARP module
++ * and should be called at regular intervals. The recommended interval
++ * is 10 seconds between the calls.
++ *
++ */
++/*-----------------------------------------------------------------------------------*/
++void
++uip_arp_timer(void)
++{
++ struct arp_entry *tabptr;
++
++ ++arptime;
++ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
++ tabptr = &arp_table[i];
++ if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
++ arptime - tabptr->time >= UIP_ARP_MAXAGE) {
++ memset(tabptr->ipaddr, 0, 4);
++ }
++ }
++
++}
++/*-----------------------------------------------------------------------------------*/
++static void
++uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
++{
++ register struct arp_entry *tabptr;
++ /* 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];
++ /* Only check those entries that are actually in use. */
++ if(tabptr->ipaddr[0] != 0 &&
++ tabptr->ipaddr[1] != 0) {
++
++ /* 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]) {
++
++ /* An old entry found, update this and return. */
++ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
++ tabptr->time = arptime;
++
++ return;
++ }
++ }
++ }
++
++ /* If we get here, no existing ARP table entry was found, so we
++ create one. */
++
++ /* 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) {
++ break;
++ }
++ }
++
++ /* If no unused entry is found, we try to find the oldest entry and
++ throw it away. */
++ if(i == UIP_ARPTAB_SIZE) {
++ tmpage = 0;
++ c = 0;
++ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
++ tabptr = &arp_table[i];
++ if(arptime - tabptr->time > tmpage) {
++ tmpage = arptime - tabptr->time;
++ c = i;
++ }
++ }
++ i = c;
++ }
++
++ /* Now, i is the ARP table entry which we will fill with the new
++ information. */
++ memcpy(tabptr->ipaddr, ipaddr, 4);
++ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
++ tabptr->time = arptime;
++}
++/*-----------------------------------------------------------------------------------*/
++/**
++ * ARP processing for incoming IP packets
++ *
++ * This function should be called by the device driver when an IP
++ * packet has been received. The function will check if the address is
++ * in the ARP cache, and if so the ARP cache entry will be
++ * refreshed. If no ARP cache entry was found, a new one is created.
++ *
++ * This function expects an IP packet with a prepended Ethernet header
++ * in the uip_buf[] buffer, and the length of the packet in the global
++ * variable uip_len.
++ */
++/*-----------------------------------------------------------------------------------*/
++void
++uip_arp_ipin(void)
++{
++ uip_len -= sizeof(struct uip_eth_hdr);
++
++ /* Only insert/update an entry if the source IP address of the
++ incoming IP packet comes from a host on the local network. */
++ if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
++ (uip_hostaddr[0] & uip_arp_netmask[0])) {
++ return;
++ }
++ if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
++ (uip_hostaddr[1] & uip_arp_netmask[1])) {
++ return;
++ }
++ uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
++
++ return;
++}
++/*-----------------------------------------------------------------------------------*/
++/**
++ * ARP processing for incoming ARP packets.
++ *
++ * This function should be called by the device driver when an ARP
++ * packet has been received. The function will act differently
++ * depending on the ARP packet type: if it is a reply for a request
++ * that we previously sent out, the ARP cache will be filled in with
++ * the values from the ARP reply. If the incoming ARP packet is an ARP
++ * request for our IP address, an ARP reply packet is created and put
++ * into the uip_buf[] buffer.
++ *
++ * When the function returns, the value of the global variable uip_len
++ * indicates whether the device driver should send out a packet or
++ * not. If uip_len is zero, no packet should be sent. If uip_len is
++ * non-zero, it contains the length of the outbound packet that is
++ * present in the uip_buf[] buffer.
++ *
++ * This function expects an ARP packet with a prepended Ethernet
++ * header in the uip_buf[] buffer, and the length of the packet in the
++ * global variable uip_len.
++ */
++/*-----------------------------------------------------------------------------------*/
++void
++uip_arp_arpin(void)
++{
++
++ if(uip_len < sizeof(struct arp_hdr)) {
++ uip_len = 0;
++ return;
++ }
++
++ uip_len = 0;
++
++ switch(BUF->opcode) {
++ case HTONS(ARP_REQUEST):
++ /* ARP request. If it asked for our address, we send out a
++ reply. */
++ if(BUF->dipaddr[0] == uip_hostaddr[0] &&
++ BUF->dipaddr[1] == uip_hostaddr[1]) {
++ /* The reply opcode is 2. */
++ BUF->opcode = HTONS(2);
++
++ 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->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];
++
++ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
++ uip_len = sizeof(struct arp_hdr);
++ }
++ break;
++ case HTONS(ARP_REPLY):
++ /* ARP reply. We insert or update the ARP table if it was meant
++ for us. */
++ if(BUF->dipaddr[0] == uip_hostaddr[0] &&
++ BUF->dipaddr[1] == uip_hostaddr[1]) {
++
++ uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
++ }
++ break;
++ }
++
++ return;
++}
++/*-----------------------------------------------------------------------------------*/
++/**
++ * Prepend Ethernet header to an outbound IP packet and see if we need
++ * to send out an ARP request.
++ *
++ * This function should be called before sending out an IP packet. The
++ * function checks the destination IP address of the IP packet to see
++ * what Ethernet MAC address that should be used as a destination MAC
++ * address on the Ethernet.
++ *
++ * If the destination IP address is in the local network (determined
++ * by logical ANDing of netmask and our IP address), the function
++ * checks the ARP cache to see if an entry for the destination IP
++ * address is found. If so, an Ethernet header is prepended and the
++ * function returns. If no ARP cache entry is found for the
++ * destination IP address, the packet in the uip_buf[] is replaced by
++ * an ARP request packet for the IP address. The IP packet is dropped
++ * and it is assumed that they higher level protocols (e.g., TCP)
++ * eventually will retransmit the dropped packet.
++ *
++ * If the destination IP address is not on the local network, the IP
++ * address of the default router is used instead.
++ *
++ * When the function returns, a packet is present in the uip_buf[]
++ * buffer, and the length of the packet is in the global variable
++ * uip_len.
++ */
++/*-----------------------------------------------------------------------------------*/
++void
++uip_arp_out(void)
++{
++ struct arp_entry *tabptr;
++ /* Find the destination IP address in the ARP table and construct
++ the Ethernet header. If the destination IP addres isn't on the
++ local network, we use the default router's IP address instead.
++
++ If not ARP table entry is found, we overwrite the original IP
++ packet with an ARP request for the IP address. */
++
++ /* Check if the destination address is on the local network. */
++ if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) !=
++ (uip_hostaddr[0] & uip_arp_netmask[0]) ||
++ (IPBUF->destipaddr[1] & uip_arp_netmask[1]) !=
++ (uip_hostaddr[1] & uip_arp_netmask[1])) {
++ /* 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. */
++ ipaddr[0] = uip_arp_draddr[0];
++ ipaddr[1] = uip_arp_draddr[1];
++ } else {
++ /* Else, we use the destination IP address. */
++ ipaddr[0] = IPBUF->destipaddr[0];
++ ipaddr[1] = IPBUF->destipaddr[1];
++ }
++
++ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
++ tabptr = &arp_table[i];
++ if(ipaddr[0] == tabptr->ipaddr[0] &&
++ ipaddr[1] == tabptr->ipaddr[1])
++ break;
++ }
++
++ if(i == UIP_ARPTAB_SIZE) {
++ /* The destination address was not in our ARP table, so we
++ overwrite the IP packet with an ARP request. */
++
++ 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);
++
++ BUF->dipaddr[0] = ipaddr[0];
++ BUF->dipaddr[1] = ipaddr[1];
++ BUF->sipaddr[0] = uip_hostaddr[0];
++ BUF->sipaddr[1] = uip_hostaddr[1];
++ BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
++ BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
++ BUF->protocol = HTONS(UIP_ETHTYPE_IP);
++ BUF->hwlen = 6;
++ BUF->protolen = 4;
++ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
++
++ uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
++
++ uip_len = sizeof(struct arp_hdr);
++ return;
++ }
++
++ /* Build an ethernet header. */
++ memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
++ memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
++
++ IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
++
++ uip_len += sizeof(struct uip_eth_hdr);
++}
++/*-----------------------------------------------------------------------------------*/
++
++/** @} */
++/** @} */
+--- /dev/null
++++ b/net/uip-0.9/uip_arp.h
+@@ -0,0 +1,201 @@
++/**
++ * \addtogroup uip
++ * @{
++ */
++
++/**
++ * \addtogroup uiparp
++ * @{
++ */
++
++/**
++ * \file
++ * Macros and definitions for the ARP module.
++ * \author Adam Dunkels <adam@dunkels.com>
++ */
++
++
++/*
++ * Copyright (c) 2001-2003, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $
++ *
++ */
++
++#ifndef __UIP_ARP_H__
++#define __UIP_ARP_H__
++
++#include "uip.h"
++
++
++/**
++ * Representation of a 48-bit Ethernet address.
++ */
++struct uip_eth_addr {
++ u8_t addr[6];
++};
++
++extern struct uip_eth_addr uip_ethaddr;
++
++/**
++ * The Ethernet header.
++ */
++struct uip_eth_hdr {
++ struct uip_eth_addr dest;
++ struct uip_eth_addr src;
++ u16_t type;
++};
++
++#define UIP_ETHTYPE_ARP 0x0806
++#define UIP_ETHTYPE_IP 0x0800
++#define UIP_ETHTYPE_IP6 0x86dd
++
++
++/* The uip_arp_init() function must be called before any of the other
++ ARP functions. */
++void uip_arp_init(void);
++
++/* The uip_arp_ipin() function should be called whenever an IP packet
++ arrives from the Ethernet. This function refreshes the ARP table or
++ inserts a new mapping if none exists. The function assumes that an
++ IP packet with an Ethernet header is present in the uip_buf buffer
++ and that the length of the packet is in the uip_len variable. */
++void uip_arp_ipin(void);
++
++/* The uip_arp_arpin() should be called when an ARP packet is received
++ by the Ethernet driver. This function also assumes that the
++ Ethernet frame is present in the uip_buf buffer. When the
++ uip_arp_arpin() function returns, the contents of the uip_buf
++ buffer should be sent out on the Ethernet if the uip_len variable
++ is > 0. */
++void uip_arp_arpin(void);
++
++/* The uip_arp_out() function should be called when an IP packet
++ should be sent out on the Ethernet. This function creates an
++ Ethernet header before the IP header in the uip_buf buffer. The
++ Ethernet header will have the correct Ethernet MAC destination
++ address filled in if an ARP table entry for the destination IP
++ address (or the IP address of the default router) is present. If no
++ such table entry is found, the IP packet is overwritten with an ARP
++ request and we rely on TCP to retransmit the packet that was
++ overwritten. In any case, the uip_len variable holds the length of
++ the Ethernet frame that should be transmitted. */
++void uip_arp_out(void);
++
++/* The uip_arp_timer() function should be called every ten seconds. It
++ is responsible for flushing old entries in the ARP table. */
++void uip_arp_timer(void);
++
++/** @} */
++
++/**
++ * \addtogroup uipconffunc
++ * @{
++ */
++
++/**
++ * Set the default router's IP address.
++ *
++ * \param addr A pointer to a 4-byte array containing the IP address
++ * of the default router.
++ *
++ * \hideinitializer
++ */
++#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \
++ uip_arp_draddr[1] = addr[1]; } while(0)
++
++/**
++ * Set the netmask.
++ *
++ * \param addr A pointer to a 4-byte array containing the IP address
++ * of the netmask.
++ *
++ * \hideinitializer
++ */
++#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \
++ uip_arp_netmask[1] = addr[1]; } while(0)
++
++
++/**
++ * Get the default router's IP address.
++ *
++ * \param addr A pointer to a 4-byte array that will be filled in with
++ * the IP address of the default router.
++ *
++ * \hideinitializer
++ */
++#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \
++ addr[1] = uip_arp_draddr[1]; } while(0)
++
++/**
++ * Get the netmask.
++ *
++ * \param addr A pointer to a 4-byte array that will be filled in with
++ * the value of the netmask.
++ *
++ * \hideinitializer
++ */
++#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \
++ addr[1] = uip_arp_netmask[1]; } while(0)
++
++
++/**
++ * Specifiy the Ethernet MAC address.
++ *
++ * The ARP code needs to know the MAC address of the Ethernet card in
++ * order to be able to respond to ARP queries and to generate working
++ * Ethernet headers.
++ *
++ * \note This macro only specifies the Ethernet MAC address to the ARP
++ * code. It cannot be used to change the MAC address of the Ethernet
++ * card.
++ *
++ * \param eaddr A pointer to a struct uip_eth_addr containing the
++ * Ethernet MAC address of the Ethernet card.
++ *
++ * \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)
++
++/** @} */
++
++/**
++ * \internal Internal variables that are set using the macros
++ * uip_setdraddr and uip_setnetmask.
++ */
++extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
++#endif /* __UIP_ARP_H__ */
++
++
+--- /dev/null
++++ b/net/uip-0.9/uipopt.h
+@@ -0,0 +1,557 @@
++/**
++ * \defgroup uipopt Configuration options for uIP
++ * @{
++ *
++ * uIP is configured using the per-project configuration file
++ * "uipopt.h". This file contains all compile-time options for uIP and
++ * should be tweaked to match each specific project. The uIP
++ * distribution contains a documented example "uipopt.h" that can be
++ * copied and modified for each project.
++ */
++
++/**
++ * \file
++ * Configuration options for uIP.
++ * \author Adam Dunkels <adam@dunkels.com>
++ *
++ * This file is used for tweaking various configuration options for
++ * uIP. You should make a copy of this file into one of your project's
++ * directories instead of editing this example "uipopt.h" file that
++ * comes with the uIP distribution.
++ */
++
++/*
++ * Copyright (c) 2001-2003, Adam Dunkels.
++ * 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. The name of the author may not be used to endorse or promote
++ * products derived from this software without specific prior
++ * written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * This file is part of the uIP TCP/IP stack.
++ *
++ * $Id: uipopt.h,v 1.16.2.5 2003/10/07 13:22:51 adam Exp $
++ *
++ */
++
++#ifndef __UIPOPT_H__
++#define __UIPOPT_H__
++
++/*------------------------------------------------------------------------------*/
++/**
++ * \defgroup uipopttypedef uIP type definitions
++ * @{
++ */
++
++/**
++ * The 8-bit unsigned data type.
++ *
++ * This may have to be tweaked for your particular compiler. "unsigned
++ * char" works for most compilers.
++ */
++typedef unsigned char u8_t;
++
++/**
++ * The 16-bit unsigned data type.
++ *
++ * This may have to be tweaked for your particular compiler. "unsigned
++ * short" works for most compilers.
++ */
++typedef unsigned short u16_t;
++
++/**
++ * The statistics data type.
++ *
++ * This datatype determines how high the statistics counters are able
++ * to count.
++ */
++typedef unsigned short uip_stats_t;
++
++/** @} */
++
++/*------------------------------------------------------------------------------*/
++
++/**
++ * \defgroup uipoptstaticconf Static configuration options
++ * @{
++ *
++ * These configuration options can be used for setting the IP address
++ * 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
++ * 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.
++ *
++ * If uIP should use a fixed IP address, the settings are set in the
++ * uipopt.h file. If not, the macros uip_sethostaddr(),
++ * uip_setdraddr() and uip_setnetmask() should be used instead.
++ *
++ * \hideinitializer
++ */
++#define UIP_FIXEDADDR 0
++
++/**
++ * Ping IP address asignment.
++ *
++ * 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
++ * the destination IP address of the first incoming "ping" (ICMP echo)
++ * packet will be used for setting the hosts IP address.
++ *
++ * \note This works only if UIP_FIXEDADDR is 0.
++ *
++ * \hideinitializer
++ */
++#define UIP_PINGADDRCONF 0
++
++#define UIP_IPADDR0 192 /**< The first octet of the IP address of
++ this uIP node, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_IPADDR1 168 /**< The second octet of the IP address of
++ this uIP node, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_IPADDR2 0 /**< The third octet of the IP address of
++ this uIP node, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_IPADDR3 250 /**< The fourth octet of the IP address of
++ this uIP node, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++
++#define UIP_NETMASK0 255 /**< The first octet of the netmask of
++ this uIP node, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_NETMASK1 255 /**< The second octet of the netmask of
++ this uIP node, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_NETMASK2 255 /**< The third octet of the netmask of
++ this uIP node, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_NETMASK3 0 /**< The fourth octet of the netmask of
++ this uIP node, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++
++#define UIP_DRIPADDR0 192 /**< The first octet of the IP address of
++ the default router, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_DRIPADDR1 168 /**< The second octet of the IP address of
++ the default router, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_DRIPADDR2 0 /**< The third octet of the IP address of
++ the default router, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++#define UIP_DRIPADDR3 1 /**< The fourth octet of the IP address of
++ the default router, if UIP_FIXEDADDR is
++ 1. \hideinitializer */
++
++/**
++ * Specifies if the uIP ARP module should be compiled with a fixed
++ * Ethernet MAC address or not.
++ *
++ * If this configuration option is 0, the macro uip_setethaddr() can
++ * be used to specify the Ethernet address at run-time.
++ *
++ * \hideinitializer
++ */
++#define UIP_FIXEDETHADDR 0
++
++#define UIP_ETHADDR0 0x00 /**< The first octet of the Ethernet
++ address if UIP_FIXEDETHADDR is
++ 1. \hideinitializer */
++#define UIP_ETHADDR1 0xbd /**< The second octet of the Ethernet
++ address if UIP_FIXEDETHADDR is
++ 1. \hideinitializer */
++#define UIP_ETHADDR2 0x3b /**< The third octet of the Ethernet
++ address if UIP_FIXEDETHADDR is
++ 1. \hideinitializer */
++#define UIP_ETHADDR3 0x33 /**< The fourth octet of the Ethernet
++ address if UIP_FIXEDETHADDR is
++ 1. \hideinitializer */
++#define UIP_ETHADDR4 0x05 /**< The fifth octet of the Ethernet
++ address if UIP_FIXEDETHADDR is
++ 1. \hideinitializer */
++#define UIP_ETHADDR5 0x71 /**< The sixth octet of the Ethernet
++ address if UIP_FIXEDETHADDR is
++ 1. \hideinitializer */
++
++/** @} */
++/*------------------------------------------------------------------------------*/
++/**
++ * \defgroup uipoptip IP configuration options
++ * @{
++ *
++ */
++/**
++ * The IP TTL (time to live) of IP packets sent by uIP.
++ *
++ * This should normally not be changed.
++ */
++#define UIP_TTL 255
++
++/**
++ * 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
++ * 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).
++ *
++ * \note IP packet reassembly is not heavily tested.
++ *
++ * \hideinitializer
++ */
++#define UIP_REASSEMBLY 0
++
++/**
++ * The maximum time an IP fragment should wait in the reassembly
++ * buffer before it is dropped.
++ *
++ */
++#define UIP_REASS_MAXAGE 40
++
++/** @} */
++
++/*------------------------------------------------------------------------------*/
++/**
++ * \defgroup uipoptudp UDP configuration options
++ * @{
++ *
++ * \note The UDP support in uIP is still not entirely complete; there
++ * is no support for sending or receiving broadcast or multicast
++ * packets, but it works well enough to support a number of vital
++ * applications such as DNS queries, though
++ */
++
++/**
++ * Toggles wether UDP support should be compiled in or not.
++ *
++ * \hideinitializer
++ */
++#define UIP_UDP 0
++
++/**
++ * Toggles if UDP checksums should be used or not.
++ *
++ * \note Support for UDP checksums is currently not included in uIP,
++ * so this option has no function.
++ *
++ * \hideinitializer
++ */
++#define UIP_UDP_CHECKSUMS 0
++
++/**
++ * The maximum amount of concurrent UDP connections.
++ *
++ * \hideinitializer
++ */
++#define UIP_UDP_CONNS 10
++
++/**
++ * The name of the function that should be called when UDP datagrams arrive.
++ *
++ * \hideinitializer
++ */
++#define UIP_UDP_APPCALL udp_appcall
++
++/** @} */
++/*------------------------------------------------------------------------------*/
++/**
++ * \defgroup uipopttcp TCP configuration options
++ * @{
++ */
++
++/**
++ * 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
++ * option can be turned off to reduce the code size of uIP.
++ *
++ * \hideinitializer
++ */
++#define UIP_ACTIVE_OPEN 1
++
++/**
++ * The maximum number of simultaneously open TCP connections.
++ *
++ * 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.
++ *
++ * \hideinitializer
++ */
++#define UIP_CONNS 10
++
++/**
++ * The maximum number of simultaneously listening TCP ports.
++ *
++ * Each listening TCP port requires 2 bytes of memory.
++ *
++ * \hideinitializer
++ */
++#define UIP_LISTENPORTS 10
++
++/**
++ * The size of the advertised receiver's window.
++ *
++ * Should be set low (i.e., to the size of the uip_buf buffer) is the
++ * application is slow to process incoming data, or high (32768 bytes)
++ * if the application processes data quickly.
++ *
++ * \hideinitializer
++ */
++#define UIP_RECEIVE_WINDOW 32768
++
++/**
++ * Determines if support for TCP urgent data notification should be
++ * compiled in.
++ *
++ * Urgent data (out-of-band data) is a rarely used TCP feature that
++ * very seldom would be required.
++ *
++ * \hideinitializer
++ */
++#define UIP_URGDATA 1
++
++/**
++ * The initial retransmission timeout counted in timer pulses.
++ *
++ * This should not be changed.
++ */
++#define UIP_RTO 3
++
++/**
++ * The maximum number of times a segment should be retransmitted
++ * before the connection should be aborted.
++ *
++ * This should not be changed.
++ */
++#define UIP_MAXRTX 8
++
++/**
++ * The maximum number of times a SYN segment should be retransmitted
++ * before a connection request should be deemed to have been
++ * unsuccessful.
++ *
++ * This should not need to be changed.
++ */
++#define UIP_MAXSYNRTX 3
++
++/**
++ * The TCP maximum segment size.
++ *
++ * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.
++ */
++#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
++
++/**
++ * How long a connection should stay in the TIME_WAIT state.
++ *
++ * This configiration option has no real implication, and it should be
++ * left untouched.
++ */
++#define UIP_TIME_WAIT_TIMEOUT 120
++
++
++/** @} */
++/*------------------------------------------------------------------------------*/
++/**
++ * \defgroup uipoptarp ARP configuration options
++ * @{
++ */
++
++/**
++ * The size of the ARP table.
++ *
++ * This option should be set to a larger value if this uIP node will
++ * have many connections from the local network.
++ *
++ * \hideinitializer
++ */
++#define UIP_ARPTAB_SIZE 8
++
++/**
++ * The maxium age of ARP table entries measured in 10ths of seconds.
++ *
++ * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
++ * default).
++ */
++#define UIP_ARP_MAXAGE 120
++
++/** @} */
++
++/*------------------------------------------------------------------------------*/
++
++/**
++ * \defgroup uipoptgeneral General configuration options
++ * @{
++ */
++
++/**
++ * The size of the uIP packet buffer.
++ *
++ * The uIP packet buffer should not be smaller than 60 bytes, and does
++ * not need to be larger than 1500 bytes. Lower size results in lower
++ * TCP throughput, larger size results in higher TCP throughput.
++ *
++ * \hideinitializer
++ */
++#define UIP_BUFSIZE 1500
++
++
++/**
++ * Determines if statistics support should be compiled in.
++ *
++ * The statistics is useful for debugging and to show the user.
++ *
++ * \hideinitializer
++ */
++#define UIP_STATISTICS 1
++
++/**
++ * Determines if logging of certain events should be compiled in.
++ *
++ * This is useful mostly for debugging. The function uip_log()
++ * must be implemented to suit the architecture of the project, if
++ * logging is turned on.
++ *
++ * \hideinitializer
++ */
++#define UIP_LOGGING 0
++
++/**
++ * Print out a uIP log message.
++ *
++ * This function must be implemented by the module that uses uIP, and
++ * is called by uIP whenever a log message is generated.
++ */
++void uip_log(char *msg);
++
++/**
++ * The link level header length.
++ *
++ * This is the offset into the uip_buf where the IP header can be
++ * found. For Ethernet, this should be set to 14. For SLIP, this
++ * should be set to 0.
++ *
++ * \hideinitializer
++ */
++#define UIP_LLH_LEN 14
++
++
++/** @} */
++/*------------------------------------------------------------------------------*/
++/**
++ * \defgroup uipoptcpu CPU architecture configuration
++ * @{
++ *
++ * The CPU architecture configuration is where the endianess of the
++ * CPU on which uIP is to be run is specified. Most CPUs today are
++ * little endian, and the most notable exception are the Motorolas
++ * which are big endian. The BYTE_ORDER macro should be changed to
++ * reflect the CPU architecture on which uIP is to be run.
++ */
++#ifndef LITTLE_ENDIAN
++#define LITTLE_ENDIAN 3412
++#endif /* LITTLE_ENDIAN */
++#ifndef BIG_ENDIAN
++#define BIG_ENDIAN 1234
++#endif /* BIGE_ENDIAN */
++
++/**
++ * The byte order of the CPU architecture on which uIP is to be run.
++ *
++ * This option can be either BIG_ENDIAN (Motorola byte order) or
++ * LITTLE_ENDIAN (Intel byte order).
++ *
++ * \hideinitializer
++ */
++/*#ifndef BYTE_ORDER*/
++#define BYTE_ORDER BIG_ENDIAN
++/*#endif*/ /* BYTE_ORDER */
++
++/** @} */
++/*------------------------------------------------------------------------------*/
++
++/**
++ * \defgroup uipoptapp Appication specific configurations
++ * @{
++ *
++ * An uIP application is implemented using a single application
++ * function that is called by uIP whenever a TCP/IP event occurs. The
++ * name of this function must be registered with uIP at compile time
++ * using the UIP_APPCALL definition.
++ *
++ * uIP applications can store the application state within the
++ * uip_conn structure by specifying the size of the application
++ * structure with the UIP_APPSTATE_SIZE macro.
++ *
++ * The file containing the definitions must be included in the
++ * uipopt.h file.
++ *
++ * The following example illustrates how this can look.
++ \code
++
++void httpd_appcall(void);
++#define UIP_APPCALL httpd_appcall
++
++struct httpd_state {
++ u8_t state;
++ u16_t count;
++ char *dataptr;
++ char *script;
++};
++#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
++ \endcode
++ */
++
++/**
++ * \var #define UIP_APPCALL
++ *
++ * The name of the application function that uIP should call in
++ * response to TCP/IP events.
++ *
++ */
++
++/**
++ * \var #define UIP_APPSTATE_SIZE
++ *
++ * The size of the application state that is to be stored in the
++ * uip_conn structure.
++ */
++/** @} */
++
++/* Include the header file for the application program that should be
++ used. If you don't use the example web server, you should change
++ this. */
++#include "httpd.h"
++
++
++#endif /* __UIPOPT_H__ */
+--- a/board/infineon/easy50712/danube.c
++++ b/board/infineon/easy50712/danube.c
+@@ -354,7 +354,7 @@ int do_http_upgrade(const unsigned char
+ }
+ /* write the image to the flash */
+ puts("http ugrade ...\n");
+- sprintf(buf, "era ${kernel_addr} +0x%x; cp.b ${ram_addr} ${kernel_addr} 0x%x", size, size);
++ sprintf(buf, "era ${kernel_addr} +0x%lx; cp.b ${ram_addr} ${kernel_addr} 0x%lx", size, size);
+ return run_command(buf, 0);
+ }
+
+--- a/common/main.c
++++ b/common/main.c
+@@ -273,6 +273,10 @@ static __inline__ int abortboot(int boot
+
+ void main_loop (void)
+ {
++#ifdef CONFIG_CMD_HTTPD
++ int ret;
++#endif
++
+ #ifndef CONFIG_SYS_HUSH_PARSER
+ static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
+ int len;
+@@ -403,12 +407,22 @@ void main_loop (void)
+ # endif
+
+ # ifndef CONFIG_SYS_HUSH_PARSER
+- run_command (s, 0);
++ ret = run_command (s, 0);
+ # else
+- parse_string_outer(s, FLAG_PARSE_SEMICOLON |
++ ret = parse_string_outer(s, FLAG_PARSE_SEMICOLON |
+ FLAG_EXIT_FROM_LOOP);
+ # endif
+
++# ifdef CONFIG_CMD_HTTPD
++ if (ret != 0) {
++ printf("Failed to execute bootcmd "
++ "(maybe invalid u-boot environment?), "
++ "starting httpd to update firmware...\n");
++ NetLoopHttpd();
++ }
++# endif
++
++
+ # ifdef CONFIG_AUTOBOOT_KEYED
+ disable_ctrlc(prev); /* restore Control C checking */
+ # endif
+--- a/include/configs/easy50712.h
++++ b/include/configs/easy50712.h
+@@ -114,4 +114,7 @@
+
+ #define CONFIG_CMD_HTTPD /* enable upgrade via HTTPD */
+
++#define CONFIG_IPADDR 192.168.0.119
++#define CONFIG_ETHADDR 00:01:02:03:04:05
++
+ #endif /* __CONFIG_H */
+--- a/lib_mips/time.c
++++ b/lib_mips/time.c
+@@ -29,6 +29,8 @@ static unsigned long timestamp;
+ /* how many counter cycles in a jiffy */
+ #define CYCLES_PER_JIFFY (CONFIG_SYS_MIPS_TIMER_FREQ + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ
+
++unsigned long ifx_get_cpuclk(void);
++
+ /*
+ * timer without interrupts
+ */
+--- a/net/httpd.c
++++ b/net/httpd.c
+@@ -35,12 +35,14 @@ HttpdHandler (void)
+ }
+ }
+
++#if 0
+ static void
+ HttpdTimeout (void)
+ {
+ puts ("T ");
+ NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
+ }
++#endif
+
+ void
+ HttpdStart (void)
+--- a/net/net.c
++++ b/net/net.c
+@@ -1966,7 +1966,7 @@ NetSendHttpd(void)
+ void
+ NetReceiveHttpd(volatile uchar * inpkt, int len)
+ {
+- memcpy(uip_buf, inpkt, len);
++ memcpy(uip_buf, (const void *)inpkt, len);
+ uip_len = len;
+ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
+ uip_arp_ipin();
+@@ -1989,6 +1989,7 @@ NetLoopHttpd(void)
+ unsigned long long tout = 0;
+ bd_t *bd = gd->bd;
+ unsigned short int ip[2];
++ struct uip_eth_addr eaddr;
+
+ #ifdef CONFIG_NET_MULTI
+ NetRestarted = 0;
+@@ -2039,6 +2040,15 @@ restart:
+ eth_getenv_enetaddr("ethaddr", NetOurEther);
+ #endif
+
++ eaddr.addr[0] = NetOurEther[0];
++ eaddr.addr[1] = NetOurEther[1];
++ eaddr.addr[2] = NetOurEther[2];
++ eaddr.addr[3] = NetOurEther[3];
++ eaddr.addr[4] = NetOurEther[4];
++ eaddr.addr[5] = NetOurEther[5];
++
++ uip_setethaddr(eaddr);
++
+ NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
+ NetOurGatewayIP = getenv_IPaddr ("gatewayip");
+ NetOurSubnetMask= getenv_IPaddr ("netmask");
+@@ -2072,6 +2082,14 @@ restart:
+ tout = t1;
+ }
+ }
++
++ if (ctrlc()) {
++ eth_halt();
++ puts ("\nAbort\n");
++ return (-1);
++ }
++
++
+ if(!httpd_upload_complete)
+ continue;
+ printf("Bytes transferred = %ld (%lx hex)\n",
+--- a/net/uip-0.9/fsdata.c
++++ b/net/uip-0.9/fsdata.c
+@@ -1,199 +1,108 @@
+-static const char data_flashing_html[] = {
+- /* /flashing.html */
+- 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
+- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
+- 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
+- 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
+- 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+- 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
+- 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
+- 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+- 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
+- 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
+- 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
+- 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
+- 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
+- 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
+- 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
+- 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
+- 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
+- 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
+- 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
+- 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
+- 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
+- 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
+- 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
+- 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
+- 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
+-
+-static const char data_fail_html[] = {
+- /* /fail.html */
+- 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
+- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
+- 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
+- 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
+- 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+- 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
+- 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
+- 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+- 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
+- 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
+- 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
+- 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
+- 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
+- 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
+- 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
+- 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
+- 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
+- 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
+- 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
+- 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
+- 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
+- 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
+- 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
+- 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
+- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
+- 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
+- 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
+- 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
+- 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
+- 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
+- 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+- 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
+- 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
+- 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
+- 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
+- 0x3e, 0xa, };
+-
+-static const char data_404_html[] = {
+- /* /404.html */
+- 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
+- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
+- 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
+- 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
+- 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
+- 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
+- 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
+- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
+- 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
+- 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
+- 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
+- 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
+- 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
+- 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
+- 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
+- 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
+- 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
+- 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
+- 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
+- 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
+- 0x6c, 0x3e, };
+-
+-static const char data_index_html[] = {
+- /* /index.html */
+- 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
+- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
+- 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
+- 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
+- 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+- 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
+- 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
+- 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+- 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
+- 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
+- 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
+- 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
+- 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
+- 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
+- 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
+- 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
+- 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
+- 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
+- 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
+- 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
+- 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
+- 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
+- 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
+- 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
+- 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
+- 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
+- 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
+- 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
+- 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
+- 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
+- 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
+- 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
+- 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
+- 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
+- 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
+- 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
+- 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
+- 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
+- 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
+- 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
+- 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
+- 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
+-
+-static const char data_flash_html[] = {
+- /* /flash.html */
+- 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
+- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
+- 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
+- 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
+- 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+- 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
+- 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
+- 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+- 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
+- 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
+- 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
+- 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
+- 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
+- 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
+- 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
+- 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
+- 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
+- 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
+- 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
+- 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
+- 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
+- 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
+- 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
+- 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
+- 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
+- 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
+- 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
+- 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
+- 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
+- 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
+- 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
+- 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
+- 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
+- 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
+- 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
+- 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
+- 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
+- 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
+- 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
+- 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
+- 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
+- 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
+- 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
+-
+-const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
++static const char data_flashing_html[] =
++"HTTP/1.0 200 OK\n"
++"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
++"Content-type: text/html\n"
++"\n"
++"<html>\n"
++"\t<head>\n"
++"\t\t<title>\n"
++"\t\t\tFailsafe UI\n"
++"\t\t</title>\n"
++"\t</head>\n"
++"\t<body>\n"
++"\t\t<center><h1>Upgrading system...</h1></center>\n"
++"\t</body>\n"
++"</html>\n";
++
++static const char data_fail_html[] =
++"HTTP/1.0 200 OK\n"
++"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
++"Content-type: text/html\n"
++"\n"
++"<html>\n"
++"\t<head>\n"
++"\t\t<title>\n"
++"\t\t\tFailsafe UI\n"
++"\t\t</title>\n"
++"\t</head>\n"
++"\t<body>\n"
++"\t\t<h1>Flashing failed</h1>\n"
++"\t\tERROR - the image you uploaded failed to pass verification.<br>\n"
++"\t\tPlease make sure to use an official update provided by http://lantiq.com/\n"
++"\t</body>\n"
++"</html>\n";
++
++static const char data_404_html[] =
++"HTTP/1.0 404 File not found\n"
++"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
++"Content-type: text/html\n"
++"\n"
++"<html>\n"
++"\t<head>\n"
++"\t\t<title>\n"
++"\t\t\tFailsafe UI\n"
++"\t\t</title>\n"
++"\t</head>\n"
++"\t<body>\n"
++"\t\t<center><h1>404 - file not found</h1></center>\n"
++"\t</body>\n"
++"</html>\n";
++
++static const char data_index_html[] =
++"HTTP/1.0 200 OK\n"
++"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
++"Content-type: text/html\n"
++"\n"
++"<html>\n"
++"\t<head>\n"
++"\t\t<title>\n"
++"\t\t\tFailsafe UI\n"
++"\t\t</title>\n"
++"\t</head>\n"
++"\t<body>\n"
++"\t\t<h1>Failsafe UI</h1>\n"
++"\t\t<form method=\"post\" enctype=\"multipart/form-data\">\n"
++"\t\t\t<input type=file name=firmware>\n"
++"\t\t\t<input type=submit>\n"
++"\t\t</form>\n"
++"\t</body>\n"
++"</html>\n";
++
++static const char data_flash_html[] =
++"HTTP/1.0 200 OK\n"
++"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
++"Content-type: text/html\n"
++"\n"
++"<html>\n"
++"\t<head>\n"
++"\t\t<title>\n"
++"\t\t\tFailsafe UI\n"
++"\t\t</title>\n"
++"\t</head>\n"
++"\t<body>\n"
++"\t\t<h1>Flashing...</h1>\n"
++"\t\tThe system is now trying to flash. If there is a problem, the LEDs will "
++"start to blink.<br>\n"
++"\n"
++"\t\tAfter a successful update the box will reboot\n"
++"\t</body>\n"
++"</html>\n";
++
++const struct fsdata_file file_flashing_html[] =
++{{NULL, "/flashing.html", data_flashing_html, sizeof(data_flashing_html)}};
++
++const struct fsdata_file file_fail_html[] =
++{{file_flashing_html, "/fail.html", data_fail_html, sizeof(data_fail_html)}};
+
+-const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
++const struct fsdata_file file_404_html[] =
++{{file_fail_html, "/404.html", data_404_html, sizeof(data_404_html)}};
+
+-const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
++const struct fsdata_file file_index_html[] =
++{{file_404_html, "/index.html", data_index_html, sizeof(data_index_html)}};
+
+-const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
+-
+-const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
++const struct fsdata_file file_flash_html[] =
++{{file_index_html, "/flash.html", data_flash_html, sizeof(data_flash_html)}};
+
+ #define FS_ROOT file_flash_html
+
+-#define FS_NUMFILES 5
+\ No newline at end of file
++#define FS_NUMFILES 5
+--- a/net/uip-0.9/httpd.c
++++ b/net/uip-0.9/httpd.c
+@@ -130,7 +130,7 @@ httpd_appcall(void)
+ if(!fs_open((const char *)&uip_appdata[4], &fsfile))
+ {
+ PRINTLN("couldn't open file");
+- fs_open(file_index_html.name, &fsfile);
++ fs_open(file_404_html.name, &fsfile);
+ }
+ }
+ hs->script = 0;
+@@ -141,7 +141,7 @@ httpd_appcall(void)
+ if(hs->state == HTTP_FIRMWARE)
+ {
+ unsigned char *start = (unsigned char*)uip_appdata;
+- char *clen = strstr(start, "Content-Length:");
++ char *clen = strstr((char *)start, "Content-Length:");
+ int len = 0;
+ unsigned char *next, *end;
+ unsigned char *boundary_start;
+@@ -150,14 +150,14 @@ httpd_appcall(void)
+ if(clen)
+ {
+ clen += sizeof("Content-Length:");
+- next = strstr(clen, eol);
++ next = (unsigned char *)strstr(clen, eol);
+ if(next)
+ {
+ len = atoi(clen);
+ next++;
+ printf("expecting %d bytes\n", len);
+ upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
+- printf("received data will be stored at 0x%08X\n", upload_data);
++ printf("received data will be stored at %p\n", upload_data);
+ if(!upload_data)
+ {
+ printf("failed to allocate memory\n");
+@@ -174,14 +174,14 @@ httpd_appcall(void)
+ uip_close();
+ return;
+ }
+- boundary_start = strstr(next, "---");
++ boundary_start = (unsigned char *)strstr((char *)next, "---");
+ if(!boundary_start)
+ {
+ uip_close();
+ return;
+ }
+- end = strstr(boundary_start, eol);
+- if(!eol)
++ end = (unsigned char *)strstr((char *)boundary_start, eol);
++ if(!end)
+ {
+ uip_close();
+ return;
+@@ -189,13 +189,13 @@ httpd_appcall(void)
+ boundary_len = end - boundary_start;
+ memcpy(boundary, boundary_start, boundary_len);
+ boundary[boundary_len] = 0;
+- next = strstr(boundary_start, "name=\"firmware\";");
++ next = (unsigned char *)strstr((char *)boundary_start, "name=\"firmware\";");
+ if(!next)
+ {
+ uip_close();
+ return;
+ }
+- next = strstr(next, eol2);
++ next = (unsigned char *)strstr((char *)next, eol2);
+ if(!next)
+ {
+ printf("could not find start of data\n");
+@@ -259,7 +259,6 @@ httpd_appcall(void)
+ {
+ if(upload_running)
+ {
+- int i;
+ httpd_upload_complete = 1;
+ // for(i = 0; i < hs->upload_total; i++)
+ // printf("%c", httpd_upload_data[i]);
+@@ -267,7 +266,7 @@ httpd_appcall(void)
+ uip_close();
+ }
+ }
+- uip_send(hs->dataptr, hs->count);
++ uip_send((unsigned char *)hs->dataptr, hs->count);
+ }
+ break;
+
+++ /dev/null
---- a/common/cmd_net.c
-+++ b/common/cmd_net.c
-@@ -43,6 +43,18 @@ U_BOOT_CMD(
- "[loadAddress] [[hostIPaddr:]bootfilename]"
- );
-
-+#if defined(CONFIG_CMD_HTTPD)
-+int do_httpd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-+{
-+ return NetLoopHttpd();
-+}
-+
-+U_BOOT_CMD(
-+ httpd, 1, 1, do_httpd,
-+ "httpd\t- start webserver", ""
-+);
-+#endif
-+
- int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
- {
- return netboot_common (TFTP, cmdtp, argc, argv);
---- /dev/null
-+++ b/include/httpd.h
-@@ -0,0 +1,17 @@
-+#ifndef _UIP_HTTPD_H__
-+#define _UIP_HTTPD_H__
-+
-+void HttpdStart (void);
-+void HttpdHandler (void);
-+
-+/* board specific implementation */
-+extern int do_http_upgrade(const unsigned char *data, const ulong size);
-+
-+#define HTTP_PROGRESS_START 0
-+#define HTTP_PROGRESS_TIMEOUT 1
-+#define HTTP_PROGRESS_UPLOAD_READY 2
-+#define HTTP_PROGRESS_UGRADE_READY 3
-+#define HTTP_PROGRESS_UGRADE_FAILED 4
-+extern int do_http_progress(const int state);
-+
-+#endif
---- a/include/net.h
-+++ b/include/net.h
-@@ -383,7 +383,8 @@ extern int NetTimeOffset; /* offset ti
-
- /* Initialize the network adapter */
- extern int NetLoop(proto_t);
--
-+extern int NetLoopHttpd(void);
-+extern void NetSendHttpd(void);
- /* Shutdown adapters and cleanup */
- extern void NetStop(void);
-
---- a/net/Makefile
-+++ b/net/Makefile
-@@ -26,6 +26,10 @@ include $(TOPDIR)/config.mk
- # CFLAGS += -DDEBUG
-
- LIB = $(obj)libnet.a
-+UIPDIR = uip-0.9
-+RSADIR = uip-0.9
-+$(shell mkdir -p $(obj)$(UIPDIR))
-+$(shell mkdir -p $(obj)$(RSADIR))
-
- COBJS-$(CONFIG_CMD_NET) += bootp.o
- COBJS-$(CONFIG_CMD_DNS) += dns.o
-@@ -36,6 +40,9 @@ COBJS-$(CONFIG_CMD_NET) += rarp.o
- COBJS-$(CONFIG_CMD_SNTP) += sntp.o
- COBJS-$(CONFIG_CMD_NET) += tftp.o
-
-+COBJS-$(CONFIG_CMD_HTTPD) += httpd.o $(UIPDIR)/fs.o $(UIPDIR)/httpd.o $(UIPDIR)/uip_arp.o $(UIPDIR)/uip_arch.o $(UIPDIR)/uip.o
-+COBJS-$(CONFIG_CMD_RSA) += $(RSADIR)/bigint.o $(RSADIR)/base64.o $(RSADIR)/rmd160.o $(RSADIR)/rsa.o
-+
- COBJS := $(COBJS-y)
- SRCS := $(COBJS:.o=.c)
- OBJS := $(addprefix $(obj),$(COBJS))
---- /dev/null
-+++ b/net/httpd.c
-@@ -0,0 +1,52 @@
-+/*
-+ * Copyright 1994, 1995, 2000 Neil Russell.
-+ * (See License)
-+ * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
-+ */
-+
-+#include <common.h>
-+#include <command.h>
-+#include <net.h>
-+#include "uip-0.9/uipopt.h"
-+#include "uip-0.9/uip.h"
-+#include "uip-0.9/uip_arp.h"
-+
-+
-+#if defined(CONFIG_CMD_HTTPD)
-+
-+#define TIMEOUT 5
-+
-+static int arptimer = 0;
-+
-+void
-+HttpdHandler (void)
-+{
-+ int i;
-+ for(i = 0; i < UIP_CONNS; i++) {
-+ uip_periodic(i);
-+ if(uip_len > 0) {
-+ uip_arp_out();
-+ NetSendHttpd();
-+ }
-+ }
-+ if(++arptimer == 20) {
-+ uip_arp_timer();
-+ arptimer = 0;
-+ }
-+}
-+
-+static void
-+HttpdTimeout (void)
-+{
-+ puts ("T ");
-+ NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
-+}
-+
-+void
-+HttpdStart (void)
-+{
-+ uip_init();
-+ httpd_init();
-+}
-+
-+#endif
---- a/net/net.c
-+++ b/net/net.c
-@@ -95,6 +95,19 @@
- #if defined(CONFIG_CMD_DNS)
- #include "dns.h"
- #endif
-+#if defined(CONFIG_CMD_HTTPD)
-+#include "httpd.h"
-+#include "uip-0.9/uipopt.h"
-+#include "uip-0.9/uip.h"
-+#include "uip-0.9/uip_arp.h"
-+static int https_running = 0;
-+int httpd_upload_complete = 0;
-+unsigned char *httpd_upload_data = 0;
-+extern int upload_running;
-+void NetReceiveHttpd(volatile uchar * inpkt, int len);
-+void NetSendHttpd(void);
-+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
-+#endif
-
- DECLARE_GLOBAL_DATA_PTR;
-
-@@ -1308,6 +1321,13 @@ NetReceive(volatile uchar * inpkt, int l
-
- debug("packet received\n");
-
-+#if defined(CONFIG_CMD_HTTPD)
-+ if(https_running) {
-+ NetReceiveHttpd(inpkt, len);
-+ return;
-+ }
-+#endif
-+
- NetRxPacket = inpkt;
- NetRxPacketLen = len;
- et = (Ethernet_t *)inpkt;
-@@ -1922,3 +1942,162 @@ ushort getenv_VLAN(char *var)
- {
- return (string_to_VLAN(getenv(var)));
- }
-+
-+#if defined(CONFIG_CMD_HTTPD)
-+
-+void
-+NetSendHttpd(void)
-+{
-+ volatile uchar *tmpbuf = NetTxPacket;
-+ int i;
-+
-+ for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
-+ tmpbuf[i] = uip_buf[i];
-+ }
-+
-+ for(; i < uip_len; i++) {
-+ tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
-+ }
-+ eth_send(NetTxPacket, uip_len);
-+}
-+
-+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
-+
-+void
-+NetReceiveHttpd(volatile uchar * inpkt, int len)
-+{
-+ memcpy(uip_buf, inpkt, len);
-+ uip_len = len;
-+ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
-+ uip_arp_ipin();
-+ uip_input();
-+ if(uip_len > 0) {
-+ uip_arp_out();
-+ NetSendHttpd();
-+ }
-+ } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
-+ uip_arp_arpin();
-+ if(uip_len > 0) {
-+ NetSendHttpd();
-+ }
-+ }
-+}
-+
-+int
-+NetLoopHttpd(void)
-+{
-+ unsigned long long tout = 0;
-+ bd_t *bd = gd->bd;
-+ unsigned short int ip[2];
-+
-+#ifdef CONFIG_NET_MULTI
-+ NetRestarted = 0;
-+ NetDevExists = 0;
-+#endif
-+
-+ /* XXX problem with bss workaround */
-+ NetArpWaitPacketMAC = NULL;
-+ NetArpWaitTxPacket = NULL;
-+ NetArpWaitPacketIP = 0;
-+ NetArpWaitReplyIP = 0;
-+ NetArpWaitTxPacket = NULL;
-+ NetTxPacket = NULL;
-+ NetTryCount = 1;
-+
-+ if (!NetTxPacket) {
-+ int i;
-+ /*
-+ * Setup packet buffers, aligned correctly.
-+ */
-+ NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
-+ NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
-+ for (i = 0; i < PKTBUFSRX; i++) {
-+ NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
-+ }
-+ }
-+
-+ if (!NetArpWaitTxPacket) {
-+ NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
-+ NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
-+ NetArpWaitTxPacketSize = 0;
-+ }
-+
-+restart:
-+
-+ eth_halt();
-+#ifdef CONFIG_NET_MULTI
-+ eth_set_current();
-+#endif
-+ if (eth_init(bd) < 0) {
-+ eth_halt();
-+ return(-1);
-+ }
-+
-+#ifdef CONFIG_NET_MULTI
-+ memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);
-+#else
-+ eth_getenv_enetaddr("ethaddr", NetOurEther);
-+#endif
-+
-+ NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
-+ NetOurGatewayIP = getenv_IPaddr ("gatewayip");
-+ NetOurSubnetMask= getenv_IPaddr ("netmask");
-+ NetOurVLAN = getenv_VLAN("vlan");
-+ NetOurNativeVLAN = getenv_VLAN("nvlan");
-+
-+ printf("starting httpd server from server %ld.%ld.%ld.%ld\n",
-+ (bd->bi_ip_addr & 0xff000000) >> 24,
-+ (bd->bi_ip_addr & 0x00ff0000) >> 16,
-+ (bd->bi_ip_addr & 0x0000ff00) >> 8,
-+ (bd->bi_ip_addr & 0x000000ff));
-+
-+ HttpdStart();
-+
-+ ip[0] = ((bd->bi_ip_addr & 0xffff0000) >> 16);
-+ ip[1] = (bd->bi_ip_addr & 0x0000ffff);
-+ uip_sethostaddr(ip);
-+
-+ do_http_progress(HTTP_PROGRESS_START);
-+
-+ https_running = 1;
-+ for (;;) {
-+ unsigned long long t1;
-+ WATCHDOG_RESET();
-+ if(eth_rx() > 0) {
-+ HttpdHandler();
-+ } else {
-+ t1 = get_ticks();
-+ if(t1 - tout > 1000) {
-+ do_http_progress(HTTP_PROGRESS_TIMEOUT);
-+ tout = t1;
-+ }
-+ }
-+ if(!httpd_upload_complete)
-+ continue;
-+ printf("Bytes transferred = %ld (%lx hex)\n",
-+ NetBootFileXferSize,
-+ NetBootFileXferSize);
-+ eth_halt();
-+ do_http_progress(HTTP_PROGRESS_UPLOAD_READY);
-+ if(do_http_upgrade(&httpd_upload_data[0], NetBootFileXferSize) == 0) {
-+ do_http_progress(HTTP_PROGRESS_UGRADE_READY);
-+ udelay(1000 * 10);
-+ do_reset (0,0,0,0);
-+ return 0;
-+ }
-+ break;
-+ }
-+ https_running = 0;
-+ NetBootFileXferSize = 0;
-+ httpd_upload_complete = 0;
-+ upload_running = 0;
-+// free(httpd_upload_data);
-+
-+ do_http_progress(HTTP_PROGRESS_UGRADE_FAILED);
-+
-+ goto restart;
-+
-+ return -1;
-+}
-+
-+#endif
---- /dev/null
-+++ b/net/rsa/Makefile
-@@ -0,0 +1,31 @@
-+#
-+# FONRSA & FONSIGN libraries unit testing
-+#
-+# This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+#
-+# Execute in this directory
-+#
-+# Created: 20070422 Pablo Martin Medrano <pablo@fon.com>
-+#
-+# $Id: Makefile 389 2007-06-11 08:29:56Z pablo.martin $
-+#
-+# FIXME: Put this in the main Makefile.am
-+#
-+all: fonsign dump_key
-+
-+fonsign:
-+ gcc -g sign_openssl.c -D__MAINTEST__ -o fonsign -lssl
-+
-+dump_key:
-+ gcc -o dump_key dump_key.c
-+ ./dump_key > public_key.h
-+
-+foncheckrsa:
-+ gcc -g bigint.c fonrsa.c rmd160.c foncheckrsa.c base64.c log.c -o foncheckrsa
-+
-+#private_fon_rsa_key.pem:
-+# openssl genrsa -out private_fon_rsa_key.pem 4096
-+# openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
-+
-+clean:
-+ rm fonsign dump_key
---- /dev/null
-+++ b/net/rsa/base64.c
-@@ -0,0 +1,137 @@
-+#include "base64.h"
-+
-+static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-+/* Note that '=' (padding) is 0 */
-+static const unsigned char fb64[256] = {
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
-+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
-+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
-+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
-+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-+};
-+
-+static int encodeblock( unsigned char *in, char *out, int len )
-+{
-+ char s[3];
-+ int i;
-+
-+ for (i = 0; i < len; i++)
-+ s[i] = in[i];
-+ for (i = len; i < 3; i++)
-+ s[i] = 0;
-+ out[0] = (unsigned char)(cb64[(s[0] & 0xfc) >> 2 ]);
-+ out[1] = (unsigned char)(cb64[((s[0] & 0x03) << 4) | ((s[1] & 0xf0) >> 4) ]);
-+ out[2] = (unsigned char)(cb64[((s[1] & 0x0f) << 2) | ((s[2] & 0xc0) >> 6) ]);
-+ out[3] = (unsigned char)(cb64[s[2] & 0x3f ]);
-+ switch (len) {
-+ case 1:
-+ out[3] = '=';
-+ case 2:
-+ out[2] = '=';
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return 4;
-+}
-+
-+static int decodeblock(char *ins, unsigned char *out, int len)
-+{
-+ int i;
-+ unsigned char in[4];
-+ int skip = 0;
-+
-+ if (len != 4)
-+ return -1;
-+ for (i = 0; i < len; i++) {
-+ if (ins[i] == '=') {
-+ in[i] = 0;
-+ skip++;
-+ } else
-+ in[i] = fb64[(int)(ins[i])];
-+ if (in[i] == 255) {
-+ return -1;
-+ }
-+ }
-+ out[0] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
-+ if (skip == 2) {
-+ return 1;
-+ }
-+ out[1] = (unsigned char )((in[1] & 0x0f) << 4 | in[2] >> 2);
-+ if (skip == 1) {
-+ return 2;
-+ }
-+ out[2] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
-+
-+ return 3;
-+}
-+
-+int B64_encode(char *source, char *destination, int size_source, int size_destination)
-+{
-+ int chunks, reminder, size, d, i, size_expected;
-+ char *s;
-+ unsigned char *t;
-+
-+ chunks = size_source / 3;
-+ reminder = size_source % 3;
-+ size = 0;
-+ size_expected = (chunks * 4) + (reminder?(reminder + 1):0);
-+ if (size_destination < ((chunks * 4) + (reminder?4:0))) {
-+ return 1;
-+ }
-+ for (i = 0; i < chunks; i++) {
-+ s = source + (i * 3);
-+ t = destination + (i * 4);
-+ d = encodeblock(s, t, 3);
-+ if (d == -1) {
-+ return 1;
-+ }
-+ size += d;
-+ }
-+ if (reminder) {
-+ d = encodeblock(source + (chunks * 3), destination + (chunks * 4), reminder);
-+ if (d == -1) {
-+ return 1;
-+ }
-+ size += d;
-+ }
-+ return size;
-+}
-+
-+int B64_decode(char *source, char *destination, int size_source, int size_destination)
-+{
-+ int chunks, reminder, size, d, i;
-+
-+ chunks = size_source / 4;
-+ reminder = size_source % 4;
-+ size = 0;
-+ if (reminder) {
-+ return 1;
-+ }
-+ if (size_destination < ((chunks * 3))) {
-+ printf("%d, %d\n",
-+ size_destination, ((chunks * 3) + reminder));
-+ return -1;
-+ }
-+ for (i = 0; i < chunks; i++) {
-+ d = decodeblock(source + (i * 4), destination + (i * 3), 4);
-+ if (d == -1) {
-+ return -1;
-+ }
-+ size += d;
-+ }
-+ return size;
-+}
-+
---- /dev/null
-+++ b/net/rsa/base64.h
-@@ -0,0 +1,11 @@
-+#ifndef _BASE64_H_
-+#define _BASE64_H_
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+int B64_encode(char *source, char *destination, int size_source, int size_destination);
-+int B64_decode(char *source, char *destination, int size_source, int size_destination);
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif
---- /dev/null
-+++ b/net/rsa/bigint.c
-@@ -0,0 +1,906 @@
-+/*
-+ * Copyright(C) 2006
-+ *
-+ * This library is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License as published by
-+ * the Free Software Foundation; either version 2.1 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+/**
-+ * @defgroup bigint_api Big Integer API
-+ * @brief The bigint implementation as used by the axTLS project.
-+ *
-+ * The bigint library is for RSA encryption/decryption as well as signing.
-+ * This code tries to minimise use of malloc/free by maintaining a small
-+ * cache. A bigint context may maintain state by being made "permanent".
-+ * It be be later released with a bi_depermanent() and bi_free() call.
-+ *
-+ * It supports the following reduction techniques:
-+ * - Classical
-+ * - Barrett
-+ * - Montgomery
-+ *
-+ * It also implements the following:
-+ * - Karatsuba multiplication
-+ * - Squaring
-+ * - Sliding window exponentiation
-+ * - Chinese Remainder Theorem (implemented in rsa.c).
-+ *
-+ * All the algorithms used are pretty standard, and designed for different
-+ * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
-+ * may need to be tested for negativity.
-+ *
-+ * This library steals some ideas from Jef Poskanzer
-+ * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
-+ * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
-+ * detail from "The Handbook of Applied Cryptography"
-+ * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
-+ * @{
-+ */
-+
-+#include "bigint.h"
-+#include <malloc.h>
-+#include "div64.h"
-+
-+static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
-+static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
-+static bigint *alloc(BI_CTX *ctx, int size);
-+static bigint *trim(bigint *bi);
-+static void more_comps(bigint *bi, int n);
-+
-+/**
-+ * @brief Start a new bigint context.
-+ * @return A bigint context.
-+ */
-+BI_CTX *bi_initialize(void)
-+{
-+ BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
-+
-+ ctx->active_list = NULL;
-+ ctx->active_count = 0;
-+ ctx->free_list = NULL;
-+ ctx->free_count = 0;
-+ ctx->mod_offset = 0;
-+
-+ /* the radix */
-+ ctx->bi_radix = alloc(ctx, 2);
-+ ctx->bi_radix->comps[0] = 0;
-+ ctx->bi_radix->comps[1] = 1;
-+ bi_permanent(ctx->bi_radix);
-+
-+ return ctx;
-+}
-+
-+/**
-+ * @brief Close the bigint context and free any resources.
-+ *
-+ * Free up any used memory - a check is done if all objects were not
-+ * properly freed.
-+ * @param ctx [in] The bigint session context.
-+ */
-+void bi_terminate(BI_CTX *ctx)
-+{
-+ bigint *p, *pn;
-+
-+ bi_depermanent(ctx->bi_radix);
-+ bi_free(ctx, ctx->bi_radix);
-+
-+ if (ctx->active_count != 0)
-+ {
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ return;
-+ }
-+
-+ for (p = ctx->free_list; p != NULL; p = pn)
-+ {
-+ pn = p->next;
-+ free(p->comps);
-+ free(p);
-+ }
-+
-+ free(ctx);
-+}
-+
-+/**
-+ * @brief Increment the number of references to this object.
-+ * It does not do a full copy.
-+ * @param bi [in] The bigint to copy.
-+ * @return A referent to the same bigint.
-+ */
-+bigint *bi_copy(bigint *bi)
-+{
-+ check(bi);
-+ if (bi->refs != PERMANENT)
-+ bi->refs++;
-+ return bi;
-+}
-+
-+/**
-+ * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
-+ *
-+ * For this object to be freed, bi_depermanent() must be called.
-+ * @param bi [in] The bigint to be made permanent.
-+ */
-+void bi_permanent(bigint *bi)
-+{
-+ check(bi);
-+ if (bi->refs != 1)
-+ {
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ return;
-+ }
-+
-+ bi->refs = PERMANENT;
-+}
-+
-+/**
-+ * @brief Take a permanent object and make it elligible for freedom.
-+ * @param bi [in] The bigint to be made back to temporary.
-+ */
-+void bi_depermanent(bigint *bi)
-+{
-+ check(bi);
-+ if (bi->refs != PERMANENT)
-+ {
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ return;
-+ }
-+
-+ bi->refs = 1;
-+}
-+
-+/**
-+ * @brief Free a bigint object so it can be used again.
-+ *
-+ * The memory itself it not actually freed, just tagged as being available
-+ * @param ctx [in] The bigint session context.
-+ * @param bi [in] The bigint to be freed.
-+ */
-+void bi_free(BI_CTX *ctx, bigint *bi)
-+{
-+ check(bi);
-+ if (bi->refs == PERMANENT)
-+ {
-+ return;
-+ }
-+
-+ if (--bi->refs > 0)
-+ {
-+ return;
-+ }
-+
-+ bi->next = ctx->free_list;
-+ ctx->free_list = bi;
-+ ctx->free_count++;
-+
-+ if (--ctx->active_count < 0)
-+ {
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ return;
-+ }
-+}
-+
-+/**
-+ * @brief Convert an (unsigned) integer into a bigint.
-+ * @param ctx [in] The bigint session context.
-+ * @param i [in] The (unsigned) integer to be converted.
-+ *
-+ */
-+bigint *int_to_bi(BI_CTX *ctx, comp i)
-+{
-+ bigint *biR = alloc(ctx, 1);
-+ biR->comps[0] = i;
-+ return biR;
-+}
-+
-+/**
-+ * @brief Do a full copy of the bigint object.
-+ * @param ctx [in] The bigint session context.
-+ * @param bi [in] The bigint object to be copied.
-+ */
-+bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
-+{
-+ bigint *biR = alloc(ctx, bi->size);
-+ check(bi);
-+ memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
-+ return biR;
-+}
-+
-+/**
-+ * @brief Perform an additon operation between two bigints.
-+ * @param ctx [in] The bigint session context.
-+ * @param bia [in] A bigint.
-+ * @param bib [in] Another bigint.
-+ * @return The result of the addition.
-+ */
-+bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
-+{
-+ int n;
-+ comp carry = 0;
-+ comp *pa, *pb;
-+
-+ check(bia);
-+ check(bib);
-+
-+ if (bia->size > bib->size)
-+ n = bia->size;
-+ else
-+ n = bib->size;
-+ more_comps(bia, n+1);
-+ more_comps(bib, n);
-+ pa = bia->comps;
-+ pb = bib->comps;
-+
-+ do
-+ {
-+ comp sl, rl, cy1;
-+ sl = *pa + *pb++;
-+ rl = sl + carry;
-+ cy1 = sl < *pa;
-+ carry = cy1 | (rl < sl);
-+ *pa++ = rl;
-+ } while (--n != 0);
-+
-+ *pa = carry; /* do overflow */
-+ bi_free(ctx, bib);
-+ return trim(bia);
-+}
-+
-+/**
-+ * @brief Perform a subtraction operation between two bigints.
-+ * @param ctx [in] The bigint session context.
-+ * @param bia [in] A bigint.
-+ * @param bib [in] Another bigint.
-+ * @param is_negative [out] If defined, indicates that the result was negative.
-+ * is_negative may be NULL.
-+ * @return The result of the subtraction. The result is always positive.
-+ */
-+bigint *bi_subtract(BI_CTX *ctx,
-+ bigint *bia, bigint *bib, int *is_negative)
-+{
-+ int n = bia->size;
-+ comp *pa, *pb, carry = 0;
-+
-+ check(bia);
-+ check(bib);
-+
-+ more_comps(bib, n);
-+ pa = bia->comps;
-+ pb = bib->comps;
-+
-+ do
-+ {
-+ comp sl, rl, cy1;
-+ sl = *pa - *pb++;
-+ rl = sl - carry;
-+ cy1 = sl > *pa;
-+ carry = cy1 | (rl > sl);
-+ *pa++ = rl;
-+ } while (--n != 0);
-+
-+ if (is_negative) /* indicate a negative result */
-+ {
-+ *is_negative = carry;
-+ }
-+
-+ bi_free(ctx, trim(bib)); /* put bib back to the way it was */
-+ return trim(bia);
-+}
-+
-+/**
-+ * Perform a multiply between a bigint an an (unsigned) integer
-+ */
-+static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
-+{
-+ int j = 0, n = bia->size;
-+ bigint *biR = alloc(ctx, n + 1);
-+ comp carry = 0;
-+ comp *r = biR->comps;
-+ comp *a = bia->comps;
-+
-+ check(bia);
-+
-+ /* clear things to start with */
-+ memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
-+
-+ do
-+ {
-+ long_comp tmp = *r + (long_comp)a[j]*b + carry;
-+ *r++ = (comp)tmp; /* downsize */
-+ carry = (comp)(tmp >> COMP_BIT_SIZE);
-+ } while (++j < n);
-+
-+ *r = carry;
-+ bi_free(ctx, bia);
-+ return trim(biR);
-+}
-+
-+/**
-+ * @brief Does both division and modulo calculations.
-+ *
-+ * Used extensively when doing classical reduction.
-+ * @param ctx [in] The bigint session context.
-+ * @param u [in] A bigint which is the numerator.
-+ * @param v [in] Either the denominator or the modulus depending on the mode.
-+ * @param is_mod [n] Determines if this is a normal division (0) or a reduction
-+ * (1).
-+ * @return The result of the division/reduction.
-+ */
-+bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
-+{
-+ int n = v->size, m = u->size-n;
-+ int j = 0, orig_u_size = u->size;
-+ uint8_t mod_offset = ctx->mod_offset;
-+ comp d;
-+ bigint *quotient, *tmp_u;
-+ comp q_dash;
-+
-+ check(u);
-+ check(v);
-+
-+ /* if doing reduction and we are < mod, then return mod */
-+ if (is_mod && bi_compare(v, u) > 0)
-+ {
-+ bi_free(ctx, v);
-+ return u;
-+ }
-+
-+ quotient = alloc(ctx, m+1);
-+ tmp_u = alloc(ctx, n+1);
-+ v = trim(v); /* make sure we have no leading 0's */
-+ // d = (comp)((long_comp)COMP_RADIX/(V1+1));
-+ long_comp x = COMP_RADIX; do_div(x, V1+1); d = x;
-+
-+ /* clear things to start with */
-+ memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
-+
-+ /* normalise */
-+ if (d > 1)
-+ {
-+ u = bi_int_multiply(ctx, u, d);
-+
-+ if (is_mod)
-+ {
-+ v = ctx->bi_normalised_mod[mod_offset];
-+ }
-+ else
-+ {
-+ v = bi_int_multiply(ctx, v, d);
-+ }
-+ }
-+
-+ if (orig_u_size == u->size) /* new digit position u0 */
-+ {
-+ more_comps(u, orig_u_size + 1);
-+ }
-+
-+ do
-+ {
-+ /* get a temporary short version of u */
-+ memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
-+
-+ /* calculate q' */
-+ if (U(0) == V1)
-+ {
-+ q_dash = COMP_RADIX-1;
-+ }
-+ else
-+ {
-+ //q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
-+ long_comp x = U(0)*COMP_RADIX + U(1); do_div(x, V1); q_dash = x;
-+
-+ }
-+
-+ if (v->size > 1 && V2)
-+ {
-+ /* we are implementing the following
-+ if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
-+ q_dash*V1)*COMP_RADIX) + U(2))) ... */
-+ comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
-+ (long_comp)q_dash*V1);
-+ if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
-+ {
-+ q_dash--;
-+ }
-+ }
-+
-+ /* multiply and subtract */
-+ if (q_dash)
-+ {
-+ int is_negative;
-+ tmp_u = bi_subtract(ctx, tmp_u,
-+ bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
-+ more_comps(tmp_u, n+1);
-+
-+ Q(j) = q_dash;
-+
-+ /* add back */
-+ if (is_negative)
-+ {
-+ Q(j)--;
-+ tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
-+ /* lop off the carry */
-+ tmp_u->size--;
-+ v->size--;
-+ }
-+ }
-+ else
-+ {
-+ Q(j) = 0;
-+ }
-+
-+ /* copy back to u */
-+ memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
-+ } while (++j <= m);
-+
-+ bi_free(ctx, tmp_u);
-+ bi_free(ctx, v);
-+
-+ if (is_mod) /* get the remainder */
-+ {
-+ bi_free(ctx, quotient);
-+ return bi_int_divide(ctx, trim(u), d);
-+ }
-+ else /* get the quotient */
-+ {
-+ bi_free(ctx, u);
-+ return trim(quotient);
-+ }
-+}
-+
-+/**
-+ * Perform an integer divide on a bigint.
-+ */
-+static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom)
-+{
-+ int i = biR->size - 1;
-+ long_comp r = 0;
-+
-+ check(biR);
-+
-+ do
-+ {
-+ r = (r<<COMP_BIT_SIZE) + biR->comps[i];
-+ //biR->comps[i] = (comp)(r / denom);
-+ long_comp x = r; do_div(x, denom); biR->comps[i] = x;
-+/* while(r > denom)
-+ {
-+ r -= denom;
-+ }*/
-+ r%=denom;
-+ } while (--i != 0);
-+
-+ return trim(biR);
-+}
-+
-+/**
-+ * @brief Allow a binary sequence to be imported as a bigint.
-+ * @param ctx [in] The bigint session context.
-+ * @param data [in] The data to be converted.
-+ * @param size [in] The number of bytes of data.
-+ * @return A bigint representing this data.
-+ */
-+bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
-+{
-+ bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
-+ int i, j = 0, offset = 0;
-+
-+ memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
-+
-+ for (i = size-1; i >= 0; i--)
-+ {
-+ biR->comps[offset] += data[i] << (j*8);
-+
-+ if (++j == COMP_BYTE_SIZE)
-+ {
-+ j = 0;
-+ offset ++;
-+ }
-+ }
-+
-+ return trim(biR);
-+}
-+
-+/**
-+ * @brief Take a bigint and convert it into a byte sequence.
-+ *
-+ * This is useful after a decrypt operation.
-+ * @param ctx [in] The bigint session context.
-+ * @param x [in] The bigint to be converted.
-+ * @param data [out] The converted data as a byte stream.
-+ * @param size [in] The maximum size of the byte stream. Unused bytes will be
-+ * zeroed.
-+ */
-+void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
-+{
-+ int i, j, k = size-1;
-+
-+ check(x);
-+ memset(data, 0, size); /* ensure all leading 0's are cleared */
-+
-+ for (i = 0; i < x->size; i++)
-+ {
-+ for (j = 0; j < COMP_BYTE_SIZE; j++)
-+ {
-+ comp mask = 0xff << (j*8);
-+ int num = (x->comps[i] & mask) >> (j*8);
-+ data[k--] = num;
-+
-+ if (k < 0)
-+ {
-+ break;
-+ }
-+ }
-+ }
-+
-+ bi_free(ctx, x);
-+}
-+
-+/**
-+ * @brief Pre-calculate some of the expensive steps in reduction.
-+ *
-+ * This function should only be called once (normally when a session starts).
-+ * When the session is over, bi_free_mod() should be called. bi_mod_power()
-+ * relies on this function being called.
-+ * @param ctx [in] The bigint session context.
-+ * @param bim [in] The bigint modulus that will be used.
-+ * @param mod_offset [in] There are three moduluii that can be stored - the
-+ * standard modulus, and it's two primes p and q. This offset refers to which
-+ * modulus we are referring to.
-+ * @see bi_free_mod(), bi_mod_power().
-+ */
-+void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
-+{
-+ int k = bim->size;
-+ comp d;
-+// comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
-+ long_comp x = COMP_RADIX; do_div(x, bim->comps[k-1]+1); d = x;
-+
-+ ctx->bi_mod[mod_offset] = bim;
-+ bi_permanent(ctx->bi_mod[mod_offset]);
-+ ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
-+ bi_permanent(ctx->bi_normalised_mod[mod_offset]);
-+}
-+
-+/**
-+ * @brief Used when cleaning various bigints at the end of a session.
-+ * @param ctx [in] The bigint session context.
-+ * @param mod_offset [in] The offset to use.
-+ * @see bi_set_mod().
-+ */
-+void bi_free_mod(BI_CTX *ctx, int mod_offset)
-+{
-+ bi_depermanent(ctx->bi_mod[mod_offset]);
-+ bi_free(ctx, ctx->bi_mod[mod_offset]);
-+ bi_depermanent(ctx->bi_normalised_mod[mod_offset]);
-+ bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
-+}
-+
-+/**
-+ * Perform a standard multiplication between two bigints.
-+ */
-+static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
-+{
-+ int i, j, i_plus_j, n = bia->size, t = bib->size;
-+ bigint *biR = alloc(ctx, n + t);
-+ comp *sr = biR->comps;
-+ comp *sa = bia->comps;
-+ comp *sb = bib->comps;
-+
-+ check(bia);
-+ check(bib);
-+
-+ /* clear things to start with */
-+ memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
-+ i = 0;
-+
-+ do
-+ {
-+ comp carry = 0;
-+ comp b = *sb++;
-+ i_plus_j = i;
-+ j = 0;
-+
-+ do
-+ {
-+ long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
-+ sr[i_plus_j++] = (comp)tmp; /* downsize */
-+ carry = (comp)(tmp >> COMP_BIT_SIZE);
-+ } while (++j < n);
-+
-+ sr[i_plus_j] = carry;
-+ } while (++i < t);
-+
-+ bi_free(ctx, bia);
-+ bi_free(ctx, bib);
-+ return trim(biR);
-+}
-+
-+/**
-+ * @brief Perform a multiplication operation between two bigints.
-+ * @param ctx [in] The bigint session context.
-+ * @param bia [in] A bigint.
-+ * @param bib [in] Another bigint.
-+ * @return The result of the multiplication.
-+ */
-+bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
-+{
-+ check(bia);
-+ check(bib);
-+
-+ return regular_multiply(ctx, bia, bib);
-+}
-+
-+
-+/**
-+ * @brief Compare two bigints.
-+ * @param bia [in] A bigint.
-+ * @param bib [in] Another bigint.
-+ * @return -1 if smaller, 1 if larger and 0 if equal.
-+ */
-+int bi_compare(bigint *bia, bigint *bib)
-+{
-+ int r, i;
-+
-+ check(bia);
-+ check(bib);
-+
-+ if (bia->size > bib->size)
-+ r = 1;
-+ else if (bia->size < bib->size)
-+ r = -1;
-+ else
-+ {
-+ comp *a = bia->comps;
-+ comp *b = bib->comps;
-+
-+ /* Same number of components. Compare starting from the high end
-+ * and working down. */
-+ r = 0;
-+ i = bia->size - 1;
-+
-+ do
-+ {
-+ if (a[i] > b[i])
-+ {
-+ r = 1;
-+ break;
-+ }
-+ else if (a[i] < b[i])
-+ {
-+ r = -1;
-+ break;
-+ }
-+ } while (--i >= 0);
-+ }
-+
-+ return r;
-+}
-+
-+/**
-+ * Allocate and zero more components. Does not consume bi.
-+ */
-+static void more_comps(bigint *bi, int n)
-+{
-+ if (n > bi->max_comps)
-+ {
-+ if ((bi->max_comps * 2) > n) {
-+ bi->max_comps = bi->max_comps * 2;
-+ } else {
-+ bi->max_comps = n;
-+ }
-+ bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
-+ }
-+
-+ if (n > bi->size)
-+ {
-+ memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
-+ }
-+
-+ bi->size = n;
-+}
-+
-+/*
-+ * Make a new empty bigint. It may just use an old one if one is available.
-+ * Otherwise get one of the heap.
-+ */
-+static bigint *alloc(BI_CTX *ctx, int size)
-+{
-+ bigint *biR;
-+
-+ /* Can we recycle an old bigint? */
-+ if (ctx->free_list != NULL)
-+ {
-+ biR = ctx->free_list;
-+ ctx->free_list = biR->next;
-+ ctx->free_count--;
-+ if (biR->refs != 0)
-+ {
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ return 0;
-+ }
-+
-+ more_comps(biR, size);
-+ }
-+ else
-+ {
-+ /* No free bigints available - create a new one. */
-+ biR = (bigint *)malloc(sizeof(bigint));
-+ biR->comps = (comp*) malloc(size * COMP_BYTE_SIZE);
-+ biR->max_comps = size; /* give some space to spare */
-+ }
-+
-+ biR->size = size;
-+ biR->refs = 1;
-+ biR->next = NULL;
-+ ctx->active_count++;
-+ return biR;
-+}
-+
-+/*
-+ * Work out the highest '1' bit in an exponent. Used when doing sliding-window
-+ * exponentiation.
-+ */
-+static int find_max_exp_index(bigint *biexp)
-+{
-+ int i = COMP_BIT_SIZE-1;
-+ comp shift = COMP_RADIX/2;
-+ comp test = biexp->comps[biexp->size-1]; /* assume no leading zeroes */
-+
-+ check(biexp);
-+
-+ do
-+ {
-+ if (test & shift)
-+ {
-+ return i+(biexp->size-1)*COMP_BIT_SIZE;
-+ }
-+
-+ shift >>= 1;
-+ } while (--i != 0);
-+
-+ return -1; /* error - must have been a leading 0 */
-+}
-+
-+/*
-+ * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
-+ * exponentiation.
-+ */
-+static int exp_bit_is_one(bigint *biexp, int offset)
-+{
-+ comp test = biexp->comps[offset / COMP_BIT_SIZE];
-+ int num_shifts = offset % COMP_BIT_SIZE;
-+ comp shift = 1;
-+ int i;
-+
-+ check(biexp);
-+
-+ for (i = 0; i < num_shifts; i++)
-+ {
-+ shift <<= 1;
-+ }
-+
-+ return test & shift;
-+}
-+
-+/*
-+ * Delete any leading 0's (and allow for 0).
-+ */
-+static bigint *trim(bigint *bi)
-+{
-+ check(bi);
-+
-+ while (bi->comps[bi->size-1] == 0 && bi->size > 1)
-+ {
-+ bi->size--;
-+ }
-+
-+ return bi;
-+}
-+
-+/**
-+ * @brief Perform a modular exponentiation.
-+ *
-+ * This function requires bi_set_mod() to have been called previously. This is
-+ * one of the optimisations used for performance.
-+ * @param ctx [in] The bigint session context.
-+ * @param bi [in] The bigint on which to perform the mod power operation.
-+ * @param biexp [in] The bigint exponent.
-+ * @see bi_set_mod().
-+ */
-+bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
-+{
-+ int i = find_max_exp_index(biexp), j, window_size = 1;
-+ bigint *biR = int_to_bi(ctx, 1);
-+
-+ check(bi);
-+ check(biexp);
-+
-+ ctx->g = (bigint **)malloc(sizeof(bigint *));
-+ ctx->g[0] = bi_clone(ctx, bi);
-+ ctx->window = 1;
-+ bi_permanent(ctx->g[0]);
-+
-+ /* if sliding-window is off, then only one bit will be done at a time and
-+ * will reduce to standard left-to-right exponentiation */
-+ do
-+ {
-+ if (exp_bit_is_one(biexp, i))
-+ {
-+ int l = i-window_size+1;
-+ int part_exp = 0;
-+
-+ if (l < 0) /* LSB of exponent will always be 1 */
-+ {
-+ l = 0;
-+ }
-+ else
-+ {
-+ while (exp_bit_is_one(biexp, l) == 0)
-+ {
-+ l++; /* go back up */
-+ }
-+ }
-+
-+ /* build up the section of the exponent */
-+ for (j = i; j >= l; j--)
-+ {
-+ biR = bi_residue(ctx, bi_square(ctx, biR));
-+ if (exp_bit_is_one(biexp, j))
-+ part_exp++;
-+
-+ if (j != l)
-+ part_exp <<= 1;
-+ }
-+
-+ part_exp = (part_exp-1)/2; /* adjust for array */
-+ biR = bi_residue(ctx,
-+ bi_multiply(ctx, biR, ctx->g[part_exp]));
-+ i = l-1;
-+ }
-+ else /* square it */
-+ {
-+ biR = bi_residue(ctx, bi_square(ctx, biR));
-+ i--;
-+ }
-+ } while (i >= 0);
-+
-+ /* cleanup */
-+ for (i = 0; i < ctx->window; i++)
-+ {
-+ bi_depermanent(ctx->g[i]);
-+ bi_free(ctx, ctx->g[i]);
-+ }
-+
-+ free(ctx->g);
-+ bi_free(ctx, bi);
-+ bi_free(ctx, biexp);
-+ return biR;
-+}
-+
-+/** @} */
---- /dev/null
-+++ b/net/rsa/bigint.h
-@@ -0,0 +1,73 @@
-+/*
-+ * Copyright(C) 2006
-+ *
-+ * This library is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Trimmed down from axTLS
-+ *
-+ * $Id: bigint.h 392 2007-06-25 16:24:51Z pablo.martin $
-+ *
-+ */
-+
-+#ifndef BIGINT_HEADER
-+#define BIGINT_HEADER
-+
-+#define CONFIG_BIGINT_CLASSICAL 1
-+
-+#define SOCKET_READ(A,B,C) read(A,B,C)
-+#define SOCKET_WRITE(A,B,C) write(A,B,C)
-+#define SOCKET_CLOSE(A) close(A)
-+#define TTY_FLUSH()
-+
-+#include "bigint_impl.h"
-+
-+#ifndef CONFIG_BIGINT_CHECK_ON
-+#define check(A) /**< disappears in normal production mode */
-+#endif
-+BI_CTX *bi_initialize(void);
-+void bi_terminate(BI_CTX *ctx);
-+void bi_permanent(bigint *bi);
-+void bi_depermanent(bigint *bi);
-+void bi_free(BI_CTX *ctx, bigint *bi);
-+bigint *bi_copy(bigint *bi);
-+bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
-+void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size);
-+bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len);
-+bigint *int_to_bi(BI_CTX *ctx, comp i);
-+
-+/* the functions that actually do something interesting */
-+bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib);
-+bigint *bi_subtract(BI_CTX *ctx, bigint *bia,
-+ bigint *bib, int *is_negative);
-+bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod);
-+bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib);
-+bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp);
-+bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp);
-+int bi_compare(bigint *bia, bigint *bib);
-+void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset);
-+void bi_free_mod(BI_CTX *ctx, int mod_offset);
-+
-+/**
-+ * @def bi_mod
-+ * Find the residue of B. bi_set_mod() must be called before hand.
-+ */
-+#define bi_mod(A, B) bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1)
-+
-+#define bi_residue(A, B) bi_mod(A, B)
-+
-+#define bi_square(A, B) bi_multiply(A, bi_copy(B), B)
-+
-+#endif
-+
---- /dev/null
-+++ b/net/rsa/bigint_impl.h
-@@ -0,0 +1,109 @@
-+/*
-+ * Copyright(C) 2006
-+ *
-+ * This library is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License as published by
-+ * the Free Software Foundation; either version 2.1 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#ifndef BIGINT_IMPL_HEADER
-+#define BIGINT_IMPL_HEADER
-+
-+#include <linux/types.h>
-+#include <common.h>
-+
-+/* Maintain a number of precomputed variables when doing reduction */
-+#define BIGINT_M_OFFSET 0 /**< Normal modulo offset. */
-+#ifdef CONFIG_BIGINT_CRT
-+#define BIGINT_P_OFFSET 1 /**< p modulo offset. */
-+#define BIGINT_Q_OFFSET 2 /**< q module offset. */
-+#define BIGINT_NUM_MODS 3 /**< The number of modulus constants used. */
-+#else
-+#define BIGINT_NUM_MODS 1
-+#endif
-+
-+/* Architecture specific functions for big ints */
-+// #ifdef WIN32
-+// #define COMP_RADIX 4294967296i64
-+// #define COMP_BIG_MSB 0x8000000000000000i64
-+// #else
-+#define COMP_RADIX 4294967296ULL /**< Max component + 1 */
-+#define COMP_BIG_MSB 0x8000000000000000ULL /**< (Max dbl comp + 1)/ 2 */
-+//#endif
-+#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */
-+#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */
-+#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */
-+
-+typedef uint32_t comp; /**< A single precision component. */
-+typedef uint64_t long_comp; /**< A double precision component. */
-+typedef int64_t slong_comp; /**< A signed double precision component. */
-+
-+/**
-+ * @struct _bigint
-+ * @brief A big integer basic object
-+ */
-+struct _bigint
-+{
-+ struct _bigint* next; /**< The next bigint in the cache. */
-+ short size; /**< The number of components in this bigint. */
-+ short max_comps; /**< The heapsize allocated for this bigint */
-+ int refs; /**< An internal reference count. */
-+ comp* comps; /**< A ptr to the actual component data */
-+};
-+
-+typedef struct _bigint bigint; /**< An alias for _bigint */
-+
-+/**
-+ * Maintains the state of the cache, and a number of variables used in
-+ * reduction.
-+ */
-+typedef struct /**< A big integer "session" context. */
-+{
-+ bigint *active_list; /**< Bigints currently used. */
-+ bigint *free_list; /**< Bigints not used. */
-+ bigint *bi_radix; /**< The radix used. */
-+ bigint *bi_mod[BIGINT_NUM_MODS]; /**< modulus */
-+
-+#if defined(CONFIG_BIGINT_MONTGOMERY)
-+ bigint *bi_RR_mod_m[BIGINT_NUM_MODS]; /**< R^2 mod m */
-+ bigint *bi_R_mod_m[BIGINT_NUM_MODS]; /**< R mod m */
-+ comp N0_dash[BIGINT_NUM_MODS];
-+#elif defined(CONFIG_BIGINT_BARRETT)
-+ bigint *bi_mu[BIGINT_NUM_MODS]; /**< Storage for mu */
-+#endif
-+ bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */
-+ bigint **g; /**< Used by sliding-window. */
-+ int window; /**< The size of the sliding window */
-+
-+ int active_count; /**< Number of active bigints. */
-+ int free_count; /**< Number of free bigints. */
-+
-+#ifdef CONFIG_BIGINT_MONTGOMERY
-+ uint8_t use_classical; /**< Use classical reduction. */
-+#endif
-+ uint8_t mod_offset; /**< The mod offset we are using */
-+} BI_CTX;
-+
-+#if 0
-+#define max(a,b) ((a)>(b)?(a):(b)) /**< Find the maximum of 2 numbers. */
-+#define min(a,b) ((a)<(b)?(a):(b)) /**< Find the minimum of 2 numbers. */
-+#endif
-+
-+#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */
-+
-+#define V1 v->comps[v->size-1] /**< v1 for division */
-+#define V2 v->comps[v->size-2] /**< v2 for division */
-+#define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */
-+#define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */
-+
-+#endif
---- /dev/null
-+++ b/net/rsa/div64.h
-@@ -0,0 +1,113 @@
-+/*
-+ * Copyright (C) 2000, 2004 Maciej W. Rozycki
-+ * Copyright (C) 2003 Ralf Baechle
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ */
-+#ifndef _ASM_DIV64_H
-+#define _ASM_DIV64_H
-+
-+#if (_MIPS_SZLONG == 32)
-+
-+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-+#define GCC_REG_ACCUM "$0"
-+#else
-+#define GCC_REG_ACCUM "accum"
-+#endif
-+
-+
-+//#include <asm/compiler.h>
-+
-+/*
-+ * No traps on overflows for any of these...
-+ */
-+
-+#define do_div64_32(res, high, low, base) ({ \
-+ unsigned long __quot, __mod; \
-+ unsigned long __cf, __tmp, __tmp2, __i; \
-+ \
-+ __asm__(".set push\n\t" \
-+ ".set noat\n\t" \
-+ ".set noreorder\n\t" \
-+ "move %2, $0\n\t" \
-+ "move %3, $0\n\t" \
-+ "b 1f\n\t" \
-+ " li %4, 0x21\n" \
-+ "0:\n\t" \
-+ "sll $1, %0, 0x1\n\t" \
-+ "srl %3, %0, 0x1f\n\t" \
-+ "or %0, $1, %5\n\t" \
-+ "sll %1, %1, 0x1\n\t" \
-+ "sll %2, %2, 0x1\n" \
-+ "1:\n\t" \
-+ "bnez %3, 2f\n\t" \
-+ " sltu %5, %0, %z6\n\t" \
-+ "bnez %5, 3f\n" \
-+ "2:\n\t" \
-+ " addiu %4, %4, -1\n\t" \
-+ "subu %0, %0, %z6\n\t" \
-+ "addiu %2, %2, 1\n" \
-+ "3:\n\t" \
-+ "bnez %4, 0b\n\t" \
-+ " srl %5, %1, 0x1f\n\t" \
-+ ".set pop" \
-+ : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
-+ "=&r" (__i), "=&r" (__tmp2) \
-+ : "Jr" (base), "0" (high), "1" (low)); \
-+ \
-+ (res) = __quot; \
-+ __mod; })
-+
-+#define do_div(n, base) ({ \
-+ unsigned long long __quot; \
-+ unsigned long __mod; \
-+ unsigned long long __div; \
-+ unsigned long __upper, __low, __high, __base; \
-+ \
-+ __div = (n); \
-+ __base = (base); \
-+ \
-+ __high = __div >> 32; \
-+ __low = __div; \
-+ __upper = __high; \
-+ \
-+ if (__high) \
-+ __asm__("divu $0, %z2, %z3" \
-+ : "=h" (__upper), "=l" (__high) \
-+ : "Jr" (__high), "Jr" (__base) \
-+ : GCC_REG_ACCUM); \
-+ \
-+ __mod = do_div64_32(__low, __upper, __low, __base); \
-+ \
-+ __quot = __high; \
-+ __quot = __quot << 32 | __low; \
-+ (n) = __quot; \
-+ __mod; })
-+#endif /* (_MIPS_SZLONG == 32) */
-+
-+#if (_MIPS_SZLONG == 64)
-+
-+/*
-+ * Hey, we're already 64-bit, no
-+ * need to play games..
-+ */
-+#define do_div(n, base) ({ \
-+ unsigned long __quot; \
-+ unsigned int __mod; \
-+ unsigned long __div; \
-+ unsigned int __base; \
-+ \
-+ __div = (n); \
-+ __base = (base); \
-+ \
-+ __mod = __div % __base; \
-+ __quot = __div / __base; \
-+ \
-+ (n) = __quot; \
-+ __mod; })
-+
-+#endif /* (_MIPS_SZLONG == 64) */
-+
-+#endif /* _ASM_DIV64_H */
---- /dev/null
-+++ b/net/rsa/dump_key.c
-@@ -0,0 +1,29 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+
-+int main(int argc, char **argv)
-+{
-+ FILE *fp = fopen("public_fon_rsa_key_6.pem", "r");
-+ struct stat s;
-+ unsigned char *b;
-+ int i;
-+ if(!fp)
-+ return 1;
-+ stat("public_fon_rsa_key_6.pem", &s);
-+ b = malloc(s.st_size);
-+ fread(b, s.st_size, 1, fp);
-+ fclose(fp);
-+ printf("unsigned char public_key[] = {\n\t");
-+ for(i = 0;i < s.st_size; i++)
-+ {
-+ printf("0x%02X,", b[i]);
-+ if(i%16 == 15)
-+ printf("\n\t");
-+ }
-+ printf("};\n");
-+// printf("\n%d %d\n", i, s.st_size);
-+ return 0;
-+}
---- /dev/null
-+++ b/net/rsa/foncheckrsa.c
-@@ -0,0 +1,79 @@
-+/*
-+ * RSA + RIPEMD160 signature verification command
-+ *
-+ * Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version 2
-+ * of the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-+ *
-+ * Created: 20060728 Pablo MartÃn Medrano <pablo@fon.com>
-+ *
-+ * $Id: foncheckrsa.c 332 2007-05-02 09:45:54Z pablo.martin $
-+ */
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include "fonrsa.h"
-+
-+int main(int argc, char **argv)
-+{
-+ int fd, i;
-+ FONRSA_ERROR fonrsa_error;
-+ void *handle;
-+
-+ if (argc != 4) {
-+ fprintf(stderr, " Usage: foncheckrsa [public_key.der] [signature] [file]\n");
-+ fprintf(stderr, " Pablo MartÃn Medrano <pablo@fon.com>\n");
-+ fprintf(stderr, " RIPEMD-160 software written by Antoon Bosselaers,\n");
-+ fprintf(stderr, " available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.\n");
-+ fprintf(stderr, " Uses the axTLS library bigint implementation (libfonrsa)\n");
-+ fprintf(stderr, " http://www.leroc.com.au/axTLS/\n");
-+ return -1;
-+ }
-+ /* Check the existence of input files */
-+ for (i = 1; i < 4; i++) {
-+ if ((fd = open(argv[i], O_RDONLY)) == -1) {
-+ fprintf(stderr, "Error: opening \"%s\": %s\n", argv[i],
-+ strerror(errno));
-+ fprintf(stderr, "Bailing out...");
-+ exit(-2);
-+ }
-+ close(fd);
-+ }
-+ handle = FR_init(argv[1]);
-+ if (handle == NULL) {
-+ printf("Error loading keys in %s\n", argv[1]);
-+ return 1;
-+ }
-+ fonrsa_error = FR_verify_file(handle, argv[3], argv[2]);
-+ FR_end(handle);
-+ switch (fonrsa_error) {
-+ case FONRSA_OK:
-+ printf("Verified OK\n");
-+ return 0;
-+ case FONRSA_VERIFICATION_FAILURE:
-+ printf("Verification failure\n");
-+ return 1;
-+ default:
-+ printf("Verification error\n");
-+ return -1;
-+ }
-+ return -1;
-+}
-+
---- /dev/null
-+++ b/net/rsa/fonrsa.c
-@@ -0,0 +1,584 @@
-+/*
-+ * FONSM RSA handling library
-+ *
-+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * This library is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
-+ *
-+ * Based on axTLS
-+ *
-+ * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
-+ */
-+#include <sys/types.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include "rmd160.h"
-+#include "bigint.h"
-+#include "fonrsa.h"
-+#include "base64.h"
-+
-+typedef struct {
-+ uint8_t *buffer;
-+ size_t size;
-+} DER_key;
-+
-+typedef struct {
-+ bigint *m; /* modulus */
-+ bigint *e; /* public exponent */
-+ int num_octets;
-+ BI_CTX *bi_ctx; /* big integer handle */
-+} RSA_parameters;
-+
-+typedef struct {
-+ DER_key *derkey;
-+ RSA_parameters *rsaparms;
-+} RSA;
-+
-+static uint8_t *CH_load_raw_file(char *filename, size_t *size);
-+static DER_key *CH_load_der_key(char *filename);
-+static void CH_free_der_key(DER_key *key);
-+static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters);
-+void CH_pub_key_new(RSA_parameters **rsa_parameters, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len);
-+int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out);
-+byte *RMDbinary(char *fname);
-+int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file);
-+static unsigned char *load_file_in_buffer(char *path, int *size);
-+static int save_file_from_buffer(char *path, unsigned char *buffer, int size);
-+int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer);
-+
-+#define RMDsize 160 /* A RIPEMD-160 hash has 160 bits */
-+
-+/*
-+ * returns RMD(message in file fname) fname is read as binary data.
-+ * non-reentrant
-+ */
-+byte *RMDbinary(char *fname)
-+{
-+ FILE *mf; /* pointer to file <fname> */
-+ byte data[1024]; /* contains current mess. block */
-+ dword nbytes; /* length of this block */
-+ dword MDbuf[RMDsize / 32]; /* contains (A, B, C, D(, E)) */
-+ static byte hashcode[RMDsize / 8]; /* for final hash-value */
-+ dword X[16]; /* current 16-word chunk */
-+ unsigned int i, j; /* counters */
-+ dword length[2]; /* length in bytes of message */
-+ dword offset; /* # of unprocessed bytes at */
-+ /* call of MDfinish */
-+
-+ /* initialize */
-+ if ((mf = fopen(fname, "rb")) == NULL) {
-+ fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n",
-+ fname);
-+ exit(1);
-+ }
-+ MDinit(MDbuf);
-+ length[0] = 0;
-+ length[1] = 0;
-+ while ((nbytes = fread(data, 1, 1024, mf)) != 0) {
-+ /* process all complete blocks */
-+ for (i = 0; i < (nbytes >> 6); i++) {
-+ for (j = 0; j < 16; j++)
-+ X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
-+ compress(MDbuf, X);
-+ }
-+ /* update length[] */
-+ if (length[0] + nbytes < length[0])
-+ length[1]++; /* overflow to msb of length */
-+ length[0] += nbytes;
-+ }
-+ /* finish: */
-+ offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
-+ MDfinish(MDbuf, data + offset, length[0], length[1]);
-+
-+ for (i = 0; i < RMDsize / 8; i += 4) {
-+ hashcode[i] = MDbuf[i >> 2];
-+ hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
-+ hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
-+ hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
-+ }
-+ fclose(mf);
-+
-+ return (byte *) hashcode;
-+}
-+byte *RMDbinary_buffer(char *buffer, int size_buffer)
-+{
-+ return NULL;
-+}
-+
-+/*
-+ * Extracts the RMD 160 hash from the signature file
-+ */
-+int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file)
-+{
-+ RSA_parameters *rsa_parameters;
-+ DER_key *derkey;
-+ uint8_t *signature;
-+ size_t signature_size;
-+ uint8_t *decrypted;
-+
-+ signature = CH_load_raw_file(signature_file, &signature_size);
-+ if ((signature == NULL)||(signature_size != 512)) {
-+ fprintf(stderr, "Error: Loading signature key '%s'\n", signature_file);
-+ exit(-1);
-+ }
-+ derkey = CH_load_der_key(public_key_file);
-+ if (derkey == NULL) {
-+ fprintf(stderr, "Error: opening DER key file '%s'\n", public_key_file);
-+ exit(-1);
-+ }
-+ if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
-+ fprintf(stderr, "Error: Extracting public key from DER file\n");
-+ exit(-1);
-+ }
-+ CH_free_der_key(derkey);
-+ if (rsa_parameters->num_octets != 512)
-+ fprintf(stderr, "Error: The RSA public key size is not 4096 bits %d\n", rsa_parameters->num_octets);
-+ decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
-+ if (CH_decrypt(rsa_parameters, signature, decrypted)) {
-+ fprintf(stderr, "Error: Decrypting signature\n");
-+ exit(-1);
-+ }
-+ memcpy(hash, decrypted + 492, 20);
-+ free(decrypted);
-+ free(signature);
-+ return 0;
-+}
-+
-+/*
-+ * Decrypts the signature buffer using the rsa public key loaded
-+ */
-+int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
-+{
-+ bigint *dat_bi;
-+ bigint *decrypted_bi;
-+ int byte_size;
-+
-+ byte_size = rsa->num_octets;
-+ dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
-+ rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
-+ bi_copy(rsa->m);
-+ decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
-+ bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
-+ return 0;
-+}
-+/*
-+ * Loads a file in a uint8_t buffer
-+ */
-+static uint8_t *CH_load_raw_file(char *filename, size_t *size)
-+{
-+ struct stat st;
-+ int fd;
-+ ssize_t br;
-+ uint8_t *ret;
-+
-+ if ((stat(filename, &st)) == -1)
-+ return NULL;
-+ if ((ret = (uint8_t *)malloc(st.st_size)) == NULL)
-+ return NULL;
-+ fd = open(filename, O_RDONLY);
-+ if (fd == -1) {
-+ free(ret);
-+ return NULL;
-+ }
-+ br = read(fd, ret, st.st_size);
-+ close(fd);
-+ if (br != st.st_size) {
-+ free(ret);
-+ return NULL;
-+ }
-+ *size = st.st_size;
-+ return ret;
-+}
-+/*
-+ * Loads a .der file in a buffer
-+ */
-+static DER_key *CH_load_der_key(char *filename)
-+{
-+ DER_key *ret;
-+
-+ if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
-+ return NULL;
-+ if ((ret->buffer = CH_load_raw_file(filename, &(ret->size))) == NULL) {
-+ free(ret);
-+ return NULL;
-+ }
-+ return ret;
-+}
-+/*
-+ * CH_load_pem_key
-+ */
-+static DER_key *CH_load_pem_key(char *filename)
-+{
-+ DER_key *ret;
-+ uint8_t *buffer;
-+ char *b64,*p,*t;
-+ char key[1024];
-+ size_t filesize;
-+ int size;
-+
-+ if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
-+ return NULL;
-+ if ((buffer = CH_load_raw_file(filename, &filesize)) == NULL) {
-+ free(ret);
-+ return NULL;
-+ }
-+ p = (char *)buffer;
-+ while ((*p != '\n') && (*p != '\0'))
-+ p++;
-+ if (*p == '\0') {
-+ free(ret);
-+ return NULL;
-+ }
-+ p++;
-+ b64 = t = p;
-+ while((p - b64) <= filesize) {
-+ if ((*p == '-')) {
-+ break;
-+ } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
-+ *t = *p;
-+ t++;
-+ }
-+ p++;
-+ }
-+ *t = '\0';
-+ size = B64_decode(b64, key, strlen(b64), 1024);
-+ if (size < 0) {
-+ free(buffer);
-+ free(ret);
-+ return NULL;
-+ }
-+ free(buffer);
-+ ret->buffer = (char *)malloc(size);
-+ ret->size = size;
-+ memcpy((void *)ret->buffer, (void *)key, size);
-+ return ret;
-+}
-+
-+/*
-+ * CH_free_der_key
-+ */
-+static void CH_free_der_key(DER_key *key)
-+{
-+ free(key->buffer);
-+ free(key);
-+}
-+
-+/*
-+ * Get the public key specifics from an ASN.1 encoded file
-+ * A function lacking in the exported axTLS API
-+ *
-+ * This is a really weird hack that only works with RSA public key
-+ * files
-+ */
-+static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
-+{
-+ uint8_t *modulus, *pub_exp;
-+ int mod_len, pub_len;
-+
-+ pub_len = 3;
-+ mod_len = len - 37;
-+ if (buf[0] != 0x30) {
-+ return -1;
-+ }
-+
-+ pub_exp = (uint8_t *)malloc(3);
-+ modulus = (uint8_t *)malloc(mod_len);
-+ memcpy(modulus, buf + 32 , mod_len);
-+ memcpy(pub_exp, buf + 34 + mod_len, 3);
-+ if (mod_len <= 0 || pub_len <= 0 )
-+ return -1;
-+ CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
-+
-+ free(modulus);
-+ free(pub_exp);
-+ return 0;
-+}
-+
-+/*
-+ * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
-+ */
-+void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
-+{
-+ RSA_parameters *rsa_parameters;
-+
-+ BI_CTX *bi_ctx = bi_initialize();
-+ *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
-+ rsa_parameters = *rsa;
-+ rsa_parameters->bi_ctx = bi_ctx;
-+ rsa_parameters->num_octets = (mod_len & 0xFFF0);
-+ rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
-+ bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
-+ rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
-+ bi_permanent(rsa_parameters->e);
-+}
-+
-+static unsigned char *load_file_in_buffer(char *path, int *size)
-+{
-+ unsigned char *buffer;
-+ struct stat st;
-+ int fd;
-+
-+ if (stat(path, &st))
-+ return NULL;
-+ buffer = (unsigned char *)malloc(st.st_size);
-+ if (buffer == NULL)
-+ return NULL;
-+ if ((fd = open(path, O_RDONLY)) == -1) {
-+ free(buffer);
-+ return NULL;
-+ }
-+ if (read(fd, (void *)buffer,st.st_size) != (ssize_t)st.st_size) {
-+ free(buffer);
-+ close(fd);
-+ return NULL;
-+ }
-+ *size = (int)st.st_size;
-+ close(fd);
-+ return buffer;
-+}
-+
-+static int save_file_from_buffer(char *path, unsigned char *buffer, int size)
-+{
-+ int fd;
-+
-+ if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
-+ return -1;
-+ if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
-+ close(fd);
-+ return -1;
-+ }
-+ close(fd);
-+ return 0;
-+}
-+
-+/* FR_init */
-+void *FR_init(char *public_key_path)
-+{
-+ DER_key *derkey;
-+ RSA_parameters *rsa_parameters;
-+ char *ending;
-+
-+ ending = public_key_path + strlen(public_key_path) - 3;
-+ if (!strcmp(ending, "der"))
-+ derkey = CH_load_der_key(public_key_path);
-+ else if (!strcmp(ending, "pem"))
-+ derkey = CH_load_pem_key(public_key_path);
-+ else {
-+ fprintf(stderr, "Error: unknown key format\n");
-+ exit(-1);
-+ }
-+ if (derkey == NULL) {
-+ fprintf(stderr, "Error: opening key file '%s'\n", public_key_path);
-+ exit(-1);
-+ }
-+ if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
-+ fprintf(stderr, "Error: Extracting public key from file\n");
-+ exit(-1);
-+ }
-+ CH_free_der_key(derkey);
-+ return (void *)rsa_parameters;
-+}
-+
-+/* FR_end */
-+FONRSA_ERROR FR_end(void *handle)
-+{
-+ RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
-+
-+ free(rsa_parameters);
-+ return FONRSA_OK;
-+}
-+
-+/* FR_decrypt_buffer */
-+FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
-+ unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
-+{
-+ RSA_parameters *rsaparms = (RSA_parameters *)handler;
-+
-+ if (cryptext_size != rsaparms->num_octets) {
-+ return FONRSA_SIZE;
-+ }
-+ if (plaintext_buffer_size < cryptext_size) {
-+ return FONRSA_SIZE;
-+ }
-+ if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)plaintext)) {
-+ return FONRSA_DECRYPT;
-+ }
-+ *plaintext_size = cryptext_size;
-+ return FONRSA_OK;
-+}
-+
-+FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
-+ unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
-+{
-+ unsigned char* AuxBuffer;
-+ int AuxSize;
-+
-+ AuxBuffer = (unsigned char*)malloc(cryptext_size);
-+
-+ RSA_parameters *rsaparms = (RSA_parameters *)handler;
-+
-+ if (cryptext_size != rsaparms->num_octets) {
-+ return FONRSA_SIZE;
-+ }
-+ if (plaintext_buffer_size < cryptext_size) {
-+ return FONRSA_SIZE;
-+ }
-+ if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)AuxBuffer)) {
-+ return FONRSA_DECRYPT;
-+ }
-+ if ((AuxSize = ExtractPadding((uint8_t*)plaintext, (uint8_t*)AuxBuffer, cryptext_size)) < 0)
-+ {
-+ printf("Incorrect Padding decrypting buffer");
-+ return FONRSA_DECRYPT;
-+ }
-+ *plaintext_size = AuxSize;
-+ return FONRSA_OK;
-+}
-+
-+/*
-+ *
-+ * Implementation of PKCS 1.5 padding, borrowed from
-+ * Tom's code (public domain)
-+ */
-+
-+/* Standalone FR_verify_file */
-+FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path)
-+{
-+ int j;
-+ byte *hashcode;
-+ byte hash[20];
-+ uint8_t *decrypted;
-+ RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
-+ char *signature_buffer;
-+ int signature_size;
-+
-+ /* Calculates the RIPEMD-160 hash of the file */
-+ hashcode = RMDbinary (file_path);
-+ /* Decrypts the signature file using the RSA public key */
-+ signature_buffer = load_file_in_buffer(signature_file_path, &signature_size);
-+ if (signature_buffer == NULL)
-+ return FONRSA_OPENKEY;
-+
-+ if (rsa_parameters->num_octets != signature_size)
-+ return FONRSA_SIZE;
-+ decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
-+ if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
-+ fprintf(stderr, "Error: Decrypting signature\n");
-+ exit(-1);
-+ }
-+ memcpy(hash, decrypted + 492, 20);
-+ free(decrypted);
-+ free(signature_buffer);
-+ for (j = 0; j < RMDsize/8; j++) {
-+ if (hash[j] != hashcode[j])
-+ return FONRSA_VERIFICATION_FAILURE;
-+ }
-+ return FONRSA_OK;
-+}
-+
-+/* FR_decrypt_file */
-+FONRSA_ERROR FR_decrypt_file(void *handle, char *crypted_file_path, char *plaintext_file_path)
-+{
-+ int size;
-+ FONRSA_ERROR ret;
-+ char *filebuffer;
-+ char crypted[1024];
-+ int crypted_size;
-+
-+ if ((filebuffer = load_file_in_buffer(crypted_file_path, &size)) == NULL) {
-+ return FONRSA_LOADFILE;
-+ }
-+
-+ ret = FR_decrypt_buffer(handle, filebuffer, size, crypted, 1024, &crypted_size);
-+ if (ret != FONRSA_OK) {
-+ free(filebuffer);
-+ return ret;
-+ }
-+ free(filebuffer);
-+
-+ if (save_file_from_buffer(plaintext_file_path, crypted, crypted_size)) {
-+ printf("Error writing %lu bytes into %s", crypted_size, plaintext_file_path);
-+ return FONRSA_SAVEFILE;
-+ }
-+ return FONRSA_OK;
-+}
-+
-+int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer)
-+{
-+ int i;
-+
-+ //First typical checks...
-+ if (LengthOfInputBuffer < MINIMUM_PADING_BYTES_PKCS_1_5)
-+ {
-+ fprintf(stderr, "Error:ExtractPadding: Error, Length of input buffer is too short.\n");
-+ return -1;
-+ }
-+ else if((InputBuffer[0] != 0) || (InputBuffer[1] > 2)) //Necessary header of Padding...
-+ {
-+ fprintf(stderr, "Error:ExtractPadding: Error, Padding header is incorrect.\n");
-+ return -1;
-+ }
-+ for (i=2; i < LengthOfInputBuffer; i++) //Variable size of non-zero padding....
-+ {
-+ if (InputBuffer[i] == 0) break; //This is the end of Padding.
-+ }
-+ //We need to evaluate if there is an existing message...
-+ if (i < LengthOfInputBuffer - 2)
-+ {//Ok, Padding is extracted... copying the message and finishing...
-+ memcpy(OutputBuffer, &(InputBuffer[i + 1]), LengthOfInputBuffer - (i + 1));
-+ return LengthOfInputBuffer - (i + 1);
-+ }
-+ //If we have reached to this point, then an error has occurred...
-+ return -1;
-+}
-+
-+#ifdef __MAINTEST__
-+int main(int argc, char **argv)
-+{
-+ void *handle = NULL;
-+ FONRSA_ERROR ret;
-+ char *filebuffer = NULL;
-+ char crypted[1024];
-+ int size, crypted_size;
-+
-+ if (argc != 4) {
-+ printf("Usage: %s <key_file> <crypted_file> <output_file>\n", argv[0]);
-+ return 1;
-+ }
-+
-+ handle = FR_init(argv[1]);
-+ if (handle == NULL) {
-+ printf("Error loading keys\n");
-+ return 1;
-+ }
-+ ret = FR_decrypt_file(handle, argv[2], argv[3]);
-+ if (ret != FONRSA_OK) {
-+ printf("FR_decrypt_file returns %d\n", ret);
-+ }
-+ FR_end(handle);
-+ return (int)ret;
-+}
-+
-+#endif
-+
-+
---- /dev/null
-+++ b/net/rsa/fonrsa.h
-@@ -0,0 +1,53 @@
-+/*
-+ * FONSM RSA handling library, used by fonsmcd and foncheckrsa
-+ *
-+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * This library is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
-+ *
-+ * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
-+ */
-+#ifndef _FONRSA_H
-+#define _FONRSA_H
-+
-+#define MINIMUM_PADING_BYTES_PKCS_1_5 3
-+
-+typedef enum {
-+ FONRSA_OK = 0,
-+ FONRSA_VERIFICATION_FAILURE = 1,
-+ FONRSA_OPENKEY = 2,
-+ FONRSA_SIZE = 3,
-+ FONRSA_LOADFILE = 4,
-+ FONRSA_CRYPT = 5,
-+ FONRSA_DECRYPT = 6,
-+ FONRSA_SAVEFILE = 7,
-+ FONRSA_NOSYS = 8,
-+ FONRSA_VERIFY = 9
-+} FONRSA_ERROR;
-+
-+void *FR_init(char *public_key_path);
-+FONRSA_ERROR FR_end(void *handle);
-+FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
-+ unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
-+FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
-+ unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
-+FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path);
-+FONRSA_ERROR FR_decrypt_file(void *handler, char *crypted_file_path, char *plaintext_file_path);
-+
-+#endif
-+
-+
---- /dev/null
-+++ b/net/rsa/log.c
-@@ -0,0 +1,138 @@
-+/*
-+ * Fonsm log module. Used inside the fonsm backend module and on the client.
-+ *
-+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
-+ *
-+ * $Id: log.c 392 2007-06-25 16:24:51Z pablo.martin $
-+ */
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stdarg.h>
-+#include <unistd.h>
-+#ifndef WIN32
-+#include <syslog.h>
-+#endif
-+#include "log.h"
-+
-+#define MAX_SESSION_PREFIX 256
-+
-+typedef struct {
-+ char domain[256];
-+ LG_LEVEL watermark;
-+ int mode;
-+ LG_log_function_pointer function;
-+} ST_fslog;
-+
-+static ST_fslog fslog;
-+static void LG_log_string(LG_LEVEL level, const char *message);
-+
-+/*!
-+ \brief Starts the log subsystem, redirecting glog() to stderr/syslog depending
-+ on mode
-+ \retval FSLOG_ERROR : FSLOG_OK if everything goes well
-+ \param lg : handle that will be returned
-+ \param ident : program identifier, any string
-+ \param low_watermark : if the log level is less than this value, it will not be logged
-+ \param mode : FSLOG_MODE_SYSLOG (log to syslog) or FSLOG_MODE_STDERR (log to stderr)
-+*/
-+FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode,
-+ LG_log_function_pointer log_function, int facility)
-+{
-+#ifndef WIN32
-+ strncpy(fslog.domain, domain, MAX_LG_DOMAIN);
-+ fslog.domain[MAX_LG_DOMAIN - 1] = '\0';
-+ fslog.watermark = watermark;
-+ fslog.mode = mode;
-+ fslog.function = log_function?log_function:LG_log_string;
-+ if (fslog.mode & LG_SYSLOG)
-+ openlog(domain, LOG_NDELAY, facility);
-+ return FSLOG_OK;
-+#else
-+ return FSLOG_OK;
-+#endif
-+}
-+
-+/*!
-+ \brief Set the low watermark
-+ \retval FSLOG_ERROR : FSLOG_OK
-+ \param lg : log handle
-+ \param low_watermark : new watermark
-+*/
-+FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark)
-+{
-+ fslog.watermark = watermark;
-+ return FSLOG_OK;
-+}
-+
-+/*!
-+ \brief Ends the log subsystem, unregisteing glog handle
-+ \retval FSLOG_ERROR : FSLOG_OK if everything goes well
-+ \param handle : log handle to free
-+*/
-+FSLOG_ERROR LG_end(void)
-+{
-+#ifndef WIN32
-+ if (fslog.mode & LG_SYSLOG)
-+ closelog();
-+#endif
-+ return FSLOG_OK;
-+}
-+
-+
-+void LG_log(LG_LEVEL loglevel, const char *message, ...)
-+{
-+#ifndef WIN32
-+ va_list ap;
-+ char buffer[4096];
-+ int n;
-+
-+ va_start(ap, message);
-+ n = vsnprintf(buffer, MAX_LOG_STRING, message, ap);
-+ va_end(ap);
-+ if (n > -1 && n < MAX_LOG_STRING)
-+ fslog.function(loglevel, buffer);
-+ else
-+ fon_critical("%s: Message too big to be logged", __FUNCTION__);
-+#else
-+ return;
-+#endif
-+}
-+
-+/* Default log function (when mode is LG_SYSLOG or LG_STDERR) */
-+static void LG_log_string(LG_LEVEL level, const char *message)
-+{
-+#ifndef WIN32
-+ static struct {
-+ int syslog_level;
-+ char *log_string;
-+ } fonlog_to_syslog[] = {
-+ [LG_DEBUG] = {LOG_ERR, "DEBUG"},
-+ [LG_MESSAGE] = {LOG_ERR, "MESSAGE"},
-+ [LG_WARNING] = {LOG_ERR, "WARNING"},
-+ [LG_CRITICAL] = {LOG_ERR, "CRITICAL"},
-+ [LG_ERROR] = {LOG_ERR, "ERROR"}
-+ };
-+
-+ if (level < fslog.watermark)
-+ return;
-+ if (fslog.mode & LG_SYSLOG) {
-+ if (level == LG_MESSAGE) {
-+ syslog(LOG_INFO, "%s", message);
-+ } else {
-+ syslog(fonlog_to_syslog[level].syslog_level, "%s: %s", fonlog_to_syslog[level].log_string, message);
-+ }
-+ }
-+ if (fslog.mode & LG_STDERR) {
-+ fprintf(stderr, "%s[%d]: %8.8s: %s\n", fslog.domain,
-+ getpid(), fonlog_to_syslog[level].log_string,
-+ message);
-+ }
-+#else
-+ /* FIXE: todo */
-+ return;
-+#endif
-+}
-+
---- /dev/null
-+++ b/net/rsa/log.h
-@@ -0,0 +1,77 @@
-+/*
-+ * Fonsm log module. Used inside the fonsm backend module and on the client.
-+ *
-+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
-+ *
-+ * $Id: log.h 379 2007-05-28 09:17:48Z pablo.martin $
-+ */
-+#ifndef _LOG_H
-+#define _LOG_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#include <stdarg.h>
-+
-+typedef enum {
-+ FSLOG_OK = 0,
-+ FSLOG_UNKNOWN = -1
-+} FSLOG_ERROR;
-+
-+
-+typedef void * LG_HANDLE;
-+
-+typedef enum {
-+ LG_DEBUG = 0,
-+ LG_MESSAGE = 1,
-+ LG_INFO = 2,
-+ LG_WARNING = 3,
-+ LG_CRITICAL = 4,
-+ LG_ERROR = 5
-+} LG_LEVEL;
-+
-+#define LG_SYSLOG 0x01
-+#define LG_STDERR 0x02
-+#define LG_CUSTOM 0x04
-+
-+#define MAX_LG_DOMAIN 256
-+#define MAX_LOG_STRING 4096
-+
-+#ifndef NDEBUG
-+#ifndef LOGPRINTF
-+#define fon_debug(...) LG_log (LG_DEBUG, __VA_ARGS__)
-+#else
-+#define fon_debug(...) { printf("DEBUG: "); printf(__VA_ARGS__); printf("\n"); }
-+#endif
-+#else
-+/* fon_debug evaluates to nothing when NDEBUG is defined */
-+#define fon_debug(...)
-+#endif
-+#ifndef LOGPRINTF
-+#define fon_message(...) LG_log (LG_MESSAGE, __VA_ARGS__)
-+#define fon_warning(...) LG_log (LG_WARNING, __VA_ARGS__)
-+#define fon_critical(...) LG_log (LG_CRITICAL, __VA_ARGS__)
-+#define fon_error(...) LG_log (LG_ERROR, __VA_ARGS__)
-+#else
-+#define fon_message(...) { printf("MESSAGE: "); printf(__VA_ARGS__); printf("\n"); }
-+#define fon_warning(...) { printf("WARNING: "); printf(__VA_ARGS__); printf("\n"); }
-+#define fon_critical(...) { printf("CRITICAL: "); printf(__VA_ARGS__); printf("\n"); }
-+#define fon_error(...) { printf("ERROR: "); printf(__VA_ARGS__); printf("\n"); }
-+#endif
-+
-+typedef void (*LG_log_function_pointer)(LG_LEVEL level, const char *message);
-+
-+FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode, LG_log_function_pointer log_function, int facility);
-+FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark);
-+FSLOG_ERROR LG_end(void);
-+void LG_log(LG_LEVEL loglevel, const char *message, ...);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
-+
---- /dev/null
-+++ b/net/rsa/public_key.h
-@@ -0,0 +1,52 @@
-+unsigned char public_key[] = {
-+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x42,0x45,0x47,0x49,0x4E,0x20,0x50,0x55,0x42,0x4C,0x49,
-+ 0x43,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x4D,0x49,0x49,0x43,0x49,
-+ 0x6A,0x41,0x4E,0x42,0x67,0x6B,0x71,0x68,0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,
-+ 0x51,0x45,0x46,0x41,0x41,0x4F,0x43,0x41,0x67,0x38,0x41,0x4D,0x49,0x49,0x43,0x43,
-+ 0x67,0x4B,0x43,0x41,0x67,0x45,0x41,0x34,0x4C,0x42,0x76,0x59,0x43,0x4B,0x38,0x38,
-+ 0x6D,0x75,0x57,0x61,0x73,0x31,0x4F,0x53,0x73,0x71,0x30,0x0A,0x38,0x39,0x38,0x79,
-+ 0x76,0x54,0x4B,0x71,0x41,0x6E,0x4F,0x37,0x78,0x2F,0x44,0x53,0x57,0x72,0x46,0x53,
-+ 0x30,0x42,0x72,0x47,0x53,0x51,0x31,0x52,0x69,0x44,0x39,0x55,0x62,0x78,0x77,0x6F,
-+ 0x64,0x76,0x36,0x65,0x51,0x4B,0x55,0x30,0x67,0x36,0x52,0x6B,0x2F,0x39,0x54,0x70,
-+ 0x4C,0x6E,0x4F,0x2F,0x76,0x51,0x4B,0x70,0x69,0x41,0x30,0x30,0x0A,0x2B,0x32,0x59,
-+ 0x30,0x74,0x6B,0x4C,0x39,0x73,0x6A,0x37,0x64,0x33,0x57,0x4B,0x47,0x39,0x62,0x6A,
-+ 0x64,0x51,0x58,0x2F,0x43,0x49,0x35,0x57,0x46,0x42,0x42,0x64,0x77,0x57,0x73,0x74,
-+ 0x4D,0x43,0x38,0x77,0x74,0x4C,0x6A,0x6A,0x45,0x59,0x79,0x43,0x58,0x46,0x32,0x31,
-+ 0x30,0x39,0x7A,0x31,0x47,0x54,0x4C,0x73,0x53,0x44,0x34,0x57,0x4F,0x0A,0x45,0x50,
-+ 0x6D,0x45,0x37,0x34,0x63,0x6E,0x6F,0x35,0x78,0x53,0x43,0x71,0x71,0x33,0x74,0x54,
-+ 0x49,0x6D,0x38,0x50,0x78,0x49,0x77,0x54,0x46,0x6D,0x46,0x6F,0x6D,0x6A,0x76,0x31,
-+ 0x4F,0x56,0x50,0x32,0x73,0x42,0x49,0x70,0x35,0x4E,0x2B,0x59,0x6F,0x56,0x61,0x53,
-+ 0x58,0x6A,0x47,0x66,0x4E,0x63,0x54,0x36,0x4E,0x6B,0x39,0x76,0x6B,0x56,0x0A,0x57,
-+ 0x69,0x67,0x39,0x30,0x71,0x50,0x4E,0x4C,0x58,0x6E,0x39,0x39,0x50,0x78,0x48,0x61,
-+ 0x49,0x31,0x36,0x52,0x7A,0x78,0x48,0x4C,0x39,0x54,0x42,0x2B,0x50,0x43,0x33,0x68,
-+ 0x33,0x61,0x58,0x33,0x71,0x57,0x30,0x4B,0x4C,0x4A,0x41,0x66,0x6F,0x35,0x70,0x48,
-+ 0x6C,0x39,0x79,0x75,0x55,0x70,0x37,0x66,0x46,0x65,0x6A,0x4A,0x2B,0x41,0x58,0x0A,
-+ 0x51,0x4F,0x4A,0x62,0x53,0x45,0x67,0x56,0x74,0x76,0x72,0x68,0x44,0x39,0x73,0x55,
-+ 0x6D,0x4B,0x30,0x74,0x36,0x63,0x51,0x44,0x65,0x32,0x32,0x4E,0x4E,0x6E,0x77,0x37,
-+ 0x43,0x4F,0x4F,0x61,0x59,0x49,0x57,0x55,0x55,0x6A,0x79,0x6A,0x68,0x35,0x50,0x4B,
-+ 0x64,0x64,0x45,0x4B,0x5A,0x38,0x68,0x62,0x62,0x47,0x65,0x61,0x5A,0x4A,0x6F,0x76,
-+ 0x0A,0x63,0x6F,0x51,0x64,0x55,0x56,0x51,0x6D,0x71,0x44,0x53,0x2B,0x6B,0x63,0x2F,
-+ 0x41,0x51,0x6C,0x65,0x55,0x36,0x68,0x51,0x6A,0x63,0x55,0x4C,0x57,0x44,0x6B,0x4E,
-+ 0x2F,0x6F,0x4F,0x6C,0x33,0x43,0x53,0x65,0x70,0x67,0x54,0x37,0x6B,0x67,0x73,0x52,
-+ 0x63,0x63,0x47,0x74,0x66,0x4B,0x65,0x37,0x77,0x4D,0x70,0x35,0x66,0x59,0x4A,0x2B,
-+ 0x41,0x0A,0x43,0x46,0x44,0x41,0x6F,0x4C,0x6E,0x58,0x4E,0x6A,0x4E,0x56,0x6C,0x65,
-+ 0x73,0x43,0x6B,0x78,0x74,0x6A,0x62,0x4C,0x62,0x49,0x72,0x66,0x32,0x6E,0x43,0x62,
-+ 0x32,0x61,0x4D,0x65,0x64,0x31,0x5A,0x48,0x4E,0x4A,0x51,0x75,0x6F,0x4E,0x58,0x67,
-+ 0x72,0x43,0x41,0x44,0x31,0x71,0x2B,0x58,0x6E,0x66,0x77,0x63,0x69,0x6D,0x57,0x50,
-+ 0x64,0x51,0x0A,0x44,0x59,0x6A,0x6D,0x65,0x44,0x70,0x35,0x77,0x36,0x41,0x4A,0x33,
-+ 0x2F,0x35,0x59,0x39,0x55,0x74,0x78,0x47,0x34,0x72,0x51,0x72,0x61,0x68,0x78,0x53,
-+ 0x42,0x77,0x43,0x4B,0x57,0x39,0x4B,0x79,0x53,0x31,0x71,0x53,0x76,0x73,0x37,0x7A,
-+ 0x59,0x2F,0x52,0x59,0x37,0x4A,0x66,0x36,0x63,0x56,0x6B,0x54,0x43,0x78,0x69,0x33,
-+ 0x7A,0x32,0x53,0x0A,0x50,0x46,0x33,0x51,0x64,0x6B,0x30,0x50,0x44,0x2F,0x73,0x2B,
-+ 0x6B,0x77,0x39,0x71,0x4F,0x4E,0x79,0x69,0x33,0x67,0x6E,0x61,0x42,0x46,0x6E,0x54,
-+ 0x77,0x48,0x7A,0x59,0x69,0x77,0x34,0x2F,0x77,0x6A,0x46,0x33,0x64,0x47,0x68,0x47,
-+ 0x4E,0x6B,0x78,0x36,0x70,0x63,0x4E,0x4F,0x52,0x55,0x46,0x4E,0x65,0x4F,0x7A,0x59,
-+ 0x76,0x39,0x6F,0x6A,0x0A,0x51,0x59,0x70,0x73,0x55,0x31,0x33,0x6A,0x6D,0x30,0x33,
-+ 0x42,0x6F,0x45,0x2B,0x42,0x31,0x64,0x38,0x50,0x47,0x75,0x57,0x2B,0x49,0x7A,0x2F,
-+ 0x41,0x4F,0x44,0x7A,0x6B,0x6F,0x56,0x6B,0x39,0x2B,0x57,0x79,0x49,0x33,0x37,0x50,
-+ 0x30,0x53,0x7A,0x47,0x4B,0x72,0x2B,0x53,0x33,0x72,0x72,0x74,0x61,0x50,0x6C,0x41,
-+ 0x70,0x71,0x4B,0x48,0x55,0x0A,0x6E,0x64,0x35,0x6C,0x30,0x63,0x76,0x75,0x59,0x66,
-+ 0x31,0x4C,0x37,0x45,0x52,0x75,0x49,0x58,0x64,0x47,0x4C,0x6A,0x30,0x43,0x41,0x77,
-+ 0x45,0x41,0x41,0x51,0x3D,0x3D,0x0A,0x2D,0x2D,0x2D,0x2D,0x2D,0x45,0x4E,0x44,0x20,
-+ 0x50,0x55,0x42,0x4C,0x49,0x43,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,
-+ };
---- /dev/null
-+++ b/net/rsa/rmd160.c
-@@ -0,0 +1,292 @@
-+/********************************************************************\
-+ *
-+ * FILE: rmd160.c
-+ *
-+ * CONTENTS: A sample C-implementation of the RIPEMD-160
-+ * hash-function.
-+ * TARGET: any computer with an ANSI C compiler
-+ *
-+ * AUTHOR: Antoon Bosselaers, ESAT-COSIC
-+ * DATE: 1 March 1996
-+ * VERSION: 1.0
-+ *
-+ * Copyright (c) Katholieke Universiteit Leuven
-+ * 1996, All Rights Reserved
-+ *
-+ * Conditions for use of the RIPEMD-160 Software
-+ *
-+ * The RIPEMD-160 software is freely available for use under the terms and
-+ * conditions described hereunder, which shall be deemed to be accepted by
-+ * any user of the software and applicable on any use of the software:
-+ *
-+ * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
-+ * all purposes be considered the owner of the RIPEMD-160 software and of
-+ * all copyright, trade secret, patent or other intellectual property
-+ * rights therein.
-+ * 2. The RIPEMD-160 software is provided on an "as is" basis without
-+ * warranty of any sort, express or implied. K.U.Leuven makes no
-+ * representation that the use of the software will not infringe any
-+ * patent or proprietary right of third parties. User will indemnify
-+ * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
-+ * which may arise as a result of its use of the software. In no
-+ * circumstances K.U.Leuven R&D will be held liable for any deficiency,
-+ * fault or other mishappening with regard to the use or performance of
-+ * the software.
-+ * 3. User agrees to give due credit to K.U.Leuven in scientific publications
-+ * or communications in relation with the use of the RIPEMD-160 software
-+ * as follows: RIPEMD-160 software written by Antoon Bosselaers,
-+ * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
-+ *
-+\********************************************************************/
-+
-+/* header files */
-+#include <common.h>
-+#include "rmd160.h"
-+
-+/********************************************************************/
-+
-+void MDinit(dword *MDbuf)
-+{
-+ MDbuf[0] = 0x67452301UL;
-+ MDbuf[1] = 0xefcdab89UL;
-+ MDbuf[2] = 0x98badcfeUL;
-+ MDbuf[3] = 0x10325476UL;
-+ MDbuf[4] = 0xc3d2e1f0UL;
-+
-+ return;
-+}
-+
-+/********************************************************************/
-+
-+void compress(dword *MDbuf, dword *X)
-+{
-+ dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
-+ dd = MDbuf[3], ee = MDbuf[4];
-+ dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
-+ ddd = MDbuf[3], eee = MDbuf[4];
-+
-+ /* round 1 */
-+ FF(aa, bb, cc, dd, ee, X[ 0], 11);
-+ FF(ee, aa, bb, cc, dd, X[ 1], 14);
-+ FF(dd, ee, aa, bb, cc, X[ 2], 15);
-+ FF(cc, dd, ee, aa, bb, X[ 3], 12);
-+ FF(bb, cc, dd, ee, aa, X[ 4], 5);
-+ FF(aa, bb, cc, dd, ee, X[ 5], 8);
-+ FF(ee, aa, bb, cc, dd, X[ 6], 7);
-+ FF(dd, ee, aa, bb, cc, X[ 7], 9);
-+ FF(cc, dd, ee, aa, bb, X[ 8], 11);
-+ FF(bb, cc, dd, ee, aa, X[ 9], 13);
-+ FF(aa, bb, cc, dd, ee, X[10], 14);
-+ FF(ee, aa, bb, cc, dd, X[11], 15);
-+ FF(dd, ee, aa, bb, cc, X[12], 6);
-+ FF(cc, dd, ee, aa, bb, X[13], 7);
-+ FF(bb, cc, dd, ee, aa, X[14], 9);
-+ FF(aa, bb, cc, dd, ee, X[15], 8);
-+
-+ /* round 2 */
-+ GG(ee, aa, bb, cc, dd, X[ 7], 7);
-+ GG(dd, ee, aa, bb, cc, X[ 4], 6);
-+ GG(cc, dd, ee, aa, bb, X[13], 8);
-+ GG(bb, cc, dd, ee, aa, X[ 1], 13);
-+ GG(aa, bb, cc, dd, ee, X[10], 11);
-+ GG(ee, aa, bb, cc, dd, X[ 6], 9);
-+ GG(dd, ee, aa, bb, cc, X[15], 7);
-+ GG(cc, dd, ee, aa, bb, X[ 3], 15);
-+ GG(bb, cc, dd, ee, aa, X[12], 7);
-+ GG(aa, bb, cc, dd, ee, X[ 0], 12);
-+ GG(ee, aa, bb, cc, dd, X[ 9], 15);
-+ GG(dd, ee, aa, bb, cc, X[ 5], 9);
-+ GG(cc, dd, ee, aa, bb, X[ 2], 11);
-+ GG(bb, cc, dd, ee, aa, X[14], 7);
-+ GG(aa, bb, cc, dd, ee, X[11], 13);
-+ GG(ee, aa, bb, cc, dd, X[ 8], 12);
-+
-+ /* round 3 */
-+ HH(dd, ee, aa, bb, cc, X[ 3], 11);
-+ HH(cc, dd, ee, aa, bb, X[10], 13);
-+ HH(bb, cc, dd, ee, aa, X[14], 6);
-+ HH(aa, bb, cc, dd, ee, X[ 4], 7);
-+ HH(ee, aa, bb, cc, dd, X[ 9], 14);
-+ HH(dd, ee, aa, bb, cc, X[15], 9);
-+ HH(cc, dd, ee, aa, bb, X[ 8], 13);
-+ HH(bb, cc, dd, ee, aa, X[ 1], 15);
-+ HH(aa, bb, cc, dd, ee, X[ 2], 14);
-+ HH(ee, aa, bb, cc, dd, X[ 7], 8);
-+ HH(dd, ee, aa, bb, cc, X[ 0], 13);
-+ HH(cc, dd, ee, aa, bb, X[ 6], 6);
-+ HH(bb, cc, dd, ee, aa, X[13], 5);
-+ HH(aa, bb, cc, dd, ee, X[11], 12);
-+ HH(ee, aa, bb, cc, dd, X[ 5], 7);
-+ HH(dd, ee, aa, bb, cc, X[12], 5);
-+
-+ /* round 4 */
-+ II(cc, dd, ee, aa, bb, X[ 1], 11);
-+ II(bb, cc, dd, ee, aa, X[ 9], 12);
-+ II(aa, bb, cc, dd, ee, X[11], 14);
-+ II(ee, aa, bb, cc, dd, X[10], 15);
-+ II(dd, ee, aa, bb, cc, X[ 0], 14);
-+ II(cc, dd, ee, aa, bb, X[ 8], 15);
-+ II(bb, cc, dd, ee, aa, X[12], 9);
-+ II(aa, bb, cc, dd, ee, X[ 4], 8);
-+ II(ee, aa, bb, cc, dd, X[13], 9);
-+ II(dd, ee, aa, bb, cc, X[ 3], 14);
-+ II(cc, dd, ee, aa, bb, X[ 7], 5);
-+ II(bb, cc, dd, ee, aa, X[15], 6);
-+ II(aa, bb, cc, dd, ee, X[14], 8);
-+ II(ee, aa, bb, cc, dd, X[ 5], 6);
-+ II(dd, ee, aa, bb, cc, X[ 6], 5);
-+ II(cc, dd, ee, aa, bb, X[ 2], 12);
-+
-+ /* round 5 */
-+ JJ(bb, cc, dd, ee, aa, X[ 4], 9);
-+ JJ(aa, bb, cc, dd, ee, X[ 0], 15);
-+ JJ(ee, aa, bb, cc, dd, X[ 5], 5);
-+ JJ(dd, ee, aa, bb, cc, X[ 9], 11);
-+ JJ(cc, dd, ee, aa, bb, X[ 7], 6);
-+ JJ(bb, cc, dd, ee, aa, X[12], 8);
-+ JJ(aa, bb, cc, dd, ee, X[ 2], 13);
-+ JJ(ee, aa, bb, cc, dd, X[10], 12);
-+ JJ(dd, ee, aa, bb, cc, X[14], 5);
-+ JJ(cc, dd, ee, aa, bb, X[ 1], 12);
-+ JJ(bb, cc, dd, ee, aa, X[ 3], 13);
-+ JJ(aa, bb, cc, dd, ee, X[ 8], 14);
-+ JJ(ee, aa, bb, cc, dd, X[11], 11);
-+ JJ(dd, ee, aa, bb, cc, X[ 6], 8);
-+ JJ(cc, dd, ee, aa, bb, X[15], 5);
-+ JJ(bb, cc, dd, ee, aa, X[13], 6);
-+
-+ /* parallel round 1 */
-+ JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
-+ JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
-+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
-+ JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
-+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
-+ JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
-+ JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
-+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
-+ JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
-+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
-+ JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
-+ JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
-+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
-+ JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
-+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
-+ JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
-+
-+ /* parallel round 2 */
-+ III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
-+ III(ddd, eee, aaa, bbb, ccc, X[11], 13);
-+ III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
-+ III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
-+ III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
-+ III(eee, aaa, bbb, ccc, ddd, X[13], 8);
-+ III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
-+ III(ccc, ddd, eee, aaa, bbb, X[10], 11);
-+ III(bbb, ccc, ddd, eee, aaa, X[14], 7);
-+ III(aaa, bbb, ccc, ddd, eee, X[15], 7);
-+ III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
-+ III(ddd, eee, aaa, bbb, ccc, X[12], 7);
-+ III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
-+ III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
-+ III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
-+ III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
-+
-+ /* parallel round 3 */
-+ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
-+ HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
-+ HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
-+ HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
-+ HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
-+ HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
-+ HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
-+ HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
-+ HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
-+ HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
-+ HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
-+ HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
-+ HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
-+ HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
-+ HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
-+ HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
-+
-+ /* parallel round 4 */
-+ GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
-+ GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
-+ GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
-+ GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
-+ GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
-+ GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
-+ GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
-+ GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
-+ GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
-+ GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
-+ GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
-+ GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
-+ GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
-+ GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
-+ GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
-+ GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
-+
-+ /* parallel round 5 */
-+ FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
-+ FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
-+ FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
-+ FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
-+ FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
-+ FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
-+ FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
-+ FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
-+ FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
-+ FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
-+ FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
-+ FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
-+ FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
-+ FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
-+ FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
-+ FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
-+
-+ /* combine results */
-+ ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
-+ MDbuf[1] = MDbuf[2] + dd + eee;
-+ MDbuf[2] = MDbuf[3] + ee + aaa;
-+ MDbuf[3] = MDbuf[4] + aa + bbb;
-+ MDbuf[4] = MDbuf[0] + bb + ccc;
-+ MDbuf[0] = ddd;
-+
-+ return;
-+}
-+
-+/********************************************************************/
-+
-+void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)
-+{
-+ unsigned int i; /* counter */
-+ dword X[16]; /* message words */
-+
-+ memset(X, 0, 16*sizeof(dword));
-+
-+ /* put bytes from strptr into X */
-+ for (i=0; i<(lswlen&63); i++) {
-+ /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
-+ X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
-+ }
-+
-+ /* append the bit m_n == 1 */
-+ X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
-+
-+ if ((lswlen & 63) > 55) {
-+ /* length goes to next block */
-+ compress(MDbuf, X);
-+ memset(X, 0, 16*sizeof(dword));
-+ }
-+
-+ /* append length in bits*/
-+ X[14] = lswlen << 3;
-+ X[15] = (lswlen >> 29) | (mswlen << 3);
-+ compress(MDbuf, X);
-+
-+ return;
-+}
-+
-+/************************ end of file rmd160.c **********************/
-+
---- /dev/null
-+++ b/net/rsa/rmd160.h
-@@ -0,0 +1,154 @@
-+/********************************************************************\
-+ *
-+ * FILE: rmd160.h
-+ *
-+ * CONTENTS: Header file for a sample C-implementation of the
-+ * RIPEMD-160 hash-function.
-+ * TARGET: any computer with an ANSI C compiler
-+ *
-+ * AUTHOR: Antoon Bosselaers, ESAT-COSIC
-+ * DATE: 1 March 1996
-+ * VERSION: 1.0
-+ *
-+ * Copyright (c) Katholieke Universiteit Leuven
-+ * 1996, All Rights Reserved
-+ *
-+ * Conditions for use of the RIPEMD-160 Software
-+ *
-+ * The RIPEMD-160 software is freely available for use under the terms and
-+ * conditions described hereunder, which shall be deemed to be accepted by
-+ * any user of the software and applicable on any use of the software:
-+ *
-+ * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
-+ * all purposes be considered the owner of the RIPEMD-160 software and of
-+ * all copyright, trade secret, patent or other intellectual property
-+ * rights therein.
-+ * 2. The RIPEMD-160 software is provided on an "as is" basis without
-+ * warranty of any sort, express or implied. K.U.Leuven makes no
-+ * representation that the use of the software will not infringe any
-+ * patent or proprietary right of third parties. User will indemnify
-+ * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
-+ * which may arise as a result of its use of the software. In no
-+ * circumstances K.U.Leuven R&D will be held liable for any deficiency,
-+ * fault or other mishappening with regard to the use or performance of
-+ * the software.
-+ * 3. User agrees to give due credit to K.U.Leuven in scientific publications
-+ * or communications in relation with the use of the RIPEMD-160 software
-+ * as follows: RIPEMD-160 software written by Antoon Bosselaers,
-+ * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
-+ *
-+\********************************************************************/
-+
-+#ifndef RMD160H /* make sure this file is read only once */
-+#define RMD160H
-+
-+/********************************************************************/
-+
-+/* typedef 8 and 32 bit types, resp. */
-+/* adapt these, if necessary,
-+ for your operating system and compiler */
-+typedef unsigned char byte;
-+typedef unsigned long dword;
-+
-+
-+/********************************************************************/
-+
-+/* macro definitions */
-+
-+/* collect four bytes into one word: */
-+#define BYTES_TO_DWORD(strptr) \
-+ (((dword) *((strptr)+3) << 24) | \
-+ ((dword) *((strptr)+2) << 16) | \
-+ ((dword) *((strptr)+1) << 8) | \
-+ ((dword) *(strptr)))
-+
-+/* ROL(x, n) cyclically rotates x over n bits to the left */
-+/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
-+#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-+
-+/* the five basic functions F(), G() and H() */
-+#define F(x, y, z) ((x) ^ (y) ^ (z))
-+#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
-+#define H(x, y, z) (((x) | ~(y)) ^ (z))
-+#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-+#define J(x, y, z) ((x) ^ ((y) | ~(z)))
-+
-+/* the ten basic operations FF() through III() */
-+#define FF(a, b, c, d, e, x, s) {\
-+ (a) += F((b), (c), (d)) + (x);\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define GG(a, b, c, d, e, x, s) {\
-+ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define HH(a, b, c, d, e, x, s) {\
-+ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define II(a, b, c, d, e, x, s) {\
-+ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define JJ(a, b, c, d, e, x, s) {\
-+ (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define FFF(a, b, c, d, e, x, s) {\
-+ (a) += F((b), (c), (d)) + (x);\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define GGG(a, b, c, d, e, x, s) {\
-+ (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define HHH(a, b, c, d, e, x, s) {\
-+ (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define III(a, b, c, d, e, x, s) {\
-+ (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+#define JJJ(a, b, c, d, e, x, s) {\
-+ (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
-+ (a) = ROL((a), (s)) + (e);\
-+ (c) = ROL((c), 10);\
-+ }
-+
-+/********************************************************************/
-+
-+/* function prototypes */
-+
-+void MDinit(dword *MDbuf);
-+/*
-+ * initializes MDbuffer to "magic constants"
-+ */
-+
-+void compress(dword *MDbuf, dword *X);
-+/*
-+ * the compression function.
-+ * transforms MDbuf using message bytes X[0] through X[15]
-+ */
-+
-+void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen);
-+/*
-+ * puts bytes from strptr into X and pad out; appends length
-+ * and finally, compresses the last block(s)
-+ * note: length in bits == 8 * (lswlen + 2^32 mswlen).
-+ * note: there are (lswlen mod 64) bytes left in strptr.
-+ */
-+
-+#endif /* RMD160H */
-+
-+/*********************** end of file rmd160.h ***********************/
-+
---- /dev/null
-+++ b/net/rsa/rsa.c
-@@ -0,0 +1,303 @@
-+/*
-+ * FONSM RSA handling library
-+ *
-+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * This library is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
-+ *
-+ * Based on axTLS
-+ *
-+ * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
-+ */
-+#include <malloc.h>
-+#include <common.h>
-+#include "rsa.h"
-+#include "rmd160.h"
-+#include "bigint.h"
-+#include "base64.h"
-+
-+#include "public_key.h"
-+
-+#define RMDsize 160 /* A RIPEMD-160 hash has 160 bits */
-+
-+typedef struct {
-+ uint8_t *buffer;
-+ size_t size;
-+} DER_key;
-+
-+typedef struct {
-+ bigint *m; /* modulus */
-+ bigint *e; /* public exponent */
-+ int num_octets;
-+ BI_CTX *bi_ctx; /* big integer handle */
-+} RSA_parameters;
-+
-+typedef struct {
-+ DER_key *derkey;
-+ RSA_parameters *rsaparms;
-+} RSA;
-+
-+static void CH_free_der_key(DER_key *key)
-+{
-+ free(key->buffer);
-+ free(key);
-+}
-+
-+int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
-+{
-+ bigint *dat_bi;
-+ bigint *decrypted_bi;
-+ int byte_size;
-+
-+ byte_size = rsa->num_octets;
-+ dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
-+ rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
-+ bi_copy(rsa->m);
-+ decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
-+ bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
-+ return 0;
-+}
-+
-+byte *RMDbinary(char *buffer, int len)
-+{
-+ byte data[1024]; /* contains current mess. block */
-+ dword nbytes; /* length of this block */
-+ dword MDbuf[RMDsize / 32]; /* contains (A, B, C, D(, E)) */
-+ static byte hashcode[RMDsize / 8]; /* for final hash-value */
-+ dword X[16]; /* current 16-word chunk */
-+ unsigned int i, j; /* counters */
-+ dword length[2]; /* length in bytes of message */
-+ dword offset; /* # of unprocessed bytes at */
-+ /* call of MDfinish */
-+ int total = len;
-+ char *tmp = buffer;
-+ MDinit(MDbuf);
-+ length[0] = 0;
-+ length[1] = 0;
-+ while ( len) {
-+ memcpy(data, tmp, 1024);
-+ if(len > 1024)
-+ {
-+ nbytes = 1024;
-+ len -= 1024;
-+ tmp += 1024;
-+ } else {
-+ nbytes = len;
-+ len = 0;
-+ }
-+ /* process all complete blocks */
-+ for (i = 0; i < (nbytes >> 6); i++) {
-+ for (j = 0; j < 16; j++)
-+ X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
-+ compress(MDbuf, X);
-+ }
-+ /* update length[] */
-+ if (length[0] + nbytes < length[0])
-+ length[1]++; /* overflow to msb of length */
-+ length[0] += nbytes;
-+ }
-+ /* finish: */
-+ offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
-+ MDfinish(MDbuf, data + offset, length[0], length[1]);
-+
-+ for (i = 0; i < RMDsize / 8; i += 4) {
-+ hashcode[i] = MDbuf[i >> 2];
-+ hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
-+ hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
-+ hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
-+ }
-+
-+ return (byte *) hashcode;
-+}
-+
-+static DER_key *CH_load_pem_key(void)
-+{
-+ DER_key *ret;
-+ uint8_t *buffer;
-+ char *b64,*p,*t;
-+ char key[1024];
-+ size_t filesize;
-+ int size;
-+
-+ if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
-+ return NULL;
-+ buffer = public_key;
-+ p = (char *)buffer;
-+ while ((*p != '\n') && (*p != '\0'))
-+ p++;
-+ if (*p == '\0') {
-+ free(ret);
-+ return NULL;
-+ }
-+ p++;
-+ b64 = t = p;
-+ while((p - b64) <= filesize) {
-+ if ((*p == '-')) {
-+ break;
-+ } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
-+ *t = *p;
-+ t++;
-+ }
-+ p++;
-+ }
-+ *t = '\0';
-+ size = B64_decode(b64, key, strlen(b64), 1024);
-+ if (size < 0) {
-+ free(buffer);
-+ free(ret);
-+ return NULL;
-+ }
-+ //free(buffer);
-+ ret->buffer = (char *)malloc(size);
-+ ret->size = size;
-+ memcpy((void *)ret->buffer, (void *)key, size);
-+ return ret;
-+}
-+
-+/*
-+ * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
-+ */
-+void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
-+{
-+ RSA_parameters *rsa_parameters;
-+
-+ BI_CTX *bi_ctx = bi_initialize();
-+ *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
-+ rsa_parameters = *rsa;
-+ rsa_parameters->bi_ctx = bi_ctx;
-+ rsa_parameters->num_octets = (mod_len & 0xFFF0);
-+ rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
-+ bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
-+ rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
-+ bi_permanent(rsa_parameters->e);
-+}
-+
-+/*
-+ * Get the public key specifics from an ASN.1 encoded file
-+ * A function lacking in the exported axTLS API
-+ *
-+ * This is a really weird hack that only works with RSA public key
-+ * files
-+ */
-+static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
-+{
-+ uint8_t *modulus, *pub_exp;
-+ int mod_len, pub_len;
-+
-+ pub_len = 3;
-+ mod_len = len - 37;
-+ if (buf[0] != 0x30) {
-+ return -1;
-+ }
-+
-+ pub_exp = (uint8_t *)malloc(3);
-+ modulus = (uint8_t *)malloc(mod_len);
-+ memcpy(modulus, buf + 32 , mod_len);
-+ memcpy(pub_exp, buf + 34 + mod_len, 3);
-+ if (mod_len <= 0 || pub_len <= 0 )
-+ return -1;
-+ CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
-+
-+ free(modulus);
-+ free(pub_exp);
-+ return 0;
-+}
-+
-+
-+/* FR_init */
-+void *FR_init(void)
-+{
-+ DER_key *derkey;
-+ RSA_parameters *rsa_parameters;
-+
-+ derkey = CH_load_pem_key();
-+ if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
-+ fprintf(stderr, "Error: Extracting public key from file\n");
-+ return 0;
-+ }
-+ CH_free_der_key(derkey);
-+ return (void *)rsa_parameters;
-+}
-+
-+FONRSA_ERROR FR_end(void *handle)
-+{
-+ RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
-+
-+ free(rsa_parameters);
-+ return FONRSA_OK;
-+}
-+
-+/*
-+ *
-+ * Implementation of PKCS 1.5 padding, borrowed from
-+ * Tom's code (public domain)
-+ */
-+
-+/* Standalone FR_verify_file */
-+FONRSA_ERROR FR_verify_file(void *handler, char *file_data, int file_len,
-+ char *signature_buffer, int signature_size)
-+{
-+ int j;
-+ byte *hashcode;
-+ byte hash[20];
-+ uint8_t *decrypted;
-+ RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
-+
-+ /* Calculates the RIPEMD-160 hash of the file */
-+ hashcode = RMDbinary (file_data, file_len);
-+
-+ if (rsa_parameters->num_octets != signature_size)
-+ return FONRSA_SIZE;
-+ decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
-+ if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
-+ printf("Error: Decrypting signature\n");
-+ return FONRSA_VERIFICATION_FAILURE;
-+ }
-+ memcpy(hash, decrypted + 492, 20);
-+ //free(decrypted);
-+ //free(signature_buffer);
-+ for (j = 0; j < RMDsize/8; j++) {
-+ if (hash[j] != hashcode[j])
-+ return FONRSA_VERIFICATION_FAILURE;
-+ }
-+ return FONRSA_OK;
-+}
-+
-+int rsa_check_signature(char *signature, int signature_len, char *buffer, int buffer_len)
-+{
-+ FONRSA_ERROR fonrsa_error;
-+ void *handle;
-+ handle = FR_init();
-+ if (handle == NULL) {
-+ printf("Error loading keys\n");
-+ return 1;
-+ }
-+ fonrsa_error = FR_verify_file(handle, buffer, buffer_len, signature, signature_len);
-+ FR_end(handle);
-+ switch (fonrsa_error) {
-+ case FONRSA_OK:
-+ printf("Verified OK\n");
-+ return 0;
-+ case FONRSA_VERIFICATION_FAILURE:
-+ printf("Verification failure\n");
-+ return 1;
-+ default:
-+ printf("Verification error\n");
-+ return -1;
-+ }
-+
-+}
---- /dev/null
-+++ b/net/rsa/rsa.h
-@@ -0,0 +1,46 @@
-+/*
-+ * FONSM RSA handling library, used by fonsmcd and foncheckrsa
-+ *
-+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * This library is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public License
-+ * along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
-+ *
-+ * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
-+ */
-+#ifndef _FONRSA_H
-+#define _FONRSA_H
-+
-+#define MINIMUM_PADING_BYTES_PKCS_1_5 3
-+
-+typedef enum {
-+ FONRSA_OK = 0,
-+ FONRSA_VERIFICATION_FAILURE = 1,
-+ FONRSA_OPENKEY = 2,
-+ FONRSA_SIZE = 3,
-+ FONRSA_LOADFILE = 4,
-+ FONRSA_CRYPT = 5,
-+ FONRSA_DECRYPT = 6,
-+ FONRSA_SAVEFILE = 7,
-+ FONRSA_NOSYS = 8,
-+ FONRSA_VERIFY = 9
-+} FONRSA_ERROR;
-+
-+int rsa_check_signature(char *signature, int signature_len, char *buffer, int buffer_len);
-+
-+#endif
-+
-+
---- /dev/null
-+++ b/net/rsa/sign.h
-@@ -0,0 +1,27 @@
-+/*
-+ * Signature interface
-+ *
-+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * Created: 20070417 Pablo MartÃn Medrano <pablo@fon.com>
-+ *
-+ * $Id: sign.h 389 2007-06-11 08:29:56Z pablo.martin $
-+ */
-+#ifndef __SIGN_H__
-+#define __SIGN_H__
-+#ifdef __cplusplus
-+ extern "C" {
-+#endif
-+
-+void SG_init(void);
-+void *SG_start(char *private_key_path, char *public_key_path);
-+void SG_stop(void *handle);
-+int SG_crypt(void *data, unsigned char *text, int size_text, unsigned char *crypted_text,
-+ unsigned int crypted_text_buffer_size, int *crypted_size);
-+int SG_crypt_v2(void *data, unsigned char *text, int size_text, unsigned char *crypted_text,
-+ unsigned int crypted_text_buffer_size, int *crypted_size);
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif /* #ifdef __SIGN_H__ */
-+
---- /dev/null
-+++ b/net/rsa/sign_openssl.c
-@@ -0,0 +1,437 @@
-+/*
-+ * Signature using OpenSSL
-+ *
-+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
-+ *
-+ * Created: 20070417 Pablo MartÃn Medrano <pablo@fon.com>
-+ *
-+ * $Id: sign_openssl.c 346 2007-05-10 19:51:38Z pablo.martin $
-+ */
-+/*
-+ *
-+ * How the RSA public and private key was generated
-+ * To check .FON files
-+ * openssl genrsa -out private_fon_rsa_key.pem 4096
-+ * openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
-+ *
-+ * How the Status Manager public and private key was generated
-+ * openssl genrsa -out private_sm_rsa_key.pem 2048
-+ * openssl rsa -in private_sm_rsa_key.pem -pubout -out public_sm_rsa_key.pem
-+ *
-+ * How to sign using the RSA private key (This is what fonsign does)
-+ * openssl dgst -rmd160 -sign private_fon_rsa_key.pem FILE > SIGNATURE
-+ * How to verify using the RSA public key (This is what fonverify + foncheckrsa does)
-+ * openssl dgst -rmd160 -verify public_fon_rsa_key.pem -signature SIGNATURE FILE
-+ * Convert to DER file (to use it in La Fonera)
-+ * openssl rsa -inform PEM -outform DER -pubin -in public_fon_rsa_key.pem -pubout -out public_fon_rsa_key.der
-+ */
-+#include <openssl/rsa.h>
-+#include <openssl/ssl.h>
-+#include <openssl/bn.h>
-+#include <openssl/pem.h>
-+#include <openssl/evp.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#ifndef __MAINTEST__
-+#include "log.h"
-+#else
-+#define fon_warning printf
-+#define fon_debug printf
-+#define fon_critical printf
-+#endif
-+#include "sign.h"
-+
-+typedef struct {
-+ RSA *rsa;
-+ int rsa_size;
-+ EVP_PKEY *pkey;
-+ int pkey_size;
-+ RSA *public_rsa;
-+ int public_rsa_size;
-+ EVP_PKEY *public_pkey;
-+ int public_pkey_size;
-+} Sign;
-+
-+typedef enum {
-+ KEY_PUBLIC = 0,
-+ KEY_PRIVATE
-+} KEY_TYPE;
-+
-+static EVP_PKEY *SG_load_key(char *key_path, KEY_TYPE type);
-+static unsigned char *load_file_in_buffer(char *path, int *size);
-+static int save_file_from_buffer(char *path, char *buffer, int size);
-+
-+void SG_init(void)
-+{
-+ SSL_load_error_strings();
-+ SSL_library_init();
-+ OpenSSL_add_all_algorithms();
-+ OpenSSL_add_all_ciphers();
-+ OpenSSL_add_all_digests();
-+}
-+
-+static unsigned char *load_file_in_buffer(char *path, int *size)
-+{
-+ char *buffer;
-+ struct stat st;
-+ int fd;
-+
-+ if (stat(path, &st))
-+ return NULL;
-+ buffer = (char *)malloc(st.st_size);
-+ if (buffer == NULL)
-+ return NULL;
-+ if ((fd = open(path, O_RDONLY)) == -1) {
-+ free(buffer);
-+ return NULL;
-+ }
-+ if (read(fd,buffer,st.st_size) != (ssize_t)st.st_size) {
-+ free(buffer);
-+ close(fd);
-+ return NULL;
-+ }
-+ *size = (int)st.st_size;
-+ close(fd);
-+ return buffer;
-+}
-+
-+static int save_file_from_buffer(char *path, char *buffer, int size)
-+{
-+ int fd;
-+
-+ if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
-+ return -1;
-+ if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
-+ close(fd);
-+ return -1;
-+ }
-+ close(fd);
-+ return 0;
-+}
-+
-+static EVP_PKEY *SG_load_key(char *key_path, KEY_TYPE type)
-+{
-+ BIO *key = NULL;
-+ EVP_PKEY *pkey;
-+
-+ if ((key = BIO_new(BIO_s_file())) == NULL) {
-+ //ERR_print_errors(err);
-+ fon_warning("%s: Error calling BIO_new()\n", __FUNCTION__);
-+ return NULL;
-+ }
-+ if (BIO_read_filename(key, key_path) <= 0) {
-+ fon_warning("%s: Error opening %s\n", __FUNCTION__, key_path);
-+ // ERR_print_errors(err);
-+ BIO_free(key);
-+ }
-+ if (type == KEY_PUBLIC) {
-+ pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
-+ } else if (type == KEY_PRIVATE) {
-+ pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
-+ } else {
-+ return NULL;
-+ }
-+
-+ if (pkey == NULL) {
-+ fon_warning("%s: Error reading %s\n", __FUNCTION__, key_path);
-+ BIO_free(key);
-+ return NULL;
-+ }
-+ BIO_free(key);
-+ return pkey;
-+}
-+
-+void *SG_start(char *private_key_path, char *public_key_path)
-+{
-+ Sign *sign;
-+
-+ if ((sign = (Sign *)malloc(sizeof(Sign))) == NULL)
-+ return NULL;
-+ memset(sign, 0, sizeof(Sign));
-+ if (private_key_path != NULL) {
-+ if ((sign->pkey = SG_load_key(private_key_path, KEY_PRIVATE)) == NULL) {
-+ fon_warning("%s: Error loading %s", __FUNCTION__, private_key_path);
-+ return NULL;
-+ }
-+ }
-+ if (public_key_path != NULL) {
-+ if ((sign->public_pkey = SG_load_key(public_key_path, KEY_PUBLIC)) == NULL) {
-+ fon_warning("%s: Error loading %s", __FUNCTION__, public_key_path);
-+ return NULL;
-+ }
-+ }
-+ if (sign->pkey != NULL) {
-+ sign->pkey_size = EVP_PKEY_size(sign->pkey);
-+ if ((sign->rsa = EVP_PKEY_get1_RSA(sign->pkey)) == NULL) {
-+ EVP_PKEY_free(sign->pkey);
-+ return NULL;
-+ }
-+ }
-+ if (sign->public_pkey != NULL) {
-+ sign->public_pkey_size = EVP_PKEY_size(sign->public_pkey);
-+ if ((sign->public_rsa = EVP_PKEY_get1_RSA(sign->public_pkey)) == NULL) {
-+ EVP_PKEY_free(sign->pkey);
-+ return NULL;
-+ }
-+ }
-+ if (((sign->rsa == NULL) && (private_key_path != NULL)) ||
-+ ((sign->public_rsa == NULL) && (public_key_path != NULL))) {
-+ fon_warning("%s: Error calling EVP_PKEY_get1_RSA()", __FUNCTION__);
-+ return NULL;
-+ }
-+ if (sign->rsa != NULL) {
-+ sign->rsa_size = RSA_size(sign->rsa);
-+ if (RSA_check_key(sign->rsa) != 1) {
-+ fon_warning("%s: RSA key failure", __FUNCTION__);
-+ return NULL;
-+ }
-+ }
-+
-+ return (void *)sign;
-+}
-+
-+void SG_stop(void *handle)
-+{
-+ Sign *sign = (Sign *)handle;
-+
-+ EVP_PKEY_free(sign->pkey);
-+ EVP_PKEY_free(sign->public_pkey);
-+ if (sign->rsa != NULL)
-+ RSA_free(sign->rsa);
-+ if (sign->public_rsa != NULL)
-+ RSA_free(sign->public_rsa);
-+ free(sign);
-+}
-+
-+int SG_verify(void *data, unsigned char *text, unsigned int size_text,
-+ unsigned char *signature, unsigned int size_signature)
-+{
-+ EVP_MD_CTX mdctx;
-+ EVP_MD *md;
-+ EVP_PKEY *pkey;
-+ int ret;
-+ Sign *sign = (Sign *)data;
-+
-+ md = (EVP_MD *)EVP_ripemd160();
-+ if(!EVP_VerifyInit(&mdctx, md))
-+ return 4;
-+ if (!EVP_VerifyUpdate(&mdctx, (const void *)text, (unsigned int)size_text)) {
-+ return 5;
-+ }
-+ ret = EVP_VerifyFinal(&mdctx, (const char *)signature, size_signature, sign->public_pkey);
-+ EVP_PKEY_free(pkey);
-+ EVP_MD_CTX_cleanup(&mdctx);
-+ return ret;
-+}
-+
-+int SG_sign(void *data, void *text, unsigned int size_text, void *signature_buffer,
-+ unsigned int size_signature_buffer, unsigned int *size_signature)
-+{
-+ unsigned char *digest[EVP_MAX_MD_SIZE];
-+ EVP_MD_CTX mdctx;
-+ EVP_MD *md;
-+ int ret;
-+ Sign *sign = (Sign *)data;
-+
-+ if (size_signature_buffer < sign->pkey_size)
-+ return 1;
-+
-+ md = (EVP_MD *)EVP_ripemd160();
-+ EVP_SignInit(&mdctx, md);
-+ if (!EVP_SignUpdate(&mdctx, (const void *)text, (unsigned int)size_text)) {
-+ return 2;
-+ }
-+ if (!EVP_SignFinal(&mdctx, (unsigned char *)signature_buffer, (unsigned int *)size_signature, sign->pkey)) {
-+ return 3;
-+ }
-+ EVP_MD_CTX_cleanup(&mdctx);
-+
-+ return 0;
-+}
-+
-+/*
-+ * It's not advised to crypt using RAW ... unless you have crypted the buffer using AES before.
-+ */
-+int SG_crypt(void *data, unsigned char *text, int size_text,
-+ unsigned char *crypted_text, unsigned int crypted_text_buffer_size,
-+ int *crypted_size)
-+{
-+ EVP_MD_CTX mdctx;
-+ EVP_MD *md;
-+ int retsize;
-+ Sign *sign = (Sign *)data;
-+
-+ if (crypted_text_buffer_size < sign->pkey_size) {
-+ fon_critical("%s: size_signature_buffer [%u] < %u", __FUNCTION__, size_text, sign->pkey_size);
-+ return 1;
-+ }
-+ if (size_text != sign->pkey_size) {
-+ fon_critical("%s: size_text [%u] != %u", __FUNCTION__, size_text, sign->pkey_size);
-+ return 2;
-+ }
-+ /* The buffer is pre-padded with random data ... */
-+ fon_debug("%s: About to call RSA_private_encrypt(%d, %x, %x, %x, %d)",
-+ __FUNCTION__, size_text, crypted_text, sign->rsa, RSA_NO_PADDING);
-+ retsize = RSA_private_encrypt(size_text, text, crypted_text, sign->rsa, RSA_NO_PADDING);
-+ if (retsize == -1) {
-+ fon_critical("%s: Error calling RSA_private_encrypt(%d, %x, %x, %x, %d)",
-+ __FUNCTION__, size_text, crypted_text, sign->rsa, RSA_NO_PADDING);
-+ return 1;
-+ }
-+ *crypted_size = retsize;
-+ return 0;
-+}
-+
-+/* SG_decrypt */
-+int SG_decrypt(void *data, unsigned char *cryptext, int cryptext_size, unsigned char *plaintext,
-+ int plaintext_buffer_size, int *plaintext_size)
-+{
-+ EVP_MD_CTX mdctx;
-+ EVP_MD *md;
-+ int retsize;
-+ Sign *sign = (Sign *)data;
-+
-+ if (plaintext_buffer_size < sign->public_pkey_size) {
-+ fon_critical("%s: plaintext_buffer_size [%u] < %u", __FUNCTION__, plaintext_buffer_size, sign->public_pkey_size);
-+ return 1;
-+ }
-+ if (cryptext_size != sign->public_pkey_size) {
-+ fon_critical("%s: cryptext_size [%u] != %u", __FUNCTION__, cryptext_size, sign->public_pkey_size);
-+ return 2;
-+ }
-+ retsize = RSA_public_decrypt(cryptext_size, cryptext, plaintext, sign->public_rsa, RSA_NO_PADDING);
-+ if (retsize == -1)
-+ return 1;
-+ *plaintext_size = retsize;
-+ return 0;
-+}
-+
-+#ifdef __MAINTEST__
-+int main(int argc, char **argv)
-+{
-+ size_t argv0_size;
-+ char *token;
-+
-+ argv0_size = strlen(argv[0]);
-+ if (argv0_size < 7) {
-+ fprintf(stderr, "%s?", argv[0]);
-+ return 1;
-+ }
-+ token = argv[0] + argv0_size - 7;
-+
-+ SG_init();
-+ if (!strcmp(token, "fonsign")) {
-+ return main_fonsign(argc, argv);
-+ } else if (!strcmp(token, "foncryp")) {
-+ return main_foncryp(argc, argv);
-+ }
-+ fprintf(stderr, "%s?", argv[0]);
-+ return 1;
-+}
-+
-+int main_foncryp(int argc, char **argv)
-+{
-+ void *handle = NULL;
-+ int encrypt = 0;
-+ char *filebuffer = NULL;
-+ char crypted[1024];
-+ int size, crypted_size, ret;
-+
-+ if (argc != 5) {
-+ printf("Usage: %s encrypt|decrypt <key_file> <file> <crypted_file>\n", argv[0]);
-+ return 1;
-+ }
-+ if (!strcmp(argv[1], "encrypt")) {
-+ printf("Encryption mode\n");
-+ encrypt = 1;
-+ } else
-+ printf("Decryption mode\n");
-+ if (encrypt)
-+ handle = SG_start(argv[2], NULL);
-+ else
-+ handle = SG_start(NULL, argv[2]);
-+ if (handle == NULL) {
-+ printf("Error loading keys\n");
-+ return 1;
-+ }
-+
-+ filebuffer = load_file_in_buffer(argv[3], &size);
-+ if (filebuffer == NULL) {
-+ printf("Error reading %s\n", argv[3]);
-+ SG_stop(handle);
-+ return 1;
-+ }
-+ if (encrypt)
-+ ret = SG_crypt(handle, filebuffer, size, crypted, 1024, &crypted_size);
-+ else
-+ ret = SG_decrypt(handle, filebuffer, size, crypted, 1024, &crypted_size);
-+
-+ if (ret) {
-+ printf("Error crypting %d bytes\n", size);
-+ SG_stop(handle);
-+ return 1;
-+ }
-+ printf("Crypted size %d\n", crypted_size);
-+ if (save_file_from_buffer(argv[4], crypted, crypted_size)) {
-+ printf("Error saving file\n");
-+ SG_stop(handle);
-+ return 1;
-+ }
-+
-+ SG_stop(handle);
-+ return 0;
-+}
-+
-+int main_fonsign(int argc, char **argv)
-+{
-+ void *handle = NULL;
-+ char signature_buffer[4096];
-+ char *signature;
-+ unsigned int signature_size;
-+ struct stat st;
-+ char *filebuffer = NULL;
-+ int size;
-+ int ret = -1;
-+
-+ if (argc != 5) {
-+ fprintf(stderr, "usage: %s <private_key_file> <public_key_file> <file_to_sign> <signature_file>\n", argv[0]);
-+ goto end;
-+ }
-+ handle = SG_start(argv[1], argv[2]);
-+ if (handle == NULL) {
-+ fprintf(stderr, "Error calling SG_start(%s)\n", argv[1]);
-+ goto end;
-+ }
-+ filebuffer = load_file_in_buffer(argv[3], &size);
-+ if (filebuffer == NULL) {
-+ fprintf(stderr, "Error reading %s\n", argv[3]);
-+ goto end;
-+ }
-+ if (SG_sign(handle, filebuffer, size, signature_buffer, 4096, &signature_size)) {
-+ fprintf(stderr, "Error calling SG_sign()\n");
-+ goto end;
-+ }
-+ ret = SG_verify(handle, filebuffer, size, signature_buffer, signature_size);
-+ if (ret == 0)
-+ fprintf(stderr, "signature failure\n");
-+ else if (ret == 1) {
-+ fprintf(stderr, "signature ok\n");
-+ ret = 0;
-+ } else {
-+ fprintf(stderr, "signature error\n");
-+ goto end;
-+ }
-+ if (save_file_from_buffer(argv[4], signature_buffer, signature_size)) {
-+ fprintf(stderr, "Error writing to %s\n", argv[4]);
-+ goto end;
-+ }
-+ ret = 0;
-+end:
-+ if (filebuffer != NULL)
-+ free(filebuffer);
-+ if (handle != NULL)
-+ SG_stop(handle);
-+ return ret;
-+}
-+#endif
-+
---- /dev/null
-+++ b/net/uip-0.9/Makefile
-@@ -0,0 +1,54 @@
-+# Copyright (c) 2001, Adam Dunkels.
-+# All rights reserved.
-+#
-+# Redistribution and use in source and binary forms, with or without
-+# modification, are permitted provided that the following conditions
-+# are met:
-+# 1. Redistributions of source code must retain the above copyright
-+# notice, this list of conditions and the following disclaimer.
-+# 2. Redistributions in binary form must reproduce the above copyright
-+# notice, this list of conditions and the following disclaimer in the
-+# documentation and/or other materials provided with the distribution.
-+# 3. All advertising materials mentioning features or use of this software
-+# must display the following acknowledgement:
-+# This product includes software developed by Adam Dunkels.
-+# 4. The name of the author may not be used to endorse or promote
-+# products derived from this software without specific prior
-+# written permission.
-+#
-+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+#
-+# This file is part of the uIP TCP/IP stack.
-+#
-+# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $
-+#
-+
-+CC=gcc
-+CFLAGS=-Wall -fpack-struct -DDUMP=0
-+
-+all: uip
-+
-+uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o
-+ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
-+
-+%.o: %.c
-+ $(CC) $(CFLAGS) -c $^ -o $@
-+
-+clean:
-+ rm -f *.o *~ *core uip
-+
-+
-+
-+
-+
-+
---- /dev/null
-+++ b/net/uip-0.9/fs.c
-@@ -0,0 +1,154 @@
-+/**
-+ * \addtogroup httpd
-+ * @{
-+ */
-+
-+/**
-+ * \file
-+ * HTTP server read-only file system code.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ *
-+ * A simple read-only filesystem.
-+ */
-+
-+/*
-+ * Copyright (c) 2001, Swedish Institute of Computer Science.
-+ * 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.
-+ *
-+ * 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 lwIP TCP/IP stack.
-+ *
-+ * Author: Adam Dunkels <adam@sics.se>
-+ *
-+ * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $
-+ */
-+
-+#include "uip.h"
-+#include "httpd.h"
-+#include "fs.h"
-+#include "fsdata.h"
-+
-+#include "fsdata.c"
-+
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+static u16_t count[FS_NUMFILES];
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+
-+/*-----------------------------------------------------------------------------------*/
-+static u8_t
-+fs_strcmp(const char *str1, const char *str2)
-+{
-+ u8_t i;
-+ i = 0;
-+ loop:
-+
-+ if(str2[i] == 0 ||
-+ str1[i] == '\r' ||
-+ str1[i] == '\n') {
-+ return 0;
-+ }
-+
-+ if(str1[i] != str2[i]) {
-+ return 1;
-+ }
-+
-+
-+ ++i;
-+ goto loop;
-+}
-+/*-----------------------------------------------------------------------------------*/
-+int
-+fs_open(const char *name, struct fs_file *file)
-+{
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+ u16_t i = 0;
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+ struct fsdata_file_noconst *f;
-+
-+ for(f = (struct fsdata_file_noconst *)FS_ROOT;
-+ f != NULL;
-+ f = (struct fsdata_file_noconst *)f->next) {
-+
-+ if(fs_strcmp(name, f->name) == 0) {
-+ file->data = f->data;
-+ file->len = f->len;
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+ ++count[i];
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+ return 1;
-+ }
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+ ++i;
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+
-+ }
-+ return 0;
-+}
-+/*-----------------------------------------------------------------------------------*/
-+void
-+fs_init(void)
-+{
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+ u16_t i;
-+ for(i = 0; i < FS_NUMFILES; i++) {
-+ count[i] = 0;
-+ }
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+}
-+/*-----------------------------------------------------------------------------------*/
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+u16_t fs_count
-+(char *name)
-+{
-+ struct fsdata_file_noconst *f;
-+ u16_t i;
-+
-+ i = 0;
-+ for(f = (struct fsdata_file_noconst *)FS_ROOT;
-+ f != NULL;
-+ f = (struct fsdata_file_noconst *)f->next) {
-+
-+ if(fs_strcmp(name, f->name) == 0) {
-+ return count[i];
-+ }
-+ ++i;
-+ }
-+ return 0;
-+}
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+/*-----------------------------------------------------------------------------------*/
---- /dev/null
-+++ b/net/uip-0.9/fs.h
-@@ -0,0 +1,80 @@
-+/**
-+ * \addtogroup httpd
-+ * @{
-+ */
-+
-+/**
-+ * \file
-+ * HTTP server read-only file system header file.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ */
-+
-+/*
-+ * Copyright (c) 2001, Swedish Institute of Computer Science.
-+ * 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.
-+ *
-+ * 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 lwIP TCP/IP stack.
-+ *
-+ * Author: Adam Dunkels <adam@sics.se>
-+ *
-+ * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $
-+ */
-+#ifndef __FS_H__
-+#define __FS_H__
-+
-+#include "uip.h"
-+
-+/**
-+ * An open file in the read-only file system.
-+ */
-+struct fs_file {
-+ char *data; /**< The actual file data. */
-+ int len; /**< The length of the file data. */
-+};
-+
-+/**
-+ * Open a file in the read-only file system.
-+ *
-+ * \param name The name of the file.
-+ *
-+ * \param file The file pointer, which must be allocated by caller and
-+ * will be filled in by the function.
-+ */
-+int fs_open(const char *name, struct fs_file *file);
-+
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+u16_t fs_count(char *name);
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+
-+/**
-+ * Initialize the read-only file system.
-+ */
-+void fs_init(void);
-+
-+#endif /* __FS_H__ */
---- /dev/null
-+++ b/net/uip-0.9/fsdata.c
-@@ -0,0 +1,199 @@
-+static const char data_flashing_html[] = {
-+ /* /flashing.html */
-+ 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
-+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
-+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
-+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
-+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
-+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
-+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
-+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
-+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
-+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
-+ 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
-+ 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
-+ 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
-+ 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
-+ 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
-+ 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
-+ 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
-+ 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
-+ 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
-+ 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
-+ 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
-+ 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
-+ 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
-+ 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
-+ 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
-+
-+static const char data_fail_html[] = {
-+ /* /fail.html */
-+ 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
-+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
-+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
-+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
-+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
-+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
-+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
-+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
-+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
-+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
-+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
-+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
-+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
-+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
-+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
-+ 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
-+ 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
-+ 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
-+ 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
-+ 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
-+ 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
-+ 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
-+ 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
-+ 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
-+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
-+ 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
-+ 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
-+ 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
-+ 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
-+ 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
-+ 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
-+ 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
-+ 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
-+ 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
-+ 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
-+ 0x3e, 0xa, };
-+
-+static const char data_404_html[] = {
-+ /* /404.html */
-+ 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
-+ 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
-+ 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
-+ 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
-+ 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
-+ 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
-+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
-+ 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
-+ 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
-+ 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
-+ 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
-+ 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
-+ 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
-+ 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
-+ 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
-+ 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
-+ 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
-+ 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
-+ 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
-+ 0x6c, 0x3e, };
-+
-+static const char data_index_html[] = {
-+ /* /index.html */
-+ 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
-+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
-+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
-+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
-+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
-+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
-+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
-+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
-+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
-+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
-+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
-+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
-+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
-+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
-+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
-+ 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
-+ 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
-+ 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
-+ 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
-+ 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
-+ 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
-+ 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
-+ 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
-+ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
-+ 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
-+ 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
-+ 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
-+ 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
-+ 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
-+ 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
-+ 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
-+ 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
-+ 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
-+ 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
-+ 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
-+ 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
-+ 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
-+ 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
-+ 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
-+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
-+ 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
-+ 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
-+
-+static const char data_flash_html[] = {
-+ /* /flash.html */
-+ 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
-+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
-+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
-+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
-+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
-+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
-+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
-+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
-+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
-+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
-+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
-+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
-+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
-+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
-+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
-+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
-+ 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
-+ 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
-+ 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
-+ 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
-+ 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
-+ 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
-+ 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
-+ 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
-+ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
-+ 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
-+ 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
-+ 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
-+ 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
-+ 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
-+ 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
-+ 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
-+ 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
-+ 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
-+ 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
-+ 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
-+ 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
-+ 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
-+ 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
-+ 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
-+ 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
-+ 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
-+ 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
-+ 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
-+
-+const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
-+
-+const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
-+
-+const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
-+
-+const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
-+
-+const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
-+
-+#define FS_ROOT file_flash_html
-+
-+#define FS_NUMFILES 5
-\ No newline at end of file
---- /dev/null
-+++ b/net/uip-0.9/fsdata.h
-@@ -0,0 +1,64 @@
-+/*
-+ * Copyright (c) 2001, Swedish Institute of Computer Science.
-+ * 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.
-+ *
-+ * 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 lwIP TCP/IP stack.
-+ *
-+ * Author: Adam Dunkels <adam@sics.se>
-+ *
-+ * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $
-+ */
-+#ifndef __FSDATA_H__
-+#define __FSDATA_H__
-+
-+#include "uipopt.h"
-+
-+struct fsdata_file {
-+ const struct fsdata_file *next;
-+ const char *name;
-+ const char *data;
-+ const int len;
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+ u16_t count;
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+};
-+
-+struct fsdata_file_noconst {
-+ struct fsdata_file *next;
-+ char *name;
-+ char *data;
-+ int len;
-+#ifdef FS_STATISTICS
-+#if FS_STATISTICS == 1
-+ u16_t count;
-+#endif /* FS_STATISTICS */
-+#endif /* FS_STATISTICS */
-+};
-+
-+#endif /* __FSDATA_H__ */
---- /dev/null
-+++ b/net/uip-0.9/httpd.c
-@@ -0,0 +1,278 @@
-+#include "uip.h"
-+#include "httpd.h"
-+#include "fs.h"
-+#include "fsdata.h"
-+#include <asm/addrspace.h>
-+
-+#define HTTP_NONE 0
-+#define HTTP_FILE 1
-+#define HTTP_FIRMWARE 2
-+
-+#define PRINT(x) printf("%s", x)
-+#define PRINTLN(x) printf("%s\n", x)
-+
-+extern unsigned long do_http_tmp_address(void);
-+
-+struct httpd_state *hs;
-+
-+extern const struct fsdata_file file_index_html;
-+extern const struct fsdata_file file_404_html;
-+extern const struct fsdata_file file_flash_html;
-+extern int httpd_upload_complete;
-+extern unsigned char *httpd_upload_data;
-+unsigned char *upload_data;
-+extern ulong NetBootFileXferSize;
-+int upload_running = 0;
-+
-+#define ISO_G 0x47
-+#define ISO_E 0x45
-+#define ISO_T 0x54
-+#define ISO_P 0x50
-+#define ISO_O 0x4f
-+#define ISO_S 0x53
-+#define ISO_T 0x54
-+#define ISO_slash 0x2f
-+#define ISO_c 0x63
-+#define ISO_g 0x67
-+#define ISO_i 0x69
-+#define ISO_space 0x20
-+#define ISO_nl 0x0a
-+#define ISO_cr 0x0d
-+#define ISO_a 0x61
-+#define ISO_t 0x74
-+#define ISO_hash 0x23
-+#define ISO_period 0x2e
-+
-+static char eol[3] = { 0x0d, 0x0a, 0x00 };
-+static char eol2[5] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00 };
-+static char boundary[128];
-+static int boundary_len = 0;
-+
-+/* we use this so that we can do without the ctype library */
-+#define is_digit(c) ((c) >= '0' && (c) <= '9')
-+static int atoi(const char *s)
-+{
-+ int i=0;
-+
-+ while (is_digit(*s))
-+ i = i*10 + *(s++) - '0';
-+ return i;
-+}
-+
-+void
-+httpd_init(void)
-+{
-+ fs_init();
-+ uip_listen(HTONS(80));
-+}
-+
-+void
-+httpd_appcall(void)
-+{
-+ struct fs_file fsfile;
-+ u8_t i;
-+ switch(uip_conn->lport) {
-+ case HTONS(80):
-+ hs = (struct httpd_state *)(uip_conn->appstate);
-+ if(uip_connected())
-+ {
-+ hs->state = HTTP_NONE;
-+ hs->count = 0;
-+ return;
-+ } else if(uip_poll())
-+ {
-+ if(hs->count++ >= 1000) {
-+ uip_abort();
-+ }
-+ return;
-+ } else if(uip_newdata() && hs->state == HTTP_NONE)
-+ {
-+ if(uip_appdata[0] == ISO_G &&
-+ uip_appdata[1] == ISO_E &&
-+ uip_appdata[2] == ISO_T &&
-+ uip_appdata[3] == ISO_space)
-+ {
-+ hs->state = HTTP_FILE;
-+ }
-+ if(uip_appdata[0] == ISO_P &&
-+ uip_appdata[1] == ISO_O &&
-+ uip_appdata[2] == ISO_S &&
-+ uip_appdata[3] == ISO_T &&
-+ uip_appdata[4] == ISO_space)
-+ {
-+ hs->state = HTTP_FIRMWARE;
-+ }
-+ if(hs->state == HTTP_NONE)
-+ {
-+ uip_abort();
-+ return;
-+ }
-+ if(hs->state == HTTP_FILE)
-+ {
-+ for(i = 4; i < 40; ++i)
-+ {
-+ if(uip_appdata[i] == ISO_space ||
-+ uip_appdata[i] == ISO_cr ||
-+ uip_appdata[i] == ISO_nl)
-+ {
-+ uip_appdata[i] = 0;
-+ break;
-+ }
-+ }
-+
-+ PRINT("request for file ");
-+ PRINTLN(&uip_appdata[4]);
-+ if(uip_appdata[4] == ISO_slash &&
-+ uip_appdata[5] == 0)
-+ {
-+ fs_open(file_index_html.name, &fsfile);
-+ } else {
-+ if(!fs_open((const char *)&uip_appdata[4], &fsfile))
-+ {
-+ PRINTLN("couldn't open file");
-+ fs_open(file_index_html.name, &fsfile);
-+ }
-+ }
-+ hs->script = 0;
-+ hs->state = HTTP_FILE;
-+ hs->dataptr = fsfile.data;
-+ hs->count = fsfile.len;
-+ }
-+ if(hs->state == HTTP_FIRMWARE)
-+ {
-+ unsigned char *start = (unsigned char*)uip_appdata;
-+ char *clen = strstr(start, "Content-Length:");
-+ int len = 0;
-+ unsigned char *next, *end;
-+ unsigned char *boundary_start;
-+ int i;
-+ uip_appdata[uip_len] = '\0';
-+ if(clen)
-+ {
-+ clen += sizeof("Content-Length:");
-+ next = strstr(clen, eol);
-+ if(next)
-+ {
-+ len = atoi(clen);
-+ next++;
-+ printf("expecting %d bytes\n", len);
-+ upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
-+ printf("received data will be stored at 0x%08X\n", upload_data);
-+ if(!upload_data)
-+ {
-+ printf("failed to allocate memory\n");
-+ uip_close();
-+ return;
-+ }
-+ } else {
-+ uip_close();
-+ return;
-+ }
-+ }
-+ if(len < 4 * 1024)
-+ {
-+ uip_close();
-+ return;
-+ }
-+ boundary_start = strstr(next, "---");
-+ if(!boundary_start)
-+ {
-+ uip_close();
-+ return;
-+ }
-+ end = strstr(boundary_start, eol);
-+ if(!eol)
-+ {
-+ uip_close();
-+ return;
-+ }
-+ boundary_len = end - boundary_start;
-+ memcpy(boundary, boundary_start, boundary_len);
-+ boundary[boundary_len] = 0;
-+ next = strstr(boundary_start, "name=\"firmware\";");
-+ if(!next)
-+ {
-+ uip_close();
-+ return;
-+ }
-+ next = strstr(next, eol2);
-+ if(!next)
-+ {
-+ printf("could not find start of data\n");
-+ uip_close();
-+ return;
-+ }
-+ next += 4;
-+ hs->script = 0;
-+ hs->state = HTTP_FIRMWARE;
-+ hs->upload = uip_len - (next - start);
-+ hs->upload_total = len - (int)(next - boundary_start);
-+ hs->upload_total -= (strlen(boundary) + 6);
-+ //printf("storing %d bytes at %p\n", (int)hs->upload, upload_data);
-+ for(i = 0; i < hs->upload; i++)
-+ upload_data[i] = next[i];
-+ upload_data += (int)hs->upload;
-+ printf("%d / %d\n", (int)hs->upload, hs->upload_total);
-+ uip_slen = 0;
-+ return;
-+ }
-+ }
-+
-+ if(hs->state == HTTP_FIRMWARE)
-+ {
-+ if(uip_newdata())
-+ {
-+ int i;
-+ hs->count = 0;
-+ uip_appdata[uip_len] = '\0';
-+ hs->upload += uip_len;
-+ //printf("storing %d bytes at %p\n", uip_len, upload_data);
-+ printf("%d / %d\n", (int)hs->upload, hs->upload_total);
-+ for(i = 0; i < uip_len; i++)
-+ upload_data[i] = uip_appdata[i];
-+ upload_data += uip_len;
-+ uip_slen = 0;
-+ if(hs->upload >= hs->upload_total)
-+ {
-+ upload_running = 1;
-+ NetBootFileXferSize = hs->upload_total;
-+ fs_open(file_flash_html.name, &fsfile);
-+ hs->script = 0;
-+ hs->state = HTTP_FILE;
-+ hs->dataptr = fsfile.data;
-+ hs->count = fsfile.len;
-+ }
-+ }
-+ }
-+ if(hs->state == HTTP_FILE)
-+ {
-+ if(uip_acked())
-+ {
-+ if(hs->count >= uip_conn->len)
-+ {
-+ hs->count -= uip_conn->len;
-+ hs->dataptr += uip_conn->len;
-+ } else {
-+ hs->count = 0;
-+ }
-+ if(hs->count == 0)
-+ {
-+ if(upload_running)
-+ {
-+ int i;
-+ httpd_upload_complete = 1;
-+ // for(i = 0; i < hs->upload_total; i++)
-+ // printf("%c", httpd_upload_data[i]);
-+ }
-+ uip_close();
-+ }
-+ }
-+ uip_send(hs->dataptr, hs->count);
-+ }
-+ break;
-+
-+ default:
-+ uip_abort();
-+ break;
-+ }
-+}
---- /dev/null
-+++ b/net/uip-0.9/httpd.h
-@@ -0,0 +1,83 @@
-+/**
-+ * \addtogroup httpd
-+ * @{
-+ */
-+
-+/**
-+ * \file
-+ * HTTP server header file.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ */
-+
-+/*
-+ * Copyright (c) 2001, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $
-+ *
-+ */
-+
-+#ifndef __HTTPD_H__
-+#define __HTTPD_H__
-+
-+void httpd_init(void);
-+void httpd_appcall(void);
-+
-+/* UIP_APPCALL: the name of the application function. This function
-+ must return void and take no arguments (i.e., C type "void
-+ appfunc(void)"). */
-+#ifndef UIP_APPCALL
-+#define UIP_APPCALL httpd_appcall
-+#endif
-+
-+struct httpd_state {
-+ u8_t state;
-+ u16_t count;
-+ char *dataptr;
-+ char *script;
-+ unsigned int upload;
-+ unsigned int upload_total;
-+};
-+
-+
-+/* UIP_APPSTATE_SIZE: The size of the application-specific state
-+ stored in the uip_conn structure. */
-+#ifndef UIP_APPSTATE_SIZE
-+#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
-+#endif
-+
-+#define FS_STATISTICS 1
-+
-+extern struct httpd_state *hs;
-+
-+
-+/* we copy the data to RAM+10MB */
-+#define TMP_DATA 0x8A100000
-+
-+#endif /* __HTTPD_H__ */
---- /dev/null
-+++ b/net/uip-0.9/main.c
-@@ -0,0 +1,88 @@
-+/*
-+ * Copyright (c) 2001-2003, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $
-+ *
-+ */
-+
-+
-+#include "uip.h"
-+#include "uip_arp.h"
-+#include "tapdev.h"
-+#include "httpd.h"
-+
-+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
-+
-+#ifndef NULL
-+#define NULL (void *)0
-+#endif /* NULL */
-+
-+/*-----------------------------------------------------------------------------------*/
-+int
-+main(void)
-+{
-+ u8_t i, arptimer;
-+ tapdev_init();
-+ uip_init();
-+ httpd_init();
-+ arptimer = 0;
-+ while(1) {
-+ uip_len = tapdev_read();
-+ if(uip_len == 0) {
-+ for(i = 0; i < UIP_CONNS; i++) {
-+ uip_periodic(i);
-+ if(uip_len > 0) {
-+ uip_arp_out();
-+ tapdev_send();
-+ }
-+ }
-+
-+ if(++arptimer == 20) {
-+ uip_arp_timer();
-+ arptimer = 0;
-+ }
-+ } else {
-+ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
-+ uip_arp_ipin();
-+ uip_input();
-+ if(uip_len > 0) {
-+ uip_arp_out();
-+ tapdev_send();
-+ }
-+ } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
-+ uip_arp_arpin();
-+ if(uip_len > 0) {
-+ tapdev_send();
-+ }
-+ }
-+ }
-+ }
-+ return 0;
-+}
---- /dev/null
-+++ b/net/uip-0.9/tapdev.c
-@@ -0,0 +1,192 @@
-+/*
-+ * Copyright (c) 2001, Swedish Institute of Computer Science.
-+ * 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.
-+ *
-+ * 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.
-+ *
-+ * Author: Adam Dunkels <adam@sics.se>
-+ *
-+ * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $
-+ */
-+
-+
-+#include <fcntl.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <sys/ioctl.h>
-+#include <sys/socket.h>
-+#include <sys/types.h>
-+#include <sys/time.h>
-+#include <sys/uio.h>
-+#include <sys/socket.h>
-+
-+#ifdef linux
-+#include <sys/ioctl.h>
-+#include <linux/if.h>
-+#include <linux/if_tun.h>
-+#define DEVTAP "/dev/net/tun"
-+#else /* linux */
-+#define DEVTAP "/dev/tap0"
-+#endif /* linux */
-+
-+#include "uip.h"
-+
-+static int fd;
-+
-+static unsigned long lasttime;
-+static struct timezone tz;
-+
-+/*-----------------------------------------------------------------------------------*/
-+void
-+tapdev_init(void)
-+{
-+ char buf[1024];
-+
-+ fd = open(DEVTAP, O_RDWR);
-+ if(fd == -1) {
-+ perror("tapdev: tapdev_init: open");
-+ exit(1);
-+ }
-+
-+#ifdef linux
-+ {
-+ struct ifreq ifr;
-+ memset(&ifr, 0, sizeof(ifr));
-+ ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
-+ if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
-+ perror(buf);
-+ exit(1);
-+ }
-+ }
-+#endif /* Linux */
-+
-+ snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
-+ UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);
-+ system(buf);
-+
-+ lasttime = 0;
-+}
-+
-+void dump_mem(int type, int len)
-+{
-+#if DUMP == 1
-+ int i;
-+ for(i = 0; i < len; i++)
-+ printf("%c", uip_buf[i]);
-+ if(type)
-+ {
-+ printf("\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01");
-+ printf("\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01");
-+ } else {
-+ printf("\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02");
-+ printf("\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02");
-+ }
-+ fflush(stdout);
-+#endif
-+}
-+
-+/*-----------------------------------------------------------------------------------*/
-+unsigned int
-+tapdev_read(void)
-+{
-+ fd_set fdset;
-+ struct timeval tv, now;
-+ int ret;
-+
-+ if(lasttime >= 500000) {
-+ lasttime = 0;
-+ return 0;
-+ }
-+
-+ tv.tv_sec = 0;
-+ tv.tv_usec = 500000 - lasttime;
-+
-+
-+ FD_ZERO(&fdset);
-+ FD_SET(fd, &fdset);
-+
-+ gettimeofday(&now, &tz);
-+ ret = select(fd + 1, &fdset, NULL, NULL, &tv);
-+ if(ret == 0) {
-+ lasttime = 0;
-+ return 0;
-+ }
-+ ret = read(fd, uip_buf, UIP_BUFSIZE);
-+ if(ret == -1) {
-+ perror("tap_dev: tapdev_read: read");
-+ }
-+ gettimeofday(&tv, &tz);
-+ lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
-+ dump_mem(0, ret);
-+ return ret;
-+}
-+/*-----------------------------------------------------------------------------------*/
-+void
-+tapdev_send(void)
-+{
-+ int ret;
-+ struct iovec iov[2];
-+
-+#ifdef linux
-+ {
-+ char tmpbuf[UIP_BUFSIZE];
-+ int i;
-+
-+ for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
-+ tmpbuf[i] = uip_buf[i];
-+ }
-+
-+ for(; i < uip_len; i++) {
-+ tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
-+ }
-+
-+ ret = write(fd, tmpbuf, uip_len);
-+ }
-+#else
-+
-+ if(uip_len < 40 + UIP_LLH_LEN) {
-+ ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN);
-+ } else {
-+ iov[0].iov_base = uip_buf;
-+ iov[0].iov_len = 40 + UIP_LLH_LEN;
-+ iov[1].iov_base = (char *)uip_appdata;
-+ iov[1].iov_len = uip_len - (40 + UIP_LLH_LEN);
-+
-+ ret = writev(fd, iov, 2);
-+ }
-+#endif
-+ dump_mem(1, ret);
-+
-+ if(ret == -1) {
-+ perror("tap_dev: tapdev_send: writev");
-+ exit(1);
-+ }
-+}
-+/*-----------------------------------------------------------------------------------*/
---- /dev/null
-+++ b/net/uip-0.9/tapdev.h
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright (c) 2001, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: tapdev.h,v 1.1.2.1 2003/10/04 22:54:17 adam Exp $
-+ *
-+ */
-+
-+#ifndef __TAPDEV_H__
-+#define __TAPDEV_H__
-+
-+void tapdev_init(void);
-+unsigned int tapdev_read(void);
-+void tapdev_send(void);
-+
-+#endif /* __TAPDEV_H__ */
---- /dev/null
-+++ b/net/uip-0.9/uip.c
-@@ -0,0 +1,1503 @@
-+/**
-+ * \addtogroup uip
-+ * @{
-+ */
-+
-+/**
-+ * \file
-+ * The uIP TCP/IP stack code.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ */
-+
-+/*
-+ * Copyright (c) 2001-2003, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
-+ *
-+ */
-+
-+/*
-+This is a small implementation of the IP and TCP protocols (as well as
-+some basic ICMP stuff). The implementation couples the IP, TCP and the
-+application layers very tightly. To keep the size of the compiled code
-+down, this code also features heavy usage of the goto statement.
-+
-+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 stack
-+parses the headers in the packet, and calls upon the application. If
-+the remote host has sent data to the application, this data is present
-+in the uip_buf and the application read the data from there. It is up
-+to the application to put this data into a byte stream if needed. The
-+application will not be fed with data that is out of sequence.
-+
-+If the application whishes to send data to the peer, it should put its
-+data into the uip_buf, 40 bytes from the start of the buffer. The
-+TCP/IP stack will calculate the checksums, and fill in the necessary
-+header fields and finally send the packet back to the peer.
-+*/
-+
-+#include "uip.h"
-+#include "uipopt.h"
-+#include "uip_arch.h"
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* Variable definitions. */
-+
-+
-+/* The IP address of this host. If it is defined to be fixed (by setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set here. Otherwise, the address */
-+#if UIP_FIXEDADDR > 0
-+const unsigned short int uip_hostaddr[2] =
-+ {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
-+ HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
-+const unsigned short int uip_arp_draddr[2] =
-+ {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
-+ HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
-+const unsigned short int uip_arp_netmask[2] =
-+ {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
-+ HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
-+#else
-+unsigned short int uip_hostaddr[2];
-+unsigned short int uip_arp_draddr[2], uip_arp_netmask[2];
-+#endif /* UIP_FIXEDADDR */
-+
-+u8_t uip_buf[UIP_BUFSIZE+2]; /* The packet buffer that contains
-+ incoming packets. */
-+volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
-+ application data. */
-+volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to the
-+ application data which is to be sent. */
-+#if UIP_URGDATA > 0
-+volatile u8_t *uip_urgdata; /* The uip_urgdata pointer points to
-+ urgent data (out-of-band data), if
-+ present. */
-+volatile u8_t uip_urglen, uip_surglen;
-+#endif /* UIP_URGDATA > 0 */
-+
-+volatile unsigned short int uip_len, uip_slen;
-+ /* The uip_len is either 8 or 16 bits,
-+ depending on the maximum packet
-+ size. */
-+
-+volatile u8_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
-+ connection. */
-+
-+struct uip_conn uip_conns[UIP_CONNS];
-+ /* The uip_conns array holds all TCP
-+ connections. */
-+unsigned short int uip_listenports[UIP_LISTENPORTS];
-+ /* The uip_listenports list all currently
-+ listning ports. */
-+#if UIP_UDP
-+struct uip_udp_conn *uip_udp_conn;
-+struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
-+#endif /* UIP_UDP */
-+
-+
-+static unsigned short int ipid; /* Ths ipid variable is an increasing
-+ number that is used for the IP ID
-+ field. */
-+
-+static u8_t iss[4]; /* The iss variable is used for the TCP
-+ initial sequence number. */
-+
-+#if UIP_ACTIVE_OPEN
-+static unsigned short int lastport; /* Keeps track of the last port used for
-+ a new connection. */
-+#endif /* UIP_ACTIVE_OPEN */
-+
-+/* Temporary variables. */
-+volatile u8_t uip_acc32[4];
-+static u8_t c, opt;
-+static unsigned short int tmp16;
-+
-+/* Structures and definitions. */
-+#define TCP_FIN 0x01
-+#define TCP_SYN 0x02
-+#define TCP_RST 0x04
-+#define TCP_PSH 0x08
-+#define TCP_ACK 0x10
-+#define TCP_URG 0x20
-+#define TCP_CTL 0x3f
-+
-+#define ICMP_ECHO_REPLY 0
-+#define ICMP_ECHO 8
-+
-+/* Macros. */
-+#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
-+#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
-+#define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
-+#define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
-+
-+#if UIP_STATISTICS == 1
-+struct uip_stats uip_stat;
-+#define UIP_STAT(s) s
-+#else
-+#define UIP_STAT(s)
-+#endif /* UIP_STATISTICS == 1 */
-+
-+#if UIP_LOGGING == 1
-+extern void puts(const char *s);
-+#define UIP_LOG(m) puts(m)
-+#else
-+#define UIP_LOG(m)
-+#endif /* UIP_LOGGING == 1 */
-+
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_init(void)
-+{
-+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
-+ uip_listenports[c] = 0;
-+ }
-+ for(c = 0; c < UIP_CONNS; ++c) {
-+ uip_conns[c].tcpstateflags = CLOSED;
-+ }
-+#if UIP_ACTIVE_OPEN
-+ lastport = 1024;
-+#endif /* UIP_ACTIVE_OPEN */
-+
-+#if UIP_UDP
-+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
-+ uip_udp_conns[c].lport = 0;
-+ }
-+#endif /* UIP_UDP */
-+
-+
-+ /* IPv4 initialization. */
-+#if UIP_FIXEDADDR == 0
-+ uip_hostaddr[0] = uip_hostaddr[1] = 0;
-+#endif /* UIP_FIXEDADDR */
-+
-+}
-+/*-----------------------------------------------------------------------------------*/
-+#if UIP_ACTIVE_OPEN
-+struct uip_conn *
-+uip_connect(unsigned short int *ripaddr, unsigned short int rport)
-+{
-+ register struct uip_conn *conn, *cconn;
-+
-+ /* Find an unused local port. */
-+ again:
-+ ++lastport;
-+
-+ if(lastport >= 32000) {
-+ lastport = 4096;
-+ }
-+
-+ /* Check if this port is already in use, and if so try to find
-+ another one. */
-+ for(c = 0; c < UIP_CONNS; ++c) {
-+ conn = &uip_conns[c];
-+ if(conn->tcpstateflags != CLOSED &&
-+ conn->lport == htons(lastport)) {
-+ goto again;
-+ }
-+ }
-+
-+
-+ conn = 0;
-+ for(c = 0; c < UIP_CONNS; ++c) {
-+ cconn = &uip_conns[c];
-+ if(cconn->tcpstateflags == CLOSED) {
-+ conn = cconn;
-+ break;
-+ }
-+ if(cconn->tcpstateflags == TIME_WAIT) {
-+ if(conn == 0 ||
-+ cconn->timer > uip_conn->timer) {
-+ conn = cconn;
-+ }
-+ }
-+ }
-+
-+ if(conn == 0) {
-+ return 0;
-+ }
-+
-+ conn->tcpstateflags = SYN_SENT;
-+
-+ conn->snd_nxt[0] = iss[0];
-+ conn->snd_nxt[1] = iss[1];
-+ conn->snd_nxt[2] = iss[2];
-+ 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->rto = UIP_RTO;
-+ conn->sa = 0;
-+ conn->sv = 16;
-+ conn->lport = htons(lastport);
-+ conn->rport = rport;
-+ conn->ripaddr[0] = ripaddr[0];
-+ conn->ripaddr[1] = ripaddr[1];
-+
-+ return conn;
-+}
-+#endif /* UIP_ACTIVE_OPEN */
-+/*-----------------------------------------------------------------------------------*/
-+#if UIP_UDP
-+struct uip_udp_conn *
-+uip_udp_new(unsigned short int *ripaddr, unsigned short int rport)
-+{
-+ register struct uip_udp_conn *conn;
-+
-+ /* Find an unused local port. */
-+ again:
-+ ++lastport;
-+
-+ if(lastport >= 32000) {
-+ lastport = 4096;
-+ }
-+
-+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
-+ if(uip_udp_conns[c].lport == lastport) {
-+ goto again;
-+ }
-+ }
-+
-+
-+ conn = 0;
-+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
-+ if(uip_udp_conns[c].lport == 0) {
-+ conn = &uip_udp_conns[c];
-+ break;
-+ }
-+ }
-+
-+ if(conn == 0) {
-+ return 0;
-+ }
-+
-+ conn->lport = HTONS(lastport);
-+ conn->rport = HTONS(rport);
-+ conn->ripaddr[0] = ripaddr[0];
-+ conn->ripaddr[1] = ripaddr[1];
-+
-+ return conn;
-+}
-+#endif /* UIP_UDP */
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_unlisten(unsigned short int port)
-+{
-+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
-+ if(uip_listenports[c] == port) {
-+ uip_listenports[c] = 0;
-+ return;
-+ }
-+ }
-+}
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_listen(unsigned short int port)
-+{
-+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
-+ if(uip_listenports[c] == 0) {
-+ uip_listenports[c] = port;
-+ return;
-+ }
-+ }
-+}
-+/*-----------------------------------------------------------------------------------*/
-+/* XXX: IP fragment reassembly: not well-tested. */
-+
-+#if UIP_REASSEMBLY
-+#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,
-+ 0x0f, 0x07, 0x03, 0x01};
-+static unsigned short int uip_reasslen;
-+static u8_t uip_reassflags;
-+#define UIP_REASS_FLAG_LASTFRAG 0x01
-+static u8_t uip_reasstmr;
-+
-+#define IP_HLEN 20
-+#define IP_MF 0x20
-+
-+static u8_t
-+uip_reass(void)
-+{
-+ unsigned short int offset, len;
-+ unsigned short int 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
-+ buffer. The timer is updated with the maximum age. */
-+ if(uip_reasstmr == 0) {
-+ memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
-+ uip_reasstmr = UIP_REASS_MAXAGE;
-+ uip_reassflags = 0;
-+ /* Clear the bitmap. */
-+ memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
-+ }
-+
-+ /* Check if the incoming fragment matches the one currently present
-+ in the reasembly buffer. If so, we proceed with copying the
-+ fragment into the buffer. */
-+ if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
-+ BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
-+ BUF->destipaddr[0] == FBUF->destipaddr[0] &&
-+ BUF->destipaddr[1] == FBUF->destipaddr[1] &&
-+ BUF->ipid[0] == FBUF->ipid[0] &&
-+ BUF->ipid[1] == FBUF->ipid[1]) {
-+
-+ len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
-+ offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
-+
-+ /* If the offset or the offset + fragment length overflows the
-+ reassembly buffer, we discard the entire packet. */
-+ if(offset > UIP_REASS_BUFSIZE ||
-+ offset + len > UIP_REASS_BUFSIZE) {
-+ uip_reasstmr = 0;
-+ goto nullreturn;
-+ }
-+
-+ /* Copy the fragment into the reassembly buffer, at the right
-+ offset. */
-+ memcpy(&uip_reassbuf[IP_HLEN + 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. */
-+
-+ 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
-+ 0xff. */
-+ uip_reassbitmap[offset / (8 * 8)] |=
-+ bitmap_bits[(offset / 8 ) & 7];
-+ for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
-+ uip_reassbitmap[i] = 0xff;
-+ }
-+ 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
-+ IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
-+ the final fragment. */
-+
-+ if((BUF->ipoffset[0] & IP_MF) == 0) {
-+ 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. */
-+ if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
-+ /* Check all bytes up to and including all but the last byte in
-+ the bitmap. */
-+ for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
-+ if(uip_reassbitmap[i] != 0xff) {
-+ goto nullreturn;
-+ }
-+ }
-+ /* 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]) {
-+ goto nullreturn;
-+ }
-+
-+ /* If we have come this far, we have a full packet in the
-+ buffer, so we allocate a pbuf and copy the packet into it. We
-+ also reset the timer. */
-+ uip_reasstmr = 0;
-+ memcpy(BUF, FBUF, uip_reasslen);
-+
-+ /* Pretend to be a "normal" (i.e., not fragmented) IP packet
-+ from now on. */
-+ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
-+ BUF->len[0] = uip_reasslen >> 8;
-+ BUF->len[1] = uip_reasslen & 0xff;
-+ BUF->ipchksum = 0;
-+ BUF->ipchksum = ~(uip_ipchksum());
-+
-+ return uip_reasslen;
-+ }
-+ }
-+
-+ nullreturn:
-+ return 0;
-+}
-+#endif /* UIP_REASSEMBL */
-+/*-----------------------------------------------------------------------------------*/
-+static void
-+uip_add_rcv_nxt(unsigned short int n)
-+{
-+ uip_add32(uip_conn->rcv_nxt, n);
-+ uip_conn->rcv_nxt[0] = uip_acc32[0];
-+ uip_conn->rcv_nxt[1] = uip_acc32[1];
-+ uip_conn->rcv_nxt[2] = uip_acc32[2];
-+ uip_conn->rcv_nxt[3] = uip_acc32[3];
-+}
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_process(u8_t flag)
-+{
-+ register struct uip_conn *uip_connr = uip_conn;
-+
-+ uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
-+
-+
-+ /* Check if we were invoked because of the perodic timer fireing. */
-+ if(flag == UIP_TIMER) {
-+#if UIP_REASSEMBLY
-+ if(uip_reasstmr != 0) {
-+ --uip_reasstmr;
-+ }
-+#endif /* UIP_REASSEMBLY */
-+ /* Increase the initial sequence number. */
-+ if(++iss[3] == 0) {
-+ if(++iss[2] == 0) {
-+ if(++iss[1] == 0) {
-+ ++iss[0];
-+ }
-+ }
-+ }
-+ uip_len = 0;
-+ if(uip_connr->tcpstateflags == TIME_WAIT ||
-+ uip_connr->tcpstateflags == FIN_WAIT_2) {
-+ ++(uip_connr->timer);
-+ if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
-+ uip_connr->tcpstateflags = CLOSED;
-+ }
-+ } else if(uip_connr->tcpstateflags != CLOSED) {
-+ /* 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 ||
-+ ((uip_connr->tcpstateflags == SYN_SENT ||
-+ uip_connr->tcpstateflags == SYN_RCVD) &&
-+ uip_connr->nrtx == UIP_MAXSYNRTX)) {
-+ uip_connr->tcpstateflags = CLOSED;
-+
-+ /* We call UIP_APPCALL() with uip_flags set to
-+ UIP_TIMEDOUT to inform the application that the
-+ connection has timed out. */
-+ uip_flags = UIP_TIMEDOUT;
-+ UIP_APPCALL();
-+
-+ /* We also send a reset packet to the remote host. */
-+ BUF->flags = TCP_RST | TCP_ACK;
-+ goto tcp_send_nodata;
-+ }
-+
-+ /* Exponential backoff. */
-+ 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
-+ data for the retransmit. In SYN_RCVD, we resend the
-+ SYNACK that we sent earlier and in LAST_ACK we have to
-+ retransmit our FINACK. */
-+ UIP_STAT(++uip_stat.tcp.rexmit);
-+ switch(uip_connr->tcpstateflags & TS_MASK) {
-+ case SYN_RCVD:
-+ /* In the SYN_RCVD state, we should retransmit our
-+ SYNACK. */
-+ goto tcp_send_synack;
-+
-+#if UIP_ACTIVE_OPEN
-+ case SYN_SENT:
-+ /* In the SYN_SENT state, we retransmit out SYN. */
-+ BUF->flags = 0;
-+ goto tcp_send_syn;
-+#endif /* UIP_ACTIVE_OPEN */
-+
-+ case ESTABLISHED:
-+ /* In the ESTABLISHED state, we call upon the application
-+ to do the actual retransmit after which we jump into
-+ the code for sending out the packet (the apprexmit
-+ label). */
-+ uip_len = 0;
-+ uip_slen = 0;
-+ uip_flags = UIP_REXMIT;
-+ UIP_APPCALL();
-+ goto apprexmit;
-+
-+ case FIN_WAIT_1:
-+ case CLOSING:
-+ case LAST_ACK:
-+ /* In all these states we should retransmit a FINACK. */
-+ goto tcp_send_finack;
-+
-+ }
-+ }
-+ } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
-+ /* If there was no need for a retransmission, we poll the
-+ application for new data. */
-+ uip_len = 0;
-+ uip_slen = 0;
-+ uip_flags = UIP_POLL;
-+ UIP_APPCALL();
-+ goto appsend;
-+ }
-+ }
-+ goto drop;
-+ }
-+#if UIP_UDP
-+ if(flag == UIP_UDP_TIMER) {
-+ if(uip_udp_conn->lport != 0) {
-+ uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
-+ uip_len = uip_slen = 0;
-+ uip_flags = UIP_POLL;
-+ UIP_UDP_APPCALL();
-+ goto udp_send;
-+ } else {
-+ goto drop;
-+ }
-+ }
-+#endif
-+
-+ /* This is where the input processing starts. */
-+ UIP_STAT(++uip_stat.ip.recv);
-+
-+
-+ /* Start of IPv4 input header processing code. */
-+
-+ /* Check validity of the IP header. */
-+ if(BUF->vhl != 0x45) { /* IP version and header length. */
-+ UIP_STAT(++uip_stat.ip.drop);
-+ UIP_STAT(++uip_stat.ip.vhlerr);
-+ UIP_LOG("ip: invalid version or header length.");
-+ goto drop;
-+ }
-+
-+ /* Check the size of the packet. If the size reported to us in
-+ uip_len doesn't match the size reported in the IP header, there
-+ has been a transmission error and we drop the packet. */
-+
-+ if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
-+ uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
-+ }
-+ if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
-+ uip_len = (uip_len & 0xff00) | BUF->len[1];
-+ }
-+
-+ /* Check the fragment flag. */
-+ if((BUF->ipoffset[0] & 0x3f) != 0 ||
-+ BUF->ipoffset[1] != 0) {
-+#if UIP_REASSEMBLY
-+ uip_len = uip_reass();
-+ if(uip_len == 0) {
-+ goto drop;
-+ }
-+#else
-+ UIP_STAT(++uip_stat.ip.drop);
-+ UIP_STAT(++uip_stat.ip.fragerr);
-+ UIP_LOG("ip: fragment dropped.");
-+ goto drop;
-+#endif /* UIP_REASSEMBLY */
-+ }
-+
-+ /* 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 UIP_PINGADDRCONF
-+ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
-+ if(BUF->proto == UIP_PROTO_ICMP) {
-+ UIP_LOG("ip: possible ping config packet received.");
-+ goto icmp_input;
-+ } else {
-+ UIP_LOG("ip: packet dropped since no address assigned.");
-+ goto drop;
-+ }
-+ }
-+#endif /* UIP_PINGADDRCONF */
-+
-+ /* Check if the packet is destined for our IP address. */
-+ if(BUF->destipaddr[0] != uip_hostaddr[0]) {
-+ UIP_STAT(++uip_stat.ip.drop);
-+ UIP_LOG("ip: packet not for us.");
-+ goto drop;
-+ }
-+ if(BUF->destipaddr[1] != uip_hostaddr[1]) {
-+ UIP_STAT(++uip_stat.ip.drop);
-+ UIP_LOG("ip: packet not for us.");
-+ goto drop;
-+ }
-+
-+ if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
-+ checksum. */
-+ UIP_STAT(++uip_stat.ip.drop);
-+ UIP_STAT(++uip_stat.ip.chkerr);
-+ UIP_LOG("ip: bad checksum.");
-+ goto drop;
-+ }
-+
-+ if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump
-+ to the tcp_input label. */
-+ goto tcp_input;
-+
-+#if UIP_UDP
-+ if(BUF->proto == UIP_PROTO_UDP)
-+ goto udp_input;
-+#endif /* UIP_UDP */
-+
-+ if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
-+ here. */
-+ UIP_STAT(++uip_stat.ip.drop);
-+ UIP_STAT(++uip_stat.ip.protoerr);
-+ UIP_LOG("ip: neither tcp nor icmp.");
-+ goto drop;
-+ }
-+
-+ //icmp_input:
-+ UIP_STAT(++uip_stat.icmp.recv);
-+
-+ /* ICMP echo (i.e., ping) processing. This is simple, we only change
-+ the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
-+ checksum before we return the packet. */
-+ if(ICMPBUF->type != ICMP_ECHO) {
-+ UIP_STAT(++uip_stat.icmp.drop);
-+ UIP_STAT(++uip_stat.icmp.typeerr);
-+ UIP_LOG("icmp: not icmp echo.");
-+ goto drop;
-+ }
-+
-+ /* 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. */
-+#if UIP_PINGADDRCONF
-+ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
-+ uip_hostaddr[0] = BUF->destipaddr[0];
-+ uip_hostaddr[1] = BUF->destipaddr[1];
-+ }
-+#endif /* UIP_PINGADDRCONF */
-+
-+ ICMPBUF->type = ICMP_ECHO_REPLY;
-+
-+ if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
-+ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
-+ } else {
-+ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
-+ }
-+
-+ /* Swap IP addresses. */
-+ 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_STAT(++uip_stat.icmp.sent);
-+ goto send;
-+
-+ /* End of IPv4 input header processing code. */
-+
-+
-+#if UIP_UDP
-+ /* UDP input processing. */
-+ udp_input:
-+ /* UDP processing is really just a hack. We don't do anything to the
-+ UDP/IP headers, but let the UDP application do all the hard
-+ work. If the application sets uip_slen, it has a packet to
-+ send. */
-+#if UIP_UDP_CHECKSUMS
-+ if(uip_udpchksum() != 0xffff) {
-+ UIP_STAT(++uip_stat.udp.drop);
-+ UIP_STAT(++uip_stat.udp.chkerr);
-+ UIP_LOG("udp: bad checksum.");
-+ goto drop;
-+ }
-+#endif /* UIP_UDP_CHECKSUMS */
-+
-+ /* 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];
-+ ++uip_udp_conn) {
-+ if(uip_udp_conn->lport != 0 &&
-+ UDPBUF->destport == uip_udp_conn->lport &&
-+ (uip_udp_conn->rport == 0 ||
-+ UDPBUF->srcport == uip_udp_conn->rport) &&
-+ BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
-+ BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
-+ goto udp_found;
-+ }
-+ }
-+ goto drop;
-+
-+ udp_found:
-+ uip_len = uip_len - 28;
-+ uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
-+ uip_flags = UIP_NEWDATA;
-+ uip_slen = 0;
-+ UIP_UDP_APPCALL();
-+ udp_send:
-+ if(uip_slen == 0) {
-+ goto drop;
-+ }
-+ uip_len = uip_slen + 28;
-+
-+ BUF->len[0] = (uip_len >> 8);
-+ BUF->len[1] = (uip_len & 0xff);
-+
-+ BUF->proto = UIP_PROTO_UDP;
-+
-+ UDPBUF->udplen = HTONS(uip_slen + 8);
-+ UDPBUF->udpchksum = 0;
-+#if UIP_UDP_CHECKSUMS
-+ /* Calculate UDP checksum. */
-+ UDPBUF->udpchksum = ~(uip_udpchksum());
-+ if(UDPBUF->udpchksum == 0) {
-+ UDPBUF->udpchksum = 0xffff;
-+ }
-+#endif /* UIP_UDP_CHECKSUMS */
-+
-+ BUF->srcport = uip_udp_conn->lport;
-+ BUF->destport = uip_udp_conn->rport;
-+
-+ BUF->srcipaddr[0] = uip_hostaddr[0];
-+ BUF->srcipaddr[1] = uip_hostaddr[1];
-+ BUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
-+ BUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
-+
-+ uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
-+ 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. */
-+
-+ if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
-+ checksum. */
-+ UIP_STAT(++uip_stat.tcp.drop);
-+ UIP_STAT(++uip_stat.tcp.chkerr);
-+ 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]; ++uip_connr) {
-+ if(uip_connr->tcpstateflags != CLOSED &&
-+ BUF->destport == uip_connr->lport &&
-+ BUF->srcport == uip_connr->rport &&
-+ BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
-+ BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
-+ goto found;
-+ }
-+ }
-+
-+ /* If we didn't find and active connection that expected the packet,
-+ either this packet is an old duplicate, or this is a SYN packet
-+ destined for a connection in LISTEN. If the SYN flag isn't set,
-+ it is an old packet and we send a RST. */
-+ if((BUF->flags & TCP_CTL) != TCP_SYN)
-+ goto reset;
-+
-+ tmp16 = BUF->destport;
-+ /* Next, check listening connections. */
-+ for(c = 0; c < 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;
-+
-+ UIP_STAT(++uip_stat.tcp.rst);
-+
-+ BUF->flags = TCP_RST | TCP_ACK;
-+ uip_len = 40;
-+ BUF->tcpoffset = 5 << 4;
-+
-+ /* Flip the seqno and ackno fields in the TCP header. */
-+ 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[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;
-+
-+ /* We also have to increase the sequence number we are
-+ acknowledging. If the least significant byte overflowed, we need
-+ to propagate the carry to the other bytes as well. */
-+ if(++BUF->ackno[3] == 0) {
-+ if(++BUF->ackno[2] == 0) {
-+ if(++BUF->ackno[1] == 0) {
-+ ++BUF->ackno[0];
-+ }
-+ }
-+ }
-+
-+ /* Swap port numbers. */
-+ tmp16 = BUF->srcport;
-+ BUF->srcport = BUF->destport;
-+ BUF->destport = tmp16;
-+
-+ /* Swap IP addresses. */
-+ 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;
-+
-+
-+ /* And send out the RST packet! */
-+ goto tcp_send_noconn;
-+
-+ /* This label will be jumped to if we matched the incoming packet
-+ 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
-+ 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
-+ CLOSED connections are found. Thanks to Eddie C. Dost for a very
-+ nice algorithm for the TIME_WAIT search. */
-+ uip_connr = 0;
-+ for(c = 0; c < UIP_CONNS; ++c) {
-+ if(uip_conns[c].tcpstateflags == CLOSED) {
-+ uip_connr = &uip_conns[c];
-+ break;
-+ }
-+ if(uip_conns[c].tcpstateflags == TIME_WAIT) {
-+ if(uip_connr == 0 ||
-+ uip_conns[c].timer > uip_connr->timer) {
-+ uip_connr = &uip_conns[c];
-+ }
-+ }
-+ }
-+
-+ if(uip_connr == 0) {
-+ /* All connections are used already, we drop packet and hope that
-+ the remote end will retransmit the packet at a time when we
-+ have more spare connections. */
-+ UIP_STAT(++uip_stat.tcp.syndrop);
-+ UIP_LOG("tcp: found no unused connections.");
-+ 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;
-+ uip_connr->sv = 4;
-+ uip_connr->nrtx = 0;
-+ uip_connr->lport = BUF->destport;
-+ uip_connr->rport = BUF->srcport;
-+ uip_connr->ripaddr[0] = BUF->srcipaddr[0];
-+ uip_connr->ripaddr[1] = BUF->srcipaddr[1];
-+ uip_connr->tcpstateflags = SYN_RCVD;
-+
-+ uip_connr->snd_nxt[0] = iss[0];
-+ uip_connr->snd_nxt[1] = iss[1];
-+ uip_connr->snd_nxt[2] = iss[2];
-+ uip_connr->snd_nxt[3] = iss[3];
-+ uip_connr->len = 1;
-+
-+ /* rcv_nxt should be the seqno from the incoming packet + 1. */
-+ uip_connr->rcv_nxt[3] = BUF->seqno[3];
-+ uip_connr->rcv_nxt[2] = BUF->seqno[2];
-+ uip_connr->rcv_nxt[1] = BUF->seqno[1];
-+ uip_connr->rcv_nxt[0] = BUF->seqno[0];
-+ uip_add_rcv_nxt(1);
-+
-+ /* Parse the TCP MSS option, if present. */
-+ if((BUF->tcpoffset & 0xf0) > 0x50) {
-+ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
-+ opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
-+ if(opt == 0x00) {
-+ /* End of options. */
-+ break;
-+ } else if(opt == 0x01) {
-+ ++c;
-+ /* NOP option. */
-+ } else if(opt == 0x02 &&
-+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
-+ /* An MSS option with the right option length. */
-+ tmp16 = ((unsigned short int)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
-+ (unsigned short int)uip_buf[40 + 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 {
-+ /* All other options have a length field, so that we easily
-+ can skip past them. */
-+ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
-+ /* If the length field is zero, the options are malformed
-+ and we don't process them further. */
-+ break;
-+ }
-+ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
-+ }
-+ }
-+ }
-+
-+ /* 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 */
-+
-+ /* We send out the TCP Maximum Segment Size option with our
-+ SYNACK. */
-+ BUF->optdata[0] = 2;
-+ BUF->optdata[1] = 4;
-+ BUF->optdata[2] = (UIP_TCP_MSS) / 256;
-+ BUF->optdata[3] = (UIP_TCP_MSS) & 255;
-+ uip_len = 44;
-+ BUF->tcpoffset = 6 << 4;
-+ goto tcp_send;
-+
-+ /* This label will be jumped to if we found an active connection. */
-+ found:
-+ uip_conn = uip_connr;
-+ 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
-+ before we accept the reset. */
-+ if(BUF->flags & TCP_RST) {
-+ uip_connr->tcpstateflags = CLOSED;
-+ UIP_LOG("tcp: got reset, aborting connection.");
-+ uip_flags = UIP_ABORT;
-+ UIP_APPCALL();
-+ goto drop;
-+ }
-+ /* Calculated 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
-+ calculated by subtracing the length of the TCP header (in
-+ c) and the length of the IP header (20 bytes). */
-+ uip_len = uip_len - c - 20;
-+
-+ /* 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_len > 0 &&
-+ (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
-+ BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
-+ BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
-+ BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
-+ goto tcp_send_ack;
-+ }
-+
-+ /* Next, check if the incoming segment acknowledges any outstanding
-+ data. If so, we update the sequence number, reset the length of
-+ the outstanding data, calculate RTT estimations, and reset the
-+ retransmission timer. */
-+ if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
-+ uip_add32(uip_connr->snd_nxt, uip_connr->len);
-+ if(BUF->ackno[0] == uip_acc32[0] &&
-+ BUF->ackno[1] == uip_acc32[1] &&
-+ BUF->ackno[2] == uip_acc32[2] &&
-+ BUF->ackno[3] == uip_acc32[3]) {
-+ /* Update sequence number. */
-+ uip_connr->snd_nxt[0] = uip_acc32[0];
-+ 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) {
-+ signed char m;
-+ m = uip_connr->rto - uip_connr->timer;
-+ /* This is taken directly from VJs original code in his paper */
-+ m = m - (uip_connr->sa >> 3);
-+ uip_connr->sa += m;
-+ if(m < 0) {
-+ m = -m;
-+ }
-+ m = m - (uip_connr->sv >> 2);
-+ uip_connr->sv += m;
-+ uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
-+
-+ }
-+ /* Set the acknowledged flag. */
-+ uip_flags = UIP_ACKDATA;
-+ /* Reset the retransmission timer. */
-+ uip_connr->timer = uip_connr->rto;
-+ }
-+
-+ }
-+
-+ /* Do different things depending on in what state the connection is. */
-+ switch(uip_connr->tcpstateflags & TS_MASK) {
-+ /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
-+ implemented, since we force the application to close when the
-+ peer sends a FIN (hence the application goes directly from
-+ ESTABLISHED to LAST_ACK). */
-+ case SYN_RCVD:
-+ /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
-+ we are waiting for an ACK that acknowledges the data we sent
-+ out the last time. Therefore, we want to have the UIP_ACKDATA
-+ flag set. If so, we enter the ESTABLISHED state. */
-+ if(uip_flags & UIP_ACKDATA) {
-+ uip_connr->tcpstateflags = ESTABLISHED;
-+ uip_flags = UIP_CONNECTED;
-+ uip_connr->len = 0;
-+ if(uip_len > 0) {
-+ uip_flags |= UIP_NEWDATA;
-+ uip_add_rcv_nxt(uip_len);
-+ }
-+ uip_slen = 0;
-+ UIP_APPCALL();
-+ goto appsend;
-+ }
-+ goto drop;
-+#if UIP_ACTIVE_OPEN
-+ case SYN_SENT:
-+ /* In SYN_SENT, we wait for a SYNACK that is sent in response to
-+ our SYN. The rcv_nxt is set to sequence number in the SYNACK
-+ plus one, and we send an ACK. We move into the ESTABLISHED
-+ state. */
-+ if((uip_flags & UIP_ACKDATA) &&
-+ BUF->flags == (TCP_SYN | TCP_ACK)) {
-+
-+ /* Parse the TCP MSS option, if present. */
-+ if((BUF->tcpoffset & 0xf0) > 0x50) {
-+ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
-+ opt = uip_buf[40 + UIP_LLH_LEN + c];
-+ if(opt == 0x00) {
-+ /* End of options. */
-+ break;
-+ } else if(opt == 0x01) {
-+ ++c;
-+ /* NOP option. */
-+ } else if(opt == 0x02 &&
-+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
-+ /* An MSS option with the right option length. */
-+ tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
-+ uip_buf[UIP_TCPIP_HLEN + 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 {
-+ /* All other options have a length field, so that we easily
-+ can skip past them. */
-+ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
-+ /* If the length field is zero, the options are malformed
-+ and we don't process them further. */
-+ break;
-+ }
-+ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
-+ }
-+ }
-+ }
-+ uip_connr->tcpstateflags = ESTABLISHED;
-+ uip_connr->rcv_nxt[0] = BUF->seqno[0];
-+ uip_connr->rcv_nxt[1] = BUF->seqno[1];
-+ uip_connr->rcv_nxt[2] = BUF->seqno[2];
-+ uip_connr->rcv_nxt[3] = BUF->seqno[3];
-+ uip_add_rcv_nxt(1);
-+ uip_flags = UIP_CONNECTED | UIP_NEWDATA;
-+ uip_connr->len = 0;
-+ uip_len = 0;
-+ uip_slen = 0;
-+ UIP_APPCALL();
-+ goto appsend;
-+ }
-+ goto reset;
-+#endif /* UIP_ACTIVE_OPEN */
-+
-+ case 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
-+ application should put new data into the buffer, otherwise we are
-+ retransmitting an old segment, and the application should put that
-+ data into the buffer.
-+
-+ If the incoming packet is a FIN, we should close the connection on
-+ this side as well, and we send out a FIN and enter the LAST_ACK
-+ state. We require that there is no outstanding data; otherwise the
-+ sequence numbers will be screwed up. */
-+
-+ if(BUF->flags & TCP_FIN) {
-+ if(uip_outstanding(uip_connr)) {
-+ goto drop;
-+ }
-+ uip_add_rcv_nxt(1 + uip_len);
-+ uip_flags = UIP_CLOSE;
-+ if(uip_len > 0) {
-+ uip_flags |= UIP_NEWDATA;
-+ }
-+ UIP_APPCALL();
-+ uip_connr->len = 1;
-+ uip_connr->tcpstateflags = LAST_ACK;
-+ uip_connr->nrtx = 0;
-+ tcp_send_finack:
-+ BUF->flags = TCP_FIN | TCP_ACK;
-+ goto tcp_send_nodata;
-+ }
-+
-+ /* Check the URG flag. If this is set, the segment carries urgent
-+ data that we must pass to the application. */
-+ if(BUF->flags & TCP_URG) {
-+#if UIP_URGDATA > 0
-+ uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
-+ if(uip_urglen > uip_len) {
-+ /* There is more urgent data in the next segment to come. */
-+ uip_urglen = uip_len;
-+ }
-+ uip_add_rcv_nxt(uip_urglen);
-+ uip_len -= uip_urglen;
-+ uip_urgdata = uip_appdata;
-+ uip_appdata += uip_urglen;
-+ } else {
-+ uip_urglen = 0;
-+#endif /* UIP_URGDATA > 0 */
-+ uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
-+ uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
-+ }
-+
-+
-+ /* If uip_len > 0 we have TCP data in the packet, and we flag this
-+ by setting the UIP_NEWDATA flag and update the sequence number
-+ we acknowledge. If the application has stopped the dataflow
-+ using uip_stop(), we must not accept any data packets from the
-+ remote host. */
-+ if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
-+ uip_flags |= UIP_NEWDATA;
-+ uip_add_rcv_nxt(uip_len);
-+ }
-+
-+ /* Check if the available buffer space advertised by the other end
-+ is smaller than the initial MSS for this connection. If so, we
-+ set the current MSS to the window size to ensure that the
-+ application does not send more data than the other end can
-+ handle.
-+
-+ If the remote host advertises a zero window, we set the MSS to
-+ 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.
-+ */
-+ tmp16 = ((unsigned short int)BUF->wnd[0] << 8) + (unsigned short int)BUF->wnd[1];
-+ if(tmp16 > uip_connr->initialmss ||
-+ tmp16 == 0) {
-+ tmp16 = uip_connr->initialmss;
-+ }
-+ uip_connr->mss = tmp16;
-+
-+ /* If this packet constitutes an ACK for outstanding data (flagged
-+ by the UIP_ACKDATA flag, we should call the application since it
-+ might want to send more data. If the incoming packet had data
-+ from the peer (as flagged by the UIP_NEWDATA flag), the
-+ application must also be notified.
-+
-+ When the application is called, the global variable uip_len
-+ contains the length of the incoming data. The application can
-+ access the incoming data through the global pointer
-+ uip_appdata, which usually points 40 bytes into the uip_buf
-+ array.
-+
-+ If the application wishes to send any data, this data should be
-+ put into the uip_appdata and the length of the data should be
-+ put into uip_len. If the application don't have any data to
-+ send, uip_len must be set to 0. */
-+ if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
-+ uip_slen = 0;
-+ UIP_APPCALL();
-+
-+ appsend:
-+
-+ if(uip_flags & UIP_ABORT) {
-+ uip_slen = 0;
-+ uip_connr->tcpstateflags = CLOSED;
-+ BUF->flags = TCP_RST | TCP_ACK;
-+ goto tcp_send_nodata;
-+ }
-+
-+ if(uip_flags & UIP_CLOSE) {
-+ uip_slen = 0;
-+ uip_connr->len = 1;
-+ uip_connr->tcpstateflags = FIN_WAIT_1;
-+ uip_connr->nrtx = 0;
-+ BUF->flags = TCP_FIN | TCP_ACK;
-+ goto tcp_send_nodata;
-+ }
-+
-+ /* If uip_slen > 0, the application has data to be sent. */
-+ if(uip_slen > 0) {
-+
-+ /* If the connection has acknowledged data, the contents of
-+ the ->len variable should be discarded. */
-+ if((uip_flags & UIP_ACKDATA) != 0) {
-+ uip_connr->len = 0;
-+ }
-+
-+ /* If the ->len variable is non-zero the connection has
-+ already data in transit and cannot send anymore right
-+ now. */
-+ if(uip_connr->len == 0) {
-+
-+ /* The application cannot send more than what is allowed by
-+ the mss (the minumum of the MSS and the available
-+ window). */
-+ if(uip_slen > uip_connr->mss) {
-+ uip_slen = uip_connr->mss;
-+ }
-+
-+ /* Remember how much data we send out now so that we know
-+ when everything has been acknowledged. */
-+ uip_connr->len = uip_slen;
-+ } else {
-+
-+ /* If the application already had unacknowledged data, we
-+ make sure that the application does not send (i.e.,
-+ retransmit) out more than it previously sent out. */
-+ uip_slen = uip_connr->len;
-+ }
-+ } else {
-+ uip_connr->len = 0;
-+ }
-+ 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) {
-+ /* Add the length of the IP and TCP headers. */
-+ uip_len = uip_connr->len + UIP_TCPIP_HLEN;
-+ /* We always set the ACK flag in response packets. */
-+ BUF->flags = TCP_ACK | TCP_PSH;
-+ /* Send the packet. */
-+ goto tcp_send_noopts;
-+ }
-+ /* If there is no data to send, just send out a pure ACK if
-+ there is newdata. */
-+ if(uip_flags & UIP_NEWDATA) {
-+ uip_len = UIP_TCPIP_HLEN;
-+ BUF->flags = TCP_ACK;
-+ goto tcp_send_noopts;
-+ }
-+ }
-+ goto drop;
-+ case LAST_ACK:
-+ /* We can close this connection if the peer has acknowledged our
-+ FIN. This is indicated by the UIP_ACKDATA flag. */
-+ if(uip_flags & UIP_ACKDATA) {
-+ uip_connr->tcpstateflags = CLOSED;
-+ uip_flags = UIP_CLOSE;
-+ UIP_APPCALL();
-+ }
-+ break;
-+
-+ case 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
-+ FIN from the other side. */
-+ if(uip_len > 0) {
-+ uip_add_rcv_nxt(uip_len);
-+ }
-+ if(BUF->flags & TCP_FIN) {
-+ if(uip_flags & UIP_ACKDATA) {
-+ uip_connr->tcpstateflags = TIME_WAIT;
-+ uip_connr->timer = 0;
-+ uip_connr->len = 0;
-+ } else {
-+ uip_connr->tcpstateflags = CLOSING;
-+ }
-+ uip_add_rcv_nxt(1);
-+ uip_flags = UIP_CLOSE;
-+ UIP_APPCALL();
-+ goto tcp_send_ack;
-+ } else if(uip_flags & UIP_ACKDATA) {
-+ uip_connr->tcpstateflags = FIN_WAIT_2;
-+ uip_connr->len = 0;
-+ goto drop;
-+ }
-+ if(uip_len > 0) {
-+ goto tcp_send_ack;
-+ }
-+ goto drop;
-+
-+ case FIN_WAIT_2:
-+ if(uip_len > 0) {
-+ uip_add_rcv_nxt(uip_len);
-+ }
-+ if(BUF->flags & TCP_FIN) {
-+ uip_connr->tcpstateflags = TIME_WAIT;
-+ uip_connr->timer = 0;
-+ uip_add_rcv_nxt(1);
-+ uip_flags = UIP_CLOSE;
-+ UIP_APPCALL();
-+ goto tcp_send_ack;
-+ }
-+ if(uip_len > 0) {
-+ goto tcp_send_ack;
-+ }
-+ goto drop;
-+
-+ case TIME_WAIT:
-+ goto tcp_send_ack;
-+
-+ case CLOSING:
-+ if(uip_flags & UIP_ACKDATA) {
-+ uip_connr->tcpstateflags = TIME_WAIT;
-+ uip_connr->timer = 0;
-+ }
-+ }
-+ 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 = 40;
-+ tcp_send_noopts:
-+ BUF->tcpoffset = 5 << 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. */
-+ 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->srcport = uip_connr->lport;
-+ BUF->destport = uip_connr->rport;
-+
-+ BUF->srcipaddr[0] = uip_hostaddr[0];
-+ BUF->srcipaddr[1] = uip_hostaddr[1];
-+ BUF->destipaddr[0] = uip_connr->ripaddr[0];
-+ BUF->destipaddr[1] = uip_connr->ripaddr[1];
-+
-+
-+ if(uip_connr->tcpstateflags & UIP_STOPPED) {
-+ /* If the connection has issued uip_stop(), we advertise a zero
-+ window so that the remote host will stop sending data. */
-+ BUF->wnd[0] = BUF->wnd[1] = 0;
-+ } else {
-+ BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
-+ BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
-+ }
-+
-+ tcp_send_noconn:
-+
-+ BUF->len[0] = (uip_len >> 8);
-+ BUF->len[1] = (uip_len & 0xff);
-+
-+ /* Calculate TCP checksum. */
-+ BUF->tcpchksum = 0;
-+ BUF->tcpchksum = ~(uip_tcpchksum());
-+
-+ //ip_send_nolen:
-+
-+ BUF->vhl = 0x45;
-+ BUF->tos = 0;
-+ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
-+ BUF->ttl = UIP_TTL;
-+ ++ipid;
-+ BUF->ipid[0] = ipid >> 8;
-+ BUF->ipid[1] = ipid & 0xff;
-+
-+ /* Calculate IP checksum. */
-+ BUF->ipchksum = 0;
-+ BUF->ipchksum = ~(uip_ipchksum());
-+
-+ UIP_STAT(++uip_stat.tcp.sent);
-+ send:
-+ UIP_STAT(++uip_stat.ip.sent);
-+ /* Return and let the caller do the actual transmission. */
-+ return;
-+ drop:
-+ uip_len = 0;
-+ return;
-+}
-+/*-----------------------------------------------------------------------------------*/
-+/*unsigned short int
-+htons(unsigned short int val)
-+{
-+ return HTONS(val);
-+}*/
-+/*-----------------------------------------------------------------------------------*/
-+/** @} */
---- /dev/null
-+++ b/net/uip-0.9/uip.h
-@@ -0,0 +1,1066 @@
-+/**
-+ * \addtogroup uip
-+ * @{
-+ */
-+
-+/**
-+ * \file
-+ * Header file for the uIP TCP/IP stack.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ *
-+ * 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
-+ * structures, TCP/IP header structures and function declarations.
-+ *
-+ */
-+
-+
-+/*
-+ * Copyright (c) 2001-2003, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $
-+ *
-+ */
-+
-+#ifndef __UIP_H__
-+#define __UIP_H__
-+#include <linux/types.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <malloc.h>
-+#include <common.h>
-+
-+
-+#include "uipopt.h"
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* First, the functions that should be called from the
-+ * system. Initialization, the periodic timer and incoming packets are
-+ * handled by the following three functions.
-+ */
-+
-+/**
-+ * \defgroup uipconffunc uIP configuration functions
-+ * @{
-+ *
-+ * The uIP configuration functions are used for setting run-time
-+ * parameters in uIP such as IP addresses.
-+ */
-+
-+/**
-+ * Set the IP address of this host.
-+ *
-+ * The IP address is represented as a 4-byte array where the first
-+ * octet of the IP address is put in the first member of the 4-byte
-+ * array.
-+ *
-+ * \param addr A pointer to a 4-byte representation of the IP address.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \
-+ uip_hostaddr[1] = addr[1]; } while(0)
-+
-+/**
-+ * Get the IP address of this host.
-+ *
-+ * The IP address is represented as a 4-byte array where the first
-+ * octet of the IP address is put in the first member of the 4-byte
-+ * array.
-+ *
-+ * \param addr A pointer to a 4-byte array that will be filled in with
-+ * the currently configured IP address.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \
-+ addr[1] = uip_hostaddr[1]; } while(0)
-+
-+/** @} */
-+
-+/**
-+ * \defgroup uipinit uIP initialization functions
-+ * @{
-+ *
-+ * The uIP initialization functions are used for booting uIP.
-+ */
-+
-+/**
-+ * uIP initialization function.
-+ *
-+ * This function should be called at boot up to initilize the uIP
-+ * TCP/IP stack.
-+ */
-+void uip_init(void);
-+
-+/** @} */
-+
-+/**
-+ * \defgroup uipdevfunc uIP device driver functions
-+ * @{
-+ *
-+ * These functions are used by a network device driver for interacting
-+ * with uIP.
-+ */
-+
-+/**
-+ * Process an incoming packet.
-+ *
-+ * This function should be called when the device driver has received
-+ * a packet from the network. The packet from the device driver must
-+ * be present in the uip_buf buffer, and the length of the packet
-+ * should be placed in the uip_len variable.
-+ *
-+ * When the function returns, there may be an outbound packet placed
-+ * in the uip_buf packet buffer. If so, the uip_len variable is set to
-+ * the length of the packet. If no packet is to be sent out, the
-+ * uip_len variable is set to 0.
-+ *
-+ * 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();
-+ }
-+ }
-+ \endcode
-+ *
-+ * \note If you are writing a uIP device driver that needs ARP
-+ * (Address Resolution Protocol), e.g., when running uIP over
-+ * 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();
-+ }
-+ }
-+ \endcode
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_input() uip_process(UIP_DATA)
-+
-+/**
-+ * Periodic processing for a connection identified by its number.
-+ *
-+ * This function does the necessary periodic processing (timers,
-+ * polling) for a uIP TCP conneciton, and should be called when the
-+ * periodic uIP timer goes off. It should be called for every
-+ * connection, regardless of whether they are open of closed.
-+ *
-+ * When the function returns, it may have an outbound packet waiting
-+ * for service in the uIP packet buffer, and if so the uip_len
-+ * 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
-+ * this:
-+ \code
-+ 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
-+ * (Address Resolution Protocol), e.g., when running uIP over
-+ * 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();
-+ }
-+ }
-+ \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)
-+
-+/**
-+ * Periodic processing for a connection identified by a pointer to its structure.
-+ *
-+ * Same as uip_periodic() but takes a pointer to the actual uip_conn
-+ * struct instead of an integer as its argument. This function can be
-+ * used to force periodic processing of a specific connection.
-+ *
-+ * \param conn A pointer to the uip_conn struct for the connection to
-+ * be processed.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_periodic_conn(conn) do { uip_conn = conn; \
-+ uip_process(UIP_TIMER); } while (0)
-+
-+#if UIP_UDP
-+/**
-+ * Periodic processing for a UDP connection identified by its number.
-+ *
-+ * This function is essentially the same as uip_prerioic(), but for
-+ * 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();
-+ }
-+ }
-+ \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();
-+ }
-+ }
-+ \endcode
-+ *
-+ * \param conn The number of the UDP connection to be processed.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
-+ uip_process(UIP_UDP_TIMER); } while (0)
-+
-+/**
-+ * Periodic processing for a UDP connection identified by a pointer to
-+ * its structure.
-+ *
-+ * Same as uip_udp_periodic() but takes a pointer to the actual
-+ * uip_conn struct instead of an integer as its argument. This
-+ * function can be used to force periodic processing of a specific
-+ * connection.
-+ *
-+ * \param conn A pointer to the uip_udp_conn struct for the connection
-+ * to be processed.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
-+ uip_process(UIP_UDP_TIMER); } while (0)
-+
-+
-+#endif /* UIP_UDP */
-+
-+/**
-+ * The uIP packet buffer.
-+ *
-+ * The uip_buf array is used to hold incoming and outgoing
-+ * packets. The device driver should place incoming data into this
-+ * buffer. When sending data, the device driver should read the link
-+ * level headers and the TCP/IP headers from this buffer. The size of
-+ * the link level headers is configured by the UIP_LLH_LEN define.
-+ *
-+ * \note The application data need not be placed in this buffer, so
-+ * the device driver must read it from the place pointed to by the
-+ * uip_appdata pointer as illustrated by the following example:
-+ \code
-+ void
-+ devicedriver_send(void)
-+ {
-+ hwsend(&uip_buf[0], UIP_LLH_LEN);
-+ hwsend(&uip_buf[UIP_LLH_LEN], 40);
-+ hwsend(uip_appdata, uip_len - 40 - UIP_LLH_LEN);
-+ }
-+ \endcode
-+ */
-+extern u8_t uip_buf[UIP_BUFSIZE+2];
-+
-+/** @} */
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* 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
-+ * @{
-+ *
-+ * Functions used by an application running of top of uIP.
-+ */
-+
-+/**
-+ * 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.
-+ *
-+ \code
-+ uip_listen(HTONS(80));
-+ \endcode
-+ *
-+ * \param port A 16-bit port number in network byte order.
-+ */
-+void uip_listen(u16_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.
-+ *
-+ \code
-+ uip_unlisten(HTONS(80));
-+ \endcode
-+ *
-+ * \param port A 16-bit port number in network byte order.
-+ */
-+void uip_unlisten(u16_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,
-+ * 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
-+ * 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 convertion using HTONS() or htons() is necessary.
-+ *
-+ \code
-+ u16_t ipaddr[2];
-+
-+ uip_ipaddr(ipaddr, 192,168,1,2);
-+ uip_connect(ipaddr, HTONS(80));
-+ \endcode
-+ *
-+ * \param ripaddr A pointer to a 4-byte array representing the IP
-+ * address of the remote hot.
-+ *
-+ * \param port A 16-bit port number in network byte order.
-+ *
-+ * \return A pointer to the uIP connection identifier for the new connection,
-+ * or NULL if no connection could be allocated.
-+ *
-+ */
-+struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
-+
-+
-+
-+/**
-+ * \internal
-+ *
-+ * Check if a connection has outstanding (i.e., unacknowledged) data.
-+ *
-+ * \param conn A pointer to the uip_conn structure for the connection.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_outstanding(conn) ((conn)->len)
-+
-+/**
-+ * Send data on the current connection.
-+ *
-+ * This function is used to send out a single segment of TCP
-+ * data. Only applications that have been invoked by uIP for event
-+ * 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
-+ * 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.
-+ *
-+ * \note This function does not guarantee that the sent data will
-+ * arrive at the destination. If the data is lost in the network, the
-+ * application will be invoked with the uip_rexmit() event being
-+ * set. The application will then have to resend the data using this
-+ * function.
-+ *
-+ * \param data A pointer to the data which is to be sent.
-+ *
-+ * \param len The maximum amount of data bytes to be sent.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0)
-+
-+/**
-+ * The length of any incoming data that is currently avaliable (if avaliable)
-+ * in the uip_appdata buffer.
-+ *
-+ * The test function uip_data() must first be used to check if there
-+ * is any data available at all.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_datalen() uip_len
-+
-+/**
-+ * The length of any out-of-band data (urgent data) that has arrived
-+ * on the connection.
-+ *
-+ * \note The configuration parameter UIP_URGDATA must be set for this
-+ * function to be enabled.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_urgdatalen() uip_urglen
-+
-+/**
-+ * Close the current connection.
-+ *
-+ * This function will close the current connection in a nice way.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_close() (uip_flags = UIP_CLOSE)
-+
-+/**
-+ * 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
-+ * uip_close() function.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_abort() (uip_flags = UIP_ABORT)
-+
-+/**
-+ * Tell the sending host to stop sending data.
-+ *
-+ * This function will close our receiver's window so that we stop
-+ * receiving data for the current connection.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
-+
-+/**
-+ * Find out if the current connection has been previously stopped with
-+ * uip_stop().
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
-+
-+/**
-+ * Restart the current connection, if is has previously been stopped
-+ * with uip_stop().
-+ *
-+ * This function will open the receiver's window again so that we
-+ * start receiving data for the current connection.
-+ *
-+ * \hideinitializer
-+ */
-+#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
-+ connection is, and what the application function should do. */
-+
-+/**
-+ * Is new incoming data available?
-+ *
-+ * 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.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_newdata() (uip_flags & UIP_NEWDATA)
-+
-+/**
-+ * Has previously sent data been acknowledged?
-+ *
-+ * Will reduce to non-zero if the previously sent data has been
-+ * acknowledged by the remote host. This means that the application
-+ * can send new data.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_acked() (uip_flags & UIP_ACKDATA)
-+
-+/**
-+ * Has the connection just been connected?
-+ *
-+ * Reduces to non-zero if the current connection has been connected to
-+ * a remote host. This will happen both if the connection has been
-+ * actively opened (with uip_connect()) or passively opened (with
-+ * uip_listen()).
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_connected() (uip_flags & UIP_CONNECTED)
-+
-+/**
-+ * Has the connection been closed by the other end?
-+ *
-+ * Is non-zero if the connection has been closed by the remote
-+ * host. The application may then do the necessary clean-ups.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_closed() (uip_flags & UIP_CLOSE)
-+
-+/**
-+ * Has the connection been aborted by the other end?
-+ *
-+ * Non-zero if the current connection has been aborted (reset) by the
-+ * remote host.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_aborted() (uip_flags & UIP_ABORT)
-+
-+/**
-+ * Has the connection timed out?
-+ *
-+ * Non-zero if the current connection has been aborted due to too many
-+ * retransmissions.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
-+
-+/**
-+ * Do we need to retransmit previously data?
-+ *
-+ * Reduces to non-zero if the previously sent data has been lost in
-+ * the network, and the application should retransmit it. The
-+ * application should send the exact same data as it did the last
-+ * time, using the uip_send() function.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_rexmit() (uip_flags & UIP_REXMIT)
-+
-+/**
-+ * Is the connection being polled by uIP?
-+ *
-+ * Is non-zero if the reason the application is invoked is that the
-+ * current connection has been idle for a while and should be
-+ * polled.
-+ *
-+ * The polling event can be used for sending data without having to
-+ * wait for the remote host to send data.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_poll() (uip_flags & UIP_POLL)
-+
-+/**
-+ * Get the initial maxium segment size (MSS) of the current
-+ * connection.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_initialmss() (uip_conn->initialmss)
-+
-+/**
-+ * Get the current maxium segment size that can be sent on the current
-+ * connection.
-+ *
-+ * The current maxiumum 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()).
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_mss() (uip_conn->mss)
-+
-+/**
-+ * Set up a new UDP connection.
-+ *
-+ * \param ripaddr A pointer to a 4-byte structure representing 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
-+ * if no connection could be allocated.
-+ */
-+struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
-+
-+/**
-+ * Removed a UDP connection.
-+ *
-+ * \param conn A pointer to the uip_udp_conn structure for the connection.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_udp_remove(conn) (conn)->lport = 0
-+
-+/**
-+ * Send a UDP datagram of length len on the current connection.
-+ *
-+ * This function can only be called in response to a UDP event (poll
-+ * or newdata). The data must be present in the uip_buf buffer, at the
-+ * place pointed to by the uip_appdata pointer.
-+ *
-+ * \param len The length of the data in the uip_buf buffer.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_udp_send(len) uip_slen = (len)
-+
-+/** @} */
-+
-+/* uIP convenience and converting functions. */
-+
-+/**
-+ * \defgroup uipconvfunc uIP conversion functions
-+ * @{
-+ *
-+ * These functions can be used for converting between different data
-+ * formats used by uIP.
-+ */
-+
-+/**
-+ * Pack an IP address into a 4-byte array which is used by uIP to
-+ * represent IP addresses.
-+ *
-+ * Example:
-+ \code
-+ u16_t ipaddr[2];
-+
-+ uip_ipaddr(&ipaddr, 192,168,1,2);
-+ \endcode
-+ *
-+ * \param addr A pointer to a 4-byte array that will be filled in with
-+ * the IP addres.
-+ * \param addr0 The first octet of the IP address.
-+ * \param addr1 The second octet of the IP address.
-+ * \param addr2 The third octet of the IP address.
-+ * \param addr3 The forth octet of the IP address.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
-+ (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \
-+ (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \
-+ } while(0)
-+
-+/**
-+ * 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.
-+ *
-+ * \hideinitializer
-+ */
-+#ifndef HTONS
-+# if BYTE_ORDER == BIG_ENDIAN
-+# define HTONS(n) (n)
-+# else /* BYTE_ORDER == BIG_ENDIAN */
-+# define HTONS(n) ((((u16_t)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))
-+# endif /* BYTE_ORDER == BIG_ENDIAN */
-+#endif /* HTONS */
-+
-+/**
-+ * Convert 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.
-+ */
-+#ifndef htons
-+u16_t htons(u16_t val);
-+#endif /* htons */
-+
-+/** @} */
-+
-+/**
-+ * Pointer to the application data in the packet buffer.
-+ *
-+ * This pointer points to the application data when the application is
-+ * called. If the application wishes to send data, the application may
-+ * use this space to write the data into before calling uip_send().
-+ */
-+extern volatile u8_t *uip_appdata;
-+extern volatile u8_t *uip_sappdata;
-+
-+#if UIP_URGDATA > 0
-+/* u8_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).
-+ */
-+extern volatile u8_t *uip_urgdata;
-+#endif /* UIP_URGDATA > 0 */
-+
-+
-+/* u[8|16]_t uip_len:
-+ *
-+ * When the application is called, uip_len contains the length of any
-+ * new data that has been received from the remote host. The
-+ * application should set this variable to the size of any data that
-+ * the application wishes to send. When the network device driver
-+ * output function is called, uip_len should contain the length of the
-+ * outgoing packet.
-+ */
-+extern volatile u16_t uip_len, uip_slen;
-+
-+#if UIP_URGDATA > 0
-+extern volatile u8_t uip_urglen, uip_surglen;
-+#endif /* UIP_URGDATA > 0 */
-+
-+
-+/**
-+ * Representation of a uIP TCP connection.
-+ *
-+ * 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
-+ * is to let the application store application-specific state (e.g.,
-+ * file pointers) for the connection. The size of this field is
-+ * configured in the "uipopt.h" header file.
-+ */
-+struct uip_conn {
-+ u16_t ripaddr[2]; /**< 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
-+ order. */
-+
-+ u8_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
-+ us. */
-+ u16_t len; /**< Length of the data that was previously sent. */
-+ u16_t mss; /**< Current maximum segment size for the
-+ connection. */
-+ u16_t initialmss; /**< Initial maximum segment size for the
-+ connection. */
-+ u8_t sa; /**< Retransmission time-out calculation state
-+ variable. */
-+ u8_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
-+ segment sent. */
-+
-+ /** The application state. */
-+ u8_t appstate[UIP_APPSTATE_SIZE];
-+};
-+
-+
-+/* Pointer to the current connection. */
-+extern struct uip_conn *uip_conn;
-+/* The array containing all uIP connections. */
-+extern struct uip_conn uip_conns[UIP_CONNS];
-+/**
-+ * \addtogroup uiparch
-+ * @{
-+ */
-+
-+/**
-+ * 4-byte array used for the 32-bit sequence number calculations.
-+ */
-+extern volatile u8_t uip_acc32[4];
-+
-+/** @} */
-+
-+
-+#if UIP_UDP
-+/**
-+ * Representation of a uIP UDP connection.
-+ */
-+struct uip_udp_conn {
-+ u16_t ripaddr[2]; /**< 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. */
-+};
-+
-+extern struct uip_udp_conn *uip_udp_conn;
-+extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
-+#endif /* UIP_UDP */
-+
-+/**
-+ * The structure holding the TCP/IP statistics that are gathered if
-+ * UIP_STATISTICS is set to 1.
-+ *
-+ */
-+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 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
-+ 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
-+ 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 typeerr; /**< Number of ICMP packets with a wrong
-+ type. */
-+ } icmp; /**< ICMP statistics. */
-+ 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 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 rexmit; /**< Number of retransmitted TCP segments. */
-+ uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
-+ connections was avaliable. */
-+ uip_stats_t synrst; /**< Number of SYNs for closed ports,
-+ triggering a RST. */
-+ } tcp; /**< TCP statistics. */
-+};
-+
-+/**
-+ * 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:
-+ *
-+ * When the application is called, uip_flags will contain the flags
-+ * that are defined in this file. Please read below for more
-+ * infomation.
-+ */
-+extern volatile u8_t uip_flags;
-+
-+/* The following flags may be set in the global variable uip_flags
-+ before calling the application callback. The UIP_ACKDATA and
-+ UIP_NEWDATA flags may both be set at the same time, whereas the
-+ others are mutualy exclusive. Note that these flags should *NOT* be
-+ accessed directly, but through the uIP functions/macros. */
-+
-+#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
-+ acked and the application should send
-+ out new data instead of retransmitting
-+ the last data. */
-+#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
-+ us new data. */
-+#define UIP_REXMIT 4 /* Tells the application to retransmit the
-+ data that was last sent. */
-+#define UIP_POLL 8 /* Used for polling the application, to
-+ check if the application has data that
-+ it wants to send. */
-+#define UIP_CLOSE 16 /* The remote host has closed the
-+ connection, thus the connection has
-+ gone away. Or the application signals
-+ that it wants to close the
-+ connection. */
-+#define UIP_ABORT 32 /* The remote host has aborted the
-+ connection, thus the connection has
-+ gone away. Or the application signals
-+ that it wants to abort the
-+ connection. */
-+#define UIP_CONNECTED 64 /* We have got a connection from a remote
-+ host and have set up a new connection
-+ for it, or an active connection has
-+ been successfully established. */
-+
-+#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
-+ too many retransmissions. */
-+
-+
-+/* 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()
-+ 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. */
-+
-+#define UIP_DATA 1 /* Tells uIP that there is incoming data in
-+ the uip_buf buffer. The length of the
-+ data is stored in the global variable
-+ uip_len. */
-+#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
-+ fired. */
-+#if UIP_UDP
-+#define UIP_UDP_TIMER 3
-+#endif /* UIP_UDP */
-+
-+/* The TCP states used in the uip_conn->tcpstateflags. */
-+#define CLOSED 0
-+#define SYN_RCVD 1
-+#define SYN_SENT 2
-+#define ESTABLISHED 3
-+#define FIN_WAIT_1 4
-+#define FIN_WAIT_2 5
-+#define CLOSING 6
-+#define TIME_WAIT 7
-+#define LAST_ACK 8
-+#define TS_MASK 15
-+
-+#define UIP_STOPPED 16
-+
-+#define UIP_TCPIP_HLEN 40
-+
-+/* The TCP and IP headers. */
-+typedef struct {
-+ /* IP header. */
-+ u8_t vhl,
-+ tos,
-+ len[2],
-+ ipid[2],
-+ ipoffset[2],
-+ ttl,
-+ proto;
-+ u16_t ipchksum;
-+ u16_t srcipaddr[2],
-+ destipaddr[2];
-+
-+ /* TCP header. */
-+ u16_t srcport,
-+ destport;
-+ u8_t seqno[4],
-+ ackno[4],
-+ tcpoffset,
-+ flags,
-+ wnd[2];
-+ u16_t tcpchksum;
-+ u8_t urgp[2];
-+ u8_t optdata[4];
-+} uip_tcpip_hdr;
-+
-+/* The ICMP and IP headers. */
-+typedef struct {
-+ /* IP header. */
-+ u8_t vhl,
-+ tos,
-+ len[2],
-+ ipid[2],
-+ ipoffset[2],
-+ ttl,
-+ proto;
-+ u16_t ipchksum;
-+ u16_t srcipaddr[2],
-+ destipaddr[2];
-+ /* ICMP (echo) header. */
-+ u8_t type, icode;
-+ u16_t icmpchksum;
-+ u16_t id, seqno;
-+} uip_icmpip_hdr;
-+
-+
-+/* The UDP and IP headers. */
-+typedef struct {
-+ /* IP header. */
-+ u8_t vhl,
-+ tos,
-+ len[2],
-+ ipid[2],
-+ ipoffset[2],
-+ ttl,
-+ proto;
-+ u16_t ipchksum;
-+ u16_t srcipaddr[2],
-+ destipaddr[2];
-+
-+ /* UDP header. */
-+ u16_t srcport,
-+ destport;
-+ u16_t udplen;
-+ u16_t udpchksum;
-+} uip_udpip_hdr;
-+
-+#define UIP_PROTO_ICMP 1
-+#define UIP_PROTO_TCP 6
-+#define UIP_PROTO_UDP 17
-+
-+#if UIP_FIXEDADDR
-+extern const u16_t uip_hostaddr[2];
-+#else /* UIP_FIXEDADDR */
-+extern u16_t uip_hostaddr[2];
-+#endif /* UIP_FIXEDADDR */
-+
-+#endif /* __UIP_H__ */
-+
-+
-+/** @} */
-+
---- /dev/null
-+++ b/net/uip-0.9/uip_arch.c
-@@ -0,0 +1,145 @@
-+/*
-+ * Copyright (c) 2001, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
-+ *
-+ */
-+
-+
-+#include "uip.h"
-+#include "uip_arch.h"
-+
-+#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
-+#define IP_PROTO_TCP 6
-+
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_add32(u8_t *op32, u16_t op16)
-+{
-+
-+ uip_acc32[3] = op32[3] + (op16 & 0xff);
-+ 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[3] < (op16 & 0xff)) {
-+ ++uip_acc32[2];
-+ if(uip_acc32[2] == 0) {
-+ ++uip_acc32[1];
-+ if(uip_acc32[1] == 0) {
-+ ++uip_acc32[0];
-+ }
-+ }
-+ }
-+}
-+/*-----------------------------------------------------------------------------------*/
-+u16_t
-+uip_chksum(u16_t *sdata, u16_t len)
-+{
-+ u16_t acc;
-+
-+ for(acc = 0; len > 1; len -= 2) {
-+ acc += *sdata;
-+ if(acc < *sdata) {
-+ /* Overflow, so we add the carry to acc (i.e., increase by
-+ one). */
-+ ++acc;
-+ }
-+ ++sdata;
-+ }
-+
-+ /* add up any odd byte */
-+ if(len == 1) {
-+ acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
-+ if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
-+ ++acc;
-+ }
-+ }
-+
-+ return acc;
-+}
-+/*-----------------------------------------------------------------------------------*/
-+u16_t
-+uip_ipchksum(void)
-+{
-+ return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
-+}
-+/*-----------------------------------------------------------------------------------*/
-+u16_t
-+uip_tcpchksum(void)
-+{
-+ u16_t hsum, sum;
-+
-+
-+ /* Compute the checksum of the TCP header. */
-+ hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
-+
-+ /* Compute the checksum of the data in the TCP packet and add it to
-+ the TCP header checksum. */
-+ sum = uip_chksum((u16_t *)uip_appdata,
-+ (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
-+
-+ if((sum += hsum) < hsum) {
-+ ++sum;
-+ }
-+
-+ if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
-+ ++sum;
-+ }
-+ if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
-+ ++sum;
-+ }
-+ if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
-+ ++sum;
-+ }
-+ if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
-+ ++sum;
-+ }
-+ if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
-+ ++sum;
-+ }
-+
-+ hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
-+
-+ if((sum += hsum) < hsum) {
-+ ++sum;
-+ }
-+
-+ return sum;
-+}
-+/*-----------------------------------------------------------------------------------*/
---- /dev/null
-+++ b/net/uip-0.9/uip_arch.h
-@@ -0,0 +1,130 @@
-+/**
-+ * \defgroup uiparch Architecture specific uIP functions
-+ * @{
-+ *
-+ * The functions in the architecture specific module implement the IP
-+ * check sum and 32-bit additions.
-+ *
-+ * The IP checksum calculation is the most computationally expensive
-+ * operation in the TCP/IP stack and it therefore pays off to
-+ * implement this in efficient assembler. The purpose of the uip-arch
-+ * module is to let the checksum functions to be implemented in
-+ * architecture specific assembler.
-+ *
-+ */
-+
-+/**
-+ * \file
-+ * Declarations of architecture specific functions.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ */
-+
-+/*
-+ * Copyright (c) 2001, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $
-+ *
-+ */
-+
-+#ifndef __UIP_ARCH_H__
-+#define __UIP_ARCH_H__
-+
-+#include "uip.h"
-+
-+/**
-+ * Carry out a 32-bit addition.
-+ *
-+ * Because not all architectures for which uIP is intended has native
-+ * 32-bit arithmetic, uIP uses an external C function for doing the
-+ * required 32-bit additions in the TCP protocol processing. This
-+ * function should add the two arguments and place the result in the
-+ * global variable uip_acc32.
-+ *
-+ * \note The 32-bit integer pointed to by the op32 parameter and the
-+ * result in the uip_acc32 variable are in network byte order (big
-+ * endian).
-+ *
-+ * \param op32 A pointer to a 4-byte array representing a 32-bit
-+ * integer in network byte order (big endian).
-+ *
-+ * \param op16 A 16-bit integer in host byte order.
-+ */
-+void uip_add32(u8_t *op32, u16_t op16);
-+
-+/**
-+ * Calculate the Internet checksum over a buffer.
-+ *
-+ * The Internet checksum is the one's complement of the one's
-+ * complement sum of all 16-bit words in the buffer.
-+ *
-+ * See RFC1071.
-+ *
-+ * \note This function is not called in the current version of uIP,
-+ * but future versions might make use of it.
-+ *
-+ * \param buf A pointer to the buffer over which the checksum is to be
-+ * computed.
-+ *
-+ * \param len The length of the buffer over which the checksum is to
-+ * be computed.
-+ *
-+ * \return The Internet checksum of the buffer.
-+ */
-+u16_t uip_chksum(u16_t *buf, u16_t len);
-+
-+/**
-+ * Calculate the IP header checksum of the packet header in uip_buf.
-+ *
-+ * The IP header checksum is the Internet checksum of the 20 bytes of
-+ * the IP header.
-+ *
-+ * \return The IP header checksum of the IP header in the uip_buf
-+ * buffer.
-+ */
-+u16_t uip_ipchksum(void);
-+
-+/**
-+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
-+ *
-+ * The TCP checksum is the Internet checksum of data contents of the
-+ * TCP segment, and a pseudo-header as defined in RFC793.
-+ *
-+ * \note The uip_appdata pointer that points to the packet data may
-+ * point anywhere in memory, so it is not possible to simply calculate
-+ * the Internet checksum of the contents of the uip_buf buffer.
-+ *
-+ * \return The TCP checksum of the TCP segment in uip_buf and pointed
-+ * to by uip_appdata.
-+ */
-+u16_t uip_tcpchksum(void);
-+
-+/** @} */
-+
-+#endif /* __UIP_ARCH_H__ */
---- /dev/null
-+++ b/net/uip-0.9/uip_arp.c
-@@ -0,0 +1,421 @@
-+/**
-+ * \addtogroup uip
-+ * @{
-+ */
-+
-+/**
-+ * \defgroup uiparp uIP Address Resolution Protocol
-+ * @{
-+ *
-+ * The Address Resolution Protocol ARP is used for mapping between IP
-+ * addresses and link level addresses such as the Ethernet MAC
-+ * addresses. ARP uses broadcast queries to ask for the link level
-+ * address of a known IP address and the host which is configured with
-+ * the IP address for which the query was meant, will respond with its
-+ * link level address.
-+ *
-+ * \note This ARP implementation only supports Ethernet.
-+ */
-+
-+/**
-+ * \file
-+ * Implementation of the ARP Address Resolution Protocol.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ *
-+ */
-+
-+/*
-+ * Copyright (c) 2001-2003, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $
-+ *
-+ */
-+
-+
-+#include "uip_arp.h"
-+
-+struct arp_hdr {
-+ struct uip_eth_hdr ethhdr;
-+ u16_t hwtype;
-+ u16_t protocol;
-+ u8_t hwlen;
-+ u8_t protolen;
-+ u16_t opcode;
-+ struct uip_eth_addr shwaddr;
-+ u16_t sipaddr[2];
-+ struct uip_eth_addr dhwaddr;
-+ u16_t dipaddr[2];
-+};
-+
-+struct ethip_hdr {
-+ struct uip_eth_hdr ethhdr;
-+ /* IP header. */
-+ u8_t vhl,
-+ tos,
-+ len[2],
-+ ipid[2],
-+ ipoffset[2],
-+ ttl,
-+ proto;
-+ u16_t ipchksum;
-+ u16_t srcipaddr[2],
-+ destipaddr[2];
-+};
-+
-+#define ARP_REQUEST 1
-+#define ARP_REPLY 2
-+
-+#define ARP_HWTYPE_ETH 1
-+
-+struct arp_entry {
-+ u16_t ipaddr[2];
-+ struct uip_eth_addr ethaddr;
-+ u8_t time;
-+};
-+
-+struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
-+ UIP_ETHADDR1,
-+ UIP_ETHADDR2,
-+ UIP_ETHADDR3,
-+ UIP_ETHADDR4,
-+ UIP_ETHADDR5}};
-+
-+static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
-+static u16_t ipaddr[2];
-+static u8_t i, c;
-+
-+static u8_t arptime;
-+static u8_t tmpage;
-+
-+#define BUF ((struct arp_hdr *)&uip_buf[0])
-+#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
-+/*-----------------------------------------------------------------------------------*/
-+/**
-+ * Initialize the ARP module.
-+ *
-+ */
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_arp_init(void)
-+{
-+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
-+ memset(arp_table[i].ipaddr, 0, 4);
-+ }
-+}
-+/*-----------------------------------------------------------------------------------*/
-+/**
-+ * Periodic ARP processing function.
-+ *
-+ * This function performs periodic timer processing in the ARP module
-+ * and should be called at regular intervals. The recommended interval
-+ * is 10 seconds between the calls.
-+ *
-+ */
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_arp_timer(void)
-+{
-+ struct arp_entry *tabptr;
-+
-+ ++arptime;
-+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
-+ tabptr = &arp_table[i];
-+ if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
-+ arptime - tabptr->time >= UIP_ARP_MAXAGE) {
-+ memset(tabptr->ipaddr, 0, 4);
-+ }
-+ }
-+
-+}
-+/*-----------------------------------------------------------------------------------*/
-+static void
-+uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
-+{
-+ register struct arp_entry *tabptr;
-+ /* 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];
-+ /* Only check those entries that are actually in use. */
-+ if(tabptr->ipaddr[0] != 0 &&
-+ tabptr->ipaddr[1] != 0) {
-+
-+ /* 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]) {
-+
-+ /* An old entry found, update this and return. */
-+ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
-+ tabptr->time = arptime;
-+
-+ return;
-+ }
-+ }
-+ }
-+
-+ /* If we get here, no existing ARP table entry was found, so we
-+ create one. */
-+
-+ /* 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) {
-+ break;
-+ }
-+ }
-+
-+ /* If no unused entry is found, we try to find the oldest entry and
-+ throw it away. */
-+ if(i == UIP_ARPTAB_SIZE) {
-+ tmpage = 0;
-+ c = 0;
-+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
-+ tabptr = &arp_table[i];
-+ if(arptime - tabptr->time > tmpage) {
-+ tmpage = arptime - tabptr->time;
-+ c = i;
-+ }
-+ }
-+ i = c;
-+ }
-+
-+ /* Now, i is the ARP table entry which we will fill with the new
-+ information. */
-+ memcpy(tabptr->ipaddr, ipaddr, 4);
-+ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
-+ tabptr->time = arptime;
-+}
-+/*-----------------------------------------------------------------------------------*/
-+/**
-+ * ARP processing for incoming IP packets
-+ *
-+ * This function should be called by the device driver when an IP
-+ * packet has been received. The function will check if the address is
-+ * in the ARP cache, and if so the ARP cache entry will be
-+ * refreshed. If no ARP cache entry was found, a new one is created.
-+ *
-+ * This function expects an IP packet with a prepended Ethernet header
-+ * in the uip_buf[] buffer, and the length of the packet in the global
-+ * variable uip_len.
-+ */
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_arp_ipin(void)
-+{
-+ uip_len -= sizeof(struct uip_eth_hdr);
-+
-+ /* Only insert/update an entry if the source IP address of the
-+ incoming IP packet comes from a host on the local network. */
-+ if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
-+ (uip_hostaddr[0] & uip_arp_netmask[0])) {
-+ return;
-+ }
-+ if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
-+ (uip_hostaddr[1] & uip_arp_netmask[1])) {
-+ return;
-+ }
-+ uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
-+
-+ return;
-+}
-+/*-----------------------------------------------------------------------------------*/
-+/**
-+ * ARP processing for incoming ARP packets.
-+ *
-+ * This function should be called by the device driver when an ARP
-+ * packet has been received. The function will act differently
-+ * depending on the ARP packet type: if it is a reply for a request
-+ * that we previously sent out, the ARP cache will be filled in with
-+ * the values from the ARP reply. If the incoming ARP packet is an ARP
-+ * request for our IP address, an ARP reply packet is created and put
-+ * into the uip_buf[] buffer.
-+ *
-+ * When the function returns, the value of the global variable uip_len
-+ * indicates whether the device driver should send out a packet or
-+ * not. If uip_len is zero, no packet should be sent. If uip_len is
-+ * non-zero, it contains the length of the outbound packet that is
-+ * present in the uip_buf[] buffer.
-+ *
-+ * This function expects an ARP packet with a prepended Ethernet
-+ * header in the uip_buf[] buffer, and the length of the packet in the
-+ * global variable uip_len.
-+ */
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_arp_arpin(void)
-+{
-+
-+ if(uip_len < sizeof(struct arp_hdr)) {
-+ uip_len = 0;
-+ return;
-+ }
-+
-+ uip_len = 0;
-+
-+ switch(BUF->opcode) {
-+ case HTONS(ARP_REQUEST):
-+ /* ARP request. If it asked for our address, we send out a
-+ reply. */
-+ if(BUF->dipaddr[0] == uip_hostaddr[0] &&
-+ BUF->dipaddr[1] == uip_hostaddr[1]) {
-+ /* The reply opcode is 2. */
-+ BUF->opcode = HTONS(2);
-+
-+ 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->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];
-+
-+ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
-+ uip_len = sizeof(struct arp_hdr);
-+ }
-+ break;
-+ case HTONS(ARP_REPLY):
-+ /* ARP reply. We insert or update the ARP table if it was meant
-+ for us. */
-+ if(BUF->dipaddr[0] == uip_hostaddr[0] &&
-+ BUF->dipaddr[1] == uip_hostaddr[1]) {
-+
-+ uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
-+ }
-+ break;
-+ }
-+
-+ return;
-+}
-+/*-----------------------------------------------------------------------------------*/
-+/**
-+ * Prepend Ethernet header to an outbound IP packet and see if we need
-+ * to send out an ARP request.
-+ *
-+ * This function should be called before sending out an IP packet. The
-+ * function checks the destination IP address of the IP packet to see
-+ * what Ethernet MAC address that should be used as a destination MAC
-+ * address on the Ethernet.
-+ *
-+ * If the destination IP address is in the local network (determined
-+ * by logical ANDing of netmask and our IP address), the function
-+ * checks the ARP cache to see if an entry for the destination IP
-+ * address is found. If so, an Ethernet header is prepended and the
-+ * function returns. If no ARP cache entry is found for the
-+ * destination IP address, the packet in the uip_buf[] is replaced by
-+ * an ARP request packet for the IP address. The IP packet is dropped
-+ * and it is assumed that they higher level protocols (e.g., TCP)
-+ * eventually will retransmit the dropped packet.
-+ *
-+ * If the destination IP address is not on the local network, the IP
-+ * address of the default router is used instead.
-+ *
-+ * When the function returns, a packet is present in the uip_buf[]
-+ * buffer, and the length of the packet is in the global variable
-+ * uip_len.
-+ */
-+/*-----------------------------------------------------------------------------------*/
-+void
-+uip_arp_out(void)
-+{
-+ struct arp_entry *tabptr;
-+ /* Find the destination IP address in the ARP table and construct
-+ the Ethernet header. If the destination IP addres isn't on the
-+ local network, we use the default router's IP address instead.
-+
-+ If not ARP table entry is found, we overwrite the original IP
-+ packet with an ARP request for the IP address. */
-+
-+ /* Check if the destination address is on the local network. */
-+ if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) !=
-+ (uip_hostaddr[0] & uip_arp_netmask[0]) ||
-+ (IPBUF->destipaddr[1] & uip_arp_netmask[1]) !=
-+ (uip_hostaddr[1] & uip_arp_netmask[1])) {
-+ /* 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. */
-+ ipaddr[0] = uip_arp_draddr[0];
-+ ipaddr[1] = uip_arp_draddr[1];
-+ } else {
-+ /* Else, we use the destination IP address. */
-+ ipaddr[0] = IPBUF->destipaddr[0];
-+ ipaddr[1] = IPBUF->destipaddr[1];
-+ }
-+
-+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
-+ tabptr = &arp_table[i];
-+ if(ipaddr[0] == tabptr->ipaddr[0] &&
-+ ipaddr[1] == tabptr->ipaddr[1])
-+ break;
-+ }
-+
-+ if(i == UIP_ARPTAB_SIZE) {
-+ /* The destination address was not in our ARP table, so we
-+ overwrite the IP packet with an ARP request. */
-+
-+ 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);
-+
-+ BUF->dipaddr[0] = ipaddr[0];
-+ BUF->dipaddr[1] = ipaddr[1];
-+ BUF->sipaddr[0] = uip_hostaddr[0];
-+ BUF->sipaddr[1] = uip_hostaddr[1];
-+ BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
-+ BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
-+ BUF->protocol = HTONS(UIP_ETHTYPE_IP);
-+ BUF->hwlen = 6;
-+ BUF->protolen = 4;
-+ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
-+
-+ uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
-+
-+ uip_len = sizeof(struct arp_hdr);
-+ return;
-+ }
-+
-+ /* Build an ethernet header. */
-+ memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
-+ memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
-+
-+ IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
-+
-+ uip_len += sizeof(struct uip_eth_hdr);
-+}
-+/*-----------------------------------------------------------------------------------*/
-+
-+/** @} */
-+/** @} */
---- /dev/null
-+++ b/net/uip-0.9/uip_arp.h
-@@ -0,0 +1,201 @@
-+/**
-+ * \addtogroup uip
-+ * @{
-+ */
-+
-+/**
-+ * \addtogroup uiparp
-+ * @{
-+ */
-+
-+/**
-+ * \file
-+ * Macros and definitions for the ARP module.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ */
-+
-+
-+/*
-+ * Copyright (c) 2001-2003, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $
-+ *
-+ */
-+
-+#ifndef __UIP_ARP_H__
-+#define __UIP_ARP_H__
-+
-+#include "uip.h"
-+
-+
-+/**
-+ * Representation of a 48-bit Ethernet address.
-+ */
-+struct uip_eth_addr {
-+ u8_t addr[6];
-+};
-+
-+extern struct uip_eth_addr uip_ethaddr;
-+
-+/**
-+ * The Ethernet header.
-+ */
-+struct uip_eth_hdr {
-+ struct uip_eth_addr dest;
-+ struct uip_eth_addr src;
-+ u16_t type;
-+};
-+
-+#define UIP_ETHTYPE_ARP 0x0806
-+#define UIP_ETHTYPE_IP 0x0800
-+#define UIP_ETHTYPE_IP6 0x86dd
-+
-+
-+/* The uip_arp_init() function must be called before any of the other
-+ ARP functions. */
-+void uip_arp_init(void);
-+
-+/* The uip_arp_ipin() function should be called whenever an IP packet
-+ arrives from the Ethernet. This function refreshes the ARP table or
-+ inserts a new mapping if none exists. The function assumes that an
-+ IP packet with an Ethernet header is present in the uip_buf buffer
-+ and that the length of the packet is in the uip_len variable. */
-+void uip_arp_ipin(void);
-+
-+/* The uip_arp_arpin() should be called when an ARP packet is received
-+ by the Ethernet driver. This function also assumes that the
-+ Ethernet frame is present in the uip_buf buffer. When the
-+ uip_arp_arpin() function returns, the contents of the uip_buf
-+ buffer should be sent out on the Ethernet if the uip_len variable
-+ is > 0. */
-+void uip_arp_arpin(void);
-+
-+/* The uip_arp_out() function should be called when an IP packet
-+ should be sent out on the Ethernet. This function creates an
-+ Ethernet header before the IP header in the uip_buf buffer. The
-+ Ethernet header will have the correct Ethernet MAC destination
-+ address filled in if an ARP table entry for the destination IP
-+ address (or the IP address of the default router) is present. If no
-+ such table entry is found, the IP packet is overwritten with an ARP
-+ request and we rely on TCP to retransmit the packet that was
-+ overwritten. In any case, the uip_len variable holds the length of
-+ the Ethernet frame that should be transmitted. */
-+void uip_arp_out(void);
-+
-+/* The uip_arp_timer() function should be called every ten seconds. It
-+ is responsible for flushing old entries in the ARP table. */
-+void uip_arp_timer(void);
-+
-+/** @} */
-+
-+/**
-+ * \addtogroup uipconffunc
-+ * @{
-+ */
-+
-+/**
-+ * Set the default router's IP address.
-+ *
-+ * \param addr A pointer to a 4-byte array containing the IP address
-+ * of the default router.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \
-+ uip_arp_draddr[1] = addr[1]; } while(0)
-+
-+/**
-+ * Set the netmask.
-+ *
-+ * \param addr A pointer to a 4-byte array containing the IP address
-+ * of the netmask.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \
-+ uip_arp_netmask[1] = addr[1]; } while(0)
-+
-+
-+/**
-+ * Get the default router's IP address.
-+ *
-+ * \param addr A pointer to a 4-byte array that will be filled in with
-+ * the IP address of the default router.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \
-+ addr[1] = uip_arp_draddr[1]; } while(0)
-+
-+/**
-+ * Get the netmask.
-+ *
-+ * \param addr A pointer to a 4-byte array that will be filled in with
-+ * the value of the netmask.
-+ *
-+ * \hideinitializer
-+ */
-+#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \
-+ addr[1] = uip_arp_netmask[1]; } while(0)
-+
-+
-+/**
-+ * Specifiy the Ethernet MAC address.
-+ *
-+ * The ARP code needs to know the MAC address of the Ethernet card in
-+ * order to be able to respond to ARP queries and to generate working
-+ * Ethernet headers.
-+ *
-+ * \note This macro only specifies the Ethernet MAC address to the ARP
-+ * code. It cannot be used to change the MAC address of the Ethernet
-+ * card.
-+ *
-+ * \param eaddr A pointer to a struct uip_eth_addr containing the
-+ * Ethernet MAC address of the Ethernet card.
-+ *
-+ * \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)
-+
-+/** @} */
-+
-+/**
-+ * \internal Internal variables that are set using the macros
-+ * uip_setdraddr and uip_setnetmask.
-+ */
-+extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
-+#endif /* __UIP_ARP_H__ */
-+
-+
---- /dev/null
-+++ b/net/uip-0.9/uipopt.h
-@@ -0,0 +1,557 @@
-+/**
-+ * \defgroup uipopt Configuration options for uIP
-+ * @{
-+ *
-+ * uIP is configured using the per-project configuration file
-+ * "uipopt.h". This file contains all compile-time options for uIP and
-+ * should be tweaked to match each specific project. The uIP
-+ * distribution contains a documented example "uipopt.h" that can be
-+ * copied and modified for each project.
-+ */
-+
-+/**
-+ * \file
-+ * Configuration options for uIP.
-+ * \author Adam Dunkels <adam@dunkels.com>
-+ *
-+ * This file is used for tweaking various configuration options for
-+ * uIP. You should make a copy of this file into one of your project's
-+ * directories instead of editing this example "uipopt.h" file that
-+ * comes with the uIP distribution.
-+ */
-+
-+/*
-+ * Copyright (c) 2001-2003, Adam Dunkels.
-+ * 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. The name of the author may not be used to endorse or promote
-+ * products derived from this software without specific prior
-+ * written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * This file is part of the uIP TCP/IP stack.
-+ *
-+ * $Id: uipopt.h,v 1.16.2.5 2003/10/07 13:22:51 adam Exp $
-+ *
-+ */
-+
-+#ifndef __UIPOPT_H__
-+#define __UIPOPT_H__
-+
-+/*------------------------------------------------------------------------------*/
-+/**
-+ * \defgroup uipopttypedef uIP type definitions
-+ * @{
-+ */
-+
-+/**
-+ * The 8-bit unsigned data type.
-+ *
-+ * This may have to be tweaked for your particular compiler. "unsigned
-+ * char" works for most compilers.
-+ */
-+typedef unsigned char u8_t;
-+
-+/**
-+ * The 16-bit unsigned data type.
-+ *
-+ * This may have to be tweaked for your particular compiler. "unsigned
-+ * short" works for most compilers.
-+ */
-+typedef unsigned short u16_t;
-+
-+/**
-+ * The statistics data type.
-+ *
-+ * This datatype determines how high the statistics counters are able
-+ * to count.
-+ */
-+typedef unsigned short uip_stats_t;
-+
-+/** @} */
-+
-+/*------------------------------------------------------------------------------*/
-+
-+/**
-+ * \defgroup uipoptstaticconf Static configuration options
-+ * @{
-+ *
-+ * These configuration options can be used for setting the IP address
-+ * 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
-+ * 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.
-+ *
-+ * If uIP should use a fixed IP address, the settings are set in the
-+ * uipopt.h file. If not, the macros uip_sethostaddr(),
-+ * uip_setdraddr() and uip_setnetmask() should be used instead.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_FIXEDADDR 0
-+
-+/**
-+ * Ping IP address asignment.
-+ *
-+ * 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
-+ * the destination IP address of the first incoming "ping" (ICMP echo)
-+ * packet will be used for setting the hosts IP address.
-+ *
-+ * \note This works only if UIP_FIXEDADDR is 0.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_PINGADDRCONF 0
-+
-+#define UIP_IPADDR0 192 /**< The first octet of the IP address of
-+ this uIP node, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_IPADDR1 168 /**< The second octet of the IP address of
-+ this uIP node, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_IPADDR2 0 /**< The third octet of the IP address of
-+ this uIP node, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_IPADDR3 250 /**< The fourth octet of the IP address of
-+ this uIP node, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+
-+#define UIP_NETMASK0 255 /**< The first octet of the netmask of
-+ this uIP node, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_NETMASK1 255 /**< The second octet of the netmask of
-+ this uIP node, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_NETMASK2 255 /**< The third octet of the netmask of
-+ this uIP node, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_NETMASK3 0 /**< The fourth octet of the netmask of
-+ this uIP node, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+
-+#define UIP_DRIPADDR0 192 /**< The first octet of the IP address of
-+ the default router, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_DRIPADDR1 168 /**< The second octet of the IP address of
-+ the default router, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_DRIPADDR2 0 /**< The third octet of the IP address of
-+ the default router, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+#define UIP_DRIPADDR3 1 /**< The fourth octet of the IP address of
-+ the default router, if UIP_FIXEDADDR is
-+ 1. \hideinitializer */
-+
-+/**
-+ * Specifies if the uIP ARP module should be compiled with a fixed
-+ * Ethernet MAC address or not.
-+ *
-+ * If this configuration option is 0, the macro uip_setethaddr() can
-+ * be used to specify the Ethernet address at run-time.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_FIXEDETHADDR 0
-+
-+#define UIP_ETHADDR0 0x00 /**< The first octet of the Ethernet
-+ address if UIP_FIXEDETHADDR is
-+ 1. \hideinitializer */
-+#define UIP_ETHADDR1 0xbd /**< The second octet of the Ethernet
-+ address if UIP_FIXEDETHADDR is
-+ 1. \hideinitializer */
-+#define UIP_ETHADDR2 0x3b /**< The third octet of the Ethernet
-+ address if UIP_FIXEDETHADDR is
-+ 1. \hideinitializer */
-+#define UIP_ETHADDR3 0x33 /**< The fourth octet of the Ethernet
-+ address if UIP_FIXEDETHADDR is
-+ 1. \hideinitializer */
-+#define UIP_ETHADDR4 0x05 /**< The fifth octet of the Ethernet
-+ address if UIP_FIXEDETHADDR is
-+ 1. \hideinitializer */
-+#define UIP_ETHADDR5 0x71 /**< The sixth octet of the Ethernet
-+ address if UIP_FIXEDETHADDR is
-+ 1. \hideinitializer */
-+
-+/** @} */
-+/*------------------------------------------------------------------------------*/
-+/**
-+ * \defgroup uipoptip IP configuration options
-+ * @{
-+ *
-+ */
-+/**
-+ * The IP TTL (time to live) of IP packets sent by uIP.
-+ *
-+ * This should normally not be changed.
-+ */
-+#define UIP_TTL 255
-+
-+/**
-+ * 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
-+ * 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).
-+ *
-+ * \note IP packet reassembly is not heavily tested.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_REASSEMBLY 0
-+
-+/**
-+ * The maximum time an IP fragment should wait in the reassembly
-+ * buffer before it is dropped.
-+ *
-+ */
-+#define UIP_REASS_MAXAGE 40
-+
-+/** @} */
-+
-+/*------------------------------------------------------------------------------*/
-+/**
-+ * \defgroup uipoptudp UDP configuration options
-+ * @{
-+ *
-+ * \note The UDP support in uIP is still not entirely complete; there
-+ * is no support for sending or receiving broadcast or multicast
-+ * packets, but it works well enough to support a number of vital
-+ * applications such as DNS queries, though
-+ */
-+
-+/**
-+ * Toggles wether UDP support should be compiled in or not.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_UDP 0
-+
-+/**
-+ * Toggles if UDP checksums should be used or not.
-+ *
-+ * \note Support for UDP checksums is currently not included in uIP,
-+ * so this option has no function.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_UDP_CHECKSUMS 0
-+
-+/**
-+ * The maximum amount of concurrent UDP connections.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_UDP_CONNS 10
-+
-+/**
-+ * The name of the function that should be called when UDP datagrams arrive.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_UDP_APPCALL udp_appcall
-+
-+/** @} */
-+/*------------------------------------------------------------------------------*/
-+/**
-+ * \defgroup uipopttcp TCP configuration options
-+ * @{
-+ */
-+
-+/**
-+ * 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
-+ * option can be turned off to reduce the code size of uIP.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_ACTIVE_OPEN 1
-+
-+/**
-+ * The maximum number of simultaneously open TCP connections.
-+ *
-+ * 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.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_CONNS 10
-+
-+/**
-+ * The maximum number of simultaneously listening TCP ports.
-+ *
-+ * Each listening TCP port requires 2 bytes of memory.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_LISTENPORTS 10
-+
-+/**
-+ * The size of the advertised receiver's window.
-+ *
-+ * Should be set low (i.e., to the size of the uip_buf buffer) is the
-+ * application is slow to process incoming data, or high (32768 bytes)
-+ * if the application processes data quickly.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_RECEIVE_WINDOW 32768
-+
-+/**
-+ * Determines if support for TCP urgent data notification should be
-+ * compiled in.
-+ *
-+ * Urgent data (out-of-band data) is a rarely used TCP feature that
-+ * very seldom would be required.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_URGDATA 1
-+
-+/**
-+ * The initial retransmission timeout counted in timer pulses.
-+ *
-+ * This should not be changed.
-+ */
-+#define UIP_RTO 3
-+
-+/**
-+ * The maximum number of times a segment should be retransmitted
-+ * before the connection should be aborted.
-+ *
-+ * This should not be changed.
-+ */
-+#define UIP_MAXRTX 8
-+
-+/**
-+ * The maximum number of times a SYN segment should be retransmitted
-+ * before a connection request should be deemed to have been
-+ * unsuccessful.
-+ *
-+ * This should not need to be changed.
-+ */
-+#define UIP_MAXSYNRTX 3
-+
-+/**
-+ * The TCP maximum segment size.
-+ *
-+ * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.
-+ */
-+#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
-+
-+/**
-+ * How long a connection should stay in the TIME_WAIT state.
-+ *
-+ * This configiration option has no real implication, and it should be
-+ * left untouched.
-+ */
-+#define UIP_TIME_WAIT_TIMEOUT 120
-+
-+
-+/** @} */
-+/*------------------------------------------------------------------------------*/
-+/**
-+ * \defgroup uipoptarp ARP configuration options
-+ * @{
-+ */
-+
-+/**
-+ * The size of the ARP table.
-+ *
-+ * This option should be set to a larger value if this uIP node will
-+ * have many connections from the local network.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_ARPTAB_SIZE 8
-+
-+/**
-+ * The maxium age of ARP table entries measured in 10ths of seconds.
-+ *
-+ * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
-+ * default).
-+ */
-+#define UIP_ARP_MAXAGE 120
-+
-+/** @} */
-+
-+/*------------------------------------------------------------------------------*/
-+
-+/**
-+ * \defgroup uipoptgeneral General configuration options
-+ * @{
-+ */
-+
-+/**
-+ * The size of the uIP packet buffer.
-+ *
-+ * The uIP packet buffer should not be smaller than 60 bytes, and does
-+ * not need to be larger than 1500 bytes. Lower size results in lower
-+ * TCP throughput, larger size results in higher TCP throughput.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_BUFSIZE 1500
-+
-+
-+/**
-+ * Determines if statistics support should be compiled in.
-+ *
-+ * The statistics is useful for debugging and to show the user.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_STATISTICS 1
-+
-+/**
-+ * Determines if logging of certain events should be compiled in.
-+ *
-+ * This is useful mostly for debugging. The function uip_log()
-+ * must be implemented to suit the architecture of the project, if
-+ * logging is turned on.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_LOGGING 0
-+
-+/**
-+ * Print out a uIP log message.
-+ *
-+ * This function must be implemented by the module that uses uIP, and
-+ * is called by uIP whenever a log message is generated.
-+ */
-+void uip_log(char *msg);
-+
-+/**
-+ * The link level header length.
-+ *
-+ * This is the offset into the uip_buf where the IP header can be
-+ * found. For Ethernet, this should be set to 14. For SLIP, this
-+ * should be set to 0.
-+ *
-+ * \hideinitializer
-+ */
-+#define UIP_LLH_LEN 14
-+
-+
-+/** @} */
-+/*------------------------------------------------------------------------------*/
-+/**
-+ * \defgroup uipoptcpu CPU architecture configuration
-+ * @{
-+ *
-+ * The CPU architecture configuration is where the endianess of the
-+ * CPU on which uIP is to be run is specified. Most CPUs today are
-+ * little endian, and the most notable exception are the Motorolas
-+ * which are big endian. The BYTE_ORDER macro should be changed to
-+ * reflect the CPU architecture on which uIP is to be run.
-+ */
-+#ifndef LITTLE_ENDIAN
-+#define LITTLE_ENDIAN 3412
-+#endif /* LITTLE_ENDIAN */
-+#ifndef BIG_ENDIAN
-+#define BIG_ENDIAN 1234
-+#endif /* BIGE_ENDIAN */
-+
-+/**
-+ * The byte order of the CPU architecture on which uIP is to be run.
-+ *
-+ * This option can be either BIG_ENDIAN (Motorola byte order) or
-+ * LITTLE_ENDIAN (Intel byte order).
-+ *
-+ * \hideinitializer
-+ */
-+/*#ifndef BYTE_ORDER*/
-+#define BYTE_ORDER BIG_ENDIAN
-+/*#endif*/ /* BYTE_ORDER */
-+
-+/** @} */
-+/*------------------------------------------------------------------------------*/
-+
-+/**
-+ * \defgroup uipoptapp Appication specific configurations
-+ * @{
-+ *
-+ * An uIP application is implemented using a single application
-+ * function that is called by uIP whenever a TCP/IP event occurs. The
-+ * name of this function must be registered with uIP at compile time
-+ * using the UIP_APPCALL definition.
-+ *
-+ * uIP applications can store the application state within the
-+ * uip_conn structure by specifying the size of the application
-+ * structure with the UIP_APPSTATE_SIZE macro.
-+ *
-+ * The file containing the definitions must be included in the
-+ * uipopt.h file.
-+ *
-+ * The following example illustrates how this can look.
-+ \code
-+
-+void httpd_appcall(void);
-+#define UIP_APPCALL httpd_appcall
-+
-+struct httpd_state {
-+ u8_t state;
-+ u16_t count;
-+ char *dataptr;
-+ char *script;
-+};
-+#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
-+ \endcode
-+ */
-+
-+/**
-+ * \var #define UIP_APPCALL
-+ *
-+ * The name of the application function that uIP should call in
-+ * response to TCP/IP events.
-+ *
-+ */
-+
-+/**
-+ * \var #define UIP_APPSTATE_SIZE
-+ *
-+ * The size of the application state that is to be stored in the
-+ * uip_conn structure.
-+ */
-+/** @} */
-+
-+/* Include the header file for the application program that should be
-+ used. If you don't use the example web server, you should change
-+ this. */
-+#include "httpd.h"
-+
-+
-+#endif /* __UIPOPT_H__ */