Root/package/uboot-lantiq/patches/200-httpd.patch

1--- a/common/cmd_net.c
2+++ b/common/cmd_net.c
3@@ -43,6 +43,18 @@ U_BOOT_CMD(
4     "[loadAddress] [[hostIPaddr:]bootfilename]"
5 );
6 
7+#if defined(CONFIG_CMD_HTTPD)
8+int do_httpd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
9+{
10+ return NetLoopHttpd();
11+}
12+
13+U_BOOT_CMD(
14+ httpd, 1, 1, do_httpd,
15+ "httpd\t- start webserver", ""
16+);
17+#endif
18+
19 int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
20 {
21     return netboot_common (TFTP, cmdtp, argc, argv);
22--- /dev/null
23+++ b/include/httpd.h
24@@ -0,0 +1,17 @@
25+#ifndef _UIP_HTTPD_H__
26+#define _UIP_HTTPD_H__
27+
28+void HttpdStart (void);
29+void HttpdHandler (void);
30+
31+/* board specific implementation */
32+extern int do_http_upgrade(const unsigned char *data, const ulong size);
33+
34+#define HTTP_PROGRESS_START 0
35+#define HTTP_PROGRESS_TIMEOUT 1
36+#define HTTP_PROGRESS_UPLOAD_READY 2
37+#define HTTP_PROGRESS_UGRADE_READY 3
38+#define HTTP_PROGRESS_UGRADE_FAILED 4
39+extern int do_http_progress(const int state);
40+
41+#endif
42--- a/include/net.h
43+++ b/include/net.h
44@@ -383,7 +383,8 @@ extern int NetTimeOffset; /* offset ti
45 
46 /* Initialize the network adapter */
47 extern int NetLoop(proto_t);
48-
49+extern int NetLoopHttpd(void);
50+extern void NetSendHttpd(void);
51 /* Shutdown adapters and cleanup */
52 extern void NetStop(void);
53 
54--- a/net/Makefile
55+++ b/net/Makefile
56@@ -26,6 +26,8 @@ include $(TOPDIR)/config.mk
57 # CFLAGS += -DDEBUG
58 
59 LIB = $(obj)libnet.a
60+UIPDIR = uip-0.9
61+$(shell mkdir -p $(obj)$(UIPDIR))
62 
63 COBJS-$(CONFIG_CMD_NET) += bootp.o
64 COBJS-$(CONFIG_CMD_DNS) += dns.o
65@@ -36,6 +40,8 @@ COBJS-$(CONFIG_CMD_NET) += rarp.o
66 COBJS-$(CONFIG_CMD_SNTP) += sntp.o
67 COBJS-$(CONFIG_CMD_NET) += tftp.o
68 
69+COBJS-$(CONFIG_CMD_HTTPD) += httpd.o $(UIPDIR)/fs.o $(UIPDIR)/httpd.o $(UIPDIR)/uip_arp.o $(UIPDIR)/uip_arch.o $(UIPDIR)/uip.o
70+
71 COBJS := $(COBJS-y)
72 SRCS := $(COBJS:.o=.c)
73 OBJS := $(addprefix $(obj),$(COBJS))
74--- /dev/null
75+++ b/net/httpd.c
76@@ -0,0 +1,52 @@
77+/*
78+ * Copyright 1994, 1995, 2000 Neil Russell.
79+ * (See License)
80+ * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
81+ */
82+
83+#include <common.h>
84+#include <command.h>
85+#include <net.h>
86+#include "uip-0.9/uipopt.h"
87+#include "uip-0.9/uip.h"
88+#include "uip-0.9/uip_arp.h"
89+
90+
91+#if defined(CONFIG_CMD_HTTPD)
92+
93+#define TIMEOUT 5
94+
95+static int arptimer = 0;
96+
97+void
98+HttpdHandler (void)
99+{
100+ int i;
101+ for(i = 0; i < UIP_CONNS; i++) {
102+ uip_periodic(i);
103+ if(uip_len > 0) {
104+ uip_arp_out();
105+ NetSendHttpd();
106+ }
107+ }
108+ if(++arptimer == 20) {
109+ uip_arp_timer();
110+ arptimer = 0;
111+ }
112+}
113+
114+static void
115+HttpdTimeout (void)
116+{
117+ puts ("T ");
118+ NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
119+}
120+
121+void
122+HttpdStart (void)
123+{
124+ uip_init();
125+ httpd_init();
126+}
127+
128+#endif
129--- a/net/net.c
130+++ b/net/net.c
131@@ -95,6 +95,19 @@
132 #if defined(CONFIG_CMD_DNS)
133 #include "dns.h"
134 #endif
135+#if defined(CONFIG_CMD_HTTPD)
136+#include "httpd.h"
137+#include "uip-0.9/uipopt.h"
138+#include "uip-0.9/uip.h"
139+#include "uip-0.9/uip_arp.h"
140+static int https_running = 0;
141+int httpd_upload_complete = 0;
142+unsigned char *httpd_upload_data = 0;
143+extern int upload_running;
144+void NetReceiveHttpd(volatile uchar * inpkt, int len);
145+void NetSendHttpd(void);
146+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
147+#endif
148 
149 DECLARE_GLOBAL_DATA_PTR;
150 
151@@ -1308,6 +1321,13 @@ NetReceive(volatile uchar * inpkt, int l
152 
153     debug("packet received\n");
154 
155+#if defined(CONFIG_CMD_HTTPD)
156+ if(https_running) {
157+ NetReceiveHttpd(inpkt, len);
158+ return;
159+ }
160+#endif
161+
162     NetRxPacket = inpkt;
163     NetRxPacketLen = len;
164     et = (Ethernet_t *)inpkt;
165@@ -1922,3 +1942,162 @@ ushort getenv_VLAN(char *var)
166 {
167     return (string_to_VLAN(getenv(var)));
168 }
169+
170+#if defined(CONFIG_CMD_HTTPD)
171+
172+void
173+NetSendHttpd(void)
174+{
175+ volatile uchar *tmpbuf = NetTxPacket;
176+ int i;
177+
178+ for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
179+ tmpbuf[i] = uip_buf[i];
180+ }
181+
182+ for(; i < uip_len; i++) {
183+ tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
184+ }
185+ eth_send(NetTxPacket, uip_len);
186+}
187+
188+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
189+
190+void
191+NetReceiveHttpd(volatile uchar * inpkt, int len)
192+{
193+ memcpy(uip_buf, inpkt, len);
194+ uip_len = len;
195+ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
196+ uip_arp_ipin();
197+ uip_input();
198+ if(uip_len > 0) {
199+ uip_arp_out();
200+ NetSendHttpd();
201+ }
202+ } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
203+ uip_arp_arpin();
204+ if(uip_len > 0) {
205+ NetSendHttpd();
206+ }
207+ }
208+}
209+
210+int
211+NetLoopHttpd(void)
212+{
213+ unsigned long long tout = 0;
214+ bd_t *bd = gd->bd;
215+ unsigned short int ip[2];
216+
217+#ifdef CONFIG_NET_MULTI
218+ NetRestarted = 0;
219+ NetDevExists = 0;
220+#endif
221+
222+ /* XXX problem with bss workaround */
223+ NetArpWaitPacketMAC = NULL;
224+ NetArpWaitTxPacket = NULL;
225+ NetArpWaitPacketIP = 0;
226+ NetArpWaitReplyIP = 0;
227+ NetArpWaitTxPacket = NULL;
228+ NetTxPacket = NULL;
229+ NetTryCount = 1;
230+
231+ if (!NetTxPacket) {
232+ int i;
233+ /*
234+ * Setup packet buffers, aligned correctly.
235+ */
236+ NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
237+ NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
238+ for (i = 0; i < PKTBUFSRX; i++) {
239+ NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
240+ }
241+ }
242+
243+ if (!NetArpWaitTxPacket) {
244+ NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
245+ NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
246+ NetArpWaitTxPacketSize = 0;
247+ }
248+
249+restart:
250+
251+ eth_halt();
252+#ifdef CONFIG_NET_MULTI
253+ eth_set_current();
254+#endif
255+ if (eth_init(bd) < 0) {
256+ eth_halt();
257+ return(-1);
258+ }
259+
260+#ifdef CONFIG_NET_MULTI
261+ memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);
262+#else
263+ eth_getenv_enetaddr("ethaddr", NetOurEther);
264+#endif
265+
266+ NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
267+ NetOurGatewayIP = getenv_IPaddr ("gatewayip");
268+ NetOurSubnetMask= getenv_IPaddr ("netmask");
269+ NetOurVLAN = getenv_VLAN("vlan");
270+ NetOurNativeVLAN = getenv_VLAN("nvlan");
271+
272+ printf("starting httpd server from server %ld.%ld.%ld.%ld\n",
273+ (bd->bi_ip_addr & 0xff000000) >> 24,
274+ (bd->bi_ip_addr & 0x00ff0000) >> 16,
275+ (bd->bi_ip_addr & 0x0000ff00) >> 8,
276+ (bd->bi_ip_addr & 0x000000ff));
277+
278+ HttpdStart();
279+
280+ ip[0] = ((bd->bi_ip_addr & 0xffff0000) >> 16);
281+ ip[1] = (bd->bi_ip_addr & 0x0000ffff);
282+ uip_sethostaddr(ip);
283+
284+ do_http_progress(HTTP_PROGRESS_START);
285+
286+ https_running = 1;
287+ for (;;) {
288+ unsigned long long t1;
289+ WATCHDOG_RESET();
290+ if(eth_rx() > 0) {
291+ HttpdHandler();
292+ } else {
293+ t1 = get_ticks();
294+ if(t1 - tout > 1000) {
295+ do_http_progress(HTTP_PROGRESS_TIMEOUT);
296+ tout = t1;
297+ }
298+ }
299+ if(!httpd_upload_complete)
300+ continue;
301+ printf("Bytes transferred = %ld (%lx hex)\n",
302+ NetBootFileXferSize,
303+ NetBootFileXferSize);
304+ eth_halt();
305+ do_http_progress(HTTP_PROGRESS_UPLOAD_READY);
306+ if(do_http_upgrade(&httpd_upload_data[0], NetBootFileXferSize) == 0) {
307+ do_http_progress(HTTP_PROGRESS_UGRADE_READY);
308+ udelay(1000 * 10);
309+ do_reset (0,0,0,0);
310+ return 0;
311+ }
312+ break;
313+ }
314+ https_running = 0;
315+ NetBootFileXferSize = 0;
316+ httpd_upload_complete = 0;
317+ upload_running = 0;
318+// free(httpd_upload_data);
319+
320+ do_http_progress(HTTP_PROGRESS_UGRADE_FAILED);
321+
322+ goto restart;
323+
324+ return -1;
325+}
326+
327+#endif
328--- /dev/null
329+++ b/net/uip-0.9/Makefile
330@@ -0,0 +1,54 @@
331+# Copyright (c) 2001, Adam Dunkels.
332+# All rights reserved.
333+#
334+# Redistribution and use in source and binary forms, with or without
335+# modification, are permitted provided that the following conditions
336+# are met:
337+# 1. Redistributions of source code must retain the above copyright
338+# notice, this list of conditions and the following disclaimer.
339+# 2. Redistributions in binary form must reproduce the above copyright
340+# notice, this list of conditions and the following disclaimer in the
341+# documentation and/or other materials provided with the distribution.
342+# 3. All advertising materials mentioning features or use of this software
343+# must display the following acknowledgement:
344+# This product includes software developed by Adam Dunkels.
345+# 4. The name of the author may not be used to endorse or promote
346+# products derived from this software without specific prior
347+# written permission.
348+#
349+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
350+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
351+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
352+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
353+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
354+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
355+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
356+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
357+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
358+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
359+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
360+#
361+# This file is part of the uIP TCP/IP stack.
362+#
363+# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $
364+#
365+
366+CC=gcc
367+CFLAGS=-Wall -fpack-struct -DDUMP=0
368+
369+all: uip
370+
371+uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o
372+ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
373+
374+%.o: %.c
375+ $(CC) $(CFLAGS) -c $^ -o $@
376+
377+clean:
378+ rm -f *.o *~ *core uip
379+
380+
381+
382+
383+
384+
385--- /dev/null
386+++ b/net/uip-0.9/fs.c
387@@ -0,0 +1,154 @@
388+/**
389+ * \addtogroup httpd
390+ * @{
391+ */
392+
393+/**
394+ * \file
395+ * HTTP server read-only file system code.
396+ * \author Adam Dunkels <adam@dunkels.com>
397+ *
398+ * A simple read-only filesystem.
399+ */
400+
401+/*
402+ * Copyright (c) 2001, Swedish Institute of Computer Science.
403+ * All rights reserved.
404+ *
405+ * Redistribution and use in source and binary forms, with or without
406+ * modification, are permitted provided that the following conditions
407+ * are met:
408+ * 1. Redistributions of source code must retain the above copyright
409+ * notice, this list of conditions and the following disclaimer.
410+ * 2. Redistributions in binary form must reproduce the above copyright
411+ * notice, this list of conditions and the following disclaimer in the
412+ * documentation and/or other materials provided with the distribution.
413+ * 3. Neither the name of the Institute nor the names of its contributors
414+ * may be used to endorse or promote products derived from this software
415+ * without specific prior written permission.
416+ *
417+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
418+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
419+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
420+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
421+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
422+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
423+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
424+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
425+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
426+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
427+ * SUCH DAMAGE.
428+ *
429+ * This file is part of the lwIP TCP/IP stack.
430+ *
431+ * Author: Adam Dunkels <adam@sics.se>
432+ *
433+ * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $
434+ */
435+
436+#include "uip.h"
437+#include "httpd.h"
438+#include "fs.h"
439+#include "fsdata.h"
440+
441+#include "fsdata.c"
442+
443+#ifdef FS_STATISTICS
444+#if FS_STATISTICS == 1
445+static u16_t count[FS_NUMFILES];
446+#endif /* FS_STATISTICS */
447+#endif /* FS_STATISTICS */
448+
449+/*-----------------------------------------------------------------------------------*/
450+static u8_t
451+fs_strcmp(const char *str1, const char *str2)
452+{
453+ u8_t i;
454+ i = 0;
455+ loop:
456+
457+ if(str2[i] == 0 ||
458+ str1[i] == '\r' ||
459+ str1[i] == '\n') {
460+ return 0;
461+ }
462+
463+ if(str1[i] != str2[i]) {
464+ return 1;
465+ }
466+
467+
468+ ++i;
469+ goto loop;
470+}
471+/*-----------------------------------------------------------------------------------*/
472+int
473+fs_open(const char *name, struct fs_file *file)
474+{
475+#ifdef FS_STATISTICS
476+#if FS_STATISTICS == 1
477+ u16_t i = 0;
478+#endif /* FS_STATISTICS */
479+#endif /* FS_STATISTICS */
480+ struct fsdata_file_noconst *f;
481+
482+ for(f = (struct fsdata_file_noconst *)FS_ROOT;
483+ f != NULL;
484+ f = (struct fsdata_file_noconst *)f->next) {
485+
486+ if(fs_strcmp(name, f->name) == 0) {
487+ file->data = f->data;
488+ file->len = f->len;
489+#ifdef FS_STATISTICS
490+#if FS_STATISTICS == 1
491+ ++count[i];
492+#endif /* FS_STATISTICS */
493+#endif /* FS_STATISTICS */
494+ return 1;
495+ }
496+#ifdef FS_STATISTICS
497+#if FS_STATISTICS == 1
498+ ++i;
499+#endif /* FS_STATISTICS */
500+#endif /* FS_STATISTICS */
501+
502+ }
503+ return 0;
504+}
505+/*-----------------------------------------------------------------------------------*/
506+void
507+fs_init(void)
508+{
509+#ifdef FS_STATISTICS
510+#if FS_STATISTICS == 1
511+ u16_t i;
512+ for(i = 0; i < FS_NUMFILES; i++) {
513+ count[i] = 0;
514+ }
515+#endif /* FS_STATISTICS */
516+#endif /* FS_STATISTICS */
517+}
518+/*-----------------------------------------------------------------------------------*/
519+#ifdef FS_STATISTICS
520+#if FS_STATISTICS == 1
521+u16_t fs_count
522+(char *name)
523+{
524+ struct fsdata_file_noconst *f;
525+ u16_t i;
526+
527+ i = 0;
528+ for(f = (struct fsdata_file_noconst *)FS_ROOT;
529+ f != NULL;
530+ f = (struct fsdata_file_noconst *)f->next) {
531+
532+ if(fs_strcmp(name, f->name) == 0) {
533+ return count[i];
534+ }
535+ ++i;
536+ }
537+ return 0;
538+}
539+#endif /* FS_STATISTICS */
540+#endif /* FS_STATISTICS */
541+/*-----------------------------------------------------------------------------------*/
542--- /dev/null
543+++ b/net/uip-0.9/fs.h
544@@ -0,0 +1,80 @@
545+/**
546+ * \addtogroup httpd
547+ * @{
548+ */
549+
550+/**
551+ * \file
552+ * HTTP server read-only file system header file.
553+ * \author Adam Dunkels <adam@dunkels.com>
554+ */
555+
556+/*
557+ * Copyright (c) 2001, Swedish Institute of Computer Science.
558+ * All rights reserved.
559+ *
560+ * Redistribution and use in source and binary forms, with or without
561+ * modification, are permitted provided that the following conditions
562+ * are met:
563+ * 1. Redistributions of source code must retain the above copyright
564+ * notice, this list of conditions and the following disclaimer.
565+ * 2. Redistributions in binary form must reproduce the above copyright
566+ * notice, this list of conditions and the following disclaimer in the
567+ * documentation and/or other materials provided with the distribution.
568+ * 3. Neither the name of the Institute nor the names of its contributors
569+ * may be used to endorse or promote products derived from this software
570+ * without specific prior written permission.
571+ *
572+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
573+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
574+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
575+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
576+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
577+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
578+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
579+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
580+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
581+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
582+ * SUCH DAMAGE.
583+ *
584+ * This file is part of the lwIP TCP/IP stack.
585+ *
586+ * Author: Adam Dunkels <adam@sics.se>
587+ *
588+ * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $
589+ */
590+#ifndef __FS_H__
591+#define __FS_H__
592+
593+#include "uip.h"
594+
595+/**
596+ * An open file in the read-only file system.
597+ */
598+struct fs_file {
599+ char *data; /**< The actual file data. */
600+ int len; /**< The length of the file data. */
601+};
602+
603+/**
604+ * Open a file in the read-only file system.
605+ *
606+ * \param name The name of the file.
607+ *
608+ * \param file The file pointer, which must be allocated by caller and
609+ * will be filled in by the function.
610+ */
611+int fs_open(const char *name, struct fs_file *file);
612+
613+#ifdef FS_STATISTICS
614+#if FS_STATISTICS == 1
615+u16_t fs_count(char *name);
616+#endif /* FS_STATISTICS */
617+#endif /* FS_STATISTICS */
618+
619+/**
620+ * Initialize the read-only file system.
621+ */
622+void fs_init(void);
623+
624+#endif /* __FS_H__ */
625--- /dev/null
626+++ b/net/uip-0.9/fsdata.c
627@@ -0,0 +1,199 @@
628+static const char data_flashing_html[] = {
629+ /* /flashing.html */
630+ 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
631+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
632+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
633+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
634+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
635+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
636+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
637+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
638+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
639+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
640+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
641+ 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
642+ 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
643+ 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
644+ 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
645+ 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
646+ 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
647+ 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
648+ 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
649+ 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
650+ 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
651+ 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
652+ 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
653+ 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
654+ 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
655+ 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
656+
657+static const char data_fail_html[] = {
658+ /* /fail.html */
659+ 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
660+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
661+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
662+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
663+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
664+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
665+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
666+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
667+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
668+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
669+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
670+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
671+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
672+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
673+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
674+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
675+ 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
676+ 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
677+ 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
678+ 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
679+ 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
680+ 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
681+ 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
682+ 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
683+ 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
684+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
685+ 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
686+ 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
687+ 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
688+ 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
689+ 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
690+ 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
691+ 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
692+ 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
693+ 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
694+ 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
695+ 0x3e, 0xa, };
696+
697+static const char data_404_html[] = {
698+ /* /404.html */
699+ 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
700+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
701+ 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
702+ 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
703+ 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
704+ 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
705+ 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
706+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
707+ 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
708+ 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
709+ 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
710+ 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
711+ 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
712+ 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
713+ 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
714+ 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
715+ 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
716+ 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
717+ 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
718+ 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
719+ 0x6c, 0x3e, };
720+
721+static const char data_index_html[] = {
722+ /* /index.html */
723+ 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
724+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
725+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
726+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
727+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
728+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
729+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
730+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
731+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
732+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
733+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
734+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
735+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
736+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
737+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
738+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
739+ 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
740+ 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
741+ 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
742+ 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
743+ 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
744+ 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
745+ 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
746+ 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
747+ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
748+ 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
749+ 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
750+ 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
751+ 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
752+ 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
753+ 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
754+ 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
755+ 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
756+ 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
757+ 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
758+ 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
759+ 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
760+ 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
761+ 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
762+ 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
763+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
764+ 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
765+ 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
766+
767+static const char data_flash_html[] = {
768+ /* /flash.html */
769+ 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
770+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
771+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
772+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
773+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
774+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
775+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
776+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
777+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
778+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
779+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
780+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
781+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
782+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
783+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
784+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
785+ 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
786+ 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
787+ 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
788+ 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
789+ 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
790+ 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
791+ 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
792+ 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
793+ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
794+ 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
795+ 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
796+ 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
797+ 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
798+ 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
799+ 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
800+ 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
801+ 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
802+ 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
803+ 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
804+ 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
805+ 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
806+ 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
807+ 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
808+ 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
809+ 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
810+ 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
811+ 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
812+ 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
813+
814+const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
815+
816+const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
817+
818+const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
819+
820+const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
821+
822+const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
823+
824+#define FS_ROOT file_flash_html
825+
826+#define FS_NUMFILES 5
827\ No newline at end of file
828--- /dev/null
829+++ b/net/uip-0.9/fsdata.h
830@@ -0,0 +1,64 @@
831+/*
832+ * Copyright (c) 2001, Swedish Institute of Computer Science.
833+ * All rights reserved.
834+ *
835+ * Redistribution and use in source and binary forms, with or without
836+ * modification, are permitted provided that the following conditions
837+ * are met:
838+ * 1. Redistributions of source code must retain the above copyright
839+ * notice, this list of conditions and the following disclaimer.
840+ * 2. Redistributions in binary form must reproduce the above copyright
841+ * notice, this list of conditions and the following disclaimer in the
842+ * documentation and/or other materials provided with the distribution.
843+ * 3. Neither the name of the Institute nor the names of its contributors
844+ * may be used to endorse or promote products derived from this software
845+ * without specific prior written permission.
846+ *
847+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
848+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
849+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
850+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
851+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
852+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
853+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
854+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
855+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
856+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
857+ * SUCH DAMAGE.
858+ *
859+ * This file is part of the lwIP TCP/IP stack.
860+ *
861+ * Author: Adam Dunkels <adam@sics.se>
862+ *
863+ * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $
864+ */
865+#ifndef __FSDATA_H__
866+#define __FSDATA_H__
867+
868+#include "uipopt.h"
869+
870+struct fsdata_file {
871+ const struct fsdata_file *next;
872+ const char *name;
873+ const char *data;
874+ const int len;
875+#ifdef FS_STATISTICS
876+#if FS_STATISTICS == 1
877+ u16_t count;
878+#endif /* FS_STATISTICS */
879+#endif /* FS_STATISTICS */
880+};
881+
882+struct fsdata_file_noconst {
883+ struct fsdata_file *next;
884+ char *name;
885+ char *data;
886+ int len;
887+#ifdef FS_STATISTICS
888+#if FS_STATISTICS == 1
889+ u16_t count;
890+#endif /* FS_STATISTICS */
891+#endif /* FS_STATISTICS */
892+};
893+
894+#endif /* __FSDATA_H__ */
895--- /dev/null
896+++ b/net/uip-0.9/httpd.c
897@@ -0,0 +1,278 @@
898+#include "uip.h"
899+#include "httpd.h"
900+#include "fs.h"
901+#include "fsdata.h"
902+#include <asm/addrspace.h>
903+
904+#define HTTP_NONE 0
905+#define HTTP_FILE 1
906+#define HTTP_FIRMWARE 2
907+
908+#define PRINT(x) printf("%s", x)
909+#define PRINTLN(x) printf("%s\n", x)
910+
911+extern unsigned long do_http_tmp_address(void);
912+
913+struct httpd_state *hs;
914+
915+extern const struct fsdata_file file_index_html;
916+extern const struct fsdata_file file_404_html;
917+extern const struct fsdata_file file_flash_html;
918+extern int httpd_upload_complete;
919+extern unsigned char *httpd_upload_data;
920+unsigned char *upload_data;
921+extern ulong NetBootFileXferSize;
922+int upload_running = 0;
923+
924+#define ISO_G 0x47
925+#define ISO_E 0x45
926+#define ISO_T 0x54
927+#define ISO_P 0x50
928+#define ISO_O 0x4f
929+#define ISO_S 0x53
930+#define ISO_T 0x54
931+#define ISO_slash 0x2f
932+#define ISO_c 0x63
933+#define ISO_g 0x67
934+#define ISO_i 0x69
935+#define ISO_space 0x20
936+#define ISO_nl 0x0a
937+#define ISO_cr 0x0d
938+#define ISO_a 0x61
939+#define ISO_t 0x74
940+#define ISO_hash 0x23
941+#define ISO_period 0x2e
942+
943+static char eol[3] = { 0x0d, 0x0a, 0x00 };
944+static char eol2[5] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00 };
945+static char boundary[128];
946+static int boundary_len = 0;
947+
948+/* we use this so that we can do without the ctype library */
949+#define is_digit(c) ((c) >= '0' && (c) <= '9')
950+static int atoi(const char *s)
951+{
952+ int i=0;
953+
954+ while (is_digit(*s))
955+ i = i*10 + *(s++) - '0';
956+ return i;
957+}
958+
959+void
960+httpd_init(void)
961+{
962+ fs_init();
963+ uip_listen(HTONS(80));
964+}
965+
966+void
967+httpd_appcall(void)
968+{
969+ struct fs_file fsfile;
970+ u8_t i;
971+ switch(uip_conn->lport) {
972+ case HTONS(80):
973+ hs = (struct httpd_state *)(uip_conn->appstate);
974+ if(uip_connected())
975+ {
976+ hs->state = HTTP_NONE;
977+ hs->count = 0;
978+ return;
979+ } else if(uip_poll())
980+ {
981+ if(hs->count++ >= 1000) {
982+ uip_abort();
983+ }
984+ return;
985+ } else if(uip_newdata() && hs->state == HTTP_NONE)
986+ {
987+ if(uip_appdata[0] == ISO_G &&
988+ uip_appdata[1] == ISO_E &&
989+ uip_appdata[2] == ISO_T &&
990+ uip_appdata[3] == ISO_space)
991+ {
992+ hs->state = HTTP_FILE;
993+ }
994+ if(uip_appdata[0] == ISO_P &&
995+ uip_appdata[1] == ISO_O &&
996+ uip_appdata[2] == ISO_S &&
997+ uip_appdata[3] == ISO_T &&
998+ uip_appdata[4] == ISO_space)
999+ {
1000+ hs->state = HTTP_FIRMWARE;
1001+ }
1002+ if(hs->state == HTTP_NONE)
1003+ {
1004+ uip_abort();
1005+ return;
1006+ }
1007+ if(hs->state == HTTP_FILE)
1008+ {
1009+ for(i = 4; i < 40; ++i)
1010+ {
1011+ if(uip_appdata[i] == ISO_space ||
1012+ uip_appdata[i] == ISO_cr ||
1013+ uip_appdata[i] == ISO_nl)
1014+ {
1015+ uip_appdata[i] = 0;
1016+ break;
1017+ }
1018+ }
1019+
1020+ PRINT("request for file ");
1021+ PRINTLN(&uip_appdata[4]);
1022+ if(uip_appdata[4] == ISO_slash &&
1023+ uip_appdata[5] == 0)
1024+ {
1025+ fs_open(file_index_html.name, &fsfile);
1026+ } else {
1027+ if(!fs_open((const char *)&uip_appdata[4], &fsfile))
1028+ {
1029+ PRINTLN("couldn't open file");
1030+ fs_open(file_index_html.name, &fsfile);
1031+ }
1032+ }
1033+ hs->script = 0;
1034+ hs->state = HTTP_FILE;
1035+ hs->dataptr = fsfile.data;
1036+ hs->count = fsfile.len;
1037+ }
1038+ if(hs->state == HTTP_FIRMWARE)
1039+ {
1040+ unsigned char *start = (unsigned char*)uip_appdata;
1041+ char *clen = strstr(start, "Content-Length:");
1042+ int len = 0;
1043+ unsigned char *next, *end;
1044+ unsigned char *boundary_start;
1045+ int i;
1046+ uip_appdata[uip_len] = '\0';
1047+ if(clen)
1048+ {
1049+ clen += sizeof("Content-Length:");
1050+ next = strstr(clen, eol);
1051+ if(next)
1052+ {
1053+ len = atoi(clen);
1054+ next++;
1055+ printf("expecting %d bytes\n", len);
1056+ upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
1057+ printf("received data will be stored at 0x%08X\n", upload_data);
1058+ if(!upload_data)
1059+ {
1060+ printf("failed to allocate memory\n");
1061+ uip_close();
1062+ return;
1063+ }
1064+ } else {
1065+ uip_close();
1066+ return;
1067+ }
1068+ }
1069+ if(len < 4 * 1024)
1070+ {
1071+ uip_close();
1072+ return;
1073+ }
1074+ boundary_start = strstr(next, "---");
1075+ if(!boundary_start)
1076+ {
1077+ uip_close();
1078+ return;
1079+ }
1080+ end = strstr(boundary_start, eol);
1081+ if(!eol)
1082+ {
1083+ uip_close();
1084+ return;
1085+ }
1086+ boundary_len = end - boundary_start;
1087+ memcpy(boundary, boundary_start, boundary_len);
1088+ boundary[boundary_len] = 0;
1089+ next = strstr(boundary_start, "name=\"firmware\";");
1090+ if(!next)
1091+ {
1092+ uip_close();
1093+ return;
1094+ }
1095+ next = strstr(next, eol2);
1096+ if(!next)
1097+ {
1098+ printf("could not find start of data\n");
1099+ uip_close();
1100+ return;
1101+ }
1102+ next += 4;
1103+ hs->script = 0;
1104+ hs->state = HTTP_FIRMWARE;
1105+ hs->upload = uip_len - (next - start);
1106+ hs->upload_total = len - (int)(next - boundary_start);
1107+ hs->upload_total -= (strlen(boundary) + 6);
1108+ //printf("storing %d bytes at %p\n", (int)hs->upload, upload_data);
1109+ for(i = 0; i < hs->upload; i++)
1110+ upload_data[i] = next[i];
1111+ upload_data += (int)hs->upload;
1112+ printf("%d / %d\n", (int)hs->upload, hs->upload_total);
1113+ uip_slen = 0;
1114+ return;
1115+ }
1116+ }
1117+
1118+ if(hs->state == HTTP_FIRMWARE)
1119+ {
1120+ if(uip_newdata())
1121+ {
1122+ int i;
1123+ hs->count = 0;
1124+ uip_appdata[uip_len] = '\0';
1125+ hs->upload += uip_len;
1126+ //printf("storing %d bytes at %p\n", uip_len, upload_data);
1127+ printf("%d / %d\n", (int)hs->upload, hs->upload_total);
1128+ for(i = 0; i < uip_len; i++)
1129+ upload_data[i] = uip_appdata[i];
1130+ upload_data += uip_len;
1131+ uip_slen = 0;
1132+ if(hs->upload >= hs->upload_total)
1133+ {
1134+ upload_running = 1;
1135+ NetBootFileXferSize = hs->upload_total;
1136+ fs_open(file_flash_html.name, &fsfile);
1137+ hs->script = 0;
1138+ hs->state = HTTP_FILE;
1139+ hs->dataptr = fsfile.data;
1140+ hs->count = fsfile.len;
1141+ }
1142+ }
1143+ }
1144+ if(hs->state == HTTP_FILE)
1145+ {
1146+ if(uip_acked())
1147+ {
1148+ if(hs->count >= uip_conn->len)
1149+ {
1150+ hs->count -= uip_conn->len;
1151+ hs->dataptr += uip_conn->len;
1152+ } else {
1153+ hs->count = 0;
1154+ }
1155+ if(hs->count == 0)
1156+ {
1157+ if(upload_running)
1158+ {
1159+ int i;
1160+ httpd_upload_complete = 1;
1161+ // for(i = 0; i < hs->upload_total; i++)
1162+ // printf("%c", httpd_upload_data[i]);
1163+ }
1164+ uip_close();
1165+ }
1166+ }
1167+ uip_send(hs->dataptr, hs->count);
1168+ }
1169+ break;
1170+
1171+ default:
1172+ uip_abort();
1173+ break;
1174+ }
1175+}
1176--- /dev/null
1177+++ b/net/uip-0.9/httpd.h
1178@@ -0,0 +1,83 @@
1179+/**
1180+ * \addtogroup httpd
1181+ * @{
1182+ */
1183+
1184+/**
1185+ * \file
1186+ * HTTP server header file.
1187+ * \author Adam Dunkels <adam@dunkels.com>
1188+ */
1189+
1190+/*
1191+ * Copyright (c) 2001, Adam Dunkels.
1192+ * All rights reserved.
1193+ *
1194+ * Redistribution and use in source and binary forms, with or without
1195+ * modification, are permitted provided that the following conditions
1196+ * are met:
1197+ * 1. Redistributions of source code must retain the above copyright
1198+ * notice, this list of conditions and the following disclaimer.
1199+ * 2. Redistributions in binary form must reproduce the above copyright
1200+ * notice, this list of conditions and the following disclaimer in the
1201+ * documentation and/or other materials provided with the distribution.
1202+ * 3. The name of the author may not be used to endorse or promote
1203+ * products derived from this software without specific prior
1204+ * written permission.
1205+ *
1206+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1207+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1208+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1209+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1210+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1211+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1212+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1213+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1214+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1215+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1216+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1217+ *
1218+ * This file is part of the uIP TCP/IP stack.
1219+ *
1220+ * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $
1221+ *
1222+ */
1223+
1224+#ifndef __HTTPD_H__
1225+#define __HTTPD_H__
1226+
1227+void httpd_init(void);
1228+void httpd_appcall(void);
1229+
1230+/* UIP_APPCALL: the name of the application function. This function
1231+ must return void and take no arguments (i.e., C type "void
1232+ appfunc(void)"). */
1233+#ifndef UIP_APPCALL
1234+#define UIP_APPCALL httpd_appcall
1235+#endif
1236+
1237+struct httpd_state {
1238+ u8_t state;
1239+ u16_t count;
1240+ char *dataptr;
1241+ char *script;
1242+ unsigned int upload;
1243+ unsigned int upload_total;
1244+};
1245+
1246+
1247+/* UIP_APPSTATE_SIZE: The size of the application-specific state
1248+ stored in the uip_conn structure. */
1249+#ifndef UIP_APPSTATE_SIZE
1250+#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
1251+#endif
1252+
1253+#define FS_STATISTICS 1
1254+
1255+extern struct httpd_state *hs;
1256+
1257+
1258+/* we copy the data to RAM+10MB */
1259+#define TMP_DATA 0x8A100000
1260+
1261+#endif /* __HTTPD_H__ */
1262--- /dev/null
1263+++ b/net/uip-0.9/main.c
1264@@ -0,0 +1,88 @@
1265+/*
1266+ * Copyright (c) 2001-2003, Adam Dunkels.
1267+ * All rights reserved.
1268+ *
1269+ * Redistribution and use in source and binary forms, with or without
1270+ * modification, are permitted provided that the following conditions
1271+ * are met:
1272+ * 1. Redistributions of source code must retain the above copyright
1273+ * notice, this list of conditions and the following disclaimer.
1274+ * 2. Redistributions in binary form must reproduce the above copyright
1275+ * notice, this list of conditions and the following disclaimer in the
1276+ * documentation and/or other materials provided with the distribution.
1277+ * 3. The name of the author may not be used to endorse or promote
1278+ * products derived from this software without specific prior
1279+ * written permission.
1280+ *
1281+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1282+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1283+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1284+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1285+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1286+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1287+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1288+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1289+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1290+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1291+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1292+ *
1293+ * This file is part of the uIP TCP/IP stack.
1294+ *
1295+ * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $
1296+ *
1297+ */
1298+
1299+
1300+#include "uip.h"
1301+#include "uip_arp.h"
1302+#include "tapdev.h"
1303+#include "httpd.h"
1304+
1305+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
1306+
1307+#ifndef NULL
1308+#define NULL (void *)0
1309+#endif /* NULL */
1310+
1311+/*-----------------------------------------------------------------------------------*/
1312+int
1313+main(void)
1314+{
1315+ u8_t i, arptimer;
1316+ tapdev_init();
1317+ uip_init();
1318+ httpd_init();
1319+ arptimer = 0;
1320+ while(1) {
1321+ uip_len = tapdev_read();
1322+ if(uip_len == 0) {
1323+ for(i = 0; i < UIP_CONNS; i++) {
1324+ uip_periodic(i);
1325+ if(uip_len > 0) {
1326+ uip_arp_out();
1327+ tapdev_send();
1328+ }
1329+ }
1330+
1331+ if(++arptimer == 20) {
1332+ uip_arp_timer();
1333+ arptimer = 0;
1334+ }
1335+ } else {
1336+ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
1337+ uip_arp_ipin();
1338+ uip_input();
1339+ if(uip_len > 0) {
1340+ uip_arp_out();
1341+ tapdev_send();
1342+ }
1343+ } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
1344+ uip_arp_arpin();
1345+ if(uip_len > 0) {
1346+ tapdev_send();
1347+ }
1348+ }
1349+ }
1350+ }
1351+ return 0;
1352+}
1353--- /dev/null
1354+++ b/net/uip-0.9/tapdev.c
1355@@ -0,0 +1,192 @@
1356+/*
1357+ * Copyright (c) 2001, Swedish Institute of Computer Science.
1358+ * All rights reserved.
1359+ *
1360+ * Redistribution and use in source and binary forms, with or without
1361+ * modification, are permitted provided that the following conditions
1362+ * are met:
1363+ *
1364+ * 1. Redistributions of source code must retain the above copyright
1365+ * notice, this list of conditions and the following disclaimer.
1366+ *
1367+ * 2. Redistributions in binary form must reproduce the above copyright
1368+ * notice, this list of conditions and the following disclaimer in the
1369+ * documentation and/or other materials provided with the distribution.
1370+ *
1371+ * 3. Neither the name of the Institute nor the names of its contributors
1372+ * may be used to endorse or promote products derived from this software
1373+ * without specific prior written permission.
1374+ *
1375+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
1376+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1377+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1378+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
1379+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1380+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1381+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1382+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1383+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1384+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1385+ * SUCH DAMAGE.
1386+ *
1387+ * Author: Adam Dunkels <adam@sics.se>
1388+ *
1389+ * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $
1390+ */
1391+
1392+
1393+#include <fcntl.h>
1394+#include <stdlib.h>
1395+#include <stdio.h>
1396+#include <unistd.h>
1397+#include <string.h>
1398+#include <sys/ioctl.h>
1399+#include <sys/socket.h>
1400+#include <sys/types.h>
1401+#include <sys/time.h>
1402+#include <sys/uio.h>
1403+#include <sys/socket.h>
1404+
1405+#ifdef linux
1406+#include <sys/ioctl.h>
1407+#include <linux/if.h>
1408+#include <linux/if_tun.h>
1409+#define DEVTAP "/dev/net/tun"
1410+#else /* linux */
1411+#define DEVTAP "/dev/tap0"
1412+#endif /* linux */
1413+
1414+#include "uip.h"
1415+
1416+static int fd;
1417+
1418+static unsigned long lasttime;
1419+static struct timezone tz;
1420+
1421+/*-----------------------------------------------------------------------------------*/
1422+void
1423+tapdev_init(void)
1424+{
1425+ char buf[1024];
1426+
1427+ fd = open(DEVTAP, O_RDWR);
1428+ if(fd == -1) {
1429+ perror("tapdev: tapdev_init: open");
1430+ exit(1);
1431+ }
1432+
1433+#ifdef linux
1434+ {
1435+ struct ifreq ifr;
1436+ memset(&ifr, 0, sizeof(ifr));
1437+ ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
1438+ if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
1439+ perror(buf);
1440+ exit(1);
1441+ }
1442+ }
1443+#endif /* Linux */
1444+
1445+ snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
1446+ UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);
1447+ system(buf);
1448+
1449+ lasttime = 0;
1450+}
1451+
1452+void dump_mem(int type, int len)
1453+{
1454+#if DUMP == 1
1455+ int i;
1456+ for(i = 0; i < len; i++)
1457+ printf("%c", uip_buf[i]);
1458+ if(type)
1459+ {
1460+ 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");
1461+ 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");
1462+ } else {
1463+ 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");
1464+ 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");
1465+ }
1466+ fflush(stdout);
1467+#endif
1468+}
1469+
1470+/*-----------------------------------------------------------------------------------*/
1471+unsigned int
1472+tapdev_read(void)
1473+{
1474+ fd_set fdset;
1475+ struct timeval tv, now;
1476+ int ret;
1477+
1478+ if(lasttime >= 500000) {
1479+ lasttime = 0;
1480+ return 0;
1481+ }
1482+
1483+ tv.tv_sec = 0;
1484+ tv.tv_usec = 500000 - lasttime;
1485+
1486+
1487+ FD_ZERO(&fdset);
1488+ FD_SET(fd, &fdset);
1489+
1490+ gettimeofday(&now, &tz);
1491+ ret = select(fd + 1, &fdset, NULL, NULL, &tv);
1492+ if(ret == 0) {
1493+ lasttime = 0;
1494+ return 0;
1495+ }
1496+ ret = read(fd, uip_buf, UIP_BUFSIZE);
1497+ if(ret == -1) {
1498+ perror("tap_dev: tapdev_read: read");
1499+ }
1500+ gettimeofday(&tv, &tz);
1501+ lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
1502+ dump_mem(0, ret);
1503+ return ret;
1504+}
1505+/*-----------------------------------------------------------------------------------*/
1506+void
1507+tapdev_send(void)
1508+{
1509+ int ret;
1510+ struct iovec iov[2];
1511+
1512+#ifdef linux
1513+ {
1514+ char tmpbuf[UIP_BUFSIZE];
1515+ int i;
1516+
1517+ for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
1518+ tmpbuf[i] = uip_buf[i];
1519+ }
1520+
1521+ for(; i < uip_len; i++) {
1522+ tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
1523+ }
1524+
1525+ ret = write(fd, tmpbuf, uip_len);
1526+ }
1527+#else
1528+
1529+ if(uip_len < 40 + UIP_LLH_LEN) {
1530+ ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN);
1531+ } else {
1532+ iov[0].iov_base = uip_buf;
1533+ iov[0].iov_len = 40 + UIP_LLH_LEN;
1534+ iov[1].iov_base = (char *)uip_appdata;
1535+ iov[1].iov_len = uip_len - (40 + UIP_LLH_LEN);
1536+
1537+ ret = writev(fd, iov, 2);
1538+ }
1539+#endif
1540+ dump_mem(1, ret);
1541+
1542+ if(ret == -1) {
1543+ perror("tap_dev: tapdev_send: writev");
1544+ exit(1);
1545+ }
1546+}
1547+/*-----------------------------------------------------------------------------------*/
1548--- /dev/null
1549+++ b/net/uip-0.9/tapdev.h
1550@@ -0,0 +1,42 @@
1551+/*
1552+ * Copyright (c) 2001, Adam Dunkels.
1553+ * All rights reserved.
1554+ *
1555+ * Redistribution and use in source and binary forms, with or without
1556+ * modification, are permitted provided that the following conditions
1557+ * are met:
1558+ * 1. Redistributions of source code must retain the above copyright
1559+ * notice, this list of conditions and the following disclaimer.
1560+ * 2. Redistributions in binary form must reproduce the above copyright
1561+ * notice, this list of conditions and the following disclaimer in the
1562+ * documentation and/or other materials provided with the distribution.
1563+ * 3. The name of the author may not be used to endorse or promote
1564+ * products derived from this software without specific prior
1565+ * written permission.
1566+ *
1567+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1568+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1569+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1570+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1571+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1572+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1573+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1574+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1575+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1576+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1577+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1578+ *
1579+ * This file is part of the uIP TCP/IP stack.
1580+ *
1581+ * $Id: tapdev.h,v 1.1.2.1 2003/10/04 22:54:17 adam Exp $
1582+ *
1583+ */
1584+
1585+#ifndef __TAPDEV_H__
1586+#define __TAPDEV_H__
1587+
1588+void tapdev_init(void);
1589+unsigned int tapdev_read(void);
1590+void tapdev_send(void);
1591+
1592+#endif /* __TAPDEV_H__ */
1593--- /dev/null
1594+++ b/net/uip-0.9/uip.c
1595@@ -0,0 +1,1503 @@
1596+/**
1597+ * \addtogroup uip
1598+ * @{
1599+ */
1600+
1601+/**
1602+ * \file
1603+ * The uIP TCP/IP stack code.
1604+ * \author Adam Dunkels <adam@dunkels.com>
1605+ */
1606+
1607+/*
1608+ * Copyright (c) 2001-2003, Adam Dunkels.
1609+ * All rights reserved.
1610+ *
1611+ * Redistribution and use in source and binary forms, with or without
1612+ * modification, are permitted provided that the following conditions
1613+ * are met:
1614+ * 1. Redistributions of source code must retain the above copyright
1615+ * notice, this list of conditions and the following disclaimer.
1616+ * 2. Redistributions in binary form must reproduce the above copyright
1617+ * notice, this list of conditions and the following disclaimer in the
1618+ * documentation and/or other materials provided with the distribution.
1619+ * 3. The name of the author may not be used to endorse or promote
1620+ * products derived from this software without specific prior
1621+ * written permission.
1622+ *
1623+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1624+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1625+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1626+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1627+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1628+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1629+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1630+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1631+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1632+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1633+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1634+ *
1635+ * This file is part of the uIP TCP/IP stack.
1636+ *
1637+ * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
1638+ *
1639+ */
1640+
1641+/*
1642+This is a small implementation of the IP and TCP protocols (as well as
1643+some basic ICMP stuff). The implementation couples the IP, TCP and the
1644+application layers very tightly. To keep the size of the compiled code
1645+down, this code also features heavy usage of the goto statement.
1646+
1647+The principle is that we have a small buffer, called the uip_buf, in
1648+which the device driver puts an incoming packet. The TCP/IP stack
1649+parses the headers in the packet, and calls upon the application. If
1650+the remote host has sent data to the application, this data is present
1651+in the uip_buf and the application read the data from there. It is up
1652+to the application to put this data into a byte stream if needed. The
1653+application will not be fed with data that is out of sequence.
1654+
1655+If the application whishes to send data to the peer, it should put its
1656+data into the uip_buf, 40 bytes from the start of the buffer. The
1657+TCP/IP stack will calculate the checksums, and fill in the necessary
1658+header fields and finally send the packet back to the peer.
1659+*/
1660+
1661+#include "uip.h"
1662+#include "uipopt.h"
1663+#include "uip_arch.h"
1664+
1665+/*-----------------------------------------------------------------------------------*/
1666+/* Variable definitions. */
1667+
1668+
1669+/* 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 */
1670+#if UIP_FIXEDADDR > 0
1671+const unsigned short int uip_hostaddr[2] =
1672+ {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
1673+ HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
1674+const unsigned short int uip_arp_draddr[2] =
1675+ {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
1676+ HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
1677+const unsigned short int uip_arp_netmask[2] =
1678+ {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
1679+ HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
1680+#else
1681+unsigned short int uip_hostaddr[2];
1682+unsigned short int uip_arp_draddr[2], uip_arp_netmask[2];
1683+#endif /* UIP_FIXEDADDR */
1684+
1685+u8_t uip_buf[UIP_BUFSIZE+2]; /* The packet buffer that contains
1686+ incoming packets. */
1687+volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
1688+ application data. */
1689+volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to the
1690+ application data which is to be sent. */
1691+#if UIP_URGDATA > 0
1692+volatile u8_t *uip_urgdata; /* The uip_urgdata pointer points to
1693+ urgent data (out-of-band data), if
1694+ present. */
1695+volatile u8_t uip_urglen, uip_surglen;
1696+#endif /* UIP_URGDATA > 0 */
1697+
1698+volatile unsigned short int uip_len, uip_slen;
1699+ /* The uip_len is either 8 or 16 bits,
1700+ depending on the maximum packet
1701+ size. */
1702+
1703+volatile u8_t uip_flags; /* The uip_flags variable is used for
1704+ communication between the TCP/IP stack
1705+ and the application program. */
1706+struct uip_conn *uip_conn; /* uip_conn always points to the current
1707+ connection. */
1708+
1709+struct uip_conn uip_conns[UIP_CONNS];
1710+ /* The uip_conns array holds all TCP
1711+ connections. */
1712+unsigned short int uip_listenports[UIP_LISTENPORTS];
1713+ /* The uip_listenports list all currently
1714+ listning ports. */
1715+#if UIP_UDP
1716+struct uip_udp_conn *uip_udp_conn;
1717+struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
1718+#endif /* UIP_UDP */
1719+
1720+
1721+static unsigned short int ipid; /* Ths ipid variable is an increasing
1722+ number that is used for the IP ID
1723+ field. */
1724+
1725+static u8_t iss[4]; /* The iss variable is used for the TCP
1726+ initial sequence number. */
1727+
1728+#if UIP_ACTIVE_OPEN
1729+static unsigned short int lastport; /* Keeps track of the last port used for
1730+ a new connection. */
1731+#endif /* UIP_ACTIVE_OPEN */
1732+
1733+/* Temporary variables. */
1734+volatile u8_t uip_acc32[4];
1735+static u8_t c, opt;
1736+static unsigned short int tmp16;
1737+
1738+/* Structures and definitions. */
1739+#define TCP_FIN 0x01
1740+#define TCP_SYN 0x02
1741+#define TCP_RST 0x04
1742+#define TCP_PSH 0x08
1743+#define TCP_ACK 0x10
1744+#define TCP_URG 0x20
1745+#define TCP_CTL 0x3f
1746+
1747+#define ICMP_ECHO_REPLY 0
1748+#define ICMP_ECHO 8
1749+
1750+/* Macros. */
1751+#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
1752+#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
1753+#define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
1754+#define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
1755+
1756+#if UIP_STATISTICS == 1
1757+struct uip_stats uip_stat;
1758+#define UIP_STAT(s) s
1759+#else
1760+#define UIP_STAT(s)
1761+#endif /* UIP_STATISTICS == 1 */
1762+
1763+#if UIP_LOGGING == 1
1764+extern void puts(const char *s);
1765+#define UIP_LOG(m) puts(m)
1766+#else
1767+#define UIP_LOG(m)
1768+#endif /* UIP_LOGGING == 1 */
1769+
1770+/*-----------------------------------------------------------------------------------*/
1771+void
1772+uip_init(void)
1773+{
1774+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
1775+ uip_listenports[c] = 0;
1776+ }
1777+ for(c = 0; c < UIP_CONNS; ++c) {
1778+ uip_conns[c].tcpstateflags = CLOSED;
1779+ }
1780+#if UIP_ACTIVE_OPEN
1781+ lastport = 1024;
1782+#endif /* UIP_ACTIVE_OPEN */
1783+
1784+#if UIP_UDP
1785+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
1786+ uip_udp_conns[c].lport = 0;
1787+ }
1788+#endif /* UIP_UDP */
1789+
1790+
1791+ /* IPv4 initialization. */
1792+#if UIP_FIXEDADDR == 0
1793+ uip_hostaddr[0] = uip_hostaddr[1] = 0;
1794+#endif /* UIP_FIXEDADDR */
1795+
1796+}
1797+/*-----------------------------------------------------------------------------------*/
1798+#if UIP_ACTIVE_OPEN
1799+struct uip_conn *
1800+uip_connect(unsigned short int *ripaddr, unsigned short int rport)
1801+{
1802+ register struct uip_conn *conn, *cconn;
1803+
1804+ /* Find an unused local port. */
1805+ again:
1806+ ++lastport;
1807+
1808+ if(lastport >= 32000) {
1809+ lastport = 4096;
1810+ }
1811+
1812+ /* Check if this port is already in use, and if so try to find
1813+ another one. */
1814+ for(c = 0; c < UIP_CONNS; ++c) {
1815+ conn = &uip_conns[c];
1816+ if(conn->tcpstateflags != CLOSED &&
1817+ conn->lport == htons(lastport)) {
1818+ goto again;
1819+ }
1820+ }
1821+
1822+
1823+ conn = 0;
1824+ for(c = 0; c < UIP_CONNS; ++c) {
1825+ cconn = &uip_conns[c];
1826+ if(cconn->tcpstateflags == CLOSED) {
1827+ conn = cconn;
1828+ break;
1829+ }
1830+ if(cconn->tcpstateflags == TIME_WAIT) {
1831+ if(conn == 0 ||
1832+ cconn->timer > uip_conn->timer) {
1833+ conn = cconn;
1834+ }
1835+ }
1836+ }
1837+
1838+ if(conn == 0) {
1839+ return 0;
1840+ }
1841+
1842+ conn->tcpstateflags = SYN_SENT;
1843+
1844+ conn->snd_nxt[0] = iss[0];
1845+ conn->snd_nxt[1] = iss[1];
1846+ conn->snd_nxt[2] = iss[2];
1847+ conn->snd_nxt[3] = iss[3];
1848+
1849+ conn->initialmss = conn->mss = UIP_TCP_MSS;
1850+
1851+ conn->len = 1; /* TCP length of the SYN is one. */
1852+ conn->nrtx = 0;
1853+ conn->timer = 1; /* Send the SYN next time around. */
1854+ conn->rto = UIP_RTO;
1855+ conn->sa = 0;
1856+ conn->sv = 16;
1857+ conn->lport = htons(lastport);
1858+ conn->rport = rport;
1859+ conn->ripaddr[0] = ripaddr[0];
1860+ conn->ripaddr[1] = ripaddr[1];
1861+
1862+ return conn;
1863+}
1864+#endif /* UIP_ACTIVE_OPEN */
1865+/*-----------------------------------------------------------------------------------*/
1866+#if UIP_UDP
1867+struct uip_udp_conn *
1868+uip_udp_new(unsigned short int *ripaddr, unsigned short int rport)
1869+{
1870+ register struct uip_udp_conn *conn;
1871+
1872+ /* Find an unused local port. */
1873+ again:
1874+ ++lastport;
1875+
1876+ if(lastport >= 32000) {
1877+ lastport = 4096;
1878+ }
1879+
1880+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
1881+ if(uip_udp_conns[c].lport == lastport) {
1882+ goto again;
1883+ }
1884+ }
1885+
1886+
1887+ conn = 0;
1888+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
1889+ if(uip_udp_conns[c].lport == 0) {
1890+ conn = &uip_udp_conns[c];
1891+ break;
1892+ }
1893+ }
1894+
1895+ if(conn == 0) {
1896+ return 0;
1897+ }
1898+
1899+ conn->lport = HTONS(lastport);
1900+ conn->rport = HTONS(rport);
1901+ conn->ripaddr[0] = ripaddr[0];
1902+ conn->ripaddr[1] = ripaddr[1];
1903+
1904+ return conn;
1905+}
1906+#endif /* UIP_UDP */
1907+/*-----------------------------------------------------------------------------------*/
1908+void
1909+uip_unlisten(unsigned short int port)
1910+{
1911+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
1912+ if(uip_listenports[c] == port) {
1913+ uip_listenports[c] = 0;
1914+ return;
1915+ }
1916+ }
1917+}
1918+/*-----------------------------------------------------------------------------------*/
1919+void
1920+uip_listen(unsigned short int port)
1921+{
1922+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
1923+ if(uip_listenports[c] == 0) {
1924+ uip_listenports[c] = port;
1925+ return;
1926+ }
1927+ }
1928+}
1929+/*-----------------------------------------------------------------------------------*/
1930+/* XXX: IP fragment reassembly: not well-tested. */
1931+
1932+#if UIP_REASSEMBLY
1933+#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
1934+static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
1935+static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
1936+static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
1937+ 0x0f, 0x07, 0x03, 0x01};
1938+static unsigned short int uip_reasslen;
1939+static u8_t uip_reassflags;
1940+#define UIP_REASS_FLAG_LASTFRAG 0x01
1941+static u8_t uip_reasstmr;
1942+
1943+#define IP_HLEN 20
1944+#define IP_MF 0x20
1945+
1946+static u8_t
1947+uip_reass(void)
1948+{
1949+ unsigned short int offset, len;
1950+ unsigned short int i;
1951+
1952+ /* If ip_reasstmr is zero, no packet is present in the buffer, so we
1953+ write the IP header of the fragment into the reassembly
1954+ buffer. The timer is updated with the maximum age. */
1955+ if(uip_reasstmr == 0) {
1956+ memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
1957+ uip_reasstmr = UIP_REASS_MAXAGE;
1958+ uip_reassflags = 0;
1959+ /* Clear the bitmap. */
1960+ memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
1961+ }
1962+
1963+ /* Check if the incoming fragment matches the one currently present
1964+ in the reasembly buffer. If so, we proceed with copying the
1965+ fragment into the buffer. */
1966+ if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
1967+ BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
1968+ BUF->destipaddr[0] == FBUF->destipaddr[0] &&
1969+ BUF->destipaddr[1] == FBUF->destipaddr[1] &&
1970+ BUF->ipid[0] == FBUF->ipid[0] &&
1971+ BUF->ipid[1] == FBUF->ipid[1]) {
1972+
1973+ len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
1974+ offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
1975+
1976+ /* If the offset or the offset + fragment length overflows the
1977+ reassembly buffer, we discard the entire packet. */
1978+ if(offset > UIP_REASS_BUFSIZE ||
1979+ offset + len > UIP_REASS_BUFSIZE) {
1980+ uip_reasstmr = 0;
1981+ goto nullreturn;
1982+ }
1983+
1984+ /* Copy the fragment into the reassembly buffer, at the right
1985+ offset. */
1986+ memcpy(&uip_reassbuf[IP_HLEN + offset],
1987+ (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
1988+ len);
1989+
1990+ /* Update the bitmap. */
1991+ if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
1992+ /* If the two endpoints are in the same byte, we only update
1993+ that byte. */
1994+
1995+ uip_reassbitmap[offset / (8 * 8)] |=
1996+ bitmap_bits[(offset / 8 ) & 7] &
1997+ ~bitmap_bits[((offset + len) / 8 ) & 7];
1998+ } else {
1999+ /* If the two endpoints are in different bytes, we update the
2000+ bytes in the endpoints and fill the stuff inbetween with
2001+ 0xff. */
2002+ uip_reassbitmap[offset / (8 * 8)] |=
2003+ bitmap_bits[(offset / 8 ) & 7];
2004+ for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
2005+ uip_reassbitmap[i] = 0xff;
2006+ }
2007+ uip_reassbitmap[(offset + len) / (8 * 8)] |=
2008+ ~bitmap_bits[((offset + len) / 8 ) & 7];
2009+ }
2010+
2011+ /* If this fragment has the More Fragments flag set to zero, we
2012+ know that this is the last fragment, so we can calculate the
2013+ size of the entire packet. We also set the
2014+ IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
2015+ the final fragment. */
2016+
2017+ if((BUF->ipoffset[0] & IP_MF) == 0) {
2018+ uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
2019+ uip_reasslen = offset + len;
2020+ }
2021+
2022+ /* Finally, we check if we have a full packet in the buffer. We do
2023+ this by checking if we have the last fragment and if all bits
2024+ in the bitmap are set. */
2025+ if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
2026+ /* Check all bytes up to and including all but the last byte in
2027+ the bitmap. */
2028+ for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
2029+ if(uip_reassbitmap[i] != 0xff) {
2030+ goto nullreturn;
2031+ }
2032+ }
2033+ /* Check the last byte in the bitmap. It should contain just the
2034+ right amount of bits. */
2035+ if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
2036+ (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
2037+ goto nullreturn;
2038+ }
2039+
2040+ /* If we have come this far, we have a full packet in the
2041+ buffer, so we allocate a pbuf and copy the packet into it. We
2042+ also reset the timer. */
2043+ uip_reasstmr = 0;
2044+ memcpy(BUF, FBUF, uip_reasslen);
2045+
2046+ /* Pretend to be a "normal" (i.e., not fragmented) IP packet
2047+ from now on. */
2048+ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
2049+ BUF->len[0] = uip_reasslen >> 8;
2050+ BUF->len[1] = uip_reasslen & 0xff;
2051+ BUF->ipchksum = 0;
2052+ BUF->ipchksum = ~(uip_ipchksum());
2053+
2054+ return uip_reasslen;
2055+ }
2056+ }
2057+
2058+ nullreturn:
2059+ return 0;
2060+}
2061+#endif /* UIP_REASSEMBL */
2062+/*-----------------------------------------------------------------------------------*/
2063+static void
2064+uip_add_rcv_nxt(unsigned short int n)
2065+{
2066+ uip_add32(uip_conn->rcv_nxt, n);
2067+ uip_conn->rcv_nxt[0] = uip_acc32[0];
2068+ uip_conn->rcv_nxt[1] = uip_acc32[1];
2069+ uip_conn->rcv_nxt[2] = uip_acc32[2];
2070+ uip_conn->rcv_nxt[3] = uip_acc32[3];
2071+}
2072+/*-----------------------------------------------------------------------------------*/
2073+void
2074+uip_process(u8_t flag)
2075+{
2076+ register struct uip_conn *uip_connr = uip_conn;
2077+
2078+ uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
2079+
2080+
2081+ /* Check if we were invoked because of the perodic timer fireing. */
2082+ if(flag == UIP_TIMER) {
2083+#if UIP_REASSEMBLY
2084+ if(uip_reasstmr != 0) {
2085+ --uip_reasstmr;
2086+ }
2087+#endif /* UIP_REASSEMBLY */
2088+ /* Increase the initial sequence number. */
2089+ if(++iss[3] == 0) {
2090+ if(++iss[2] == 0) {
2091+ if(++iss[1] == 0) {
2092+ ++iss[0];
2093+ }
2094+ }
2095+ }
2096+ uip_len = 0;
2097+ if(uip_connr->tcpstateflags == TIME_WAIT ||
2098+ uip_connr->tcpstateflags == FIN_WAIT_2) {
2099+ ++(uip_connr->timer);
2100+ if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
2101+ uip_connr->tcpstateflags = CLOSED;
2102+ }
2103+ } else if(uip_connr->tcpstateflags != CLOSED) {
2104+ /* If the connection has outstanding data, we increase the
2105+ connection's timer and see if it has reached the RTO value
2106+ in which case we retransmit. */
2107+ if(uip_outstanding(uip_connr)) {
2108+ if(uip_connr->timer-- == 0) {
2109+ if(uip_connr->nrtx == UIP_MAXRTX ||
2110+ ((uip_connr->tcpstateflags == SYN_SENT ||
2111+ uip_connr->tcpstateflags == SYN_RCVD) &&
2112+ uip_connr->nrtx == UIP_MAXSYNRTX)) {
2113+ uip_connr->tcpstateflags = CLOSED;
2114+
2115+ /* We call UIP_APPCALL() with uip_flags set to
2116+ UIP_TIMEDOUT to inform the application that the
2117+ connection has timed out. */
2118+ uip_flags = UIP_TIMEDOUT;
2119+ UIP_APPCALL();
2120+
2121+ /* We also send a reset packet to the remote host. */
2122+ BUF->flags = TCP_RST | TCP_ACK;
2123+ goto tcp_send_nodata;
2124+ }
2125+
2126+ /* Exponential backoff. */
2127+ uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
2128+ 4:
2129+ uip_connr->nrtx);
2130+ ++(uip_connr->nrtx);
2131+
2132+ /* Ok, so we need to retransmit. We do this differently
2133+ depending on which state we are in. In ESTABLISHED, we
2134+ call upon the application so that it may prepare the
2135+ data for the retransmit. In SYN_RCVD, we resend the
2136+ SYNACK that we sent earlier and in LAST_ACK we have to
2137+ retransmit our FINACK. */
2138+ UIP_STAT(++uip_stat.tcp.rexmit);
2139+ switch(uip_connr->tcpstateflags & TS_MASK) {
2140+ case SYN_RCVD:
2141+ /* In the SYN_RCVD state, we should retransmit our
2142+ SYNACK. */
2143+ goto tcp_send_synack;
2144+
2145+#if UIP_ACTIVE_OPEN
2146+ case SYN_SENT:
2147+ /* In the SYN_SENT state, we retransmit out SYN. */
2148+ BUF->flags = 0;
2149+ goto tcp_send_syn;
2150+#endif /* UIP_ACTIVE_OPEN */
2151+
2152+ case ESTABLISHED:
2153+ /* In the ESTABLISHED state, we call upon the application
2154+ to do the actual retransmit after which we jump into
2155+ the code for sending out the packet (the apprexmit
2156+ label). */
2157+ uip_len = 0;
2158+ uip_slen = 0;
2159+ uip_flags = UIP_REXMIT;
2160+ UIP_APPCALL();
2161+ goto apprexmit;
2162+
2163+ case FIN_WAIT_1:
2164+ case CLOSING:
2165+ case LAST_ACK:
2166+ /* In all these states we should retransmit a FINACK. */
2167+ goto tcp_send_finack;
2168+
2169+ }
2170+ }
2171+ } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
2172+ /* If there was no need for a retransmission, we poll the
2173+ application for new data. */
2174+ uip_len = 0;
2175+ uip_slen = 0;
2176+ uip_flags = UIP_POLL;
2177+ UIP_APPCALL();
2178+ goto appsend;
2179+ }
2180+ }
2181+ goto drop;
2182+ }
2183+#if UIP_UDP
2184+ if(flag == UIP_UDP_TIMER) {
2185+ if(uip_udp_conn->lport != 0) {
2186+ uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
2187+ uip_len = uip_slen = 0;
2188+ uip_flags = UIP_POLL;
2189+ UIP_UDP_APPCALL();
2190+ goto udp_send;
2191+ } else {
2192+ goto drop;
2193+ }
2194+ }
2195+#endif
2196+
2197+ /* This is where the input processing starts. */
2198+ UIP_STAT(++uip_stat.ip.recv);
2199+
2200+
2201+ /* Start of IPv4 input header processing code. */
2202+
2203+ /* Check validity of the IP header. */
2204+ if(BUF->vhl != 0x45) { /* IP version and header length. */
2205+ UIP_STAT(++uip_stat.ip.drop);
2206+ UIP_STAT(++uip_stat.ip.vhlerr);
2207+ UIP_LOG("ip: invalid version or header length.");
2208+ goto drop;
2209+ }
2210+
2211+ /* Check the size of the packet. If the size reported to us in
2212+ uip_len doesn't match the size reported in the IP header, there
2213+ has been a transmission error and we drop the packet. */
2214+
2215+ if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
2216+ uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
2217+ }
2218+ if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
2219+ uip_len = (uip_len & 0xff00) | BUF->len[1];
2220+ }
2221+
2222+ /* Check the fragment flag. */
2223+ if((BUF->ipoffset[0] & 0x3f) != 0 ||
2224+ BUF->ipoffset[1] != 0) {
2225+#if UIP_REASSEMBLY
2226+ uip_len = uip_reass();
2227+ if(uip_len == 0) {
2228+ goto drop;
2229+ }
2230+#else
2231+ UIP_STAT(++uip_stat.ip.drop);
2232+ UIP_STAT(++uip_stat.ip.fragerr);
2233+ UIP_LOG("ip: fragment dropped.");
2234+ goto drop;
2235+#endif /* UIP_REASSEMBLY */
2236+ }
2237+
2238+ /* If we are configured to use ping IP address configuration and
2239+ hasn't been assigned an IP address yet, we accept all ICMP
2240+ packets. */
2241+#if UIP_PINGADDRCONF
2242+ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
2243+ if(BUF->proto == UIP_PROTO_ICMP) {
2244+ UIP_LOG("ip: possible ping config packet received.");
2245+ goto icmp_input;
2246+ } else {
2247+ UIP_LOG("ip: packet dropped since no address assigned.");
2248+ goto drop;
2249+ }
2250+ }
2251+#endif /* UIP_PINGADDRCONF */
2252+
2253+ /* Check if the packet is destined for our IP address. */
2254+ if(BUF->destipaddr[0] != uip_hostaddr[0]) {
2255+ UIP_STAT(++uip_stat.ip.drop);
2256+ UIP_LOG("ip: packet not for us.");
2257+ goto drop;
2258+ }
2259+ if(BUF->destipaddr[1] != uip_hostaddr[1]) {
2260+ UIP_STAT(++uip_stat.ip.drop);
2261+ UIP_LOG("ip: packet not for us.");
2262+ goto drop;
2263+ }
2264+
2265+ if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
2266+ checksum. */
2267+ UIP_STAT(++uip_stat.ip.drop);
2268+ UIP_STAT(++uip_stat.ip.chkerr);
2269+ UIP_LOG("ip: bad checksum.");
2270+ goto drop;
2271+ }
2272+
2273+ if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump
2274+ to the tcp_input label. */
2275+ goto tcp_input;
2276+
2277+#if UIP_UDP
2278+ if(BUF->proto == UIP_PROTO_UDP)
2279+ goto udp_input;
2280+#endif /* UIP_UDP */
2281+
2282+ if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
2283+ here. */
2284+ UIP_STAT(++uip_stat.ip.drop);
2285+ UIP_STAT(++uip_stat.ip.protoerr);
2286+ UIP_LOG("ip: neither tcp nor icmp.");
2287+ goto drop;
2288+ }
2289+
2290+ //icmp_input:
2291+ UIP_STAT(++uip_stat.icmp.recv);
2292+
2293+ /* ICMP echo (i.e., ping) processing. This is simple, we only change
2294+ the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
2295+ checksum before we return the packet. */
2296+ if(ICMPBUF->type != ICMP_ECHO) {
2297+ UIP_STAT(++uip_stat.icmp.drop);
2298+ UIP_STAT(++uip_stat.icmp.typeerr);
2299+ UIP_LOG("icmp: not icmp echo.");
2300+ goto drop;
2301+ }
2302+
2303+ /* If we are configured to use ping IP address assignment, we use
2304+ the destination IP address of this ping packet and assign it to
2305+ ourself. */
2306+#if UIP_PINGADDRCONF
2307+ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
2308+ uip_hostaddr[0] = BUF->destipaddr[0];
2309+ uip_hostaddr[1] = BUF->destipaddr[1];
2310+ }
2311+#endif /* UIP_PINGADDRCONF */
2312+
2313+ ICMPBUF->type = ICMP_ECHO_REPLY;
2314+
2315+ if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
2316+ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
2317+ } else {
2318+ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
2319+ }
2320+
2321+ /* Swap IP addresses. */
2322+ tmp16 = BUF->destipaddr[0];
2323+ BUF->destipaddr[0] = BUF->srcipaddr[0];
2324+ BUF->srcipaddr[0] = tmp16;
2325+ tmp16 = BUF->destipaddr[1];
2326+ BUF->destipaddr[1] = BUF->srcipaddr[1];
2327+ BUF->srcipaddr[1] = tmp16;
2328+
2329+ UIP_STAT(++uip_stat.icmp.sent);
2330+ goto send;
2331+
2332+ /* End of IPv4 input header processing code. */
2333+
2334+
2335+#if UIP_UDP
2336+ /* UDP input processing. */
2337+ udp_input:
2338+ /* UDP processing is really just a hack. We don't do anything to the
2339+ UDP/IP headers, but let the UDP application do all the hard
2340+ work. If the application sets uip_slen, it has a packet to
2341+ send. */
2342+#if UIP_UDP_CHECKSUMS
2343+ if(uip_udpchksum() != 0xffff) {
2344+ UIP_STAT(++uip_stat.udp.drop);
2345+ UIP_STAT(++uip_stat.udp.chkerr);
2346+ UIP_LOG("udp: bad checksum.");
2347+ goto drop;
2348+ }
2349+#endif /* UIP_UDP_CHECKSUMS */
2350+
2351+ /* Demultiplex this UDP packet between the UDP "connections". */
2352+ for(uip_udp_conn = &uip_udp_conns[0];
2353+ uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
2354+ ++uip_udp_conn) {
2355+ if(uip_udp_conn->lport != 0 &&
2356+ UDPBUF->destport == uip_udp_conn->lport &&
2357+ (uip_udp_conn->rport == 0 ||
2358+ UDPBUF->srcport == uip_udp_conn->rport) &&
2359+ BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
2360+ BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
2361+ goto udp_found;
2362+ }
2363+ }
2364+ goto drop;
2365+
2366+ udp_found:
2367+ uip_len = uip_len - 28;
2368+ uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
2369+ uip_flags = UIP_NEWDATA;
2370+ uip_slen = 0;
2371+ UIP_UDP_APPCALL();
2372+ udp_send:
2373+ if(uip_slen == 0) {
2374+ goto drop;
2375+ }
2376+ uip_len = uip_slen + 28;
2377+
2378+ BUF->len[0] = (uip_len >> 8);
2379+ BUF->len[1] = (uip_len & 0xff);
2380+
2381+ BUF->proto = UIP_PROTO_UDP;
2382+
2383+ UDPBUF->udplen = HTONS(uip_slen + 8);
2384+ UDPBUF->udpchksum = 0;
2385+#if UIP_UDP_CHECKSUMS
2386+ /* Calculate UDP checksum. */
2387+ UDPBUF->udpchksum = ~(uip_udpchksum());
2388+ if(UDPBUF->udpchksum == 0) {
2389+ UDPBUF->udpchksum = 0xffff;
2390+ }
2391+#endif /* UIP_UDP_CHECKSUMS */
2392+
2393+ BUF->srcport = uip_udp_conn->lport;
2394+ BUF->destport = uip_udp_conn->rport;
2395+
2396+ BUF->srcipaddr[0] = uip_hostaddr[0];
2397+ BUF->srcipaddr[1] = uip_hostaddr[1];
2398+ BUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
2399+ BUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
2400+
2401+ uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
2402+ goto ip_send_nolen;
2403+#endif /* UIP_UDP */
2404+
2405+ /* TCP input processing. */
2406+ tcp_input:
2407+ UIP_STAT(++uip_stat.tcp.recv);
2408+
2409+ /* Start of TCP input header processing code. */
2410+
2411+ if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
2412+ checksum. */
2413+ UIP_STAT(++uip_stat.tcp.drop);
2414+ UIP_STAT(++uip_stat.tcp.chkerr);
2415+ UIP_LOG("tcp: bad checksum.");
2416+ goto drop;
2417+ }
2418+
2419+ /* Demultiplex this segment. */
2420+ /* First check any active connections. */
2421+ for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) {
2422+ if(uip_connr->tcpstateflags != CLOSED &&
2423+ BUF->destport == uip_connr->lport &&
2424+ BUF->srcport == uip_connr->rport &&
2425+ BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
2426+ BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
2427+ goto found;
2428+ }
2429+ }
2430+
2431+ /* If we didn't find and active connection that expected the packet,
2432+ either this packet is an old duplicate, or this is a SYN packet
2433+ destined for a connection in LISTEN. If the SYN flag isn't set,
2434+ it is an old packet and we send a RST. */
2435+ if((BUF->flags & TCP_CTL) != TCP_SYN)
2436+ goto reset;
2437+
2438+ tmp16 = BUF->destport;
2439+ /* Next, check listening connections. */
2440+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
2441+ if(tmp16 == uip_listenports[c])
2442+ goto found_listen;
2443+ }
2444+
2445+ /* No matching connection found, so we send a RST packet. */
2446+ UIP_STAT(++uip_stat.tcp.synrst);
2447+ reset:
2448+
2449+ /* We do not send resets in response to resets. */
2450+ if(BUF->flags & TCP_RST)
2451+ goto drop;
2452+
2453+ UIP_STAT(++uip_stat.tcp.rst);
2454+
2455+ BUF->flags = TCP_RST | TCP_ACK;
2456+ uip_len = 40;
2457+ BUF->tcpoffset = 5 << 4;
2458+
2459+ /* Flip the seqno and ackno fields in the TCP header. */
2460+ c = BUF->seqno[3];
2461+ BUF->seqno[3] = BUF->ackno[3];
2462+ BUF->ackno[3] = c;
2463+
2464+ c = BUF->seqno[2];
2465+ BUF->seqno[2] = BUF->ackno[2];
2466+ BUF->ackno[2] = c;
2467+
2468+ c = BUF->seqno[1];
2469+ BUF->seqno[1] = BUF->ackno[1];
2470+ BUF->ackno[1] = c;
2471+
2472+ c = BUF->seqno[0];
2473+ BUF->seqno[0] = BUF->ackno[0];
2474+ BUF->ackno[0] = c;
2475+
2476+ /* We also have to increase the sequence number we are
2477+ acknowledging. If the least significant byte overflowed, we need
2478+ to propagate the carry to the other bytes as well. */
2479+ if(++BUF->ackno[3] == 0) {
2480+ if(++BUF->ackno[2] == 0) {
2481+ if(++BUF->ackno[1] == 0) {
2482+ ++BUF->ackno[0];
2483+ }
2484+ }
2485+ }
2486+
2487+ /* Swap port numbers. */
2488+ tmp16 = BUF->srcport;
2489+ BUF->srcport = BUF->destport;
2490+ BUF->destport = tmp16;
2491+
2492+ /* Swap IP addresses. */
2493+ tmp16 = BUF->destipaddr[0];
2494+ BUF->destipaddr[0] = BUF->srcipaddr[0];
2495+ BUF->srcipaddr[0] = tmp16;
2496+ tmp16 = BUF->destipaddr[1];
2497+ BUF->destipaddr[1] = BUF->srcipaddr[1];
2498+ BUF->srcipaddr[1] = tmp16;
2499+
2500+
2501+ /* And send out the RST packet! */
2502+ goto tcp_send_noconn;
2503+
2504+ /* This label will be jumped to if we matched the incoming packet
2505+ with a connection in LISTEN. In that case, we should create a new
2506+ connection and send a SYNACK in return. */
2507+ found_listen:
2508+ /* First we check if there are any connections avaliable. Unused
2509+ connections are kept in the same table as used connections, but
2510+ unused ones have the tcpstate set to CLOSED. Also, connections in
2511+ TIME_WAIT are kept track of and we'll use the oldest one if no
2512+ CLOSED connections are found. Thanks to Eddie C. Dost for a very
2513+ nice algorithm for the TIME_WAIT search. */
2514+ uip_connr = 0;
2515+ for(c = 0; c < UIP_CONNS; ++c) {
2516+ if(uip_conns[c].tcpstateflags == CLOSED) {
2517+ uip_connr = &uip_conns[c];
2518+ break;
2519+ }
2520+ if(uip_conns[c].tcpstateflags == TIME_WAIT) {
2521+ if(uip_connr == 0 ||
2522+ uip_conns[c].timer > uip_connr->timer) {
2523+ uip_connr = &uip_conns[c];
2524+ }
2525+ }
2526+ }
2527+
2528+ if(uip_connr == 0) {
2529+ /* All connections are used already, we drop packet and hope that
2530+ the remote end will retransmit the packet at a time when we
2531+ have more spare connections. */
2532+ UIP_STAT(++uip_stat.tcp.syndrop);
2533+ UIP_LOG("tcp: found no unused connections.");
2534+ goto drop;
2535+ }
2536+ uip_conn = uip_connr;
2537+
2538+ /* Fill in the necessary fields for the new connection. */
2539+ uip_connr->rto = uip_connr->timer = UIP_RTO;
2540+ uip_connr->sa = 0;
2541+ uip_connr->sv = 4;
2542+ uip_connr->nrtx = 0;
2543+ uip_connr->lport = BUF->destport;
2544+ uip_connr->rport = BUF->srcport;
2545+ uip_connr->ripaddr[0] = BUF->srcipaddr[0];
2546+ uip_connr->ripaddr[1] = BUF->srcipaddr[1];
2547+ uip_connr->tcpstateflags = SYN_RCVD;
2548+
2549+ uip_connr->snd_nxt[0] = iss[0];
2550+ uip_connr->snd_nxt[1] = iss[1];
2551+ uip_connr->snd_nxt[2] = iss[2];
2552+ uip_connr->snd_nxt[3] = iss[3];
2553+ uip_connr->len = 1;
2554+
2555+ /* rcv_nxt should be the seqno from the incoming packet + 1. */
2556+ uip_connr->rcv_nxt[3] = BUF->seqno[3];
2557+ uip_connr->rcv_nxt[2] = BUF->seqno[2];
2558+ uip_connr->rcv_nxt[1] = BUF->seqno[1];
2559+ uip_connr->rcv_nxt[0] = BUF->seqno[0];
2560+ uip_add_rcv_nxt(1);
2561+
2562+ /* Parse the TCP MSS option, if present. */
2563+ if((BUF->tcpoffset & 0xf0) > 0x50) {
2564+ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
2565+ opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
2566+ if(opt == 0x00) {
2567+ /* End of options. */
2568+ break;
2569+ } else if(opt == 0x01) {
2570+ ++c;
2571+ /* NOP option. */
2572+ } else if(opt == 0x02 &&
2573+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
2574+ /* An MSS option with the right option length. */
2575+ tmp16 = ((unsigned short int)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
2576+ (unsigned short int)uip_buf[40 + UIP_LLH_LEN + 3 + c];
2577+ uip_connr->initialmss = uip_connr->mss =
2578+ tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
2579+
2580+ /* And we are done processing options. */
2581+ break;
2582+ } else {
2583+ /* All other options have a length field, so that we easily
2584+ can skip past them. */
2585+ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
2586+ /* If the length field is zero, the options are malformed
2587+ and we don't process them further. */
2588+ break;
2589+ }
2590+ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
2591+ }
2592+ }
2593+ }
2594+
2595+ /* Our response will be a SYNACK. */
2596+#if UIP_ACTIVE_OPEN
2597+ tcp_send_synack:
2598+ BUF->flags = TCP_ACK;
2599+
2600+ tcp_send_syn:
2601+ BUF->flags |= TCP_SYN;
2602+#else /* UIP_ACTIVE_OPEN */
2603+ tcp_send_synack:
2604+ BUF->flags = TCP_SYN | TCP_ACK;
2605+#endif /* UIP_ACTIVE_OPEN */
2606+
2607+ /* We send out the TCP Maximum Segment Size option with our
2608+ SYNACK. */
2609+ BUF->optdata[0] = 2;
2610+ BUF->optdata[1] = 4;
2611+ BUF->optdata[2] = (UIP_TCP_MSS) / 256;
2612+ BUF->optdata[3] = (UIP_TCP_MSS) & 255;
2613+ uip_len = 44;
2614+ BUF->tcpoffset = 6 << 4;
2615+ goto tcp_send;
2616+
2617+ /* This label will be jumped to if we found an active connection. */
2618+ found:
2619+ uip_conn = uip_connr;
2620+ uip_flags = 0;
2621+
2622+ /* We do a very naive form of TCP reset processing; we just accept
2623+ any RST and kill our connection. We should in fact check if the
2624+ sequence number of this reset is wihtin our advertised window
2625+ before we accept the reset. */
2626+ if(BUF->flags & TCP_RST) {
2627+ uip_connr->tcpstateflags = CLOSED;
2628+ UIP_LOG("tcp: got reset, aborting connection.");
2629+ uip_flags = UIP_ABORT;
2630+ UIP_APPCALL();
2631+ goto drop;
2632+ }
2633+ /* Calculated the length of the data, if the application has sent
2634+ any data to us. */
2635+ c = (BUF->tcpoffset >> 4) << 2;
2636+ /* uip_len will contain the length of the actual TCP data. This is
2637+ calculated by subtracing the length of the TCP header (in
2638+ c) and the length of the IP header (20 bytes). */
2639+ uip_len = uip_len - c - 20;
2640+
2641+ /* First, check if the sequence number of the incoming packet is
2642+ what we're expecting next. If not, we send out an ACK with the
2643+ correct numbers in. */
2644+ if(uip_len > 0 &&
2645+ (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
2646+ BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
2647+ BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
2648+ BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
2649+ goto tcp_send_ack;
2650+ }
2651+
2652+ /* Next, check if the incoming segment acknowledges any outstanding
2653+ data. If so, we update the sequence number, reset the length of
2654+ the outstanding data, calculate RTT estimations, and reset the
2655+ retransmission timer. */
2656+ if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
2657+ uip_add32(uip_connr->snd_nxt, uip_connr->len);
2658+ if(BUF->ackno[0] == uip_acc32[0] &&
2659+ BUF->ackno[1] == uip_acc32[1] &&
2660+ BUF->ackno[2] == uip_acc32[2] &&
2661+ BUF->ackno[3] == uip_acc32[3]) {
2662+ /* Update sequence number. */
2663+ uip_connr->snd_nxt[0] = uip_acc32[0];
2664+ uip_connr->snd_nxt[1] = uip_acc32[1];
2665+ uip_connr->snd_nxt[2] = uip_acc32[2];
2666+ uip_connr->snd_nxt[3] = uip_acc32[3];
2667+
2668+
2669+ /* Do RTT estimation, unless we have done retransmissions. */
2670+ if(uip_connr->nrtx == 0) {
2671+ signed char m;
2672+ m = uip_connr->rto - uip_connr->timer;
2673+ /* This is taken directly from VJs original code in his paper */
2674+ m = m - (uip_connr->sa >> 3);
2675+ uip_connr->sa += m;
2676+ if(m < 0) {
2677+ m = -m;
2678+ }
2679+ m = m - (uip_connr->sv >> 2);
2680+ uip_connr->sv += m;
2681+ uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
2682+
2683+ }
2684+ /* Set the acknowledged flag. */
2685+ uip_flags = UIP_ACKDATA;
2686+ /* Reset the retransmission timer. */
2687+ uip_connr->timer = uip_connr->rto;
2688+ }
2689+
2690+ }
2691+
2692+ /* Do different things depending on in what state the connection is. */
2693+ switch(uip_connr->tcpstateflags & TS_MASK) {
2694+ /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
2695+ implemented, since we force the application to close when the
2696+ peer sends a FIN (hence the application goes directly from
2697+ ESTABLISHED to LAST_ACK). */
2698+ case SYN_RCVD:
2699+ /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
2700+ we are waiting for an ACK that acknowledges the data we sent
2701+ out the last time. Therefore, we want to have the UIP_ACKDATA
2702+ flag set. If so, we enter the ESTABLISHED state. */
2703+ if(uip_flags & UIP_ACKDATA) {
2704+ uip_connr->tcpstateflags = ESTABLISHED;
2705+ uip_flags = UIP_CONNECTED;
2706+ uip_connr->len = 0;
2707+ if(uip_len > 0) {
2708+ uip_flags |= UIP_NEWDATA;
2709+ uip_add_rcv_nxt(uip_len);
2710+ }
2711+ uip_slen = 0;
2712+ UIP_APPCALL();
2713+ goto appsend;
2714+ }
2715+ goto drop;
2716+#if UIP_ACTIVE_OPEN
2717+ case SYN_SENT:
2718+ /* In SYN_SENT, we wait for a SYNACK that is sent in response to
2719+ our SYN. The rcv_nxt is set to sequence number in the SYNACK
2720+ plus one, and we send an ACK. We move into the ESTABLISHED
2721+ state. */
2722+ if((uip_flags & UIP_ACKDATA) &&
2723+ BUF->flags == (TCP_SYN | TCP_ACK)) {
2724+
2725+ /* Parse the TCP MSS option, if present. */
2726+ if((BUF->tcpoffset & 0xf0) > 0x50) {
2727+ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
2728+ opt = uip_buf[40 + UIP_LLH_LEN + c];
2729+ if(opt == 0x00) {
2730+ /* End of options. */
2731+ break;
2732+ } else if(opt == 0x01) {
2733+ ++c;
2734+ /* NOP option. */
2735+ } else if(opt == 0x02 &&
2736+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
2737+ /* An MSS option with the right option length. */
2738+ tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
2739+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
2740+ uip_connr->initialmss =
2741+ uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
2742+
2743+ /* And we are done processing options. */
2744+ break;
2745+ } else {
2746+ /* All other options have a length field, so that we easily
2747+ can skip past them. */
2748+ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
2749+ /* If the length field is zero, the options are malformed
2750+ and we don't process them further. */
2751+ break;
2752+ }
2753+ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
2754+ }
2755+ }
2756+ }
2757+ uip_connr->tcpstateflags = ESTABLISHED;
2758+ uip_connr->rcv_nxt[0] = BUF->seqno[0];
2759+ uip_connr->rcv_nxt[1] = BUF->seqno[1];
2760+ uip_connr->rcv_nxt[2] = BUF->seqno[2];
2761+ uip_connr->rcv_nxt[3] = BUF->seqno[3];
2762+ uip_add_rcv_nxt(1);
2763+ uip_flags = UIP_CONNECTED | UIP_NEWDATA;
2764+ uip_connr->len = 0;
2765+ uip_len = 0;
2766+ uip_slen = 0;
2767+ UIP_APPCALL();
2768+ goto appsend;
2769+ }
2770+ goto reset;
2771+#endif /* UIP_ACTIVE_OPEN */
2772+
2773+ case ESTABLISHED:
2774+ /* In the ESTABLISHED state, we call upon the application to feed
2775+ data into the uip_buf. If the UIP_ACKDATA flag is set, the
2776+ application should put new data into the buffer, otherwise we are
2777+ retransmitting an old segment, and the application should put that
2778+ data into the buffer.
2779+
2780+ If the incoming packet is a FIN, we should close the connection on
2781+ this side as well, and we send out a FIN and enter the LAST_ACK
2782+ state. We require that there is no outstanding data; otherwise the
2783+ sequence numbers will be screwed up. */
2784+
2785+ if(BUF->flags & TCP_FIN) {
2786+ if(uip_outstanding(uip_connr)) {
2787+ goto drop;
2788+ }
2789+ uip_add_rcv_nxt(1 + uip_len);
2790+ uip_flags = UIP_CLOSE;
2791+ if(uip_len > 0) {
2792+ uip_flags |= UIP_NEWDATA;
2793+ }
2794+ UIP_APPCALL();
2795+ uip_connr->len = 1;
2796+ uip_connr->tcpstateflags = LAST_ACK;
2797+ uip_connr->nrtx = 0;
2798+ tcp_send_finack:
2799+ BUF->flags = TCP_FIN | TCP_ACK;
2800+ goto tcp_send_nodata;
2801+ }
2802+
2803+ /* Check the URG flag. If this is set, the segment carries urgent
2804+ data that we must pass to the application. */
2805+ if(BUF->flags & TCP_URG) {
2806+#if UIP_URGDATA > 0
2807+ uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
2808+ if(uip_urglen > uip_len) {
2809+ /* There is more urgent data in the next segment to come. */
2810+ uip_urglen = uip_len;
2811+ }
2812+ uip_add_rcv_nxt(uip_urglen);
2813+ uip_len -= uip_urglen;
2814+ uip_urgdata = uip_appdata;
2815+ uip_appdata += uip_urglen;
2816+ } else {
2817+ uip_urglen = 0;
2818+#endif /* UIP_URGDATA > 0 */
2819+ uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
2820+ uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
2821+ }
2822+
2823+
2824+ /* If uip_len > 0 we have TCP data in the packet, and we flag this
2825+ by setting the UIP_NEWDATA flag and update the sequence number
2826+ we acknowledge. If the application has stopped the dataflow
2827+ using uip_stop(), we must not accept any data packets from the
2828+ remote host. */
2829+ if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
2830+ uip_flags |= UIP_NEWDATA;
2831+ uip_add_rcv_nxt(uip_len);
2832+ }
2833+
2834+ /* Check if the available buffer space advertised by the other end
2835+ is smaller than the initial MSS for this connection. If so, we
2836+ set the current MSS to the window size to ensure that the
2837+ application does not send more data than the other end can
2838+ handle.
2839+
2840+ If the remote host advertises a zero window, we set the MSS to
2841+ the initial MSS so that the application will send an entire MSS
2842+ of data. This data will not be acknowledged by the receiver,
2843+ and the application will retransmit it. This is called the
2844+ "persistent timer" and uses the retransmission mechanim.
2845+ */
2846+ tmp16 = ((unsigned short int)BUF->wnd[0] << 8) + (unsigned short int)BUF->wnd[1];
2847+ if(tmp16 > uip_connr->initialmss ||
2848+ tmp16 == 0) {
2849+ tmp16 = uip_connr->initialmss;
2850+ }
2851+ uip_connr->mss = tmp16;
2852+
2853+ /* If this packet constitutes an ACK for outstanding data (flagged
2854+ by the UIP_ACKDATA flag, we should call the application since it
2855+ might want to send more data. If the incoming packet had data
2856+ from the peer (as flagged by the UIP_NEWDATA flag), the
2857+ application must also be notified.
2858+
2859+ When the application is called, the global variable uip_len
2860+ contains the length of the incoming data. The application can
2861+ access the incoming data through the global pointer
2862+ uip_appdata, which usually points 40 bytes into the uip_buf
2863+ array.
2864+
2865+ If the application wishes to send any data, this data should be
2866+ put into the uip_appdata and the length of the data should be
2867+ put into uip_len. If the application don't have any data to
2868+ send, uip_len must be set to 0. */
2869+ if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
2870+ uip_slen = 0;
2871+ UIP_APPCALL();
2872+
2873+ appsend:
2874+
2875+ if(uip_flags & UIP_ABORT) {
2876+ uip_slen = 0;
2877+ uip_connr->tcpstateflags = CLOSED;
2878+ BUF->flags = TCP_RST | TCP_ACK;
2879+ goto tcp_send_nodata;
2880+ }
2881+
2882+ if(uip_flags & UIP_CLOSE) {
2883+ uip_slen = 0;
2884+ uip_connr->len = 1;
2885+ uip_connr->tcpstateflags = FIN_WAIT_1;
2886+ uip_connr->nrtx = 0;
2887+ BUF->flags = TCP_FIN | TCP_ACK;
2888+ goto tcp_send_nodata;
2889+ }
2890+
2891+ /* If uip_slen > 0, the application has data to be sent. */
2892+ if(uip_slen > 0) {
2893+
2894+ /* If the connection has acknowledged data, the contents of
2895+ the ->len variable should be discarded. */
2896+ if((uip_flags & UIP_ACKDATA) != 0) {
2897+ uip_connr->len = 0;
2898+ }
2899+
2900+ /* If the ->len variable is non-zero the connection has
2901+ already data in transit and cannot send anymore right
2902+ now. */
2903+ if(uip_connr->len == 0) {
2904+
2905+ /* The application cannot send more than what is allowed by
2906+ the mss (the minumum of the MSS and the available
2907+ window). */
2908+ if(uip_slen > uip_connr->mss) {
2909+ uip_slen = uip_connr->mss;
2910+ }
2911+
2912+ /* Remember how much data we send out now so that we know
2913+ when everything has been acknowledged. */
2914+ uip_connr->len = uip_slen;
2915+ } else {
2916+
2917+ /* If the application already had unacknowledged data, we
2918+ make sure that the application does not send (i.e.,
2919+ retransmit) out more than it previously sent out. */
2920+ uip_slen = uip_connr->len;
2921+ }
2922+ } else {
2923+ uip_connr->len = 0;
2924+ }
2925+ uip_connr->nrtx = 0;
2926+ apprexmit:
2927+ uip_appdata = uip_sappdata;
2928+
2929+ /* If the application has data to be sent, or if the incoming
2930+ packet had new data in it, we must send out a packet. */
2931+ if(uip_slen > 0 && uip_connr->len > 0) {
2932+ /* Add the length of the IP and TCP headers. */
2933+ uip_len = uip_connr->len + UIP_TCPIP_HLEN;
2934+ /* We always set the ACK flag in response packets. */
2935+ BUF->flags = TCP_ACK | TCP_PSH;
2936+ /* Send the packet. */
2937+ goto tcp_send_noopts;
2938+ }
2939+ /* If there is no data to send, just send out a pure ACK if
2940+ there is newdata. */
2941+ if(uip_flags & UIP_NEWDATA) {
2942+ uip_len = UIP_TCPIP_HLEN;
2943+ BUF->flags = TCP_ACK;
2944+ goto tcp_send_noopts;
2945+ }
2946+ }
2947+ goto drop;
2948+ case LAST_ACK:
2949+ /* We can close this connection if the peer has acknowledged our
2950+ FIN. This is indicated by the UIP_ACKDATA flag. */
2951+ if(uip_flags & UIP_ACKDATA) {
2952+ uip_connr->tcpstateflags = CLOSED;
2953+ uip_flags = UIP_CLOSE;
2954+ UIP_APPCALL();
2955+ }
2956+ break;
2957+
2958+ case FIN_WAIT_1:
2959+ /* The application has closed the connection, but the remote host
2960+ hasn't closed its end yet. Thus we do nothing but wait for a
2961+ FIN from the other side. */
2962+ if(uip_len > 0) {
2963+ uip_add_rcv_nxt(uip_len);
2964+ }
2965+ if(BUF->flags & TCP_FIN) {
2966+ if(uip_flags & UIP_ACKDATA) {
2967+ uip_connr->tcpstateflags = TIME_WAIT;
2968+ uip_connr->timer = 0;
2969+ uip_connr->len = 0;
2970+ } else {
2971+ uip_connr->tcpstateflags = CLOSING;
2972+ }
2973+ uip_add_rcv_nxt(1);
2974+ uip_flags = UIP_CLOSE;
2975+ UIP_APPCALL();
2976+ goto tcp_send_ack;
2977+ } else if(uip_flags & UIP_ACKDATA) {
2978+ uip_connr->tcpstateflags = FIN_WAIT_2;
2979+ uip_connr->len = 0;
2980+ goto drop;
2981+ }
2982+ if(uip_len > 0) {
2983+ goto tcp_send_ack;
2984+ }
2985+ goto drop;
2986+
2987+ case FIN_WAIT_2:
2988+ if(uip_len > 0) {
2989+ uip_add_rcv_nxt(uip_len);
2990+ }
2991+ if(BUF->flags & TCP_FIN) {
2992+ uip_connr->tcpstateflags = TIME_WAIT;
2993+ uip_connr->timer = 0;
2994+ uip_add_rcv_nxt(1);
2995+ uip_flags = UIP_CLOSE;
2996+ UIP_APPCALL();
2997+ goto tcp_send_ack;
2998+ }
2999+ if(uip_len > 0) {
3000+ goto tcp_send_ack;
3001+ }
3002+ goto drop;
3003+
3004+ case TIME_WAIT:
3005+ goto tcp_send_ack;
3006+
3007+ case CLOSING:
3008+ if(uip_flags & UIP_ACKDATA) {
3009+ uip_connr->tcpstateflags = TIME_WAIT;
3010+ uip_connr->timer = 0;
3011+ }
3012+ }
3013+ goto drop;
3014+
3015+
3016+ /* We jump here when we are ready to send the packet, and just want
3017+ to set the appropriate TCP sequence numbers in the TCP header. */
3018+ tcp_send_ack:
3019+ BUF->flags = TCP_ACK;
3020+ tcp_send_nodata:
3021+ uip_len = 40;
3022+ tcp_send_noopts:
3023+ BUF->tcpoffset = 5 << 4;
3024+ tcp_send:
3025+ /* We're done with the input processing. We are now ready to send a
3026+ reply. Our job is to fill in all the fields of the TCP and IP
3027+ headers before calculating the checksum and finally send the
3028+ packet. */
3029+ BUF->ackno[0] = uip_connr->rcv_nxt[0];
3030+ BUF->ackno[1] = uip_connr->rcv_nxt[1];
3031+ BUF->ackno[2] = uip_connr->rcv_nxt[2];
3032+ BUF->ackno[3] = uip_connr->rcv_nxt[3];
3033+
3034+ BUF->seqno[0] = uip_connr->snd_nxt[0];
3035+ BUF->seqno[1] = uip_connr->snd_nxt[1];
3036+ BUF->seqno[2] = uip_connr->snd_nxt[2];
3037+ BUF->seqno[3] = uip_connr->snd_nxt[3];
3038+
3039+ BUF->proto = UIP_PROTO_TCP;
3040+
3041+ BUF->srcport = uip_connr->lport;
3042+ BUF->destport = uip_connr->rport;
3043+
3044+ BUF->srcipaddr[0] = uip_hostaddr[0];
3045+ BUF->srcipaddr[1] = uip_hostaddr[1];
3046+ BUF->destipaddr[0] = uip_connr->ripaddr[0];
3047+ BUF->destipaddr[1] = uip_connr->ripaddr[1];
3048+
3049+
3050+ if(uip_connr->tcpstateflags & UIP_STOPPED) {
3051+ /* If the connection has issued uip_stop(), we advertise a zero
3052+ window so that the remote host will stop sending data. */
3053+ BUF->wnd[0] = BUF->wnd[1] = 0;
3054+ } else {
3055+ BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
3056+ BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
3057+ }
3058+
3059+ tcp_send_noconn:
3060+
3061+ BUF->len[0] = (uip_len >> 8);
3062+ BUF->len[1] = (uip_len & 0xff);
3063+
3064+ /* Calculate TCP checksum. */
3065+ BUF->tcpchksum = 0;
3066+ BUF->tcpchksum = ~(uip_tcpchksum());
3067+
3068+ //ip_send_nolen:
3069+
3070+ BUF->vhl = 0x45;
3071+ BUF->tos = 0;
3072+ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
3073+ BUF->ttl = UIP_TTL;
3074+ ++ipid;
3075+ BUF->ipid[0] = ipid >> 8;
3076+ BUF->ipid[1] = ipid & 0xff;
3077+
3078+ /* Calculate IP checksum. */
3079+ BUF->ipchksum = 0;
3080+ BUF->ipchksum = ~(uip_ipchksum());
3081+
3082+ UIP_STAT(++uip_stat.tcp.sent);
3083+ send:
3084+ UIP_STAT(++uip_stat.ip.sent);
3085+ /* Return and let the caller do the actual transmission. */
3086+ return;
3087+ drop:
3088+ uip_len = 0;
3089+ return;
3090+}
3091+/*-----------------------------------------------------------------------------------*/
3092+/*unsigned short int
3093+htons(unsigned short int val)
3094+{
3095+ return HTONS(val);
3096+}*/
3097+/*-----------------------------------------------------------------------------------*/
3098+/** @} */
3099--- /dev/null
3100+++ b/net/uip-0.9/uip.h
3101@@ -0,0 +1,1066 @@
3102+/**
3103+ * \addtogroup uip
3104+ * @{
3105+ */
3106+
3107+/**
3108+ * \file
3109+ * Header file for the uIP TCP/IP stack.
3110+ * \author Adam Dunkels <adam@dunkels.com>
3111+ *
3112+ * The uIP TCP/IP stack header file contains definitions for a number
3113+ * of C macros that are used by uIP programs as well as internal uIP
3114+ * structures, TCP/IP header structures and function declarations.
3115+ *
3116+ */
3117+
3118+
3119+/*
3120+ * Copyright (c) 2001-2003, Adam Dunkels.
3121+ * All rights reserved.
3122+ *
3123+ * Redistribution and use in source and binary forms, with or without
3124+ * modification, are permitted provided that the following conditions
3125+ * are met:
3126+ * 1. Redistributions of source code must retain the above copyright
3127+ * notice, this list of conditions and the following disclaimer.
3128+ * 2. Redistributions in binary form must reproduce the above copyright
3129+ * notice, this list of conditions and the following disclaimer in the
3130+ * documentation and/or other materials provided with the distribution.
3131+ * 3. The name of the author may not be used to endorse or promote
3132+ * products derived from this software without specific prior
3133+ * written permission.
3134+ *
3135+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
3136+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3137+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3138+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
3139+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3140+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
3141+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3142+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3143+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3144+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3145+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3146+ *
3147+ * This file is part of the uIP TCP/IP stack.
3148+ *
3149+ * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $
3150+ *
3151+ */
3152+
3153+#ifndef __UIP_H__
3154+#define __UIP_H__
3155+#include <linux/types.h>
3156+#include <linux/string.h>
3157+#include <linux/ctype.h>
3158+#include <malloc.h>
3159+#include <common.h>
3160+
3161+
3162+#include "uipopt.h"
3163+
3164+/*-----------------------------------------------------------------------------------*/
3165+/* First, the functions that should be called from the
3166+ * system. Initialization, the periodic timer and incoming packets are
3167+ * handled by the following three functions.
3168+ */
3169+
3170+/**
3171+ * \defgroup uipconffunc uIP configuration functions
3172+ * @{
3173+ *
3174+ * The uIP configuration functions are used for setting run-time
3175+ * parameters in uIP such as IP addresses.
3176+ */
3177+
3178+/**
3179+ * Set the IP address of this host.
3180+ *
3181+ * The IP address is represented as a 4-byte array where the first
3182+ * octet of the IP address is put in the first member of the 4-byte
3183+ * array.
3184+ *
3185+ * \param addr A pointer to a 4-byte representation of the IP address.
3186+ *
3187+ * \hideinitializer
3188+ */
3189+#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \
3190+ uip_hostaddr[1] = addr[1]; } while(0)
3191+
3192+/**
3193+ * Get the IP address of this host.
3194+ *
3195+ * The IP address is represented as a 4-byte array where the first
3196+ * octet of the IP address is put in the first member of the 4-byte
3197+ * array.
3198+ *
3199+ * \param addr A pointer to a 4-byte array that will be filled in with
3200+ * the currently configured IP address.
3201+ *
3202+ * \hideinitializer
3203+ */
3204+#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \
3205+ addr[1] = uip_hostaddr[1]; } while(0)
3206+
3207+/** @} */
3208+
3209+/**
3210+ * \defgroup uipinit uIP initialization functions
3211+ * @{
3212+ *
3213+ * The uIP initialization functions are used for booting uIP.
3214+ */
3215+
3216+/**
3217+ * uIP initialization function.
3218+ *
3219+ * This function should be called at boot up to initilize the uIP
3220+ * TCP/IP stack.
3221+ */
3222+void uip_init(void);
3223+
3224+/** @} */
3225+
3226+/**
3227+ * \defgroup uipdevfunc uIP device driver functions
3228+ * @{
3229+ *
3230+ * These functions are used by a network device driver for interacting
3231+ * with uIP.
3232+ */
3233+
3234+/**
3235+ * Process an incoming packet.
3236+ *
3237+ * This function should be called when the device driver has received
3238+ * a packet from the network. The packet from the device driver must
3239+ * be present in the uip_buf buffer, and the length of the packet
3240+ * should be placed in the uip_len variable.
3241+ *
3242+ * When the function returns, there may be an outbound packet placed
3243+ * in the uip_buf packet buffer. If so, the uip_len variable is set to
3244+ * the length of the packet. If no packet is to be sent out, the
3245+ * uip_len variable is set to 0.
3246+ *
3247+ * The usual way of calling the function is presented by the source
3248+ * code below.
3249+ \code
3250+ uip_len = devicedriver_poll();
3251+ if(uip_len > 0) {
3252+ uip_input();
3253+ if(uip_len > 0) {
3254+ devicedriver_send();
3255+ }
3256+ }
3257+ \endcode
3258+ *
3259+ * \note If you are writing a uIP device driver that needs ARP
3260+ * (Address Resolution Protocol), e.g., when running uIP over
3261+ * Ethernet, you will need to call the uIP ARP code before calling
3262+ * this function:
3263+ \code
3264+ #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
3265+ uip_len = ethernet_devicedrver_poll();
3266+ if(uip_len > 0) {
3267+ if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
3268+ uip_arp_ipin();
3269+ uip_input();
3270+ if(uip_len > 0) {
3271+ uip_arp_out();
3272+ ethernet_devicedriver_send();
3273+ }
3274+ } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
3275+ uip_arp_arpin();
3276+ if(uip_len > 0) {
3277+ ethernet_devicedriver_send();
3278+ }
3279+ }
3280+ \endcode
3281+ *
3282+ * \hideinitializer
3283+ */
3284+#define uip_input() uip_process(UIP_DATA)
3285+
3286+/**
3287+ * Periodic processing for a connection identified by its number.
3288+ *
3289+ * This function does the necessary periodic processing (timers,
3290+ * polling) for a uIP TCP conneciton, and should be called when the
3291+ * periodic uIP timer goes off. It should be called for every
3292+ * connection, regardless of whether they are open of closed.
3293+ *
3294+ * When the function returns, it may have an outbound packet waiting
3295+ * for service in the uIP packet buffer, and if so the uip_len
3296+ * variable is set to a value larger than zero. The device driver
3297+ * should be called to send out the packet.
3298+ *
3299+ * The ususal way of calling the function is through a for() loop like
3300+ * this:
3301+ \code
3302+ for(i = 0; i < UIP_CONNS; ++i) {
3303+ uip_periodic(i);
3304+ if(uip_len > 0) {
3305+ devicedriver_send();
3306+ }
3307+ }
3308+ \endcode
3309+ *
3310+ * \note If you are writing a uIP device driver that needs ARP
3311+ * (Address Resolution Protocol), e.g., when running uIP over
3312+ * Ethernet, you will need to call the uip_arp_out() function before
3313+ * calling the device driver:
3314+ \code
3315+ for(i = 0; i < UIP_CONNS; ++i) {
3316+ uip_periodic(i);
3317+ if(uip_len > 0) {
3318+ uip_arp_out();
3319+ ethernet_devicedriver_send();
3320+ }
3321+ }
3322+ \endcode
3323+ *
3324+ * \param conn The number of the connection which is to be periodically polled.
3325+ *
3326+ * \hideinitializer
3327+ */
3328+#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
3329+ uip_process(UIP_TIMER); } while (0)
3330+
3331+/**
3332+ * Periodic processing for a connection identified by a pointer to its structure.
3333+ *
3334+ * Same as uip_periodic() but takes a pointer to the actual uip_conn
3335+ * struct instead of an integer as its argument. This function can be
3336+ * used to force periodic processing of a specific connection.
3337+ *
3338+ * \param conn A pointer to the uip_conn struct for the connection to
3339+ * be processed.
3340+ *
3341+ * \hideinitializer
3342+ */
3343+#define uip_periodic_conn(conn) do { uip_conn = conn; \
3344+ uip_process(UIP_TIMER); } while (0)
3345+
3346+#if UIP_UDP
3347+/**
3348+ * Periodic processing for a UDP connection identified by its number.
3349+ *
3350+ * This function is essentially the same as uip_prerioic(), but for
3351+ * UDP connections. It is called in a similar fashion as the
3352+ * uip_periodic() function:
3353+ \code
3354+ for(i = 0; i < UIP_UDP_CONNS; i++) {
3355+ uip_udp_periodic(i);
3356+ if(uip_len > 0) {
3357+ devicedriver_send();
3358+ }
3359+ }
3360+ \endcode
3361+ *
3362+ * \note As for the uip_periodic() function, special care has to be
3363+ * taken when using uIP together with ARP and Ethernet:
3364+ \code
3365+ for(i = 0; i < UIP_UDP_CONNS; i++) {
3366+ uip_udp_periodic(i);
3367+ if(uip_len > 0) {
3368+ uip_arp_out();
3369+ ethernet_devicedriver_send();
3370+ }
3371+ }
3372+ \endcode
3373+ *
3374+ * \param conn The number of the UDP connection to be processed.
3375+ *
3376+ * \hideinitializer
3377+ */
3378+#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
3379+ uip_process(UIP_UDP_TIMER); } while (0)
3380+
3381+/**
3382+ * Periodic processing for a UDP connection identified by a pointer to
3383+ * its structure.
3384+ *
3385+ * Same as uip_udp_periodic() but takes a pointer to the actual
3386+ * uip_conn struct instead of an integer as its argument. This
3387+ * function can be used to force periodic processing of a specific
3388+ * connection.
3389+ *
3390+ * \param conn A pointer to the uip_udp_conn struct for the connection
3391+ * to be processed.
3392+ *
3393+ * \hideinitializer
3394+ */
3395+#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
3396+ uip_process(UIP_UDP_TIMER); } while (0)
3397+
3398+
3399+#endif /* UIP_UDP */
3400+
3401+/**
3402+ * The uIP packet buffer.
3403+ *
3404+ * The uip_buf array is used to hold incoming and outgoing
3405+ * packets. The device driver should place incoming data into this
3406+ * buffer. When sending data, the device driver should read the link
3407+ * level headers and the TCP/IP headers from this buffer. The size of
3408+ * the link level headers is configured by the UIP_LLH_LEN define.
3409+ *
3410+ * \note The application data need not be placed in this buffer, so
3411+ * the device driver must read it from the place pointed to by the
3412+ * uip_appdata pointer as illustrated by the following example:
3413+ \code
3414+ void
3415+ devicedriver_send(void)
3416+ {
3417+ hwsend(&uip_buf[0], UIP_LLH_LEN);
3418+ hwsend(&uip_buf[UIP_LLH_LEN], 40);
3419+ hwsend(uip_appdata, uip_len - 40 - UIP_LLH_LEN);
3420+ }
3421+ \endcode
3422+ */
3423+extern u8_t uip_buf[UIP_BUFSIZE+2];
3424+
3425+/** @} */
3426+
3427+/*-----------------------------------------------------------------------------------*/
3428+/* Functions that are used by the uIP application program. Opening and
3429+ * closing connections, sending and receiving data, etc. is all
3430+ * handled by the functions below.
3431+*/
3432+/**
3433+ * \defgroup uipappfunc uIP application functions
3434+ * @{
3435+ *
3436+ * Functions used by an application running of top of uIP.
3437+ */
3438+
3439+/**
3440+ * Start listening to the specified port.
3441+ *
3442+ * \note Since this function expects the port number in network byte
3443+ * order, a conversion using HTONS() or htons() is necessary.
3444+ *
3445+ \code
3446+ uip_listen(HTONS(80));
3447+ \endcode
3448+ *
3449+ * \param port A 16-bit port number in network byte order.
3450+ */
3451+void uip_listen(u16_t port);
3452+
3453+/**
3454+ * Stop listening to the specified port.
3455+ *
3456+ * \note Since this function expects the port number in network byte
3457+ * order, a conversion using HTONS() or htons() is necessary.
3458+ *
3459+ \code
3460+ uip_unlisten(HTONS(80));
3461+ \endcode
3462+ *
3463+ * \param port A 16-bit port number in network byte order.
3464+ */
3465+void uip_unlisten(u16_t port);
3466+
3467+/**
3468+ * Connect to a remote host using TCP.
3469+ *
3470+ * This function is used to start a new connection to the specified
3471+ * port on the specied host. It allocates a new connection identifier,
3472+ * sets the connection to the SYN_SENT state and sets the
3473+ * retransmission timer to 0. This will cause a TCP SYN segment to be
3474+ * sent out the next time this connection is periodically processed,
3475+ * which usually is done within 0.5 seconds after the call to
3476+ * uip_connect().
3477+ *
3478+ * \note This function is avaliable only if support for active open
3479+ * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
3480+ *
3481+ * \note Since this function requires the port number to be in network
3482+ * byte order, a convertion using HTONS() or htons() is necessary.
3483+ *
3484+ \code
3485+ u16_t ipaddr[2];
3486+
3487+ uip_ipaddr(ipaddr, 192,168,1,2);
3488+ uip_connect(ipaddr, HTONS(80));
3489+ \endcode
3490+ *
3491+ * \param ripaddr A pointer to a 4-byte array representing the IP
3492+ * address of the remote hot.
3493+ *
3494+ * \param port A 16-bit port number in network byte order.
3495+ *
3496+ * \return A pointer to the uIP connection identifier for the new connection,
3497+ * or NULL if no connection could be allocated.
3498+ *
3499+ */
3500+struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
3501+
3502+
3503+
3504+/**
3505+ * \internal
3506+ *
3507+ * Check if a connection has outstanding (i.e., unacknowledged) data.
3508+ *
3509+ * \param conn A pointer to the uip_conn structure for the connection.
3510+ *
3511+ * \hideinitializer
3512+ */
3513+#define uip_outstanding(conn) ((conn)->len)
3514+
3515+/**
3516+ * Send data on the current connection.
3517+ *
3518+ * This function is used to send out a single segment of TCP
3519+ * data. Only applications that have been invoked by uIP for event
3520+ * processing can send data.
3521+ *
3522+ * The amount of data that actually is sent out after a call to this
3523+ * funcion is determined by the maximum amount of data TCP allows. uIP
3524+ * will automatically crop the data so that only the appropriate
3525+ * amount of data is sent. The function uip_mss() can be used to query
3526+ * uIP for the amount of data that actually will be sent.
3527+ *
3528+ * \note This function does not guarantee that the sent data will
3529+ * arrive at the destination. If the data is lost in the network, the
3530+ * application will be invoked with the uip_rexmit() event being
3531+ * set. The application will then have to resend the data using this
3532+ * function.
3533+ *
3534+ * \param data A pointer to the data which is to be sent.
3535+ *
3536+ * \param len The maximum amount of data bytes to be sent.
3537+ *
3538+ * \hideinitializer
3539+ */
3540+#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0)
3541+
3542+/**
3543+ * The length of any incoming data that is currently avaliable (if avaliable)
3544+ * in the uip_appdata buffer.
3545+ *
3546+ * The test function uip_data() must first be used to check if there
3547+ * is any data available at all.
3548+ *
3549+ * \hideinitializer
3550+ */
3551+#define uip_datalen() uip_len
3552+
3553+/**
3554+ * The length of any out-of-band data (urgent data) that has arrived
3555+ * on the connection.
3556+ *
3557+ * \note The configuration parameter UIP_URGDATA must be set for this
3558+ * function to be enabled.
3559+ *
3560+ * \hideinitializer
3561+ */
3562+#define uip_urgdatalen() uip_urglen
3563+
3564+/**
3565+ * Close the current connection.
3566+ *
3567+ * This function will close the current connection in a nice way.
3568+ *
3569+ * \hideinitializer
3570+ */
3571+#define uip_close() (uip_flags = UIP_CLOSE)
3572+
3573+/**
3574+ * Abort the current connection.
3575+ *
3576+ * This function will abort (reset) the current connection, and is
3577+ * usually used when an error has occured that prevents using the
3578+ * uip_close() function.
3579+ *
3580+ * \hideinitializer
3581+ */
3582+#define uip_abort() (uip_flags = UIP_ABORT)
3583+
3584+/**
3585+ * Tell the sending host to stop sending data.
3586+ *
3587+ * This function will close our receiver's window so that we stop
3588+ * receiving data for the current connection.
3589+ *
3590+ * \hideinitializer
3591+ */
3592+#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
3593+
3594+/**
3595+ * Find out if the current connection has been previously stopped with
3596+ * uip_stop().
3597+ *
3598+ * \hideinitializer
3599+ */
3600+#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
3601+
3602+/**
3603+ * Restart the current connection, if is has previously been stopped
3604+ * with uip_stop().
3605+ *
3606+ * This function will open the receiver's window again so that we
3607+ * start receiving data for the current connection.
3608+ *
3609+ * \hideinitializer
3610+ */
3611+#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
3612+ uip_conn->tcpstateflags &= ~UIP_STOPPED; \
3613+ } while(0)
3614+
3615+
3616+/* uIP tests that can be made to determine in what state the current
3617+ connection is, and what the application function should do. */
3618+
3619+/**
3620+ * Is new incoming data available?
3621+ *
3622+ * Will reduce to non-zero if there is new data for the application
3623+ * present at the uip_appdata pointer. The size of the data is
3624+ * avaliable through the uip_len variable.
3625+ *
3626+ * \hideinitializer
3627+ */
3628+#define uip_newdata() (uip_flags & UIP_NEWDATA)
3629+
3630+/**
3631+ * Has previously sent data been acknowledged?
3632+ *
3633+ * Will reduce to non-zero if the previously sent data has been
3634+ * acknowledged by the remote host. This means that the application
3635+ * can send new data.
3636+ *
3637+ * \hideinitializer
3638+ */
3639+#define uip_acked() (uip_flags & UIP_ACKDATA)
3640+
3641+/**
3642+ * Has the connection just been connected?
3643+ *
3644+ * Reduces to non-zero if the current connection has been connected to
3645+ * a remote host. This will happen both if the connection has been
3646+ * actively opened (with uip_connect()) or passively opened (with
3647+ * uip_listen()).
3648+ *
3649+ * \hideinitializer
3650+ */
3651+#define uip_connected() (uip_flags & UIP_CONNECTED)
3652+
3653+/**
3654+ * Has the connection been closed by the other end?
3655+ *
3656+ * Is non-zero if the connection has been closed by the remote
3657+ * host. The application may then do the necessary clean-ups.
3658+ *
3659+ * \hideinitializer
3660+ */
3661+#define uip_closed() (uip_flags & UIP_CLOSE)
3662+
3663+/**
3664+ * Has the connection been aborted by the other end?
3665+ *
3666+ * Non-zero if the current connection has been aborted (reset) by the
3667+ * remote host.
3668+ *
3669+ * \hideinitializer
3670+ */
3671+#define uip_aborted() (uip_flags & UIP_ABORT)
3672+
3673+/**
3674+ * Has the connection timed out?
3675+ *
3676+ * Non-zero if the current connection has been aborted due to too many
3677+ * retransmissions.
3678+ *
3679+ * \hideinitializer
3680+ */
3681+#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
3682+
3683+/**
3684+ * Do we need to retransmit previously data?
3685+ *
3686+ * Reduces to non-zero if the previously sent data has been lost in
3687+ * the network, and the application should retransmit it. The
3688+ * application should send the exact same data as it did the last
3689+ * time, using the uip_send() function.
3690+ *
3691+ * \hideinitializer
3692+ */
3693+#define uip_rexmit() (uip_flags & UIP_REXMIT)
3694+
3695+/**
3696+ * Is the connection being polled by uIP?
3697+ *
3698+ * Is non-zero if the reason the application is invoked is that the
3699+ * current connection has been idle for a while and should be
3700+ * polled.
3701+ *
3702+ * The polling event can be used for sending data without having to
3703+ * wait for the remote host to send data.
3704+ *
3705+ * \hideinitializer
3706+ */
3707+#define uip_poll() (uip_flags & UIP_POLL)
3708+
3709+/**
3710+ * Get the initial maxium segment size (MSS) of the current
3711+ * connection.
3712+ *
3713+ * \hideinitializer
3714+ */
3715+#define uip_initialmss() (uip_conn->initialmss)
3716+
3717+/**
3718+ * Get the current maxium segment size that can be sent on the current
3719+ * connection.
3720+ *
3721+ * The current maxiumum segment size that can be sent on the
3722+ * connection is computed from the receiver's window and the MSS of
3723+ * the connection (which also is available by calling
3724+ * uip_initialmss()).
3725+ *
3726+ * \hideinitializer
3727+ */
3728+#define uip_mss() (uip_conn->mss)
3729+
3730+/**
3731+ * Set up a new UDP connection.
3732+ *
3733+ * \param ripaddr A pointer to a 4-byte structure representing the IP
3734+ * address of the remote host.
3735+ *
3736+ * \param rport The remote port number in network byte order.
3737+ *
3738+ * \return The uip_udp_conn structure for the new connection or NULL
3739+ * if no connection could be allocated.
3740+ */
3741+struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
3742+
3743+/**
3744+ * Removed a UDP connection.
3745+ *
3746+ * \param conn A pointer to the uip_udp_conn structure for the connection.
3747+ *
3748+ * \hideinitializer
3749+ */
3750+#define uip_udp_remove(conn) (conn)->lport = 0
3751+
3752+/**
3753+ * Send a UDP datagram of length len on the current connection.
3754+ *
3755+ * This function can only be called in response to a UDP event (poll
3756+ * or newdata). The data must be present in the uip_buf buffer, at the
3757+ * place pointed to by the uip_appdata pointer.
3758+ *
3759+ * \param len The length of the data in the uip_buf buffer.
3760+ *
3761+ * \hideinitializer
3762+ */
3763+#define uip_udp_send(len) uip_slen = (len)
3764+
3765+/** @} */
3766+
3767+/* uIP convenience and converting functions. */
3768+
3769+/**
3770+ * \defgroup uipconvfunc uIP conversion functions
3771+ * @{
3772+ *
3773+ * These functions can be used for converting between different data
3774+ * formats used by uIP.
3775+ */
3776+
3777+/**
3778+ * Pack an IP address into a 4-byte array which is used by uIP to
3779+ * represent IP addresses.
3780+ *
3781+ * Example:
3782+ \code
3783+ u16_t ipaddr[2];
3784+
3785+ uip_ipaddr(&ipaddr, 192,168,1,2);
3786+ \endcode
3787+ *
3788+ * \param addr A pointer to a 4-byte array that will be filled in with
3789+ * the IP addres.
3790+ * \param addr0 The first octet of the IP address.
3791+ * \param addr1 The second octet of the IP address.
3792+ * \param addr2 The third octet of the IP address.
3793+ * \param addr3 The forth octet of the IP address.
3794+ *
3795+ * \hideinitializer
3796+ */
3797+#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
3798+ (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \
3799+ (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \
3800+ } while(0)
3801+
3802+/**
3803+ * Convert 16-bit quantity from host byte order to network byte order.
3804+ *
3805+ * This macro is primarily used for converting constants from host
3806+ * byte order to network byte order. For converting variables to
3807+ * network byte order, use the htons() function instead.
3808+ *
3809+ * \hideinitializer
3810+ */
3811+#ifndef HTONS
3812+# if BYTE_ORDER == BIG_ENDIAN
3813+# define HTONS(n) (n)
3814+# else /* BYTE_ORDER == BIG_ENDIAN */
3815+# define HTONS(n) ((((u16_t)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))
3816+# endif /* BYTE_ORDER == BIG_ENDIAN */
3817+#endif /* HTONS */
3818+
3819+/**
3820+ * Convert 16-bit quantity from host byte order to network byte order.
3821+ *
3822+ * This function is primarily used for converting variables from host
3823+ * byte order to network byte order. For converting constants to
3824+ * network byte order, use the HTONS() macro instead.
3825+ */
3826+#ifndef htons
3827+u16_t htons(u16_t val);
3828+#endif /* htons */
3829+
3830+/** @} */
3831+
3832+/**
3833+ * Pointer to the application data in the packet buffer.
3834+ *
3835+ * This pointer points to the application data when the application is
3836+ * called. If the application wishes to send data, the application may
3837+ * use this space to write the data into before calling uip_send().
3838+ */
3839+extern volatile u8_t *uip_appdata;
3840+extern volatile u8_t *uip_sappdata;
3841+
3842+#if UIP_URGDATA > 0
3843+/* u8_t *uip_urgdata:
3844+ *
3845+ * This pointer points to any urgent data that has been received. Only
3846+ * present if compiled with support for urgent data (UIP_URGDATA).
3847+ */
3848+extern volatile u8_t *uip_urgdata;
3849+#endif /* UIP_URGDATA > 0 */
3850+
3851+
3852+/* u[8|16]_t uip_len:
3853+ *
3854+ * When the application is called, uip_len contains the length of any
3855+ * new data that has been received from the remote host. The
3856+ * application should set this variable to the size of any data that
3857+ * the application wishes to send. When the network device driver
3858+ * output function is called, uip_len should contain the length of the
3859+ * outgoing packet.
3860+ */
3861+extern volatile u16_t uip_len, uip_slen;
3862+
3863+#if UIP_URGDATA > 0
3864+extern volatile u8_t uip_urglen, uip_surglen;
3865+#endif /* UIP_URGDATA > 0 */
3866+
3867+
3868+/**
3869+ * Representation of a uIP TCP connection.
3870+ *
3871+ * The uip_conn structure is used for identifying a connection. All
3872+ * but one field in the structure are to be considered read-only by an
3873+ * application. The only exception is the appstate field whos purpose
3874+ * is to let the application store application-specific state (e.g.,
3875+ * file pointers) for the connection. The size of this field is
3876+ * configured in the "uipopt.h" header file.
3877+ */
3878+struct uip_conn {
3879+ u16_t ripaddr[2]; /**< The IP address of the remote host. */
3880+
3881+ u16_t lport; /**< The local TCP port, in network byte order. */
3882+ u16_t rport; /**< The local remote TCP port, in network byte
3883+ order. */
3884+
3885+ u8_t rcv_nxt[4]; /**< The sequence number that we expect to
3886+ receive next. */
3887+ u8_t snd_nxt[4]; /**< The sequence number that was last sent by
3888+ us. */
3889+ u16_t len; /**< Length of the data that was previously sent. */
3890+ u16_t mss; /**< Current maximum segment size for the
3891+ connection. */
3892+ u16_t initialmss; /**< Initial maximum segment size for the
3893+ connection. */
3894+ u8_t sa; /**< Retransmission time-out calculation state
3895+ variable. */
3896+ u8_t sv; /**< Retransmission time-out calculation state
3897+ variable. */
3898+ u8_t rto; /**< Retransmission time-out. */
3899+ u8_t tcpstateflags; /**< TCP state and flags. */
3900+ u8_t timer; /**< The retransmission timer. */
3901+ u8_t nrtx; /**< The number of retransmissions for the last
3902+ segment sent. */
3903+
3904+ /** The application state. */
3905+ u8_t appstate[UIP_APPSTATE_SIZE];
3906+};
3907+
3908+
3909+/* Pointer to the current connection. */
3910+extern struct uip_conn *uip_conn;
3911+/* The array containing all uIP connections. */
3912+extern struct uip_conn uip_conns[UIP_CONNS];
3913+/**
3914+ * \addtogroup uiparch
3915+ * @{
3916+ */
3917+
3918+/**
3919+ * 4-byte array used for the 32-bit sequence number calculations.
3920+ */
3921+extern volatile u8_t uip_acc32[4];
3922+
3923+/** @} */
3924+
3925+
3926+#if UIP_UDP
3927+/**
3928+ * Representation of a uIP UDP connection.
3929+ */
3930+struct uip_udp_conn {
3931+ u16_t ripaddr[2]; /**< The IP address of the remote peer. */
3932+ u16_t lport; /**< The local port number in network byte order. */
3933+ u16_t rport; /**< The remote port number in network byte order. */
3934+};
3935+
3936+extern struct uip_udp_conn *uip_udp_conn;
3937+extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
3938+#endif /* UIP_UDP */
3939+
3940+/**
3941+ * The structure holding the TCP/IP statistics that are gathered if
3942+ * UIP_STATISTICS is set to 1.
3943+ *
3944+ */
3945+struct uip_stats {
3946+ struct {
3947+ uip_stats_t drop; /**< Number of dropped packets at the IP
3948+ layer. */
3949+ uip_stats_t recv; /**< Number of received packets at the IP
3950+ layer. */
3951+ uip_stats_t sent; /**< Number of sent packets at the IP
3952+ layer. */
3953+ uip_stats_t vhlerr; /**< Number of packets dropped due to wrong
3954+ IP version or header length. */
3955+ uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
3956+ IP length, high byte. */
3957+ uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
3958+ IP length, low byte. */
3959+ uip_stats_t fragerr; /**< Number of packets dropped since they
3960+ were IP fragments. */
3961+ uip_stats_t chkerr; /**< Number of packets dropped due to IP
3962+ checksum errors. */
3963+ uip_stats_t protoerr; /**< Number of packets dropped since they
3964+ were neither ICMP, UDP nor TCP. */
3965+ } ip; /**< IP statistics. */
3966+ struct {
3967+ uip_stats_t drop; /**< Number of dropped ICMP packets. */
3968+ uip_stats_t recv; /**< Number of received ICMP packets. */
3969+ uip_stats_t sent; /**< Number of sent ICMP packets. */
3970+ uip_stats_t typeerr; /**< Number of ICMP packets with a wrong
3971+ type. */
3972+ } icmp; /**< ICMP statistics. */
3973+ struct {
3974+ uip_stats_t drop; /**< Number of dropped TCP segments. */
3975+ uip_stats_t recv; /**< Number of recived TCP segments. */
3976+ uip_stats_t sent; /**< Number of sent TCP segments. */
3977+ uip_stats_t chkerr; /**< Number of TCP segments with a bad
3978+ checksum. */
3979+ uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
3980+ number. */
3981+ uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */
3982+ uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */
3983+ uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
3984+ connections was avaliable. */
3985+ uip_stats_t synrst; /**< Number of SYNs for closed ports,
3986+ triggering a RST. */
3987+ } tcp; /**< TCP statistics. */
3988+};
3989+
3990+/**
3991+ * The uIP TCP/IP statistics.
3992+ *
3993+ * This is the variable in which the uIP TCP/IP statistics are gathered.
3994+ */
3995+extern struct uip_stats uip_stat;
3996+
3997+
3998+/*-----------------------------------------------------------------------------------*/
3999+/* All the stuff below this point is internal to uIP and should not be
4000+ * used directly by an application or by a device driver.
4001+ */
4002+/*-----------------------------------------------------------------------------------*/
4003+/* u8_t uip_flags:
4004+ *
4005+ * When the application is called, uip_flags will contain the flags
4006+ * that are defined in this file. Please read below for more
4007+ * infomation.
4008+ */
4009+extern volatile u8_t uip_flags;
4010+
4011+/* The following flags may be set in the global variable uip_flags
4012+ before calling the application callback. The UIP_ACKDATA and
4013+ UIP_NEWDATA flags may both be set at the same time, whereas the
4014+ others are mutualy exclusive. Note that these flags should *NOT* be
4015+ accessed directly, but through the uIP functions/macros. */
4016+
4017+#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
4018+ acked and the application should send
4019+ out new data instead of retransmitting
4020+ the last data. */
4021+#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
4022+ us new data. */
4023+#define UIP_REXMIT 4 /* Tells the application to retransmit the
4024+ data that was last sent. */
4025+#define UIP_POLL 8 /* Used for polling the application, to
4026+ check if the application has data that
4027+ it wants to send. */
4028+#define UIP_CLOSE 16 /* The remote host has closed the
4029+ connection, thus the connection has
4030+ gone away. Or the application signals
4031+ that it wants to close the
4032+ connection. */
4033+#define UIP_ABORT 32 /* The remote host has aborted the
4034+ connection, thus the connection has
4035+ gone away. Or the application signals
4036+ that it wants to abort the
4037+ connection. */
4038+#define UIP_CONNECTED 64 /* We have got a connection from a remote
4039+ host and have set up a new connection
4040+ for it, or an active connection has
4041+ been successfully established. */
4042+
4043+#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
4044+ too many retransmissions. */
4045+
4046+
4047+/* uip_process(flag):
4048+ *
4049+ * The actual uIP function which does all the work.
4050+ */
4051+void uip_process(u8_t flag);
4052+
4053+/* The following flags are passed as an argument to the uip_process()
4054+ function. They are used to distinguish between the two cases where
4055+ uip_process() is called. It can be called either because we have
4056+ incoming data that should be processed, or because the periodic
4057+ timer has fired. */
4058+
4059+#define UIP_DATA 1 /* Tells uIP that there is incoming data in
4060+ the uip_buf buffer. The length of the
4061+ data is stored in the global variable
4062+ uip_len. */
4063+#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
4064+ fired. */
4065+#if UIP_UDP
4066+#define UIP_UDP_TIMER 3
4067+#endif /* UIP_UDP */
4068+
4069+/* The TCP states used in the uip_conn->tcpstateflags. */
4070+#define CLOSED 0
4071+#define SYN_RCVD 1
4072+#define SYN_SENT 2
4073+#define ESTABLISHED 3
4074+#define FIN_WAIT_1 4
4075+#define FIN_WAIT_2 5
4076+#define CLOSING 6
4077+#define TIME_WAIT 7
4078+#define LAST_ACK 8
4079+#define TS_MASK 15
4080+
4081+#define UIP_STOPPED 16
4082+
4083+#define UIP_TCPIP_HLEN 40
4084+
4085+/* The TCP and IP headers. */
4086+typedef struct {
4087+ /* IP header. */
4088+ u8_t vhl,
4089+ tos,
4090+ len[2],
4091+ ipid[2],
4092+ ipoffset[2],
4093+ ttl,
4094+ proto;
4095+ u16_t ipchksum;
4096+ u16_t srcipaddr[2],
4097+ destipaddr[2];
4098+
4099+ /* TCP header. */
4100+ u16_t srcport,
4101+ destport;
4102+ u8_t seqno[4],
4103+ ackno[4],
4104+ tcpoffset,
4105+ flags,
4106+ wnd[2];
4107+ u16_t tcpchksum;
4108+ u8_t urgp[2];
4109+ u8_t optdata[4];
4110+} uip_tcpip_hdr;
4111+
4112+/* The ICMP and IP headers. */
4113+typedef struct {
4114+ /* IP header. */
4115+ u8_t vhl,
4116+ tos,
4117+ len[2],
4118+ ipid[2],
4119+ ipoffset[2],
4120+ ttl,
4121+ proto;
4122+ u16_t ipchksum;
4123+ u16_t srcipaddr[2],
4124+ destipaddr[2];
4125+ /* ICMP (echo) header. */
4126+ u8_t type, icode;
4127+ u16_t icmpchksum;
4128+ u16_t id, seqno;
4129+} uip_icmpip_hdr;
4130+
4131+
4132+/* The UDP and IP headers. */
4133+typedef struct {
4134+ /* IP header. */
4135+ u8_t vhl,
4136+ tos,
4137+ len[2],
4138+ ipid[2],
4139+ ipoffset[2],
4140+ ttl,
4141+ proto;
4142+ u16_t ipchksum;
4143+ u16_t srcipaddr[2],
4144+ destipaddr[2];
4145+
4146+ /* UDP header. */
4147+ u16_t srcport,
4148+ destport;
4149+ u16_t udplen;
4150+ u16_t udpchksum;
4151+} uip_udpip_hdr;
4152+
4153+#define UIP_PROTO_ICMP 1
4154+#define UIP_PROTO_TCP 6
4155+#define UIP_PROTO_UDP 17
4156+
4157+#if UIP_FIXEDADDR
4158+extern const u16_t uip_hostaddr[2];
4159+#else /* UIP_FIXEDADDR */
4160+extern u16_t uip_hostaddr[2];
4161+#endif /* UIP_FIXEDADDR */
4162+
4163+#endif /* __UIP_H__ */
4164+
4165+
4166+/** @} */
4167+
4168--- /dev/null
4169+++ b/net/uip-0.9/uip_arch.c
4170@@ -0,0 +1,145 @@
4171+/*
4172+ * Copyright (c) 2001, Adam Dunkels.
4173+ * All rights reserved.
4174+ *
4175+ * Redistribution and use in source and binary forms, with or without
4176+ * modification, are permitted provided that the following conditions
4177+ * are met:
4178+ * 1. Redistributions of source code must retain the above copyright
4179+ * notice, this list of conditions and the following disclaimer.
4180+ * 2. Redistributions in binary form must reproduce the above copyright
4181+ * notice, this list of conditions and the following disclaimer in the
4182+ * documentation and/or other materials provided with the distribution.
4183+ * 3. The name of the author may not be used to endorse or promote
4184+ * products derived from this software without specific prior
4185+ * written permission.
4186+ *
4187+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4188+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4189+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4190+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4191+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4192+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4193+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4194+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4195+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4196+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4197+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4198+ *
4199+ * This file is part of the uIP TCP/IP stack.
4200+ *
4201+ * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
4202+ *
4203+ */
4204+
4205+
4206+#include "uip.h"
4207+#include "uip_arch.h"
4208+
4209+#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
4210+#define IP_PROTO_TCP 6
4211+
4212+/*-----------------------------------------------------------------------------------*/
4213+void
4214+uip_add32(u8_t *op32, u16_t op16)
4215+{
4216+
4217+ uip_acc32[3] = op32[3] + (op16 & 0xff);
4218+ uip_acc32[2] = op32[2] + (op16 >> 8);
4219+ uip_acc32[1] = op32[1];
4220+ uip_acc32[0] = op32[0];
4221+
4222+ if(uip_acc32[2] < (op16 >> 8)) {
4223+ ++uip_acc32[1];
4224+ if(uip_acc32[1] == 0) {
4225+ ++uip_acc32[0];
4226+ }
4227+ }
4228+
4229+
4230+ if(uip_acc32[3] < (op16 & 0xff)) {
4231+ ++uip_acc32[2];
4232+ if(uip_acc32[2] == 0) {
4233+ ++uip_acc32[1];
4234+ if(uip_acc32[1] == 0) {
4235+ ++uip_acc32[0];
4236+ }
4237+ }
4238+ }
4239+}
4240+/*-----------------------------------------------------------------------------------*/
4241+u16_t
4242+uip_chksum(u16_t *sdata, u16_t len)
4243+{
4244+ u16_t acc;
4245+
4246+ for(acc = 0; len > 1; len -= 2) {
4247+ acc += *sdata;
4248+ if(acc < *sdata) {
4249+ /* Overflow, so we add the carry to acc (i.e., increase by
4250+ one). */
4251+ ++acc;
4252+ }
4253+ ++sdata;
4254+ }
4255+
4256+ /* add up any odd byte */
4257+ if(len == 1) {
4258+ acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
4259+ if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
4260+ ++acc;
4261+ }
4262+ }
4263+
4264+ return acc;
4265+}
4266+/*-----------------------------------------------------------------------------------*/
4267+u16_t
4268+uip_ipchksum(void)
4269+{
4270+ return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
4271+}
4272+/*-----------------------------------------------------------------------------------*/
4273+u16_t
4274+uip_tcpchksum(void)
4275+{
4276+ u16_t hsum, sum;
4277+
4278+
4279+ /* Compute the checksum of the TCP header. */
4280+ hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
4281+
4282+ /* Compute the checksum of the data in the TCP packet and add it to
4283+ the TCP header checksum. */
4284+ sum = uip_chksum((u16_t *)uip_appdata,
4285+ (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
4286+
4287+ if((sum += hsum) < hsum) {
4288+ ++sum;
4289+ }
4290+
4291+ if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
4292+ ++sum;
4293+ }
4294+ if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
4295+ ++sum;
4296+ }
4297+ if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
4298+ ++sum;
4299+ }
4300+ if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
4301+ ++sum;
4302+ }
4303+ if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
4304+ ++sum;
4305+ }
4306+
4307+ hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
4308+
4309+ if((sum += hsum) < hsum) {
4310+ ++sum;
4311+ }
4312+
4313+ return sum;
4314+}
4315+/*-----------------------------------------------------------------------------------*/
4316--- /dev/null
4317+++ b/net/uip-0.9/uip_arch.h
4318@@ -0,0 +1,130 @@
4319+/**
4320+ * \defgroup uiparch Architecture specific uIP functions
4321+ * @{
4322+ *
4323+ * The functions in the architecture specific module implement the IP
4324+ * check sum and 32-bit additions.
4325+ *
4326+ * The IP checksum calculation is the most computationally expensive
4327+ * operation in the TCP/IP stack and it therefore pays off to
4328+ * implement this in efficient assembler. The purpose of the uip-arch
4329+ * module is to let the checksum functions to be implemented in
4330+ * architecture specific assembler.
4331+ *
4332+ */
4333+
4334+/**
4335+ * \file
4336+ * Declarations of architecture specific functions.
4337+ * \author Adam Dunkels <adam@dunkels.com>
4338+ */
4339+
4340+/*
4341+ * Copyright (c) 2001, Adam Dunkels.
4342+ * All rights reserved.
4343+ *
4344+ * Redistribution and use in source and binary forms, with or without
4345+ * modification, are permitted provided that the following conditions
4346+ * are met:
4347+ * 1. Redistributions of source code must retain the above copyright
4348+ * notice, this list of conditions and the following disclaimer.
4349+ * 2. Redistributions in binary form must reproduce the above copyright
4350+ * notice, this list of conditions and the following disclaimer in the
4351+ * documentation and/or other materials provided with the distribution.
4352+ * 3. The name of the author may not be used to endorse or promote
4353+ * products derived from this software without specific prior
4354+ * written permission.
4355+ *
4356+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4357+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4358+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4359+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4360+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4361+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4362+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4363+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4364+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4365+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4366+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4367+ *
4368+ * This file is part of the uIP TCP/IP stack.
4369+ *
4370+ * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $
4371+ *
4372+ */
4373+
4374+#ifndef __UIP_ARCH_H__
4375+#define __UIP_ARCH_H__
4376+
4377+#include "uip.h"
4378+
4379+/**
4380+ * Carry out a 32-bit addition.
4381+ *
4382+ * Because not all architectures for which uIP is intended has native
4383+ * 32-bit arithmetic, uIP uses an external C function for doing the
4384+ * required 32-bit additions in the TCP protocol processing. This
4385+ * function should add the two arguments and place the result in the
4386+ * global variable uip_acc32.
4387+ *
4388+ * \note The 32-bit integer pointed to by the op32 parameter and the
4389+ * result in the uip_acc32 variable are in network byte order (big
4390+ * endian).
4391+ *
4392+ * \param op32 A pointer to a 4-byte array representing a 32-bit
4393+ * integer in network byte order (big endian).
4394+ *
4395+ * \param op16 A 16-bit integer in host byte order.
4396+ */
4397+void uip_add32(u8_t *op32, u16_t op16);
4398+
4399+/**
4400+ * Calculate the Internet checksum over a buffer.
4401+ *
4402+ * The Internet checksum is the one's complement of the one's
4403+ * complement sum of all 16-bit words in the buffer.
4404+ *
4405+ * See RFC1071.
4406+ *
4407+ * \note This function is not called in the current version of uIP,
4408+ * but future versions might make use of it.
4409+ *
4410+ * \param buf A pointer to the buffer over which the checksum is to be
4411+ * computed.
4412+ *
4413+ * \param len The length of the buffer over which the checksum is to
4414+ * be computed.
4415+ *
4416+ * \return The Internet checksum of the buffer.
4417+ */
4418+u16_t uip_chksum(u16_t *buf, u16_t len);
4419+
4420+/**
4421+ * Calculate the IP header checksum of the packet header in uip_buf.
4422+ *
4423+ * The IP header checksum is the Internet checksum of the 20 bytes of
4424+ * the IP header.
4425+ *
4426+ * \return The IP header checksum of the IP header in the uip_buf
4427+ * buffer.
4428+ */
4429+u16_t uip_ipchksum(void);
4430+
4431+/**
4432+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
4433+ *
4434+ * The TCP checksum is the Internet checksum of data contents of the
4435+ * TCP segment, and a pseudo-header as defined in RFC793.
4436+ *
4437+ * \note The uip_appdata pointer that points to the packet data may
4438+ * point anywhere in memory, so it is not possible to simply calculate
4439+ * the Internet checksum of the contents of the uip_buf buffer.
4440+ *
4441+ * \return The TCP checksum of the TCP segment in uip_buf and pointed
4442+ * to by uip_appdata.
4443+ */
4444+u16_t uip_tcpchksum(void);
4445+
4446+/** @} */
4447+
4448+#endif /* __UIP_ARCH_H__ */
4449--- /dev/null
4450+++ b/net/uip-0.9/uip_arp.c
4451@@ -0,0 +1,421 @@
4452+/**
4453+ * \addtogroup uip
4454+ * @{
4455+ */
4456+
4457+/**
4458+ * \defgroup uiparp uIP Address Resolution Protocol
4459+ * @{
4460+ *
4461+ * The Address Resolution Protocol ARP is used for mapping between IP
4462+ * addresses and link level addresses such as the Ethernet MAC
4463+ * addresses. ARP uses broadcast queries to ask for the link level
4464+ * address of a known IP address and the host which is configured with
4465+ * the IP address for which the query was meant, will respond with its
4466+ * link level address.
4467+ *
4468+ * \note This ARP implementation only supports Ethernet.
4469+ */
4470+
4471+/**
4472+ * \file
4473+ * Implementation of the ARP Address Resolution Protocol.
4474+ * \author Adam Dunkels <adam@dunkels.com>
4475+ *
4476+ */
4477+
4478+/*
4479+ * Copyright (c) 2001-2003, Adam Dunkels.
4480+ * All rights reserved.
4481+ *
4482+ * Redistribution and use in source and binary forms, with or without
4483+ * modification, are permitted provided that the following conditions
4484+ * are met:
4485+ * 1. Redistributions of source code must retain the above copyright
4486+ * notice, this list of conditions and the following disclaimer.
4487+ * 2. Redistributions in binary form must reproduce the above copyright
4488+ * notice, this list of conditions and the following disclaimer in the
4489+ * documentation and/or other materials provided with the distribution.
4490+ * 3. The name of the author may not be used to endorse or promote
4491+ * products derived from this software without specific prior
4492+ * written permission.
4493+ *
4494+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4495+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4496+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4497+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4498+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4499+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4500+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4501+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4502+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4503+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4504+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4505+ *
4506+ * This file is part of the uIP TCP/IP stack.
4507+ *
4508+ * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $
4509+ *
4510+ */
4511+
4512+
4513+#include "uip_arp.h"
4514+
4515+struct arp_hdr {
4516+ struct uip_eth_hdr ethhdr;
4517+ u16_t hwtype;
4518+ u16_t protocol;
4519+ u8_t hwlen;
4520+ u8_t protolen;
4521+ u16_t opcode;
4522+ struct uip_eth_addr shwaddr;
4523+ u16_t sipaddr[2];
4524+ struct uip_eth_addr dhwaddr;
4525+ u16_t dipaddr[2];
4526+};
4527+
4528+struct ethip_hdr {
4529+ struct uip_eth_hdr ethhdr;
4530+ /* IP header. */
4531+ u8_t vhl,
4532+ tos,
4533+ len[2],
4534+ ipid[2],
4535+ ipoffset[2],
4536+ ttl,
4537+ proto;
4538+ u16_t ipchksum;
4539+ u16_t srcipaddr[2],
4540+ destipaddr[2];
4541+};
4542+
4543+#define ARP_REQUEST 1
4544+#define ARP_REPLY 2
4545+
4546+#define ARP_HWTYPE_ETH 1
4547+
4548+struct arp_entry {
4549+ u16_t ipaddr[2];
4550+ struct uip_eth_addr ethaddr;
4551+ u8_t time;
4552+};
4553+
4554+struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
4555+ UIP_ETHADDR1,
4556+ UIP_ETHADDR2,
4557+ UIP_ETHADDR3,
4558+ UIP_ETHADDR4,
4559+ UIP_ETHADDR5}};
4560+
4561+static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
4562+static u16_t ipaddr[2];
4563+static u8_t i, c;
4564+
4565+static u8_t arptime;
4566+static u8_t tmpage;
4567+
4568+#define BUF ((struct arp_hdr *)&uip_buf[0])
4569+#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
4570+/*-----------------------------------------------------------------------------------*/
4571+/**
4572+ * Initialize the ARP module.
4573+ *
4574+ */
4575+/*-----------------------------------------------------------------------------------*/
4576+void
4577+uip_arp_init(void)
4578+{
4579+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
4580+ memset(arp_table[i].ipaddr, 0, 4);
4581+ }
4582+}
4583+/*-----------------------------------------------------------------------------------*/
4584+/**
4585+ * Periodic ARP processing function.
4586+ *
4587+ * This function performs periodic timer processing in the ARP module
4588+ * and should be called at regular intervals. The recommended interval
4589+ * is 10 seconds between the calls.
4590+ *
4591+ */
4592+/*-----------------------------------------------------------------------------------*/
4593+void
4594+uip_arp_timer(void)
4595+{
4596+ struct arp_entry *tabptr;
4597+
4598+ ++arptime;
4599+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
4600+ tabptr = &arp_table[i];
4601+ if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
4602+ arptime - tabptr->time >= UIP_ARP_MAXAGE) {
4603+ memset(tabptr->ipaddr, 0, 4);
4604+ }
4605+ }
4606+
4607+}
4608+/*-----------------------------------------------------------------------------------*/
4609+static void
4610+uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
4611+{
4612+ register struct arp_entry *tabptr = 0;
4613+ /* Walk through the ARP mapping table and try to find an entry to
4614+ update. If none is found, the IP -> MAC address mapping is
4615+ inserted in the ARP table. */
4616+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
4617+
4618+ tabptr = &arp_table[i];
4619+ /* Only check those entries that are actually in use. */
4620+ if(tabptr->ipaddr[0] != 0 &&
4621+ tabptr->ipaddr[1] != 0) {
4622+
4623+ /* Check if the source IP address of the incoming packet matches
4624+ the IP address in this ARP table entry. */
4625+ if(ipaddr[0] == tabptr->ipaddr[0] &&
4626+ ipaddr[1] == tabptr->ipaddr[1]) {
4627+
4628+ /* An old entry found, update this and return. */
4629+ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
4630+ tabptr->time = arptime;
4631+
4632+ return;
4633+ }
4634+ }
4635+ }
4636+
4637+ /* If we get here, no existing ARP table entry was found, so we
4638+ create one. */
4639+
4640+ /* First, we try to find an unused entry in the ARP table. */
4641+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
4642+ tabptr = &arp_table[i];
4643+ if(tabptr->ipaddr[0] == 0 &&
4644+ tabptr->ipaddr[1] == 0) {
4645+ break;
4646+ }
4647+ }
4648+
4649+ /* If no unused entry is found, we try to find the oldest entry and
4650+ throw it away. */
4651+ if(i == UIP_ARPTAB_SIZE) {
4652+ tmpage = 0;
4653+ c = 0;
4654+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
4655+ tabptr = &arp_table[i];
4656+ if(arptime - tabptr->time > tmpage) {
4657+ tmpage = arptime - tabptr->time;
4658+ c = i;
4659+ }
4660+ }
4661+ i = c;
4662+ }
4663+
4664+ /* Now, i is the ARP table entry which we will fill with the new
4665+ information. */
4666+ memcpy(tabptr->ipaddr, ipaddr, 4);
4667+ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
4668+ tabptr->time = arptime;
4669+}
4670+/*-----------------------------------------------------------------------------------*/
4671+/**
4672+ * ARP processing for incoming IP packets
4673+ *
4674+ * This function should be called by the device driver when an IP
4675+ * packet has been received. The function will check if the address is
4676+ * in the ARP cache, and if so the ARP cache entry will be
4677+ * refreshed. If no ARP cache entry was found, a new one is created.
4678+ *
4679+ * This function expects an IP packet with a prepended Ethernet header
4680+ * in the uip_buf[] buffer, and the length of the packet in the global
4681+ * variable uip_len.
4682+ */
4683+/*-----------------------------------------------------------------------------------*/
4684+void
4685+uip_arp_ipin(void)
4686+{
4687+ uip_len -= sizeof(struct uip_eth_hdr);
4688+
4689+ /* Only insert/update an entry if the source IP address of the
4690+ incoming IP packet comes from a host on the local network. */
4691+ if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
4692+ (uip_hostaddr[0] & uip_arp_netmask[0])) {
4693+ return;
4694+ }
4695+ if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
4696+ (uip_hostaddr[1] & uip_arp_netmask[1])) {
4697+ return;
4698+ }
4699+ uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
4700+
4701+ return;
4702+}
4703+/*-----------------------------------------------------------------------------------*/
4704+/**
4705+ * ARP processing for incoming ARP packets.
4706+ *
4707+ * This function should be called by the device driver when an ARP
4708+ * packet has been received. The function will act differently
4709+ * depending on the ARP packet type: if it is a reply for a request
4710+ * that we previously sent out, the ARP cache will be filled in with
4711+ * the values from the ARP reply. If the incoming ARP packet is an ARP
4712+ * request for our IP address, an ARP reply packet is created and put
4713+ * into the uip_buf[] buffer.
4714+ *
4715+ * When the function returns, the value of the global variable uip_len
4716+ * indicates whether the device driver should send out a packet or
4717+ * not. If uip_len is zero, no packet should be sent. If uip_len is
4718+ * non-zero, it contains the length of the outbound packet that is
4719+ * present in the uip_buf[] buffer.
4720+ *
4721+ * This function expects an ARP packet with a prepended Ethernet
4722+ * header in the uip_buf[] buffer, and the length of the packet in the
4723+ * global variable uip_len.
4724+ */
4725+/*-----------------------------------------------------------------------------------*/
4726+void
4727+uip_arp_arpin(void)
4728+{
4729+
4730+ if(uip_len < sizeof(struct arp_hdr)) {
4731+ uip_len = 0;
4732+ return;
4733+ }
4734+
4735+ uip_len = 0;
4736+
4737+ switch(BUF->opcode) {
4738+ case HTONS(ARP_REQUEST):
4739+ /* ARP request. If it asked for our address, we send out a
4740+ reply. */
4741+ if(BUF->dipaddr[0] == uip_hostaddr[0] &&
4742+ BUF->dipaddr[1] == uip_hostaddr[1]) {
4743+ /* The reply opcode is 2. */
4744+ BUF->opcode = HTONS(2);
4745+
4746+ memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
4747+ memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
4748+ memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
4749+ memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
4750+
4751+ BUF->dipaddr[0] = BUF->sipaddr[0];
4752+ BUF->dipaddr[1] = BUF->sipaddr[1];
4753+ BUF->sipaddr[0] = uip_hostaddr[0];
4754+ BUF->sipaddr[1] = uip_hostaddr[1];
4755+
4756+ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
4757+ uip_len = sizeof(struct arp_hdr);
4758+ }
4759+ break;
4760+ case HTONS(ARP_REPLY):
4761+ /* ARP reply. We insert or update the ARP table if it was meant
4762+ for us. */
4763+ if(BUF->dipaddr[0] == uip_hostaddr[0] &&
4764+ BUF->dipaddr[1] == uip_hostaddr[1]) {
4765+
4766+ uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
4767+ }
4768+ break;
4769+ }
4770+
4771+ return;
4772+}
4773+/*-----------------------------------------------------------------------------------*/
4774+/**
4775+ * Prepend Ethernet header to an outbound IP packet and see if we need
4776+ * to send out an ARP request.
4777+ *
4778+ * This function should be called before sending out an IP packet. The
4779+ * function checks the destination IP address of the IP packet to see
4780+ * what Ethernet MAC address that should be used as a destination MAC
4781+ * address on the Ethernet.
4782+ *
4783+ * If the destination IP address is in the local network (determined
4784+ * by logical ANDing of netmask and our IP address), the function
4785+ * checks the ARP cache to see if an entry for the destination IP
4786+ * address is found. If so, an Ethernet header is prepended and the
4787+ * function returns. If no ARP cache entry is found for the
4788+ * destination IP address, the packet in the uip_buf[] is replaced by
4789+ * an ARP request packet for the IP address. The IP packet is dropped
4790+ * and it is assumed that they higher level protocols (e.g., TCP)
4791+ * eventually will retransmit the dropped packet.
4792+ *
4793+ * If the destination IP address is not on the local network, the IP
4794+ * address of the default router is used instead.
4795+ *
4796+ * When the function returns, a packet is present in the uip_buf[]
4797+ * buffer, and the length of the packet is in the global variable
4798+ * uip_len.
4799+ */
4800+/*-----------------------------------------------------------------------------------*/
4801+void
4802+uip_arp_out(void)
4803+{
4804+ struct arp_entry *tabptr = 0;
4805+ /* Find the destination IP address in the ARP table and construct
4806+ the Ethernet header. If the destination IP addres isn't on the
4807+ local network, we use the default router's IP address instead.
4808+
4809+ If not ARP table entry is found, we overwrite the original IP
4810+ packet with an ARP request for the IP address. */
4811+
4812+ /* Check if the destination address is on the local network. */
4813+ if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) !=
4814+ (uip_hostaddr[0] & uip_arp_netmask[0]) ||
4815+ (IPBUF->destipaddr[1] & uip_arp_netmask[1]) !=
4816+ (uip_hostaddr[1] & uip_arp_netmask[1])) {
4817+ /* Destination address was not on the local network, so we need to
4818+ use the default router's IP address instead of the destination
4819+ address when determining the MAC address. */
4820+ ipaddr[0] = uip_arp_draddr[0];
4821+ ipaddr[1] = uip_arp_draddr[1];
4822+ } else {
4823+ /* Else, we use the destination IP address. */
4824+ ipaddr[0] = IPBUF->destipaddr[0];
4825+ ipaddr[1] = IPBUF->destipaddr[1];
4826+ }
4827+
4828+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
4829+ tabptr = &arp_table[i];
4830+ if(ipaddr[0] == tabptr->ipaddr[0] &&
4831+ ipaddr[1] == tabptr->ipaddr[1])
4832+ break;
4833+ }
4834+
4835+ if(i == UIP_ARPTAB_SIZE) {
4836+ /* The destination address was not in our ARP table, so we
4837+ overwrite the IP packet with an ARP request. */
4838+
4839+ memset(BUF->ethhdr.dest.addr, 0xff, 6);
4840+ memset(BUF->dhwaddr.addr, 0x00, 6);
4841+ memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
4842+ memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
4843+
4844+ BUF->dipaddr[0] = ipaddr[0];
4845+ BUF->dipaddr[1] = ipaddr[1];
4846+ BUF->sipaddr[0] = uip_hostaddr[0];
4847+ BUF->sipaddr[1] = uip_hostaddr[1];
4848+ BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
4849+ BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
4850+ BUF->protocol = HTONS(UIP_ETHTYPE_IP);
4851+ BUF->hwlen = 6;
4852+ BUF->protolen = 4;
4853+ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
4854+
4855+ uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
4856+
4857+ uip_len = sizeof(struct arp_hdr);
4858+ return;
4859+ }
4860+
4861+ /* Build an ethernet header. */
4862+ memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
4863+ memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
4864+
4865+ IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
4866+
4867+ uip_len += sizeof(struct uip_eth_hdr);
4868+}
4869+/*-----------------------------------------------------------------------------------*/
4870+
4871+/** @} */
4872+/** @} */
4873--- /dev/null
4874+++ b/net/uip-0.9/uip_arp.h
4875@@ -0,0 +1,201 @@
4876+/**
4877+ * \addtogroup uip
4878+ * @{
4879+ */
4880+
4881+/**
4882+ * \addtogroup uiparp
4883+ * @{
4884+ */
4885+
4886+/**
4887+ * \file
4888+ * Macros and definitions for the ARP module.
4889+ * \author Adam Dunkels <adam@dunkels.com>
4890+ */
4891+
4892+
4893+/*
4894+ * Copyright (c) 2001-2003, Adam Dunkels.
4895+ * All rights reserved.
4896+ *
4897+ * Redistribution and use in source and binary forms, with or without
4898+ * modification, are permitted provided that the following conditions
4899+ * are met:
4900+ * 1. Redistributions of source code must retain the above copyright
4901+ * notice, this list of conditions and the following disclaimer.
4902+ * 2. Redistributions in binary form must reproduce the above copyright
4903+ * notice, this list of conditions and the following disclaimer in the
4904+ * documentation and/or other materials provided with the distribution.
4905+ * 3. The name of the author may not be used to endorse or promote
4906+ * products derived from this software without specific prior
4907+ * written permission.
4908+ *
4909+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4910+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4911+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4912+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4913+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4914+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4915+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4916+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4917+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4918+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4919+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4920+ *
4921+ * This file is part of the uIP TCP/IP stack.
4922+ *
4923+ * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $
4924+ *
4925+ */
4926+
4927+#ifndef __UIP_ARP_H__
4928+#define __UIP_ARP_H__
4929+
4930+#include "uip.h"
4931+
4932+
4933+/**
4934+ * Representation of a 48-bit Ethernet address.
4935+ */
4936+struct uip_eth_addr {
4937+ u8_t addr[6];
4938+};
4939+
4940+extern struct uip_eth_addr uip_ethaddr;
4941+
4942+/**
4943+ * The Ethernet header.
4944+ */
4945+struct uip_eth_hdr {
4946+ struct uip_eth_addr dest;
4947+ struct uip_eth_addr src;
4948+ u16_t type;
4949+};
4950+
4951+#define UIP_ETHTYPE_ARP 0x0806
4952+#define UIP_ETHTYPE_IP 0x0800
4953+#define UIP_ETHTYPE_IP6 0x86dd
4954+
4955+
4956+/* The uip_arp_init() function must be called before any of the other
4957+ ARP functions. */
4958+void uip_arp_init(void);
4959+
4960+/* The uip_arp_ipin() function should be called whenever an IP packet
4961+ arrives from the Ethernet. This function refreshes the ARP table or
4962+ inserts a new mapping if none exists. The function assumes that an
4963+ IP packet with an Ethernet header is present in the uip_buf buffer
4964+ and that the length of the packet is in the uip_len variable. */
4965+void uip_arp_ipin(void);
4966+
4967+/* The uip_arp_arpin() should be called when an ARP packet is received
4968+ by the Ethernet driver. This function also assumes that the
4969+ Ethernet frame is present in the uip_buf buffer. When the
4970+ uip_arp_arpin() function returns, the contents of the uip_buf
4971+ buffer should be sent out on the Ethernet if the uip_len variable
4972+ is > 0. */
4973+void uip_arp_arpin(void);
4974+
4975+/* The uip_arp_out() function should be called when an IP packet
4976+ should be sent out on the Ethernet. This function creates an
4977+ Ethernet header before the IP header in the uip_buf buffer. The
4978+ Ethernet header will have the correct Ethernet MAC destination
4979+ address filled in if an ARP table entry for the destination IP
4980+ address (or the IP address of the default router) is present. If no
4981+ such table entry is found, the IP packet is overwritten with an ARP
4982+ request and we rely on TCP to retransmit the packet that was
4983+ overwritten. In any case, the uip_len variable holds the length of
4984+ the Ethernet frame that should be transmitted. */
4985+void uip_arp_out(void);
4986+
4987+/* The uip_arp_timer() function should be called every ten seconds. It
4988+ is responsible for flushing old entries in the ARP table. */
4989+void uip_arp_timer(void);
4990+
4991+/** @} */
4992+
4993+/**
4994+ * \addtogroup uipconffunc
4995+ * @{
4996+ */
4997+
4998+/**
4999+ * Set the default router's IP address.
5000+ *
5001+ * \param addr A pointer to a 4-byte array containing the IP address
5002+ * of the default router.
5003+ *
5004+ * \hideinitializer
5005+ */
5006+#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \
5007+ uip_arp_draddr[1] = addr[1]; } while(0)
5008+
5009+/**
5010+ * Set the netmask.
5011+ *
5012+ * \param addr A pointer to a 4-byte array containing the IP address
5013+ * of the netmask.
5014+ *
5015+ * \hideinitializer
5016+ */
5017+#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \
5018+ uip_arp_netmask[1] = addr[1]; } while(0)
5019+
5020+
5021+/**
5022+ * Get the default router's IP address.
5023+ *
5024+ * \param addr A pointer to a 4-byte array that will be filled in with
5025+ * the IP address of the default router.
5026+ *
5027+ * \hideinitializer
5028+ */
5029+#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \
5030+ addr[1] = uip_arp_draddr[1]; } while(0)
5031+
5032+/**
5033+ * Get the netmask.
5034+ *
5035+ * \param addr A pointer to a 4-byte array that will be filled in with
5036+ * the value of the netmask.
5037+ *
5038+ * \hideinitializer
5039+ */
5040+#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \
5041+ addr[1] = uip_arp_netmask[1]; } while(0)
5042+
5043+
5044+/**
5045+ * Specifiy the Ethernet MAC address.
5046+ *
5047+ * The ARP code needs to know the MAC address of the Ethernet card in
5048+ * order to be able to respond to ARP queries and to generate working
5049+ * Ethernet headers.
5050+ *
5051+ * \note This macro only specifies the Ethernet MAC address to the ARP
5052+ * code. It cannot be used to change the MAC address of the Ethernet
5053+ * card.
5054+ *
5055+ * \param eaddr A pointer to a struct uip_eth_addr containing the
5056+ * Ethernet MAC address of the Ethernet card.
5057+ *
5058+ * \hideinitializer
5059+ */
5060+#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
5061+ uip_ethaddr.addr[1] = eaddr.addr[1];\
5062+ uip_ethaddr.addr[2] = eaddr.addr[2];\
5063+ uip_ethaddr.addr[3] = eaddr.addr[3];\
5064+ uip_ethaddr.addr[4] = eaddr.addr[4];\
5065+ uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
5066+
5067+/** @} */
5068+
5069+/**
5070+ * \internal Internal variables that are set using the macros
5071+ * uip_setdraddr and uip_setnetmask.
5072+ */
5073+extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
5074+#endif /* __UIP_ARP_H__ */
5075+
5076+
5077--- /dev/null
5078+++ b/net/uip-0.9/uipopt.h
5079@@ -0,0 +1,557 @@
5080+/**
5081+ * \defgroup uipopt Configuration options for uIP
5082+ * @{
5083+ *
5084+ * uIP is configured using the per-project configuration file
5085+ * "uipopt.h". This file contains all compile-time options for uIP and
5086+ * should be tweaked to match each specific project. The uIP
5087+ * distribution contains a documented example "uipopt.h" that can be
5088+ * copied and modified for each project.
5089+ */
5090+
5091+/**
5092+ * \file
5093+ * Configuration options for uIP.
5094+ * \author Adam Dunkels <adam@dunkels.com>
5095+ *
5096+ * This file is used for tweaking various configuration options for
5097+ * uIP. You should make a copy of this file into one of your project's
5098+ * directories instead of editing this example "uipopt.h" file that
5099+ * comes with the uIP distribution.
5100+ */
5101+
5102+/*
5103+ * Copyright (c) 2001-2003, Adam Dunkels.
5104+ * All rights reserved.
5105+ *
5106+ * Redistribution and use in source and binary forms, with or without
5107+ * modification, are permitted provided that the following conditions
5108+ * are met:
5109+ * 1. Redistributions of source code must retain the above copyright
5110+ * notice, this list of conditions and the following disclaimer.
5111+ * 2. Redistributions in binary form must reproduce the above copyright
5112+ * notice, this list of conditions and the following disclaimer in the
5113+ * documentation and/or other materials provided with the distribution.
5114+ * 3. The name of the author may not be used to endorse or promote
5115+ * products derived from this software without specific prior
5116+ * written permission.
5117+ *
5118+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5119+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5120+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5121+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5122+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5123+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5124+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5125+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5126+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5127+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5128+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5129+ *
5130+ * This file is part of the uIP TCP/IP stack.
5131+ *
5132+ * $Id: uipopt.h,v 1.16.2.5 2003/10/07 13:22:51 adam Exp $
5133+ *
5134+ */
5135+
5136+#ifndef __UIPOPT_H__
5137+#define __UIPOPT_H__
5138+
5139+/*------------------------------------------------------------------------------*/
5140+/**
5141+ * \defgroup uipopttypedef uIP type definitions
5142+ * @{
5143+ */
5144+
5145+/**
5146+ * The 8-bit unsigned data type.
5147+ *
5148+ * This may have to be tweaked for your particular compiler. "unsigned
5149+ * char" works for most compilers.
5150+ */
5151+typedef unsigned char u8_t;
5152+
5153+/**
5154+ * The 16-bit unsigned data type.
5155+ *
5156+ * This may have to be tweaked for your particular compiler. "unsigned
5157+ * short" works for most compilers.
5158+ */
5159+typedef unsigned short u16_t;
5160+
5161+/**
5162+ * The statistics data type.
5163+ *
5164+ * This datatype determines how high the statistics counters are able
5165+ * to count.
5166+ */
5167+typedef unsigned short uip_stats_t;
5168+
5169+/** @} */
5170+
5171+/*------------------------------------------------------------------------------*/
5172+
5173+/**
5174+ * \defgroup uipoptstaticconf Static configuration options
5175+ * @{
5176+ *
5177+ * These configuration options can be used for setting the IP address
5178+ * settings statically, but only if UIP_FIXEDADDR is set to 1. The
5179+ * configuration options for a specific node includes IP address,
5180+ * netmask and default router as well as the Ethernet address. The
5181+ * netmask, default router and Ethernet address are appliciable only
5182+ * if uIP should be run over Ethernet.
5183+ *
5184+ * All of these should be changed to suit your project.
5185+*/
5186+
5187+/**
5188+ * Determines if uIP should use a fixed IP address or not.
5189+ *
5190+ * If uIP should use a fixed IP address, the settings are set in the
5191+ * uipopt.h file. If not, the macros uip_sethostaddr(),
5192+ * uip_setdraddr() and uip_setnetmask() should be used instead.
5193+ *
5194+ * \hideinitializer
5195+ */
5196+#define UIP_FIXEDADDR 0
5197+
5198+/**
5199+ * Ping IP address asignment.
5200+ *
5201+ * uIP uses a "ping" packets for setting its own IP address if this
5202+ * option is set. If so, uIP will start with an empty IP address and
5203+ * the destination IP address of the first incoming "ping" (ICMP echo)
5204+ * packet will be used for setting the hosts IP address.
5205+ *
5206+ * \note This works only if UIP_FIXEDADDR is 0.
5207+ *
5208+ * \hideinitializer
5209+ */
5210+#define UIP_PINGADDRCONF 0
5211+
5212+#define UIP_IPADDR0 192 /**< The first octet of the IP address of
5213+ this uIP node, if UIP_FIXEDADDR is
5214+ 1. \hideinitializer */
5215+#define UIP_IPADDR1 168 /**< The second octet of the IP address of
5216+ this uIP node, if UIP_FIXEDADDR is
5217+ 1. \hideinitializer */
5218+#define UIP_IPADDR2 0 /**< The third octet of the IP address of
5219+ this uIP node, if UIP_FIXEDADDR is
5220+ 1. \hideinitializer */
5221+#define UIP_IPADDR3 250 /**< The fourth octet of the IP address of
5222+ this uIP node, if UIP_FIXEDADDR is
5223+ 1. \hideinitializer */
5224+
5225+#define UIP_NETMASK0 255 /**< The first octet of the netmask of
5226+ this uIP node, if UIP_FIXEDADDR is
5227+ 1. \hideinitializer */
5228+#define UIP_NETMASK1 255 /**< The second octet of the netmask of
5229+ this uIP node, if UIP_FIXEDADDR is
5230+ 1. \hideinitializer */
5231+#define UIP_NETMASK2 255 /**< The third octet of the netmask of
5232+ this uIP node, if UIP_FIXEDADDR is
5233+ 1. \hideinitializer */
5234+#define UIP_NETMASK3 0 /**< The fourth octet of the netmask of
5235+ this uIP node, if UIP_FIXEDADDR is
5236+ 1. \hideinitializer */
5237+
5238+#define UIP_DRIPADDR0 192 /**< The first octet of the IP address of
5239+ the default router, if UIP_FIXEDADDR is
5240+ 1. \hideinitializer */
5241+#define UIP_DRIPADDR1 168 /**< The second octet of the IP address of
5242+ the default router, if UIP_FIXEDADDR is
5243+ 1. \hideinitializer */
5244+#define UIP_DRIPADDR2 0 /**< The third octet of the IP address of
5245+ the default router, if UIP_FIXEDADDR is
5246+ 1. \hideinitializer */
5247+#define UIP_DRIPADDR3 1 /**< The fourth octet of the IP address of
5248+ the default router, if UIP_FIXEDADDR is
5249+ 1. \hideinitializer */
5250+
5251+/**
5252+ * Specifies if the uIP ARP module should be compiled with a fixed
5253+ * Ethernet MAC address or not.
5254+ *
5255+ * If this configuration option is 0, the macro uip_setethaddr() can
5256+ * be used to specify the Ethernet address at run-time.
5257+ *
5258+ * \hideinitializer
5259+ */
5260+#define UIP_FIXEDETHADDR 0
5261+
5262+#define UIP_ETHADDR0 0x00 /**< The first octet of the Ethernet
5263+ address if UIP_FIXEDETHADDR is
5264+ 1. \hideinitializer */
5265+#define UIP_ETHADDR1 0xbd /**< The second octet of the Ethernet
5266+ address if UIP_FIXEDETHADDR is
5267+ 1. \hideinitializer */
5268+#define UIP_ETHADDR2 0x3b /**< The third octet of the Ethernet
5269+ address if UIP_FIXEDETHADDR is
5270+ 1. \hideinitializer */
5271+#define UIP_ETHADDR3 0x33 /**< The fourth octet of the Ethernet
5272+ address if UIP_FIXEDETHADDR is
5273+ 1. \hideinitializer */
5274+#define UIP_ETHADDR4 0x05 /**< The fifth octet of the Ethernet
5275+ address if UIP_FIXEDETHADDR is
5276+ 1. \hideinitializer */
5277+#define UIP_ETHADDR5 0x71 /**< The sixth octet of the Ethernet
5278+ address if UIP_FIXEDETHADDR is
5279+ 1. \hideinitializer */
5280+
5281+/** @} */
5282+/*------------------------------------------------------------------------------*/
5283+/**
5284+ * \defgroup uipoptip IP configuration options
5285+ * @{
5286+ *
5287+ */
5288+/**
5289+ * The IP TTL (time to live) of IP packets sent by uIP.
5290+ *
5291+ * This should normally not be changed.
5292+ */
5293+#define UIP_TTL 255
5294+
5295+/**
5296+ * Turn on support for IP packet reassembly.
5297+ *
5298+ * uIP supports reassembly of fragmented IP packets. This features
5299+ * requires an additonal amount of RAM to hold the reassembly buffer
5300+ * and the reassembly code size is approximately 700 bytes. The
5301+ * reassembly buffer is of the same size as the uip_buf buffer
5302+ * (configured by UIP_BUFSIZE).
5303+ *
5304+ * \note IP packet reassembly is not heavily tested.
5305+ *
5306+ * \hideinitializer
5307+ */
5308+#define UIP_REASSEMBLY 0
5309+
5310+/**
5311+ * The maximum time an IP fragment should wait in the reassembly
5312+ * buffer before it is dropped.
5313+ *
5314+ */
5315+#define UIP_REASS_MAXAGE 40
5316+
5317+/** @} */
5318+
5319+/*------------------------------------------------------------------------------*/
5320+/**
5321+ * \defgroup uipoptudp UDP configuration options
5322+ * @{
5323+ *
5324+ * \note The UDP support in uIP is still not entirely complete; there
5325+ * is no support for sending or receiving broadcast or multicast
5326+ * packets, but it works well enough to support a number of vital
5327+ * applications such as DNS queries, though
5328+ */
5329+
5330+/**
5331+ * Toggles wether UDP support should be compiled in or not.
5332+ *
5333+ * \hideinitializer
5334+ */
5335+#define UIP_UDP 0
5336+
5337+/**
5338+ * Toggles if UDP checksums should be used or not.
5339+ *
5340+ * \note Support for UDP checksums is currently not included in uIP,
5341+ * so this option has no function.
5342+ *
5343+ * \hideinitializer
5344+ */
5345+#define UIP_UDP_CHECKSUMS 0
5346+
5347+/**
5348+ * The maximum amount of concurrent UDP connections.
5349+ *
5350+ * \hideinitializer
5351+ */
5352+#define UIP_UDP_CONNS 10
5353+
5354+/**
5355+ * The name of the function that should be called when UDP datagrams arrive.
5356+ *
5357+ * \hideinitializer
5358+ */
5359+#define UIP_UDP_APPCALL udp_appcall
5360+
5361+/** @} */
5362+/*------------------------------------------------------------------------------*/
5363+/**
5364+ * \defgroup uipopttcp TCP configuration options
5365+ * @{
5366+ */
5367+
5368+/**
5369+ * Determines if support for opening connections from uIP should be
5370+ * compiled in.
5371+ *
5372+ * If the applications that are running on top of uIP for this project
5373+ * do not need to open outgoing TCP connections, this configration
5374+ * option can be turned off to reduce the code size of uIP.
5375+ *
5376+ * \hideinitializer
5377+ */
5378+#define UIP_ACTIVE_OPEN 1
5379+
5380+/**
5381+ * The maximum number of simultaneously open TCP connections.
5382+ *
5383+ * Since the TCP connections are statically allocated, turning this
5384+ * configuration knob down results in less RAM used. Each TCP
5385+ * connection requires approximatly 30 bytes of memory.
5386+ *
5387+ * \hideinitializer
5388+ */
5389+#define UIP_CONNS 10
5390+
5391+/**
5392+ * The maximum number of simultaneously listening TCP ports.
5393+ *
5394+ * Each listening TCP port requires 2 bytes of memory.
5395+ *
5396+ * \hideinitializer
5397+ */
5398+#define UIP_LISTENPORTS 10
5399+
5400+/**
5401+ * The size of the advertised receiver's window.
5402+ *
5403+ * Should be set low (i.e., to the size of the uip_buf buffer) is the
5404+ * application is slow to process incoming data, or high (32768 bytes)
5405+ * if the application processes data quickly.
5406+ *
5407+ * \hideinitializer
5408+ */
5409+#define UIP_RECEIVE_WINDOW 32768
5410+
5411+/**
5412+ * Determines if support for TCP urgent data notification should be
5413+ * compiled in.
5414+ *
5415+ * Urgent data (out-of-band data) is a rarely used TCP feature that
5416+ * very seldom would be required.
5417+ *
5418+ * \hideinitializer
5419+ */
5420+#define UIP_URGDATA 1
5421+
5422+/**
5423+ * The initial retransmission timeout counted in timer pulses.
5424+ *
5425+ * This should not be changed.
5426+ */
5427+#define UIP_RTO 3
5428+
5429+/**
5430+ * The maximum number of times a segment should be retransmitted
5431+ * before the connection should be aborted.
5432+ *
5433+ * This should not be changed.
5434+ */
5435+#define UIP_MAXRTX 8
5436+
5437+/**
5438+ * The maximum number of times a SYN segment should be retransmitted
5439+ * before a connection request should be deemed to have been
5440+ * unsuccessful.
5441+ *
5442+ * This should not need to be changed.
5443+ */
5444+#define UIP_MAXSYNRTX 3
5445+
5446+/**
5447+ * The TCP maximum segment size.
5448+ *
5449+ * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.
5450+ */
5451+#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
5452+
5453+/**
5454+ * How long a connection should stay in the TIME_WAIT state.
5455+ *
5456+ * This configiration option has no real implication, and it should be
5457+ * left untouched.
5458+ */
5459+#define UIP_TIME_WAIT_TIMEOUT 120
5460+
5461+
5462+/** @} */
5463+/*------------------------------------------------------------------------------*/
5464+/**
5465+ * \defgroup uipoptarp ARP configuration options
5466+ * @{
5467+ */
5468+
5469+/**
5470+ * The size of the ARP table.
5471+ *
5472+ * This option should be set to a larger value if this uIP node will
5473+ * have many connections from the local network.
5474+ *
5475+ * \hideinitializer
5476+ */
5477+#define UIP_ARPTAB_SIZE 8
5478+
5479+/**
5480+ * The maxium age of ARP table entries measured in 10ths of seconds.
5481+ *
5482+ * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
5483+ * default).
5484+ */
5485+#define UIP_ARP_MAXAGE 120
5486+
5487+/** @} */
5488+
5489+/*------------------------------------------------------------------------------*/
5490+
5491+/**
5492+ * \defgroup uipoptgeneral General configuration options
5493+ * @{
5494+ */
5495+
5496+/**
5497+ * The size of the uIP packet buffer.
5498+ *
5499+ * The uIP packet buffer should not be smaller than 60 bytes, and does
5500+ * not need to be larger than 1500 bytes. Lower size results in lower
5501+ * TCP throughput, larger size results in higher TCP throughput.
5502+ *
5503+ * \hideinitializer
5504+ */
5505+#define UIP_BUFSIZE 1500
5506+
5507+
5508+/**
5509+ * Determines if statistics support should be compiled in.
5510+ *
5511+ * The statistics is useful for debugging and to show the user.
5512+ *
5513+ * \hideinitializer
5514+ */
5515+#define UIP_STATISTICS 1
5516+
5517+/**
5518+ * Determines if logging of certain events should be compiled in.
5519+ *
5520+ * This is useful mostly for debugging. The function uip_log()
5521+ * must be implemented to suit the architecture of the project, if
5522+ * logging is turned on.
5523+ *
5524+ * \hideinitializer
5525+ */
5526+#define UIP_LOGGING 0
5527+
5528+/**
5529+ * Print out a uIP log message.
5530+ *
5531+ * This function must be implemented by the module that uses uIP, and
5532+ * is called by uIP whenever a log message is generated.
5533+ */
5534+void uip_log(char *msg);
5535+
5536+/**
5537+ * The link level header length.
5538+ *
5539+ * This is the offset into the uip_buf where the IP header can be
5540+ * found. For Ethernet, this should be set to 14. For SLIP, this
5541+ * should be set to 0.
5542+ *
5543+ * \hideinitializer
5544+ */
5545+#define UIP_LLH_LEN 14
5546+
5547+
5548+/** @} */
5549+/*------------------------------------------------------------------------------*/
5550+/**
5551+ * \defgroup uipoptcpu CPU architecture configuration
5552+ * @{
5553+ *
5554+ * The CPU architecture configuration is where the endianess of the
5555+ * CPU on which uIP is to be run is specified. Most CPUs today are
5556+ * little endian, and the most notable exception are the Motorolas
5557+ * which are big endian. The BYTE_ORDER macro should be changed to
5558+ * reflect the CPU architecture on which uIP is to be run.
5559+ */
5560+#ifndef LITTLE_ENDIAN
5561+#define LITTLE_ENDIAN 3412
5562+#endif /* LITTLE_ENDIAN */
5563+#ifndef BIG_ENDIAN
5564+#define BIG_ENDIAN 1234
5565+#endif /* BIGE_ENDIAN */
5566+
5567+/**
5568+ * The byte order of the CPU architecture on which uIP is to be run.
5569+ *
5570+ * This option can be either BIG_ENDIAN (Motorola byte order) or
5571+ * LITTLE_ENDIAN (Intel byte order).
5572+ *
5573+ * \hideinitializer
5574+ */
5575+/*#ifndef BYTE_ORDER*/
5576+#define BYTE_ORDER BIG_ENDIAN
5577+/*#endif*/ /* BYTE_ORDER */
5578+
5579+/** @} */
5580+/*------------------------------------------------------------------------------*/
5581+
5582+/**
5583+ * \defgroup uipoptapp Appication specific configurations
5584+ * @{
5585+ *
5586+ * An uIP application is implemented using a single application
5587+ * function that is called by uIP whenever a TCP/IP event occurs. The
5588+ * name of this function must be registered with uIP at compile time
5589+ * using the UIP_APPCALL definition.
5590+ *
5591+ * uIP applications can store the application state within the
5592+ * uip_conn structure by specifying the size of the application
5593+ * structure with the UIP_APPSTATE_SIZE macro.
5594+ *
5595+ * The file containing the definitions must be included in the
5596+ * uipopt.h file.
5597+ *
5598+ * The following example illustrates how this can look.
5599+ \code
5600+
5601+void httpd_appcall(void);
5602+#define UIP_APPCALL httpd_appcall
5603+
5604+struct httpd_state {
5605+ u8_t state;
5606+ u16_t count;
5607+ char *dataptr;
5608+ char *script;
5609+};
5610+#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
5611+ \endcode
5612+ */
5613+
5614+/**
5615+ * \var #define UIP_APPCALL
5616+ *
5617+ * The name of the application function that uIP should call in
5618+ * response to TCP/IP events.
5619+ *
5620+ */
5621+
5622+/**
5623+ * \var #define UIP_APPSTATE_SIZE
5624+ *
5625+ * The size of the application state that is to be stored in the
5626+ * uip_conn structure.
5627+ */
5628+/** @} */
5629+
5630+/* Include the header file for the application program that should be
5631+ used. If you don't use the example web server, you should change
5632+ this. */
5633+#include "httpd.h"
5634+
5635+
5636+#endif /* __UIPOPT_H__ */
5637--- a/board/infineon/easy50712/danube.c
5638+++ b/board/infineon/easy50712/danube.c
5639@@ -354,7 +354,7 @@ int do_http_upgrade(const unsigned char
5640     }
5641     /* write the image to the flash */
5642     puts("http ugrade ...\n");
5643- sprintf(buf, "era ${kernel_addr} +0x%x; cp.b ${ram_addr} ${kernel_addr} 0x%x", size, size);
5644+ sprintf(buf, "era ${kernel_addr} +0x%lx; cp.b ${ram_addr} ${kernel_addr} 0x%lx", size, size);
5645     return run_command(buf, 0);
5646 }
5647 
5648--- a/common/main.c
5649+++ b/common/main.c
5650@@ -273,6 +273,10 @@ static __inline__ int abortboot(int boot
5651 
5652 void main_loop (void)
5653 {
5654+#ifdef CONFIG_CMD_HTTPD
5655+ int ret;
5656+#endif
5657+
5658 #ifndef CONFIG_SYS_HUSH_PARSER
5659     static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
5660     int len;
5661@@ -403,12 +407,22 @@ void main_loop (void)
5662 # endif
5663 
5664 # ifndef CONFIG_SYS_HUSH_PARSER
5665- run_command (s, 0);
5666+ ret = run_command (s, 0);
5667 # else
5668- parse_string_outer(s, FLAG_PARSE_SEMICOLON |
5669+ ret = parse_string_outer(s, FLAG_PARSE_SEMICOLON |
5670                     FLAG_EXIT_FROM_LOOP);
5671 # endif
5672 
5673+# ifdef CONFIG_CMD_HTTPD
5674+ if (ret != 0) {
5675+ printf("Failed to execute bootcmd "
5676+ "(maybe invalid u-boot environment?), "
5677+ "starting httpd to update firmware...\n");
5678+ NetLoopHttpd();
5679+ }
5680+# endif
5681+
5682+
5683 # ifdef CONFIG_AUTOBOOT_KEYED
5684         disable_ctrlc(prev); /* restore Control C checking */
5685 # endif
5686--- a/include/configs/easy50712.h
5687+++ b/include/configs/easy50712.h
5688@@ -114,4 +114,7 @@
5689 
5690 #define CONFIG_CMD_HTTPD /* enable upgrade via HTTPD */
5691 
5692+#define CONFIG_IPADDR 192.168.0.119
5693+#define CONFIG_ETHADDR 00:01:02:03:04:05
5694+
5695 #endif /* __CONFIG_H */
5696--- a/lib_mips/time.c
5697+++ b/lib_mips/time.c
5698@@ -29,6 +29,8 @@ static unsigned long timestamp;
5699 /* how many counter cycles in a jiffy */
5700 #define CYCLES_PER_JIFFY (CONFIG_SYS_MIPS_TIMER_FREQ + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ
5701 
5702+unsigned long ifx_get_cpuclk(void);
5703+
5704 /*
5705  * timer without interrupts
5706  */
5707--- a/net/httpd.c
5708+++ b/net/httpd.c
5709@@ -35,12 +35,14 @@ HttpdHandler (void)
5710     }
5711 }
5712 
5713+#if 0
5714 static void
5715 HttpdTimeout (void)
5716 {
5717     puts ("T ");
5718     NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
5719 }
5720+#endif
5721 
5722 void
5723 HttpdStart (void)
5724--- a/net/net.c
5725+++ b/net/net.c
5726@@ -1966,7 +1966,7 @@ NetSendHttpd(void)
5727 void
5728 NetReceiveHttpd(volatile uchar * inpkt, int len)
5729 {
5730- memcpy(uip_buf, inpkt, len);
5731+ memcpy(uip_buf, (const void *)inpkt, len);
5732     uip_len = len;
5733     if(BUF->type == htons(UIP_ETHTYPE_IP)) {
5734         uip_arp_ipin();
5735@@ -1989,6 +1989,7 @@ NetLoopHttpd(void)
5736     unsigned long long tout = 0;
5737     bd_t *bd = gd->bd;
5738     unsigned short int ip[2];
5739+ struct uip_eth_addr eaddr;
5740 
5741 #ifdef CONFIG_NET_MULTI
5742     NetRestarted = 0;
5743@@ -2039,6 +2040,15 @@ restart:
5744     eth_getenv_enetaddr("ethaddr", NetOurEther);
5745 #endif
5746 
5747+ eaddr.addr[0] = NetOurEther[0];
5748+ eaddr.addr[1] = NetOurEther[1];
5749+ eaddr.addr[2] = NetOurEther[2];
5750+ eaddr.addr[3] = NetOurEther[3];
5751+ eaddr.addr[4] = NetOurEther[4];
5752+ eaddr.addr[5] = NetOurEther[5];
5753+
5754+ uip_setethaddr(eaddr);
5755+
5756     NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
5757     NetOurGatewayIP = getenv_IPaddr ("gatewayip");
5758     NetOurSubnetMask= getenv_IPaddr ("netmask");
5759@@ -2072,6 +2082,14 @@ restart:
5760                 tout = t1;
5761             }
5762         }
5763+
5764+ if (ctrlc()) {
5765+ eth_halt();
5766+ puts ("\nAbort\n");
5767+ return (-1);
5768+ }
5769+
5770+
5771         if(!httpd_upload_complete)
5772             continue;
5773         printf("Bytes transferred = %ld (%lx hex)\n",
5774--- a/net/uip-0.9/fsdata.c
5775+++ b/net/uip-0.9/fsdata.c
5776@@ -1,199 +1,108 @@
5777-static const char data_flashing_html[] = {
5778- /* /flashing.html */
5779- 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5780- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
5781- 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
5782- 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
5783- 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5784- 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
5785- 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
5786- 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
5787- 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
5788- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
5789- 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
5790- 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
5791- 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
5792- 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
5793- 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
5794- 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
5795- 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
5796- 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
5797- 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
5798- 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
5799- 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
5800- 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
5801- 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
5802- 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
5803- 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
5804- 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5805-
5806-static const char data_fail_html[] = {
5807- /* /fail.html */
5808- 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5809- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
5810- 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
5811- 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
5812- 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5813- 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
5814- 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
5815- 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
5816- 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
5817- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
5818- 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
5819- 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
5820- 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
5821- 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
5822- 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
5823- 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
5824- 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
5825- 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
5826- 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
5827- 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
5828- 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
5829- 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
5830- 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
5831- 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
5832- 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
5833- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
5834- 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
5835- 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
5836- 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
5837- 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
5838- 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
5839- 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5840- 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
5841- 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
5842- 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
5843- 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
5844- 0x3e, 0xa, };
5845-
5846-static const char data_404_html[] = {
5847- /* /404.html */
5848- 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5849- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
5850- 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
5851- 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
5852- 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
5853- 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
5854- 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
5855- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
5856- 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
5857- 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
5858- 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
5859- 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
5860- 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
5861- 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
5862- 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
5863- 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
5864- 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
5865- 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
5866- 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
5867- 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
5868- 0x6c, 0x3e, };
5869-
5870-static const char data_index_html[] = {
5871- /* /index.html */
5872- 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5873- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
5874- 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
5875- 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
5876- 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5877- 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
5878- 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
5879- 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
5880- 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
5881- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
5882- 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
5883- 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
5884- 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
5885- 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
5886- 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
5887- 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
5888- 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
5889- 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
5890- 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
5891- 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
5892- 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
5893- 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
5894- 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
5895- 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
5896- 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
5897- 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
5898- 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
5899- 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
5900- 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
5901- 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
5902- 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
5903- 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
5904- 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
5905- 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
5906- 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
5907- 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
5908- 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
5909- 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
5910- 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
5911- 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
5912- 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
5913- 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
5914- 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5915-
5916-static const char data_flash_html[] = {
5917- /* /flash.html */
5918- 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5919- 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
5920- 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
5921- 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
5922- 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5923- 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
5924- 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
5925- 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
5926- 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
5927- 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
5928- 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
5929- 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
5930- 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
5931- 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
5932- 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
5933- 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
5934- 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
5935- 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
5936- 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
5937- 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
5938- 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
5939- 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
5940- 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
5941- 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
5942- 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
5943- 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
5944- 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
5945- 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
5946- 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
5947- 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
5948- 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
5949- 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
5950- 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
5951- 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
5952- 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
5953- 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
5954- 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
5955- 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
5956- 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
5957- 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
5958- 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
5959- 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
5960- 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
5961- 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5962-
5963-const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
5964+static const char data_flashing_html[] =
5965+"HTTP/1.0 200 OK\n"
5966+"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
5967+"Content-type: text/html\n"
5968+"\n"
5969+"<html>\n"
5970+"\t<head>\n"
5971+"\t\t<title>\n"
5972+"\t\t\tFailsafe UI\n"
5973+"\t\t</title>\n"
5974+"\t</head>\n"
5975+"\t<body>\n"
5976+"\t\t<center><h1>Upgrading system...</h1></center>\n"
5977+"\t</body>\n"
5978+"</html>\n";
5979+
5980+static const char data_fail_html[] =
5981+"HTTP/1.0 200 OK\n"
5982+"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
5983+"Content-type: text/html\n"
5984+"\n"
5985+"<html>\n"
5986+"\t<head>\n"
5987+"\t\t<title>\n"
5988+"\t\t\tFailsafe UI\n"
5989+"\t\t</title>\n"
5990+"\t</head>\n"
5991+"\t<body>\n"
5992+"\t\t<h1>Flashing failed</h1>\n"
5993+"\t\tERROR - the image you uploaded failed to pass verification.<br>\n"
5994+"\t\tPlease make sure to use an official update provided by http://lantiq.com/\n"
5995+"\t</body>\n"
5996+"</html>\n";
5997+
5998+static const char data_404_html[] =
5999+"HTTP/1.0 404 File not found\n"
6000+"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
6001+"Content-type: text/html\n"
6002+"\n"
6003+"<html>\n"
6004+"\t<head>\n"
6005+"\t\t<title>\n"
6006+"\t\t\tFailsafe UI\n"
6007+"\t\t</title>\n"
6008+"\t</head>\n"
6009+"\t<body>\n"
6010+"\t\t<center><h1>404 - file not found</h1></center>\n"
6011+"\t</body>\n"
6012+"</html>\n";
6013+
6014+static const char data_index_html[] =
6015+"HTTP/1.0 200 OK\n"
6016+"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
6017+"Content-type: text/html\n"
6018+"\n"
6019+"<html>\n"
6020+"\t<head>\n"
6021+"\t\t<title>\n"
6022+"\t\t\tFailsafe UI\n"
6023+"\t\t</title>\n"
6024+"\t</head>\n"
6025+"\t<body>\n"
6026+"\t\t<h1>Failsafe UI</h1>\n"
6027+"\t\t<form method=\"post\" enctype=\"multipart/form-data\">\n"
6028+"\t\t\t<input type=file name=firmware>\n"
6029+"\t\t\t<input type=submit>\n"
6030+"\t\t</form>\n"
6031+"\t</body>\n"
6032+"</html>\n";
6033+
6034+static const char data_flash_html[] =
6035+"HTTP/1.0 200 OK\n"
6036+"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
6037+"Content-type: text/html\n"
6038+"\n"
6039+"<html>\n"
6040+"\t<head>\n"
6041+"\t\t<title>\n"
6042+"\t\t\tFailsafe UI\n"
6043+"\t\t</title>\n"
6044+"\t</head>\n"
6045+"\t<body>\n"
6046+"\t\t<h1>Flashing...</h1>\n"
6047+"\t\tThe system is now trying to flash. If there is a problem, the LEDs will "
6048+"start to blink.<br>\n"
6049+"\n"
6050+"\t\tAfter a successful update the box will reboot\n"
6051+"\t</body>\n"
6052+"</html>\n";
6053+
6054+const struct fsdata_file file_flashing_html[] =
6055+{{NULL, "/flashing.html", data_flashing_html, sizeof(data_flashing_html)}};
6056+
6057+const struct fsdata_file file_fail_html[] =
6058+{{file_flashing_html, "/fail.html", data_fail_html, sizeof(data_fail_html)}};
6059 
6060-const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
6061+const struct fsdata_file file_404_html[] =
6062+{{file_fail_html, "/404.html", data_404_html, sizeof(data_404_html)}};
6063 
6064-const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
6065+const struct fsdata_file file_index_html[] =
6066+{{file_404_html, "/index.html", data_index_html, sizeof(data_index_html)}};
6067 
6068-const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
6069-
6070-const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
6071+const struct fsdata_file file_flash_html[] =
6072+{{file_index_html, "/flash.html", data_flash_html, sizeof(data_flash_html)}};
6073 
6074 #define FS_ROOT file_flash_html
6075 
6076-#define FS_NUMFILES 5
6077\ No newline at end of file
6078+#define FS_NUMFILES 5
6079--- a/net/uip-0.9/httpd.c
6080+++ b/net/uip-0.9/httpd.c
6081@@ -130,7 +130,7 @@ httpd_appcall(void)
6082                     if(!fs_open((const char *)&uip_appdata[4], &fsfile))
6083                     {
6084                         PRINTLN("couldn't open file");
6085- fs_open(file_index_html.name, &fsfile);
6086+ fs_open(file_404_html.name, &fsfile);
6087                     }
6088                 }
6089                 hs->script = 0;
6090@@ -141,7 +141,7 @@ httpd_appcall(void)
6091             if(hs->state == HTTP_FIRMWARE)
6092             {
6093                 unsigned char *start = (unsigned char*)uip_appdata;
6094- char *clen = strstr(start, "Content-Length:");
6095+ char *clen = strstr((char *)start, "Content-Length:");
6096                 int len = 0;
6097                 unsigned char *next, *end;
6098                 unsigned char *boundary_start;
6099@@ -150,14 +150,14 @@ httpd_appcall(void)
6100                 if(clen)
6101                 {
6102                     clen += sizeof("Content-Length:");
6103- next = strstr(clen, eol);
6104+ next = (unsigned char *)strstr(clen, eol);
6105                     if(next)
6106                     {
6107                         len = atoi(clen);
6108                         next++;
6109                         printf("expecting %d bytes\n", len);
6110                         upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
6111- printf("received data will be stored at 0x%08X\n", upload_data);
6112+ printf("received data will be stored at %p\n", upload_data);
6113                         if(!upload_data)
6114                         {
6115                             printf("failed to allocate memory\n");
6116@@ -174,14 +174,14 @@ httpd_appcall(void)
6117                     uip_close();
6118                     return;
6119                 }
6120- boundary_start = strstr(next, "---");
6121+ boundary_start = (unsigned char *)strstr((char *)next, "---");
6122                 if(!boundary_start)
6123                 {
6124                     uip_close();
6125                     return;
6126                 }
6127- end = strstr(boundary_start, eol);
6128- if(!eol)
6129+ end = (unsigned char *)strstr((char *)boundary_start, eol);
6130+ if(!end)
6131                 {
6132                     uip_close();
6133                     return;
6134@@ -189,13 +189,13 @@ httpd_appcall(void)
6135                 boundary_len = end - boundary_start;
6136                 memcpy(boundary, boundary_start, boundary_len);
6137                 boundary[boundary_len] = 0;
6138- next = strstr(boundary_start, "name=\"firmware\";");
6139+ next = (unsigned char *)strstr((char *)boundary_start, "name=\"firmware\";");
6140                 if(!next)
6141                 {
6142                     uip_close();
6143                     return;
6144                 }
6145- next = strstr(next, eol2);
6146+ next = (unsigned char *)strstr((char *)next, eol2);
6147                 if(!next)
6148                 {
6149                     printf("could not find start of data\n");
6150@@ -259,7 +259,6 @@ httpd_appcall(void)
6151                 {
6152                     if(upload_running)
6153                     {
6154- int i;
6155                         httpd_upload_complete = 1;
6156                     // for(i = 0; i < hs->upload_total; i++)
6157                     // printf("%c", httpd_upload_data[i]);
6158@@ -267,7 +266,7 @@ httpd_appcall(void)
6159                     uip_close();
6160                 }
6161             }
6162- uip_send(hs->dataptr, hs->count);
6163+ uip_send((unsigned char *)hs->dataptr, hs->count);
6164         }
6165         break;
6166 
6167

Archive Download this file



interactive