[lantiq] fix maintainer flag
[openwrt.git] / 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,8 @@ static __inline__ int abortboot(int boot
5651  
5652  void main_loop (void)
5653  {
5654 +       int ret;
5655 +
5656  #ifndef CONFIG_SYS_HUSH_PARSER
5657         static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
5658         int len;
5659 @@ -403,12 +407,22 @@ void main_loop (void)
5660  # endif
5661  
5662  # ifndef CONFIG_SYS_HUSH_PARSER
5663 -               run_command (s, 0);
5664 +               ret = run_command (s, 0);
5665  # else
5666 -               parse_string_outer(s, FLAG_PARSE_SEMICOLON |
5667 +               ret = parse_string_outer(s, FLAG_PARSE_SEMICOLON |
5668                                     FLAG_EXIT_FROM_LOOP);
5669  # endif
5670  
5671 +# ifdef CONFIG_CMD_HTTPD
5672 +               if (ret != 0) {
5673 +                       printf("Failed to execute bootcmd "
5674 +                                       "(maybe invalid u-boot environment?), "
5675 +                                       "starting httpd to update firmware...\n");
5676 +                       NetLoopHttpd();
5677 +               }
5678 +# endif
5679 +
5680 +
5681  # ifdef CONFIG_AUTOBOOT_KEYED
5682                 disable_ctrlc(prev);    /* restore Control C checking */
5683  # endif
5684 --- a/include/configs/easy50712.h
5685 +++ b/include/configs/easy50712.h
5686 @@ -114,4 +114,7 @@
5687  
5688  #define CONFIG_CMD_HTTPD               /* enable upgrade via HTTPD */
5689  
5690 +#define CONFIG_IPADDR          192.168.0.119
5691 +#define CONFIG_ETHADDR         00:01:02:03:04:05
5692 +
5693  #endif /* __CONFIG_H */
5694 --- a/lib_mips/time.c
5695 +++ b/lib_mips/time.c
5696 @@ -29,6 +29,8 @@ static unsigned long timestamp;
5697  /* how many counter cycles in a jiffy */
5698  #define CYCLES_PER_JIFFY       (CONFIG_SYS_MIPS_TIMER_FREQ + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ
5699  
5700 +unsigned long ifx_get_cpuclk(void);
5701 +
5702  /*
5703   * timer without interrupts
5704   */
5705 --- a/net/httpd.c
5706 +++ b/net/httpd.c
5707 @@ -35,12 +35,14 @@ HttpdHandler (void)
5708         }
5709  }
5710  
5711 +#if 0
5712  static void
5713  HttpdTimeout (void)
5714  {
5715         puts ("T ");
5716         NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
5717  }
5718 +#endif
5719  
5720  void
5721  HttpdStart (void)
5722 --- a/net/net.c
5723 +++ b/net/net.c
5724 @@ -1966,7 +1966,7 @@ NetSendHttpd(void)
5725  void
5726  NetReceiveHttpd(volatile uchar * inpkt, int len)
5727  {
5728 -       memcpy(uip_buf, inpkt, len);
5729 +       memcpy(uip_buf, (const void *)inpkt, len);
5730         uip_len = len;
5731         if(BUF->type == htons(UIP_ETHTYPE_IP)) {
5732                 uip_arp_ipin();
5733 @@ -1989,6 +1989,7 @@ NetLoopHttpd(void)
5734         unsigned long long tout = 0;
5735         bd_t *bd = gd->bd;
5736         unsigned short int ip[2];
5737 +       struct uip_eth_addr eaddr;
5738  
5739  #ifdef CONFIG_NET_MULTI
5740         NetRestarted = 0;
5741 @@ -2039,6 +2040,15 @@ restart:
5742         eth_getenv_enetaddr("ethaddr", NetOurEther);
5743  #endif
5744  
5745 +       eaddr.addr[0] = NetOurEther[0];
5746 +       eaddr.addr[1] = NetOurEther[1];
5747 +       eaddr.addr[2] = NetOurEther[2];
5748 +       eaddr.addr[3] = NetOurEther[3];
5749 +       eaddr.addr[4] = NetOurEther[4];
5750 +       eaddr.addr[5] = NetOurEther[5];
5751 +
5752 +       uip_setethaddr(eaddr);
5753 +
5754         NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
5755         NetOurGatewayIP = getenv_IPaddr ("gatewayip");
5756         NetOurSubnetMask= getenv_IPaddr ("netmask");
5757 @@ -2072,6 +2082,14 @@ restart:
5758                                 tout = t1;
5759                         }
5760                 }
5761 +
5762 +               if (ctrlc()) {
5763 +                       eth_halt();
5764 +                       puts ("\nAbort\n");
5765 +                       return (-1);
5766 +               }
5767 +
5768 +
5769                 if(!httpd_upload_complete)
5770                         continue;
5771                 printf("Bytes transferred = %ld (%lx hex)\n",
5772 --- a/net/uip-0.9/fsdata.c
5773 +++ b/net/uip-0.9/fsdata.c
5774 @@ -1,199 +1,108 @@
5775 -static const char data_flashing_html[] = {
5776 -       /* /flashing.html */
5777 -       0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5778 -       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
5779 -       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
5780 -       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
5781 -       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
5782 -       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
5783 -       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
5784 -       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
5785 -       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
5786 -       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
5787 -       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 
5788 -       0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 
5789 -       0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30, 
5790 -       0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68, 
5791 -       0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 
5792 -       0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 
5793 -       0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 
5794 -       0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 
5795 -       0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34, 
5796 -       0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 
5797 -       0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61, 
5798 -       0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 
5799 -       0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31, 
5800 -       0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 
5801 -       0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 
5802 -       0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5803 -
5804 -static const char data_fail_html[] = {
5805 -       /* /fail.html */
5806 -       0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5807 -       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
5808 -       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
5809 -       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
5810 -       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
5811 -       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
5812 -       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
5813 -       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
5814 -       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
5815 -       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
5816 -       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9, 
5817 -       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c, 
5818 -       0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9, 
5819 -       0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46, 
5820 -       0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49, 
5821 -       0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 
5822 -       0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 
5823 -       0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 
5824 -       0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 
5825 -       0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45, 
5826 -       0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65, 
5827 -       0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75, 
5828 -       0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 
5829 -       0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 
5830 -       0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66, 
5831 -       0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50, 
5832 -       0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65, 
5833 -       0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75, 
5834 -       0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69, 
5835 -       0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 
5836 -       0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 
5837 -       0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
5838 -       0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 
5839 -       0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e, 
5840 -       0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 
5841 -       0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 
5842 -       0x3e, 0xa, };
5843 -
5844 -static const char data_404_html[] = {
5845 -       /* /404.html */
5846 -       0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5847 -       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 
5848 -       0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 
5849 -       0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 
5850 -       0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 
5851 -       0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 
5852 -       0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 
5853 -       0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 
5854 -       0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 
5855 -       0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 
5856 -       0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 
5857 -       0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 
5858 -       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 
5859 -       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 
5860 -       0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 
5861 -       0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20, 
5862 -       0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 
5863 -       0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 
5864 -       0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f, 
5865 -       0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 
5866 -       0x6c, 0x3e, };
5867 -
5868 -static const char data_index_html[] = {
5869 -       /* /index.html */
5870 -       0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5871 -       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
5872 -       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
5873 -       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
5874 -       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
5875 -       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
5876 -       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
5877 -       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
5878 -       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
5879 -       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
5880 -       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9, 
5881 -       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c, 
5882 -       0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9, 
5883 -       0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46, 
5884 -       0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49, 
5885 -       0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 
5886 -       0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 
5887 -       0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 
5888 -       0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 
5889 -       0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 
5890 -       0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 
5891 -       0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 
5892 -       0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62, 
5893 -       0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 
5894 -       0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 
5895 -       0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9, 
5896 -       0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 
5897 -       0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 
5898 -       0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 
5899 -       0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 
5900 -       0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, 
5901 -       0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d, 
5902 -       0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 
5903 -       0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 
5904 -       0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70, 
5905 -       0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69, 
5906 -       0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69, 
5907 -       0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9, 
5908 -       0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 
5909 -       0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e, 
5910 -       0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 
5911 -       0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 
5912 -       0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5913 -
5914 -static const char data_flash_html[] = {
5915 -       /* /flash.html */
5916 -       0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5917 -       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
5918 -       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
5919 -       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
5920 -       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
5921 -       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
5922 -       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
5923 -       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
5924 -       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
5925 -       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
5926 -       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9, 
5927 -       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c, 
5928 -       0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9, 
5929 -       0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46, 
5930 -       0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49, 
5931 -       0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 
5932 -       0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 
5933 -       0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 
5934 -       0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 
5935 -       0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 
5936 -       0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 
5937 -       0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 
5938 -       0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62, 
5939 -       0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 
5940 -       0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 
5941 -       0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9, 
5942 -       0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69, 
5943 -       0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 
5944 -       0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 
5945 -       0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72, 
5946 -       0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c, 
5947 -       0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 
5948 -       0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70, 
5949 -       0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68, 
5950 -       0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c, 
5951 -       0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f, 
5952 -       0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9, 
5953 -       0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73, 
5954 -       0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c, 
5955 -       0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 
5956 -       0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c, 
5957 -       0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c, 
5958 -       0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 
5959 -       0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5960 -
5961 -const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
5962 +static const char data_flashing_html[] =
5963 +"HTTP/1.0 200 OK\n"
5964 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
5965 +"Content-type: text/html\n"
5966 +"\n"
5967 +"<html>\n"
5968 +"\t<head>\n"
5969 +"\t\t<title>\n"
5970 +"\t\t\tFailsafe UI\n"
5971 +"\t\t</title>\n"
5972 +"\t</head>\n"
5973 +"\t<body>\n"
5974 +"\t\t<center><h1>Upgrading system...</h1></center>\n"
5975 +"\t</body>\n"
5976 +"</html>\n";
5977 +
5978 +static const char data_fail_html[] =
5979 +"HTTP/1.0 200 OK\n"
5980 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
5981 +"Content-type: text/html\n"
5982 +"\n"
5983 +"<html>\n"
5984 +"\t<head>\n"
5985 +"\t\t<title>\n"
5986 +"\t\t\tFailsafe UI\n"
5987 +"\t\t</title>\n"
5988 +"\t</head>\n"
5989 +"\t<body>\n"
5990 +"\t\t<h1>Flashing failed</h1>\n"
5991 +"\t\tERROR - the image you uploaded failed to pass verification.<br>\n"
5992 +"\t\tPlease make sure to use an official update provided by http://lantiq.com/\n"
5993 +"\t</body>\n"
5994 +"</html>\n";
5995 +
5996 +static const char data_404_html[] =
5997 +"HTTP/1.0 404 File not found\n"
5998 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
5999 +"Content-type: text/html\n"
6000 +"\n"
6001 +"<html>\n"
6002 +"\t<head>\n"
6003 +"\t\t<title>\n"
6004 +"\t\t\tFailsafe UI\n"
6005 +"\t\t</title>\n"
6006 +"\t</head>\n"
6007 +"\t<body>\n"
6008 +"\t\t<center><h1>404 - file not found</h1></center>\n"
6009 +"\t</body>\n"
6010 +"</html>\n";
6011 +
6012 +static const char data_index_html[] =
6013 +"HTTP/1.0 200 OK\n"
6014 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
6015 +"Content-type: text/html\n"
6016 +"\n"
6017 +"<html>\n"
6018 +"\t<head>\n"
6019 +"\t\t<title>\n"
6020 +"\t\t\tFailsafe UI\n"
6021 +"\t\t</title>\n"
6022 +"\t</head>\n"
6023 +"\t<body>\n"
6024 +"\t\t<h1>Failsafe UI</h1>\n"
6025 +"\t\t<form method=\"post\" enctype=\"multipart/form-data\">\n"
6026 +"\t\t\t<input type=file name=firmware>\n"
6027 +"\t\t\t<input type=submit>\n"
6028 +"\t\t</form>\n"
6029 +"\t</body>\n"
6030 +"</html>\n";
6031 +
6032 +static const char data_flash_html[] =
6033 +"HTTP/1.0 200 OK\n"
6034 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
6035 +"Content-type: text/html\n"
6036 +"\n"
6037 +"<html>\n"
6038 +"\t<head>\n"
6039 +"\t\t<title>\n"
6040 +"\t\t\tFailsafe UI\n"
6041 +"\t\t</title>\n"
6042 +"\t</head>\n"
6043 +"\t<body>\n"
6044 +"\t\t<h1>Flashing...</h1>\n"
6045 +"\t\tThe system is now trying to flash. If there is a problem, the LEDs will "
6046 +"start to blink.<br>\n"
6047 +"\n"
6048 +"\t\tAfter a successful update the box will reboot\n"
6049 +"\t</body>\n"
6050 +"</html>\n";
6051 +
6052 +const struct fsdata_file file_flashing_html[] =
6053 +{{NULL, "/flashing.html", data_flashing_html, sizeof(data_flashing_html)}};
6054 +
6055 +const struct fsdata_file file_fail_html[] =
6056 +{{file_flashing_html, "/fail.html", data_fail_html, sizeof(data_fail_html)}};
6057  
6058 -const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
6059 +const struct fsdata_file file_404_html[] =
6060 +{{file_fail_html, "/404.html", data_404_html, sizeof(data_404_html)}};
6061  
6062 -const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
6063 +const struct fsdata_file file_index_html[] =
6064 +{{file_404_html, "/index.html", data_index_html, sizeof(data_index_html)}};
6065  
6066 -const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
6067 -
6068 -const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
6069 +const struct fsdata_file file_flash_html[] =
6070 +{{file_index_html, "/flash.html", data_flash_html, sizeof(data_flash_html)}};
6071  
6072  #define FS_ROOT file_flash_html
6073  
6074 -#define FS_NUMFILES 5
6075 \ No newline at end of file
6076 +#define FS_NUMFILES 5
6077 --- a/net/uip-0.9/httpd.c
6078 +++ b/net/uip-0.9/httpd.c
6079 @@ -130,7 +130,7 @@ httpd_appcall(void)
6080                                         if(!fs_open((const char *)&uip_appdata[4], &fsfile))
6081                                         {
6082                                                 PRINTLN("couldn't open file");
6083 -                                               fs_open(file_index_html.name, &fsfile);
6084 +                                               fs_open(file_404_html.name, &fsfile);
6085                                         }
6086                                 }
6087                                 hs->script = 0;
6088 @@ -141,7 +141,7 @@ httpd_appcall(void)
6089                         if(hs->state == HTTP_FIRMWARE)
6090                         {
6091                                 unsigned char *start = (unsigned char*)uip_appdata;
6092 -                               char *clen = strstr(start, "Content-Length:");
6093 +                               char *clen = strstr((char *)start, "Content-Length:");
6094                                 int len = 0;
6095                                 unsigned char *next, *end;
6096                                 unsigned char *boundary_start;
6097 @@ -150,14 +150,14 @@ httpd_appcall(void)
6098                                 if(clen)
6099                                 {
6100                                         clen += sizeof("Content-Length:");
6101 -                                       next = strstr(clen, eol);
6102 +                                       next = (unsigned char *)strstr(clen, eol);
6103                                         if(next)
6104                                         {
6105                                                 len = atoi(clen);
6106                                                 next++;
6107                                                 printf("expecting %d bytes\n", len);
6108                                                 upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
6109 -                                               printf("received data will be stored at 0x%08X\n", upload_data);
6110 +                                               printf("received data will be stored at %p\n", upload_data);
6111                                                 if(!upload_data)
6112                                                 {
6113                                                         printf("failed to allocate memory\n");
6114 @@ -174,14 +174,14 @@ httpd_appcall(void)
6115                                         uip_close();
6116                                         return;
6117                                 }
6118 -                               boundary_start = strstr(next, "---");
6119 +                               boundary_start = (unsigned char *)strstr((char *)next, "---");
6120                                 if(!boundary_start)
6121                                 {
6122                                         uip_close();
6123                                         return;
6124                                 }
6125 -                               end = strstr(boundary_start, eol);
6126 -                               if(!eol)
6127 +                               end = (unsigned char *)strstr((char *)boundary_start, eol);
6128 +                               if(!end)
6129                                 {
6130                                         uip_close();
6131                                         return;
6132 @@ -189,13 +189,13 @@ httpd_appcall(void)
6133                                 boundary_len = end - boundary_start;
6134                                 memcpy(boundary, boundary_start, boundary_len);
6135                                 boundary[boundary_len] = 0;
6136 -                               next = strstr(boundary_start, "name=\"firmware\";");
6137 +                               next = (unsigned char *)strstr((char *)boundary_start, "name=\"firmware\";");
6138                                 if(!next)
6139                                 {
6140                                         uip_close();
6141                                         return;
6142                                 }
6143 -                               next = strstr(next, eol2);
6144 +                               next = (unsigned char *)strstr((char *)next, eol2);
6145                                 if(!next)
6146                                 {
6147                                         printf("could not find start of data\n");
6148 @@ -259,7 +259,6 @@ httpd_appcall(void)
6149                                 {
6150                                         if(upload_running)
6151                                         {
6152 -                                               int i;
6153                                                 httpd_upload_complete = 1;
6154                                         //      for(i = 0; i < hs->upload_total; i++)
6155                                         //              printf("%c", httpd_upload_data[i]);
6156 @@ -267,7 +266,7 @@ httpd_appcall(void)
6157                                         uip_close();
6158                                 }
6159                         }
6160 -                       uip_send(hs->dataptr, hs->count);
6161 +                       uip_send((unsigned char *)hs->dataptr, hs->count);
6162                 }
6163                 break;
6164