3 @@ -43,6 +43,18 @@ U_BOOT_CMD(
4 "[loadAddress] [[hostIPaddr:]bootfilename]"
7 +#if defined(CONFIG_CMD_HTTPD)
8 +int do_httpd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
10 + return NetLoopHttpd();
14 + httpd, 1, 1, do_httpd,
15 + "httpd\t- start webserver", ""
19 int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
21 return netboot_common (TFTP, cmdtp, argc, argv);
25 +#ifndef _UIP_HTTPD_H__
26 +#define _UIP_HTTPD_H__
28 +void HttpdStart (void);
29 +void HttpdHandler (void);
31 +/* board specific implementation */
32 +extern int do_http_upgrade(const unsigned char *data, const ulong size);
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);
44 @@ -383,7 +383,8 @@ extern int NetTimeOffset; /* offset ti
46 /* Initialize the network adapter */
47 extern int NetLoop(proto_t);
49 +extern int NetLoopHttpd(void);
50 +extern void NetSendHttpd(void);
51 /* Shutdown adapters and cleanup */
52 extern void NetStop(void);
56 @@ -26,6 +26,8 @@ include $(TOPDIR)/config.mk
61 +$(shell mkdir -p $(obj)$(UIPDIR))
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
69 +COBJS-$(CONFIG_CMD_HTTPD) += httpd.o $(UIPDIR)/fs.o $(UIPDIR)/httpd.o $(UIPDIR)/uip_arp.o $(UIPDIR)/uip_arch.o $(UIPDIR)/uip.o
72 SRCS := $(COBJS:.o=.c)
73 OBJS := $(addprefix $(obj),$(COBJS))
78 + * Copyright 1994, 1995, 2000 Neil Russell.
80 + * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
86 +#include "uip-0.9/uipopt.h"
87 +#include "uip-0.9/uip.h"
88 +#include "uip-0.9/uip_arp.h"
91 +#if defined(CONFIG_CMD_HTTPD)
95 +static int arptimer = 0;
101 + for(i = 0; i < UIP_CONNS; i++) {
108 + if(++arptimer == 20) {
118 + NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
132 #if defined(CONFIG_CMD_DNS)
135 +#if defined(CONFIG_CMD_HTTPD)
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[]);
149 DECLARE_GLOBAL_DATA_PTR;
151 @@ -1308,6 +1321,13 @@ NetReceive(volatile uchar * inpkt, int l
153 debug("packet received\n");
155 +#if defined(CONFIG_CMD_HTTPD)
156 + if(https_running) {
157 + NetReceiveHttpd(inpkt, len);
163 NetRxPacketLen = len;
164 et = (Ethernet_t *)inpkt;
165 @@ -1922,3 +1942,162 @@ ushort getenv_VLAN(char *var)
167 return (string_to_VLAN(getenv(var)));
170 +#if defined(CONFIG_CMD_HTTPD)
175 + volatile uchar *tmpbuf = NetTxPacket;
178 + for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
179 + tmpbuf[i] = uip_buf[i];
182 + for(; i < uip_len; i++) {
183 + tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
185 + eth_send(NetTxPacket, uip_len);
188 +#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
191 +NetReceiveHttpd(volatile uchar * inpkt, int len)
193 + memcpy(uip_buf, inpkt, len);
195 + if(BUF->type == htons(UIP_ETHTYPE_IP)) {
202 + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
213 + unsigned long long tout = 0;
215 + unsigned short int ip[2];
217 +#ifdef CONFIG_NET_MULTI
222 + /* XXX problem with bss workaround */
223 + NetArpWaitPacketMAC = NULL;
224 + NetArpWaitTxPacket = NULL;
225 + NetArpWaitPacketIP = 0;
226 + NetArpWaitReplyIP = 0;
227 + NetArpWaitTxPacket = NULL;
228 + NetTxPacket = NULL;
231 + if (!NetTxPacket) {
234 + * Setup packet buffers, aligned correctly.
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;
243 + if (!NetArpWaitTxPacket) {
244 + NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
245 + NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
246 + NetArpWaitTxPacketSize = 0;
252 +#ifdef CONFIG_NET_MULTI
255 + if (eth_init(bd) < 0) {
260 +#ifdef CONFIG_NET_MULTI
261 + memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);
263 + eth_getenv_enetaddr("ethaddr", NetOurEther);
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");
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));
280 + ip[0] = ((bd->bi_ip_addr & 0xffff0000) >> 16);
281 + ip[1] = (bd->bi_ip_addr & 0x0000ffff);
282 + uip_sethostaddr(ip);
284 + do_http_progress(HTTP_PROGRESS_START);
288 + unsigned long long t1;
294 + if(t1 - tout > 1000) {
295 + do_http_progress(HTTP_PROGRESS_TIMEOUT);
299 + if(!httpd_upload_complete)
301 + printf("Bytes transferred = %ld (%lx hex)\n",
302 + NetBootFileXferSize,
303 + NetBootFileXferSize);
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);
309 + do_reset (0,0,0,0);
315 + NetBootFileXferSize = 0;
316 + httpd_upload_complete = 0;
317 + upload_running = 0;
318 +// free(httpd_upload_data);
320 + do_http_progress(HTTP_PROGRESS_UGRADE_FAILED);
329 +++ b/net/uip-0.9/Makefile
331 +# Copyright (c) 2001, Adam Dunkels.
332 +# All rights reserved.
334 +# Redistribution and use in source and binary forms, with or without
335 +# modification, are permitted provided that the following conditions
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.
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.
361 +# This file is part of the uIP TCP/IP stack.
363 +# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $
367 +CFLAGS=-Wall -fpack-struct -DDUMP=0
371 +uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o
372 + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
375 + $(CC) $(CFLAGS) -c $^ -o $@
378 + rm -f *.o *~ *core uip
386 +++ b/net/uip-0.9/fs.c
389 + * \addtogroup httpd
395 + * HTTP server read-only file system code.
396 + * \author Adam Dunkels <adam@dunkels.com>
398 + * A simple read-only filesystem.
402 + * Copyright (c) 2001, Swedish Institute of Computer Science.
403 + * All rights reserved.
405 + * Redistribution and use in source and binary forms, with or without
406 + * modification, are permitted provided that the following conditions
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.
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
429 + * This file is part of the lwIP TCP/IP stack.
431 + * Author: Adam Dunkels <adam@sics.se>
433 + * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $
443 +#ifdef FS_STATISTICS
444 +#if FS_STATISTICS == 1
445 +static u16_t count[FS_NUMFILES];
446 +#endif /* FS_STATISTICS */
447 +#endif /* FS_STATISTICS */
449 +/*-----------------------------------------------------------------------------------*/
451 +fs_strcmp(const char *str1, const char *str2)
463 + if(str1[i] != str2[i]) {
471 +/*-----------------------------------------------------------------------------------*/
473 +fs_open(const char *name, struct fs_file *file)
475 +#ifdef FS_STATISTICS
476 +#if FS_STATISTICS == 1
478 +#endif /* FS_STATISTICS */
479 +#endif /* FS_STATISTICS */
480 + struct fsdata_file_noconst *f;
482 + for(f = (struct fsdata_file_noconst *)FS_ROOT;
484 + f = (struct fsdata_file_noconst *)f->next) {
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
492 +#endif /* FS_STATISTICS */
493 +#endif /* FS_STATISTICS */
496 +#ifdef FS_STATISTICS
497 +#if FS_STATISTICS == 1
499 +#endif /* FS_STATISTICS */
500 +#endif /* FS_STATISTICS */
505 +/*-----------------------------------------------------------------------------------*/
509 +#ifdef FS_STATISTICS
510 +#if FS_STATISTICS == 1
512 + for(i = 0; i < FS_NUMFILES; i++) {
515 +#endif /* FS_STATISTICS */
516 +#endif /* FS_STATISTICS */
518 +/*-----------------------------------------------------------------------------------*/
519 +#ifdef FS_STATISTICS
520 +#if FS_STATISTICS == 1
524 + struct fsdata_file_noconst *f;
528 + for(f = (struct fsdata_file_noconst *)FS_ROOT;
530 + f = (struct fsdata_file_noconst *)f->next) {
532 + if(fs_strcmp(name, f->name) == 0) {
539 +#endif /* FS_STATISTICS */
540 +#endif /* FS_STATISTICS */
541 +/*-----------------------------------------------------------------------------------*/
543 +++ b/net/uip-0.9/fs.h
546 + * \addtogroup httpd
552 + * HTTP server read-only file system header file.
553 + * \author Adam Dunkels <adam@dunkels.com>
557 + * Copyright (c) 2001, Swedish Institute of Computer Science.
558 + * All rights reserved.
560 + * Redistribution and use in source and binary forms, with or without
561 + * modification, are permitted provided that the following conditions
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.
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
584 + * This file is part of the lwIP TCP/IP stack.
586 + * Author: Adam Dunkels <adam@sics.se>
588 + * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $
596 + * An open file in the read-only file system.
599 + char *data; /**< The actual file data. */
600 + int len; /**< The length of the file data. */
604 + * Open a file in the read-only file system.
606 + * \param name The name of the file.
608 + * \param file The file pointer, which must be allocated by caller and
609 + * will be filled in by the function.
611 +int fs_open(const char *name, struct fs_file *file);
613 +#ifdef FS_STATISTICS
614 +#if FS_STATISTICS == 1
615 +u16_t fs_count(char *name);
616 +#endif /* FS_STATISTICS */
617 +#endif /* FS_STATISTICS */
620 + * Initialize the read-only file system.
624 +#endif /* __FS_H__ */
626 +++ b/net/uip-0.9/fsdata.c
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, };
657 +static const char data_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,
697 +static const char data_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,
721 +static const char data_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, };
767 +static const char data_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, };
814 +const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
816 +const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
818 +const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
820 +const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
822 +const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
824 +#define FS_ROOT file_flash_html
826 +#define FS_NUMFILES 5
827 \ No newline at end of file
829 +++ b/net/uip-0.9/fsdata.h
832 + * Copyright (c) 2001, Swedish Institute of Computer Science.
833 + * All rights reserved.
835 + * Redistribution and use in source and binary forms, with or without
836 + * modification, are permitted provided that the following conditions
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.
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
859 + * This file is part of the lwIP TCP/IP stack.
861 + * Author: Adam Dunkels <adam@sics.se>
863 + * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $
865 +#ifndef __FSDATA_H__
866 +#define __FSDATA_H__
870 +struct fsdata_file {
871 + const struct fsdata_file *next;
875 +#ifdef FS_STATISTICS
876 +#if FS_STATISTICS == 1
878 +#endif /* FS_STATISTICS */
879 +#endif /* FS_STATISTICS */
882 +struct fsdata_file_noconst {
883 + struct fsdata_file *next;
887 +#ifdef FS_STATISTICS
888 +#if FS_STATISTICS == 1
890 +#endif /* FS_STATISTICS */
891 +#endif /* FS_STATISTICS */
894 +#endif /* __FSDATA_H__ */
896 +++ b/net/uip-0.9/httpd.c
902 +#include <asm/addrspace.h>
906 +#define HTTP_FIRMWARE 2
908 +#define PRINT(x) printf("%s", x)
909 +#define PRINTLN(x) printf("%s\n", x)
911 +extern unsigned long do_http_tmp_address(void);
913 +struct httpd_state *hs;
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;
931 +#define ISO_slash 0x2f
935 +#define ISO_space 0x20
940 +#define ISO_hash 0x23
941 +#define ISO_period 0x2e
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;
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)
954 + while (is_digit(*s))
955 + i = i*10 + *(s++) - '0';
963 + uip_listen(HTONS(80));
969 + struct fs_file fsfile;
971 + switch(uip_conn->lport) {
973 + hs = (struct httpd_state *)(uip_conn->appstate);
974 + if(uip_connected())
976 + hs->state = HTTP_NONE;
979 + } else if(uip_poll())
981 + if(hs->count++ >= 1000) {
985 + } else if(uip_newdata() && hs->state == HTTP_NONE)
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)
992 + hs->state = HTTP_FILE;
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)
1000 + hs->state = HTTP_FIRMWARE;
1002 + if(hs->state == HTTP_NONE)
1007 + if(hs->state == HTTP_FILE)
1009 + for(i = 4; i < 40; ++i)
1011 + if(uip_appdata[i] == ISO_space ||
1012 + uip_appdata[i] == ISO_cr ||
1013 + uip_appdata[i] == ISO_nl)
1015 + uip_appdata[i] = 0;
1020 + PRINT("request for file ");
1021 + PRINTLN(&uip_appdata[4]);
1022 + if(uip_appdata[4] == ISO_slash &&
1023 + uip_appdata[5] == 0)
1025 + fs_open(file_index_html.name, &fsfile);
1027 + if(!fs_open((const char *)&uip_appdata[4], &fsfile))
1029 + PRINTLN("couldn't open file");
1030 + fs_open(file_index_html.name, &fsfile);
1034 + hs->state = HTTP_FILE;
1035 + hs->dataptr = fsfile.data;
1036 + hs->count = fsfile.len;
1038 + if(hs->state == HTTP_FIRMWARE)
1040 + unsigned char *start = (unsigned char*)uip_appdata;
1041 + char *clen = strstr(start, "Content-Length:");
1043 + unsigned char *next, *end;
1044 + unsigned char *boundary_start;
1046 + uip_appdata[uip_len] = '\0';
1049 + clen += sizeof("Content-Length:");
1050 + next = strstr(clen, eol);
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);
1060 + printf("failed to allocate memory\n");
1069 + if(len < 4 * 1024)
1074 + boundary_start = strstr(next, "---");
1075 + if(!boundary_start)
1080 + end = strstr(boundary_start, eol);
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\";");
1095 + next = strstr(next, eol2);
1098 + printf("could not find start of data\n");
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);
1118 + if(hs->state == HTTP_FIRMWARE)
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;
1132 + if(hs->upload >= hs->upload_total)
1134 + upload_running = 1;
1135 + NetBootFileXferSize = hs->upload_total;
1136 + fs_open(file_flash_html.name, &fsfile);
1138 + hs->state = HTTP_FILE;
1139 + hs->dataptr = fsfile.data;
1140 + hs->count = fsfile.len;
1144 + if(hs->state == HTTP_FILE)
1148 + if(hs->count >= uip_conn->len)
1150 + hs->count -= uip_conn->len;
1151 + hs->dataptr += uip_conn->len;
1155 + if(hs->count == 0)
1157 + if(upload_running)
1160 + httpd_upload_complete = 1;
1161 + // for(i = 0; i < hs->upload_total; i++)
1162 + // printf("%c", httpd_upload_data[i]);
1167 + uip_send(hs->dataptr, hs->count);
1177 +++ b/net/uip-0.9/httpd.h
1180 + * \addtogroup httpd
1186 + * HTTP server header file.
1187 + * \author Adam Dunkels <adam@dunkels.com>
1191 + * Copyright (c) 2001, Adam Dunkels.
1192 + * All rights reserved.
1194 + * Redistribution and use in source and binary forms, with or without
1195 + * modification, are permitted provided that the following conditions
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.
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.
1218 + * This file is part of the uIP TCP/IP stack.
1220 + * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $
1224 +#ifndef __HTTPD_H__
1225 +#define __HTTPD_H__
1227 +void httpd_init(void);
1228 +void httpd_appcall(void);
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
1237 +struct httpd_state {
1242 + unsigned int upload;
1243 + unsigned int upload_total;
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))
1253 +#define FS_STATISTICS 1
1255 +extern struct httpd_state *hs;
1258 +/* we copy the data to RAM+10MB */
1259 +#define TMP_DATA 0x8A100000
1261 +#endif /* __HTTPD_H__ */
1263 +++ b/net/uip-0.9/main.c
1266 + * Copyright (c) 2001-2003, Adam Dunkels.
1267 + * All rights reserved.
1269 + * Redistribution and use in source and binary forms, with or without
1270 + * modification, are permitted provided that the following conditions
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.
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.
1293 + * This file is part of the uIP TCP/IP stack.
1295 + * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $
1301 +#include "uip_arp.h"
1302 +#include "tapdev.h"
1305 +#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
1308 +#define NULL (void *)0
1311 +/*-----------------------------------------------------------------------------------*/
1321 + uip_len = tapdev_read();
1322 + if(uip_len == 0) {
1323 + for(i = 0; i < UIP_CONNS; i++) {
1331 + if(++arptimer == 20) {
1336 + if(BUF->type == htons(UIP_ETHTYPE_IP)) {
1343 + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
1354 +++ b/net/uip-0.9/tapdev.c
1357 + * Copyright (c) 2001, Swedish Institute of Computer Science.
1358 + * All rights reserved.
1360 + * Redistribution and use in source and binary forms, with or without
1361 + * modification, are permitted provided that the following conditions
1364 + * 1. Redistributions of source code must retain the above copyright
1365 + * notice, this list of conditions and the following disclaimer.
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.
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.
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
1387 + * Author: Adam Dunkels <adam@sics.se>
1389 + * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $
1394 +#include <stdlib.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>
1406 +#include <sys/ioctl.h>
1407 +#include <linux/if.h>
1408 +#include <linux/if_tun.h>
1409 +#define DEVTAP "/dev/net/tun"
1411 +#define DEVTAP "/dev/tap0"
1418 +static unsigned long lasttime;
1419 +static struct timezone tz;
1421 +/*-----------------------------------------------------------------------------------*/
1427 + fd = open(DEVTAP, O_RDWR);
1429 + perror("tapdev: tapdev_init: open");
1436 + memset(&ifr, 0, sizeof(ifr));
1437 + ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
1438 + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
1445 + snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
1446 + UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);
1452 +void dump_mem(int type, int len)
1456 + for(i = 0; i < len; i++)
1457 + printf("%c", uip_buf[i]);
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");
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");
1470 +/*-----------------------------------------------------------------------------------*/
1475 + struct timeval tv, now;
1478 + if(lasttime >= 500000) {
1484 + tv.tv_usec = 500000 - lasttime;
1488 + FD_SET(fd, &fdset);
1490 + gettimeofday(&now, &tz);
1491 + ret = select(fd + 1, &fdset, NULL, NULL, &tv);
1496 + ret = read(fd, uip_buf, UIP_BUFSIZE);
1498 + perror("tap_dev: tapdev_read: read");
1500 + gettimeofday(&tv, &tz);
1501 + lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
1505 +/*-----------------------------------------------------------------------------------*/
1510 + struct iovec iov[2];
1514 + char tmpbuf[UIP_BUFSIZE];
1517 + for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
1518 + tmpbuf[i] = uip_buf[i];
1521 + for(; i < uip_len; i++) {
1522 + tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
1525 + ret = write(fd, tmpbuf, uip_len);
1529 + if(uip_len < 40 + UIP_LLH_LEN) {
1530 + ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN);
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);
1537 + ret = writev(fd, iov, 2);
1543 + perror("tap_dev: tapdev_send: writev");
1547 +/*-----------------------------------------------------------------------------------*/
1549 +++ b/net/uip-0.9/tapdev.h
1552 + * Copyright (c) 2001, Adam Dunkels.
1553 + * All rights reserved.
1555 + * Redistribution and use in source and binary forms, with or without
1556 + * modification, are permitted provided that the following conditions
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.
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.
1579 + * This file is part of the uIP TCP/IP stack.
1581 + * $Id: tapdev.h,v 1.1.2.1 2003/10/04 22:54:17 adam Exp $
1585 +#ifndef __TAPDEV_H__
1586 +#define __TAPDEV_H__
1588 +void tapdev_init(void);
1589 +unsigned int tapdev_read(void);
1590 +void tapdev_send(void);
1592 +#endif /* __TAPDEV_H__ */
1594 +++ b/net/uip-0.9/uip.c
1603 + * The uIP TCP/IP stack code.
1604 + * \author Adam Dunkels <adam@dunkels.com>
1608 + * Copyright (c) 2001-2003, Adam Dunkels.
1609 + * All rights reserved.
1611 + * Redistribution and use in source and binary forms, with or without
1612 + * modification, are permitted provided that the following conditions
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.
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.
1635 + * This file is part of the uIP TCP/IP stack.
1637 + * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
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.
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.
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.
1662 +#include "uipopt.h"
1663 +#include "uip_arch.h"
1665 +/*-----------------------------------------------------------------------------------*/
1666 +/* Variable definitions. */
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)};
1681 +unsigned short int uip_hostaddr[2];
1682 +unsigned short int uip_arp_draddr[2], uip_arp_netmask[2];
1683 +#endif /* UIP_FIXEDADDR */
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
1695 +volatile u8_t uip_urglen, uip_surglen;
1696 +#endif /* UIP_URGDATA > 0 */
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
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
1709 +struct uip_conn uip_conns[UIP_CONNS];
1710 + /* The uip_conns array holds all TCP
1712 +unsigned short int uip_listenports[UIP_LISTENPORTS];
1713 + /* The uip_listenports list all currently
1714 + listning ports. */
1716 +struct uip_udp_conn *uip_udp_conn;
1717 +struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
1718 +#endif /* UIP_UDP */
1721 +static unsigned short int ipid; /* Ths ipid variable is an increasing
1722 + number that is used for the IP ID
1725 +static u8_t iss[4]; /* The iss variable is used for the TCP
1726 + initial sequence number. */
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 */
1733 +/* Temporary variables. */
1734 +volatile u8_t uip_acc32[4];
1735 +static u8_t c, opt;
1736 +static unsigned short int tmp16;
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
1747 +#define ICMP_ECHO_REPLY 0
1748 +#define ICMP_ECHO 8
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])
1756 +#if UIP_STATISTICS == 1
1757 +struct uip_stats uip_stat;
1758 +#define UIP_STAT(s) s
1760 +#define UIP_STAT(s)
1761 +#endif /* UIP_STATISTICS == 1 */
1763 +#if UIP_LOGGING == 1
1764 +extern void puts(const char *s);
1765 +#define UIP_LOG(m) puts(m)
1768 +#endif /* UIP_LOGGING == 1 */
1770 +/*-----------------------------------------------------------------------------------*/
1774 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
1775 + uip_listenports[c] = 0;
1777 + for(c = 0; c < UIP_CONNS; ++c) {
1778 + uip_conns[c].tcpstateflags = CLOSED;
1780 +#if UIP_ACTIVE_OPEN
1782 +#endif /* UIP_ACTIVE_OPEN */
1785 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
1786 + uip_udp_conns[c].lport = 0;
1788 +#endif /* UIP_UDP */
1791 + /* IPv4 initialization. */
1792 +#if UIP_FIXEDADDR == 0
1793 + uip_hostaddr[0] = uip_hostaddr[1] = 0;
1794 +#endif /* UIP_FIXEDADDR */
1797 +/*-----------------------------------------------------------------------------------*/
1798 +#if UIP_ACTIVE_OPEN
1800 +uip_connect(unsigned short int *ripaddr, unsigned short int rport)
1802 + register struct uip_conn *conn, *cconn;
1804 + /* Find an unused local port. */
1808 + if(lastport >= 32000) {
1812 + /* Check if this port is already in use, and if so try to find
1814 + for(c = 0; c < UIP_CONNS; ++c) {
1815 + conn = &uip_conns[c];
1816 + if(conn->tcpstateflags != CLOSED &&
1817 + conn->lport == htons(lastport)) {
1824 + for(c = 0; c < UIP_CONNS; ++c) {
1825 + cconn = &uip_conns[c];
1826 + if(cconn->tcpstateflags == CLOSED) {
1830 + if(cconn->tcpstateflags == TIME_WAIT) {
1832 + cconn->timer > uip_conn->timer) {
1842 + conn->tcpstateflags = SYN_SENT;
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];
1849 + conn->initialmss = conn->mss = UIP_TCP_MSS;
1851 + conn->len = 1; /* TCP length of the SYN is one. */
1853 + conn->timer = 1; /* Send the SYN next time around. */
1854 + conn->rto = UIP_RTO;
1857 + conn->lport = htons(lastport);
1858 + conn->rport = rport;
1859 + conn->ripaddr[0] = ripaddr[0];
1860 + conn->ripaddr[1] = ripaddr[1];
1864 +#endif /* UIP_ACTIVE_OPEN */
1865 +/*-----------------------------------------------------------------------------------*/
1867 +struct uip_udp_conn *
1868 +uip_udp_new(unsigned short int *ripaddr, unsigned short int rport)
1870 + register struct uip_udp_conn *conn;
1872 + /* Find an unused local port. */
1876 + if(lastport >= 32000) {
1880 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
1881 + if(uip_udp_conns[c].lport == lastport) {
1888 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
1889 + if(uip_udp_conns[c].lport == 0) {
1890 + conn = &uip_udp_conns[c];
1899 + conn->lport = HTONS(lastport);
1900 + conn->rport = HTONS(rport);
1901 + conn->ripaddr[0] = ripaddr[0];
1902 + conn->ripaddr[1] = ripaddr[1];
1906 +#endif /* UIP_UDP */
1907 +/*-----------------------------------------------------------------------------------*/
1909 +uip_unlisten(unsigned short int port)
1911 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
1912 + if(uip_listenports[c] == port) {
1913 + uip_listenports[c] = 0;
1918 +/*-----------------------------------------------------------------------------------*/
1920 +uip_listen(unsigned short int port)
1922 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
1923 + if(uip_listenports[c] == 0) {
1924 + uip_listenports[c] = port;
1929 +/*-----------------------------------------------------------------------------------*/
1930 +/* XXX: IP fragment reassembly: not well-tested. */
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;
1949 + unsigned short int offset, len;
1950 + unsigned short int i;
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);
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]) {
1973 + len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
1974 + offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
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) {
1984 + /* Copy the fragment into the reassembly buffer, at the right
1986 + memcpy(&uip_reassbuf[IP_HLEN + offset],
1987 + (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
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
1995 + uip_reassbitmap[offset / (8 * 8)] |=
1996 + bitmap_bits[(offset / 8 ) & 7] &
1997 + ~bitmap_bits[((offset + len) / 8 ) & 7];
1999 + /* If the two endpoints are in different bytes, we update the
2000 + bytes in the endpoints and fill the stuff inbetween with
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;
2007 + uip_reassbitmap[(offset + len) / (8 * 8)] |=
2008 + ~bitmap_bits[((offset + len) / 8 ) & 7];
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. */
2017 + if((BUF->ipoffset[0] & IP_MF) == 0) {
2018 + uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
2019 + uip_reasslen = offset + len;
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
2028 + for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
2029 + if(uip_reassbitmap[i] != 0xff) {
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]) {
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. */
2044 + memcpy(BUF, FBUF, uip_reasslen);
2046 + /* Pretend to be a "normal" (i.e., not fragmented) IP packet
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());
2054 + return uip_reasslen;
2061 +#endif /* UIP_REASSEMBL */
2062 +/*-----------------------------------------------------------------------------------*/
2064 +uip_add_rcv_nxt(unsigned short int n)
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];
2072 +/*-----------------------------------------------------------------------------------*/
2074 +uip_process(u8_t flag)
2076 + register struct uip_conn *uip_connr = uip_conn;
2078 + uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
2081 + /* Check if we were invoked because of the perodic timer fireing. */
2082 + if(flag == UIP_TIMER) {
2084 + if(uip_reasstmr != 0) {
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) {
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;
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;
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;
2121 + /* We also send a reset packet to the remote host. */
2122 + BUF->flags = TCP_RST | TCP_ACK;
2123 + goto tcp_send_nodata;
2126 + /* Exponential backoff. */
2127 + uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
2130 + ++(uip_connr->nrtx);
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) {
2141 + /* In the SYN_RCVD state, we should retransmit our
2143 + goto tcp_send_synack;
2145 +#if UIP_ACTIVE_OPEN
2147 + /* In the SYN_SENT state, we retransmit out SYN. */
2149 + goto tcp_send_syn;
2150 +#endif /* UIP_ACTIVE_OPEN */
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
2159 + uip_flags = UIP_REXMIT;
2166 + /* In all these states we should retransmit a FINACK. */
2167 + goto tcp_send_finack;
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. */
2176 + uip_flags = UIP_POLL;
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();
2197 + /* This is where the input processing starts. */
2198 + UIP_STAT(++uip_stat.ip.recv);
2201 + /* Start of IPv4 input header processing code. */
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.");
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. */
2215 + if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
2216 + uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
2218 + if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
2219 + uip_len = (uip_len & 0xff00) | BUF->len[1];
2222 + /* Check the fragment flag. */
2223 + if((BUF->ipoffset[0] & 0x3f) != 0 ||
2224 + BUF->ipoffset[1] != 0) {
2226 + uip_len = uip_reass();
2227 + if(uip_len == 0) {
2231 + UIP_STAT(++uip_stat.ip.drop);
2232 + UIP_STAT(++uip_stat.ip.fragerr);
2233 + UIP_LOG("ip: fragment dropped.");
2235 +#endif /* UIP_REASSEMBLY */
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
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.");
2247 + UIP_LOG("ip: packet dropped since no address assigned.");
2251 +#endif /* UIP_PINGADDRCONF */
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.");
2259 + if(BUF->destipaddr[1] != uip_hostaddr[1]) {
2260 + UIP_STAT(++uip_stat.ip.drop);
2261 + UIP_LOG("ip: packet not for us.");
2265 + if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
2267 + UIP_STAT(++uip_stat.ip.drop);
2268 + UIP_STAT(++uip_stat.ip.chkerr);
2269 + UIP_LOG("ip: bad checksum.");
2273 + if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump
2274 + to the tcp_input label. */
2278 + if(BUF->proto == UIP_PROTO_UDP)
2280 +#endif /* UIP_UDP */
2282 + if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
2284 + UIP_STAT(++uip_stat.ip.drop);
2285 + UIP_STAT(++uip_stat.ip.protoerr);
2286 + UIP_LOG("ip: neither tcp nor icmp.");
2291 + UIP_STAT(++uip_stat.icmp.recv);
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.");
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
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];
2311 +#endif /* UIP_PINGADDRCONF */
2313 + ICMPBUF->type = ICMP_ECHO_REPLY;
2315 + if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
2316 + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
2318 + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
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;
2329 + UIP_STAT(++uip_stat.icmp.sent);
2332 + /* End of IPv4 input header processing code. */
2336 + /* UDP input processing. */
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
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.");
2349 +#endif /* UIP_UDP_CHECKSUMS */
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];
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]) {
2367 + uip_len = uip_len - 28;
2368 + uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
2369 + uip_flags = UIP_NEWDATA;
2371 + UIP_UDP_APPCALL();
2373 + if(uip_slen == 0) {
2376 + uip_len = uip_slen + 28;
2378 + BUF->len[0] = (uip_len >> 8);
2379 + BUF->len[1] = (uip_len & 0xff);
2381 + BUF->proto = UIP_PROTO_UDP;
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;
2391 +#endif /* UIP_UDP_CHECKSUMS */
2393 + BUF->srcport = uip_udp_conn->lport;
2394 + BUF->destport = uip_udp_conn->rport;
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];
2401 + uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
2402 + goto ip_send_nolen;
2403 +#endif /* UIP_UDP */
2405 + /* TCP input processing. */
2407 + UIP_STAT(++uip_stat.tcp.recv);
2409 + /* Start of TCP input header processing code. */
2411 + if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
2413 + UIP_STAT(++uip_stat.tcp.drop);
2414 + UIP_STAT(++uip_stat.tcp.chkerr);
2415 + UIP_LOG("tcp: bad checksum.");
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]) {
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)
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;
2445 + /* No matching connection found, so we send a RST packet. */
2446 + UIP_STAT(++uip_stat.tcp.synrst);
2449 + /* We do not send resets in response to resets. */
2450 + if(BUF->flags & TCP_RST)
2453 + UIP_STAT(++uip_stat.tcp.rst);
2455 + BUF->flags = TCP_RST | TCP_ACK;
2457 + BUF->tcpoffset = 5 << 4;
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;
2464 + c = BUF->seqno[2];
2465 + BUF->seqno[2] = BUF->ackno[2];
2466 + BUF->ackno[2] = c;
2468 + c = BUF->seqno[1];
2469 + BUF->seqno[1] = BUF->ackno[1];
2470 + BUF->ackno[1] = c;
2472 + c = BUF->seqno[0];
2473 + BUF->seqno[0] = BUF->ackno[0];
2474 + BUF->ackno[0] = c;
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) {
2487 + /* Swap port numbers. */
2488 + tmp16 = BUF->srcport;
2489 + BUF->srcport = BUF->destport;
2490 + BUF->destport = tmp16;
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;
2501 + /* And send out the RST packet! */
2502 + goto tcp_send_noconn;
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. */
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. */
2515 + for(c = 0; c < UIP_CONNS; ++c) {
2516 + if(uip_conns[c].tcpstateflags == CLOSED) {
2517 + uip_connr = &uip_conns[c];
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];
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.");
2536 + uip_conn = uip_connr;
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;
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;
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);
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];
2567 + /* End of options. */
2569 + } else if(opt == 0x01) {
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;
2580 + /* And we are done processing options. */
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. */
2590 + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
2595 + /* Our response will be a SYNACK. */
2596 +#if UIP_ACTIVE_OPEN
2598 + BUF->flags = TCP_ACK;
2601 + BUF->flags |= TCP_SYN;
2602 +#else /* UIP_ACTIVE_OPEN */
2604 + BUF->flags = TCP_SYN | TCP_ACK;
2605 +#endif /* UIP_ACTIVE_OPEN */
2607 + /* We send out the TCP Maximum Segment Size option with our
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;
2614 + BUF->tcpoffset = 6 << 4;
2617 + /* This label will be jumped to if we found an active connection. */
2619 + uip_conn = uip_connr;
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;
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;
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. */
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;
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];
2669 + /* Do RTT estimation, unless we have done retransmissions. */
2670 + if(uip_connr->nrtx == 0) {
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;
2679 + m = m - (uip_connr->sv >> 2);
2680 + uip_connr->sv += m;
2681 + uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
2684 + /* Set the acknowledged flag. */
2685 + uip_flags = UIP_ACKDATA;
2686 + /* Reset the retransmission timer. */
2687 + uip_connr->timer = uip_connr->rto;
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). */
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;
2708 + uip_flags |= UIP_NEWDATA;
2709 + uip_add_rcv_nxt(uip_len);
2716 +#if UIP_ACTIVE_OPEN
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
2722 + if((uip_flags & UIP_ACKDATA) &&
2723 + BUF->flags == (TCP_SYN | TCP_ACK)) {
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];
2730 + /* End of options. */
2732 + } else if(opt == 0x01) {
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;
2743 + /* And we are done processing options. */
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. */
2753 + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
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;
2771 +#endif /* UIP_ACTIVE_OPEN */
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.
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. */
2785 + if(BUF->flags & TCP_FIN) {
2786 + if(uip_outstanding(uip_connr)) {
2789 + uip_add_rcv_nxt(1 + uip_len);
2790 + uip_flags = UIP_CLOSE;
2792 + uip_flags |= UIP_NEWDATA;
2795 + uip_connr->len = 1;
2796 + uip_connr->tcpstateflags = LAST_ACK;
2797 + uip_connr->nrtx = 0;
2799 + BUF->flags = TCP_FIN | TCP_ACK;
2800 + goto tcp_send_nodata;
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;
2812 + uip_add_rcv_nxt(uip_urglen);
2813 + uip_len -= uip_urglen;
2814 + uip_urgdata = uip_appdata;
2815 + uip_appdata += uip_urglen;
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];
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
2829 + if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
2830 + uip_flags |= UIP_NEWDATA;
2831 + uip_add_rcv_nxt(uip_len);
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
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.
2846 + tmp16 = ((unsigned short int)BUF->wnd[0] << 8) + (unsigned short int)BUF->wnd[1];
2847 + if(tmp16 > uip_connr->initialmss ||
2849 + tmp16 = uip_connr->initialmss;
2851 + uip_connr->mss = tmp16;
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.
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
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)) {
2875 + if(uip_flags & UIP_ABORT) {
2877 + uip_connr->tcpstateflags = CLOSED;
2878 + BUF->flags = TCP_RST | TCP_ACK;
2879 + goto tcp_send_nodata;
2882 + if(uip_flags & UIP_CLOSE) {
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;
2891 + /* If uip_slen > 0, the application has data to be sent. */
2892 + if(uip_slen > 0) {
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;
2900 + /* If the ->len variable is non-zero the connection has
2901 + already data in transit and cannot send anymore right
2903 + if(uip_connr->len == 0) {
2905 + /* The application cannot send more than what is allowed by
2906 + the mss (the minumum of the MSS and the available
2908 + if(uip_slen > uip_connr->mss) {
2909 + uip_slen = uip_connr->mss;
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;
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;
2923 + uip_connr->len = 0;
2925 + uip_connr->nrtx = 0;
2927 + uip_appdata = uip_sappdata;
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;
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;
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;
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. */
2963 + uip_add_rcv_nxt(uip_len);
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;
2971 + uip_connr->tcpstateflags = CLOSING;
2973 + uip_add_rcv_nxt(1);
2974 + uip_flags = UIP_CLOSE;
2976 + goto tcp_send_ack;
2977 + } else if(uip_flags & UIP_ACKDATA) {
2978 + uip_connr->tcpstateflags = FIN_WAIT_2;
2979 + uip_connr->len = 0;
2983 + goto tcp_send_ack;
2989 + uip_add_rcv_nxt(uip_len);
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;
2997 + goto tcp_send_ack;
3000 + goto tcp_send_ack;
3005 + goto tcp_send_ack;
3008 + if(uip_flags & UIP_ACKDATA) {
3009 + uip_connr->tcpstateflags = TIME_WAIT;
3010 + uip_connr->timer = 0;
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. */
3019 + BUF->flags = TCP_ACK;
3023 + BUF->tcpoffset = 5 << 4;
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
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];
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];
3039 + BUF->proto = UIP_PROTO_TCP;
3041 + BUF->srcport = uip_connr->lport;
3042 + BUF->destport = uip_connr->rport;
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];
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;
3055 + BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
3056 + BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
3061 + BUF->len[0] = (uip_len >> 8);
3062 + BUF->len[1] = (uip_len & 0xff);
3064 + /* Calculate TCP checksum. */
3065 + BUF->tcpchksum = 0;
3066 + BUF->tcpchksum = ~(uip_tcpchksum());
3072 + BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
3073 + BUF->ttl = UIP_TTL;
3075 + BUF->ipid[0] = ipid >> 8;
3076 + BUF->ipid[1] = ipid & 0xff;
3078 + /* Calculate IP checksum. */
3079 + BUF->ipchksum = 0;
3080 + BUF->ipchksum = ~(uip_ipchksum());
3082 + UIP_STAT(++uip_stat.tcp.sent);
3084 + UIP_STAT(++uip_stat.ip.sent);
3085 + /* Return and let the caller do the actual transmission. */
3091 +/*-----------------------------------------------------------------------------------*/
3092 +/*unsigned short int
3093 +htons(unsigned short int val)
3095 + return HTONS(val);
3097 +/*-----------------------------------------------------------------------------------*/
3100 +++ b/net/uip-0.9/uip.h
3109 + * Header file for the uIP TCP/IP stack.
3110 + * \author Adam Dunkels <adam@dunkels.com>
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.
3120 + * Copyright (c) 2001-2003, Adam Dunkels.
3121 + * All rights reserved.
3123 + * Redistribution and use in source and binary forms, with or without
3124 + * modification, are permitted provided that the following conditions
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.
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.
3147 + * This file is part of the uIP TCP/IP stack.
3149 + * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $
3155 +#include <linux/types.h>
3156 +#include <linux/string.h>
3157 +#include <linux/ctype.h>
3158 +#include <malloc.h>
3159 +#include <common.h>
3162 +#include "uipopt.h"
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.
3171 + * \defgroup uipconffunc uIP configuration functions
3174 + * The uIP configuration functions are used for setting run-time
3175 + * parameters in uIP such as IP addresses.
3179 + * Set the IP address of this host.
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
3185 + * \param addr A pointer to a 4-byte representation of the IP address.
3187 + * \hideinitializer
3189 +#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \
3190 + uip_hostaddr[1] = addr[1]; } while(0)
3193 + * Get the IP address of this host.
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
3199 + * \param addr A pointer to a 4-byte array that will be filled in with
3200 + * the currently configured IP address.
3202 + * \hideinitializer
3204 +#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \
3205 + addr[1] = uip_hostaddr[1]; } while(0)
3210 + * \defgroup uipinit uIP initialization functions
3213 + * The uIP initialization functions are used for booting uIP.
3217 + * uIP initialization function.
3219 + * This function should be called at boot up to initilize the uIP
3222 +void uip_init(void);
3227 + * \defgroup uipdevfunc uIP device driver functions
3230 + * These functions are used by a network device driver for interacting
3235 + * Process an incoming packet.
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.
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.
3247 + * The usual way of calling the function is presented by the source
3250 + uip_len = devicedriver_poll();
3254 + devicedriver_send();
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
3264 + #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
3265 + uip_len = ethernet_devicedrver_poll();
3267 + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
3272 + ethernet_devicedriver_send();
3274 + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
3277 + ethernet_devicedriver_send();
3282 + * \hideinitializer
3284 +#define uip_input() uip_process(UIP_DATA)
3287 + * Periodic processing for a connection identified by its number.
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.
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.
3299 + * The ususal way of calling the function is through a for() loop like
3302 + for(i = 0; i < UIP_CONNS; ++i) {
3305 + devicedriver_send();
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:
3315 + for(i = 0; i < UIP_CONNS; ++i) {
3319 + ethernet_devicedriver_send();
3324 + * \param conn The number of the connection which is to be periodically polled.
3326 + * \hideinitializer
3328 +#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
3329 + uip_process(UIP_TIMER); } while (0)
3332 + * Periodic processing for a connection identified by a pointer to its structure.
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.
3338 + * \param conn A pointer to the uip_conn struct for the connection to
3341 + * \hideinitializer
3343 +#define uip_periodic_conn(conn) do { uip_conn = conn; \
3344 + uip_process(UIP_TIMER); } while (0)
3348 + * Periodic processing for a UDP connection identified by its number.
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:
3354 + for(i = 0; i < UIP_UDP_CONNS; i++) {
3355 + uip_udp_periodic(i);
3357 + devicedriver_send();
3362 + * \note As for the uip_periodic() function, special care has to be
3363 + * taken when using uIP together with ARP and Ethernet:
3365 + for(i = 0; i < UIP_UDP_CONNS; i++) {
3366 + uip_udp_periodic(i);
3369 + ethernet_devicedriver_send();
3374 + * \param conn The number of the UDP connection to be processed.
3376 + * \hideinitializer
3378 +#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
3379 + uip_process(UIP_UDP_TIMER); } while (0)
3382 + * Periodic processing for a UDP connection identified by a pointer to
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
3390 + * \param conn A pointer to the uip_udp_conn struct for the connection
3391 + * to be processed.
3393 + * \hideinitializer
3395 +#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
3396 + uip_process(UIP_UDP_TIMER); } while (0)
3399 +#endif /* UIP_UDP */
3402 + * The uIP packet buffer.
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.
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:
3415 + devicedriver_send(void)
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);
3423 +extern u8_t uip_buf[UIP_BUFSIZE+2];
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.
3433 + * \defgroup uipappfunc uIP application functions
3436 + * Functions used by an application running of top of uIP.
3440 + * Start listening to the specified port.
3442 + * \note Since this function expects the port number in network byte
3443 + * order, a conversion using HTONS() or htons() is necessary.
3446 + uip_listen(HTONS(80));
3449 + * \param port A 16-bit port number in network byte order.
3451 +void uip_listen(u16_t port);
3454 + * Stop listening to the specified port.
3456 + * \note Since this function expects the port number in network byte
3457 + * order, a conversion using HTONS() or htons() is necessary.
3460 + uip_unlisten(HTONS(80));
3463 + * \param port A 16-bit port number in network byte order.
3465 +void uip_unlisten(u16_t port);
3468 + * Connect to a remote host using TCP.
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
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.
3481 + * \note Since this function requires the port number to be in network
3482 + * byte order, a convertion using HTONS() or htons() is necessary.
3487 + uip_ipaddr(ipaddr, 192,168,1,2);
3488 + uip_connect(ipaddr, HTONS(80));
3491 + * \param ripaddr A pointer to a 4-byte array representing the IP
3492 + * address of the remote hot.
3494 + * \param port A 16-bit port number in network byte order.
3496 + * \return A pointer to the uIP connection identifier for the new connection,
3497 + * or NULL if no connection could be allocated.
3500 +struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
3507 + * Check if a connection has outstanding (i.e., unacknowledged) data.
3509 + * \param conn A pointer to the uip_conn structure for the connection.
3511 + * \hideinitializer
3513 +#define uip_outstanding(conn) ((conn)->len)
3516 + * Send data on the current connection.
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.
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.
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
3534 + * \param data A pointer to the data which is to be sent.
3536 + * \param len The maximum amount of data bytes to be sent.
3538 + * \hideinitializer
3540 +#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0)
3543 + * The length of any incoming data that is currently avaliable (if avaliable)
3544 + * in the uip_appdata buffer.
3546 + * The test function uip_data() must first be used to check if there
3547 + * is any data available at all.
3549 + * \hideinitializer
3551 +#define uip_datalen() uip_len
3554 + * The length of any out-of-band data (urgent data) that has arrived
3555 + * on the connection.
3557 + * \note The configuration parameter UIP_URGDATA must be set for this
3558 + * function to be enabled.
3560 + * \hideinitializer
3562 +#define uip_urgdatalen() uip_urglen
3565 + * Close the current connection.
3567 + * This function will close the current connection in a nice way.
3569 + * \hideinitializer
3571 +#define uip_close() (uip_flags = UIP_CLOSE)
3574 + * Abort the current connection.
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.
3580 + * \hideinitializer
3582 +#define uip_abort() (uip_flags = UIP_ABORT)
3585 + * Tell the sending host to stop sending data.
3587 + * This function will close our receiver's window so that we stop
3588 + * receiving data for the current connection.
3590 + * \hideinitializer
3592 +#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
3595 + * Find out if the current connection has been previously stopped with
3598 + * \hideinitializer
3600 +#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
3603 + * Restart the current connection, if is has previously been stopped
3604 + * with uip_stop().
3606 + * This function will open the receiver's window again so that we
3607 + * start receiving data for the current connection.
3609 + * \hideinitializer
3611 +#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
3612 + uip_conn->tcpstateflags &= ~UIP_STOPPED; \
3616 +/* uIP tests that can be made to determine in what state the current
3617 + connection is, and what the application function should do. */
3620 + * Is new incoming data available?
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.
3626 + * \hideinitializer
3628 +#define uip_newdata() (uip_flags & UIP_NEWDATA)
3631 + * Has previously sent data been acknowledged?
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.
3637 + * \hideinitializer
3639 +#define uip_acked() (uip_flags & UIP_ACKDATA)
3642 + * Has the connection just been connected?
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
3649 + * \hideinitializer
3651 +#define uip_connected() (uip_flags & UIP_CONNECTED)
3654 + * Has the connection been closed by the other end?
3656 + * Is non-zero if the connection has been closed by the remote
3657 + * host. The application may then do the necessary clean-ups.
3659 + * \hideinitializer
3661 +#define uip_closed() (uip_flags & UIP_CLOSE)
3664 + * Has the connection been aborted by the other end?
3666 + * Non-zero if the current connection has been aborted (reset) by the
3669 + * \hideinitializer
3671 +#define uip_aborted() (uip_flags & UIP_ABORT)
3674 + * Has the connection timed out?
3676 + * Non-zero if the current connection has been aborted due to too many
3677 + * retransmissions.
3679 + * \hideinitializer
3681 +#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
3684 + * Do we need to retransmit previously data?
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.
3691 + * \hideinitializer
3693 +#define uip_rexmit() (uip_flags & UIP_REXMIT)
3696 + * Is the connection being polled by uIP?
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
3702 + * The polling event can be used for sending data without having to
3703 + * wait for the remote host to send data.
3705 + * \hideinitializer
3707 +#define uip_poll() (uip_flags & UIP_POLL)
3710 + * Get the initial maxium segment size (MSS) of the current
3713 + * \hideinitializer
3715 +#define uip_initialmss() (uip_conn->initialmss)
3718 + * Get the current maxium segment size that can be sent on the current
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()).
3726 + * \hideinitializer
3728 +#define uip_mss() (uip_conn->mss)
3731 + * Set up a new UDP connection.
3733 + * \param ripaddr A pointer to a 4-byte structure representing the IP
3734 + * address of the remote host.
3736 + * \param rport The remote port number in network byte order.
3738 + * \return The uip_udp_conn structure for the new connection or NULL
3739 + * if no connection could be allocated.
3741 +struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
3744 + * Removed a UDP connection.
3746 + * \param conn A pointer to the uip_udp_conn structure for the connection.
3748 + * \hideinitializer
3750 +#define uip_udp_remove(conn) (conn)->lport = 0
3753 + * Send a UDP datagram of length len on the current connection.
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.
3759 + * \param len The length of the data in the uip_buf buffer.
3761 + * \hideinitializer
3763 +#define uip_udp_send(len) uip_slen = (len)
3767 +/* uIP convenience and converting functions. */
3770 + * \defgroup uipconvfunc uIP conversion functions
3773 + * These functions can be used for converting between different data
3774 + * formats used by uIP.
3778 + * Pack an IP address into a 4-byte array which is used by uIP to
3779 + * represent IP addresses.
3785 + uip_ipaddr(&ipaddr, 192,168,1,2);
3788 + * \param addr A pointer to a 4-byte array that will be filled in with
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.
3795 + * \hideinitializer
3797 +#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
3798 + (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \
3799 + (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \
3803 + * Convert 16-bit quantity from host byte order to network byte order.
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.
3809 + * \hideinitializer
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 */
3820 + * Convert 16-bit quantity from host byte order to network byte order.
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.
3827 +u16_t htons(u16_t val);
3833 + * Pointer to the application data in the packet buffer.
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().
3839 +extern volatile u8_t *uip_appdata;
3840 +extern volatile u8_t *uip_sappdata;
3842 +#if UIP_URGDATA > 0
3843 +/* u8_t *uip_urgdata:
3845 + * This pointer points to any urgent data that has been received. Only
3846 + * present if compiled with support for urgent data (UIP_URGDATA).
3848 +extern volatile u8_t *uip_urgdata;
3849 +#endif /* UIP_URGDATA > 0 */
3852 +/* u[8|16]_t uip_len:
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.
3861 +extern volatile u16_t uip_len, uip_slen;
3863 +#if UIP_URGDATA > 0
3864 +extern volatile u8_t uip_urglen, uip_surglen;
3865 +#endif /* UIP_URGDATA > 0 */
3869 + * Representation of a uIP TCP connection.
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.
3879 + u16_t ripaddr[2]; /**< The IP address of the remote host. */
3881 + u16_t lport; /**< The local TCP port, in network byte order. */
3882 + u16_t rport; /**< The local remote TCP port, in network byte
3885 + u8_t rcv_nxt[4]; /**< The sequence number that we expect to
3887 + u8_t snd_nxt[4]; /**< The sequence number that was last sent by
3889 + u16_t len; /**< Length of the data that was previously sent. */
3890 + u16_t mss; /**< Current maximum segment size for the
3892 + u16_t initialmss; /**< Initial maximum segment size for the
3894 + u8_t sa; /**< Retransmission time-out calculation state
3896 + u8_t sv; /**< Retransmission time-out calculation state
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
3904 + /** The application state. */
3905 + u8_t appstate[UIP_APPSTATE_SIZE];
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];
3914 + * \addtogroup uiparch
3919 + * 4-byte array used for the 32-bit sequence number calculations.
3921 +extern volatile u8_t uip_acc32[4];
3928 + * Representation of a uIP UDP connection.
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. */
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 */
3941 + * The structure holding the TCP/IP statistics that are gathered if
3942 + * UIP_STATISTICS is set to 1.
3947 + uip_stats_t drop; /**< Number of dropped packets at the IP
3949 + uip_stats_t recv; /**< Number of received packets at the IP
3951 + uip_stats_t sent; /**< Number of sent packets at the IP
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. */
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
3972 + } icmp; /**< ICMP statistics. */
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
3979 + uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
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. */
3991 + * The uIP TCP/IP statistics.
3993 + * This is the variable in which the uIP TCP/IP statistics are gathered.
3995 +extern struct uip_stats uip_stat;
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.
4002 +/*-----------------------------------------------------------------------------------*/
4005 + * When the application is called, uip_flags will contain the flags
4006 + * that are defined in this file. Please read below for more
4009 +extern volatile u8_t uip_flags;
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. */
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
4021 +#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
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
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
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. */
4043 +#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
4044 + too many retransmissions. */
4047 +/* uip_process(flag):
4049 + * The actual uIP function which does all the work.
4051 +void uip_process(u8_t flag);
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. */
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
4063 +#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
4066 +#define UIP_UDP_TIMER 3
4067 +#endif /* UIP_UDP */
4069 +/* The TCP states used in the uip_conn->tcpstateflags. */
4073 +#define ESTABLISHED 3
4074 +#define FIN_WAIT_1 4
4075 +#define FIN_WAIT_2 5
4077 +#define TIME_WAIT 7
4081 +#define UIP_STOPPED 16
4083 +#define UIP_TCPIP_HLEN 40
4085 +/* The TCP and IP headers. */
4096 + u16_t srcipaddr[2],
4112 +/* The ICMP and IP headers. */
4123 + u16_t srcipaddr[2],
4125 + /* ICMP (echo) header. */
4132 +/* The UDP and IP headers. */
4143 + u16_t srcipaddr[2],
4153 +#define UIP_PROTO_ICMP 1
4154 +#define UIP_PROTO_TCP 6
4155 +#define UIP_PROTO_UDP 17
4158 +extern const u16_t uip_hostaddr[2];
4159 +#else /* UIP_FIXEDADDR */
4160 +extern u16_t uip_hostaddr[2];
4161 +#endif /* UIP_FIXEDADDR */
4163 +#endif /* __UIP_H__ */
4169 +++ b/net/uip-0.9/uip_arch.c
4172 + * Copyright (c) 2001, Adam Dunkels.
4173 + * All rights reserved.
4175 + * Redistribution and use in source and binary forms, with or without
4176 + * modification, are permitted provided that the following conditions
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.
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.
4199 + * This file is part of the uIP TCP/IP stack.
4201 + * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
4207 +#include "uip_arch.h"
4209 +#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
4210 +#define IP_PROTO_TCP 6
4212 +/*-----------------------------------------------------------------------------------*/
4214 +uip_add32(u8_t *op32, u16_t op16)
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];
4222 + if(uip_acc32[2] < (op16 >> 8)) {
4224 + if(uip_acc32[1] == 0) {
4230 + if(uip_acc32[3] < (op16 & 0xff)) {
4232 + if(uip_acc32[2] == 0) {
4234 + if(uip_acc32[1] == 0) {
4240 +/*-----------------------------------------------------------------------------------*/
4242 +uip_chksum(u16_t *sdata, u16_t len)
4246 + for(acc = 0; len > 1; len -= 2) {
4248 + if(acc < *sdata) {
4249 + /* Overflow, so we add the carry to acc (i.e., increase by
4256 + /* add up any odd byte */
4258 + acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
4259 + if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
4266 +/*-----------------------------------------------------------------------------------*/
4270 + return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
4272 +/*-----------------------------------------------------------------------------------*/
4274 +uip_tcpchksum(void)
4279 + /* Compute the checksum of the TCP header. */
4280 + hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
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)));
4287 + if((sum += hsum) < hsum) {
4291 + if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
4294 + if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
4297 + if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
4300 + if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
4303 + if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
4307 + hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
4309 + if((sum += hsum) < hsum) {
4315 +/*-----------------------------------------------------------------------------------*/
4317 +++ b/net/uip-0.9/uip_arch.h
4320 + * \defgroup uiparch Architecture specific uIP functions
4323 + * The functions in the architecture specific module implement the IP
4324 + * check sum and 32-bit additions.
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.
4336 + * Declarations of architecture specific functions.
4337 + * \author Adam Dunkels <adam@dunkels.com>
4341 + * Copyright (c) 2001, Adam Dunkels.
4342 + * All rights reserved.
4344 + * Redistribution and use in source and binary forms, with or without
4345 + * modification, are permitted provided that the following conditions
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.
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.
4368 + * This file is part of the uIP TCP/IP stack.
4370 + * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $
4374 +#ifndef __UIP_ARCH_H__
4375 +#define __UIP_ARCH_H__
4380 + * Carry out a 32-bit addition.
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.
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
4392 + * \param op32 A pointer to a 4-byte array representing a 32-bit
4393 + * integer in network byte order (big endian).
4395 + * \param op16 A 16-bit integer in host byte order.
4397 +void uip_add32(u8_t *op32, u16_t op16);
4400 + * Calculate the Internet checksum over a buffer.
4402 + * The Internet checksum is the one's complement of the one's
4403 + * complement sum of all 16-bit words in the buffer.
4407 + * \note This function is not called in the current version of uIP,
4408 + * but future versions might make use of it.
4410 + * \param buf A pointer to the buffer over which the checksum is to be
4413 + * \param len The length of the buffer over which the checksum is to
4416 + * \return The Internet checksum of the buffer.
4418 +u16_t uip_chksum(u16_t *buf, u16_t len);
4421 + * Calculate the IP header checksum of the packet header in uip_buf.
4423 + * The IP header checksum is the Internet checksum of the 20 bytes of
4426 + * \return The IP header checksum of the IP header in the uip_buf
4429 +u16_t uip_ipchksum(void);
4432 + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
4434 + * The TCP checksum is the Internet checksum of data contents of the
4435 + * TCP segment, and a pseudo-header as defined in RFC793.
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.
4441 + * \return The TCP checksum of the TCP segment in uip_buf and pointed
4442 + * to by uip_appdata.
4444 +u16_t uip_tcpchksum(void);
4448 +#endif /* __UIP_ARCH_H__ */
4450 +++ b/net/uip-0.9/uip_arp.c
4458 + * \defgroup uiparp uIP Address Resolution Protocol
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.
4468 + * \note This ARP implementation only supports Ethernet.
4473 + * Implementation of the ARP Address Resolution Protocol.
4474 + * \author Adam Dunkels <adam@dunkels.com>
4479 + * Copyright (c) 2001-2003, Adam Dunkels.
4480 + * All rights reserved.
4482 + * Redistribution and use in source and binary forms, with or without
4483 + * modification, are permitted provided that the following conditions
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.
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.
4506 + * This file is part of the uIP TCP/IP stack.
4508 + * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $
4513 +#include "uip_arp.h"
4516 + struct uip_eth_hdr ethhdr;
4522 + struct uip_eth_addr shwaddr;
4524 + struct uip_eth_addr dhwaddr;
4529 + struct uip_eth_hdr ethhdr;
4539 + u16_t srcipaddr[2],
4543 +#define ARP_REQUEST 1
4544 +#define ARP_REPLY 2
4546 +#define ARP_HWTYPE_ETH 1
4550 + struct uip_eth_addr ethaddr;
4554 +struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
4561 +static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
4562 +static u16_t ipaddr[2];
4565 +static u8_t arptime;
4566 +static u8_t tmpage;
4568 +#define BUF ((struct arp_hdr *)&uip_buf[0])
4569 +#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
4570 +/*-----------------------------------------------------------------------------------*/
4572 + * Initialize the ARP module.
4575 +/*-----------------------------------------------------------------------------------*/
4579 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
4580 + memset(arp_table[i].ipaddr, 0, 4);
4583 +/*-----------------------------------------------------------------------------------*/
4585 + * Periodic ARP processing function.
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.
4592 +/*-----------------------------------------------------------------------------------*/
4594 +uip_arp_timer(void)
4596 + struct arp_entry *tabptr;
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);
4608 +/*-----------------------------------------------------------------------------------*/
4610 +uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
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) {
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) {
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]) {
4628 + /* An old entry found, update this and return. */
4629 + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
4630 + tabptr->time = arptime;
4637 + /* If we get here, no existing ARP table entry was found, so we
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) {
4649 + /* If no unused entry is found, we try to find the oldest entry and
4651 + if(i == UIP_ARPTAB_SIZE) {
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;
4664 + /* Now, i is the ARP table entry which we will fill with the new
4666 + memcpy(tabptr->ipaddr, ipaddr, 4);
4667 + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
4668 + tabptr->time = arptime;
4670 +/*-----------------------------------------------------------------------------------*/
4672 + * ARP processing for incoming IP packets
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.
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.
4683 +/*-----------------------------------------------------------------------------------*/
4687 + uip_len -= sizeof(struct uip_eth_hdr);
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])) {
4695 + if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
4696 + (uip_hostaddr[1] & uip_arp_netmask[1])) {
4699 + uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
4703 +/*-----------------------------------------------------------------------------------*/
4705 + * ARP processing for incoming ARP packets.
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.
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.
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.
4725 +/*-----------------------------------------------------------------------------------*/
4727 +uip_arp_arpin(void)
4730 + if(uip_len < sizeof(struct arp_hdr)) {
4737 + switch(BUF->opcode) {
4738 + case HTONS(ARP_REQUEST):
4739 + /* ARP request. If it asked for our address, we send out a
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);
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);
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];
4756 + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
4757 + uip_len = sizeof(struct arp_hdr);
4760 + case HTONS(ARP_REPLY):
4761 + /* ARP reply. We insert or update the ARP table if it was meant
4763 + if(BUF->dipaddr[0] == uip_hostaddr[0] &&
4764 + BUF->dipaddr[1] == uip_hostaddr[1]) {
4766 + uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
4773 +/*-----------------------------------------------------------------------------------*/
4775 + * Prepend Ethernet header to an outbound IP packet and see if we need
4776 + * to send out an ARP request.
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.
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.
4793 + * If the destination IP address is not on the local network, the IP
4794 + * address of the default router is used instead.
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
4800 +/*-----------------------------------------------------------------------------------*/
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.
4809 + If not ARP table entry is found, we overwrite the original IP
4810 + packet with an ARP request for the IP address. */
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];
4823 + /* Else, we use the destination IP address. */
4824 + ipaddr[0] = IPBUF->destipaddr[0];
4825 + ipaddr[1] = IPBUF->destipaddr[1];
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])
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. */
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);
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);
4852 + BUF->protolen = 4;
4853 + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
4855 + uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
4857 + uip_len = sizeof(struct arp_hdr);
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);
4865 + IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
4867 + uip_len += sizeof(struct uip_eth_hdr);
4869 +/*-----------------------------------------------------------------------------------*/
4874 +++ b/net/uip-0.9/uip_arp.h
4882 + * \addtogroup uiparp
4888 + * Macros and definitions for the ARP module.
4889 + * \author Adam Dunkels <adam@dunkels.com>
4894 + * Copyright (c) 2001-2003, Adam Dunkels.
4895 + * All rights reserved.
4897 + * Redistribution and use in source and binary forms, with or without
4898 + * modification, are permitted provided that the following conditions
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.
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.
4921 + * This file is part of the uIP TCP/IP stack.
4923 + * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $
4927 +#ifndef __UIP_ARP_H__
4928 +#define __UIP_ARP_H__
4934 + * Representation of a 48-bit Ethernet address.
4936 +struct uip_eth_addr {
4940 +extern struct uip_eth_addr uip_ethaddr;
4943 + * The Ethernet header.
4945 +struct uip_eth_hdr {
4946 + struct uip_eth_addr dest;
4947 + struct uip_eth_addr src;
4951 +#define UIP_ETHTYPE_ARP 0x0806
4952 +#define UIP_ETHTYPE_IP 0x0800
4953 +#define UIP_ETHTYPE_IP6 0x86dd
4956 +/* The uip_arp_init() function must be called before any of the other
4958 +void uip_arp_init(void);
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);
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
4973 +void uip_arp_arpin(void);
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);
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);
4994 + * \addtogroup uipconffunc
4999 + * Set the default router's IP address.
5001 + * \param addr A pointer to a 4-byte array containing the IP address
5002 + * of the default router.
5004 + * \hideinitializer
5006 +#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \
5007 + uip_arp_draddr[1] = addr[1]; } while(0)
5010 + * Set the netmask.
5012 + * \param addr A pointer to a 4-byte array containing the IP address
5015 + * \hideinitializer
5017 +#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \
5018 + uip_arp_netmask[1] = addr[1]; } while(0)
5022 + * Get the default router's IP address.
5024 + * \param addr A pointer to a 4-byte array that will be filled in with
5025 + * the IP address of the default router.
5027 + * \hideinitializer
5029 +#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \
5030 + addr[1] = uip_arp_draddr[1]; } while(0)
5033 + * Get the netmask.
5035 + * \param addr A pointer to a 4-byte array that will be filled in with
5036 + * the value of the netmask.
5038 + * \hideinitializer
5040 +#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \
5041 + addr[1] = uip_arp_netmask[1]; } while(0)
5045 + * Specifiy the Ethernet MAC address.
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.
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
5055 + * \param eaddr A pointer to a struct uip_eth_addr containing the
5056 + * Ethernet MAC address of the Ethernet card.
5058 + * \hideinitializer
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)
5070 + * \internal Internal variables that are set using the macros
5071 + * uip_setdraddr and uip_setnetmask.
5073 +extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
5074 +#endif /* __UIP_ARP_H__ */
5078 +++ b/net/uip-0.9/uipopt.h
5081 + * \defgroup uipopt Configuration options for uIP
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.
5093 + * Configuration options for uIP.
5094 + * \author Adam Dunkels <adam@dunkels.com>
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.
5103 + * Copyright (c) 2001-2003, Adam Dunkels.
5104 + * All rights reserved.
5106 + * Redistribution and use in source and binary forms, with or without
5107 + * modification, are permitted provided that the following conditions
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.
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.
5130 + * This file is part of the uIP TCP/IP stack.
5132 + * $Id: uipopt.h,v 1.16.2.5 2003/10/07 13:22:51 adam Exp $
5136 +#ifndef __UIPOPT_H__
5137 +#define __UIPOPT_H__
5139 +/*------------------------------------------------------------------------------*/
5141 + * \defgroup uipopttypedef uIP type definitions
5146 + * The 8-bit unsigned data type.
5148 + * This may have to be tweaked for your particular compiler. "unsigned
5149 + * char" works for most compilers.
5151 +typedef unsigned char u8_t;
5154 + * The 16-bit unsigned data type.
5156 + * This may have to be tweaked for your particular compiler. "unsigned
5157 + * short" works for most compilers.
5159 +typedef unsigned short u16_t;
5162 + * The statistics data type.
5164 + * This datatype determines how high the statistics counters are able
5167 +typedef unsigned short uip_stats_t;
5171 +/*------------------------------------------------------------------------------*/
5174 + * \defgroup uipoptstaticconf Static configuration options
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.
5184 + * All of these should be changed to suit your project.
5188 + * Determines if uIP should use a fixed IP address or not.
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.
5194 + * \hideinitializer
5196 +#define UIP_FIXEDADDR 0
5199 + * Ping IP address asignment.
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.
5206 + * \note This works only if UIP_FIXEDADDR is 0.
5208 + * \hideinitializer
5210 +#define UIP_PINGADDRCONF 0
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 */
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 */
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 */
5252 + * Specifies if the uIP ARP module should be compiled with a fixed
5253 + * Ethernet MAC address or not.
5255 + * If this configuration option is 0, the macro uip_setethaddr() can
5256 + * be used to specify the Ethernet address at run-time.
5258 + * \hideinitializer
5260 +#define UIP_FIXEDETHADDR 0
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 */
5282 +/*------------------------------------------------------------------------------*/
5284 + * \defgroup uipoptip IP configuration options
5289 + * The IP TTL (time to live) of IP packets sent by uIP.
5291 + * This should normally not be changed.
5293 +#define UIP_TTL 255
5296 + * Turn on support for IP packet reassembly.
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).
5304 + * \note IP packet reassembly is not heavily tested.
5306 + * \hideinitializer
5308 +#define UIP_REASSEMBLY 0
5311 + * The maximum time an IP fragment should wait in the reassembly
5312 + * buffer before it is dropped.
5315 +#define UIP_REASS_MAXAGE 40
5319 +/*------------------------------------------------------------------------------*/
5321 + * \defgroup uipoptudp UDP configuration options
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
5331 + * Toggles wether UDP support should be compiled in or not.
5333 + * \hideinitializer
5338 + * Toggles if UDP checksums should be used or not.
5340 + * \note Support for UDP checksums is currently not included in uIP,
5341 + * so this option has no function.
5343 + * \hideinitializer
5345 +#define UIP_UDP_CHECKSUMS 0
5348 + * The maximum amount of concurrent UDP connections.
5350 + * \hideinitializer
5352 +#define UIP_UDP_CONNS 10
5355 + * The name of the function that should be called when UDP datagrams arrive.
5357 + * \hideinitializer
5359 +#define UIP_UDP_APPCALL udp_appcall
5362 +/*------------------------------------------------------------------------------*/
5364 + * \defgroup uipopttcp TCP configuration options
5369 + * Determines if support for opening connections from uIP should be
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.
5376 + * \hideinitializer
5378 +#define UIP_ACTIVE_OPEN 1
5381 + * The maximum number of simultaneously open TCP connections.
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.
5387 + * \hideinitializer
5389 +#define UIP_CONNS 10
5392 + * The maximum number of simultaneously listening TCP ports.
5394 + * Each listening TCP port requires 2 bytes of memory.
5396 + * \hideinitializer
5398 +#define UIP_LISTENPORTS 10
5401 + * The size of the advertised receiver's window.
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.
5407 + * \hideinitializer
5409 +#define UIP_RECEIVE_WINDOW 32768
5412 + * Determines if support for TCP urgent data notification should be
5415 + * Urgent data (out-of-band data) is a rarely used TCP feature that
5416 + * very seldom would be required.
5418 + * \hideinitializer
5420 +#define UIP_URGDATA 1
5423 + * The initial retransmission timeout counted in timer pulses.
5425 + * This should not be changed.
5430 + * The maximum number of times a segment should be retransmitted
5431 + * before the connection should be aborted.
5433 + * This should not be changed.
5435 +#define UIP_MAXRTX 8
5438 + * The maximum number of times a SYN segment should be retransmitted
5439 + * before a connection request should be deemed to have been
5442 + * This should not need to be changed.
5444 +#define UIP_MAXSYNRTX 3
5447 + * The TCP maximum segment size.
5449 + * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.
5451 +#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
5454 + * How long a connection should stay in the TIME_WAIT state.
5456 + * This configiration option has no real implication, and it should be
5459 +#define UIP_TIME_WAIT_TIMEOUT 120
5463 +/*------------------------------------------------------------------------------*/
5465 + * \defgroup uipoptarp ARP configuration options
5470 + * The size of the ARP table.
5472 + * This option should be set to a larger value if this uIP node will
5473 + * have many connections from the local network.
5475 + * \hideinitializer
5477 +#define UIP_ARPTAB_SIZE 8
5480 + * The maxium age of ARP table entries measured in 10ths of seconds.
5482 + * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
5485 +#define UIP_ARP_MAXAGE 120
5489 +/*------------------------------------------------------------------------------*/
5492 + * \defgroup uipoptgeneral General configuration options
5497 + * The size of the uIP packet buffer.
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.
5503 + * \hideinitializer
5505 +#define UIP_BUFSIZE 1500
5509 + * Determines if statistics support should be compiled in.
5511 + * The statistics is useful for debugging and to show the user.
5513 + * \hideinitializer
5515 +#define UIP_STATISTICS 1
5518 + * Determines if logging of certain events should be compiled in.
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.
5524 + * \hideinitializer
5526 +#define UIP_LOGGING 0
5529 + * Print out a uIP log message.
5531 + * This function must be implemented by the module that uses uIP, and
5532 + * is called by uIP whenever a log message is generated.
5534 +void uip_log(char *msg);
5537 + * The link level header length.
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.
5543 + * \hideinitializer
5545 +#define UIP_LLH_LEN 14
5549 +/*------------------------------------------------------------------------------*/
5551 + * \defgroup uipoptcpu CPU architecture configuration
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.
5560 +#ifndef LITTLE_ENDIAN
5561 +#define LITTLE_ENDIAN 3412
5562 +#endif /* LITTLE_ENDIAN */
5564 +#define BIG_ENDIAN 1234
5565 +#endif /* BIGE_ENDIAN */
5568 + * The byte order of the CPU architecture on which uIP is to be run.
5570 + * This option can be either BIG_ENDIAN (Motorola byte order) or
5571 + * LITTLE_ENDIAN (Intel byte order).
5573 + * \hideinitializer
5575 +/*#ifndef BYTE_ORDER*/
5576 +#define BYTE_ORDER BIG_ENDIAN
5577 +/*#endif*/ /* BYTE_ORDER */
5580 +/*------------------------------------------------------------------------------*/
5583 + * \defgroup uipoptapp Appication specific configurations
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.
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.
5595 + * The file containing the definitions must be included in the
5598 + * The following example illustrates how this can look.
5601 +void httpd_appcall(void);
5602 +#define UIP_APPCALL httpd_appcall
5604 +struct httpd_state {
5610 +#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
5615 + * \var #define UIP_APPCALL
5617 + * The name of the application function that uIP should call in
5618 + * response to TCP/IP events.
5623 + * \var #define UIP_APPSTATE_SIZE
5625 + * The size of the application state that is to be stored in the
5626 + * uip_conn structure.
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
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
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);
5650 @@ -273,6 +273,10 @@ static __inline__ int abortboot(int boot
5652 void main_loop (void)
5654 +#ifdef CONFIG_CMD_HTTPD
5658 #ifndef CONFIG_SYS_HUSH_PARSER
5659 static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
5661 @@ -403,12 +407,22 @@ void main_loop (void)
5664 # ifndef CONFIG_SYS_HUSH_PARSER
5665 - run_command (s, 0);
5666 + ret = run_command (s, 0);
5668 - parse_string_outer(s, FLAG_PARSE_SEMICOLON |
5669 + ret = parse_string_outer(s, FLAG_PARSE_SEMICOLON |
5670 FLAG_EXIT_FROM_LOOP);
5673 +# ifdef CONFIG_CMD_HTTPD
5675 + printf("Failed to execute bootcmd "
5676 + "(maybe invalid u-boot environment?), "
5677 + "starting httpd to update firmware...\n");
5683 # ifdef CONFIG_AUTOBOOT_KEYED
5684 disable_ctrlc(prev); /* restore Control C checking */
5686 --- a/include/configs/easy50712.h
5687 +++ b/include/configs/easy50712.h
5690 #define CONFIG_CMD_HTTPD /* enable upgrade via HTTPD */
5692 +#define CONFIG_IPADDR 192.168.0.119
5693 +#define CONFIG_ETHADDR 00:01:02:03:04:05
5695 #endif /* __CONFIG_H */
5696 --- a/lib_mips/time.c
5697 +++ b/lib_mips/time.c
5698 @@ -29,6 +29,8 @@ static unsigned long timestamp;
5699 /* how many counter cycles in a jiffy */
5700 #define CYCLES_PER_JIFFY (CONFIG_SYS_MIPS_TIMER_FREQ + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ
5702 +unsigned long ifx_get_cpuclk(void);
5705 * timer without interrupts
5709 @@ -35,12 +35,14 @@ HttpdHandler (void)
5718 NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
5726 @@ -1966,7 +1966,7 @@ NetSendHttpd(void)
5728 NetReceiveHttpd(volatile uchar * inpkt, int len)
5730 - memcpy(uip_buf, inpkt, len);
5731 + memcpy(uip_buf, (const void *)inpkt, len);
5733 if(BUF->type == htons(UIP_ETHTYPE_IP)) {
5735 @@ -1989,6 +1989,7 @@ NetLoopHttpd(void)
5736 unsigned long long tout = 0;
5738 unsigned short int ip[2];
5739 + struct uip_eth_addr eaddr;
5741 #ifdef CONFIG_NET_MULTI
5743 @@ -2039,6 +2040,15 @@ restart:
5744 eth_getenv_enetaddr("ethaddr", NetOurEther);
5747 + eaddr.addr[0] = NetOurEther[0];
5748 + eaddr.addr[1] = NetOurEther[1];
5749 + eaddr.addr[2] = NetOurEther[2];
5750 + eaddr.addr[3] = NetOurEther[3];
5751 + eaddr.addr[4] = NetOurEther[4];
5752 + eaddr.addr[5] = NetOurEther[5];
5754 + uip_setethaddr(eaddr);
5756 NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
5757 NetOurGatewayIP = getenv_IPaddr ("gatewayip");
5758 NetOurSubnetMask= getenv_IPaddr ("netmask");
5759 @@ -2072,6 +2082,14 @@ restart:
5766 + puts ("\nAbort\n");
5771 if(!httpd_upload_complete)
5773 printf("Bytes transferred = %ld (%lx hex)\n",
5774 --- a/net/uip-0.9/fsdata.c
5775 +++ b/net/uip-0.9/fsdata.c
5777 -static const char data_flashing_html[] = {
5778 - /* /flashing.html */
5779 - 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5780 - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
5781 - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
5782 - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
5783 - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5784 - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
5785 - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
5786 - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
5787 - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
5788 - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
5789 - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
5790 - 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
5791 - 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
5792 - 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
5793 - 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
5794 - 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
5795 - 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
5796 - 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
5797 - 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
5798 - 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
5799 - 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
5800 - 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
5801 - 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
5802 - 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
5803 - 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
5804 - 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5806 -static const char data_fail_html[] = {
5808 - 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5809 - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
5810 - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
5811 - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
5812 - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5813 - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
5814 - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
5815 - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
5816 - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
5817 - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
5818 - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
5819 - 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
5820 - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
5821 - 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
5822 - 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
5823 - 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
5824 - 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
5825 - 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
5826 - 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
5827 - 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
5828 - 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
5829 - 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
5830 - 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
5831 - 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
5832 - 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
5833 - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
5834 - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
5835 - 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
5836 - 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
5837 - 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
5838 - 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
5839 - 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5840 - 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
5841 - 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
5842 - 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
5843 - 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
5846 -static const char data_404_html[] = {
5848 - 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5849 - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
5850 - 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
5851 - 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
5852 - 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
5853 - 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
5854 - 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
5855 - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
5856 - 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
5857 - 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
5858 - 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
5859 - 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
5860 - 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
5861 - 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
5862 - 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
5863 - 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
5864 - 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
5865 - 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
5866 - 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
5867 - 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
5870 -static const char data_index_html[] = {
5872 - 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5873 - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
5874 - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
5875 - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
5876 - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5877 - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
5878 - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
5879 - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
5880 - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
5881 - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
5882 - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
5883 - 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
5884 - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
5885 - 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
5886 - 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
5887 - 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
5888 - 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
5889 - 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
5890 - 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
5891 - 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
5892 - 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
5893 - 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
5894 - 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
5895 - 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
5896 - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
5897 - 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
5898 - 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
5899 - 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
5900 - 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
5901 - 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
5902 - 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
5903 - 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
5904 - 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
5905 - 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
5906 - 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
5907 - 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
5908 - 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
5909 - 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
5910 - 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
5911 - 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
5912 - 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
5913 - 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
5914 - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5916 -static const char data_flash_html[] = {
5918 - 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
5919 - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
5920 - 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
5921 - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
5922 - 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
5923 - 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
5924 - 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
5925 - 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
5926 - 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
5927 - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
5928 - 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
5929 - 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
5930 - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
5931 - 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
5932 - 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
5933 - 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
5934 - 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
5935 - 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
5936 - 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
5937 - 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
5938 - 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
5939 - 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
5940 - 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
5941 - 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
5942 - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
5943 - 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
5944 - 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
5945 - 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
5946 - 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
5947 - 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
5948 - 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
5949 - 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
5950 - 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
5951 - 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
5952 - 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
5953 - 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
5954 - 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
5955 - 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
5956 - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
5957 - 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
5958 - 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
5959 - 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
5960 - 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
5961 - 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
5963 -const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
5964 +static const char data_flashing_html[] =
5965 +"HTTP/1.0 200 OK\n"
5966 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
5967 +"Content-type: text/html\n"
5972 +"\t\t\tFailsafe UI\n"
5976 +"\t\t<center><h1>Upgrading system...</h1></center>\n"
5980 +static const char data_fail_html[] =
5981 +"HTTP/1.0 200 OK\n"
5982 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
5983 +"Content-type: text/html\n"
5988 +"\t\t\tFailsafe UI\n"
5992 +"\t\t<h1>Flashing failed</h1>\n"
5993 +"\t\tERROR - the image you uploaded failed to pass verification.<br>\n"
5994 +"\t\tPlease make sure to use an official update provided by http://lantiq.com/\n"
5998 +static const char data_404_html[] =
5999 +"HTTP/1.0 404 File not found\n"
6000 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
6001 +"Content-type: text/html\n"
6006 +"\t\t\tFailsafe UI\n"
6010 +"\t\t<center><h1>404 - file not found</h1></center>\n"
6014 +static const char data_index_html[] =
6015 +"HTTP/1.0 200 OK\n"
6016 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
6017 +"Content-type: text/html\n"
6022 +"\t\t\tFailsafe UI\n"
6026 +"\t\t<h1>Failsafe UI</h1>\n"
6027 +"\t\t<form method=\"post\" enctype=\"multipart/form-data\">\n"
6028 +"\t\t\t<input type=file name=firmware>\n"
6029 +"\t\t\t<input type=submit>\n"
6034 +static const char data_flash_html[] =
6035 +"HTTP/1.0 200 OK\n"
6036 +"Server: uIP/0.9 (http://dunkels.com/adam/uip/)\n"
6037 +"Content-type: text/html\n"
6042 +"\t\t\tFailsafe UI\n"
6046 +"\t\t<h1>Flashing...</h1>\n"
6047 +"\t\tThe system is now trying to flash. If there is a problem, the LEDs will "
6048 +"start to blink.<br>\n"
6050 +"\t\tAfter a successful update the box will reboot\n"
6054 +const struct fsdata_file file_flashing_html[] =
6055 +{{NULL, "/flashing.html", data_flashing_html, sizeof(data_flashing_html)}};
6057 +const struct fsdata_file file_fail_html[] =
6058 +{{file_flashing_html, "/fail.html", data_fail_html, sizeof(data_fail_html)}};
6060 -const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
6061 +const struct fsdata_file file_404_html[] =
6062 +{{file_fail_html, "/404.html", data_404_html, sizeof(data_404_html)}};
6064 -const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
6065 +const struct fsdata_file file_index_html[] =
6066 +{{file_404_html, "/index.html", data_index_html, sizeof(data_index_html)}};
6068 -const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
6070 -const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
6071 +const struct fsdata_file file_flash_html[] =
6072 +{{file_index_html, "/flash.html", data_flash_html, sizeof(data_flash_html)}};
6074 #define FS_ROOT file_flash_html
6076 -#define FS_NUMFILES 5
6077 \ No newline at end of file
6078 +#define FS_NUMFILES 5
6079 --- a/net/uip-0.9/httpd.c
6080 +++ b/net/uip-0.9/httpd.c
6081 @@ -130,7 +130,7 @@ httpd_appcall(void)
6082 if(!fs_open((const char *)&uip_appdata[4], &fsfile))
6084 PRINTLN("couldn't open file");
6085 - fs_open(file_index_html.name, &fsfile);
6086 + fs_open(file_404_html.name, &fsfile);
6090 @@ -141,7 +141,7 @@ httpd_appcall(void)
6091 if(hs->state == HTTP_FIRMWARE)
6093 unsigned char *start = (unsigned char*)uip_appdata;
6094 - char *clen = strstr(start, "Content-Length:");
6095 + char *clen = strstr((char *)start, "Content-Length:");
6097 unsigned char *next, *end;
6098 unsigned char *boundary_start;
6099 @@ -150,14 +150,14 @@ httpd_appcall(void)
6102 clen += sizeof("Content-Length:");
6103 - next = strstr(clen, eol);
6104 + next = (unsigned char *)strstr(clen, eol);
6109 printf("expecting %d bytes\n", len);
6110 upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
6111 - printf("received data will be stored at 0x%08X\n", upload_data);
6112 + printf("received data will be stored at %p\n", upload_data);
6115 printf("failed to allocate memory\n");
6116 @@ -174,14 +174,14 @@ httpd_appcall(void)
6120 - boundary_start = strstr(next, "---");
6121 + boundary_start = (unsigned char *)strstr((char *)next, "---");
6127 - end = strstr(boundary_start, eol);
6129 + end = (unsigned char *)strstr((char *)boundary_start, eol);
6134 @@ -189,13 +189,13 @@ httpd_appcall(void)
6135 boundary_len = end - boundary_start;
6136 memcpy(boundary, boundary_start, boundary_len);
6137 boundary[boundary_len] = 0;
6138 - next = strstr(boundary_start, "name=\"firmware\";");
6139 + next = (unsigned char *)strstr((char *)boundary_start, "name=\"firmware\";");
6145 - next = strstr(next, eol2);
6146 + next = (unsigned char *)strstr((char *)next, eol2);
6149 printf("could not find start of data\n");
6150 @@ -259,7 +259,6 @@ httpd_appcall(void)
6155 httpd_upload_complete = 1;
6156 // for(i = 0; i < hs->upload_total; i++)
6157 // printf("%c", httpd_upload_data[i]);
6158 @@ -267,7 +266,7 @@ httpd_appcall(void)
6162 - uip_send(hs->dataptr, hs->count);
6163 + uip_send((unsigned char *)hs->dataptr, hs->count);