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

1--- a/common/cmd_net.c
2+++ b/common/cmd_net.c
3@@ -43,6 +43,18 @@ U_BOOT_CMD(
4     "[loadAddress] [[hostIPaddr:]bootfilename]"
5 );
6 
7+#if defined(CONFIG_CMD_HTTPD)
8+int do_httpd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
9+{
10+ return NetLoopHttpd();
11+}
12+
13+U_BOOT_CMD(
14+ httpd, 1, 1, do_httpd,
15+ "httpd\t- start webserver", ""
16+);
17+#endif
18+
19 int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
20 {
21     return netboot_common (TFTP, cmdtp, argc, argv);
22--- a/include/net.h
23+++ b/include/net.h
24@@ -383,7 +383,8 @@ extern int NetTimeOffset; /* offset ti
25 
26 /* Initialize the network adapter */
27 extern int NetLoop(proto_t);
28-
29+extern int NetLoopHttpd(void);
30+extern void NetSendHttpd(void);
31 /* Shutdown adapters and cleanup */
32 extern void NetStop(void);
33 
34--- /dev/null
35+++ b/net/httpd.c
36@@ -0,0 +1,52 @@
37+/*
38+ * Copyright 1994, 1995, 2000 Neil Russell.
39+ * (See License)
40+ * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
41+ */
42+
43+#include <common.h>
44+#include <command.h>
45+#include <net.h>
46+#include "uip-0.9/uipopt.h"
47+#include "uip-0.9/uip.h"
48+#include "uip-0.9/uip_arp.h"
49+
50+
51+#if defined(CONFIG_CMD_HTTPD)
52+
53+#define TIMEOUT 5
54+
55+static int arptimer = 0;
56+
57+void
58+HttpdHandler (void)
59+{
60+ int i;
61+ for(i = 0; i < UIP_CONNS; i++) {
62+ uip_periodic(i);
63+ if(uip_len > 0) {
64+ uip_arp_out();
65+ NetSendHttpd();
66+ }
67+ }
68+ if(++arptimer == 20) {
69+ uip_arp_timer();
70+ arptimer = 0;
71+ }
72+}
73+
74+static void
75+HttpdTimeout (void)
76+{
77+ puts ("T ");
78+ NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
79+}
80+
81+void
82+HttpdStart (void)
83+{
84+ uip_init();
85+ httpd_init();
86+}
87+
88+#endif
89--- /dev/null
90+++ b/include/httpd.h
91@@ -0,0 +1,17 @@
92+#ifndef _UIP_HTTPD_H__
93+#define _UIP_HTTPD_H__
94+
95+void HttpdStart (void);
96+void HttpdHandler (void);
97+
98+/* board specific implementation */
99+extern int do_http_upgrade(const unsigned char *data, const ulong size);
100+
101+#define HTTP_PROGRESS_START 0
102+#define HTTP_PROGRESS_TIMEOUT 1
103+#define HTTP_PROGRESS_UPLOAD_READY 2
104+#define HTTP_PROGRESS_UGRADE_READY 3
105+#define HTTP_PROGRESS_UGRADE_FAILED 4
106+extern int do_http_progress(const int state);
107+
108+#endif
109--- a/net/Makefile
110+++ b/net/Makefile
111@@ -26,6 +26,10 @@ include $(TOPDIR)/config.mk
112 # CFLAGS += -DDEBUG
113 
114 LIB = $(obj)libnet.a
115+UIPDIR = uip-0.9
116+RSADIR = uip-0.9
117+$(shell mkdir -p $(obj)$(UIPDIR))
118+$(shell mkdir -p $(obj)$(RSADIR))
119 
120 COBJS-y += bootp.o
121 COBJS-$(CONFIG_CMD_DNS) += dns.o
122@@ -36,6 +40,9 @@ COBJS-y += rarp.o
123 COBJS-$(CONFIG_CMD_SNTP) += sntp.o
124 COBJS-y += tftp.o
125 
126+COBJS-$(CONFIG_CMD_HTTPD) += httpd.o $(UIPDIR)/fs.o $(UIPDIR)/httpd.o $(UIPDIR)/uip_arp.o $(UIPDIR)/uip_arch.o $(UIPDIR)/uip.o
127+COBJS-$(CONFIG_CMD_RSA) += $(RSADIR)/bigint.o $(RSADIR)/base64.o $(RSADIR)/rmd160.o $(RSADIR)/rsa.o
128+
129 COBJS := $(COBJS-y)
130 SRCS := $(COBJS:.o=.c)
131 OBJS := $(addprefix $(obj),$(COBJS))
132--- a/net/net.c
133+++ b/net/net.c
134@@ -95,6 +95,19 @@
135 #if defined(CONFIG_CMD_DNS)
136 #include "dns.h"
137 #endif
138+#if defined(CONFIG_CMD_HTTPD)
139+#include "httpd.h"
140+#include "uip-0.9/uipopt.h"
141+#include "uip-0.9/uip.h"
142+#include "uip-0.9/uip_arp.h"
143+static int https_running = 0;
144+int httpd_upload_complete = 0;
145+unsigned char *httpd_upload_data = 0;
146+extern int upload_running;
147+void NetReceiveHttpd(volatile uchar * inpkt, int len);
148+void NetSendHttpd(void);
149+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
150+#endif
151 
152 #if defined(CONFIG_CMD_NET)
153 
154@@ -1310,6 +1323,13 @@ NetReceive(volatile uchar * inpkt, int l
155 
156     debug("packet received\n");
157 
158+#if defined(CONFIG_CMD_HTTPD)
159+ if(https_running) {
160+ NetReceiveHttpd(inpkt, len);
161+ return;
162+ }
163+#endif
164+
165     NetRxPacket = inpkt;
166     NetRxPacketLen = len;
167     et = (Ethernet_t *)inpkt;
168@@ -1952,3 +1972,162 @@ ushort getenv_VLAN(char *var)
169 {
170     return (string_to_VLAN(getenv(var)));
171 }
172+
173+#if defined(CONFIG_CMD_HTTPD)
174+
175+void
176+NetSendHttpd(void)
177+{
178+ volatile uchar *tmpbuf = NetTxPacket;
179+ int i;
180+
181+ for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
182+ tmpbuf[i] = uip_buf[i];
183+ }
184+
185+ for(; i < uip_len; i++) {
186+ tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
187+ }
188+ eth_send(NetTxPacket, uip_len);
189+}
190+
191+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
192+
193+void
194+NetReceiveHttpd(volatile uchar * inpkt, int len)
195+{
196+ memcpy(uip_buf, inpkt, len);
197+ uip_len = len;
198+ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
199+ uip_arp_ipin();
200+ uip_input();
201+ if(uip_len > 0) {
202+ uip_arp_out();
203+ NetSendHttpd();
204+ }
205+ } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
206+ uip_arp_arpin();
207+ if(uip_len > 0) {
208+ NetSendHttpd();
209+ }
210+ }
211+}
212+
213+int
214+NetLoopHttpd(void)
215+{
216+ unsigned long long tout = 0;
217+ bd_t *bd = gd->bd;
218+ unsigned short int ip[2];
219+
220+#ifdef CONFIG_NET_MULTI
221+ NetRestarted = 0;
222+ NetDevExists = 0;
223+#endif
224+
225+ /* XXX problem with bss workaround */
226+ NetArpWaitPacketMAC = NULL;
227+ NetArpWaitTxPacket = NULL;
228+ NetArpWaitPacketIP = 0;
229+ NetArpWaitReplyIP = 0;
230+ NetArpWaitTxPacket = NULL;
231+ NetTxPacket = NULL;
232+ NetTryCount = 1;
233+
234+ if (!NetTxPacket) {
235+ int i;
236+ /*
237+ * Setup packet buffers, aligned correctly.
238+ */
239+ NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
240+ NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
241+ for (i = 0; i < PKTBUFSRX; i++) {
242+ NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
243+ }
244+ }
245+
246+ if (!NetArpWaitTxPacket) {
247+ NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
248+ NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
249+ NetArpWaitTxPacketSize = 0;
250+ }
251+
252+restart:
253+
254+ eth_halt();
255+#ifdef CONFIG_NET_MULTI
256+ eth_set_current();
257+#endif
258+ if (eth_init(bd) < 0) {
259+ eth_halt();
260+ return(-1);
261+ }
262+
263+#ifdef CONFIG_NET_MULTI
264+ memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);
265+#else
266+ eth_getenv_enetaddr("ethaddr", NetOurEther);
267+#endif
268+
269+ NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
270+ NetOurGatewayIP = getenv_IPaddr ("gatewayip");
271+ NetOurSubnetMask= getenv_IPaddr ("netmask");
272+ NetOurVLAN = getenv_VLAN("vlan");
273+ NetOurNativeVLAN = getenv_VLAN("nvlan");
274+
275+ printf("starting httpd server from server %ld.%ld.%ld.%ld\n",
276+ (bd->bi_ip_addr & 0xff000000) >> 24,
277+ (bd->bi_ip_addr & 0x00ff0000) >> 16,
278+ (bd->bi_ip_addr & 0x0000ff00) >> 8,
279+ (bd->bi_ip_addr & 0x000000ff));
280+
281+ HttpdStart();
282+
283+ ip[0] = ((bd->bi_ip_addr & 0xffff0000) >> 16);
284+ ip[1] = (bd->bi_ip_addr & 0x0000ffff);
285+ uip_sethostaddr(ip);
286+
287+ do_http_progress(HTTP_PROGRESS_START);
288+
289+ https_running = 1;
290+ for (;;) {
291+ unsigned long long t1;
292+ WATCHDOG_RESET();
293+ if(eth_rx() > 0) {
294+ HttpdHandler();
295+ } else {
296+ t1 = get_ticks();
297+ if(t1 - tout > 1000) {
298+ do_http_progress(HTTP_PROGRESS_TIMEOUT);
299+ tout = t1;
300+ }
301+ }
302+ if(!httpd_upload_complete)
303+ continue;
304+ printf("Bytes transferred = %ld (%lx hex)\n",
305+ NetBootFileXferSize,
306+ NetBootFileXferSize);
307+ eth_halt();
308+ do_http_progress(HTTP_PROGRESS_UPLOAD_READY);
309+ if(do_http_upgrade(&httpd_upload_data[0], NetBootFileXferSize) == 0) {
310+ do_http_progress(HTTP_PROGRESS_UGRADE_READY);
311+ udelay(1000 * 10);
312+ do_reset (0,0,0,0);
313+ return 0;
314+ }
315+ break;
316+ }
317+ https_running = 0;
318+ NetBootFileXferSize = 0;
319+ httpd_upload_complete = 0;
320+ upload_running = 0;
321+// free(httpd_upload_data);
322+
323+ do_http_progress(HTTP_PROGRESS_UGRADE_FAILED);
324+
325+ goto restart;
326+
327+ return -1;
328+}
329+
330+#endif
331--- /dev/null
332+++ b/net/rsa/base64.c
333@@ -0,0 +1,137 @@
334+#include "base64.h"
335+
336+static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
337+/* Note that '=' (padding) is 0 */
338+static const unsigned char fb64[256] = {
339+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
340+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
341+ 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
342+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
343+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
344+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
345+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
346+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
347+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
348+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
349+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
350+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
351+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
352+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
353+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
354+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
355+};
356+
357+static int encodeblock( unsigned char *in, char *out, int len )
358+{
359+ char s[3];
360+ int i;
361+
362+ for (i = 0; i < len; i++)
363+ s[i] = in[i];
364+ for (i = len; i < 3; i++)
365+ s[i] = 0;
366+ out[0] = (unsigned char)(cb64[(s[0] & 0xfc) >> 2 ]);
367+ out[1] = (unsigned char)(cb64[((s[0] & 0x03) << 4) | ((s[1] & 0xf0) >> 4) ]);
368+ out[2] = (unsigned char)(cb64[((s[1] & 0x0f) << 2) | ((s[2] & 0xc0) >> 6) ]);
369+ out[3] = (unsigned char)(cb64[s[2] & 0x3f ]);
370+ switch (len) {
371+ case 1:
372+ out[3] = '=';
373+ case 2:
374+ out[2] = '=';
375+ break;
376+ default:
377+ break;
378+ }
379+
380+ return 4;
381+}
382+
383+static int decodeblock(char *ins, unsigned char *out, int len)
384+{
385+ int i;
386+ unsigned char in[4];
387+ int skip = 0;
388+
389+ if (len != 4)
390+ return -1;
391+ for (i = 0; i < len; i++) {
392+ if (ins[i] == '=') {
393+ in[i] = 0;
394+ skip++;
395+ } else
396+ in[i] = fb64[(int)(ins[i])];
397+ if (in[i] == 255) {
398+ return -1;
399+ }
400+ }
401+ out[0] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
402+ if (skip == 2) {
403+ return 1;
404+ }
405+ out[1] = (unsigned char )((in[1] & 0x0f) << 4 | in[2] >> 2);
406+ if (skip == 1) {
407+ return 2;
408+ }
409+ out[2] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
410+
411+ return 3;
412+}
413+
414+int B64_encode(char *source, char *destination, int size_source, int size_destination)
415+{
416+ int chunks, reminder, size, d, i, size_expected;
417+ char *s;
418+ unsigned char *t;
419+
420+ chunks = size_source / 3;
421+ reminder = size_source % 3;
422+ size = 0;
423+ size_expected = (chunks * 4) + (reminder?(reminder + 1):0);
424+ if (size_destination < ((chunks * 4) + (reminder?4:0))) {
425+ return 1;
426+ }
427+ for (i = 0; i < chunks; i++) {
428+ s = source + (i * 3);
429+ t = destination + (i * 4);
430+ d = encodeblock(s, t, 3);
431+ if (d == -1) {
432+ return 1;
433+ }
434+ size += d;
435+ }
436+ if (reminder) {
437+ d = encodeblock(source + (chunks * 3), destination + (chunks * 4), reminder);
438+ if (d == -1) {
439+ return 1;
440+ }
441+ size += d;
442+ }
443+ return size;
444+}
445+
446+int B64_decode(char *source, char *destination, int size_source, int size_destination)
447+{
448+ int chunks, reminder, size, d, i;
449+
450+ chunks = size_source / 4;
451+ reminder = size_source % 4;
452+ size = 0;
453+ if (reminder) {
454+ return 1;
455+ }
456+ if (size_destination < ((chunks * 3))) {
457+ printf("%d, %d\n",
458+ size_destination, ((chunks * 3) + reminder));
459+ return -1;
460+ }
461+ for (i = 0; i < chunks; i++) {
462+ d = decodeblock(source + (i * 4), destination + (i * 3), 4);
463+ if (d == -1) {
464+ return -1;
465+ }
466+ size += d;
467+ }
468+ return size;
469+}
470+
471--- /dev/null
472+++ b/net/rsa/base64.h
473@@ -0,0 +1,11 @@
474+#ifndef _BASE64_H_
475+#define _BASE64_H_
476+#ifdef __cplusplus
477+extern "C" {
478+#endif
479+int B64_encode(char *source, char *destination, int size_source, int size_destination);
480+int B64_decode(char *source, char *destination, int size_source, int size_destination);
481+#ifdef __cplusplus
482+}
483+#endif
484+#endif
485--- /dev/null
486+++ b/net/rsa/bigint.c
487@@ -0,0 +1,906 @@
488+/*
489+ * Copyright(C) 2006
490+ *
491+ * This library is free software; you can redistribute it and/or modify
492+ * it under the terms of the GNU Lesser General Public License as published by
493+ * the Free Software Foundation; either version 2.1 of the License, or
494+ * (at your option) any later version.
495+ *
496+ * This library is distributed in the hope that it will be useful,
497+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
498+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
499+ * GNU Lesser General Public License for more details.
500+ *
501+ * You should have received a copy of the GNU Lesser General Public License
502+ * along with this library; if not, write to the Free Software
503+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
504+ */
505+
506+/**
507+ * @defgroup bigint_api Big Integer API
508+ * @brief The bigint implementation as used by the axTLS project.
509+ *
510+ * The bigint library is for RSA encryption/decryption as well as signing.
511+ * This code tries to minimise use of malloc/free by maintaining a small
512+ * cache. A bigint context may maintain state by being made "permanent".
513+ * It be be later released with a bi_depermanent() and bi_free() call.
514+ *
515+ * It supports the following reduction techniques:
516+ * - Classical
517+ * - Barrett
518+ * - Montgomery
519+ *
520+ * It also implements the following:
521+ * - Karatsuba multiplication
522+ * - Squaring
523+ * - Sliding window exponentiation
524+ * - Chinese Remainder Theorem (implemented in rsa.c).
525+ *
526+ * All the algorithms used are pretty standard, and designed for different
527+ * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
528+ * may need to be tested for negativity.
529+ *
530+ * This library steals some ideas from Jef Poskanzer
531+ * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
532+ * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
533+ * detail from "The Handbook of Applied Cryptography"
534+ * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
535+ * @{
536+ */
537+
538+#include "bigint.h"
539+#include <malloc.h>
540+#include "div64.h"
541+
542+static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
543+static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
544+static bigint *alloc(BI_CTX *ctx, int size);
545+static bigint *trim(bigint *bi);
546+static void more_comps(bigint *bi, int n);
547+
548+/**
549+ * @brief Start a new bigint context.
550+ * @return A bigint context.
551+ */
552+BI_CTX *bi_initialize(void)
553+{
554+ BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
555+
556+ ctx->active_list = NULL;
557+ ctx->active_count = 0;
558+ ctx->free_list = NULL;
559+ ctx->free_count = 0;
560+ ctx->mod_offset = 0;
561+
562+ /* the radix */
563+ ctx->bi_radix = alloc(ctx, 2);
564+ ctx->bi_radix->comps[0] = 0;
565+ ctx->bi_radix->comps[1] = 1;
566+ bi_permanent(ctx->bi_radix);
567+
568+ return ctx;
569+}
570+
571+/**
572+ * @brief Close the bigint context and free any resources.
573+ *
574+ * Free up any used memory - a check is done if all objects were not
575+ * properly freed.
576+ * @param ctx [in] The bigint session context.
577+ */
578+void bi_terminate(BI_CTX *ctx)
579+{
580+ bigint *p, *pn;
581+
582+ bi_depermanent(ctx->bi_radix);
583+ bi_free(ctx, ctx->bi_radix);
584+
585+ if (ctx->active_count != 0)
586+ {
587+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
588+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
589+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
590+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
591+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
592+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
593+ return;
594+ }
595+
596+ for (p = ctx->free_list; p != NULL; p = pn)
597+ {
598+ pn = p->next;
599+ free(p->comps);
600+ free(p);
601+ }
602+
603+ free(ctx);
604+}
605+
606+/**
607+ * @brief Increment the number of references to this object.
608+ * It does not do a full copy.
609+ * @param bi [in] The bigint to copy.
610+ * @return A referent to the same bigint.
611+ */
612+bigint *bi_copy(bigint *bi)
613+{
614+ check(bi);
615+ if (bi->refs != PERMANENT)
616+ bi->refs++;
617+ return bi;
618+}
619+
620+/**
621+ * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
622+ *
623+ * For this object to be freed, bi_depermanent() must be called.
624+ * @param bi [in] The bigint to be made permanent.
625+ */
626+void bi_permanent(bigint *bi)
627+{
628+ check(bi);
629+ if (bi->refs != 1)
630+ {
631+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
632+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
633+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
634+ return;
635+ }
636+
637+ bi->refs = PERMANENT;
638+}
639+
640+/**
641+ * @brief Take a permanent object and make it elligible for freedom.
642+ * @param bi [in] The bigint to be made back to temporary.
643+ */
644+void bi_depermanent(bigint *bi)
645+{
646+ check(bi);
647+ if (bi->refs != PERMANENT)
648+ {
649+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
650+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
651+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
652+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
653+ return;
654+ }
655+
656+ bi->refs = 1;
657+}
658+
659+/**
660+ * @brief Free a bigint object so it can be used again.
661+ *
662+ * The memory itself it not actually freed, just tagged as being available
663+ * @param ctx [in] The bigint session context.
664+ * @param bi [in] The bigint to be freed.
665+ */
666+void bi_free(BI_CTX *ctx, bigint *bi)
667+{
668+ check(bi);
669+ if (bi->refs == PERMANENT)
670+ {
671+ return;
672+ }
673+
674+ if (--bi->refs > 0)
675+ {
676+ return;
677+ }
678+
679+ bi->next = ctx->free_list;
680+ ctx->free_list = bi;
681+ ctx->free_count++;
682+
683+ if (--ctx->active_count < 0)
684+ {
685+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
686+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
687+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
688+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
689+ return;
690+ }
691+}
692+
693+/**
694+ * @brief Convert an (unsigned) integer into a bigint.
695+ * @param ctx [in] The bigint session context.
696+ * @param i [in] The (unsigned) integer to be converted.
697+ *
698+ */
699+bigint *int_to_bi(BI_CTX *ctx, comp i)
700+{
701+ bigint *biR = alloc(ctx, 1);
702+ biR->comps[0] = i;
703+ return biR;
704+}
705+
706+/**
707+ * @brief Do a full copy of the bigint object.
708+ * @param ctx [in] The bigint session context.
709+ * @param bi [in] The bigint object to be copied.
710+ */
711+bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
712+{
713+ bigint *biR = alloc(ctx, bi->size);
714+ check(bi);
715+ memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
716+ return biR;
717+}
718+
719+/**
720+ * @brief Perform an additon operation between two bigints.
721+ * @param ctx [in] The bigint session context.
722+ * @param bia [in] A bigint.
723+ * @param bib [in] Another bigint.
724+ * @return The result of the addition.
725+ */
726+bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
727+{
728+ int n;
729+ comp carry = 0;
730+ comp *pa, *pb;
731+
732+ check(bia);
733+ check(bib);
734+
735+ if (bia->size > bib->size)
736+ n = bia->size;
737+ else
738+ n = bib->size;
739+ more_comps(bia, n+1);
740+ more_comps(bib, n);
741+ pa = bia->comps;
742+ pb = bib->comps;
743+
744+ do
745+ {
746+ comp sl, rl, cy1;
747+ sl = *pa + *pb++;
748+ rl = sl + carry;
749+ cy1 = sl < *pa;
750+ carry = cy1 | (rl < sl);
751+ *pa++ = rl;
752+ } while (--n != 0);
753+
754+ *pa = carry; /* do overflow */
755+ bi_free(ctx, bib);
756+ return trim(bia);
757+}
758+
759+/**
760+ * @brief Perform a subtraction operation between two bigints.
761+ * @param ctx [in] The bigint session context.
762+ * @param bia [in] A bigint.
763+ * @param bib [in] Another bigint.
764+ * @param is_negative [out] If defined, indicates that the result was negative.
765+ * is_negative may be NULL.
766+ * @return The result of the subtraction. The result is always positive.
767+ */
768+bigint *bi_subtract(BI_CTX *ctx,
769+ bigint *bia, bigint *bib, int *is_negative)
770+{
771+ int n = bia->size;
772+ comp *pa, *pb, carry = 0;
773+
774+ check(bia);
775+ check(bib);
776+
777+ more_comps(bib, n);
778+ pa = bia->comps;
779+ pb = bib->comps;
780+
781+ do
782+ {
783+ comp sl, rl, cy1;
784+ sl = *pa - *pb++;
785+ rl = sl - carry;
786+ cy1 = sl > *pa;
787+ carry = cy1 | (rl > sl);
788+ *pa++ = rl;
789+ } while (--n != 0);
790+
791+ if (is_negative) /* indicate a negative result */
792+ {
793+ *is_negative = carry;
794+ }
795+
796+ bi_free(ctx, trim(bib)); /* put bib back to the way it was */
797+ return trim(bia);
798+}
799+
800+/**
801+ * Perform a multiply between a bigint an an (unsigned) integer
802+ */
803+static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
804+{
805+ int j = 0, n = bia->size;
806+ bigint *biR = alloc(ctx, n + 1);
807+ comp carry = 0;
808+ comp *r = biR->comps;
809+ comp *a = bia->comps;
810+
811+ check(bia);
812+
813+ /* clear things to start with */
814+ memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
815+
816+ do
817+ {
818+ long_comp tmp = *r + (long_comp)a[j]*b + carry;
819+ *r++ = (comp)tmp; /* downsize */
820+ carry = (comp)(tmp >> COMP_BIT_SIZE);
821+ } while (++j < n);
822+
823+ *r = carry;
824+ bi_free(ctx, bia);
825+ return trim(biR);
826+}
827+
828+/**
829+ * @brief Does both division and modulo calculations.
830+ *
831+ * Used extensively when doing classical reduction.
832+ * @param ctx [in] The bigint session context.
833+ * @param u [in] A bigint which is the numerator.
834+ * @param v [in] Either the denominator or the modulus depending on the mode.
835+ * @param is_mod [n] Determines if this is a normal division (0) or a reduction
836+ * (1).
837+ * @return The result of the division/reduction.
838+ */
839+bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
840+{
841+ int n = v->size, m = u->size-n;
842+ int j = 0, orig_u_size = u->size;
843+ uint8_t mod_offset = ctx->mod_offset;
844+ comp d;
845+ bigint *quotient, *tmp_u;
846+ comp q_dash;
847+
848+ check(u);
849+ check(v);
850+
851+ /* if doing reduction and we are < mod, then return mod */
852+ if (is_mod && bi_compare(v, u) > 0)
853+ {
854+ bi_free(ctx, v);
855+ return u;
856+ }
857+
858+ quotient = alloc(ctx, m+1);
859+ tmp_u = alloc(ctx, n+1);
860+ v = trim(v); /* make sure we have no leading 0's */
861+ // d = (comp)((long_comp)COMP_RADIX/(V1+1));
862+ long_comp x = COMP_RADIX; do_div(x, V1+1); d = x;
863+
864+ /* clear things to start with */
865+ memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
866+
867+ /* normalise */
868+ if (d > 1)
869+ {
870+ u = bi_int_multiply(ctx, u, d);
871+
872+ if (is_mod)
873+ {
874+ v = ctx->bi_normalised_mod[mod_offset];
875+ }
876+ else
877+ {
878+ v = bi_int_multiply(ctx, v, d);
879+ }
880+ }
881+
882+ if (orig_u_size == u->size) /* new digit position u0 */
883+ {
884+ more_comps(u, orig_u_size + 1);
885+ }
886+
887+ do
888+ {
889+ /* get a temporary short version of u */
890+ memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
891+
892+ /* calculate q' */
893+ if (U(0) == V1)
894+ {
895+ q_dash = COMP_RADIX-1;
896+ }
897+ else
898+ {
899+ //q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
900+ long_comp x = U(0)*COMP_RADIX + U(1); do_div(x, V1); q_dash = x;
901+
902+ }
903+
904+ if (v->size > 1 && V2)
905+ {
906+ /* we are implementing the following
907+ if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
908+ q_dash*V1)*COMP_RADIX) + U(2))) ... */
909+ comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
910+ (long_comp)q_dash*V1);
911+ if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
912+ {
913+ q_dash--;
914+ }
915+ }
916+
917+ /* multiply and subtract */
918+ if (q_dash)
919+ {
920+ int is_negative;
921+ tmp_u = bi_subtract(ctx, tmp_u,
922+ bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
923+ more_comps(tmp_u, n+1);
924+
925+ Q(j) = q_dash;
926+
927+ /* add back */
928+ if (is_negative)
929+ {
930+ Q(j)--;
931+ tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
932+ /* lop off the carry */
933+ tmp_u->size--;
934+ v->size--;
935+ }
936+ }
937+ else
938+ {
939+ Q(j) = 0;
940+ }
941+
942+ /* copy back to u */
943+ memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
944+ } while (++j <= m);
945+
946+ bi_free(ctx, tmp_u);
947+ bi_free(ctx, v);
948+
949+ if (is_mod) /* get the remainder */
950+ {
951+ bi_free(ctx, quotient);
952+ return bi_int_divide(ctx, trim(u), d);
953+ }
954+ else /* get the quotient */
955+ {
956+ bi_free(ctx, u);
957+ return trim(quotient);
958+ }
959+}
960+
961+/**
962+ * Perform an integer divide on a bigint.
963+ */
964+static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom)
965+{
966+ int i = biR->size - 1;
967+ long_comp r = 0;
968+
969+ check(biR);
970+
971+ do
972+ {
973+ r = (r<<COMP_BIT_SIZE) + biR->comps[i];
974+ //biR->comps[i] = (comp)(r / denom);
975+ long_comp x = r; do_div(x, denom); biR->comps[i] = x;
976+/* while(r > denom)
977+ {
978+ r -= denom;
979+ }*/
980+ r%=denom;
981+ } while (--i != 0);
982+
983+ return trim(biR);
984+}
985+
986+/**
987+ * @brief Allow a binary sequence to be imported as a bigint.
988+ * @param ctx [in] The bigint session context.
989+ * @param data [in] The data to be converted.
990+ * @param size [in] The number of bytes of data.
991+ * @return A bigint representing this data.
992+ */
993+bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
994+{
995+ bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
996+ int i, j = 0, offset = 0;
997+
998+ memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
999+
1000+ for (i = size-1; i >= 0; i--)
1001+ {
1002+ biR->comps[offset] += data[i] << (j*8);
1003+
1004+ if (++j == COMP_BYTE_SIZE)
1005+ {
1006+ j = 0;
1007+ offset ++;
1008+ }
1009+ }
1010+
1011+ return trim(biR);
1012+}
1013+
1014+/**
1015+ * @brief Take a bigint and convert it into a byte sequence.
1016+ *
1017+ * This is useful after a decrypt operation.
1018+ * @param ctx [in] The bigint session context.
1019+ * @param x [in] The bigint to be converted.
1020+ * @param data [out] The converted data as a byte stream.
1021+ * @param size [in] The maximum size of the byte stream. Unused bytes will be
1022+ * zeroed.
1023+ */
1024+void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
1025+{
1026+ int i, j, k = size-1;
1027+
1028+ check(x);
1029+ memset(data, 0, size); /* ensure all leading 0's are cleared */
1030+
1031+ for (i = 0; i < x->size; i++)
1032+ {
1033+ for (j = 0; j < COMP_BYTE_SIZE; j++)
1034+ {
1035+ comp mask = 0xff << (j*8);
1036+ int num = (x->comps[i] & mask) >> (j*8);
1037+ data[k--] = num;
1038+
1039+ if (k < 0)
1040+ {
1041+ break;
1042+ }
1043+ }
1044+ }
1045+
1046+ bi_free(ctx, x);
1047+}
1048+
1049+/**
1050+ * @brief Pre-calculate some of the expensive steps in reduction.
1051+ *
1052+ * This function should only be called once (normally when a session starts).
1053+ * When the session is over, bi_free_mod() should be called. bi_mod_power()
1054+ * relies on this function being called.
1055+ * @param ctx [in] The bigint session context.
1056+ * @param bim [in] The bigint modulus that will be used.
1057+ * @param mod_offset [in] There are three moduluii that can be stored - the
1058+ * standard modulus, and it's two primes p and q. This offset refers to which
1059+ * modulus we are referring to.
1060+ * @see bi_free_mod(), bi_mod_power().
1061+ */
1062+void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
1063+{
1064+ int k = bim->size;
1065+ comp d;
1066+// comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
1067+ long_comp x = COMP_RADIX; do_div(x, bim->comps[k-1]+1); d = x;
1068+
1069+ ctx->bi_mod[mod_offset] = bim;
1070+ bi_permanent(ctx->bi_mod[mod_offset]);
1071+ ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
1072+ bi_permanent(ctx->bi_normalised_mod[mod_offset]);
1073+}
1074+
1075+/**
1076+ * @brief Used when cleaning various bigints at the end of a session.
1077+ * @param ctx [in] The bigint session context.
1078+ * @param mod_offset [in] The offset to use.
1079+ * @see bi_set_mod().
1080+ */
1081+void bi_free_mod(BI_CTX *ctx, int mod_offset)
1082+{
1083+ bi_depermanent(ctx->bi_mod[mod_offset]);
1084+ bi_free(ctx, ctx->bi_mod[mod_offset]);
1085+ bi_depermanent(ctx->bi_normalised_mod[mod_offset]);
1086+ bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
1087+}
1088+
1089+/**
1090+ * Perform a standard multiplication between two bigints.
1091+ */
1092+static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
1093+{
1094+ int i, j, i_plus_j, n = bia->size, t = bib->size;
1095+ bigint *biR = alloc(ctx, n + t);
1096+ comp *sr = biR->comps;
1097+ comp *sa = bia->comps;
1098+ comp *sb = bib->comps;
1099+
1100+ check(bia);
1101+ check(bib);
1102+
1103+ /* clear things to start with */
1104+ memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
1105+ i = 0;
1106+
1107+ do
1108+ {
1109+ comp carry = 0;
1110+ comp b = *sb++;
1111+ i_plus_j = i;
1112+ j = 0;
1113+
1114+ do
1115+ {
1116+ long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
1117+ sr[i_plus_j++] = (comp)tmp; /* downsize */
1118+ carry = (comp)(tmp >> COMP_BIT_SIZE);
1119+ } while (++j < n);
1120+
1121+ sr[i_plus_j] = carry;
1122+ } while (++i < t);
1123+
1124+ bi_free(ctx, bia);
1125+ bi_free(ctx, bib);
1126+ return trim(biR);
1127+}
1128+
1129+/**
1130+ * @brief Perform a multiplication operation between two bigints.
1131+ * @param ctx [in] The bigint session context.
1132+ * @param bia [in] A bigint.
1133+ * @param bib [in] Another bigint.
1134+ * @return The result of the multiplication.
1135+ */
1136+bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
1137+{
1138+ check(bia);
1139+ check(bib);
1140+
1141+ return regular_multiply(ctx, bia, bib);
1142+}
1143+
1144+
1145+/**
1146+ * @brief Compare two bigints.
1147+ * @param bia [in] A bigint.
1148+ * @param bib [in] Another bigint.
1149+ * @return -1 if smaller, 1 if larger and 0 if equal.
1150+ */
1151+int bi_compare(bigint *bia, bigint *bib)
1152+{
1153+ int r, i;
1154+
1155+ check(bia);
1156+ check(bib);
1157+
1158+ if (bia->size > bib->size)
1159+ r = 1;
1160+ else if (bia->size < bib->size)
1161+ r = -1;
1162+ else
1163+ {
1164+ comp *a = bia->comps;
1165+ comp *b = bib->comps;
1166+
1167+ /* Same number of components. Compare starting from the high end
1168+ * and working down. */
1169+ r = 0;
1170+ i = bia->size - 1;
1171+
1172+ do
1173+ {
1174+ if (a[i] > b[i])
1175+ {
1176+ r = 1;
1177+ break;
1178+ }
1179+ else if (a[i] < b[i])
1180+ {
1181+ r = -1;
1182+ break;
1183+ }
1184+ } while (--i >= 0);
1185+ }
1186+
1187+ return r;
1188+}
1189+
1190+/**
1191+ * Allocate and zero more components. Does not consume bi.
1192+ */
1193+static void more_comps(bigint *bi, int n)
1194+{
1195+ if (n > bi->max_comps)
1196+ {
1197+ if ((bi->max_comps * 2) > n) {
1198+ bi->max_comps = bi->max_comps * 2;
1199+ } else {
1200+ bi->max_comps = n;
1201+ }
1202+ bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
1203+ }
1204+
1205+ if (n > bi->size)
1206+ {
1207+ memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
1208+ }
1209+
1210+ bi->size = n;
1211+}
1212+
1213+/*
1214+ * Make a new empty bigint. It may just use an old one if one is available.
1215+ * Otherwise get one of the heap.
1216+ */
1217+static bigint *alloc(BI_CTX *ctx, int size)
1218+{
1219+ bigint *biR;
1220+
1221+ /* Can we recycle an old bigint? */
1222+ if (ctx->free_list != NULL)
1223+ {
1224+ biR = ctx->free_list;
1225+ ctx->free_list = biR->next;
1226+ ctx->free_count--;
1227+ if (biR->refs != 0)
1228+ {
1229+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1230+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1231+ printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1232+ return 0;
1233+ }
1234+
1235+ more_comps(biR, size);
1236+ }
1237+ else
1238+ {
1239+ /* No free bigints available - create a new one. */
1240+ biR = (bigint *)malloc(sizeof(bigint));
1241+ biR->comps = (comp*) malloc(size * COMP_BYTE_SIZE);
1242+ biR->max_comps = size; /* give some space to spare */
1243+ }
1244+
1245+ biR->size = size;
1246+ biR->refs = 1;
1247+ biR->next = NULL;
1248+ ctx->active_count++;
1249+ return biR;
1250+}
1251+
1252+/*
1253+ * Work out the highest '1' bit in an exponent. Used when doing sliding-window
1254+ * exponentiation.
1255+ */
1256+static int find_max_exp_index(bigint *biexp)
1257+{
1258+ int i = COMP_BIT_SIZE-1;
1259+ comp shift = COMP_RADIX/2;
1260+ comp test = biexp->comps[biexp->size-1]; /* assume no leading zeroes */
1261+
1262+ check(biexp);
1263+
1264+ do
1265+ {
1266+ if (test & shift)
1267+ {
1268+ return i+(biexp->size-1)*COMP_BIT_SIZE;
1269+ }
1270+
1271+ shift >>= 1;
1272+ } while (--i != 0);
1273+
1274+ return -1; /* error - must have been a leading 0 */
1275+}
1276+
1277+/*
1278+ * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
1279+ * exponentiation.
1280+ */
1281+static int exp_bit_is_one(bigint *biexp, int offset)
1282+{
1283+ comp test = biexp->comps[offset / COMP_BIT_SIZE];
1284+ int num_shifts = offset % COMP_BIT_SIZE;
1285+ comp shift = 1;
1286+ int i;
1287+
1288+ check(biexp);
1289+
1290+ for (i = 0; i < num_shifts; i++)
1291+ {
1292+ shift <<= 1;
1293+ }
1294+
1295+ return test & shift;
1296+}
1297+
1298+/*
1299+ * Delete any leading 0's (and allow for 0).
1300+ */
1301+static bigint *trim(bigint *bi)
1302+{
1303+ check(bi);
1304+
1305+ while (bi->comps[bi->size-1] == 0 && bi->size > 1)
1306+ {
1307+ bi->size--;
1308+ }
1309+
1310+ return bi;
1311+}
1312+
1313+/**
1314+ * @brief Perform a modular exponentiation.
1315+ *
1316+ * This function requires bi_set_mod() to have been called previously. This is
1317+ * one of the optimisations used for performance.
1318+ * @param ctx [in] The bigint session context.
1319+ * @param bi [in] The bigint on which to perform the mod power operation.
1320+ * @param biexp [in] The bigint exponent.
1321+ * @see bi_set_mod().
1322+ */
1323+bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
1324+{
1325+ int i = find_max_exp_index(biexp), j, window_size = 1;
1326+ bigint *biR = int_to_bi(ctx, 1);
1327+
1328+ check(bi);
1329+ check(biexp);
1330+
1331+ ctx->g = (bigint **)malloc(sizeof(bigint *));
1332+ ctx->g[0] = bi_clone(ctx, bi);
1333+ ctx->window = 1;
1334+ bi_permanent(ctx->g[0]);
1335+
1336+ /* if sliding-window is off, then only one bit will be done at a time and
1337+ * will reduce to standard left-to-right exponentiation */
1338+ do
1339+ {
1340+ if (exp_bit_is_one(biexp, i))
1341+ {
1342+ int l = i-window_size+1;
1343+ int part_exp = 0;
1344+
1345+ if (l < 0) /* LSB of exponent will always be 1 */
1346+ {
1347+ l = 0;
1348+ }
1349+ else
1350+ {
1351+ while (exp_bit_is_one(biexp, l) == 0)
1352+ {
1353+ l++; /* go back up */
1354+ }
1355+ }
1356+
1357+ /* build up the section of the exponent */
1358+ for (j = i; j >= l; j--)
1359+ {
1360+ biR = bi_residue(ctx, bi_square(ctx, biR));
1361+ if (exp_bit_is_one(biexp, j))
1362+ part_exp++;
1363+
1364+ if (j != l)
1365+ part_exp <<= 1;
1366+ }
1367+
1368+ part_exp = (part_exp-1)/2; /* adjust for array */
1369+ biR = bi_residue(ctx,
1370+ bi_multiply(ctx, biR, ctx->g[part_exp]));
1371+ i = l-1;
1372+ }
1373+ else /* square it */
1374+ {
1375+ biR = bi_residue(ctx, bi_square(ctx, biR));
1376+ i--;
1377+ }
1378+ } while (i >= 0);
1379+
1380+ /* cleanup */
1381+ for (i = 0; i < ctx->window; i++)
1382+ {
1383+ bi_depermanent(ctx->g[i]);
1384+ bi_free(ctx, ctx->g[i]);
1385+ }
1386+
1387+ free(ctx->g);
1388+ bi_free(ctx, bi);
1389+ bi_free(ctx, biexp);
1390+ return biR;
1391+}
1392+
1393+/** @} */
1394--- /dev/null
1395+++ b/net/rsa/bigint.h
1396@@ -0,0 +1,73 @@
1397+/*
1398+ * Copyright(C) 2006
1399+ *
1400+ * This library is free software; you can redistribute it and/or modify
1401+ * it under the terms of the GNU Lesser General Public License as published by
1402+ * the Free Software Foundation; either version 2 of the License, or
1403+ * (at your option) any later version.
1404+ *
1405+ * This library is distributed in the hope that it will be useful,
1406+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1407+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1408+ * GNU Lesser General Public License for more details.
1409+ *
1410+ * You should have received a copy of the GNU Lesser General Public License
1411+ * along with this library; if not, write to the Free Software
1412+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1413+ *
1414+ * Trimmed down from axTLS
1415+ *
1416+ * $Id: bigint.h 392 2007-06-25 16:24:51Z pablo.martin $
1417+ *
1418+ */
1419+
1420+#ifndef BIGINT_HEADER
1421+#define BIGINT_HEADER
1422+
1423+#define CONFIG_BIGINT_CLASSICAL 1
1424+
1425+#define SOCKET_READ(A,B,C) read(A,B,C)
1426+#define SOCKET_WRITE(A,B,C) write(A,B,C)
1427+#define SOCKET_CLOSE(A) close(A)
1428+#define TTY_FLUSH()
1429+
1430+#include "bigint_impl.h"
1431+
1432+#ifndef CONFIG_BIGINT_CHECK_ON
1433+#define check(A) /**< disappears in normal production mode */
1434+#endif
1435+BI_CTX *bi_initialize(void);
1436+void bi_terminate(BI_CTX *ctx);
1437+void bi_permanent(bigint *bi);
1438+void bi_depermanent(bigint *bi);
1439+void bi_free(BI_CTX *ctx, bigint *bi);
1440+bigint *bi_copy(bigint *bi);
1441+bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
1442+void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size);
1443+bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len);
1444+bigint *int_to_bi(BI_CTX *ctx, comp i);
1445+
1446+/* the functions that actually do something interesting */
1447+bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib);
1448+bigint *bi_subtract(BI_CTX *ctx, bigint *bia,
1449+ bigint *bib, int *is_negative);
1450+bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod);
1451+bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib);
1452+bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp);
1453+bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp);
1454+int bi_compare(bigint *bia, bigint *bib);
1455+void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset);
1456+void bi_free_mod(BI_CTX *ctx, int mod_offset);
1457+
1458+/**
1459+ * @def bi_mod
1460+ * Find the residue of B. bi_set_mod() must be called before hand.
1461+ */
1462+#define bi_mod(A, B) bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1)
1463+
1464+#define bi_residue(A, B) bi_mod(A, B)
1465+
1466+#define bi_square(A, B) bi_multiply(A, bi_copy(B), B)
1467+
1468+#endif
1469+
1470--- /dev/null
1471+++ b/net/rsa/bigint_impl.h
1472@@ -0,0 +1,109 @@
1473+/*
1474+ * Copyright(C) 2006
1475+ *
1476+ * This library is free software; you can redistribute it and/or modify
1477+ * it under the terms of the GNU Lesser General Public License as published by
1478+ * the Free Software Foundation; either version 2.1 of the License, or
1479+ * (at your option) any later version.
1480+ *
1481+ * This library is distributed in the hope that it will be useful,
1482+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1483+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1484+ * GNU Lesser General Public License for more details.
1485+ *
1486+ * You should have received a copy of the GNU Lesser General Public License
1487+ * along with this library; if not, write to the Free Software
1488+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1489+ */
1490+
1491+#ifndef BIGINT_IMPL_HEADER
1492+#define BIGINT_IMPL_HEADER
1493+
1494+#include <linux/types.h>
1495+#include <common.h>
1496+
1497+/* Maintain a number of precomputed variables when doing reduction */
1498+#define BIGINT_M_OFFSET 0 /**< Normal modulo offset. */
1499+#ifdef CONFIG_BIGINT_CRT
1500+#define BIGINT_P_OFFSET 1 /**< p modulo offset. */
1501+#define BIGINT_Q_OFFSET 2 /**< q module offset. */
1502+#define BIGINT_NUM_MODS 3 /**< The number of modulus constants used. */
1503+#else
1504+#define BIGINT_NUM_MODS 1
1505+#endif
1506+
1507+/* Architecture specific functions for big ints */
1508+// #ifdef WIN32
1509+// #define COMP_RADIX 4294967296i64
1510+// #define COMP_BIG_MSB 0x8000000000000000i64
1511+// #else
1512+#define COMP_RADIX 4294967296ULL /**< Max component + 1 */
1513+#define COMP_BIG_MSB 0x8000000000000000ULL /**< (Max dbl comp + 1)/ 2 */
1514+//#endif
1515+#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */
1516+#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */
1517+#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */
1518+
1519+typedef uint32_t comp; /**< A single precision component. */
1520+typedef uint64_t long_comp; /**< A double precision component. */
1521+typedef int64_t slong_comp; /**< A signed double precision component. */
1522+
1523+/**
1524+ * @struct _bigint
1525+ * @brief A big integer basic object
1526+ */
1527+struct _bigint
1528+{
1529+ struct _bigint* next; /**< The next bigint in the cache. */
1530+ short size; /**< The number of components in this bigint. */
1531+ short max_comps; /**< The heapsize allocated for this bigint */
1532+ int refs; /**< An internal reference count. */
1533+ comp* comps; /**< A ptr to the actual component data */
1534+};
1535+
1536+typedef struct _bigint bigint; /**< An alias for _bigint */
1537+
1538+/**
1539+ * Maintains the state of the cache, and a number of variables used in
1540+ * reduction.
1541+ */
1542+typedef struct /**< A big integer "session" context. */
1543+{
1544+ bigint *active_list; /**< Bigints currently used. */
1545+ bigint *free_list; /**< Bigints not used. */
1546+ bigint *bi_radix; /**< The radix used. */
1547+ bigint *bi_mod[BIGINT_NUM_MODS]; /**< modulus */
1548+
1549+#if defined(CONFIG_BIGINT_MONTGOMERY)
1550+ bigint *bi_RR_mod_m[BIGINT_NUM_MODS]; /**< R^2 mod m */
1551+ bigint *bi_R_mod_m[BIGINT_NUM_MODS]; /**< R mod m */
1552+ comp N0_dash[BIGINT_NUM_MODS];
1553+#elif defined(CONFIG_BIGINT_BARRETT)
1554+ bigint *bi_mu[BIGINT_NUM_MODS]; /**< Storage for mu */
1555+#endif
1556+ bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */
1557+ bigint **g; /**< Used by sliding-window. */
1558+ int window; /**< The size of the sliding window */
1559+
1560+ int active_count; /**< Number of active bigints. */
1561+ int free_count; /**< Number of free bigints. */
1562+
1563+#ifdef CONFIG_BIGINT_MONTGOMERY
1564+ uint8_t use_classical; /**< Use classical reduction. */
1565+#endif
1566+ uint8_t mod_offset; /**< The mod offset we are using */
1567+} BI_CTX;
1568+
1569+#if 0
1570+#define max(a,b) ((a)>(b)?(a):(b)) /**< Find the maximum of 2 numbers. */
1571+#define min(a,b) ((a)<(b)?(a):(b)) /**< Find the minimum of 2 numbers. */
1572+#endif
1573+
1574+#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */
1575+
1576+#define V1 v->comps[v->size-1] /**< v1 for division */
1577+#define V2 v->comps[v->size-2] /**< v2 for division */
1578+#define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */
1579+#define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */
1580+
1581+#endif
1582--- /dev/null
1583+++ b/net/rsa/div64.h
1584@@ -0,0 +1,113 @@
1585+/*
1586+ * Copyright (C) 2000, 2004 Maciej W. Rozycki
1587+ * Copyright (C) 2003 Ralf Baechle
1588+ *
1589+ * This file is subject to the terms and conditions of the GNU General Public
1590+ * License. See the file "COPYING" in the main directory of this archive
1591+ * for more details.
1592+ */
1593+#ifndef _ASM_DIV64_H
1594+#define _ASM_DIV64_H
1595+
1596+#if (_MIPS_SZLONG == 32)
1597+
1598+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
1599+#define GCC_REG_ACCUM "$0"
1600+#else
1601+#define GCC_REG_ACCUM "accum"
1602+#endif
1603+
1604+
1605+//#include <asm/compiler.h>
1606+
1607+/*
1608+ * No traps on overflows for any of these...
1609+ */
1610+
1611+#define do_div64_32(res, high, low, base) ({ \
1612+ unsigned long __quot, __mod; \
1613+ unsigned long __cf, __tmp, __tmp2, __i; \
1614+ \
1615+ __asm__(".set push\n\t" \
1616+ ".set noat\n\t" \
1617+ ".set noreorder\n\t" \
1618+ "move %2, $0\n\t" \
1619+ "move %3, $0\n\t" \
1620+ "b 1f\n\t" \
1621+ " li %4, 0x21\n" \
1622+ "0:\n\t" \
1623+ "sll $1, %0, 0x1\n\t" \
1624+ "srl %3, %0, 0x1f\n\t" \
1625+ "or %0, $1, %5\n\t" \
1626+ "sll %1, %1, 0x1\n\t" \
1627+ "sll %2, %2, 0x1\n" \
1628+ "1:\n\t" \
1629+ "bnez %3, 2f\n\t" \
1630+ " sltu %5, %0, %z6\n\t" \
1631+ "bnez %5, 3f\n" \
1632+ "2:\n\t" \
1633+ " addiu %4, %4, -1\n\t" \
1634+ "subu %0, %0, %z6\n\t" \
1635+ "addiu %2, %2, 1\n" \
1636+ "3:\n\t" \
1637+ "bnez %4, 0b\n\t" \
1638+ " srl %5, %1, 0x1f\n\t" \
1639+ ".set pop" \
1640+ : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
1641+ "=&r" (__i), "=&r" (__tmp2) \
1642+ : "Jr" (base), "0" (high), "1" (low)); \
1643+ \
1644+ (res) = __quot; \
1645+ __mod; })
1646+
1647+#define do_div(n, base) ({ \
1648+ unsigned long long __quot; \
1649+ unsigned long __mod; \
1650+ unsigned long long __div; \
1651+ unsigned long __upper, __low, __high, __base; \
1652+ \
1653+ __div = (n); \
1654+ __base = (base); \
1655+ \
1656+ __high = __div >> 32; \
1657+ __low = __div; \
1658+ __upper = __high; \
1659+ \
1660+ if (__high) \
1661+ __asm__("divu $0, %z2, %z3" \
1662+ : "=h" (__upper), "=l" (__high) \
1663+ : "Jr" (__high), "Jr" (__base) \
1664+ : GCC_REG_ACCUM); \
1665+ \
1666+ __mod = do_div64_32(__low, __upper, __low, __base); \
1667+ \
1668+ __quot = __high; \
1669+ __quot = __quot << 32 | __low; \
1670+ (n) = __quot; \
1671+ __mod; })
1672+#endif /* (_MIPS_SZLONG == 32) */
1673+
1674+#if (_MIPS_SZLONG == 64)
1675+
1676+/*
1677+ * Hey, we're already 64-bit, no
1678+ * need to play games..
1679+ */
1680+#define do_div(n, base) ({ \
1681+ unsigned long __quot; \
1682+ unsigned int __mod; \
1683+ unsigned long __div; \
1684+ unsigned int __base; \
1685+ \
1686+ __div = (n); \
1687+ __base = (base); \
1688+ \
1689+ __mod = __div % __base; \
1690+ __quot = __div / __base; \
1691+ \
1692+ (n) = __quot; \
1693+ __mod; })
1694+
1695+#endif /* (_MIPS_SZLONG == 64) */
1696+
1697+#endif /* _ASM_DIV64_H */
1698--- /dev/null
1699+++ b/net/rsa/dump_key.c
1700@@ -0,0 +1,29 @@
1701+#include <stdio.h>
1702+#include <stdlib.h>
1703+#include <sys/types.h>
1704+#include <sys/stat.h>
1705+#include <unistd.h>
1706+
1707+int main(int argc, char **argv)
1708+{
1709+ FILE *fp = fopen("public_fon_rsa_key_6.pem", "r");
1710+ struct stat s;
1711+ unsigned char *b;
1712+ int i;
1713+ if(!fp)
1714+ return 1;
1715+ stat("public_fon_rsa_key_6.pem", &s);
1716+ b = malloc(s.st_size);
1717+ fread(b, s.st_size, 1, fp);
1718+ fclose(fp);
1719+ printf("unsigned char public_key[] = {\n\t");
1720+ for(i = 0;i < s.st_size; i++)
1721+ {
1722+ printf("0x%02X,", b[i]);
1723+ if(i%16 == 15)
1724+ printf("\n\t");
1725+ }
1726+ printf("};\n");
1727+// printf("\n%d %d\n", i, s.st_size);
1728+ return 0;
1729+}
1730--- /dev/null
1731+++ b/net/rsa/foncheckrsa.c
1732@@ -0,0 +1,79 @@
1733+/*
1734+ * RSA + RIPEMD160 signature verification command
1735+ *
1736+ * Copyright (C) 2007 FON Wireless Ltd.
1737+ *
1738+ * This program is free software; you can redistribute it and/or
1739+ * modify it under the terms of the GNU General Public License
1740+ * as published by the Free Software Foundation; either version 2
1741+ * of the License, or (at your option) any later version.
1742+ *
1743+ * This program is distributed in the hope that it will be useful,
1744+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1745+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1746+ * GNU General Public License for more details.
1747+ *
1748+ * You should have received a copy of the GNU General Public License
1749+ * along with this program; if not, write to the Free Software
1750+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1751+ *
1752+ * Created: 20060728 Pablo Martín Medrano <pablo@fon.com>
1753+ *
1754+ * $Id: foncheckrsa.c 332 2007-05-02 09:45:54Z pablo.martin $
1755+ */
1756+#include <stdio.h>
1757+#include <stdlib.h>
1758+#include <sys/types.h>
1759+#include <sys/stat.h>
1760+#include <fcntl.h>
1761+#include <string.h>
1762+#include <errno.h>
1763+#include <unistd.h>
1764+#include "fonrsa.h"
1765+
1766+int main(int argc, char **argv)
1767+{
1768+ int fd, i;
1769+ FONRSA_ERROR fonrsa_error;
1770+ void *handle;
1771+
1772+ if (argc != 4) {
1773+ fprintf(stderr, " Usage: foncheckrsa [public_key.der] [signature] [file]\n");
1774+ fprintf(stderr, " Pablo Martín Medrano <pablo@fon.com>\n");
1775+ fprintf(stderr, " RIPEMD-160 software written by Antoon Bosselaers,\n");
1776+ fprintf(stderr, " available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.\n");
1777+ fprintf(stderr, " Uses the axTLS library bigint implementation (libfonrsa)\n");
1778+ fprintf(stderr, " http://www.leroc.com.au/axTLS/\n");
1779+ return -1;
1780+ }
1781+ /* Check the existence of input files */
1782+ for (i = 1; i < 4; i++) {
1783+ if ((fd = open(argv[i], O_RDONLY)) == -1) {
1784+ fprintf(stderr, "Error: opening \"%s\": %s\n", argv[i],
1785+ strerror(errno));
1786+ fprintf(stderr, "Bailing out...");
1787+ exit(-2);
1788+ }
1789+ close(fd);
1790+ }
1791+ handle = FR_init(argv[1]);
1792+ if (handle == NULL) {
1793+ printf("Error loading keys in %s\n", argv[1]);
1794+ return 1;
1795+ }
1796+ fonrsa_error = FR_verify_file(handle, argv[3], argv[2]);
1797+ FR_end(handle);
1798+ switch (fonrsa_error) {
1799+ case FONRSA_OK:
1800+ printf("Verified OK\n");
1801+ return 0;
1802+ case FONRSA_VERIFICATION_FAILURE:
1803+ printf("Verification failure\n");
1804+ return 1;
1805+ default:
1806+ printf("Verification error\n");
1807+ return -1;
1808+ }
1809+ return -1;
1810+}
1811+
1812--- /dev/null
1813+++ b/net/rsa/fonrsa.c
1814@@ -0,0 +1,584 @@
1815+/*
1816+ * FONSM RSA handling library
1817+ *
1818+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
1819+ *
1820+ * This library is free software; you can redistribute it and/or modify
1821+ * it under the terms of the GNU Lesser General Public License as published by
1822+ * the Free Software Foundation; either version 2 of the License, or
1823+ * (at your option) any later version.
1824+ *
1825+ * This library is distributed in the hope that it will be useful,
1826+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1827+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1828+ * GNU Lesser General Public License for more details.
1829+ *
1830+ * You should have received a copy of the GNU Lesser General Public License
1831+ * along with this library; if not, write to the Free Software
1832+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1833+ *
1834+ * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
1835+ *
1836+ * Based on axTLS
1837+ *
1838+ * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
1839+ */
1840+#include <sys/types.h>
1841+#include <stdlib.h>
1842+#include <stdio.h>
1843+#include <string.h>
1844+#include <sys/types.h>
1845+#include <sys/stat.h>
1846+#include <fcntl.h>
1847+#include <unistd.h>
1848+#include <errno.h>
1849+#include "rmd160.h"
1850+#include "bigint.h"
1851+#include "fonrsa.h"
1852+#include "base64.h"
1853+
1854+typedef struct {
1855+ uint8_t *buffer;
1856+ size_t size;
1857+} DER_key;
1858+
1859+typedef struct {
1860+ bigint *m; /* modulus */
1861+ bigint *e; /* public exponent */
1862+ int num_octets;
1863+ BI_CTX *bi_ctx; /* big integer handle */
1864+} RSA_parameters;
1865+
1866+typedef struct {
1867+ DER_key *derkey;
1868+ RSA_parameters *rsaparms;
1869+} RSA;
1870+
1871+static uint8_t *CH_load_raw_file(char *filename, size_t *size);
1872+static DER_key *CH_load_der_key(char *filename);
1873+static void CH_free_der_key(DER_key *key);
1874+static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters);
1875+void CH_pub_key_new(RSA_parameters **rsa_parameters, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len);
1876+int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out);
1877+byte *RMDbinary(char *fname);
1878+int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file);
1879+static unsigned char *load_file_in_buffer(char *path, int *size);
1880+static int save_file_from_buffer(char *path, unsigned char *buffer, int size);
1881+int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer);
1882+
1883+#define RMDsize 160 /* A RIPEMD-160 hash has 160 bits */
1884+
1885+/*
1886+ * returns RMD(message in file fname) fname is read as binary data.
1887+ * non-reentrant
1888+ */
1889+byte *RMDbinary(char *fname)
1890+{
1891+ FILE *mf; /* pointer to file <fname> */
1892+ byte data[1024]; /* contains current mess. block */
1893+ dword nbytes; /* length of this block */
1894+ dword MDbuf[RMDsize / 32]; /* contains (A, B, C, D(, E)) */
1895+ static byte hashcode[RMDsize / 8]; /* for final hash-value */
1896+ dword X[16]; /* current 16-word chunk */
1897+ unsigned int i, j; /* counters */
1898+ dword length[2]; /* length in bytes of message */
1899+ dword offset; /* # of unprocessed bytes at */
1900+ /* call of MDfinish */
1901+
1902+ /* initialize */
1903+ if ((mf = fopen(fname, "rb")) == NULL) {
1904+ fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n",
1905+ fname);
1906+ exit(1);
1907+ }
1908+ MDinit(MDbuf);
1909+ length[0] = 0;
1910+ length[1] = 0;
1911+ while ((nbytes = fread(data, 1, 1024, mf)) != 0) {
1912+ /* process all complete blocks */
1913+ for (i = 0; i < (nbytes >> 6); i++) {
1914+ for (j = 0; j < 16; j++)
1915+ X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
1916+ compress(MDbuf, X);
1917+ }
1918+ /* update length[] */
1919+ if (length[0] + nbytes < length[0])
1920+ length[1]++; /* overflow to msb of length */
1921+ length[0] += nbytes;
1922+ }
1923+ /* finish: */
1924+ offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
1925+ MDfinish(MDbuf, data + offset, length[0], length[1]);
1926+
1927+ for (i = 0; i < RMDsize / 8; i += 4) {
1928+ hashcode[i] = MDbuf[i >> 2];
1929+ hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
1930+ hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
1931+ hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
1932+ }
1933+ fclose(mf);
1934+
1935+ return (byte *) hashcode;
1936+}
1937+byte *RMDbinary_buffer(char *buffer, int size_buffer)
1938+{
1939+ return NULL;
1940+}
1941+
1942+/*
1943+ * Extracts the RMD 160 hash from the signature file
1944+ */
1945+int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file)
1946+{
1947+ RSA_parameters *rsa_parameters;
1948+ DER_key *derkey;
1949+ uint8_t *signature;
1950+ size_t signature_size;
1951+ uint8_t *decrypted;
1952+
1953+ signature = CH_load_raw_file(signature_file, &signature_size);
1954+ if ((signature == NULL)||(signature_size != 512)) {
1955+ fprintf(stderr, "Error: Loading signature key '%s'\n", signature_file);
1956+ exit(-1);
1957+ }
1958+ derkey = CH_load_der_key(public_key_file);
1959+ if (derkey == NULL) {
1960+ fprintf(stderr, "Error: opening DER key file '%s'\n", public_key_file);
1961+ exit(-1);
1962+ }
1963+ if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
1964+ fprintf(stderr, "Error: Extracting public key from DER file\n");
1965+ exit(-1);
1966+ }
1967+ CH_free_der_key(derkey);
1968+ if (rsa_parameters->num_octets != 512)
1969+ fprintf(stderr, "Error: The RSA public key size is not 4096 bits %d\n", rsa_parameters->num_octets);
1970+ decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
1971+ if (CH_decrypt(rsa_parameters, signature, decrypted)) {
1972+ fprintf(stderr, "Error: Decrypting signature\n");
1973+ exit(-1);
1974+ }
1975+ memcpy(hash, decrypted + 492, 20);
1976+ free(decrypted);
1977+ free(signature);
1978+ return 0;
1979+}
1980+
1981+/*
1982+ * Decrypts the signature buffer using the rsa public key loaded
1983+ */
1984+int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
1985+{
1986+ bigint *dat_bi;
1987+ bigint *decrypted_bi;
1988+ int byte_size;
1989+
1990+ byte_size = rsa->num_octets;
1991+ dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
1992+ rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
1993+ bi_copy(rsa->m);
1994+ decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
1995+ bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
1996+ return 0;
1997+}
1998+/*
1999+ * Loads a file in a uint8_t buffer
2000+ */
2001+static uint8_t *CH_load_raw_file(char *filename, size_t *size)
2002+{
2003+ struct stat st;
2004+ int fd;
2005+ ssize_t br;
2006+ uint8_t *ret;
2007+
2008+ if ((stat(filename, &st)) == -1)
2009+ return NULL;
2010+ if ((ret = (uint8_t *)malloc(st.st_size)) == NULL)
2011+ return NULL;
2012+ fd = open(filename, O_RDONLY);
2013+ if (fd == -1) {
2014+ free(ret);
2015+ return NULL;
2016+ }
2017+ br = read(fd, ret, st.st_size);
2018+ close(fd);
2019+ if (br != st.st_size) {
2020+ free(ret);
2021+ return NULL;
2022+ }
2023+ *size = st.st_size;
2024+ return ret;
2025+}
2026+/*
2027+ * Loads a .der file in a buffer
2028+ */
2029+static DER_key *CH_load_der_key(char *filename)
2030+{
2031+ DER_key *ret;
2032+
2033+ if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
2034+ return NULL;
2035+ if ((ret->buffer = CH_load_raw_file(filename, &(ret->size))) == NULL) {
2036+ free(ret);
2037+ return NULL;
2038+ }
2039+ return ret;
2040+}
2041+/*
2042+ * CH_load_pem_key
2043+ */
2044+static DER_key *CH_load_pem_key(char *filename)
2045+{
2046+ DER_key *ret;
2047+ uint8_t *buffer;
2048+ char *b64,*p,*t;
2049+ char key[1024];
2050+ size_t filesize;
2051+ int size;
2052+
2053+ if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
2054+ return NULL;
2055+ if ((buffer = CH_load_raw_file(filename, &filesize)) == NULL) {
2056+ free(ret);
2057+ return NULL;
2058+ }
2059+ p = (char *)buffer;
2060+ while ((*p != '\n') && (*p != '\0'))
2061+ p++;
2062+ if (*p == '\0') {
2063+ free(ret);
2064+ return NULL;
2065+ }
2066+ p++;
2067+ b64 = t = p;
2068+ while((p - b64) <= filesize) {
2069+ if ((*p == '-')) {
2070+ break;
2071+ } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
2072+ *t = *p;
2073+ t++;
2074+ }
2075+ p++;
2076+ }
2077+ *t = '\0';
2078+ size = B64_decode(b64, key, strlen(b64), 1024);
2079+ if (size < 0) {
2080+ free(buffer);
2081+ free(ret);
2082+ return NULL;
2083+ }
2084+ free(buffer);
2085+ ret->buffer = (char *)malloc(size);
2086+ ret->size = size;
2087+ memcpy((void *)ret->buffer, (void *)key, size);
2088+ return ret;
2089+}
2090+
2091+/*
2092+ * CH_free_der_key
2093+ */
2094+static void CH_free_der_key(DER_key *key)
2095+{
2096+ free(key->buffer);
2097+ free(key);
2098+}
2099+
2100+/*
2101+ * Get the public key specifics from an ASN.1 encoded file
2102+ * A function lacking in the exported axTLS API
2103+ *
2104+ * This is a really weird hack that only works with RSA public key
2105+ * files
2106+ */
2107+static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
2108+{
2109+ uint8_t *modulus, *pub_exp;
2110+ int mod_len, pub_len;
2111+
2112+ pub_len = 3;
2113+ mod_len = len - 37;
2114+ if (buf[0] != 0x30) {
2115+ return -1;
2116+ }
2117+
2118+ pub_exp = (uint8_t *)malloc(3);
2119+ modulus = (uint8_t *)malloc(mod_len);
2120+ memcpy(modulus, buf + 32 , mod_len);
2121+ memcpy(pub_exp, buf + 34 + mod_len, 3);
2122+ if (mod_len <= 0 || pub_len <= 0 )
2123+ return -1;
2124+ CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
2125+
2126+ free(modulus);
2127+ free(pub_exp);
2128+ return 0;
2129+}
2130+
2131+/*
2132+ * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
2133+ */
2134+void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
2135+{
2136+ RSA_parameters *rsa_parameters;
2137+
2138+ BI_CTX *bi_ctx = bi_initialize();
2139+ *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
2140+ rsa_parameters = *rsa;
2141+ rsa_parameters->bi_ctx = bi_ctx;
2142+ rsa_parameters->num_octets = (mod_len & 0xFFF0);
2143+ rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
2144+ bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
2145+ rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
2146+ bi_permanent(rsa_parameters->e);
2147+}
2148+
2149+static unsigned char *load_file_in_buffer(char *path, int *size)
2150+{
2151+ unsigned char *buffer;
2152+ struct stat st;
2153+ int fd;
2154+
2155+ if (stat(path, &st))
2156+ return NULL;
2157+ buffer = (unsigned char *)malloc(st.st_size);
2158+ if (buffer == NULL)
2159+ return NULL;
2160+ if ((fd = open(path, O_RDONLY)) == -1) {
2161+ free(buffer);
2162+ return NULL;
2163+ }
2164+ if (read(fd, (void *)buffer,st.st_size) != (ssize_t)st.st_size) {
2165+ free(buffer);
2166+ close(fd);
2167+ return NULL;
2168+ }
2169+ *size = (int)st.st_size;
2170+ close(fd);
2171+ return buffer;
2172+}
2173+
2174+static int save_file_from_buffer(char *path, unsigned char *buffer, int size)
2175+{
2176+ int fd;
2177+
2178+ if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
2179+ return -1;
2180+ if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
2181+ close(fd);
2182+ return -1;
2183+ }
2184+ close(fd);
2185+ return 0;
2186+}
2187+
2188+/* FR_init */
2189+void *FR_init(char *public_key_path)
2190+{
2191+ DER_key *derkey;
2192+ RSA_parameters *rsa_parameters;
2193+ char *ending;
2194+
2195+ ending = public_key_path + strlen(public_key_path) - 3;
2196+ if (!strcmp(ending, "der"))
2197+ derkey = CH_load_der_key(public_key_path);
2198+ else if (!strcmp(ending, "pem"))
2199+ derkey = CH_load_pem_key(public_key_path);
2200+ else {
2201+ fprintf(stderr, "Error: unknown key format\n");
2202+ exit(-1);
2203+ }
2204+ if (derkey == NULL) {
2205+ fprintf(stderr, "Error: opening key file '%s'\n", public_key_path);
2206+ exit(-1);
2207+ }
2208+ if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
2209+ fprintf(stderr, "Error: Extracting public key from file\n");
2210+ exit(-1);
2211+ }
2212+ CH_free_der_key(derkey);
2213+ return (void *)rsa_parameters;
2214+}
2215+
2216+/* FR_end */
2217+FONRSA_ERROR FR_end(void *handle)
2218+{
2219+ RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
2220+
2221+ free(rsa_parameters);
2222+ return FONRSA_OK;
2223+}
2224+
2225+/* FR_decrypt_buffer */
2226+FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
2227+ unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
2228+{
2229+ RSA_parameters *rsaparms = (RSA_parameters *)handler;
2230+
2231+ if (cryptext_size != rsaparms->num_octets) {
2232+ return FONRSA_SIZE;
2233+ }
2234+ if (plaintext_buffer_size < cryptext_size) {
2235+ return FONRSA_SIZE;
2236+ }
2237+ if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)plaintext)) {
2238+ return FONRSA_DECRYPT;
2239+ }
2240+ *plaintext_size = cryptext_size;
2241+ return FONRSA_OK;
2242+}
2243+
2244+FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
2245+ unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
2246+{
2247+ unsigned char* AuxBuffer;
2248+ int AuxSize;
2249+
2250+ AuxBuffer = (unsigned char*)malloc(cryptext_size);
2251+
2252+ RSA_parameters *rsaparms = (RSA_parameters *)handler;
2253+
2254+ if (cryptext_size != rsaparms->num_octets) {
2255+ return FONRSA_SIZE;
2256+ }
2257+ if (plaintext_buffer_size < cryptext_size) {
2258+ return FONRSA_SIZE;
2259+ }
2260+ if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)AuxBuffer)) {
2261+ return FONRSA_DECRYPT;
2262+ }
2263+ if ((AuxSize = ExtractPadding((uint8_t*)plaintext, (uint8_t*)AuxBuffer, cryptext_size)) < 0)
2264+ {
2265+ printf("Incorrect Padding decrypting buffer");
2266+ return FONRSA_DECRYPT;
2267+ }
2268+ *plaintext_size = AuxSize;
2269+ return FONRSA_OK;
2270+}
2271+
2272+/*
2273+ *
2274+ * Implementation of PKCS 1.5 padding, borrowed from
2275+ * Tom's code (public domain)
2276+ */
2277+
2278+/* Standalone FR_verify_file */
2279+FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path)
2280+{
2281+ int j;
2282+ byte *hashcode;
2283+ byte hash[20];
2284+ uint8_t *decrypted;
2285+ RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
2286+ char *signature_buffer;
2287+ int signature_size;
2288+
2289+ /* Calculates the RIPEMD-160 hash of the file */
2290+ hashcode = RMDbinary (file_path);
2291+ /* Decrypts the signature file using the RSA public key */
2292+ signature_buffer = load_file_in_buffer(signature_file_path, &signature_size);
2293+ if (signature_buffer == NULL)
2294+ return FONRSA_OPENKEY;
2295+
2296+ if (rsa_parameters->num_octets != signature_size)
2297+ return FONRSA_SIZE;
2298+ decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
2299+ if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
2300+ fprintf(stderr, "Error: Decrypting signature\n");
2301+ exit(-1);
2302+ }
2303+ memcpy(hash, decrypted + 492, 20);
2304+ free(decrypted);
2305+ free(signature_buffer);
2306+ for (j = 0; j < RMDsize/8; j++) {
2307+ if (hash[j] != hashcode[j])
2308+ return FONRSA_VERIFICATION_FAILURE;
2309+ }
2310+ return FONRSA_OK;
2311+}
2312+
2313+/* FR_decrypt_file */
2314+FONRSA_ERROR FR_decrypt_file(void *handle, char *crypted_file_path, char *plaintext_file_path)
2315+{
2316+ int size;
2317+ FONRSA_ERROR ret;
2318+ char *filebuffer;
2319+ char crypted[1024];
2320+ int crypted_size;
2321+
2322+ if ((filebuffer = load_file_in_buffer(crypted_file_path, &size)) == NULL) {
2323+ return FONRSA_LOADFILE;
2324+ }
2325+
2326+ ret = FR_decrypt_buffer(handle, filebuffer, size, crypted, 1024, &crypted_size);
2327+ if (ret != FONRSA_OK) {
2328+ free(filebuffer);
2329+ return ret;
2330+ }
2331+ free(filebuffer);
2332+
2333+ if (save_file_from_buffer(plaintext_file_path, crypted, crypted_size)) {
2334+ printf("Error writing %lu bytes into %s", crypted_size, plaintext_file_path);
2335+ return FONRSA_SAVEFILE;
2336+ }
2337+ return FONRSA_OK;
2338+}
2339+
2340+int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer)
2341+{
2342+ int i;
2343+
2344+ //First typical checks...
2345+ if (LengthOfInputBuffer < MINIMUM_PADING_BYTES_PKCS_1_5)
2346+ {
2347+ fprintf(stderr, "Error:ExtractPadding: Error, Length of input buffer is too short.\n");
2348+ return -1;
2349+ }
2350+ else if((InputBuffer[0] != 0) || (InputBuffer[1] > 2)) //Necessary header of Padding...
2351+ {
2352+ fprintf(stderr, "Error:ExtractPadding: Error, Padding header is incorrect.\n");
2353+ return -1;
2354+ }
2355+ for (i=2; i < LengthOfInputBuffer; i++) //Variable size of non-zero padding....
2356+ {
2357+ if (InputBuffer[i] == 0) break; //This is the end of Padding.
2358+ }
2359+ //We need to evaluate if there is an existing message...
2360+ if (i < LengthOfInputBuffer - 2)
2361+ {//Ok, Padding is extracted... copying the message and finishing...
2362+ memcpy(OutputBuffer, &(InputBuffer[i + 1]), LengthOfInputBuffer - (i + 1));
2363+ return LengthOfInputBuffer - (i + 1);
2364+ }
2365+ //If we have reached to this point, then an error has occurred...
2366+ return -1;
2367+}
2368+
2369+#ifdef __MAINTEST__
2370+int main(int argc, char **argv)
2371+{
2372+ void *handle = NULL;
2373+ FONRSA_ERROR ret;
2374+ char *filebuffer = NULL;
2375+ char crypted[1024];
2376+ int size, crypted_size;
2377+
2378+ if (argc != 4) {
2379+ printf("Usage: %s <key_file> <crypted_file> <output_file>\n", argv[0]);
2380+ return 1;
2381+ }
2382+
2383+ handle = FR_init(argv[1]);
2384+ if (handle == NULL) {
2385+ printf("Error loading keys\n");
2386+ return 1;
2387+ }
2388+ ret = FR_decrypt_file(handle, argv[2], argv[3]);
2389+ if (ret != FONRSA_OK) {
2390+ printf("FR_decrypt_file returns %d\n", ret);
2391+ }
2392+ FR_end(handle);
2393+ return (int)ret;
2394+}
2395+
2396+#endif
2397+
2398+
2399--- /dev/null
2400+++ b/net/rsa/fonrsa.h
2401@@ -0,0 +1,53 @@
2402+/*
2403+ * FONSM RSA handling library, used by fonsmcd and foncheckrsa
2404+ *
2405+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2406+ *
2407+ * This library is free software; you can redistribute it and/or modify
2408+ * it under the terms of the GNU Lesser General Public License as published by
2409+ * the Free Software Foundation; either version 2 of the License, or
2410+ * (at your option) any later version.
2411+ *
2412+ * This library is distributed in the hope that it will be useful,
2413+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2415+ * GNU Lesser General Public License for more details.
2416+ *
2417+ * You should have received a copy of the GNU Lesser General Public License
2418+ * along with this library; if not, write to the Free Software
2419+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2420+ *
2421+ * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
2422+ *
2423+ * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
2424+ */
2425+#ifndef _FONRSA_H
2426+#define _FONRSA_H
2427+
2428+#define MINIMUM_PADING_BYTES_PKCS_1_5 3
2429+
2430+typedef enum {
2431+ FONRSA_OK = 0,
2432+ FONRSA_VERIFICATION_FAILURE = 1,
2433+ FONRSA_OPENKEY = 2,
2434+ FONRSA_SIZE = 3,
2435+ FONRSA_LOADFILE = 4,
2436+ FONRSA_CRYPT = 5,
2437+ FONRSA_DECRYPT = 6,
2438+ FONRSA_SAVEFILE = 7,
2439+ FONRSA_NOSYS = 8,
2440+ FONRSA_VERIFY = 9
2441+} FONRSA_ERROR;
2442+
2443+void *FR_init(char *public_key_path);
2444+FONRSA_ERROR FR_end(void *handle);
2445+FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
2446+ unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
2447+FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
2448+ unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
2449+FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path);
2450+FONRSA_ERROR FR_decrypt_file(void *handler, char *crypted_file_path, char *plaintext_file_path);
2451+
2452+#endif
2453+
2454+
2455--- /dev/null
2456+++ b/net/rsa/log.c
2457@@ -0,0 +1,138 @@
2458+/*
2459+ * Fonsm log module. Used inside the fonsm backend module and on the client.
2460+ *
2461+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2462+ *
2463+ * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
2464+ *
2465+ * $Id: log.c 392 2007-06-25 16:24:51Z pablo.martin $
2466+ */
2467+#include <stdio.h>
2468+#include <string.h>
2469+#include <stdlib.h>
2470+#include <stdarg.h>
2471+#include <unistd.h>
2472+#ifndef WIN32
2473+#include <syslog.h>
2474+#endif
2475+#include "log.h"
2476+
2477+#define MAX_SESSION_PREFIX 256
2478+
2479+typedef struct {
2480+ char domain[256];
2481+ LG_LEVEL watermark;
2482+ int mode;
2483+ LG_log_function_pointer function;
2484+} ST_fslog;
2485+
2486+static ST_fslog fslog;
2487+static void LG_log_string(LG_LEVEL level, const char *message);
2488+
2489+/*!
2490+ \brief Starts the log subsystem, redirecting glog() to stderr/syslog depending
2491+ on mode
2492+ \retval FSLOG_ERROR : FSLOG_OK if everything goes well
2493+ \param lg : handle that will be returned
2494+ \param ident : program identifier, any string
2495+ \param low_watermark : if the log level is less than this value, it will not be logged
2496+ \param mode : FSLOG_MODE_SYSLOG (log to syslog) or FSLOG_MODE_STDERR (log to stderr)
2497+*/
2498+FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode,
2499+ LG_log_function_pointer log_function, int facility)
2500+{
2501+#ifndef WIN32
2502+ strncpy(fslog.domain, domain, MAX_LG_DOMAIN);
2503+ fslog.domain[MAX_LG_DOMAIN - 1] = '\0';
2504+ fslog.watermark = watermark;
2505+ fslog.mode = mode;
2506+ fslog.function = log_function?log_function:LG_log_string;
2507+ if (fslog.mode & LG_SYSLOG)
2508+ openlog(domain, LOG_NDELAY, facility);
2509+ return FSLOG_OK;
2510+#else
2511+ return FSLOG_OK;
2512+#endif
2513+}
2514+
2515+/*!
2516+ \brief Set the low watermark
2517+ \retval FSLOG_ERROR : FSLOG_OK
2518+ \param lg : log handle
2519+ \param low_watermark : new watermark
2520+*/
2521+FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark)
2522+{
2523+ fslog.watermark = watermark;
2524+ return FSLOG_OK;
2525+}
2526+
2527+/*!
2528+ \brief Ends the log subsystem, unregisteing glog handle
2529+ \retval FSLOG_ERROR : FSLOG_OK if everything goes well
2530+ \param handle : log handle to free
2531+*/
2532+FSLOG_ERROR LG_end(void)
2533+{
2534+#ifndef WIN32
2535+ if (fslog.mode & LG_SYSLOG)
2536+ closelog();
2537+#endif
2538+ return FSLOG_OK;
2539+}
2540+
2541+
2542+void LG_log(LG_LEVEL loglevel, const char *message, ...)
2543+{
2544+#ifndef WIN32
2545+ va_list ap;
2546+ char buffer[4096];
2547+ int n;
2548+
2549+ va_start(ap, message);
2550+ n = vsnprintf(buffer, MAX_LOG_STRING, message, ap);
2551+ va_end(ap);
2552+ if (n > -1 && n < MAX_LOG_STRING)
2553+ fslog.function(loglevel, buffer);
2554+ else
2555+ fon_critical("%s: Message too big to be logged", __FUNCTION__);
2556+#else
2557+ return;
2558+#endif
2559+}
2560+
2561+/* Default log function (when mode is LG_SYSLOG or LG_STDERR) */
2562+static void LG_log_string(LG_LEVEL level, const char *message)
2563+{
2564+#ifndef WIN32
2565+ static struct {
2566+ int syslog_level;
2567+ char *log_string;
2568+ } fonlog_to_syslog[] = {
2569+ [LG_DEBUG] = {LOG_ERR, "DEBUG"},
2570+ [LG_MESSAGE] = {LOG_ERR, "MESSAGE"},
2571+ [LG_WARNING] = {LOG_ERR, "WARNING"},
2572+ [LG_CRITICAL] = {LOG_ERR, "CRITICAL"},
2573+ [LG_ERROR] = {LOG_ERR, "ERROR"}
2574+ };
2575+
2576+ if (level < fslog.watermark)
2577+ return;
2578+ if (fslog.mode & LG_SYSLOG) {
2579+ if (level == LG_MESSAGE) {
2580+ syslog(LOG_INFO, "%s", message);
2581+ } else {
2582+ syslog(fonlog_to_syslog[level].syslog_level, "%s: %s", fonlog_to_syslog[level].log_string, message);
2583+ }
2584+ }
2585+ if (fslog.mode & LG_STDERR) {
2586+ fprintf(stderr, "%s[%d]: %8.8s: %s\n", fslog.domain,
2587+ getpid(), fonlog_to_syslog[level].log_string,
2588+ message);
2589+ }
2590+#else
2591+ /* FIXE: todo */
2592+ return;
2593+#endif
2594+}
2595+
2596--- /dev/null
2597+++ b/net/rsa/log.h
2598@@ -0,0 +1,77 @@
2599+/*
2600+ * Fonsm log module. Used inside the fonsm backend module and on the client.
2601+ *
2602+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2603+ *
2604+ * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
2605+ *
2606+ * $Id: log.h 379 2007-05-28 09:17:48Z pablo.martin $
2607+ */
2608+#ifndef _LOG_H
2609+#define _LOG_H
2610+
2611+#ifdef __cplusplus
2612+extern "C" {
2613+#endif
2614+
2615+#include <stdarg.h>
2616+
2617+typedef enum {
2618+ FSLOG_OK = 0,
2619+ FSLOG_UNKNOWN = -1
2620+} FSLOG_ERROR;
2621+
2622+
2623+typedef void * LG_HANDLE;
2624+
2625+typedef enum {
2626+ LG_DEBUG = 0,
2627+ LG_MESSAGE = 1,
2628+ LG_INFO = 2,
2629+ LG_WARNING = 3,
2630+ LG_CRITICAL = 4,
2631+ LG_ERROR = 5
2632+} LG_LEVEL;
2633+
2634+#define LG_SYSLOG 0x01
2635+#define LG_STDERR 0x02
2636+#define LG_CUSTOM 0x04
2637+
2638+#define MAX_LG_DOMAIN 256
2639+#define MAX_LOG_STRING 4096
2640+
2641+#ifndef NDEBUG
2642+#ifndef LOGPRINTF
2643+#define fon_debug(...) LG_log (LG_DEBUG, __VA_ARGS__)
2644+#else
2645+#define fon_debug(...) { printf("DEBUG: "); printf(__VA_ARGS__); printf("\n"); }
2646+#endif
2647+#else
2648+/* fon_debug evaluates to nothing when NDEBUG is defined */
2649+#define fon_debug(...)
2650+#endif
2651+#ifndef LOGPRINTF
2652+#define fon_message(...) LG_log (LG_MESSAGE, __VA_ARGS__)
2653+#define fon_warning(...) LG_log (LG_WARNING, __VA_ARGS__)
2654+#define fon_critical(...) LG_log (LG_CRITICAL, __VA_ARGS__)
2655+#define fon_error(...) LG_log (LG_ERROR, __VA_ARGS__)
2656+#else
2657+#define fon_message(...) { printf("MESSAGE: "); printf(__VA_ARGS__); printf("\n"); }
2658+#define fon_warning(...) { printf("WARNING: "); printf(__VA_ARGS__); printf("\n"); }
2659+#define fon_critical(...) { printf("CRITICAL: "); printf(__VA_ARGS__); printf("\n"); }
2660+#define fon_error(...) { printf("ERROR: "); printf(__VA_ARGS__); printf("\n"); }
2661+#endif
2662+
2663+typedef void (*LG_log_function_pointer)(LG_LEVEL level, const char *message);
2664+
2665+FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode, LG_log_function_pointer log_function, int facility);
2666+FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark);
2667+FSLOG_ERROR LG_end(void);
2668+void LG_log(LG_LEVEL loglevel, const char *message, ...);
2669+
2670+#ifdef __cplusplus
2671+}
2672+#endif
2673+
2674+#endif
2675+
2676--- /dev/null
2677+++ b/net/rsa/Makefile
2678@@ -0,0 +1,31 @@
2679+#
2680+# FONRSA & FONSIGN libraries unit testing
2681+#
2682+# This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2683+#
2684+# Execute in this directory
2685+#
2686+# Created: 20070422 Pablo Martin Medrano <pablo@fon.com>
2687+#
2688+# $Id: Makefile 389 2007-06-11 08:29:56Z pablo.martin $
2689+#
2690+# FIXME: Put this in the main Makefile.am
2691+#
2692+all: fonsign dump_key
2693+
2694+fonsign:
2695+ gcc -g sign_openssl.c -D__MAINTEST__ -o fonsign -lssl
2696+
2697+dump_key:
2698+ gcc -o dump_key dump_key.c
2699+ ./dump_key > public_key.h
2700+
2701+foncheckrsa:
2702+ gcc -g bigint.c fonrsa.c rmd160.c foncheckrsa.c base64.c log.c -o foncheckrsa
2703+
2704+#private_fon_rsa_key.pem:
2705+# openssl genrsa -out private_fon_rsa_key.pem 4096
2706+# openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
2707+
2708+clean:
2709+ rm fonsign dump_key
2710--- /dev/null
2711+++ b/net/rsa/public_key.h
2712@@ -0,0 +1,52 @@
2713+unsigned char public_key[] = {
2714+ 0x2D,0x2D,0x2D,0x2D,0x2D,0x42,0x45,0x47,0x49,0x4E,0x20,0x50,0x55,0x42,0x4C,0x49,
2715+ 0x43,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x4D,0x49,0x49,0x43,0x49,
2716+ 0x6A,0x41,0x4E,0x42,0x67,0x6B,0x71,0x68,0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,
2717+ 0x51,0x45,0x46,0x41,0x41,0x4F,0x43,0x41,0x67,0x38,0x41,0x4D,0x49,0x49,0x43,0x43,
2718+ 0x67,0x4B,0x43,0x41,0x67,0x45,0x41,0x34,0x4C,0x42,0x76,0x59,0x43,0x4B,0x38,0x38,
2719+ 0x6D,0x75,0x57,0x61,0x73,0x31,0x4F,0x53,0x73,0x71,0x30,0x0A,0x38,0x39,0x38,0x79,
2720+ 0x76,0x54,0x4B,0x71,0x41,0x6E,0x4F,0x37,0x78,0x2F,0x44,0x53,0x57,0x72,0x46,0x53,
2721+ 0x30,0x42,0x72,0x47,0x53,0x51,0x31,0x52,0x69,0x44,0x39,0x55,0x62,0x78,0x77,0x6F,
2722+ 0x64,0x76,0x36,0x65,0x51,0x4B,0x55,0x30,0x67,0x36,0x52,0x6B,0x2F,0x39,0x54,0x70,
2723+ 0x4C,0x6E,0x4F,0x2F,0x76,0x51,0x4B,0x70,0x69,0x41,0x30,0x30,0x0A,0x2B,0x32,0x59,
2724+ 0x30,0x74,0x6B,0x4C,0x39,0x73,0x6A,0x37,0x64,0x33,0x57,0x4B,0x47,0x39,0x62,0x6A,
2725+ 0x64,0x51,0x58,0x2F,0x43,0x49,0x35,0x57,0x46,0x42,0x42,0x64,0x77,0x57,0x73,0x74,
2726+ 0x4D,0x43,0x38,0x77,0x74,0x4C,0x6A,0x6A,0x45,0x59,0x79,0x43,0x58,0x46,0x32,0x31,
2727+ 0x30,0x39,0x7A,0x31,0x47,0x54,0x4C,0x73,0x53,0x44,0x34,0x57,0x4F,0x0A,0x45,0x50,
2728+ 0x6D,0x45,0x37,0x34,0x63,0x6E,0x6F,0x35,0x78,0x53,0x43,0x71,0x71,0x33,0x74,0x54,
2729+ 0x49,0x6D,0x38,0x50,0x78,0x49,0x77,0x54,0x46,0x6D,0x46,0x6F,0x6D,0x6A,0x76,0x31,
2730+ 0x4F,0x56,0x50,0x32,0x73,0x42,0x49,0x70,0x35,0x4E,0x2B,0x59,0x6F,0x56,0x61,0x53,
2731+ 0x58,0x6A,0x47,0x66,0x4E,0x63,0x54,0x36,0x4E,0x6B,0x39,0x76,0x6B,0x56,0x0A,0x57,
2732+ 0x69,0x67,0x39,0x30,0x71,0x50,0x4E,0x4C,0x58,0x6E,0x39,0x39,0x50,0x78,0x48,0x61,
2733+ 0x49,0x31,0x36,0x52,0x7A,0x78,0x48,0x4C,0x39,0x54,0x42,0x2B,0x50,0x43,0x33,0x68,
2734+ 0x33,0x61,0x58,0x33,0x71,0x57,0x30,0x4B,0x4C,0x4A,0x41,0x66,0x6F,0x35,0x70,0x48,
2735+ 0x6C,0x39,0x79,0x75,0x55,0x70,0x37,0x66,0x46,0x65,0x6A,0x4A,0x2B,0x41,0x58,0x0A,
2736+ 0x51,0x4F,0x4A,0x62,0x53,0x45,0x67,0x56,0x74,0x76,0x72,0x68,0x44,0x39,0x73,0x55,
2737+ 0x6D,0x4B,0x30,0x74,0x36,0x63,0x51,0x44,0x65,0x32,0x32,0x4E,0x4E,0x6E,0x77,0x37,
2738+ 0x43,0x4F,0x4F,0x61,0x59,0x49,0x57,0x55,0x55,0x6A,0x79,0x6A,0x68,0x35,0x50,0x4B,
2739+ 0x64,0x64,0x45,0x4B,0x5A,0x38,0x68,0x62,0x62,0x47,0x65,0x61,0x5A,0x4A,0x6F,0x76,
2740+ 0x0A,0x63,0x6F,0x51,0x64,0x55,0x56,0x51,0x6D,0x71,0x44,0x53,0x2B,0x6B,0x63,0x2F,
2741+ 0x41,0x51,0x6C,0x65,0x55,0x36,0x68,0x51,0x6A,0x63,0x55,0x4C,0x57,0x44,0x6B,0x4E,
2742+ 0x2F,0x6F,0x4F,0x6C,0x33,0x43,0x53,0x65,0x70,0x67,0x54,0x37,0x6B,0x67,0x73,0x52,
2743+ 0x63,0x63,0x47,0x74,0x66,0x4B,0x65,0x37,0x77,0x4D,0x70,0x35,0x66,0x59,0x4A,0x2B,
2744+ 0x41,0x0A,0x43,0x46,0x44,0x41,0x6F,0x4C,0x6E,0x58,0x4E,0x6A,0x4E,0x56,0x6C,0x65,
2745+ 0x73,0x43,0x6B,0x78,0x74,0x6A,0x62,0x4C,0x62,0x49,0x72,0x66,0x32,0x6E,0x43,0x62,
2746+ 0x32,0x61,0x4D,0x65,0x64,0x31,0x5A,0x48,0x4E,0x4A,0x51,0x75,0x6F,0x4E,0x58,0x67,
2747+ 0x72,0x43,0x41,0x44,0x31,0x71,0x2B,0x58,0x6E,0x66,0x77,0x63,0x69,0x6D,0x57,0x50,
2748+ 0x64,0x51,0x0A,0x44,0x59,0x6A,0x6D,0x65,0x44,0x70,0x35,0x77,0x36,0x41,0x4A,0x33,
2749+ 0x2F,0x35,0x59,0x39,0x55,0x74,0x78,0x47,0x34,0x72,0x51,0x72,0x61,0x68,0x78,0x53,
2750+ 0x42,0x77,0x43,0x4B,0x57,0x39,0x4B,0x79,0x53,0x31,0x71,0x53,0x76,0x73,0x37,0x7A,
2751+ 0x59,0x2F,0x52,0x59,0x37,0x4A,0x66,0x36,0x63,0x56,0x6B,0x54,0x43,0x78,0x69,0x33,
2752+ 0x7A,0x32,0x53,0x0A,0x50,0x46,0x33,0x51,0x64,0x6B,0x30,0x50,0x44,0x2F,0x73,0x2B,
2753+ 0x6B,0x77,0x39,0x71,0x4F,0x4E,0x79,0x69,0x33,0x67,0x6E,0x61,0x42,0x46,0x6E,0x54,
2754+ 0x77,0x48,0x7A,0x59,0x69,0x77,0x34,0x2F,0x77,0x6A,0x46,0x33,0x64,0x47,0x68,0x47,
2755+ 0x4E,0x6B,0x78,0x36,0x70,0x63,0x4E,0x4F,0x52,0x55,0x46,0x4E,0x65,0x4F,0x7A,0x59,
2756+ 0x76,0x39,0x6F,0x6A,0x0A,0x51,0x59,0x70,0x73,0x55,0x31,0x33,0x6A,0x6D,0x30,0x33,
2757+ 0x42,0x6F,0x45,0x2B,0x42,0x31,0x64,0x38,0x50,0x47,0x75,0x57,0x2B,0x49,0x7A,0x2F,
2758+ 0x41,0x4F,0x44,0x7A,0x6B,0x6F,0x56,0x6B,0x39,0x2B,0x57,0x79,0x49,0x33,0x37,0x50,
2759+ 0x30,0x53,0x7A,0x47,0x4B,0x72,0x2B,0x53,0x33,0x72,0x72,0x74,0x61,0x50,0x6C,0x41,
2760+ 0x70,0x71,0x4B,0x48,0x55,0x0A,0x6E,0x64,0x35,0x6C,0x30,0x63,0x76,0x75,0x59,0x66,
2761+ 0x31,0x4C,0x37,0x45,0x52,0x75,0x49,0x58,0x64,0x47,0x4C,0x6A,0x30,0x43,0x41,0x77,
2762+ 0x45,0x41,0x41,0x51,0x3D,0x3D,0x0A,0x2D,0x2D,0x2D,0x2D,0x2D,0x45,0x4E,0x44,0x20,
2763+ 0x50,0x55,0x42,0x4C,0x49,0x43,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,
2764+ };
2765--- /dev/null
2766+++ b/net/rsa/rmd160.c
2767@@ -0,0 +1,292 @@
2768+/********************************************************************\
2769+ *
2770+ * FILE: rmd160.c
2771+ *
2772+ * CONTENTS: A sample C-implementation of the RIPEMD-160
2773+ * hash-function.
2774+ * TARGET: any computer with an ANSI C compiler
2775+ *
2776+ * AUTHOR: Antoon Bosselaers, ESAT-COSIC
2777+ * DATE: 1 March 1996
2778+ * VERSION: 1.0
2779+ *
2780+ * Copyright (c) Katholieke Universiteit Leuven
2781+ * 1996, All Rights Reserved
2782+ *
2783+ * Conditions for use of the RIPEMD-160 Software
2784+ *
2785+ * The RIPEMD-160 software is freely available for use under the terms and
2786+ * conditions described hereunder, which shall be deemed to be accepted by
2787+ * any user of the software and applicable on any use of the software:
2788+ *
2789+ * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
2790+ * all purposes be considered the owner of the RIPEMD-160 software and of
2791+ * all copyright, trade secret, patent or other intellectual property
2792+ * rights therein.
2793+ * 2. The RIPEMD-160 software is provided on an "as is" basis without
2794+ * warranty of any sort, express or implied. K.U.Leuven makes no
2795+ * representation that the use of the software will not infringe any
2796+ * patent or proprietary right of third parties. User will indemnify
2797+ * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
2798+ * which may arise as a result of its use of the software. In no
2799+ * circumstances K.U.Leuven R&D will be held liable for any deficiency,
2800+ * fault or other mishappening with regard to the use or performance of
2801+ * the software.
2802+ * 3. User agrees to give due credit to K.U.Leuven in scientific publications
2803+ * or communications in relation with the use of the RIPEMD-160 software
2804+ * as follows: RIPEMD-160 software written by Antoon Bosselaers,
2805+ * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
2806+ *
2807+\********************************************************************/
2808+
2809+/* header files */
2810+#include <common.h>
2811+#include "rmd160.h"
2812+
2813+/********************************************************************/
2814+
2815+void MDinit(dword *MDbuf)
2816+{
2817+ MDbuf[0] = 0x67452301UL;
2818+ MDbuf[1] = 0xefcdab89UL;
2819+ MDbuf[2] = 0x98badcfeUL;
2820+ MDbuf[3] = 0x10325476UL;
2821+ MDbuf[4] = 0xc3d2e1f0UL;
2822+
2823+ return;
2824+}
2825+
2826+/********************************************************************/
2827+
2828+void compress(dword *MDbuf, dword *X)
2829+{
2830+ dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
2831+ dd = MDbuf[3], ee = MDbuf[4];
2832+ dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
2833+ ddd = MDbuf[3], eee = MDbuf[4];
2834+
2835+ /* round 1 */
2836+ FF(aa, bb, cc, dd, ee, X[ 0], 11);
2837+ FF(ee, aa, bb, cc, dd, X[ 1], 14);
2838+ FF(dd, ee, aa, bb, cc, X[ 2], 15);
2839+ FF(cc, dd, ee, aa, bb, X[ 3], 12);
2840+ FF(bb, cc, dd, ee, aa, X[ 4], 5);
2841+ FF(aa, bb, cc, dd, ee, X[ 5], 8);
2842+ FF(ee, aa, bb, cc, dd, X[ 6], 7);
2843+ FF(dd, ee, aa, bb, cc, X[ 7], 9);
2844+ FF(cc, dd, ee, aa, bb, X[ 8], 11);
2845+ FF(bb, cc, dd, ee, aa, X[ 9], 13);
2846+ FF(aa, bb, cc, dd, ee, X[10], 14);
2847+ FF(ee, aa, bb, cc, dd, X[11], 15);
2848+ FF(dd, ee, aa, bb, cc, X[12], 6);
2849+ FF(cc, dd, ee, aa, bb, X[13], 7);
2850+ FF(bb, cc, dd, ee, aa, X[14], 9);
2851+ FF(aa, bb, cc, dd, ee, X[15], 8);
2852+
2853+ /* round 2 */
2854+ GG(ee, aa, bb, cc, dd, X[ 7], 7);
2855+ GG(dd, ee, aa, bb, cc, X[ 4], 6);
2856+ GG(cc, dd, ee, aa, bb, X[13], 8);
2857+ GG(bb, cc, dd, ee, aa, X[ 1], 13);
2858+ GG(aa, bb, cc, dd, ee, X[10], 11);
2859+ GG(ee, aa, bb, cc, dd, X[ 6], 9);
2860+ GG(dd, ee, aa, bb, cc, X[15], 7);
2861+ GG(cc, dd, ee, aa, bb, X[ 3], 15);
2862+ GG(bb, cc, dd, ee, aa, X[12], 7);
2863+ GG(aa, bb, cc, dd, ee, X[ 0], 12);
2864+ GG(ee, aa, bb, cc, dd, X[ 9], 15);
2865+ GG(dd, ee, aa, bb, cc, X[ 5], 9);
2866+ GG(cc, dd, ee, aa, bb, X[ 2], 11);
2867+ GG(bb, cc, dd, ee, aa, X[14], 7);
2868+ GG(aa, bb, cc, dd, ee, X[11], 13);
2869+ GG(ee, aa, bb, cc, dd, X[ 8], 12);
2870+
2871+ /* round 3 */
2872+ HH(dd, ee, aa, bb, cc, X[ 3], 11);
2873+ HH(cc, dd, ee, aa, bb, X[10], 13);
2874+ HH(bb, cc, dd, ee, aa, X[14], 6);
2875+ HH(aa, bb, cc, dd, ee, X[ 4], 7);
2876+ HH(ee, aa, bb, cc, dd, X[ 9], 14);
2877+ HH(dd, ee, aa, bb, cc, X[15], 9);
2878+ HH(cc, dd, ee, aa, bb, X[ 8], 13);
2879+ HH(bb, cc, dd, ee, aa, X[ 1], 15);
2880+ HH(aa, bb, cc, dd, ee, X[ 2], 14);
2881+ HH(ee, aa, bb, cc, dd, X[ 7], 8);
2882+ HH(dd, ee, aa, bb, cc, X[ 0], 13);
2883+ HH(cc, dd, ee, aa, bb, X[ 6], 6);
2884+ HH(bb, cc, dd, ee, aa, X[13], 5);
2885+ HH(aa, bb, cc, dd, ee, X[11], 12);
2886+ HH(ee, aa, bb, cc, dd, X[ 5], 7);
2887+ HH(dd, ee, aa, bb, cc, X[12], 5);
2888+
2889+ /* round 4 */
2890+ II(cc, dd, ee, aa, bb, X[ 1], 11);
2891+ II(bb, cc, dd, ee, aa, X[ 9], 12);
2892+ II(aa, bb, cc, dd, ee, X[11], 14);
2893+ II(ee, aa, bb, cc, dd, X[10], 15);
2894+ II(dd, ee, aa, bb, cc, X[ 0], 14);
2895+ II(cc, dd, ee, aa, bb, X[ 8], 15);
2896+ II(bb, cc, dd, ee, aa, X[12], 9);
2897+ II(aa, bb, cc, dd, ee, X[ 4], 8);
2898+ II(ee, aa, bb, cc, dd, X[13], 9);
2899+ II(dd, ee, aa, bb, cc, X[ 3], 14);
2900+ II(cc, dd, ee, aa, bb, X[ 7], 5);
2901+ II(bb, cc, dd, ee, aa, X[15], 6);
2902+ II(aa, bb, cc, dd, ee, X[14], 8);
2903+ II(ee, aa, bb, cc, dd, X[ 5], 6);
2904+ II(dd, ee, aa, bb, cc, X[ 6], 5);
2905+ II(cc, dd, ee, aa, bb, X[ 2], 12);
2906+
2907+ /* round 5 */
2908+ JJ(bb, cc, dd, ee, aa, X[ 4], 9);
2909+ JJ(aa, bb, cc, dd, ee, X[ 0], 15);
2910+ JJ(ee, aa, bb, cc, dd, X[ 5], 5);
2911+ JJ(dd, ee, aa, bb, cc, X[ 9], 11);
2912+ JJ(cc, dd, ee, aa, bb, X[ 7], 6);
2913+ JJ(bb, cc, dd, ee, aa, X[12], 8);
2914+ JJ(aa, bb, cc, dd, ee, X[ 2], 13);
2915+ JJ(ee, aa, bb, cc, dd, X[10], 12);
2916+ JJ(dd, ee, aa, bb, cc, X[14], 5);
2917+ JJ(cc, dd, ee, aa, bb, X[ 1], 12);
2918+ JJ(bb, cc, dd, ee, aa, X[ 3], 13);
2919+ JJ(aa, bb, cc, dd, ee, X[ 8], 14);
2920+ JJ(ee, aa, bb, cc, dd, X[11], 11);
2921+ JJ(dd, ee, aa, bb, cc, X[ 6], 8);
2922+ JJ(cc, dd, ee, aa, bb, X[15], 5);
2923+ JJ(bb, cc, dd, ee, aa, X[13], 6);
2924+
2925+ /* parallel round 1 */
2926+ JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
2927+ JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
2928+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
2929+ JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
2930+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
2931+ JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
2932+ JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
2933+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
2934+ JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
2935+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
2936+ JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
2937+ JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
2938+ JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
2939+ JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
2940+ JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
2941+ JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
2942+
2943+ /* parallel round 2 */
2944+ III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
2945+ III(ddd, eee, aaa, bbb, ccc, X[11], 13);
2946+ III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
2947+ III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
2948+ III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
2949+ III(eee, aaa, bbb, ccc, ddd, X[13], 8);
2950+ III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
2951+ III(ccc, ddd, eee, aaa, bbb, X[10], 11);
2952+ III(bbb, ccc, ddd, eee, aaa, X[14], 7);
2953+ III(aaa, bbb, ccc, ddd, eee, X[15], 7);
2954+ III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
2955+ III(ddd, eee, aaa, bbb, ccc, X[12], 7);
2956+ III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
2957+ III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
2958+ III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
2959+ III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
2960+
2961+ /* parallel round 3 */
2962+ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
2963+ HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
2964+ HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
2965+ HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
2966+ HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
2967+ HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
2968+ HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
2969+ HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
2970+ HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
2971+ HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
2972+ HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
2973+ HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
2974+ HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
2975+ HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
2976+ HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
2977+ HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
2978+
2979+ /* parallel round 4 */
2980+ GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
2981+ GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
2982+ GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
2983+ GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
2984+ GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
2985+ GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
2986+ GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
2987+ GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
2988+ GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
2989+ GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
2990+ GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
2991+ GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
2992+ GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
2993+ GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
2994+ GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
2995+ GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
2996+
2997+ /* parallel round 5 */
2998+ FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
2999+ FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
3000+ FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
3001+ FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
3002+ FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
3003+ FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
3004+ FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
3005+ FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
3006+ FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
3007+ FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
3008+ FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
3009+ FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
3010+ FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
3011+ FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
3012+ FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
3013+ FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
3014+
3015+ /* combine results */
3016+ ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
3017+ MDbuf[1] = MDbuf[2] + dd + eee;
3018+ MDbuf[2] = MDbuf[3] + ee + aaa;
3019+ MDbuf[3] = MDbuf[4] + aa + bbb;
3020+ MDbuf[4] = MDbuf[0] + bb + ccc;
3021+ MDbuf[0] = ddd;
3022+
3023+ return;
3024+}
3025+
3026+/********************************************************************/
3027+
3028+void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)
3029+{
3030+ unsigned int i; /* counter */
3031+ dword X[16]; /* message words */
3032+
3033+ memset(X, 0, 16*sizeof(dword));
3034+
3035+ /* put bytes from strptr into X */
3036+ for (i=0; i<(lswlen&63); i++) {
3037+ /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
3038+ X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
3039+ }
3040+
3041+ /* append the bit m_n == 1 */
3042+ X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
3043+
3044+ if ((lswlen & 63) > 55) {
3045+ /* length goes to next block */
3046+ compress(MDbuf, X);
3047+ memset(X, 0, 16*sizeof(dword));
3048+ }
3049+
3050+ /* append length in bits*/
3051+ X[14] = lswlen << 3;
3052+ X[15] = (lswlen >> 29) | (mswlen << 3);
3053+ compress(MDbuf, X);
3054+
3055+ return;
3056+}
3057+
3058+/************************ end of file rmd160.c **********************/
3059+
3060--- /dev/null
3061+++ b/net/rsa/rmd160.h
3062@@ -0,0 +1,154 @@
3063+/********************************************************************\
3064+ *
3065+ * FILE: rmd160.h
3066+ *
3067+ * CONTENTS: Header file for a sample C-implementation of the
3068+ * RIPEMD-160 hash-function.
3069+ * TARGET: any computer with an ANSI C compiler
3070+ *
3071+ * AUTHOR: Antoon Bosselaers, ESAT-COSIC
3072+ * DATE: 1 March 1996
3073+ * VERSION: 1.0
3074+ *
3075+ * Copyright (c) Katholieke Universiteit Leuven
3076+ * 1996, All Rights Reserved
3077+ *
3078+ * Conditions for use of the RIPEMD-160 Software
3079+ *
3080+ * The RIPEMD-160 software is freely available for use under the terms and
3081+ * conditions described hereunder, which shall be deemed to be accepted by
3082+ * any user of the software and applicable on any use of the software:
3083+ *
3084+ * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
3085+ * all purposes be considered the owner of the RIPEMD-160 software and of
3086+ * all copyright, trade secret, patent or other intellectual property
3087+ * rights therein.
3088+ * 2. The RIPEMD-160 software is provided on an "as is" basis without
3089+ * warranty of any sort, express or implied. K.U.Leuven makes no
3090+ * representation that the use of the software will not infringe any
3091+ * patent or proprietary right of third parties. User will indemnify
3092+ * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
3093+ * which may arise as a result of its use of the software. In no
3094+ * circumstances K.U.Leuven R&D will be held liable for any deficiency,
3095+ * fault or other mishappening with regard to the use or performance of
3096+ * the software.
3097+ * 3. User agrees to give due credit to K.U.Leuven in scientific publications
3098+ * or communications in relation with the use of the RIPEMD-160 software
3099+ * as follows: RIPEMD-160 software written by Antoon Bosselaers,
3100+ * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
3101+ *
3102+\********************************************************************/
3103+
3104+#ifndef RMD160H /* make sure this file is read only once */
3105+#define RMD160H
3106+
3107+/********************************************************************/
3108+
3109+/* typedef 8 and 32 bit types, resp. */
3110+/* adapt these, if necessary,
3111+ for your operating system and compiler */
3112+typedef unsigned char byte;
3113+typedef unsigned long dword;
3114+
3115+
3116+/********************************************************************/
3117+
3118+/* macro definitions */
3119+
3120+/* collect four bytes into one word: */
3121+#define BYTES_TO_DWORD(strptr) \
3122+ (((dword) *((strptr)+3) << 24) | \
3123+ ((dword) *((strptr)+2) << 16) | \
3124+ ((dword) *((strptr)+1) << 8) | \
3125+ ((dword) *(strptr)))
3126+
3127+/* ROL(x, n) cyclically rotates x over n bits to the left */
3128+/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
3129+#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
3130+
3131+/* the five basic functions F(), G() and H() */
3132+#define F(x, y, z) ((x) ^ (y) ^ (z))
3133+#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
3134+#define H(x, y, z) (((x) | ~(y)) ^ (z))
3135+#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
3136+#define J(x, y, z) ((x) ^ ((y) | ~(z)))
3137+
3138+/* the ten basic operations FF() through III() */
3139+#define FF(a, b, c, d, e, x, s) {\
3140+ (a) += F((b), (c), (d)) + (x);\
3141+ (a) = ROL((a), (s)) + (e);\
3142+ (c) = ROL((c), 10);\
3143+ }
3144+#define GG(a, b, c, d, e, x, s) {\
3145+ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
3146+ (a) = ROL((a), (s)) + (e);\
3147+ (c) = ROL((c), 10);\
3148+ }
3149+#define HH(a, b, c, d, e, x, s) {\
3150+ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
3151+ (a) = ROL((a), (s)) + (e);\
3152+ (c) = ROL((c), 10);\
3153+ }
3154+#define II(a, b, c, d, e, x, s) {\
3155+ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
3156+ (a) = ROL((a), (s)) + (e);\
3157+ (c) = ROL((c), 10);\
3158+ }
3159+#define JJ(a, b, c, d, e, x, s) {\
3160+ (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
3161+ (a) = ROL((a), (s)) + (e);\
3162+ (c) = ROL((c), 10);\
3163+ }
3164+#define FFF(a, b, c, d, e, x, s) {\
3165+ (a) += F((b), (c), (d)) + (x);\
3166+ (a) = ROL((a), (s)) + (e);\
3167+ (c) = ROL((c), 10);\
3168+ }
3169+#define GGG(a, b, c, d, e, x, s) {\
3170+ (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
3171+ (a) = ROL((a), (s)) + (e);\
3172+ (c) = ROL((c), 10);\
3173+ }
3174+#define HHH(a, b, c, d, e, x, s) {\
3175+ (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
3176+ (a) = ROL((a), (s)) + (e);\
3177+ (c) = ROL((c), 10);\
3178+ }
3179+#define III(a, b, c, d, e, x, s) {\
3180+ (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
3181+ (a) = ROL((a), (s)) + (e);\
3182+ (c) = ROL((c), 10);\
3183+ }
3184+#define JJJ(a, b, c, d, e, x, s) {\
3185+ (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
3186+ (a) = ROL((a), (s)) + (e);\
3187+ (c) = ROL((c), 10);\
3188+ }
3189+
3190+/********************************************************************/
3191+
3192+/* function prototypes */
3193+
3194+void MDinit(dword *MDbuf);
3195+/*
3196+ * initializes MDbuffer to "magic constants"
3197+ */
3198+
3199+void compress(dword *MDbuf, dword *X);
3200+/*
3201+ * the compression function.
3202+ * transforms MDbuf using message bytes X[0] through X[15]
3203+ */
3204+
3205+void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen);
3206+/*
3207+ * puts bytes from strptr into X and pad out; appends length
3208+ * and finally, compresses the last block(s)
3209+ * note: length in bits == 8 * (lswlen + 2^32 mswlen).
3210+ * note: there are (lswlen mod 64) bytes left in strptr.
3211+ */
3212+
3213+#endif /* RMD160H */
3214+
3215+/*********************** end of file rmd160.h ***********************/
3216+
3217--- /dev/null
3218+++ b/net/rsa/rsa.c
3219@@ -0,0 +1,303 @@
3220+/*
3221+ * FONSM RSA handling library
3222+ *
3223+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3224+ *
3225+ * This library is free software; you can redistribute it and/or modify
3226+ * it under the terms of the GNU Lesser General Public License as published by
3227+ * the Free Software Foundation; either version 2 of the License, or
3228+ * (at your option) any later version.
3229+ *
3230+ * This library is distributed in the hope that it will be useful,
3231+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3232+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3233+ * GNU Lesser General Public License for more details.
3234+ *
3235+ * You should have received a copy of the GNU Lesser General Public License
3236+ * along with this library; if not, write to the Free Software
3237+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3238+ *
3239+ * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
3240+ *
3241+ * Based on axTLS
3242+ *
3243+ * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
3244+ */
3245+#include <malloc.h>
3246+#include <common.h>
3247+#include "rsa.h"
3248+#include "rmd160.h"
3249+#include "bigint.h"
3250+#include "base64.h"
3251+
3252+#include "public_key.h"
3253+
3254+#define RMDsize 160 /* A RIPEMD-160 hash has 160 bits */
3255+
3256+typedef struct {
3257+ uint8_t *buffer;
3258+ size_t size;
3259+} DER_key;
3260+
3261+typedef struct {
3262+ bigint *m; /* modulus */
3263+ bigint *e; /* public exponent */
3264+ int num_octets;
3265+ BI_CTX *bi_ctx; /* big integer handle */
3266+} RSA_parameters;
3267+
3268+typedef struct {
3269+ DER_key *derkey;
3270+ RSA_parameters *rsaparms;
3271+} RSA;
3272+
3273+static void CH_free_der_key(DER_key *key)
3274+{
3275+ free(key->buffer);
3276+ free(key);
3277+}
3278+
3279+int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
3280+{
3281+ bigint *dat_bi;
3282+ bigint *decrypted_bi;
3283+ int byte_size;
3284+
3285+ byte_size = rsa->num_octets;
3286+ dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
3287+ rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
3288+ bi_copy(rsa->m);
3289+ decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
3290+ bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
3291+ return 0;
3292+}
3293+
3294+byte *RMDbinary(char *buffer, int len)
3295+{
3296+ byte data[1024]; /* contains current mess. block */
3297+ dword nbytes; /* length of this block */
3298+ dword MDbuf[RMDsize / 32]; /* contains (A, B, C, D(, E)) */
3299+ static byte hashcode[RMDsize / 8]; /* for final hash-value */
3300+ dword X[16]; /* current 16-word chunk */
3301+ unsigned int i, j; /* counters */
3302+ dword length[2]; /* length in bytes of message */
3303+ dword offset; /* # of unprocessed bytes at */
3304+ /* call of MDfinish */
3305+ int total = len;
3306+ char *tmp = buffer;
3307+ MDinit(MDbuf);
3308+ length[0] = 0;
3309+ length[1] = 0;
3310+ while ( len) {
3311+ memcpy(data, tmp, 1024);
3312+ if(len > 1024)
3313+ {
3314+ nbytes = 1024;
3315+ len -= 1024;
3316+ tmp += 1024;
3317+ } else {
3318+ nbytes = len;
3319+ len = 0;
3320+ }
3321+ /* process all complete blocks */
3322+ for (i = 0; i < (nbytes >> 6); i++) {
3323+ for (j = 0; j < 16; j++)
3324+ X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
3325+ compress(MDbuf, X);
3326+ }
3327+ /* update length[] */
3328+ if (length[0] + nbytes < length[0])
3329+ length[1]++; /* overflow to msb of length */
3330+ length[0] += nbytes;
3331+ }
3332+ /* finish: */
3333+ offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
3334+ MDfinish(MDbuf, data + offset, length[0], length[1]);
3335+
3336+ for (i = 0; i < RMDsize / 8; i += 4) {
3337+ hashcode[i] = MDbuf[i >> 2];
3338+ hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
3339+ hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
3340+ hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
3341+ }
3342+
3343+ return (byte *) hashcode;
3344+}
3345+
3346+static DER_key *CH_load_pem_key(void)
3347+{
3348+ DER_key *ret;
3349+ uint8_t *buffer;
3350+ char *b64,*p,*t;
3351+ char key[1024];
3352+ size_t filesize;
3353+ int size;
3354+
3355+ if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
3356+ return NULL;
3357+ buffer = public_key;
3358+ p = (char *)buffer;
3359+ while ((*p != '\n') && (*p != '\0'))
3360+ p++;
3361+ if (*p == '\0') {
3362+ free(ret);
3363+ return NULL;
3364+ }
3365+ p++;
3366+ b64 = t = p;
3367+ while((p - b64) <= filesize) {
3368+ if ((*p == '-')) {
3369+ break;
3370+ } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
3371+ *t = *p;
3372+ t++;
3373+ }
3374+ p++;
3375+ }
3376+ *t = '\0';
3377+ size = B64_decode(b64, key, strlen(b64), 1024);
3378+ if (size < 0) {
3379+ free(buffer);
3380+ free(ret);
3381+ return NULL;
3382+ }
3383+ //free(buffer);
3384+ ret->buffer = (char *)malloc(size);
3385+ ret->size = size;
3386+ memcpy((void *)ret->buffer, (void *)key, size);
3387+ return ret;
3388+}
3389+
3390+/*
3391+ * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
3392+ */
3393+void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
3394+{
3395+ RSA_parameters *rsa_parameters;
3396+
3397+ BI_CTX *bi_ctx = bi_initialize();
3398+ *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
3399+ rsa_parameters = *rsa;
3400+ rsa_parameters->bi_ctx = bi_ctx;
3401+ rsa_parameters->num_octets = (mod_len & 0xFFF0);
3402+ rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
3403+ bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
3404+ rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
3405+ bi_permanent(rsa_parameters->e);
3406+}
3407+
3408+/*
3409+ * Get the public key specifics from an ASN.1 encoded file
3410+ * A function lacking in the exported axTLS API
3411+ *
3412+ * This is a really weird hack that only works with RSA public key
3413+ * files
3414+ */
3415+static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
3416+{
3417+ uint8_t *modulus, *pub_exp;
3418+ int mod_len, pub_len;
3419+
3420+ pub_len = 3;
3421+ mod_len = len - 37;
3422+ if (buf[0] != 0x30) {
3423+ return -1;
3424+ }
3425+
3426+ pub_exp = (uint8_t *)malloc(3);
3427+ modulus = (uint8_t *)malloc(mod_len);
3428+ memcpy(modulus, buf + 32 , mod_len);
3429+ memcpy(pub_exp, buf + 34 + mod_len, 3);
3430+ if (mod_len <= 0 || pub_len <= 0 )
3431+ return -1;
3432+ CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
3433+
3434+ free(modulus);
3435+ free(pub_exp);
3436+ return 0;
3437+}
3438+
3439+
3440+/* FR_init */
3441+void *FR_init(void)
3442+{
3443+ DER_key *derkey;
3444+ RSA_parameters *rsa_parameters;
3445+
3446+ derkey = CH_load_pem_key();
3447+ if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
3448+ fprintf(stderr, "Error: Extracting public key from file\n");
3449+ return 0;
3450+ }
3451+ CH_free_der_key(derkey);
3452+ return (void *)rsa_parameters;
3453+}
3454+
3455+FONRSA_ERROR FR_end(void *handle)
3456+{
3457+ RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
3458+
3459+ free(rsa_parameters);
3460+ return FONRSA_OK;
3461+}
3462+
3463+/*
3464+ *
3465+ * Implementation of PKCS 1.5 padding, borrowed from
3466+ * Tom's code (public domain)
3467+ */
3468+
3469+/* Standalone FR_verify_file */
3470+FONRSA_ERROR FR_verify_file(void *handler, char *file_data, int file_len,
3471+ char *signature_buffer, int signature_size)
3472+{
3473+ int j;
3474+ byte *hashcode;
3475+ byte hash[20];
3476+ uint8_t *decrypted;
3477+ RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
3478+
3479+ /* Calculates the RIPEMD-160 hash of the file */
3480+ hashcode = RMDbinary (file_data, file_len);
3481+
3482+ if (rsa_parameters->num_octets != signature_size)
3483+ return FONRSA_SIZE;
3484+ decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
3485+ if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
3486+ printf("Error: Decrypting signature\n");
3487+ return FONRSA_VERIFICATION_FAILURE;
3488+ }
3489+ memcpy(hash, decrypted + 492, 20);
3490+ //free(decrypted);
3491+ //free(signature_buffer);
3492+ for (j = 0; j < RMDsize/8; j++) {
3493+ if (hash[j] != hashcode[j])
3494+ return FONRSA_VERIFICATION_FAILURE;
3495+ }
3496+ return FONRSA_OK;
3497+}
3498+
3499+int rsa_check_signature(char *signature, int signature_len, char *buffer, int buffer_len)
3500+{
3501+ FONRSA_ERROR fonrsa_error;
3502+ void *handle;
3503+ handle = FR_init();
3504+ if (handle == NULL) {
3505+ printf("Error loading keys\n");
3506+ return 1;
3507+ }
3508+ fonrsa_error = FR_verify_file(handle, buffer, buffer_len, signature, signature_len);
3509+ FR_end(handle);
3510+ switch (fonrsa_error) {
3511+ case FONRSA_OK:
3512+ printf("Verified OK\n");
3513+ return 0;
3514+ case FONRSA_VERIFICATION_FAILURE:
3515+ printf("Verification failure\n");
3516+ return 1;
3517+ default:
3518+ printf("Verification error\n");
3519+ return -1;
3520+ }
3521+
3522+}
3523--- /dev/null
3524+++ b/net/rsa/rsa.h
3525@@ -0,0 +1,46 @@
3526+/*
3527+ * FONSM RSA handling library, used by fonsmcd and foncheckrsa
3528+ *
3529+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3530+ *
3531+ * This library is free software; you can redistribute it and/or modify
3532+ * it under the terms of the GNU Lesser General Public License as published by
3533+ * the Free Software Foundation; either version 2 of the License, or
3534+ * (at your option) any later version.
3535+ *
3536+ * This library is distributed in the hope that it will be useful,
3537+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3538+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3539+ * GNU Lesser General Public License for more details.
3540+ *
3541+ * You should have received a copy of the GNU Lesser General Public License
3542+ * along with this library; if not, write to the Free Software
3543+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3544+ *
3545+ * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
3546+ *
3547+ * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
3548+ */
3549+#ifndef _FONRSA_H
3550+#define _FONRSA_H
3551+
3552+#define MINIMUM_PADING_BYTES_PKCS_1_5 3
3553+
3554+typedef enum {
3555+ FONRSA_OK = 0,
3556+ FONRSA_VERIFICATION_FAILURE = 1,
3557+ FONRSA_OPENKEY = 2,
3558+ FONRSA_SIZE = 3,
3559+ FONRSA_LOADFILE = 4,
3560+ FONRSA_CRYPT = 5,
3561+ FONRSA_DECRYPT = 6,
3562+ FONRSA_SAVEFILE = 7,
3563+ FONRSA_NOSYS = 8,
3564+ FONRSA_VERIFY = 9
3565+} FONRSA_ERROR;
3566+
3567+int rsa_check_signature(char *signature, int signature_len, char *buffer, int buffer_len);
3568+
3569+#endif
3570+
3571+
3572--- /dev/null
3573+++ b/net/rsa/sign.h
3574@@ -0,0 +1,27 @@
3575+/*
3576+ * Signature interface
3577+ *
3578+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3579+ *
3580+ * Created: 20070417 Pablo Martín Medrano <pablo@fon.com>
3581+ *
3582+ * $Id: sign.h 389 2007-06-11 08:29:56Z pablo.martin $
3583+ */
3584+#ifndef __SIGN_H__
3585+#define __SIGN_H__
3586+#ifdef __cplusplus
3587+ extern "C" {
3588+#endif
3589+
3590+void SG_init(void);
3591+void *SG_start(char *private_key_path, char *public_key_path);
3592+void SG_stop(void *handle);
3593+int SG_crypt(void *data, unsigned char *text, int size_text, unsigned char *crypted_text,
3594+ unsigned int crypted_text_buffer_size, int *crypted_size);
3595+int SG_crypt_v2(void *data, unsigned char *text, int size_text, unsigned char *crypted_text,
3596+ unsigned int crypted_text_buffer_size, int *crypted_size);
3597+#ifdef __cplusplus
3598+}
3599+#endif
3600+#endif /* #ifdef __SIGN_H__ */
3601+
3602--- /dev/null
3603+++ b/net/rsa/sign_openssl.c
3604@@ -0,0 +1,437 @@
3605+/*
3606+ * Signature using OpenSSL
3607+ *
3608+ * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3609+ *
3610+ * Created: 20070417 Pablo Martín Medrano <pablo@fon.com>
3611+ *
3612+ * $Id: sign_openssl.c 346 2007-05-10 19:51:38Z pablo.martin $
3613+ */
3614+/*
3615+ *
3616+ * How the RSA public and private key was generated
3617+ * To check .FON files
3618+ * openssl genrsa -out private_fon_rsa_key.pem 4096
3619+ * openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
3620+ *
3621+ * How the Status Manager public and private key was generated
3622+ * openssl genrsa -out private_sm_rsa_key.pem 2048
3623+ * openssl rsa -in private_sm_rsa_key.pem -pubout -out public_sm_rsa_key.pem
3624+ *
3625+ * How to sign using the RSA private key (This is what fonsign does)
3626+ * openssl dgst -rmd160 -sign private_fon_rsa_key.pem FILE > SIGNATURE
3627+ * How to verify using the RSA public key (This is what fonverify + foncheckrsa does)
3628+ * openssl dgst -rmd160 -verify public_fon_rsa_key.pem -signature SIGNATURE FILE
3629+ * Convert to DER file (to use it in La Fonera)
3630+ * openssl rsa -inform PEM -outform DER -pubin -in public_fon_rsa_key.pem -pubout -out public_fon_rsa_key.der
3631+ */
3632+#include <openssl/rsa.h>
3633+#include <openssl/ssl.h>
3634+#include <openssl/bn.h>
3635+#include <openssl/pem.h>
3636+#include <openssl/evp.h>
3637+#include <sys/stat.h>
3638+#include <fcntl.h>
3639+#ifndef __MAINTEST__
3640+#include "log.h"
3641+#else
3642+#define fon_warning printf
3643+#define fon_debug printf
3644+#define fon_critical printf
3645+#endif
3646+#include "sign.h"
3647+
3648+typedef struct {
3649+ RSA *rsa;
3650+ int rsa_size;
3651+ EVP_PKEY *pkey;
3652+ int pkey_size;
3653+ RSA *public_rsa;
3654+ int public_rsa_size;
3655+ EVP_PKEY *public_pkey;
3656+ int public_pkey_size;
3657+} Sign;
3658+
3659+typedef enum {
3660+ KEY_PUBLIC = 0,
3661+ KEY_PRIVATE
3662+} KEY_TYPE;
3663+
3664+static EVP_PKEY *SG_load_key(char *key_path, KEY_TYPE type);
3665+static unsigned char *load_file_in_buffer(char *path, int *size);
3666+static int save_file_from_buffer(char *path, char *buffer, int size);
3667+
3668+void SG_init(void)
3669+{
3670+ SSL_load_error_strings();
3671+ SSL_library_init();
3672+ OpenSSL_add_all_algorithms();
3673+ OpenSSL_add_all_ciphers();
3674+ OpenSSL_add_all_digests();
3675+}
3676+
3677+static unsigned char *load_file_in_buffer(char *path, int *size)
3678+{
3679+ char *buffer;
3680+ struct stat st;
3681+ int fd;
3682+
3683+ if (stat(path, &st))
3684+ return NULL;
3685+ buffer = (char *)malloc(st.st_size);
3686+ if (buffer == NULL)
3687+ return NULL;
3688+ if ((fd = open(path, O_RDONLY)) == -1) {
3689+ free(buffer);
3690+ return NULL;
3691+ }
3692+ if (read(fd,buffer,st.st_size) != (ssize_t)st.st_size) {
3693+ free(buffer);
3694+ close(fd);
3695+ return NULL;
3696+ }
3697+ *size = (int)st.st_size;
3698+ close(fd);
3699+ return buffer;
3700+}
3701+
3702+static int save_file_from_buffer(char *path, char *buffer, int size)
3703+{
3704+ int fd;
3705+
3706+ if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
3707+ return -1;
3708+ if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
3709+ close(fd);
3710+ return -1;
3711+ }
3712+ close(fd);
3713+ return 0;
3714+}
3715+
3716+static EVP_PKEY *SG_load_key(char *key_path, KEY_TYPE type)
3717+{
3718+ BIO *key = NULL;
3719+ EVP_PKEY *pkey;
3720+
3721+ if ((key = BIO_new(BIO_s_file())) == NULL) {
3722+ //ERR_print_errors(err);
3723+ fon_warning("%s: Error calling BIO_new()\n", __FUNCTION__);
3724+ return NULL;
3725+ }
3726+ if (BIO_read_filename(key, key_path) <= 0) {
3727+ fon_warning("%s: Error opening %s\n", __FUNCTION__, key_path);
3728+ // ERR_print_errors(err);
3729+ BIO_free(key);
3730+ }
3731+ if (type == KEY_PUBLIC) {
3732+ pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
3733+ } else if (type == KEY_PRIVATE) {
3734+ pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
3735+ } else {
3736+ return NULL;
3737+ }
3738+
3739+ if (pkey == NULL) {
3740+ fon_warning("%s: Error reading %s\n", __FUNCTION__, key_path);
3741+ BIO_free(key);
3742+ return NULL;
3743+ }
3744+ BIO_free(key);
3745+ return pkey;
3746+}
3747+
3748+void *SG_start(char *private_key_path, char *public_key_path)
3749+{
3750+ Sign *sign;
3751+
3752+ if ((sign = (Sign *)malloc(sizeof(Sign))) == NULL)
3753+ return NULL;
3754+ memset(sign, 0, sizeof(Sign));
3755+ if (private_key_path != NULL) {
3756+ if ((sign->pkey = SG_load_key(private_key_path, KEY_PRIVATE)) == NULL) {
3757+ fon_warning("%s: Error loading %s", __FUNCTION__, private_key_path);
3758+ return NULL;
3759+ }
3760+ }
3761+ if (public_key_path != NULL) {
3762+ if ((sign->public_pkey = SG_load_key(public_key_path, KEY_PUBLIC)) == NULL) {
3763+ fon_warning("%s: Error loading %s", __FUNCTION__, public_key_path);
3764+ return NULL;
3765+ }
3766+ }
3767+ if (sign->pkey != NULL) {
3768+ sign->pkey_size = EVP_PKEY_size(sign->pkey);
3769+ if ((sign->rsa = EVP_PKEY_get1_RSA(sign->pkey)) == NULL) {
3770+ EVP_PKEY_free(sign->pkey);
3771+ return NULL;
3772+ }
3773+ }
3774+ if (sign->public_pkey != NULL) {
3775+ sign->public_pkey_size = EVP_PKEY_size(sign->public_pkey);
3776+ if ((sign->public_rsa = EVP_PKEY_get1_RSA(sign->public_pkey)) == NULL) {
3777+ EVP_PKEY_free(sign->pkey);
3778+ return NULL;
3779+ }
3780+ }
3781+ if (((sign->rsa == NULL) && (private_key_path != NULL)) ||
3782+ ((sign->public_rsa == NULL) && (public_key_path != NULL))) {
3783+ fon_warning("%s: Error calling EVP_PKEY_get1_RSA()", __FUNCTION__);
3784+ return NULL;
3785+ }
3786+ if (sign->rsa != NULL) {
3787+ sign->rsa_size = RSA_size(sign->rsa);
3788+ if (RSA_check_key(sign->rsa) != 1) {
3789+ fon_warning("%s: RSA key failure", __FUNCTION__);
3790+ return NULL;
3791+ }
3792+ }
3793+
3794+ return (void *)sign;
3795+}
3796+
3797+void SG_stop(void *handle)
3798+{
3799+ Sign *sign = (Sign *)handle;
3800+
3801+ EVP_PKEY_free(sign->pkey);
3802+ EVP_PKEY_free(sign->public_pkey);
3803+ if (sign->rsa != NULL)
3804+ RSA_free(sign->rsa);
3805+ if (sign->public_rsa != NULL)
3806+ RSA_free(sign->public_rsa);
3807+ free(sign);
3808+}
3809+
3810+int SG_verify(void *data, unsigned char *text, unsigned int size_text,
3811+ unsigned char *signature, unsigned int size_signature)
3812+{
3813+ EVP_MD_CTX mdctx;
3814+ EVP_MD *md;
3815+ EVP_PKEY *pkey;
3816+ int ret;
3817+ Sign *sign = (Sign *)data;
3818+
3819+ md = (EVP_MD *)EVP_ripemd160();
3820+ if(!EVP_VerifyInit(&mdctx, md))
3821+ return 4;
3822+ if (!EVP_VerifyUpdate(&mdctx, (const void *)text, (unsigned int)size_text)) {
3823+ return 5;
3824+ }
3825+ ret = EVP_VerifyFinal(&mdctx, (const char *)signature, size_signature, sign->public_pkey);
3826+ EVP_PKEY_free(pkey);
3827+ EVP_MD_CTX_cleanup(&mdctx);
3828+ return ret;
3829+}
3830+
3831+int SG_sign(void *data, void *text, unsigned int size_text, void *signature_buffer,
3832+ unsigned int size_signature_buffer, unsigned int *size_signature)
3833+{
3834+ unsigned char *digest[EVP_MAX_MD_SIZE];
3835+ EVP_MD_CTX mdctx;
3836+ EVP_MD *md;
3837+ int ret;
3838+ Sign *sign = (Sign *)data;
3839+
3840+ if (size_signature_buffer < sign->pkey_size)
3841+ return 1;
3842+
3843+ md = (EVP_MD *)EVP_ripemd160();
3844+ EVP_SignInit(&mdctx, md);
3845+ if (!EVP_SignUpdate(&mdctx, (const void *)text, (unsigned int)size_text)) {
3846+ return 2;
3847+ }
3848+ if (!EVP_SignFinal(&mdctx, (unsigned char *)signature_buffer, (unsigned int *)size_signature, sign->pkey)) {
3849+ return 3;
3850+ }
3851+ EVP_MD_CTX_cleanup(&mdctx);
3852+
3853+ return 0;
3854+}
3855+
3856+/*
3857+ * It's not advised to crypt using RAW ... unless you have crypted the buffer using AES before.
3858+ */
3859+int SG_crypt(void *data, unsigned char *text, int size_text,
3860+ unsigned char *crypted_text, unsigned int crypted_text_buffer_size,
3861+ int *crypted_size)
3862+{
3863+ EVP_MD_CTX mdctx;
3864+ EVP_MD *md;
3865+ int retsize;
3866+ Sign *sign = (Sign *)data;
3867+
3868+ if (crypted_text_buffer_size < sign->pkey_size) {
3869+ fon_critical("%s: size_signature_buffer [%u] < %u", __FUNCTION__, size_text, sign->pkey_size);
3870+ return 1;
3871+ }
3872+ if (size_text != sign->pkey_size) {
3873+ fon_critical("%s: size_text [%u] != %u", __FUNCTION__, size_text, sign->pkey_size);
3874+ return 2;
3875+ }
3876+ /* The buffer is pre-padded with random data ... */
3877+ fon_debug("%s: About to call RSA_private_encrypt(%d, %x, %x, %x, %d)",
3878+ __FUNCTION__, size_text, crypted_text, sign->rsa, RSA_NO_PADDING);
3879+ retsize = RSA_private_encrypt(size_text, text, crypted_text, sign->rsa, RSA_NO_PADDING);
3880+ if (retsize == -1) {
3881+ fon_critical("%s: Error calling RSA_private_encrypt(%d, %x, %x, %x, %d)",
3882+ __FUNCTION__, size_text, crypted_text, sign->rsa, RSA_NO_PADDING);
3883+ return 1;
3884+ }
3885+ *crypted_size = retsize;
3886+ return 0;
3887+}
3888+
3889+/* SG_decrypt */
3890+int SG_decrypt(void *data, unsigned char *cryptext, int cryptext_size, unsigned char *plaintext,
3891+ int plaintext_buffer_size, int *plaintext_size)
3892+{
3893+ EVP_MD_CTX mdctx;
3894+ EVP_MD *md;
3895+ int retsize;
3896+ Sign *sign = (Sign *)data;
3897+
3898+ if (plaintext_buffer_size < sign->public_pkey_size) {
3899+ fon_critical("%s: plaintext_buffer_size [%u] < %u", __FUNCTION__, plaintext_buffer_size, sign->public_pkey_size);
3900+ return 1;
3901+ }
3902+ if (cryptext_size != sign->public_pkey_size) {
3903+ fon_critical("%s: cryptext_size [%u] != %u", __FUNCTION__, cryptext_size, sign->public_pkey_size);
3904+ return 2;
3905+ }
3906+ retsize = RSA_public_decrypt(cryptext_size, cryptext, plaintext, sign->public_rsa, RSA_NO_PADDING);
3907+ if (retsize == -1)
3908+ return 1;
3909+ *plaintext_size = retsize;
3910+ return 0;
3911+}
3912+
3913+#ifdef __MAINTEST__
3914+int main(int argc, char **argv)
3915+{
3916+ size_t argv0_size;
3917+ char *token;
3918+
3919+ argv0_size = strlen(argv[0]);
3920+ if (argv0_size < 7) {
3921+ fprintf(stderr, "%s?", argv[0]);
3922+ return 1;
3923+ }
3924+ token = argv[0] + argv0_size - 7;
3925+
3926+ SG_init();
3927+ if (!strcmp(token, "fonsign")) {
3928+ return main_fonsign(argc, argv);
3929+ } else if (!strcmp(token, "foncryp")) {
3930+ return main_foncryp(argc, argv);
3931+ }
3932+ fprintf(stderr, "%s?", argv[0]);
3933+ return 1;
3934+}
3935+
3936+int main_foncryp(int argc, char **argv)
3937+{
3938+ void *handle = NULL;
3939+ int encrypt = 0;
3940+ char *filebuffer = NULL;
3941+ char crypted[1024];
3942+ int size, crypted_size, ret;
3943+
3944+ if (argc != 5) {
3945+ printf("Usage: %s encrypt|decrypt <key_file> <file> <crypted_file>\n", argv[0]);
3946+ return 1;
3947+ }
3948+ if (!strcmp(argv[1], "encrypt")) {
3949+ printf("Encryption mode\n");
3950+ encrypt = 1;
3951+ } else
3952+ printf("Decryption mode\n");
3953+ if (encrypt)
3954+ handle = SG_start(argv[2], NULL);
3955+ else
3956+ handle = SG_start(NULL, argv[2]);
3957+ if (handle == NULL) {
3958+ printf("Error loading keys\n");
3959+ return 1;
3960+ }
3961+
3962+ filebuffer = load_file_in_buffer(argv[3], &size);
3963+ if (filebuffer == NULL) {
3964+ printf("Error reading %s\n", argv[3]);
3965+ SG_stop(handle);
3966+ return 1;
3967+ }
3968+ if (encrypt)
3969+ ret = SG_crypt(handle, filebuffer, size, crypted, 1024, &crypted_size);
3970+ else
3971+ ret = SG_decrypt(handle, filebuffer, size, crypted, 1024, &crypted_size);
3972+
3973+ if (ret) {
3974+ printf("Error crypting %d bytes\n", size);
3975+ SG_stop(handle);
3976+ return 1;
3977+ }
3978+ printf("Crypted size %d\n", crypted_size);
3979+ if (save_file_from_buffer(argv[4], crypted, crypted_size)) {
3980+ printf("Error saving file\n");
3981+ SG_stop(handle);
3982+ return 1;
3983+ }
3984+
3985+ SG_stop(handle);
3986+ return 0;
3987+}
3988+
3989+int main_fonsign(int argc, char **argv)
3990+{
3991+ void *handle = NULL;
3992+ char signature_buffer[4096];
3993+ char *signature;
3994+ unsigned int signature_size;
3995+ struct stat st;
3996+ char *filebuffer = NULL;
3997+ int size;
3998+ int ret = -1;
3999+
4000+ if (argc != 5) {
4001+ fprintf(stderr, "usage: %s <private_key_file> <public_key_file> <file_to_sign> <signature_file>\n", argv[0]);
4002+ goto end;
4003+ }
4004+ handle = SG_start(argv[1], argv[2]);
4005+ if (handle == NULL) {
4006+ fprintf(stderr, "Error calling SG_start(%s)\n", argv[1]);
4007+ goto end;
4008+ }
4009+ filebuffer = load_file_in_buffer(argv[3], &size);
4010+ if (filebuffer == NULL) {
4011+ fprintf(stderr, "Error reading %s\n", argv[3]);
4012+ goto end;
4013+ }
4014+ if (SG_sign(handle, filebuffer, size, signature_buffer, 4096, &signature_size)) {
4015+ fprintf(stderr, "Error calling SG_sign()\n");
4016+ goto end;
4017+ }
4018+ ret = SG_verify(handle, filebuffer, size, signature_buffer, signature_size);
4019+ if (ret == 0)
4020+ fprintf(stderr, "signature failure\n");
4021+ else if (ret == 1) {
4022+ fprintf(stderr, "signature ok\n");
4023+ ret = 0;
4024+ } else {
4025+ fprintf(stderr, "signature error\n");
4026+ goto end;
4027+ }
4028+ if (save_file_from_buffer(argv[4], signature_buffer, signature_size)) {
4029+ fprintf(stderr, "Error writing to %s\n", argv[4]);
4030+ goto end;
4031+ }
4032+ ret = 0;
4033+end:
4034+ if (filebuffer != NULL)
4035+ free(filebuffer);
4036+ if (handle != NULL)
4037+ SG_stop(handle);
4038+ return ret;
4039+}
4040+#endif
4041+
4042--- /dev/null
4043+++ b/net/uip-0.9/fs.c
4044@@ -0,0 +1,154 @@
4045+/**
4046+ * \addtogroup httpd
4047+ * @{
4048+ */
4049+
4050+/**
4051+ * \file
4052+ * HTTP server read-only file system code.
4053+ * \author Adam Dunkels <adam@dunkels.com>
4054+ *
4055+ * A simple read-only filesystem.
4056+ */
4057+
4058+/*
4059+ * Copyright (c) 2001, Swedish Institute of Computer Science.
4060+ * All rights reserved.
4061+ *
4062+ * Redistribution and use in source and binary forms, with or without
4063+ * modification, are permitted provided that the following conditions
4064+ * are met:
4065+ * 1. Redistributions of source code must retain the above copyright
4066+ * notice, this list of conditions and the following disclaimer.
4067+ * 2. Redistributions in binary form must reproduce the above copyright
4068+ * notice, this list of conditions and the following disclaimer in the
4069+ * documentation and/or other materials provided with the distribution.
4070+ * 3. Neither the name of the Institute nor the names of its contributors
4071+ * may be used to endorse or promote products derived from this software
4072+ * without specific prior written permission.
4073+ *
4074+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4075+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4076+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4077+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4078+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4079+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4080+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4081+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4082+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4083+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4084+ * SUCH DAMAGE.
4085+ *
4086+ * This file is part of the lwIP TCP/IP stack.
4087+ *
4088+ * Author: Adam Dunkels <adam@sics.se>
4089+ *
4090+ * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $
4091+ */
4092+
4093+#include "uip.h"
4094+#include "httpd.h"
4095+#include "fs.h"
4096+#include "fsdata.h"
4097+
4098+#include "fsdata.c"
4099+
4100+#ifdef FS_STATISTICS
4101+#if FS_STATISTICS == 1
4102+static u16_t count[FS_NUMFILES];
4103+#endif /* FS_STATISTICS */
4104+#endif /* FS_STATISTICS */
4105+
4106+/*-----------------------------------------------------------------------------------*/
4107+static u8_t
4108+fs_strcmp(const char *str1, const char *str2)
4109+{
4110+ u8_t i;
4111+ i = 0;
4112+ loop:
4113+
4114+ if(str2[i] == 0 ||
4115+ str1[i] == '\r' ||
4116+ str1[i] == '\n') {
4117+ return 0;
4118+ }
4119+
4120+ if(str1[i] != str2[i]) {
4121+ return 1;
4122+ }
4123+
4124+
4125+ ++i;
4126+ goto loop;
4127+}
4128+/*-----------------------------------------------------------------------------------*/
4129+int
4130+fs_open(const char *name, struct fs_file *file)
4131+{
4132+#ifdef FS_STATISTICS
4133+#if FS_STATISTICS == 1
4134+ u16_t i = 0;
4135+#endif /* FS_STATISTICS */
4136+#endif /* FS_STATISTICS */
4137+ struct fsdata_file_noconst *f;
4138+
4139+ for(f = (struct fsdata_file_noconst *)FS_ROOT;
4140+ f != NULL;
4141+ f = (struct fsdata_file_noconst *)f->next) {
4142+
4143+ if(fs_strcmp(name, f->name) == 0) {
4144+ file->data = f->data;
4145+ file->len = f->len;
4146+#ifdef FS_STATISTICS
4147+#if FS_STATISTICS == 1
4148+ ++count[i];
4149+#endif /* FS_STATISTICS */
4150+#endif /* FS_STATISTICS */
4151+ return 1;
4152+ }
4153+#ifdef FS_STATISTICS
4154+#if FS_STATISTICS == 1
4155+ ++i;
4156+#endif /* FS_STATISTICS */
4157+#endif /* FS_STATISTICS */
4158+
4159+ }
4160+ return 0;
4161+}
4162+/*-----------------------------------------------------------------------------------*/
4163+void
4164+fs_init(void)
4165+{
4166+#ifdef FS_STATISTICS
4167+#if FS_STATISTICS == 1
4168+ u16_t i;
4169+ for(i = 0; i < FS_NUMFILES; i++) {
4170+ count[i] = 0;
4171+ }
4172+#endif /* FS_STATISTICS */
4173+#endif /* FS_STATISTICS */
4174+}
4175+/*-----------------------------------------------------------------------------------*/
4176+#ifdef FS_STATISTICS
4177+#if FS_STATISTICS == 1
4178+u16_t fs_count
4179+(char *name)
4180+{
4181+ struct fsdata_file_noconst *f;
4182+ u16_t i;
4183+
4184+ i = 0;
4185+ for(f = (struct fsdata_file_noconst *)FS_ROOT;
4186+ f != NULL;
4187+ f = (struct fsdata_file_noconst *)f->next) {
4188+
4189+ if(fs_strcmp(name, f->name) == 0) {
4190+ return count[i];
4191+ }
4192+ ++i;
4193+ }
4194+ return 0;
4195+}
4196+#endif /* FS_STATISTICS */
4197+#endif /* FS_STATISTICS */
4198+/*-----------------------------------------------------------------------------------*/
4199--- /dev/null
4200+++ b/net/uip-0.9/fsdata.c
4201@@ -0,0 +1,199 @@
4202+static const char data_flashing_html[] = {
4203+ /* /flashing.html */
4204+ 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4205+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4206+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4207+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4208+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4209+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4210+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4211+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4212+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4213+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4214+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
4215+ 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
4216+ 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
4217+ 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
4218+ 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
4219+ 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
4220+ 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
4221+ 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
4222+ 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
4223+ 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
4224+ 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
4225+ 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
4226+ 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
4227+ 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
4228+ 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
4229+ 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4230+
4231+static const char data_fail_html[] = {
4232+ /* /fail.html */
4233+ 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4234+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4235+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4236+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4237+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4238+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4239+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4240+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4241+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4242+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4243+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4244+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4245+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4246+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4247+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4248+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4249+ 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
4250+ 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
4251+ 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
4252+ 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
4253+ 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
4254+ 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
4255+ 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
4256+ 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
4257+ 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
4258+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
4259+ 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
4260+ 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
4261+ 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
4262+ 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
4263+ 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
4264+ 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4265+ 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
4266+ 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
4267+ 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
4268+ 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
4269+ 0x3e, 0xa, };
4270+
4271+static const char data_404_html[] = {
4272+ /* /404.html */
4273+ 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4274+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
4275+ 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
4276+ 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
4277+ 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
4278+ 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
4279+ 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
4280+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
4281+ 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
4282+ 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
4283+ 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
4284+ 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
4285+ 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
4286+ 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
4287+ 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
4288+ 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
4289+ 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
4290+ 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
4291+ 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
4292+ 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
4293+ 0x6c, 0x3e, };
4294+
4295+static const char data_index_html[] = {
4296+ /* /index.html */
4297+ 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4298+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4299+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4300+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4301+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4302+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4303+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4304+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4305+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4306+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4307+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4308+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4309+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4310+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4311+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4312+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4313+ 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
4314+ 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
4315+ 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
4316+ 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
4317+ 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
4318+ 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
4319+ 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
4320+ 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
4321+ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
4322+ 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
4323+ 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
4324+ 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
4325+ 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
4326+ 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
4327+ 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
4328+ 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
4329+ 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
4330+ 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
4331+ 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
4332+ 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
4333+ 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
4334+ 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
4335+ 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
4336+ 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
4337+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
4338+ 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
4339+ 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4340+
4341+static const char data_flash_html[] = {
4342+ /* /flash.html */
4343+ 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4344+ 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4345+ 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4346+ 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4347+ 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4348+ 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4349+ 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4350+ 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4351+ 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4352+ 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4353+ 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4354+ 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4355+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4356+ 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4357+ 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4358+ 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4359+ 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
4360+ 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
4361+ 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
4362+ 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
4363+ 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
4364+ 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
4365+ 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
4366+ 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
4367+ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
4368+ 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
4369+ 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
4370+ 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
4371+ 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
4372+ 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
4373+ 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
4374+ 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
4375+ 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
4376+ 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
4377+ 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
4378+ 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
4379+ 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
4380+ 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
4381+ 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
4382+ 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
4383+ 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
4384+ 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
4385+ 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
4386+ 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4387+
4388+const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
4389+
4390+const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
4391+
4392+const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
4393+
4394+const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
4395+
4396+const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
4397+
4398+#define FS_ROOT file_flash_html
4399+
4400+#define FS_NUMFILES 5
4401\ No newline at end of file
4402--- /dev/null
4403+++ b/net/uip-0.9/fsdata.h
4404@@ -0,0 +1,64 @@
4405+/*
4406+ * Copyright (c) 2001, Swedish Institute of Computer Science.
4407+ * All rights reserved.
4408+ *
4409+ * Redistribution and use in source and binary forms, with or without
4410+ * modification, are permitted provided that the following conditions
4411+ * are met:
4412+ * 1. Redistributions of source code must retain the above copyright
4413+ * notice, this list of conditions and the following disclaimer.
4414+ * 2. Redistributions in binary form must reproduce the above copyright
4415+ * notice, this list of conditions and the following disclaimer in the
4416+ * documentation and/or other materials provided with the distribution.
4417+ * 3. Neither the name of the Institute nor the names of its contributors
4418+ * may be used to endorse or promote products derived from this software
4419+ * without specific prior written permission.
4420+ *
4421+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4422+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4423+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4424+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4425+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4426+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4427+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4428+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4429+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4430+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4431+ * SUCH DAMAGE.
4432+ *
4433+ * This file is part of the lwIP TCP/IP stack.
4434+ *
4435+ * Author: Adam Dunkels <adam@sics.se>
4436+ *
4437+ * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $
4438+ */
4439+#ifndef __FSDATA_H__
4440+#define __FSDATA_H__
4441+
4442+#include "uipopt.h"
4443+
4444+struct fsdata_file {
4445+ const struct fsdata_file *next;
4446+ const char *name;
4447+ const char *data;
4448+ const int len;
4449+#ifdef FS_STATISTICS
4450+#if FS_STATISTICS == 1
4451+ u16_t count;
4452+#endif /* FS_STATISTICS */
4453+#endif /* FS_STATISTICS */
4454+};
4455+
4456+struct fsdata_file_noconst {
4457+ struct fsdata_file *next;
4458+ char *name;
4459+ char *data;
4460+ int len;
4461+#ifdef FS_STATISTICS
4462+#if FS_STATISTICS == 1
4463+ u16_t count;
4464+#endif /* FS_STATISTICS */
4465+#endif /* FS_STATISTICS */
4466+};
4467+
4468+#endif /* __FSDATA_H__ */
4469--- /dev/null
4470+++ b/net/uip-0.9/fs.h
4471@@ -0,0 +1,80 @@
4472+/**
4473+ * \addtogroup httpd
4474+ * @{
4475+ */
4476+
4477+/**
4478+ * \file
4479+ * HTTP server read-only file system header file.
4480+ * \author Adam Dunkels <adam@dunkels.com>
4481+ */
4482+
4483+/*
4484+ * Copyright (c) 2001, Swedish Institute of Computer Science.
4485+ * All rights reserved.
4486+ *
4487+ * Redistribution and use in source and binary forms, with or without
4488+ * modification, are permitted provided that the following conditions
4489+ * are met:
4490+ * 1. Redistributions of source code must retain the above copyright
4491+ * notice, this list of conditions and the following disclaimer.
4492+ * 2. Redistributions in binary form must reproduce the above copyright
4493+ * notice, this list of conditions and the following disclaimer in the
4494+ * documentation and/or other materials provided with the distribution.
4495+ * 3. Neither the name of the Institute nor the names of its contributors
4496+ * may be used to endorse or promote products derived from this software
4497+ * without specific prior written permission.
4498+ *
4499+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4500+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4501+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4502+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4503+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4504+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4505+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4506+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4507+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4508+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4509+ * SUCH DAMAGE.
4510+ *
4511+ * This file is part of the lwIP TCP/IP stack.
4512+ *
4513+ * Author: Adam Dunkels <adam@sics.se>
4514+ *
4515+ * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $
4516+ */
4517+#ifndef __FS_H__
4518+#define __FS_H__
4519+
4520+#include "uip.h"
4521+
4522+/**
4523+ * An open file in the read-only file system.
4524+ */
4525+struct fs_file {
4526+ char *data; /**< The actual file data. */
4527+ int len; /**< The length of the file data. */
4528+};
4529+
4530+/**
4531+ * Open a file in the read-only file system.
4532+ *
4533+ * \param name The name of the file.
4534+ *
4535+ * \param file The file pointer, which must be allocated by caller and
4536+ * will be filled in by the function.
4537+ */
4538+int fs_open(const char *name, struct fs_file *file);
4539+
4540+#ifdef FS_STATISTICS
4541+#if FS_STATISTICS == 1
4542+u16_t fs_count(char *name);
4543+#endif /* FS_STATISTICS */
4544+#endif /* FS_STATISTICS */
4545+
4546+/**
4547+ * Initialize the read-only file system.
4548+ */
4549+void fs_init(void);
4550+
4551+#endif /* __FS_H__ */
4552--- /dev/null
4553+++ b/net/uip-0.9/httpd.c
4554@@ -0,0 +1,278 @@
4555+#include "uip.h"
4556+#include "httpd.h"
4557+#include "fs.h"
4558+#include "fsdata.h"
4559+#include <asm/addrspace.h>
4560+
4561+#define HTTP_NONE 0
4562+#define HTTP_FILE 1
4563+#define HTTP_FIRMWARE 2
4564+
4565+#define PRINT(x) printf("%s", x)
4566+#define PRINTLN(x) printf("%s\n", x)
4567+
4568+extern unsigned long do_http_tmp_address(void);
4569+
4570+struct httpd_state *hs;
4571+
4572+extern const struct fsdata_file file_index_html;
4573+extern const struct fsdata_file file_404_html;
4574+extern const struct fsdata_file file_flash_html;
4575+extern int httpd_upload_complete;
4576+extern unsigned char *httpd_upload_data;
4577+unsigned char *upload_data;
4578+extern ulong NetBootFileXferSize;
4579+int upload_running = 0;
4580+
4581+#define ISO_G 0x47
4582+#define ISO_E 0x45
4583+#define ISO_T 0x54
4584+#define ISO_P 0x50
4585+#define ISO_O 0x4f
4586+#define ISO_S 0x53
4587+#define ISO_T 0x54
4588+#define ISO_slash 0x2f
4589+#define ISO_c 0x63
4590+#define ISO_g 0x67
4591+#define ISO_i 0x69
4592+#define ISO_space 0x20
4593+#define ISO_nl 0x0a
4594+#define ISO_cr 0x0d
4595+#define ISO_a 0x61
4596+#define ISO_t 0x74
4597+#define ISO_hash 0x23
4598+#define ISO_period 0x2e
4599+
4600+static char eol[3] = { 0x0d, 0x0a, 0x00 };
4601+static char eol2[5] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00 };
4602+static char boundary[128];
4603+static int boundary_len = 0;
4604+
4605+/* we use this so that we can do without the ctype library */
4606+#define is_digit(c) ((c) >= '0' && (c) <= '9')
4607+static int atoi(const char *s)
4608+{
4609+ int i=0;
4610+
4611+ while (is_digit(*s))
4612+ i = i*10 + *(s++) - '0';
4613+ return i;
4614+}
4615+
4616+void
4617+httpd_init(void)
4618+{
4619+ fs_init();
4620+ uip_listen(HTONS(80));
4621+}
4622+
4623+void
4624+httpd_appcall(void)
4625+{
4626+ struct fs_file fsfile;
4627+ u8_t i;
4628+ switch(uip_conn->lport) {
4629+ case HTONS(80):
4630+ hs = (struct httpd_state *)(uip_conn->appstate);
4631+ if(uip_connected())
4632+ {
4633+ hs->state = HTTP_NONE;
4634+ hs->count = 0;
4635+ return;
4636+ } else if(uip_poll())
4637+ {
4638+ if(hs->count++ >= 1000) {
4639+ uip_abort();
4640+ }
4641+ return;
4642+ } else if(uip_newdata() && hs->state == HTTP_NONE)
4643+ {
4644+ if(uip_appdata[0] == ISO_G &&
4645+ uip_appdata[1] == ISO_E &&
4646+ uip_appdata[2] == ISO_T &&
4647+ uip_appdata[3] == ISO_space)
4648+ {
4649+ hs->state = HTTP_FILE;
4650+ }
4651+ if(uip_appdata[0] == ISO_P &&
4652+ uip_appdata[1] == ISO_O &&
4653+ uip_appdata[2] == ISO_S &&
4654+ uip_appdata[3] == ISO_T &&
4655+ uip_appdata[4] == ISO_space)
4656+ {
4657+ hs->state = HTTP_FIRMWARE;
4658+ }
4659+ if(hs->state == HTTP_NONE)
4660+ {
4661+ uip_abort();
4662+ return;
4663+ }
4664+ if(hs->state == HTTP_FILE)
4665+ {
4666+ for(i = 4; i < 40; ++i)
4667+ {
4668+ if(uip_appdata[i] == ISO_space ||
4669+ uip_appdata[i] == ISO_cr ||
4670+ uip_appdata[i] == ISO_nl)
4671+ {
4672+ uip_appdata[i] = 0;
4673+ break;
4674+ }
4675+ }
4676+
4677+ PRINT("request for file ");
4678+ PRINTLN(&uip_appdata[4]);
4679+ if(uip_appdata[4] == ISO_slash &&
4680+ uip_appdata[5] == 0)
4681+ {
4682+ fs_open(file_index_html.name, &fsfile);
4683+ } else {
4684+ if(!fs_open((const char *)&uip_appdata[4], &fsfile))
4685+ {
4686+ PRINTLN("couldn't open file");
4687+ fs_open(file_index_html.name, &fsfile);
4688+ }
4689+ }
4690+ hs->script = 0;
4691+ hs->state = HTTP_FILE;
4692+ hs->dataptr = fsfile.data;
4693+ hs->count = fsfile.len;
4694+ }
4695+ if(hs->state == HTTP_FIRMWARE)
4696+ {
4697+ unsigned char *start = (unsigned char*)uip_appdata;
4698+ char *clen = strstr(start, "Content-Length:");
4699+ int len = 0;
4700+ unsigned char *next, *end;
4701+ unsigned char *boundary_start;
4702+ int i;
4703+ uip_appdata[uip_len] = '\0';
4704+ if(clen)
4705+ {
4706+ clen += sizeof("Content-Length:");
4707+ next = strstr(clen, eol);
4708+ if(next)
4709+ {
4710+ len = atoi(clen);
4711+ next++;
4712+ printf("expecting %d bytes\n", len);
4713+ upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
4714+ printf("received data will be stored at 0x%08X\n", upload_data);
4715+ if(!upload_data)
4716+ {
4717+ printf("failed to allocate memory\n");
4718+ uip_close();
4719+ return;
4720+ }
4721+ } else {
4722+ uip_close();
4723+ return;
4724+ }
4725+ }
4726+ if(len < 4 * 1024)
4727+ {
4728+ uip_close();
4729+ return;
4730+ }
4731+ boundary_start = strstr(next, "---");
4732+ if(!boundary_start)
4733+ {
4734+ uip_close();
4735+ return;
4736+ }
4737+ end = strstr(boundary_start, eol);
4738+ if(!eol)
4739+ {
4740+ uip_close();
4741+ return;
4742+ }
4743+ boundary_len = end - boundary_start;
4744+ memcpy(boundary, boundary_start, boundary_len);
4745+ boundary[boundary_len] = 0;
4746+ next = strstr(boundary_start, "name=\"firmware\";");
4747+ if(!next)
4748+ {
4749+ uip_close();
4750+ return;
4751+ }
4752+ next = strstr(next, eol2);
4753+ if(!next)
4754+ {
4755+ printf("could not find start of data\n");
4756+ uip_close();
4757+ return;
4758+ }
4759+ next += 4;
4760+ hs->script = 0;
4761+ hs->state = HTTP_FIRMWARE;
4762+ hs->upload = uip_len - (next - start);
4763+ hs->upload_total = len - (int)(next - boundary_start);
4764+ hs->upload_total -= (strlen(boundary) + 6);
4765+ //printf("storing %d bytes at %p\n", (int)hs->upload, upload_data);
4766+ for(i = 0; i < hs->upload; i++)
4767+ upload_data[i] = next[i];
4768+ upload_data += (int)hs->upload;
4769+ printf("%d / %d\n", (int)hs->upload, hs->upload_total);
4770+ uip_slen = 0;
4771+ return;
4772+ }
4773+ }
4774+
4775+ if(hs->state == HTTP_FIRMWARE)
4776+ {
4777+ if(uip_newdata())
4778+ {
4779+ int i;
4780+ hs->count = 0;
4781+ uip_appdata[uip_len] = '\0';
4782+ hs->upload += uip_len;
4783+ //printf("storing %d bytes at %p\n", uip_len, upload_data);
4784+ printf("%d / %d\n", (int)hs->upload, hs->upload_total);
4785+ for(i = 0; i < uip_len; i++)
4786+ upload_data[i] = uip_appdata[i];
4787+ upload_data += uip_len;
4788+ uip_slen = 0;
4789+ if(hs->upload >= hs->upload_total)
4790+ {
4791+ upload_running = 1;
4792+ NetBootFileXferSize = hs->upload_total;
4793+ fs_open(file_flash_html.name, &fsfile);
4794+ hs->script = 0;
4795+ hs->state = HTTP_FILE;
4796+ hs->dataptr = fsfile.data;
4797+ hs->count = fsfile.len;
4798+ }
4799+ }
4800+ }
4801+ if(hs->state == HTTP_FILE)
4802+ {
4803+ if(uip_acked())
4804+ {
4805+ if(hs->count >= uip_conn->len)
4806+ {
4807+ hs->count -= uip_conn->len;
4808+ hs->dataptr += uip_conn->len;
4809+ } else {
4810+ hs->count = 0;
4811+ }
4812+ if(hs->count == 0)
4813+ {
4814+ if(upload_running)
4815+ {
4816+ int i;
4817+ httpd_upload_complete = 1;
4818+ // for(i = 0; i < hs->upload_total; i++)
4819+ // printf("%c", httpd_upload_data[i]);
4820+ }
4821+ uip_close();
4822+ }
4823+ }
4824+ uip_send(hs->dataptr, hs->count);
4825+ }
4826+ break;
4827+
4828+ default:
4829+ uip_abort();
4830+ break;
4831+ }
4832+}
4833--- /dev/null
4834+++ b/net/uip-0.9/httpd.h
4835@@ -0,0 +1,83 @@
4836+/**
4837+ * \addtogroup httpd
4838+ * @{
4839+ */
4840+
4841+/**
4842+ * \file
4843+ * HTTP server header file.
4844+ * \author Adam Dunkels <adam@dunkels.com>
4845+ */
4846+
4847+/*
4848+ * Copyright (c) 2001, Adam Dunkels.
4849+ * All rights reserved.
4850+ *
4851+ * Redistribution and use in source and binary forms, with or without
4852+ * modification, are permitted provided that the following conditions
4853+ * are met:
4854+ * 1. Redistributions of source code must retain the above copyright
4855+ * notice, this list of conditions and the following disclaimer.
4856+ * 2. Redistributions in binary form must reproduce the above copyright
4857+ * notice, this list of conditions and the following disclaimer in the
4858+ * documentation and/or other materials provided with the distribution.
4859+ * 3. The name of the author may not be used to endorse or promote
4860+ * products derived from this software without specific prior
4861+ * written permission.
4862+ *
4863+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4864+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4865+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4866+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4867+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4868+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4869+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4870+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4871+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4872+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4873+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4874+ *
4875+ * This file is part of the uIP TCP/IP stack.
4876+ *
4877+ * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $
4878+ *
4879+ */
4880+
4881+#ifndef __HTTPD_H__
4882+#define __HTTPD_H__
4883+
4884+void httpd_init(void);
4885+void httpd_appcall(void);
4886+
4887+/* UIP_APPCALL: the name of the application function. This function
4888+ must return void and take no arguments (i.e., C type "void
4889+ appfunc(void)"). */
4890+#ifndef UIP_APPCALL
4891+#define UIP_APPCALL httpd_appcall
4892+#endif
4893+
4894+struct httpd_state {
4895+ u8_t state;
4896+ u16_t count;
4897+ char *dataptr;
4898+ char *script;
4899+ unsigned int upload;
4900+ unsigned int upload_total;
4901+};
4902+
4903+
4904+/* UIP_APPSTATE_SIZE: The size of the application-specific state
4905+ stored in the uip_conn structure. */
4906+#ifndef UIP_APPSTATE_SIZE
4907+#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
4908+#endif
4909+
4910+#define FS_STATISTICS 1
4911+
4912+extern struct httpd_state *hs;
4913+
4914+
4915+/* we copy the data to RAM+10MB */
4916+#define TMP_DATA 0x8A100000
4917+
4918+#endif /* __HTTPD_H__ */
4919--- /dev/null
4920+++ b/net/uip-0.9/main.c
4921@@ -0,0 +1,88 @@
4922+/*
4923+ * Copyright (c) 2001-2003, Adam Dunkels.
4924+ * All rights reserved.
4925+ *
4926+ * Redistribution and use in source and binary forms, with or without
4927+ * modification, are permitted provided that the following conditions
4928+ * are met:
4929+ * 1. Redistributions of source code must retain the above copyright
4930+ * notice, this list of conditions and the following disclaimer.
4931+ * 2. Redistributions in binary form must reproduce the above copyright
4932+ * notice, this list of conditions and the following disclaimer in the
4933+ * documentation and/or other materials provided with the distribution.
4934+ * 3. The name of the author may not be used to endorse or promote
4935+ * products derived from this software without specific prior
4936+ * written permission.
4937+ *
4938+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4939+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4940+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4941+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4942+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4943+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4944+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4945+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4946+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4947+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4948+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4949+ *
4950+ * This file is part of the uIP TCP/IP stack.
4951+ *
4952+ * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $
4953+ *
4954+ */
4955+
4956+
4957+#include "uip.h"
4958+#include "uip_arp.h"
4959+#include "tapdev.h"
4960+#include "httpd.h"
4961+
4962+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
4963+
4964+#ifndef NULL
4965+#define NULL (void *)0
4966+#endif /* NULL */
4967+
4968+/*-----------------------------------------------------------------------------------*/
4969+int
4970+main(void)
4971+{
4972+ u8_t i, arptimer;
4973+ tapdev_init();
4974+ uip_init();
4975+ httpd_init();
4976+ arptimer = 0;
4977+ while(1) {
4978+ uip_len = tapdev_read();
4979+ if(uip_len == 0) {
4980+ for(i = 0; i < UIP_CONNS; i++) {
4981+ uip_periodic(i);
4982+ if(uip_len > 0) {
4983+ uip_arp_out();
4984+ tapdev_send();
4985+ }
4986+ }
4987+
4988+ if(++arptimer == 20) {
4989+ uip_arp_timer();
4990+ arptimer = 0;
4991+ }
4992+ } else {
4993+ if(BUF->type == htons(UIP_ETHTYPE_IP)) {
4994+ uip_arp_ipin();
4995+ uip_input();
4996+ if(uip_len > 0) {
4997+ uip_arp_out();
4998+ tapdev_send();
4999+ }
5000+ } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
5001+ uip_arp_arpin();
5002+ if(uip_len > 0) {
5003+ tapdev_send();
5004+ }
5005+ }
5006+ }
5007+ }
5008+ return 0;
5009+}
5010--- /dev/null
5011+++ b/net/uip-0.9/Makefile
5012@@ -0,0 +1,54 @@
5013+# Copyright (c) 2001, Adam Dunkels.
5014+# All rights reserved.
5015+#
5016+# Redistribution and use in source and binary forms, with or without
5017+# modification, are permitted provided that the following conditions
5018+# are met:
5019+# 1. Redistributions of source code must retain the above copyright
5020+# notice, this list of conditions and the following disclaimer.
5021+# 2. Redistributions in binary form must reproduce the above copyright
5022+# notice, this list of conditions and the following disclaimer in the
5023+# documentation and/or other materials provided with the distribution.
5024+# 3. All advertising materials mentioning features or use of this software
5025+# must display the following acknowledgement:
5026+# This product includes software developed by Adam Dunkels.
5027+# 4. The name of the author may not be used to endorse or promote
5028+# products derived from this software without specific prior
5029+# written permission.
5030+#
5031+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5032+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5033+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5034+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5035+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5036+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5037+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5038+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5039+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5040+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5041+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5042+#
5043+# This file is part of the uIP TCP/IP stack.
5044+#
5045+# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $
5046+#
5047+
5048+CC=gcc
5049+CFLAGS=-Wall -fpack-struct -DDUMP=0
5050+
5051+all: uip
5052+
5053+uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o
5054+ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
5055+
5056+%.o: %.c
5057+ $(CC) $(CFLAGS) -c $^ -o $@
5058+
5059+clean:
5060+ rm -f *.o *~ *core uip
5061+
5062+
5063+
5064+
5065+
5066+
5067--- /dev/null
5068+++ b/net/uip-0.9/tapdev.c
5069@@ -0,0 +1,192 @@
5070+/*
5071+ * Copyright (c) 2001, Swedish Institute of Computer Science.
5072+ * All rights reserved.
5073+ *
5074+ * Redistribution and use in source and binary forms, with or without
5075+ * modification, are permitted provided that the following conditions
5076+ * are met:
5077+ *
5078+ * 1. Redistributions of source code must retain the above copyright
5079+ * notice, this list of conditions and the following disclaimer.
5080+ *
5081+ * 2. Redistributions in binary form must reproduce the above copyright
5082+ * notice, this list of conditions and the following disclaimer in the
5083+ * documentation and/or other materials provided with the distribution.
5084+ *
5085+ * 3. Neither the name of the Institute nor the names of its contributors
5086+ * may be used to endorse or promote products derived from this software
5087+ * without specific prior written permission.
5088+ *
5089+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
5090+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5091+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5092+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
5093+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5094+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5095+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5096+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5097+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5098+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5099+ * SUCH DAMAGE.
5100+ *
5101+ * Author: Adam Dunkels <adam@sics.se>
5102+ *
5103+ * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $
5104+ */
5105+
5106+
5107+#include <fcntl.h>
5108+#include <stdlib.h>
5109+#include <stdio.h>
5110+#include <unistd.h>
5111+#include <string.h>
5112+#include <sys/ioctl.h>
5113+#include <sys/socket.h>
5114+#include <sys/types.h>
5115+#include <sys/time.h>
5116+#include <sys/uio.h>
5117+#include <sys/socket.h>
5118+
5119+#ifdef linux
5120+#include <sys/ioctl.h>
5121+#include <linux/if.h>
5122+#include <linux/if_tun.h>
5123+#define DEVTAP "/dev/net/tun"
5124+#else /* linux */
5125+#define DEVTAP "/dev/tap0"
5126+#endif /* linux */
5127+
5128+#include "uip.h"
5129+
5130+static int fd;
5131+
5132+static unsigned long lasttime;
5133+static struct timezone tz;
5134+
5135+/*-----------------------------------------------------------------------------------*/
5136+void
5137+tapdev_init(void)
5138+{
5139+ char buf[1024];
5140+
5141+ fd = open(DEVTAP, O_RDWR);
5142+ if(fd == -1) {
5143+ perror("tapdev: tapdev_init: open");
5144+ exit(1);
5145+ }
5146+
5147+#ifdef linux
5148+ {
5149+ struct ifreq ifr;
5150+ memset(&ifr, 0, sizeof(ifr));
5151+ ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
5152+ if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
5153+ perror(buf);
5154+ exit(1);
5155+ }
5156+ }
5157+#endif /* Linux */
5158+
5159+ snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
5160+ UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);
5161+ system(buf);
5162+
5163+ lasttime = 0;
5164+}
5165+
5166+void dump_mem(int type, int len)
5167+{
5168+#if DUMP == 1
5169+ int i;
5170+ for(i = 0; i < len; i++)
5171+ printf("%c", uip_buf[i]);
5172+ if(type)
5173+ {
5174+ 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");
5175+ 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");
5176+ } else {
5177+ 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");
5178+ 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");
5179+ }
5180+ fflush(stdout);
5181+#endif
5182+}
5183+
5184+/*-----------------------------------------------------------------------------------*/
5185+unsigned int
5186+tapdev_read(void)
5187+{
5188+ fd_set fdset;
5189+ struct timeval tv, now;
5190+ int ret;
5191+
5192+ if(lasttime >= 500000) {
5193+ lasttime = 0;
5194+ return 0;
5195+ }
5196+
5197+ tv.tv_sec = 0;
5198+ tv.tv_usec = 500000 - lasttime;
5199+
5200+
5201+ FD_ZERO(&fdset);
5202+ FD_SET(fd, &fdset);
5203+
5204+ gettimeofday(&now, &tz);
5205+ ret = select(fd + 1, &fdset, NULL, NULL, &tv);
5206+ if(ret == 0) {
5207+ lasttime = 0;
5208+ return 0;
5209+ }
5210+ ret = read(fd, uip_buf, UIP_BUFSIZE);
5211+ if(ret == -1) {
5212+ perror("tap_dev: tapdev_read: read");
5213+ }
5214+ gettimeofday(&tv, &tz);
5215+ lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
5216+ dump_mem(0, ret);
5217+ return ret;
5218+}
5219+/*-----------------------------------------------------------------------------------*/
5220+void
5221+tapdev_send(void)
5222+{
5223+ int ret;
5224+ struct iovec iov[2];
5225+
5226+#ifdef linux
5227+ {
5228+ char tmpbuf[UIP_BUFSIZE];
5229+ int i;
5230+
5231+ for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
5232+ tmpbuf[i] = uip_buf[i];
5233+ }
5234+
5235+ for(; i < uip_len; i++) {
5236+ tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
5237+ }
5238+
5239+ ret = write(fd, tmpbuf, uip_len);
5240+ }
5241+#else
5242+
5243+ if(uip_len < 40 + UIP_LLH_LEN) {
5244+ ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN);
5245+ } else {
5246+ iov[0].iov_base = uip_buf;
5247+ iov[0].iov_len = 40 + UIP_LLH_LEN;
5248+ iov[1].iov_base = (char *)uip_appdata;
5249+ iov[1].iov_len = uip_len - (40 + UIP_LLH_LEN);
5250+
5251+ ret = writev(fd, iov, 2);
5252+ }
5253+#endif
5254+ dump_mem(1, ret);
5255+
5256+ if(ret == -1) {
5257+ perror("tap_dev: tapdev_send: writev");
5258+ exit(1);
5259+ }
5260+}
5261+/*-----------------------------------------------------------------------------------*/
5262--- /dev/null
5263+++ b/net/uip-0.9/tapdev.h
5264@@ -0,0 +1,42 @@
5265+/*
5266+ * Copyright (c) 2001, Adam Dunkels.
5267+ * All rights reserved.
5268+ *
5269+ * Redistribution and use in source and binary forms, with or without
5270+ * modification, are permitted provided that the following conditions
5271+ * are met:
5272+ * 1. Redistributions of source code must retain the above copyright
5273+ * notice, this list of conditions and the following disclaimer.
5274+ * 2. Redistributions in binary form must reproduce the above copyright
5275+ * notice, this list of conditions and the following disclaimer in the
5276+ * documentation and/or other materials provided with the distribution.
5277+ * 3. The name of the author may not be used to endorse or promote
5278+ * products derived from this software without specific prior
5279+ * written permission.
5280+ *
5281+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5282+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5283+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5284+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5285+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5286+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5287+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5288+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5289+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5290+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5291+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5292+ *
5293+ * This file is part of the uIP TCP/IP stack.
5294+ *
5295+ * $Id: tapdev.h,v 1.1.2.1 2003/10/04 22:54:17 adam Exp $
5296+ *
5297+ */
5298+
5299+#ifndef __TAPDEV_H__
5300+#define __TAPDEV_H__
5301+
5302+void tapdev_init(void);
5303+unsigned int tapdev_read(void);
5304+void tapdev_send(void);
5305+
5306+#endif /* __TAPDEV_H__ */
5307--- /dev/null
5308+++ b/net/uip-0.9/uip_arch.c
5309@@ -0,0 +1,145 @@
5310+/*
5311+ * Copyright (c) 2001, Adam Dunkels.
5312+ * All rights reserved.
5313+ *
5314+ * Redistribution and use in source and binary forms, with or without
5315+ * modification, are permitted provided that the following conditions
5316+ * are met:
5317+ * 1. Redistributions of source code must retain the above copyright
5318+ * notice, this list of conditions and the following disclaimer.
5319+ * 2. Redistributions in binary form must reproduce the above copyright
5320+ * notice, this list of conditions and the following disclaimer in the
5321+ * documentation and/or other materials provided with the distribution.
5322+ * 3. The name of the author may not be used to endorse or promote
5323+ * products derived from this software without specific prior
5324+ * written permission.
5325+ *
5326+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5327+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5328+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5329+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5330+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5331+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5332+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5333+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5334+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5335+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5336+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5337+ *
5338+ * This file is part of the uIP TCP/IP stack.
5339+ *
5340+ * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
5341+ *
5342+ */
5343+
5344+
5345+#include "uip.h"
5346+#include "uip_arch.h"
5347+
5348+#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
5349+#define IP_PROTO_TCP 6
5350+
5351+/*-----------------------------------------------------------------------------------*/
5352+void
5353+uip_add32(u8_t *op32, u16_t op16)
5354+{
5355+
5356+ uip_acc32[3] = op32[3] + (op16 & 0xff);
5357+ uip_acc32[2] = op32[2] + (op16 >> 8);
5358+ uip_acc32[1] = op32[1];
5359+ uip_acc32[0] = op32[0];
5360+
5361+ if(uip_acc32[2] < (op16 >> 8)) {
5362+ ++uip_acc32[1];
5363+ if(uip_acc32[1] == 0) {
5364+ ++uip_acc32[0];
5365+ }
5366+ }
5367+
5368+
5369+ if(uip_acc32[3] < (op16 & 0xff)) {
5370+ ++uip_acc32[2];
5371+ if(uip_acc32[2] == 0) {
5372+ ++uip_acc32[1];
5373+ if(uip_acc32[1] == 0) {
5374+ ++uip_acc32[0];
5375+ }
5376+ }
5377+ }
5378+}
5379+/*-----------------------------------------------------------------------------------*/
5380+u16_t
5381+uip_chksum(u16_t *sdata, u16_t len)
5382+{
5383+ u16_t acc;
5384+
5385+ for(acc = 0; len > 1; len -= 2) {
5386+ acc += *sdata;
5387+ if(acc < *sdata) {
5388+ /* Overflow, so we add the carry to acc (i.e., increase by
5389+ one). */
5390+ ++acc;
5391+ }
5392+ ++sdata;
5393+ }
5394+
5395+ /* add up any odd byte */
5396+ if(len == 1) {
5397+ acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
5398+ if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
5399+ ++acc;
5400+ }
5401+ }
5402+
5403+ return acc;
5404+}
5405+/*-----------------------------------------------------------------------------------*/
5406+u16_t
5407+uip_ipchksum(void)
5408+{
5409+ return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
5410+}
5411+/*-----------------------------------------------------------------------------------*/
5412+u16_t
5413+uip_tcpchksum(void)
5414+{
5415+ u16_t hsum, sum;
5416+
5417+
5418+ /* Compute the checksum of the TCP header. */
5419+ hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
5420+
5421+ /* Compute the checksum of the data in the TCP packet and add it to
5422+ the TCP header checksum. */
5423+ sum = uip_chksum((u16_t *)uip_appdata,
5424+ (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
5425+
5426+ if((sum += hsum) < hsum) {
5427+ ++sum;
5428+ }
5429+
5430+ if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
5431+ ++sum;
5432+ }
5433+ if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
5434+ ++sum;
5435+ }
5436+ if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
5437+ ++sum;
5438+ }
5439+ if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
5440+ ++sum;
5441+ }
5442+ if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
5443+ ++sum;
5444+ }
5445+
5446+ hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
5447+
5448+ if((sum += hsum) < hsum) {
5449+ ++sum;
5450+ }
5451+
5452+ return sum;
5453+}
5454+/*-----------------------------------------------------------------------------------*/
5455--- /dev/null
5456+++ b/net/uip-0.9/uip_arch.h
5457@@ -0,0 +1,130 @@
5458+/**
5459+ * \defgroup uiparch Architecture specific uIP functions
5460+ * @{
5461+ *
5462+ * The functions in the architecture specific module implement the IP
5463+ * check sum and 32-bit additions.
5464+ *
5465+ * The IP checksum calculation is the most computationally expensive
5466+ * operation in the TCP/IP stack and it therefore pays off to
5467+ * implement this in efficient assembler. The purpose of the uip-arch
5468+ * module is to let the checksum functions to be implemented in
5469+ * architecture specific assembler.
5470+ *
5471+ */
5472+
5473+/**
5474+ * \file
5475+ * Declarations of architecture specific functions.
5476+ * \author Adam Dunkels <adam@dunkels.com>
5477+ */
5478+
5479+/*
5480+ * Copyright (c) 2001, Adam Dunkels.
5481+ * All rights reserved.
5482+ *
5483+ * Redistribution and use in source and binary forms, with or without
5484+ * modification, are permitted provided that the following conditions
5485+ * are met:
5486+ * 1. Redistributions of source code must retain the above copyright
5487+ * notice, this list of conditions and the following disclaimer.
5488+ * 2. Redistributions in binary form must reproduce the above copyright
5489+ * notice, this list of conditions and the following disclaimer in the
5490+ * documentation and/or other materials provided with the distribution.
5491+ * 3. The name of the author may not be used to endorse or promote
5492+ * products derived from this software without specific prior
5493+ * written permission.
5494+ *
5495+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5496+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5497+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5498+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5499+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5500+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5501+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5502+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5503+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5504+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5505+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5506+ *
5507+ * This file is part of the uIP TCP/IP stack.
5508+ *
5509+ * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $
5510+ *
5511+ */
5512+
5513+#ifndef __UIP_ARCH_H__
5514+#define __UIP_ARCH_H__
5515+
5516+#include "uip.h"
5517+
5518+/**
5519+ * Carry out a 32-bit addition.
5520+ *
5521+ * Because not all architectures for which uIP is intended has native
5522+ * 32-bit arithmetic, uIP uses an external C function for doing the
5523+ * required 32-bit additions in the TCP protocol processing. This
5524+ * function should add the two arguments and place the result in the
5525+ * global variable uip_acc32.
5526+ *
5527+ * \note The 32-bit integer pointed to by the op32 parameter and the
5528+ * result in the uip_acc32 variable are in network byte order (big
5529+ * endian).
5530+ *
5531+ * \param op32 A pointer to a 4-byte array representing a 32-bit
5532+ * integer in network byte order (big endian).
5533+ *
5534+ * \param op16 A 16-bit integer in host byte order.
5535+ */
5536+void uip_add32(u8_t *op32, u16_t op16);
5537+
5538+/**
5539+ * Calculate the Internet checksum over a buffer.
5540+ *
5541+ * The Internet checksum is the one's complement of the one's
5542+ * complement sum of all 16-bit words in the buffer.
5543+ *
5544+ * See RFC1071.
5545+ *
5546+ * \note This function is not called in the current version of uIP,
5547+ * but future versions might make use of it.
5548+ *
5549+ * \param buf A pointer to the buffer over which the checksum is to be
5550+ * computed.
5551+ *
5552+ * \param len The length of the buffer over which the checksum is to
5553+ * be computed.
5554+ *
5555+ * \return The Internet checksum of the buffer.
5556+ */
5557+u16_t uip_chksum(u16_t *buf, u16_t len);
5558+
5559+/**
5560+ * Calculate the IP header checksum of the packet header in uip_buf.
5561+ *
5562+ * The IP header checksum is the Internet checksum of the 20 bytes of
5563+ * the IP header.
5564+ *
5565+ * \return The IP header checksum of the IP header in the uip_buf
5566+ * buffer.
5567+ */
5568+u16_t uip_ipchksum(void);
5569+
5570+/**
5571+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
5572+ *
5573+ * The TCP checksum is the Internet checksum of data contents of the
5574+ * TCP segment, and a pseudo-header as defined in RFC793.
5575+ *
5576+ * \note The uip_appdata pointer that points to the packet data may
5577+ * point anywhere in memory, so it is not possible to simply calculate
5578+ * the Internet checksum of the contents of the uip_buf buffer.
5579+ *
5580+ * \return The TCP checksum of the TCP segment in uip_buf and pointed
5581+ * to by uip_appdata.
5582+ */
5583+u16_t uip_tcpchksum(void);
5584+
5585+/** @} */
5586+
5587+#endif /* __UIP_ARCH_H__ */
5588--- /dev/null
5589+++ b/net/uip-0.9/uip_arp.c
5590@@ -0,0 +1,421 @@
5591+/**
5592+ * \addtogroup uip
5593+ * @{
5594+ */
5595+
5596+/**
5597+ * \defgroup uiparp uIP Address Resolution Protocol
5598+ * @{
5599+ *
5600+ * The Address Resolution Protocol ARP is used for mapping between IP
5601+ * addresses and link level addresses such as the Ethernet MAC
5602+ * addresses. ARP uses broadcast queries to ask for the link level
5603+ * address of a known IP address and the host which is configured with
5604+ * the IP address for which the query was meant, will respond with its
5605+ * link level address.
5606+ *
5607+ * \note This ARP implementation only supports Ethernet.
5608+ */
5609+
5610+/**
5611+ * \file
5612+ * Implementation of the ARP Address Resolution Protocol.
5613+ * \author Adam Dunkels <adam@dunkels.com>
5614+ *
5615+ */
5616+
5617+/*
5618+ * Copyright (c) 2001-2003, Adam Dunkels.
5619+ * All rights reserved.
5620+ *
5621+ * Redistribution and use in source and binary forms, with or without
5622+ * modification, are permitted provided that the following conditions
5623+ * are met:
5624+ * 1. Redistributions of source code must retain the above copyright
5625+ * notice, this list of conditions and the following disclaimer.
5626+ * 2. Redistributions in binary form must reproduce the above copyright
5627+ * notice, this list of conditions and the following disclaimer in the
5628+ * documentation and/or other materials provided with the distribution.
5629+ * 3. The name of the author may not be used to endorse or promote
5630+ * products derived from this software without specific prior
5631+ * written permission.
5632+ *
5633+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5634+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5635+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5636+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5637+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5638+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5639+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5640+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5641+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5642+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5643+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5644+ *
5645+ * This file is part of the uIP TCP/IP stack.
5646+ *
5647+ * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $
5648+ *
5649+ */
5650+
5651+
5652+#include "uip_arp.h"
5653+
5654+struct arp_hdr {
5655+ struct uip_eth_hdr ethhdr;
5656+ u16_t hwtype;
5657+ u16_t protocol;
5658+ u8_t hwlen;
5659+ u8_t protolen;
5660+ u16_t opcode;
5661+ struct uip_eth_addr shwaddr;
5662+ u16_t sipaddr[2];
5663+ struct uip_eth_addr dhwaddr;
5664+ u16_t dipaddr[2];
5665+};
5666+
5667+struct ethip_hdr {
5668+ struct uip_eth_hdr ethhdr;
5669+ /* IP header. */
5670+ u8_t vhl,
5671+ tos,
5672+ len[2],
5673+ ipid[2],
5674+ ipoffset[2],
5675+ ttl,
5676+ proto;
5677+ u16_t ipchksum;
5678+ u16_t srcipaddr[2],
5679+ destipaddr[2];
5680+};
5681+
5682+#define ARP_REQUEST 1
5683+#define ARP_REPLY 2
5684+
5685+#define ARP_HWTYPE_ETH 1
5686+
5687+struct arp_entry {
5688+ u16_t ipaddr[2];
5689+ struct uip_eth_addr ethaddr;
5690+ u8_t time;
5691+};
5692+
5693+struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
5694+ UIP_ETHADDR1,
5695+ UIP_ETHADDR2,
5696+ UIP_ETHADDR3,
5697+ UIP_ETHADDR4,
5698+ UIP_ETHADDR5}};
5699+
5700+static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
5701+static u16_t ipaddr[2];
5702+static u8_t i, c;
5703+
5704+static u8_t arptime;
5705+static u8_t tmpage;
5706+
5707+#define BUF ((struct arp_hdr *)&uip_buf[0])
5708+#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
5709+/*-----------------------------------------------------------------------------------*/
5710+/**
5711+ * Initialize the ARP module.
5712+ *
5713+ */
5714+/*-----------------------------------------------------------------------------------*/
5715+void
5716+uip_arp_init(void)
5717+{
5718+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5719+ memset(arp_table[i].ipaddr, 0, 4);
5720+ }
5721+}
5722+/*-----------------------------------------------------------------------------------*/
5723+/**
5724+ * Periodic ARP processing function.
5725+ *
5726+ * This function performs periodic timer processing in the ARP module
5727+ * and should be called at regular intervals. The recommended interval
5728+ * is 10 seconds between the calls.
5729+ *
5730+ */
5731+/*-----------------------------------------------------------------------------------*/
5732+void
5733+uip_arp_timer(void)
5734+{
5735+ struct arp_entry *tabptr;
5736+
5737+ ++arptime;
5738+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5739+ tabptr = &arp_table[i];
5740+ if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
5741+ arptime - tabptr->time >= UIP_ARP_MAXAGE) {
5742+ memset(tabptr->ipaddr, 0, 4);
5743+ }
5744+ }
5745+
5746+}
5747+/*-----------------------------------------------------------------------------------*/
5748+static void
5749+uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
5750+{
5751+ register struct arp_entry *tabptr;
5752+ /* Walk through the ARP mapping table and try to find an entry to
5753+ update. If none is found, the IP -> MAC address mapping is
5754+ inserted in the ARP table. */
5755+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5756+
5757+ tabptr = &arp_table[i];
5758+ /* Only check those entries that are actually in use. */
5759+ if(tabptr->ipaddr[0] != 0 &&
5760+ tabptr->ipaddr[1] != 0) {
5761+
5762+ /* Check if the source IP address of the incoming packet matches
5763+ the IP address in this ARP table entry. */
5764+ if(ipaddr[0] == tabptr->ipaddr[0] &&
5765+ ipaddr[1] == tabptr->ipaddr[1]) {
5766+
5767+ /* An old entry found, update this and return. */
5768+ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
5769+ tabptr->time = arptime;
5770+
5771+ return;
5772+ }
5773+ }
5774+ }
5775+
5776+ /* If we get here, no existing ARP table entry was found, so we
5777+ create one. */
5778+
5779+ /* First, we try to find an unused entry in the ARP table. */
5780+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5781+ tabptr = &arp_table[i];
5782+ if(tabptr->ipaddr[0] == 0 &&
5783+ tabptr->ipaddr[1] == 0) {
5784+ break;
5785+ }
5786+ }
5787+
5788+ /* If no unused entry is found, we try to find the oldest entry and
5789+ throw it away. */
5790+ if(i == UIP_ARPTAB_SIZE) {
5791+ tmpage = 0;
5792+ c = 0;
5793+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5794+ tabptr = &arp_table[i];
5795+ if(arptime - tabptr->time > tmpage) {
5796+ tmpage = arptime - tabptr->time;
5797+ c = i;
5798+ }
5799+ }
5800+ i = c;
5801+ }
5802+
5803+ /* Now, i is the ARP table entry which we will fill with the new
5804+ information. */
5805+ memcpy(tabptr->ipaddr, ipaddr, 4);
5806+ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
5807+ tabptr->time = arptime;
5808+}
5809+/*-----------------------------------------------------------------------------------*/
5810+/**
5811+ * ARP processing for incoming IP packets
5812+ *
5813+ * This function should be called by the device driver when an IP
5814+ * packet has been received. The function will check if the address is
5815+ * in the ARP cache, and if so the ARP cache entry will be
5816+ * refreshed. If no ARP cache entry was found, a new one is created.
5817+ *
5818+ * This function expects an IP packet with a prepended Ethernet header
5819+ * in the uip_buf[] buffer, and the length of the packet in the global
5820+ * variable uip_len.
5821+ */
5822+/*-----------------------------------------------------------------------------------*/
5823+void
5824+uip_arp_ipin(void)
5825+{
5826+ uip_len -= sizeof(struct uip_eth_hdr);
5827+
5828+ /* Only insert/update an entry if the source IP address of the
5829+ incoming IP packet comes from a host on the local network. */
5830+ if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
5831+ (uip_hostaddr[0] & uip_arp_netmask[0])) {
5832+ return;
5833+ }
5834+ if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
5835+ (uip_hostaddr[1] & uip_arp_netmask[1])) {
5836+ return;
5837+ }
5838+ uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
5839+
5840+ return;
5841+}
5842+/*-----------------------------------------------------------------------------------*/
5843+/**
5844+ * ARP processing for incoming ARP packets.
5845+ *
5846+ * This function should be called by the device driver when an ARP
5847+ * packet has been received. The function will act differently
5848+ * depending on the ARP packet type: if it is a reply for a request
5849+ * that we previously sent out, the ARP cache will be filled in with
5850+ * the values from the ARP reply. If the incoming ARP packet is an ARP
5851+ * request for our IP address, an ARP reply packet is created and put
5852+ * into the uip_buf[] buffer.
5853+ *
5854+ * When the function returns, the value of the global variable uip_len
5855+ * indicates whether the device driver should send out a packet or
5856+ * not. If uip_len is zero, no packet should be sent. If uip_len is
5857+ * non-zero, it contains the length of the outbound packet that is
5858+ * present in the uip_buf[] buffer.
5859+ *
5860+ * This function expects an ARP packet with a prepended Ethernet
5861+ * header in the uip_buf[] buffer, and the length of the packet in the
5862+ * global variable uip_len.
5863+ */
5864+/*-----------------------------------------------------------------------------------*/
5865+void
5866+uip_arp_arpin(void)
5867+{
5868+
5869+ if(uip_len < sizeof(struct arp_hdr)) {
5870+ uip_len = 0;
5871+ return;
5872+ }
5873+
5874+ uip_len = 0;
5875+
5876+ switch(BUF->opcode) {
5877+ case HTONS(ARP_REQUEST):
5878+ /* ARP request. If it asked for our address, we send out a
5879+ reply. */
5880+ if(BUF->dipaddr[0] == uip_hostaddr[0] &&
5881+ BUF->dipaddr[1] == uip_hostaddr[1]) {
5882+ /* The reply opcode is 2. */
5883+ BUF->opcode = HTONS(2);
5884+
5885+ memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
5886+ memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
5887+ memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
5888+ memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
5889+
5890+ BUF->dipaddr[0] = BUF->sipaddr[0];
5891+ BUF->dipaddr[1] = BUF->sipaddr[1];
5892+ BUF->sipaddr[0] = uip_hostaddr[0];
5893+ BUF->sipaddr[1] = uip_hostaddr[1];
5894+
5895+ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
5896+ uip_len = sizeof(struct arp_hdr);
5897+ }
5898+ break;
5899+ case HTONS(ARP_REPLY):
5900+ /* ARP reply. We insert or update the ARP table if it was meant
5901+ for us. */
5902+ if(BUF->dipaddr[0] == uip_hostaddr[0] &&
5903+ BUF->dipaddr[1] == uip_hostaddr[1]) {
5904+
5905+ uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
5906+ }
5907+ break;
5908+ }
5909+
5910+ return;
5911+}
5912+/*-----------------------------------------------------------------------------------*/
5913+/**
5914+ * Prepend Ethernet header to an outbound IP packet and see if we need
5915+ * to send out an ARP request.
5916+ *
5917+ * This function should be called before sending out an IP packet. The
5918+ * function checks the destination IP address of the IP packet to see
5919+ * what Ethernet MAC address that should be used as a destination MAC
5920+ * address on the Ethernet.
5921+ *
5922+ * If the destination IP address is in the local network (determined
5923+ * by logical ANDing of netmask and our IP address), the function
5924+ * checks the ARP cache to see if an entry for the destination IP
5925+ * address is found. If so, an Ethernet header is prepended and the
5926+ * function returns. If no ARP cache entry is found for the
5927+ * destination IP address, the packet in the uip_buf[] is replaced by
5928+ * an ARP request packet for the IP address. The IP packet is dropped
5929+ * and it is assumed that they higher level protocols (e.g., TCP)
5930+ * eventually will retransmit the dropped packet.
5931+ *
5932+ * If the destination IP address is not on the local network, the IP
5933+ * address of the default router is used instead.
5934+ *
5935+ * When the function returns, a packet is present in the uip_buf[]
5936+ * buffer, and the length of the packet is in the global variable
5937+ * uip_len.
5938+ */
5939+/*-----------------------------------------------------------------------------------*/
5940+void
5941+uip_arp_out(void)
5942+{
5943+ struct arp_entry *tabptr;
5944+ /* Find the destination IP address in the ARP table and construct
5945+ the Ethernet header. If the destination IP addres isn't on the
5946+ local network, we use the default router's IP address instead.
5947+
5948+ If not ARP table entry is found, we overwrite the original IP
5949+ packet with an ARP request for the IP address. */
5950+
5951+ /* Check if the destination address is on the local network. */
5952+ if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) !=
5953+ (uip_hostaddr[0] & uip_arp_netmask[0]) ||
5954+ (IPBUF->destipaddr[1] & uip_arp_netmask[1]) !=
5955+ (uip_hostaddr[1] & uip_arp_netmask[1])) {
5956+ /* Destination address was not on the local network, so we need to
5957+ use the default router's IP address instead of the destination
5958+ address when determining the MAC address. */
5959+ ipaddr[0] = uip_arp_draddr[0];
5960+ ipaddr[1] = uip_arp_draddr[1];
5961+ } else {
5962+ /* Else, we use the destination IP address. */
5963+ ipaddr[0] = IPBUF->destipaddr[0];
5964+ ipaddr[1] = IPBUF->destipaddr[1];
5965+ }
5966+
5967+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5968+ tabptr = &arp_table[i];
5969+ if(ipaddr[0] == tabptr->ipaddr[0] &&
5970+ ipaddr[1] == tabptr->ipaddr[1])
5971+ break;
5972+ }
5973+
5974+ if(i == UIP_ARPTAB_SIZE) {
5975+ /* The destination address was not in our ARP table, so we
5976+ overwrite the IP packet with an ARP request. */
5977+
5978+ memset(BUF->ethhdr.dest.addr, 0xff, 6);
5979+ memset(BUF->dhwaddr.addr, 0x00, 6);
5980+ memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
5981+ memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
5982+
5983+ BUF->dipaddr[0] = ipaddr[0];
5984+ BUF->dipaddr[1] = ipaddr[1];
5985+ BUF->sipaddr[0] = uip_hostaddr[0];
5986+ BUF->sipaddr[1] = uip_hostaddr[1];
5987+ BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
5988+ BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
5989+ BUF->protocol = HTONS(UIP_ETHTYPE_IP);
5990+ BUF->hwlen = 6;
5991+ BUF->protolen = 4;
5992+ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
5993+
5994+ uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
5995+
5996+ uip_len = sizeof(struct arp_hdr);
5997+ return;
5998+ }
5999+
6000+ /* Build an ethernet header. */
6001+ memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
6002+ memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
6003+
6004+ IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
6005+
6006+ uip_len += sizeof(struct uip_eth_hdr);
6007+}
6008+/*-----------------------------------------------------------------------------------*/
6009+
6010+/** @} */
6011+/** @} */
6012--- /dev/null
6013+++ b/net/uip-0.9/uip_arp.h
6014@@ -0,0 +1,201 @@
6015+/**
6016+ * \addtogroup uip
6017+ * @{
6018+ */
6019+
6020+/**
6021+ * \addtogroup uiparp
6022+ * @{
6023+ */
6024+
6025+/**
6026+ * \file
6027+ * Macros and definitions for the ARP module.
6028+ * \author Adam Dunkels <adam@dunkels.com>
6029+ */
6030+
6031+
6032+/*
6033+ * Copyright (c) 2001-2003, Adam Dunkels.
6034+ * All rights reserved.
6035+ *
6036+ * Redistribution and use in source and binary forms, with or without
6037+ * modification, are permitted provided that the following conditions
6038+ * are met:
6039+ * 1. Redistributions of source code must retain the above copyright
6040+ * notice, this list of conditions and the following disclaimer.
6041+ * 2. Redistributions in binary form must reproduce the above copyright
6042+ * notice, this list of conditions and the following disclaimer in the
6043+ * documentation and/or other materials provided with the distribution.
6044+ * 3. The name of the author may not be used to endorse or promote
6045+ * products derived from this software without specific prior
6046+ * written permission.
6047+ *
6048+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
6049+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6050+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6051+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
6052+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6053+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6054+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6055+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
6056+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6057+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6058+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6059+ *
6060+ * This file is part of the uIP TCP/IP stack.
6061+ *
6062+ * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $
6063+ *
6064+ */
6065+
6066+#ifndef __UIP_ARP_H__
6067+#define __UIP_ARP_H__
6068+
6069+#include "uip.h"
6070+
6071+
6072+/**
6073+ * Representation of a 48-bit Ethernet address.
6074+ */
6075+struct uip_eth_addr {
6076+ u8_t addr[6];
6077+};
6078+
6079+extern struct uip_eth_addr uip_ethaddr;
6080+
6081+/**
6082+ * The Ethernet header.
6083+ */
6084+struct uip_eth_hdr {
6085+ struct uip_eth_addr dest;
6086+ struct uip_eth_addr src;
6087+ u16_t type;
6088+};
6089+
6090+#define UIP_ETHTYPE_ARP 0x0806
6091+#define UIP_ETHTYPE_IP 0x0800
6092+#define UIP_ETHTYPE_IP6 0x86dd
6093+
6094+
6095+/* The uip_arp_init() function must be called before any of the other
6096+ ARP functions. */
6097+void uip_arp_init(void);
6098+
6099+/* The uip_arp_ipin() function should be called whenever an IP packet
6100+ arrives from the Ethernet. This function refreshes the ARP table or
6101+ inserts a new mapping if none exists. The function assumes that an
6102+ IP packet with an Ethernet header is present in the uip_buf buffer
6103+ and that the length of the packet is in the uip_len variable. */
6104+void uip_arp_ipin(void);
6105+
6106+/* The uip_arp_arpin() should be called when an ARP packet is received
6107+ by the Ethernet driver. This function also assumes that the
6108+ Ethernet frame is present in the uip_buf buffer. When the
6109+ uip_arp_arpin() function returns, the contents of the uip_buf
6110+ buffer should be sent out on the Ethernet if the uip_len variable
6111+ is > 0. */
6112+void uip_arp_arpin(void);
6113+
6114+/* The uip_arp_out() function should be called when an IP packet
6115+ should be sent out on the Ethernet. This function creates an
6116+ Ethernet header before the IP header in the uip_buf buffer. The
6117+ Ethernet header will have the correct Ethernet MAC destination
6118+ address filled in if an ARP table entry for the destination IP
6119+ address (or the IP address of the default router) is present. If no
6120+ such table entry is found, the IP packet is overwritten with an ARP
6121+ request and we rely on TCP to retransmit the packet that was
6122+ overwritten. In any case, the uip_len variable holds the length of
6123+ the Ethernet frame that should be transmitted. */
6124+void uip_arp_out(void);
6125+
6126+/* The uip_arp_timer() function should be called every ten seconds. It
6127+ is responsible for flushing old entries in the ARP table. */
6128+void uip_arp_timer(void);
6129+
6130+/** @} */
6131+
6132+/**
6133+ * \addtogroup uipconffunc
6134+ * @{
6135+ */
6136+
6137+/**
6138+ * Set the default router's IP address.
6139+ *
6140+ * \param addr A pointer to a 4-byte array containing the IP address
6141+ * of the default router.
6142+ *
6143+ * \hideinitializer
6144+ */
6145+#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \
6146+ uip_arp_draddr[1] = addr[1]; } while(0)
6147+
6148+/**
6149+ * Set the netmask.
6150+ *
6151+ * \param addr A pointer to a 4-byte array containing the IP address
6152+ * of the netmask.
6153+ *
6154+ * \hideinitializer
6155+ */
6156+#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \
6157+ uip_arp_netmask[1] = addr[1]; } while(0)
6158+
6159+
6160+/**
6161+ * Get the default router's IP address.
6162+ *
6163+ * \param addr A pointer to a 4-byte array that will be filled in with
6164+ * the IP address of the default router.
6165+ *
6166+ * \hideinitializer
6167+ */
6168+#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \
6169+ addr[1] = uip_arp_draddr[1]; } while(0)
6170+
6171+/**
6172+ * Get the netmask.
6173+ *
6174+ * \param addr A pointer to a 4-byte array that will be filled in with
6175+ * the value of the netmask.
6176+ *
6177+ * \hideinitializer
6178+ */
6179+#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \
6180+ addr[1] = uip_arp_netmask[1]; } while(0)
6181+
6182+
6183+/**
6184+ * Specifiy the Ethernet MAC address.
6185+ *
6186+ * The ARP code needs to know the MAC address of the Ethernet card in
6187+ * order to be able to respond to ARP queries and to generate working
6188+ * Ethernet headers.
6189+ *
6190+ * \note This macro only specifies the Ethernet MAC address to the ARP
6191+ * code. It cannot be used to change the MAC address of the Ethernet
6192+ * card.
6193+ *
6194+ * \param eaddr A pointer to a struct uip_eth_addr containing the
6195+ * Ethernet MAC address of the Ethernet card.
6196+ *
6197+ * \hideinitializer
6198+ */
6199+#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
6200+ uip_ethaddr.addr[1] = eaddr.addr[1];\
6201+ uip_ethaddr.addr[2] = eaddr.addr[2];\
6202+ uip_ethaddr.addr[3] = eaddr.addr[3];\
6203+ uip_ethaddr.addr[4] = eaddr.addr[4];\
6204+ uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
6205+
6206+/** @} */
6207+
6208+/**
6209+ * \internal Internal variables that are set using the macros
6210+ * uip_setdraddr and uip_setnetmask.
6211+ */
6212+extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
6213+#endif /* __UIP_ARP_H__ */
6214+
6215+
6216--- /dev/null
6217+++ b/net/uip-0.9/uip.c
6218@@ -0,0 +1,1503 @@
6219+/**
6220+ * \addtogroup uip
6221+ * @{
6222+ */
6223+
6224+/**
6225+ * \file
6226+ * The uIP TCP/IP stack code.
6227+ * \author Adam Dunkels <adam@dunkels.com>
6228+ */
6229+
6230+/*
6231+ * Copyright (c) 2001-2003, Adam Dunkels.
6232+ * All rights reserved.
6233+ *
6234+ * Redistribution and use in source and binary forms, with or without
6235+ * modification, are permitted provided that the following conditions
6236+ * are met:
6237+ * 1. Redistributions of source code must retain the above copyright
6238+ * notice, this list of conditions and the following disclaimer.
6239+ * 2. Redistributions in binary form must reproduce the above copyright
6240+ * notice, this list of conditions and the following disclaimer in the
6241+ * documentation and/or other materials provided with the distribution.
6242+ * 3. The name of the author may not be used to endorse or promote
6243+ * products derived from this software without specific prior
6244+ * written permission.
6245+ *
6246+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
6247+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6248+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6249+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
6250+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6251+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6252+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6253+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
6254+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6255+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6256+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6257+ *
6258+ * This file is part of the uIP TCP/IP stack.
6259+ *
6260+ * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
6261+ *
6262+ */
6263+
6264+/*
6265+This is a small implementation of the IP and TCP protocols (as well as
6266+some basic ICMP stuff). The implementation couples the IP, TCP and the
6267+application layers very tightly. To keep the size of the compiled code
6268+down, this code also features heavy usage of the goto statement.
6269+
6270+The principle is that we have a small buffer, called the uip_buf, in
6271+which the device driver puts an incoming packet. The TCP/IP stack
6272+parses the headers in the packet, and calls upon the application. If
6273+the remote host has sent data to the application, this data is present
6274+in the uip_buf and the application read the data from there. It is up
6275+to the application to put this data into a byte stream if needed. The
6276+application will not be fed with data that is out of sequence.
6277+
6278+If the application whishes to send data to the peer, it should put its
6279+data into the uip_buf, 40 bytes from the start of the buffer. The
6280+TCP/IP stack will calculate the checksums, and fill in the necessary
6281+header fields and finally send the packet back to the peer.
6282+*/
6283+
6284+#include "uip.h"
6285+#include "uipopt.h"
6286+#include "uip_arch.h"
6287+
6288+/*-----------------------------------------------------------------------------------*/
6289+/* Variable definitions. */
6290+
6291+
6292+/* 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 */
6293+#if UIP_FIXEDADDR > 0
6294+const unsigned short int uip_hostaddr[2] =
6295+ {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
6296+ HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
6297+const unsigned short int uip_arp_draddr[2] =
6298+ {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
6299+ HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
6300+const unsigned short int uip_arp_netmask[2] =
6301+ {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
6302+ HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
6303+#else
6304+unsigned short int uip_hostaddr[2];
6305+unsigned short int uip_arp_draddr[2], uip_arp_netmask[2];
6306+#endif /* UIP_FIXEDADDR */
6307+
6308+u8_t uip_buf[UIP_BUFSIZE+2]; /* The packet buffer that contains
6309+ incoming packets. */
6310+volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
6311+ application data. */
6312+volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to the
6313+ application data which is to be sent. */
6314+#if UIP_URGDATA > 0
6315+volatile u8_t *uip_urgdata; /* The uip_urgdata pointer points to
6316+ urgent data (out-of-band data), if
6317+ present. */
6318+volatile u8_t uip_urglen, uip_surglen;
6319+#endif /* UIP_URGDATA > 0 */
6320+
6321+volatile unsigned short int uip_len, uip_slen;
6322+ /* The uip_len is either 8 or 16 bits,
6323+ depending on the maximum packet
6324+ size. */
6325+
6326+volatile u8_t uip_flags; /* The uip_flags variable is used for
6327+ communication between the TCP/IP stack
6328+ and the application program. */
6329+struct uip_conn *uip_conn; /* uip_conn always points to the current
6330+ connection. */
6331+
6332+struct uip_conn uip_conns[UIP_CONNS];
6333+ /* The uip_conns array holds all TCP
6334+ connections. */
6335+unsigned short int uip_listenports[UIP_LISTENPORTS];
6336+ /* The uip_listenports list all currently
6337+ listning ports. */
6338+#if UIP_UDP
6339+struct uip_udp_conn *uip_udp_conn;
6340+struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
6341+#endif /* UIP_UDP */
6342+
6343+
6344+static unsigned short int ipid; /* Ths ipid variable is an increasing
6345+ number that is used for the IP ID
6346+ field. */
6347+
6348+static u8_t iss[4]; /* The iss variable is used for the TCP
6349+ initial sequence number. */
6350+
6351+#if UIP_ACTIVE_OPEN
6352+static unsigned short int lastport; /* Keeps track of the last port used for
6353+ a new connection. */
6354+#endif /* UIP_ACTIVE_OPEN */
6355+
6356+/* Temporary variables. */
6357+volatile u8_t uip_acc32[4];
6358+static u8_t c, opt;
6359+static unsigned short int tmp16;
6360+
6361+/* Structures and definitions. */
6362+#define TCP_FIN 0x01
6363+#define TCP_SYN 0x02
6364+#define TCP_RST 0x04
6365+#define TCP_PSH 0x08
6366+#define TCP_ACK 0x10
6367+#define TCP_URG 0x20
6368+#define TCP_CTL 0x3f
6369+
6370+#define ICMP_ECHO_REPLY 0
6371+#define ICMP_ECHO 8
6372+
6373+/* Macros. */
6374+#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
6375+#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
6376+#define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
6377+#define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
6378+
6379+#if UIP_STATISTICS == 1
6380+struct uip_stats uip_stat;
6381+#define UIP_STAT(s) s
6382+#else
6383+#define UIP_STAT(s)
6384+#endif /* UIP_STATISTICS == 1 */
6385+
6386+#if UIP_LOGGING == 1
6387+extern void puts(const char *s);
6388+#define UIP_LOG(m) puts(m)
6389+#else
6390+#define UIP_LOG(m)
6391+#endif /* UIP_LOGGING == 1 */
6392+
6393+/*-----------------------------------------------------------------------------------*/
6394+void
6395+uip_init(void)
6396+{
6397+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
6398+ uip_listenports[c] = 0;
6399+ }
6400+ for(c = 0; c < UIP_CONNS; ++c) {
6401+ uip_conns[c].tcpstateflags = CLOSED;
6402+ }
6403+#if UIP_ACTIVE_OPEN
6404+ lastport = 1024;
6405+#endif /* UIP_ACTIVE_OPEN */
6406+
6407+#if UIP_UDP
6408+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
6409+ uip_udp_conns[c].lport = 0;
6410+ }
6411+#endif /* UIP_UDP */
6412+
6413+
6414+ /* IPv4 initialization. */
6415+#if UIP_FIXEDADDR == 0
6416+ uip_hostaddr[0] = uip_hostaddr[1] = 0;
6417+#endif /* UIP_FIXEDADDR */
6418+
6419+}
6420+/*-----------------------------------------------------------------------------------*/
6421+#if UIP_ACTIVE_OPEN
6422+struct uip_conn *
6423+uip_connect(unsigned short int *ripaddr, unsigned short int rport)
6424+{
6425+ register struct uip_conn *conn, *cconn;
6426+
6427+ /* Find an unused local port. */
6428+ again:
6429+ ++lastport;
6430+
6431+ if(lastport >= 32000) {
6432+ lastport = 4096;
6433+ }
6434+
6435+ /* Check if this port is already in use, and if so try to find
6436+ another one. */
6437+ for(c = 0; c < UIP_CONNS; ++c) {
6438+ conn = &uip_conns[c];
6439+ if(conn->tcpstateflags != CLOSED &&
6440+ conn->lport == htons(lastport)) {
6441+ goto again;
6442+ }
6443+ }
6444+
6445+
6446+ conn = 0;
6447+ for(c = 0; c < UIP_CONNS; ++c) {
6448+ cconn = &uip_conns[c];
6449+ if(cconn->tcpstateflags == CLOSED) {
6450+ conn = cconn;
6451+ break;
6452+ }
6453+ if(cconn->tcpstateflags == TIME_WAIT) {
6454+ if(conn == 0 ||
6455+ cconn->timer > uip_conn->timer) {
6456+ conn = cconn;
6457+ }
6458+ }
6459+ }
6460+
6461+ if(conn == 0) {
6462+ return 0;
6463+ }
6464+
6465+ conn->tcpstateflags = SYN_SENT;
6466+
6467+ conn->snd_nxt[0] = iss[0];
6468+ conn->snd_nxt[1] = iss[1];
6469+ conn->snd_nxt[2] = iss[2];
6470+ conn->snd_nxt[3] = iss[3];
6471+
6472+ conn->initialmss = conn->mss = UIP_TCP_MSS;
6473+
6474+ conn->len = 1; /* TCP length of the SYN is one. */
6475+ conn->nrtx = 0;
6476+ conn->timer = 1; /* Send the SYN next time around. */
6477+ conn->rto = UIP_RTO;
6478+ conn->sa = 0;
6479+ conn->sv = 16;
6480+ conn->lport = htons(lastport);
6481+ conn->rport = rport;
6482+ conn->ripaddr[0] = ripaddr[0];
6483+ conn->ripaddr[1] = ripaddr[1];
6484+
6485+ return conn;
6486+}
6487+#endif /* UIP_ACTIVE_OPEN */
6488+/*-----------------------------------------------------------------------------------*/
6489+#if UIP_UDP
6490+struct uip_udp_conn *
6491+uip_udp_new(unsigned short int *ripaddr, unsigned short int rport)
6492+{
6493+ register struct uip_udp_conn *conn;
6494+
6495+ /* Find an unused local port. */
6496+ again:
6497+ ++lastport;
6498+
6499+ if(lastport >= 32000) {
6500+ lastport = 4096;
6501+ }
6502+
6503+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
6504+ if(uip_udp_conns[c].lport == lastport) {
6505+ goto again;
6506+ }
6507+ }
6508+
6509+
6510+ conn = 0;
6511+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
6512+ if(uip_udp_conns[c].lport == 0) {
6513+ conn = &uip_udp_conns[c];
6514+ break;
6515+ }
6516+ }
6517+
6518+ if(conn == 0) {
6519+ return 0;
6520+ }
6521+
6522+ conn->lport = HTONS(lastport);
6523+ conn->rport = HTONS(rport);
6524+ conn->ripaddr[0] = ripaddr[0];
6525+ conn->ripaddr[1] = ripaddr[1];
6526+
6527+ return conn;
6528+}
6529+#endif /* UIP_UDP */
6530+/*-----------------------------------------------------------------------------------*/
6531+void
6532+uip_unlisten(unsigned short int port)
6533+{
6534+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
6535+ if(uip_listenports[c] == port) {
6536+ uip_listenports[c] = 0;
6537+ return;
6538+ }
6539+ }
6540+}
6541+/*-----------------------------------------------------------------------------------*/
6542+void
6543+uip_listen(unsigned short int port)
6544+{
6545+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
6546+ if(uip_listenports[c] == 0) {
6547+ uip_listenports[c] = port;
6548+ return;
6549+ }
6550+ }
6551+}
6552+/*-----------------------------------------------------------------------------------*/
6553+/* XXX: IP fragment reassembly: not well-tested. */
6554+
6555+#if UIP_REASSEMBLY
6556+#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
6557+static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
6558+static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
6559+static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
6560+ 0x0f, 0x07, 0x03, 0x01};
6561+static unsigned short int uip_reasslen;
6562+static u8_t uip_reassflags;
6563+#define UIP_REASS_FLAG_LASTFRAG 0x01
6564+static u8_t uip_reasstmr;
6565+
6566+#define IP_HLEN 20
6567+#define IP_MF 0x20
6568+
6569+static u8_t
6570+uip_reass(void)
6571+{
6572+ unsigned short int offset, len;
6573+ unsigned short int i;
6574+
6575+ /* If ip_reasstmr is zero, no packet is present in the buffer, so we
6576+ write the IP header of the fragment into the reassembly
6577+ buffer. The timer is updated with the maximum age. */
6578+ if(uip_reasstmr == 0) {
6579+ memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
6580+ uip_reasstmr = UIP_REASS_MAXAGE;
6581+ uip_reassflags = 0;
6582+ /* Clear the bitmap. */
6583+ memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
6584+ }
6585+
6586+ /* Check if the incoming fragment matches the one currently present
6587+ in the reasembly buffer. If so, we proceed with copying the
6588+ fragment into the buffer. */
6589+ if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
6590+ BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
6591+ BUF->destipaddr[0] == FBUF->destipaddr[0] &&
6592+ BUF->destipaddr[1] == FBUF->destipaddr[1] &&
6593+ BUF->ipid[0] == FBUF->ipid[0] &&
6594+ BUF->ipid[1] == FBUF->ipid[1]) {
6595+
6596+ len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
6597+ offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
6598+
6599+ /* If the offset or the offset + fragment length overflows the
6600+ reassembly buffer, we discard the entire packet. */
6601+ if(offset > UIP_REASS_BUFSIZE ||
6602+ offset + len > UIP_REASS_BUFSIZE) {
6603+ uip_reasstmr = 0;
6604+ goto nullreturn;
6605+ }
6606+
6607+ /* Copy the fragment into the reassembly buffer, at the right
6608+ offset. */
6609+ memcpy(&uip_reassbuf[IP_HLEN + offset],
6610+ (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
6611+ len);
6612+
6613+ /* Update the bitmap. */
6614+ if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
6615+ /* If the two endpoints are in the same byte, we only update
6616+ that byte. */
6617+
6618+ uip_reassbitmap[offset / (8 * 8)] |=
6619+ bitmap_bits[(offset / 8 ) & 7] &
6620+ ~bitmap_bits[((offset + len) / 8 ) & 7];
6621+ } else {
6622+ /* If the two endpoints are in different bytes, we update the
6623+ bytes in the endpoints and fill the stuff inbetween with
6624+ 0xff. */
6625+ uip_reassbitmap[offset / (8 * 8)] |=
6626+ bitmap_bits[(offset / 8 ) & 7];
6627+ for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
6628+ uip_reassbitmap[i] = 0xff;
6629+ }
6630+ uip_reassbitmap[(offset + len) / (8 * 8)] |=
6631+ ~bitmap_bits[((offset + len) / 8 ) & 7];
6632+ }
6633+
6634+ /* If this fragment has the More Fragments flag set to zero, we
6635+ know that this is the last fragment, so we can calculate the
6636+ size of the entire packet. We also set the
6637+ IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
6638+ the final fragment. */
6639+
6640+ if((BUF->ipoffset[0] & IP_MF) == 0) {
6641+ uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
6642+ uip_reasslen = offset + len;
6643+ }
6644+
6645+ /* Finally, we check if we have a full packet in the buffer. We do
6646+ this by checking if we have the last fragment and if all bits
6647+ in the bitmap are set. */
6648+ if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
6649+ /* Check all bytes up to and including all but the last byte in
6650+ the bitmap. */
6651+ for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
6652+ if(uip_reassbitmap[i] != 0xff) {
6653+ goto nullreturn;
6654+ }
6655+ }
6656+ /* Check the last byte in the bitmap. It should contain just the
6657+ right amount of bits. */
6658+ if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
6659+ (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
6660+ goto nullreturn;
6661+ }
6662+
6663+ /* If we have come this far, we have a full packet in the
6664+ buffer, so we allocate a pbuf and copy the packet into it. We
6665+ also reset the timer. */
6666+ uip_reasstmr = 0;
6667+ memcpy(BUF, FBUF, uip_reasslen);
6668+
6669+ /* Pretend to be a "normal" (i.e., not fragmented) IP packet
6670+ from now on. */
6671+ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
6672+ BUF->len[0] = uip_reasslen >> 8;
6673+ BUF->len[1] = uip_reasslen & 0xff;
6674+ BUF->ipchksum = 0;
6675+ BUF->ipchksum = ~(uip_ipchksum());
6676+
6677+ return uip_reasslen;
6678+ }
6679+ }
6680+
6681+ nullreturn:
6682+ return 0;
6683+}
6684+#endif /* UIP_REASSEMBL */
6685+/*-----------------------------------------------------------------------------------*/
6686+static void
6687+uip_add_rcv_nxt(unsigned short int n)
6688+{
6689+ uip_add32(uip_conn->rcv_nxt, n);
6690+ uip_conn->rcv_nxt[0] = uip_acc32[0];
6691+ uip_conn->rcv_nxt[1] = uip_acc32[1];
6692+ uip_conn->rcv_nxt[2] = uip_acc32[2];
6693+ uip_conn->rcv_nxt[3] = uip_acc32[3];
6694+}
6695+/*-----------------------------------------------------------------------------------*/
6696+void
6697+uip_process(u8_t flag)
6698+{
6699+ register struct uip_conn *uip_connr = uip_conn;
6700+
6701+ uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
6702+
6703+
6704+ /* Check if we were invoked because of the perodic timer fireing. */
6705+ if(flag == UIP_TIMER) {
6706+#if UIP_REASSEMBLY
6707+ if(uip_reasstmr != 0) {
6708+ --uip_reasstmr;
6709+ }
6710+#endif /* UIP_REASSEMBLY */
6711+ /* Increase the initial sequence number. */
6712+ if(++iss[3] == 0) {
6713+ if(++iss[2] == 0) {
6714+ if(++iss[1] == 0) {
6715+ ++iss[0];
6716+ }
6717+ }
6718+ }
6719+ uip_len = 0;
6720+ if(uip_connr->tcpstateflags == TIME_WAIT ||
6721+ uip_connr->tcpstateflags == FIN_WAIT_2) {
6722+ ++(uip_connr->timer);
6723+ if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
6724+ uip_connr->tcpstateflags = CLOSED;
6725+ }
6726+ } else if(uip_connr->tcpstateflags != CLOSED) {
6727+ /* If the connection has outstanding data, we increase the
6728+ connection's timer and see if it has reached the RTO value
6729+ in which case we retransmit. */
6730+ if(uip_outstanding(uip_connr)) {
6731+ if(uip_connr->timer-- == 0) {
6732+ if(uip_connr->nrtx == UIP_MAXRTX ||
6733+ ((uip_connr->tcpstateflags == SYN_SENT ||
6734+ uip_connr->tcpstateflags == SYN_RCVD) &&
6735+ uip_connr->nrtx == UIP_MAXSYNRTX)) {
6736+ uip_connr->tcpstateflags = CLOSED;
6737+
6738+ /* We call UIP_APPCALL() with uip_flags set to
6739+ UIP_TIMEDOUT to inform the application that the
6740+ connection has timed out. */
6741+ uip_flags = UIP_TIMEDOUT;
6742+ UIP_APPCALL();
6743+
6744+ /* We also send a reset packet to the remote host. */
6745+ BUF->flags = TCP_RST | TCP_ACK;
6746+ goto tcp_send_nodata;
6747+ }
6748+
6749+ /* Exponential backoff. */
6750+ uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
6751+ 4:
6752+ uip_connr->nrtx);
6753+ ++(uip_connr->nrtx);
6754+
6755+ /* Ok, so we need to retransmit. We do this differently
6756+ depending on which state we are in. In ESTABLISHED, we
6757+ call upon the application so that it may prepare the
6758+ data for the retransmit. In SYN_RCVD, we resend the
6759+ SYNACK that we sent earlier and in LAST_ACK we have to
6760+ retransmit our FINACK. */
6761+ UIP_STAT(++uip_stat.tcp.rexmit);
6762+ switch(uip_connr->tcpstateflags & TS_MASK) {
6763+ case SYN_RCVD:
6764+ /* In the SYN_RCVD state, we should retransmit our
6765+ SYNACK. */
6766+ goto tcp_send_synack;
6767+
6768+#if UIP_ACTIVE_OPEN
6769+ case SYN_SENT:
6770+ /* In the SYN_SENT state, we retransmit out SYN. */
6771+ BUF->flags = 0;
6772+ goto tcp_send_syn;
6773+#endif /* UIP_ACTIVE_OPEN */
6774+
6775+ case ESTABLISHED:
6776+ /* In the ESTABLISHED state, we call upon the application
6777+ to do the actual retransmit after which we jump into
6778+ the code for sending out the packet (the apprexmit
6779+ label). */
6780+ uip_len = 0;
6781+ uip_slen = 0;
6782+ uip_flags = UIP_REXMIT;
6783+ UIP_APPCALL();
6784+ goto apprexmit;
6785+
6786+ case FIN_WAIT_1:
6787+ case CLOSING:
6788+ case LAST_ACK:
6789+ /* In all these states we should retransmit a FINACK. */
6790+ goto tcp_send_finack;
6791+
6792+ }
6793+ }
6794+ } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
6795+ /* If there was no need for a retransmission, we poll the
6796+ application for new data. */
6797+ uip_len = 0;
6798+ uip_slen = 0;
6799+ uip_flags = UIP_POLL;
6800+ UIP_APPCALL();
6801+ goto appsend;
6802+ }
6803+ }
6804+ goto drop;
6805+ }
6806+#if UIP_UDP
6807+ if(flag == UIP_UDP_TIMER) {
6808+ if(uip_udp_conn->lport != 0) {
6809+ uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
6810+ uip_len = uip_slen = 0;
6811+ uip_flags = UIP_POLL;
6812+ UIP_UDP_APPCALL();
6813+ goto udp_send;
6814+ } else {
6815+ goto drop;
6816+ }
6817+ }
6818+#endif
6819+
6820+ /* This is where the input processing starts. */
6821+ UIP_STAT(++uip_stat.ip.recv);
6822+
6823+
6824+ /* Start of IPv4 input header processing code. */
6825+
6826+ /* Check validity of the IP header. */
6827+ if(BUF->vhl != 0x45) { /* IP version and header length. */
6828+ UIP_STAT(++uip_stat.ip.drop);
6829+ UIP_STAT(++uip_stat.ip.vhlerr);
6830+ UIP_LOG("ip: invalid version or header length.");
6831+ goto drop;
6832+ }
6833+
6834+ /* Check the size of the packet. If the size reported to us in
6835+ uip_len doesn't match the size reported in the IP header, there
6836+ has been a transmission error and we drop the packet. */
6837+
6838+ if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
6839+ uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
6840+ }
6841+ if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
6842+ uip_len = (uip_len & 0xff00) | BUF->len[1];
6843+ }
6844+
6845+ /* Check the fragment flag. */
6846+ if((BUF->ipoffset[0] & 0x3f) != 0 ||
6847+ BUF->ipoffset[1] != 0) {
6848+#if UIP_REASSEMBLY
6849+ uip_len = uip_reass();
6850+ if(uip_len == 0) {
6851+ goto drop;
6852+ }
6853+#else
6854+ UIP_STAT(++uip_stat.ip.drop);
6855+ UIP_STAT(++uip_stat.ip.fragerr);
6856+ UIP_LOG("ip: fragment dropped.");
6857+ goto drop;
6858+#endif /* UIP_REASSEMBLY */
6859+ }
6860+
6861+ /* If we are configured to use ping IP address configuration and
6862+ hasn't been assigned an IP address yet, we accept all ICMP
6863+ packets. */
6864+#if UIP_PINGADDRCONF
6865+ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
6866+ if(BUF->proto == UIP_PROTO_ICMP) {
6867+ UIP_LOG("ip: possible ping config packet received.");
6868+ goto icmp_input;
6869+ } else {
6870+ UIP_LOG("ip: packet dropped since no address assigned.");
6871+ goto drop;
6872+ }
6873+ }
6874+#endif /* UIP_PINGADDRCONF */
6875+
6876+ /* Check if the packet is destined for our IP address. */
6877+ if(BUF->destipaddr[0] != uip_hostaddr[0]) {
6878+ UIP_STAT(++uip_stat.ip.drop);
6879+ UIP_LOG("ip: packet not for us.");
6880+ goto drop;
6881+ }
6882+ if(BUF->destipaddr[1] != uip_hostaddr[1]) {
6883+ UIP_STAT(++uip_stat.ip.drop);
6884+ UIP_LOG("ip: packet not for us.");
6885+ goto drop;
6886+ }
6887+
6888+ if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
6889+ checksum. */
6890+ UIP_STAT(++uip_stat.ip.drop);
6891+ UIP_STAT(++uip_stat.ip.chkerr);
6892+ UIP_LOG("ip: bad checksum.");
6893+ goto drop;
6894+ }
6895+
6896+ if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump
6897+ to the tcp_input label. */
6898+ goto tcp_input;
6899+
6900+#if UIP_UDP
6901+ if(BUF->proto == UIP_PROTO_UDP)
6902+ goto udp_input;
6903+#endif /* UIP_UDP */
6904+
6905+ if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
6906+ here. */
6907+ UIP_STAT(++uip_stat.ip.drop);
6908+ UIP_STAT(++uip_stat.ip.protoerr);
6909+ UIP_LOG("ip: neither tcp nor icmp.");
6910+ goto drop;
6911+ }
6912+
6913+ //icmp_input:
6914+ UIP_STAT(++uip_stat.icmp.recv);
6915+
6916+ /* ICMP echo (i.e., ping) processing. This is simple, we only change
6917+ the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
6918+ checksum before we return the packet. */
6919+ if(ICMPBUF->type != ICMP_ECHO) {
6920+ UIP_STAT(++uip_stat.icmp.drop);
6921+ UIP_STAT(++uip_stat.icmp.typeerr);
6922+ UIP_LOG("icmp: not icmp echo.");
6923+ goto drop;
6924+ }
6925+
6926+ /* If we are configured to use ping IP address assignment, we use
6927+ the destination IP address of this ping packet and assign it to
6928+ ourself. */
6929+#if UIP_PINGADDRCONF
6930+ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
6931+ uip_hostaddr[0] = BUF->destipaddr[0];
6932+ uip_hostaddr[1] = BUF->destipaddr[1];
6933+ }
6934+#endif /* UIP_PINGADDRCONF */
6935+
6936+ ICMPBUF->type = ICMP_ECHO_REPLY;
6937+
6938+ if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
6939+ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
6940+ } else {
6941+ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
6942+ }
6943+
6944+ /* Swap IP addresses. */
6945+ tmp16 = BUF->destipaddr[0];
6946+ BUF->destipaddr[0] = BUF->srcipaddr[0];
6947+ BUF->srcipaddr[0] = tmp16;
6948+ tmp16 = BUF->destipaddr[1];
6949+ BUF->destipaddr[1] = BUF->srcipaddr[1];
6950+ BUF->srcipaddr[1] = tmp16;
6951+
6952+ UIP_STAT(++uip_stat.icmp.sent);
6953+ goto send;
6954+
6955+ /* End of IPv4 input header processing code. */
6956+
6957+
6958+#if UIP_UDP
6959+ /* UDP input processing. */
6960+ udp_input:
6961+ /* UDP processing is really just a hack. We don't do anything to the
6962+ UDP/IP headers, but let the UDP application do all the hard
6963+ work. If the application sets uip_slen, it has a packet to
6964+ send. */
6965+#if UIP_UDP_CHECKSUMS
6966+ if(uip_udpchksum() != 0xffff) {
6967+ UIP_STAT(++uip_stat.udp.drop);
6968+ UIP_STAT(++uip_stat.udp.chkerr);
6969+ UIP_LOG("udp: bad checksum.");
6970+ goto drop;
6971+ }
6972+#endif /* UIP_UDP_CHECKSUMS */
6973+
6974+ /* Demultiplex this UDP packet between the UDP "connections". */
6975+ for(uip_udp_conn = &uip_udp_conns[0];
6976+ uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
6977+ ++uip_udp_conn) {
6978+ if(uip_udp_conn->lport != 0 &&
6979+ UDPBUF->destport == uip_udp_conn->lport &&
6980+ (uip_udp_conn->rport == 0 ||
6981+ UDPBUF->srcport == uip_udp_conn->rport) &&
6982+ BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
6983+ BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
6984+ goto udp_found;
6985+ }
6986+ }
6987+ goto drop;
6988+
6989+ udp_found:
6990+ uip_len = uip_len - 28;
6991+ uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
6992+ uip_flags = UIP_NEWDATA;
6993+ uip_slen = 0;
6994+ UIP_UDP_APPCALL();
6995+ udp_send:
6996+ if(uip_slen == 0) {
6997+ goto drop;
6998+ }
6999+ uip_len = uip_slen + 28;
7000+
7001+ BUF->len[0] = (uip_len >> 8);
7002+ BUF->len[1] = (uip_len & 0xff);
7003+
7004+ BUF->proto = UIP_PROTO_UDP;
7005+
7006+ UDPBUF->udplen = HTONS(uip_slen + 8);
7007+ UDPBUF->udpchksum = 0;
7008+#if UIP_UDP_CHECKSUMS
7009+ /* Calculate UDP checksum. */
7010+ UDPBUF->udpchksum = ~(uip_udpchksum());
7011+ if(UDPBUF->udpchksum == 0) {
7012+ UDPBUF->udpchksum = 0xffff;
7013+ }
7014+#endif /* UIP_UDP_CHECKSUMS */
7015+
7016+ BUF->srcport = uip_udp_conn->lport;
7017+ BUF->destport = uip_udp_conn->rport;
7018+
7019+ BUF->srcipaddr[0] = uip_hostaddr[0];
7020+ BUF->srcipaddr[1] = uip_hostaddr[1];
7021+ BUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
7022+ BUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
7023+
7024+ uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
7025+ goto ip_send_nolen;
7026+#endif /* UIP_UDP */
7027+
7028+ /* TCP input processing. */
7029+ tcp_input:
7030+ UIP_STAT(++uip_stat.tcp.recv);
7031+
7032+ /* Start of TCP input header processing code. */
7033+
7034+ if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
7035+ checksum. */
7036+ UIP_STAT(++uip_stat.tcp.drop);
7037+ UIP_STAT(++uip_stat.tcp.chkerr);
7038+ UIP_LOG("tcp: bad checksum.");
7039+ goto drop;
7040+ }
7041+
7042+ /* Demultiplex this segment. */
7043+ /* First check any active connections. */
7044+ for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) {
7045+ if(uip_connr->tcpstateflags != CLOSED &&
7046+ BUF->destport == uip_connr->lport &&
7047+ BUF->srcport == uip_connr->rport &&
7048+ BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
7049+ BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
7050+ goto found;
7051+ }
7052+ }
7053+
7054+ /* If we didn't find and active connection that expected the packet,
7055+ either this packet is an old duplicate, or this is a SYN packet
7056+ destined for a connection in LISTEN. If the SYN flag isn't set,
7057+ it is an old packet and we send a RST. */
7058+ if((BUF->flags & TCP_CTL) != TCP_SYN)
7059+ goto reset;
7060+
7061+ tmp16 = BUF->destport;
7062+ /* Next, check listening connections. */
7063+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
7064+ if(tmp16 == uip_listenports[c])
7065+ goto found_listen;
7066+ }
7067+
7068+ /* No matching connection found, so we send a RST packet. */
7069+ UIP_STAT(++uip_stat.tcp.synrst);
7070+ reset:
7071+
7072+ /* We do not send resets in response to resets. */
7073+ if(BUF->flags & TCP_RST)
7074+ goto drop;
7075+
7076+ UIP_STAT(++uip_stat.tcp.rst);
7077+
7078+ BUF->flags = TCP_RST | TCP_ACK;
7079+ uip_len = 40;
7080+ BUF->tcpoffset = 5 << 4;
7081+
7082+ /* Flip the seqno and ackno fields in the TCP header. */
7083+ c = BUF->seqno[3];
7084+ BUF->seqno[3] = BUF->ackno[3];
7085+ BUF->ackno[3] = c;
7086+
7087+ c = BUF->seqno[2];
7088+ BUF->seqno[2] = BUF->ackno[2];
7089+ BUF->ackno[2] = c;
7090+
7091+ c = BUF->seqno[1];
7092+ BUF->seqno[1] = BUF->ackno[1];
7093+ BUF->ackno[1] = c;
7094+
7095+ c = BUF->seqno[0];
7096+ BUF->seqno[0] = BUF->ackno[0];
7097+ BUF->ackno[0] = c;
7098+
7099+ /* We also have to increase the sequence number we are
7100+ acknowledging. If the least significant byte overflowed, we need
7101+ to propagate the carry to the other bytes as well. */
7102+ if(++BUF->ackno[3] == 0) {
7103+ if(++BUF->ackno[2] == 0) {
7104+ if(++BUF->ackno[1] == 0) {
7105+ ++BUF->ackno[0];
7106+ }
7107+ }
7108+ }
7109+
7110+ /* Swap port numbers. */
7111+ tmp16 = BUF->srcport;
7112+ BUF->srcport = BUF->destport;
7113+ BUF->destport = tmp16;
7114+
7115+ /* Swap IP addresses. */
7116+ tmp16 = BUF->destipaddr[0];
7117+ BUF->destipaddr[0] = BUF->srcipaddr[0];
7118+ BUF->srcipaddr[0] = tmp16;
7119+ tmp16 = BUF->destipaddr[1];
7120+ BUF->destipaddr[1] = BUF->srcipaddr[1];
7121+ BUF->srcipaddr[1] = tmp16;
7122+
7123+
7124+ /* And send out the RST packet! */
7125+ goto tcp_send_noconn;
7126+
7127+ /* This label will be jumped to if we matched the incoming packet
7128+ with a connection in LISTEN. In that case, we should create a new
7129+ connection and send a SYNACK in return. */
7130+ found_listen:
7131+ /* First we check if there are any connections avaliable. Unused
7132+ connections are kept in the same table as used connections, but
7133+ unused ones have the tcpstate set to CLOSED. Also, connections in
7134+ TIME_WAIT are kept track of and we'll use the oldest one if no
7135+ CLOSED connections are found. Thanks to Eddie C. Dost for a very
7136+ nice algorithm for the TIME_WAIT search. */
7137+ uip_connr = 0;
7138+ for(c = 0; c < UIP_CONNS; ++c) {
7139+ if(uip_conns[c].tcpstateflags == CLOSED) {
7140+ uip_connr = &uip_conns[c];
7141+ break;
7142+ }
7143+ if(uip_conns[c].tcpstateflags == TIME_WAIT) {
7144+ if(uip_connr == 0 ||
7145+ uip_conns[c].timer > uip_connr->timer) {
7146+ uip_connr = &uip_conns[c];
7147+ }
7148+ }
7149+ }
7150+
7151+ if(uip_connr == 0) {
7152+ /* All connections are used already, we drop packet and hope that
7153+ the remote end will retransmit the packet at a time when we
7154+ have more spare connections. */
7155+ UIP_STAT(++uip_stat.tcp.syndrop);
7156+ UIP_LOG("tcp: found no unused connections.");
7157+ goto drop;
7158+ }
7159+ uip_conn = uip_connr;
7160+
7161+ /* Fill in the necessary fields for the new connection. */
7162+ uip_connr->rto = uip_connr->timer = UIP_RTO;
7163+ uip_connr->sa = 0;
7164+ uip_connr->sv = 4;
7165+ uip_connr->nrtx = 0;
7166+ uip_connr->lport = BUF->destport;
7167+ uip_connr->rport = BUF->srcport;
7168+ uip_connr->ripaddr[0] = BUF->srcipaddr[0];
7169+ uip_connr->ripaddr[1] = BUF->srcipaddr[1];
7170+ uip_connr->tcpstateflags = SYN_RCVD;
7171+
7172+ uip_connr->snd_nxt[0] = iss[0];
7173+ uip_connr->snd_nxt[1] = iss[1];
7174+ uip_connr->snd_nxt[2] = iss[2];
7175+ uip_connr->snd_nxt[3] = iss[3];
7176+ uip_connr->len = 1;
7177+
7178+ /* rcv_nxt should be the seqno from the incoming packet + 1. */
7179+ uip_connr->rcv_nxt[3] = BUF->seqno[3];
7180+ uip_connr->rcv_nxt[2] = BUF->seqno[2];
7181+ uip_connr->rcv_nxt[1] = BUF->seqno[1];
7182+ uip_connr->rcv_nxt[0] = BUF->seqno[0];
7183+ uip_add_rcv_nxt(1);
7184+
7185+ /* Parse the TCP MSS option, if present. */
7186+ if((BUF->tcpoffset & 0xf0) > 0x50) {
7187+ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
7188+ opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
7189+ if(opt == 0x00) {
7190+ /* End of options. */
7191+ break;
7192+ } else if(opt == 0x01) {
7193+ ++c;
7194+ /* NOP option. */
7195+ } else if(opt == 0x02 &&
7196+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
7197+ /* An MSS option with the right option length. */
7198+ tmp16 = ((unsigned short int)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
7199+ (unsigned short int)uip_buf[40 + UIP_LLH_LEN + 3 + c];
7200+ uip_connr->initialmss = uip_connr->mss =
7201+ tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
7202+
7203+ /* And we are done processing options. */
7204+ break;
7205+ } else {
7206+ /* All other options have a length field, so that we easily
7207+ can skip past them. */
7208+ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
7209+ /* If the length field is zero, the options are malformed
7210+ and we don't process them further. */
7211+ break;
7212+ }
7213+ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
7214+ }
7215+ }
7216+ }
7217+
7218+ /* Our response will be a SYNACK. */
7219+#if UIP_ACTIVE_OPEN
7220+ tcp_send_synack:
7221+ BUF->flags = TCP_ACK;
7222+
7223+ tcp_send_syn:
7224+ BUF->flags |= TCP_SYN;
7225+#else /* UIP_ACTIVE_OPEN */
7226+ tcp_send_synack:
7227+ BUF->flags = TCP_SYN | TCP_ACK;
7228+#endif /* UIP_ACTIVE_OPEN */
7229+
7230+ /* We send out the TCP Maximum Segment Size option with our
7231+ SYNACK. */
7232+ BUF->optdata[0] = 2;
7233+ BUF->optdata[1] = 4;
7234+ BUF->optdata[2] = (UIP_TCP_MSS) / 256;
7235+ BUF->optdata[3] = (UIP_TCP_MSS) & 255;
7236+ uip_len = 44;
7237+ BUF->tcpoffset = 6 << 4;
7238+ goto tcp_send;
7239+
7240+ /* This label will be jumped to if we found an active connection. */
7241+ found:
7242+ uip_conn = uip_connr;
7243+ uip_flags = 0;
7244+
7245+ /* We do a very naive form of TCP reset processing; we just accept
7246+ any RST and kill our connection. We should in fact check if the
7247+ sequence number of this reset is wihtin our advertised window
7248+ before we accept the reset. */
7249+ if(BUF->flags & TCP_RST) {
7250+ uip_connr->tcpstateflags = CLOSED;
7251+ UIP_LOG("tcp: got reset, aborting connection.");
7252+ uip_flags = UIP_ABORT;
7253+ UIP_APPCALL();
7254+ goto drop;
7255+ }
7256+ /* Calculated the length of the data, if the application has sent
7257+ any data to us. */
7258+ c = (BUF->tcpoffset >> 4) << 2;
7259+ /* uip_len will contain the length of the actual TCP data. This is
7260+ calculated by subtracing the length of the TCP header (in
7261+ c) and the length of the IP header (20 bytes). */
7262+ uip_len = uip_len - c - 20;
7263+
7264+ /* First, check if the sequence number of the incoming packet is
7265+ what we're expecting next. If not, we send out an ACK with the
7266+ correct numbers in. */
7267+ if(uip_len > 0 &&
7268+ (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
7269+ BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
7270+ BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
7271+ BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
7272+ goto tcp_send_ack;
7273+ }
7274+
7275+ /* Next, check if the incoming segment acknowledges any outstanding
7276+ data. If so, we update the sequence number, reset the length of
7277+ the outstanding data, calculate RTT estimations, and reset the
7278+ retransmission timer. */
7279+ if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
7280+ uip_add32(uip_connr->snd_nxt, uip_connr->len);
7281+ if(BUF->ackno[0] == uip_acc32[0] &&
7282+ BUF->ackno[1] == uip_acc32[1] &&
7283+ BUF->ackno[2] == uip_acc32[2] &&
7284+ BUF->ackno[3] == uip_acc32[3]) {
7285+ /* Update sequence number. */
7286+ uip_connr->snd_nxt[0] = uip_acc32[0];
7287+ uip_connr->snd_nxt[1] = uip_acc32[1];
7288+ uip_connr->snd_nxt[2] = uip_acc32[2];
7289+ uip_connr->snd_nxt[3] = uip_acc32[3];
7290+
7291+
7292+ /* Do RTT estimation, unless we have done retransmissions. */
7293+ if(uip_connr->nrtx == 0) {
7294+ signed char m;
7295+ m = uip_connr->rto - uip_connr->timer;
7296+ /* This is taken directly from VJs original code in his paper */
7297+ m = m - (uip_connr->sa >> 3);
7298+ uip_connr->sa += m;
7299+ if(m < 0) {
7300+ m = -m;
7301+ }
7302+ m = m - (uip_connr->sv >> 2);
7303+ uip_connr->sv += m;
7304+ uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
7305+
7306+ }
7307+ /* Set the acknowledged flag. */
7308+ uip_flags = UIP_ACKDATA;
7309+ /* Reset the retransmission timer. */
7310+ uip_connr->timer = uip_connr->rto;
7311+ }
7312+
7313+ }
7314+
7315+ /* Do different things depending on in what state the connection is. */
7316+ switch(uip_connr->tcpstateflags & TS_MASK) {
7317+ /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
7318+ implemented, since we force the application to close when the
7319+ peer sends a FIN (hence the application goes directly from
7320+ ESTABLISHED to LAST_ACK). */
7321+ case SYN_RCVD:
7322+ /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
7323+ we are waiting for an ACK that acknowledges the data we sent
7324+ out the last time. Therefore, we want to have the UIP_ACKDATA
7325+ flag set. If so, we enter the ESTABLISHED state. */
7326+ if(uip_flags & UIP_ACKDATA) {
7327+ uip_connr->tcpstateflags = ESTABLISHED;
7328+ uip_flags = UIP_CONNECTED;
7329+ uip_connr->len = 0;
7330+ if(uip_len > 0) {
7331+ uip_flags |= UIP_NEWDATA;
7332+ uip_add_rcv_nxt(uip_len);
7333+ }
7334+ uip_slen = 0;
7335+ UIP_APPCALL();
7336+ goto appsend;
7337+ }
7338+ goto drop;
7339+#if UIP_ACTIVE_OPEN
7340+ case SYN_SENT:
7341+ /* In SYN_SENT, we wait for a SYNACK that is sent in response to
7342+ our SYN. The rcv_nxt is set to sequence number in the SYNACK
7343+ plus one, and we send an ACK. We move into the ESTABLISHED
7344+ state. */
7345+ if((uip_flags & UIP_ACKDATA) &&
7346+ BUF->flags == (TCP_SYN | TCP_ACK)) {
7347+
7348+ /* Parse the TCP MSS option, if present. */
7349+ if((BUF->tcpoffset & 0xf0) > 0x50) {
7350+ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
7351+ opt = uip_buf[40 + UIP_LLH_LEN + c];
7352+ if(opt == 0x00) {
7353+ /* End of options. */
7354+ break;
7355+ } else if(opt == 0x01) {
7356+ ++c;
7357+ /* NOP option. */
7358+ } else if(opt == 0x02 &&
7359+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
7360+ /* An MSS option with the right option length. */
7361+ tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
7362+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
7363+ uip_connr->initialmss =
7364+ uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
7365+
7366+ /* And we are done processing options. */
7367+ break;
7368+ } else {
7369+ /* All other options have a length field, so that we easily
7370+ can skip past them. */
7371+ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
7372+ /* If the length field is zero, the options are malformed
7373+ and we don't process them further. */
7374+ break;
7375+ }
7376+ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
7377+ }
7378+ }
7379+ }
7380+ uip_connr->tcpstateflags = ESTABLISHED;
7381+ uip_connr->rcv_nxt[0] = BUF->seqno[0];
7382+ uip_connr->rcv_nxt[1] = BUF->seqno[1];
7383+ uip_connr->rcv_nxt[2] = BUF->seqno[2];
7384+ uip_connr->rcv_nxt[3] = BUF->seqno[3];
7385+ uip_add_rcv_nxt(1);
7386+ uip_flags = UIP_CONNECTED | UIP_NEWDATA;
7387+ uip_connr->len = 0;
7388+ uip_len = 0;
7389+ uip_slen = 0;
7390+ UIP_APPCALL();
7391+ goto appsend;
7392+ }
7393+ goto reset;
7394+#endif /* UIP_ACTIVE_OPEN */
7395+
7396+ case ESTABLISHED:
7397+ /* In the ESTABLISHED state, we call upon the application to feed
7398+ data into the uip_buf. If the UIP_ACKDATA flag is set, the
7399+ application should put new data into the buffer, otherwise we are
7400+ retransmitting an old segment, and the application should put that
7401+ data into the buffer.
7402+
7403+ If the incoming packet is a FIN, we should close the connection on
7404+ this side as well, and we send out a FIN and enter the LAST_ACK
7405+ state. We require that there is no outstanding data; otherwise the
7406+ sequence numbers will be screwed up. */
7407+
7408+ if(BUF->flags & TCP_FIN) {
7409+ if(uip_outstanding(uip_connr)) {
7410+ goto drop;
7411+ }
7412+ uip_add_rcv_nxt(1 + uip_len);
7413+ uip_flags = UIP_CLOSE;
7414+ if(uip_len > 0) {
7415+ uip_flags |= UIP_NEWDATA;
7416+ }
7417+ UIP_APPCALL();
7418+ uip_connr->len = 1;
7419+ uip_connr->tcpstateflags = LAST_ACK;
7420+ uip_connr->nrtx = 0;
7421+ tcp_send_finack:
7422+ BUF->flags = TCP_FIN | TCP_ACK;
7423+ goto tcp_send_nodata;
7424+ }
7425+
7426+ /* Check the URG flag. If this is set, the segment carries urgent
7427+ data that we must pass to the application. */
7428+ if(BUF->flags & TCP_URG) {
7429+#if UIP_URGDATA > 0
7430+ uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
7431+ if(uip_urglen > uip_len) {
7432+ /* There is more urgent data in the next segment to come. */
7433+ uip_urglen = uip_len;
7434+ }
7435+ uip_add_rcv_nxt(uip_urglen);
7436+ uip_len -= uip_urglen;
7437+ uip_urgdata = uip_appdata;
7438+ uip_appdata += uip_urglen;
7439+ } else {
7440+ uip_urglen = 0;
7441+#endif /* UIP_URGDATA > 0 */
7442+ uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
7443+ uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
7444+ }
7445+
7446+
7447+ /* If uip_len > 0 we have TCP data in the packet, and we flag this
7448+ by setting the UIP_NEWDATA flag and update the sequence number
7449+ we acknowledge. If the application has stopped the dataflow
7450+ using uip_stop(), we must not accept any data packets from the
7451+ remote host. */
7452+ if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
7453+ uip_flags |= UIP_NEWDATA;
7454+ uip_add_rcv_nxt(uip_len);
7455+ }
7456+
7457+ /* Check if the available buffer space advertised by the other end
7458+ is smaller than the initial MSS for this connection. If so, we
7459+ set the current MSS to the window size to ensure that the
7460+ application does not send more data than the other end can
7461+ handle.
7462+
7463+ If the remote host advertises a zero window, we set the MSS to
7464+ the initial MSS so that the application will send an entire MSS
7465+ of data. This data will not be acknowledged by the receiver,
7466+ and the application will retransmit it. This is called the
7467+ "persistent timer" and uses the retransmission mechanim.
7468+ */
7469+ tmp16 = ((unsigned short int)BUF->wnd[0] << 8) + (unsigned short int)BUF->wnd[1];
7470+ if(tmp16 > uip_connr->initialmss ||
7471+ tmp16 == 0) {
7472+ tmp16 = uip_connr->initialmss;
7473+ }
7474+ uip_connr->mss = tmp16;
7475+
7476+ /* If this packet constitutes an ACK for outstanding data (flagged
7477+ by the UIP_ACKDATA flag, we should call the application since it
7478+ might want to send more data. If the incoming packet had data
7479+ from the peer (as flagged by the UIP_NEWDATA flag), the
7480+ application must also be notified.
7481+
7482+ When the application is called, the global variable uip_len
7483+ contains the length of the incoming data. The application can
7484+ access the incoming data through the global pointer
7485+ uip_appdata, which usually points 40 bytes into the uip_buf
7486+ array.
7487+
7488+ If the application wishes to send any data, this data should be
7489+ put into the uip_appdata and the length of the data should be
7490+ put into uip_len. If the application don't have any data to
7491+ send, uip_len must be set to 0. */
7492+ if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
7493+ uip_slen = 0;
7494+ UIP_APPCALL();
7495+
7496+ appsend:
7497+
7498+ if(uip_flags & UIP_ABORT) {
7499+ uip_slen = 0;
7500+ uip_connr->tcpstateflags = CLOSED;
7501+ BUF->flags = TCP_RST | TCP_ACK;
7502+ goto tcp_send_nodata;
7503+ }
7504+
7505+ if(uip_flags & UIP_CLOSE) {
7506+ uip_slen = 0;
7507+ uip_connr->len = 1;
7508+ uip_connr->tcpstateflags = FIN_WAIT_1;
7509+ uip_connr->nrtx = 0;
7510+ BUF->flags = TCP_FIN | TCP_ACK;
7511+ goto tcp_send_nodata;
7512+ }
7513+
7514+ /* If uip_slen > 0, the application has data to be sent. */
7515+ if(uip_slen > 0) {
7516+
7517+ /* If the connection has acknowledged data, the contents of
7518+ the ->len variable should be discarded. */
7519+ if((uip_flags & UIP_ACKDATA) != 0) {
7520+ uip_connr->len = 0;
7521+ }
7522+
7523+ /* If the ->len variable is non-zero the connection has
7524+ already data in transit and cannot send anymore right
7525+ now. */
7526+ if(uip_connr->len == 0) {
7527+
7528+ /* The application cannot send more than what is allowed by
7529+ the mss (the minumum of the MSS and the available
7530+ window). */
7531+ if(uip_slen > uip_connr->mss) {
7532+ uip_slen = uip_connr->mss;
7533+ }
7534+
7535+ /* Remember how much data we send out now so that we know
7536+ when everything has been acknowledged. */
7537+ uip_connr->len = uip_slen;
7538+ } else {
7539+
7540+ /* If the application already had unacknowledged data, we
7541+ make sure that the application does not send (i.e.,
7542+ retransmit) out more than it previously sent out. */
7543+ uip_slen = uip_connr->len;
7544+ }
7545+ } else {
7546+ uip_connr->len = 0;
7547+ }
7548+ uip_connr->nrtx = 0;
7549+ apprexmit:
7550+ uip_appdata = uip_sappdata;
7551+
7552+ /* If the application has data to be sent, or if the incoming
7553+ packet had new data in it, we must send out a packet. */
7554+ if(uip_slen > 0 && uip_connr->len > 0) {
7555+ /* Add the length of the IP and TCP headers. */
7556+ uip_len = uip_connr->len + UIP_TCPIP_HLEN;
7557+ /* We always set the ACK flag in response packets. */
7558+ BUF->flags = TCP_ACK | TCP_PSH;
7559+ /* Send the packet. */
7560+ goto tcp_send_noopts;
7561+ }
7562+ /* If there is no data to send, just send out a pure ACK if
7563+ there is newdata. */
7564+ if(uip_flags & UIP_NEWDATA) {
7565+ uip_len = UIP_TCPIP_HLEN;
7566+ BUF->flags = TCP_ACK;
7567+ goto tcp_send_noopts;
7568+ }
7569+ }
7570+ goto drop;
7571+ case LAST_ACK:
7572+ /* We can close this connection if the peer has acknowledged our
7573+ FIN. This is indicated by the UIP_ACKDATA flag. */
7574+ if(uip_flags & UIP_ACKDATA) {
7575+ uip_connr->tcpstateflags = CLOSED;
7576+ uip_flags = UIP_CLOSE;
7577+ UIP_APPCALL();
7578+ }
7579+ break;
7580+
7581+ case FIN_WAIT_1:
7582+ /* The application has closed the connection, but the remote host
7583+ hasn't closed its end yet. Thus we do nothing but wait for a
7584+ FIN from the other side. */
7585+ if(uip_len > 0) {
7586+ uip_add_rcv_nxt(uip_len);
7587+ }
7588+ if(BUF->flags & TCP_FIN) {
7589+ if(uip_flags & UIP_ACKDATA) {
7590+ uip_connr->tcpstateflags = TIME_WAIT;
7591+ uip_connr->timer = 0;
7592+ uip_connr->len = 0;
7593+ } else {
7594+ uip_connr->tcpstateflags = CLOSING;
7595+ }
7596+ uip_add_rcv_nxt(1);
7597+ uip_flags = UIP_CLOSE;
7598+ UIP_APPCALL();
7599+ goto tcp_send_ack;
7600+ } else if(uip_flags & UIP_ACKDATA) {
7601+ uip_connr->tcpstateflags = FIN_WAIT_2;
7602+ uip_connr->len = 0;
7603+ goto drop;
7604+ }
7605+ if(uip_len > 0) {
7606+ goto tcp_send_ack;
7607+ }
7608+ goto drop;
7609+
7610+ case FIN_WAIT_2:
7611+ if(uip_len > 0) {
7612+ uip_add_rcv_nxt(uip_len);
7613+ }
7614+ if(BUF->flags & TCP_FIN) {
7615+ uip_connr->tcpstateflags = TIME_WAIT;
7616+ uip_connr->timer = 0;
7617+ uip_add_rcv_nxt(1);
7618+ uip_flags = UIP_CLOSE;
7619+ UIP_APPCALL();
7620+ goto tcp_send_ack;
7621+ }
7622+ if(uip_len > 0) {
7623+ goto tcp_send_ack;
7624+ }
7625+ goto drop;
7626+
7627+ case TIME_WAIT:
7628+ goto tcp_send_ack;
7629+
7630+ case CLOSING:
7631+ if(uip_flags & UIP_ACKDATA) {
7632+ uip_connr->tcpstateflags = TIME_WAIT;
7633+ uip_connr->timer = 0;
7634+ }
7635+ }
7636+ goto drop;
7637+
7638+
7639+ /* We jump here when we are ready to send the packet, and just want
7640+ to set the appropriate TCP sequence numbers in the TCP header. */
7641+ tcp_send_ack:
7642+ BUF->flags = TCP_ACK;
7643+ tcp_send_nodata:
7644+ uip_len = 40;
7645+ tcp_send_noopts:
7646+ BUF->tcpoffset = 5 << 4;
7647+ tcp_send:
7648+ /* We're done with the input processing. We are now ready to send a
7649+ reply. Our job is to fill in all the fields of the TCP and IP
7650+ headers before calculating the checksum and finally send the
7651+ packet. */
7652+ BUF->ackno[0] = uip_connr->rcv_nxt[0];
7653+ BUF->ackno[1] = uip_connr->rcv_nxt[1];
7654+ BUF->ackno[2] = uip_connr->rcv_nxt[2];
7655+ BUF->ackno[3] = uip_connr->rcv_nxt[3];
7656+
7657+ BUF->seqno[0] = uip_connr->snd_nxt[0];
7658+ BUF->seqno[1] = uip_connr->snd_nxt[1];
7659+ BUF->seqno[2] = uip_connr->snd_nxt[2];
7660+ BUF->seqno[3] = uip_connr->snd_nxt[3];
7661+
7662+ BUF->proto = UIP_PROTO_TCP;
7663+
7664+ BUF->srcport = uip_connr->lport;
7665+ BUF->destport = uip_connr->rport;
7666+
7667+ BUF->srcipaddr[0] = uip_hostaddr[0];
7668+ BUF->srcipaddr[1] = uip_hostaddr[1];
7669+ BUF->destipaddr[0] = uip_connr->ripaddr[0];
7670+ BUF->destipaddr[1] = uip_connr->ripaddr[1];
7671+
7672+
7673+ if(uip_connr->tcpstateflags & UIP_STOPPED) {
7674+ /* If the connection has issued uip_stop(), we advertise a zero
7675+ window so that the remote host will stop sending data. */
7676+ BUF->wnd[0] = BUF->wnd[1] = 0;
7677+ } else {
7678+ BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
7679+ BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
7680+ }
7681+
7682+ tcp_send_noconn:
7683+
7684+ BUF->len[0] = (uip_len >> 8);
7685+ BUF->len[1] = (uip_len & 0xff);
7686+
7687+ /* Calculate TCP checksum. */
7688+ BUF->tcpchksum = 0;
7689+ BUF->tcpchksum = ~(uip_tcpchksum());
7690+
7691+ //ip_send_nolen:
7692+
7693+ BUF->vhl = 0x45;
7694+ BUF->tos = 0;
7695+ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
7696+ BUF->ttl = UIP_TTL;
7697+ ++ipid;
7698+ BUF->ipid[0] = ipid >> 8;
7699+ BUF->ipid[1] = ipid & 0xff;
7700+
7701+ /* Calculate IP checksum. */
7702+ BUF->ipchksum = 0;
7703+ BUF->ipchksum = ~(uip_ipchksum());
7704+
7705+ UIP_STAT(++uip_stat.tcp.sent);
7706+ send:
7707+ UIP_STAT(++uip_stat.ip.sent);
7708+ /* Return and let the caller do the actual transmission. */
7709+ return;
7710+ drop:
7711+ uip_len = 0;
7712+ return;
7713+}
7714+/*-----------------------------------------------------------------------------------*/
7715+/*unsigned short int
7716+htons(unsigned short int val)
7717+{
7718+ return HTONS(val);
7719+}*/
7720+/*-----------------------------------------------------------------------------------*/
7721+/** @} */
7722--- /dev/null
7723+++ b/net/uip-0.9/uip.h
7724@@ -0,0 +1,1066 @@
7725+/**
7726+ * \addtogroup uip
7727+ * @{
7728+ */
7729+
7730+/**
7731+ * \file
7732+ * Header file for the uIP TCP/IP stack.
7733+ * \author Adam Dunkels <adam@dunkels.com>
7734+ *
7735+ * The uIP TCP/IP stack header file contains definitions for a number
7736+ * of C macros that are used by uIP programs as well as internal uIP
7737+ * structures, TCP/IP header structures and function declarations.
7738+ *
7739+ */
7740+
7741+
7742+/*
7743+ * Copyright (c) 2001-2003, Adam Dunkels.
7744+ * All rights reserved.
7745+ *
7746+ * Redistribution and use in source and binary forms, with or without
7747+ * modification, are permitted provided that the following conditions
7748+ * are met:
7749+ * 1. Redistributions of source code must retain the above copyright
7750+ * notice, this list of conditions and the following disclaimer.
7751+ * 2. Redistributions in binary form must reproduce the above copyright
7752+ * notice, this list of conditions and the following disclaimer in the
7753+ * documentation and/or other materials provided with the distribution.
7754+ * 3. The name of the author may not be used to endorse or promote
7755+ * products derived from this software without specific prior
7756+ * written permission.
7757+ *
7758+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
7759+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7760+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7761+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
7762+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7763+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
7764+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
7765+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
7766+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
7767+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7768+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7769+ *
7770+ * This file is part of the uIP TCP/IP stack.
7771+ *
7772+ * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $
7773+ *
7774+ */
7775+
7776+#ifndef __UIP_H__
7777+#define __UIP_H__
7778+#include <linux/types.h>
7779+#include <linux/string.h>
7780+#include <linux/ctype.h>
7781+#include <malloc.h>
7782+#include <common.h>
7783+
7784+
7785+#include "uipopt.h"
7786+
7787+/*-----------------------------------------------------------------------------------*/
7788+/* First, the functions that should be called from the
7789+ * system. Initialization, the periodic timer and incoming packets are
7790+ * handled by the following three functions.
7791+ */
7792+
7793+/**
7794+ * \defgroup uipconffunc uIP configuration functions
7795+ * @{
7796+ *
7797+ * The uIP configuration functions are used for setting run-time
7798+ * parameters in uIP such as IP addresses.
7799+ */
7800+
7801+/**
7802+ * Set the IP address of this host.
7803+ *
7804+ * The IP address is represented as a 4-byte array where the first
7805+ * octet of the IP address is put in the first member of the 4-byte
7806+ * array.
7807+ *
7808+ * \param addr A pointer to a 4-byte representation of the IP address.
7809+ *
7810+ * \hideinitializer
7811+ */
7812+#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \
7813+ uip_hostaddr[1] = addr[1]; } while(0)
7814+
7815+/**
7816+ * Get the IP address of this host.
7817+ *
7818+ * The IP address is represented as a 4-byte array where the first
7819+ * octet of the IP address is put in the first member of the 4-byte
7820+ * array.
7821+ *
7822+ * \param addr A pointer to a 4-byte array that will be filled in with
7823+ * the currently configured IP address.
7824+ *
7825+ * \hideinitializer
7826+ */
7827+#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \
7828+ addr[1] = uip_hostaddr[1]; } while(0)
7829+
7830+/** @} */
7831+
7832+/**
7833+ * \defgroup uipinit uIP initialization functions
7834+ * @{
7835+ *
7836+ * The uIP initialization functions are used for booting uIP.
7837+ */
7838+
7839+/**
7840+ * uIP initialization function.
7841+ *
7842+ * This function should be called at boot up to initilize the uIP
7843+ * TCP/IP stack.
7844+ */
7845+void uip_init(void);
7846+
7847+/** @} */
7848+
7849+/**
7850+ * \defgroup uipdevfunc uIP device driver functions
7851+ * @{
7852+ *
7853+ * These functions are used by a network device driver for interacting
7854+ * with uIP.
7855+ */
7856+
7857+/**
7858+ * Process an incoming packet.
7859+ *
7860+ * This function should be called when the device driver has received
7861+ * a packet from the network. The packet from the device driver must
7862+ * be present in the uip_buf buffer, and the length of the packet
7863+ * should be placed in the uip_len variable.
7864+ *
7865+ * When the function returns, there may be an outbound packet placed
7866+ * in the uip_buf packet buffer. If so, the uip_len variable is set to
7867+ * the length of the packet. If no packet is to be sent out, the
7868+ * uip_len variable is set to 0.
7869+ *
7870+ * The usual way of calling the function is presented by the source
7871+ * code below.
7872+ \code
7873+ uip_len = devicedriver_poll();
7874+ if(uip_len > 0) {
7875+ uip_input();
7876+ if(uip_len > 0) {
7877+ devicedriver_send();
7878+ }
7879+ }
7880+ \endcode
7881+ *
7882+ * \note If you are writing a uIP device driver that needs ARP
7883+ * (Address Resolution Protocol), e.g., when running uIP over
7884+ * Ethernet, you will need to call the uIP ARP code before calling
7885+ * this function:
7886+ \code
7887+ #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
7888+ uip_len = ethernet_devicedrver_poll();
7889+ if(uip_len > 0) {
7890+ if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
7891+ uip_arp_ipin();
7892+ uip_input();
7893+ if(uip_len > 0) {
7894+ uip_arp_out();
7895+ ethernet_devicedriver_send();
7896+ }
7897+ } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
7898+ uip_arp_arpin();
7899+ if(uip_len > 0) {
7900+ ethernet_devicedriver_send();
7901+ }
7902+ }
7903+ \endcode
7904+ *
7905+ * \hideinitializer
7906+ */
7907+#define uip_input() uip_process(UIP_DATA)
7908+
7909+/**
7910+ * Periodic processing for a connection identified by its number.
7911+ *
7912+ * This function does the necessary periodic processing (timers,
7913+ * polling) for a uIP TCP conneciton, and should be called when the
7914+ * periodic uIP timer goes off. It should be called for every
7915+ * connection, regardless of whether they are open of closed.
7916+ *
7917+ * When the function returns, it may have an outbound packet waiting
7918+ * for service in the uIP packet buffer, and if so the uip_len
7919+ * variable is set to a value larger than zero. The device driver
7920+ * should be called to send out the packet.
7921+ *
7922+ * The ususal way of calling the function is through a for() loop like
7923+ * this:
7924+ \code
7925+ for(i = 0; i < UIP_CONNS; ++i) {
7926+ uip_periodic(i);
7927+ if(uip_len > 0) {
7928+ devicedriver_send();
7929+ }
7930+ }
7931+ \endcode
7932+ *
7933+ * \note If you are writing a uIP device driver that needs ARP
7934+ * (Address Resolution Protocol), e.g., when running uIP over
7935+ * Ethernet, you will need to call the uip_arp_out() function before
7936+ * calling the device driver:
7937+ \code
7938+ for(i = 0; i < UIP_CONNS; ++i) {
7939+ uip_periodic(i);
7940+ if(uip_len > 0) {
7941+ uip_arp_out();
7942+ ethernet_devicedriver_send();
7943+ }
7944+ }
7945+ \endcode
7946+ *
7947+ * \param conn The number of the connection which is to be periodically polled.
7948+ *
7949+ * \hideinitializer
7950+ */
7951+#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
7952+ uip_process(UIP_TIMER); } while (0)
7953+
7954+/**
7955+ * Periodic processing for a connection identified by a pointer to its structure.
7956+ *
7957+ * Same as uip_periodic() but takes a pointer to the actual uip_conn
7958+ * struct instead of an integer as its argument. This function can be
7959+ * used to force periodic processing of a specific connection.
7960+ *
7961+ * \param conn A pointer to the uip_conn struct for the connection to
7962+ * be processed.
7963+ *
7964+ * \hideinitializer
7965+ */
7966+#define uip_periodic_conn(conn) do { uip_conn = conn; \
7967+ uip_process(UIP_TIMER); } while (0)
7968+
7969+#if UIP_UDP
7970+/**
7971+ * Periodic processing for a UDP connection identified by its number.
7972+ *
7973+ * This function is essentially the same as uip_prerioic(), but for
7974+ * UDP connections. It is called in a similar fashion as the
7975+ * uip_periodic() function:
7976+ \code
7977+ for(i = 0; i < UIP_UDP_CONNS; i++) {
7978+ uip_udp_periodic(i);
7979+ if(uip_len > 0) {
7980+ devicedriver_send();
7981+ }
7982+ }
7983+ \endcode
7984+ *
7985+ * \note As for the uip_periodic() function, special care has to be
7986+ * taken when using uIP together with ARP and Ethernet:
7987+ \code
7988+ for(i = 0; i < UIP_UDP_CONNS; i++) {
7989+ uip_udp_periodic(i);
7990+ if(uip_len > 0) {
7991+ uip_arp_out();
7992+ ethernet_devicedriver_send();
7993+ }
7994+ }
7995+ \endcode
7996+ *
7997+ * \param conn The number of the UDP connection to be processed.
7998+ *
7999+ * \hideinitializer
8000+ */
8001+#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
8002+ uip_process(UIP_UDP_TIMER); } while (0)
8003+
8004+/**
8005+ * Periodic processing for a UDP connection identified by a pointer to
8006+ * its structure.
8007+ *
8008+ * Same as uip_udp_periodic() but takes a pointer to the actual
8009+ * uip_conn struct instead of an integer as its argument. This
8010+ * function can be used to force periodic processing of a specific
8011+ * connection.
8012+ *
8013+ * \param conn A pointer to the uip_udp_conn struct for the connection
8014+ * to be processed.
8015+ *
8016+ * \hideinitializer
8017+ */
8018+#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
8019+ uip_process(UIP_UDP_TIMER); } while (0)
8020+
8021+
8022+#endif /* UIP_UDP */
8023+
8024+/**
8025+ * The uIP packet buffer.
8026+ *
8027+ * The uip_buf array is used to hold incoming and outgoing
8028+ * packets. The device driver should place incoming data into this
8029+ * buffer. When sending data, the device driver should read the link
8030+ * level headers and the TCP/IP headers from this buffer. The size of
8031+ * the link level headers is configured by the UIP_LLH_LEN define.
8032+ *
8033+ * \note The application data need not be placed in this buffer, so
8034+ * the device driver must read it from the place pointed to by the
8035+ * uip_appdata pointer as illustrated by the following example:
8036+ \code
8037+ void
8038+ devicedriver_send(void)
8039+ {
8040+ hwsend(&uip_buf[0], UIP_LLH_LEN);
8041+ hwsend(&uip_buf[UIP_LLH_LEN], 40);
8042+ hwsend(uip_appdata, uip_len - 40 - UIP_LLH_LEN);
8043+ }
8044+ \endcode
8045+ */
8046+extern u8_t uip_buf[UIP_BUFSIZE+2];
8047+
8048+/** @} */
8049+
8050+/*-----------------------------------------------------------------------------------*/
8051+/* Functions that are used by the uIP application program. Opening and
8052+ * closing connections, sending and receiving data, etc. is all
8053+ * handled by the functions below.
8054+*/
8055+/**
8056+ * \defgroup uipappfunc uIP application functions
8057+ * @{
8058+ *
8059+ * Functions used by an application running of top of uIP.
8060+ */
8061+
8062+/**
8063+ * Start listening to the specified port.
8064+ *
8065+ * \note Since this function expects the port number in network byte
8066+ * order, a conversion using HTONS() or htons() is necessary.
8067+ *
8068+ \code
8069+ uip_listen(HTONS(80));
8070+ \endcode
8071+ *
8072+ * \param port A 16-bit port number in network byte order.
8073+ */
8074+void uip_listen(u16_t port);
8075+
8076+/**
8077+ * Stop listening to the specified port.
8078+ *
8079+ * \note Since this function expects the port number in network byte
8080+ * order, a conversion using HTONS() or htons() is necessary.
8081+ *
8082+ \code
8083+ uip_unlisten(HTONS(80));
8084+ \endcode
8085+ *
8086+ * \param port A 16-bit port number in network byte order.
8087+ */
8088+void uip_unlisten(u16_t port);
8089+
8090+/**
8091+ * Connect to a remote host using TCP.
8092+ *
8093+ * This function is used to start a new connection to the specified
8094+ * port on the specied host. It allocates a new connection identifier,
8095+ * sets the connection to the SYN_SENT state and sets the
8096+ * retransmission timer to 0. This will cause a TCP SYN segment to be
8097+ * sent out the next time this connection is periodically processed,
8098+ * which usually is done within 0.5 seconds after the call to
8099+ * uip_connect().
8100+ *
8101+ * \note This function is avaliable only if support for active open
8102+ * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
8103+ *
8104+ * \note Since this function requires the port number to be in network
8105+ * byte order, a convertion using HTONS() or htons() is necessary.
8106+ *
8107+ \code
8108+ u16_t ipaddr[2];
8109+
8110+ uip_ipaddr(ipaddr, 192,168,1,2);
8111+ uip_connect(ipaddr, HTONS(80));
8112+ \endcode
8113+ *
8114+ * \param ripaddr A pointer to a 4-byte array representing the IP
8115+ * address of the remote hot.
8116+ *
8117+ * \param port A 16-bit port number in network byte order.
8118+ *
8119+ * \return A pointer to the uIP connection identifier for the new connection,
8120+ * or NULL if no connection could be allocated.
8121+ *
8122+ */
8123+struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
8124+
8125+
8126+
8127+/**
8128+ * \internal
8129+ *
8130+ * Check if a connection has outstanding (i.e., unacknowledged) data.
8131+ *
8132+ * \param conn A pointer to the uip_conn structure for the connection.
8133+ *
8134+ * \hideinitializer
8135+ */
8136+#define uip_outstanding(conn) ((conn)->len)
8137+
8138+/**
8139+ * Send data on the current connection.
8140+ *
8141+ * This function is used to send out a single segment of TCP
8142+ * data. Only applications that have been invoked by uIP for event
8143+ * processing can send data.
8144+ *
8145+ * The amount of data that actually is sent out after a call to this
8146+ * funcion is determined by the maximum amount of data TCP allows. uIP
8147+ * will automatically crop the data so that only the appropriate
8148+ * amount of data is sent. The function uip_mss() can be used to query
8149+ * uIP for the amount of data that actually will be sent.
8150+ *
8151+ * \note This function does not guarantee that the sent data will
8152+ * arrive at the destination. If the data is lost in the network, the
8153+ * application will be invoked with the uip_rexmit() event being
8154+ * set. The application will then have to resend the data using this
8155+ * function.
8156+ *
8157+ * \param data A pointer to the data which is to be sent.
8158+ *
8159+ * \param len The maximum amount of data bytes to be sent.
8160+ *
8161+ * \hideinitializer
8162+ */
8163+#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0)
8164+
8165+/**
8166+ * The length of any incoming data that is currently avaliable (if avaliable)
8167+ * in the uip_appdata buffer.
8168+ *
8169+ * The test function uip_data() must first be used to check if there
8170+ * is any data available at all.
8171+ *
8172+ * \hideinitializer
8173+ */
8174+#define uip_datalen() uip_len
8175+
8176+/**
8177+ * The length of any out-of-band data (urgent data) that has arrived
8178+ * on the connection.
8179+ *
8180+ * \note The configuration parameter UIP_URGDATA must be set for this
8181+ * function to be enabled.
8182+ *
8183+ * \hideinitializer
8184+ */
8185+#define uip_urgdatalen() uip_urglen
8186+
8187+/**
8188+ * Close the current connection.
8189+ *
8190+ * This function will close the current connection in a nice way.
8191+ *
8192+ * \hideinitializer
8193+ */
8194+#define uip_close() (uip_flags = UIP_CLOSE)
8195+
8196+/**
8197+ * Abort the current connection.
8198+ *
8199+ * This function will abort (reset) the current connection, and is
8200+ * usually used when an error has occured that prevents using the
8201+ * uip_close() function.
8202+ *
8203+ * \hideinitializer
8204+ */
8205+#define uip_abort() (uip_flags = UIP_ABORT)
8206+
8207+/**
8208+ * Tell the sending host to stop sending data.
8209+ *
8210+ * This function will close our receiver's window so that we stop
8211+ * receiving data for the current connection.
8212+ *
8213+ * \hideinitializer
8214+ */
8215+#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
8216+
8217+/**
8218+ * Find out if the current connection has been previously stopped with
8219+ * uip_stop().
8220+ *
8221+ * \hideinitializer
8222+ */
8223+#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
8224+
8225+/**
8226+ * Restart the current connection, if is has previously been stopped
8227+ * with uip_stop().
8228+ *
8229+ * This function will open the receiver's window again so that we
8230+ * start receiving data for the current connection.
8231+ *
8232+ * \hideinitializer
8233+ */
8234+#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
8235+ uip_conn->tcpstateflags &= ~UIP_STOPPED; \
8236+ } while(0)
8237+
8238+
8239+/* uIP tests that can be made to determine in what state the current
8240+ connection is, and what the application function should do. */
8241+
8242+/**
8243+ * Is new incoming data available?
8244+ *
8245+ * Will reduce to non-zero if there is new data for the application
8246+ * present at the uip_appdata pointer. The size of the data is
8247+ * avaliable through the uip_len variable.
8248+ *
8249+ * \hideinitializer
8250+ */
8251+#define uip_newdata() (uip_flags & UIP_NEWDATA)
8252+
8253+/**
8254+ * Has previously sent data been acknowledged?
8255+ *
8256+ * Will reduce to non-zero if the previously sent data has been
8257+ * acknowledged by the remote host. This means that the application
8258+ * can send new data.
8259+ *
8260+ * \hideinitializer
8261+ */
8262+#define uip_acked() (uip_flags & UIP_ACKDATA)
8263+
8264+/**
8265+ * Has the connection just been connected?
8266+ *
8267+ * Reduces to non-zero if the current connection has been connected to
8268+ * a remote host. This will happen both if the connection has been
8269+ * actively opened (with uip_connect()) or passively opened (with
8270+ * uip_listen()).
8271+ *
8272+ * \hideinitializer
8273+ */
8274+#define uip_connected() (uip_flags & UIP_CONNECTED)
8275+
8276+/**
8277+ * Has the connection been closed by the other end?
8278+ *
8279+ * Is non-zero if the connection has been closed by the remote
8280+ * host. The application may then do the necessary clean-ups.
8281+ *
8282+ * \hideinitializer
8283+ */
8284+#define uip_closed() (uip_flags & UIP_CLOSE)
8285+
8286+/**
8287+ * Has the connection been aborted by the other end?
8288+ *
8289+ * Non-zero if the current connection has been aborted (reset) by the
8290+ * remote host.
8291+ *
8292+ * \hideinitializer
8293+ */
8294+#define uip_aborted() (uip_flags & UIP_ABORT)
8295+
8296+/**
8297+ * Has the connection timed out?
8298+ *
8299+ * Non-zero if the current connection has been aborted due to too many
8300+ * retransmissions.
8301+ *
8302+ * \hideinitializer
8303+ */
8304+#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
8305+
8306+/**
8307+ * Do we need to retransmit previously data?
8308+ *
8309+ * Reduces to non-zero if the previously sent data has been lost in
8310+ * the network, and the application should retransmit it. The
8311+ * application should send the exact same data as it did the last
8312+ * time, using the uip_send() function.
8313+ *
8314+ * \hideinitializer
8315+ */
8316+#define uip_rexmit() (uip_flags & UIP_REXMIT)
8317+
8318+/**
8319+ * Is the connection being polled by uIP?
8320+ *
8321+ * Is non-zero if the reason the application is invoked is that the
8322+ * current connection has been idle for a while and should be
8323+ * polled.
8324+ *
8325+ * The polling event can be used for sending data without having to
8326+ * wait for the remote host to send data.
8327+ *
8328+ * \hideinitializer
8329+ */
8330+#define uip_poll() (uip_flags & UIP_POLL)
8331+
8332+/**
8333+ * Get the initial maxium segment size (MSS) of the current
8334+ * connection.
8335+ *
8336+ * \hideinitializer
8337+ */
8338+#define uip_initialmss() (uip_conn->initialmss)
8339+
8340+/**
8341+ * Get the current maxium segment size that can be sent on the current
8342+ * connection.
8343+ *
8344+ * The current maxiumum segment size that can be sent on the
8345+ * connection is computed from the receiver's window and the MSS of
8346+ * the connection (which also is available by calling
8347+ * uip_initialmss()).
8348+ *
8349+ * \hideinitializer
8350+ */
8351+#define uip_mss() (uip_conn->mss)
8352+
8353+/**
8354+ * Set up a new UDP connection.
8355+ *
8356+ * \param ripaddr A pointer to a 4-byte structure representing the IP
8357+ * address of the remote host.
8358+ *
8359+ * \param rport The remote port number in network byte order.
8360+ *
8361+ * \return The uip_udp_conn structure for the new connection or NULL
8362+ * if no connection could be allocated.
8363+ */
8364+struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
8365+
8366+/**
8367+ * Removed a UDP connection.
8368+ *
8369+ * \param conn A pointer to the uip_udp_conn structure for the connection.
8370+ *
8371+ * \hideinitializer
8372+ */
8373+#define uip_udp_remove(conn) (conn)->lport = 0
8374+
8375+/**
8376+ * Send a UDP datagram of length len on the current connection.
8377+ *
8378+ * This function can only be called in response to a UDP event (poll
8379+ * or newdata). The data must be present in the uip_buf buffer, at the
8380+ * place pointed to by the uip_appdata pointer.
8381+ *
8382+ * \param len The length of the data in the uip_buf buffer.
8383+ *
8384+ * \hideinitializer
8385+ */
8386+#define uip_udp_send(len) uip_slen = (len)
8387+
8388+/** @} */
8389+
8390+/* uIP convenience and converting functions. */
8391+
8392+/**
8393+ * \defgroup uipconvfunc uIP conversion functions
8394+ * @{
8395+ *
8396+ * These functions can be used for converting between different data
8397+ * formats used by uIP.
8398+ */
8399+
8400+/**
8401+ * Pack an IP address into a 4-byte array which is used by uIP to
8402+ * represent IP addresses.
8403+ *
8404+ * Example:
8405+ \code
8406+ u16_t ipaddr[2];
8407+
8408+ uip_ipaddr(&ipaddr, 192,168,1,2);
8409+ \endcode
8410+ *
8411+ * \param addr A pointer to a 4-byte array that will be filled in with
8412+ * the IP addres.
8413+ * \param addr0 The first octet of the IP address.
8414+ * \param addr1 The second octet of the IP address.
8415+ * \param addr2 The third octet of the IP address.
8416+ * \param addr3 The forth octet of the IP address.
8417+ *
8418+ * \hideinitializer
8419+ */
8420+#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
8421+ (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \
8422+ (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \
8423+ } while(0)
8424+
8425+/**
8426+ * Convert 16-bit quantity from host byte order to network byte order.
8427+ *
8428+ * This macro is primarily used for converting constants from host
8429+ * byte order to network byte order. For converting variables to
8430+ * network byte order, use the htons() function instead.
8431+ *
8432+ * \hideinitializer
8433+ */
8434+#ifndef HTONS
8435+# if BYTE_ORDER == BIG_ENDIAN
8436+# define HTONS(n) (n)
8437+# else /* BYTE_ORDER == BIG_ENDIAN */
8438+# define HTONS(n) ((((u16_t)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))
8439+# endif /* BYTE_ORDER == BIG_ENDIAN */
8440+#endif /* HTONS */
8441+
8442+/**
8443+ * Convert 16-bit quantity from host byte order to network byte order.
8444+ *
8445+ * This function is primarily used for converting variables from host
8446+ * byte order to network byte order. For converting constants to
8447+ * network byte order, use the HTONS() macro instead.
8448+ */
8449+#ifndef htons
8450+u16_t htons(u16_t val);
8451+#endif /* htons */
8452+
8453+/** @} */
8454+
8455+/**
8456+ * Pointer to the application data in the packet buffer.
8457+ *
8458+ * This pointer points to the application data when the application is
8459+ * called. If the application wishes to send data, the application may
8460+ * use this space to write the data into before calling uip_send().
8461+ */
8462+extern volatile u8_t *uip_appdata;
8463+extern volatile u8_t *uip_sappdata;
8464+
8465+#if UIP_URGDATA > 0
8466+/* u8_t *uip_urgdata:
8467+ *
8468+ * This pointer points to any urgent data that has been received. Only
8469+ * present if compiled with support for urgent data (UIP_URGDATA).
8470+ */
8471+extern volatile u8_t *uip_urgdata;
8472+#endif /* UIP_URGDATA > 0 */
8473+
8474+
8475+/* u[8|16]_t uip_len:
8476+ *
8477+ * When the application is called, uip_len contains the length of any
8478+ * new data that has been received from the remote host. The
8479+ * application should set this variable to the size of any data that
8480+ * the application wishes to send. When the network device driver
8481+ * output function is called, uip_len should contain the length of the
8482+ * outgoing packet.
8483+ */
8484+extern volatile u16_t uip_len, uip_slen;
8485+
8486+#if UIP_URGDATA > 0
8487+extern volatile u8_t uip_urglen, uip_surglen;
8488+#endif /* UIP_URGDATA > 0 */
8489+
8490+
8491+/**
8492+ * Representation of a uIP TCP connection.
8493+ *
8494+ * The uip_conn structure is used for identifying a connection. All
8495+ * but one field in the structure are to be considered read-only by an
8496+ * application. The only exception is the appstate field whos purpose
8497+ * is to let the application store application-specific state (e.g.,
8498+ * file pointers) for the connection. The size of this field is
8499+ * configured in the "uipopt.h" header file.
8500+ */
8501+struct uip_conn {
8502+ u16_t ripaddr[2]; /**< The IP address of the remote host. */
8503+
8504+ u16_t lport; /**< The local TCP port, in network byte order. */
8505+ u16_t rport; /**< The local remote TCP port, in network byte
8506+ order. */
8507+
8508+ u8_t rcv_nxt[4]; /**< The sequence number that we expect to
8509+ receive next. */
8510+ u8_t snd_nxt[4]; /**< The sequence number that was last sent by
8511+ us. */
8512+ u16_t len; /**< Length of the data that was previously sent. */
8513+ u16_t mss; /**< Current maximum segment size for the
8514+ connection. */
8515+ u16_t initialmss; /**< Initial maximum segment size for the
8516+ connection. */
8517+ u8_t sa; /**< Retransmission time-out calculation state
8518+ variable. */
8519+ u8_t sv; /**< Retransmission time-out calculation state
8520+ variable. */
8521+ u8_t rto; /**< Retransmission time-out. */
8522+ u8_t tcpstateflags; /**< TCP state and flags. */
8523+ u8_t timer; /**< The retransmission timer. */
8524+ u8_t nrtx; /**< The number of retransmissions for the last
8525+ segment sent. */
8526+
8527+ /** The application state. */
8528+ u8_t appstate[UIP_APPSTATE_SIZE];
8529+};
8530+
8531+
8532+/* Pointer to the current connection. */
8533+extern struct uip_conn *uip_conn;
8534+/* The array containing all uIP connections. */
8535+extern struct uip_conn uip_conns[UIP_CONNS];
8536+/**
8537+ * \addtogroup uiparch
8538+ * @{
8539+ */
8540+
8541+/**
8542+ * 4-byte array used for the 32-bit sequence number calculations.
8543+ */
8544+extern volatile u8_t uip_acc32[4];
8545+
8546+/** @} */
8547+
8548+
8549+#if UIP_UDP
8550+/**
8551+ * Representation of a uIP UDP connection.
8552+ */
8553+struct uip_udp_conn {
8554+ u16_t ripaddr[2]; /**< The IP address of the remote peer. */
8555+ u16_t lport; /**< The local port number in network byte order. */
8556+ u16_t rport; /**< The remote port number in network byte order. */
8557+};
8558+
8559+extern struct uip_udp_conn *uip_udp_conn;
8560+extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
8561+#endif /* UIP_UDP */
8562+
8563+/**
8564+ * The structure holding the TCP/IP statistics that are gathered if
8565+ * UIP_STATISTICS is set to 1.
8566+ *
8567+ */
8568+struct uip_stats {
8569+ struct {
8570+ uip_stats_t drop; /**< Number of dropped packets at the IP
8571+ layer. */
8572+ uip_stats_t recv; /**< Number of received packets at the IP
8573+ layer. */
8574+ uip_stats_t sent; /**< Number of sent packets at the IP
8575+ layer. */
8576+ uip_stats_t vhlerr; /**< Number of packets dropped due to wrong
8577+ IP version or header length. */
8578+ uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
8579+ IP length, high byte. */
8580+ uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
8581+ IP length, low byte. */
8582+ uip_stats_t fragerr; /**< Number of packets dropped since they
8583+ were IP fragments. */
8584+ uip_stats_t chkerr; /**< Number of packets dropped due to IP
8585+ checksum errors. */
8586+ uip_stats_t protoerr; /**< Number of packets dropped since they
8587+ were neither ICMP, UDP nor TCP. */
8588+ } ip; /**< IP statistics. */
8589+ struct {
8590+ uip_stats_t drop; /**< Number of dropped ICMP packets. */
8591+ uip_stats_t recv; /**< Number of received ICMP packets. */
8592+ uip_stats_t sent; /**< Number of sent ICMP packets. */
8593+ uip_stats_t typeerr; /**< Number of ICMP packets with a wrong
8594+ type. */
8595+ } icmp; /**< ICMP statistics. */
8596+ struct {
8597+ uip_stats_t drop; /**< Number of dropped TCP segments. */
8598+ uip_stats_t recv; /**< Number of recived TCP segments. */
8599+ uip_stats_t sent; /**< Number of sent TCP segments. */
8600+ uip_stats_t chkerr; /**< Number of TCP segments with a bad
8601+ checksum. */
8602+ uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
8603+ number. */
8604+ uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */
8605+ uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */
8606+ uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
8607+ connections was avaliable. */
8608+ uip_stats_t synrst; /**< Number of SYNs for closed ports,
8609+ triggering a RST. */
8610+ } tcp; /**< TCP statistics. */
8611+};
8612+
8613+/**
8614+ * The uIP TCP/IP statistics.
8615+ *
8616+ * This is the variable in which the uIP TCP/IP statistics are gathered.
8617+ */
8618+extern struct uip_stats uip_stat;
8619+
8620+
8621+/*-----------------------------------------------------------------------------------*/
8622+/* All the stuff below this point is internal to uIP and should not be
8623+ * used directly by an application or by a device driver.
8624+ */
8625+/*-----------------------------------------------------------------------------------*/
8626+/* u8_t uip_flags:
8627+ *
8628+ * When the application is called, uip_flags will contain the flags
8629+ * that are defined in this file. Please read below for more
8630+ * infomation.
8631+ */
8632+extern volatile u8_t uip_flags;
8633+
8634+/* The following flags may be set in the global variable uip_flags
8635+ before calling the application callback. The UIP_ACKDATA and
8636+ UIP_NEWDATA flags may both be set at the same time, whereas the
8637+ others are mutualy exclusive. Note that these flags should *NOT* be
8638+ accessed directly, but through the uIP functions/macros. */
8639+
8640+#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
8641+ acked and the application should send
8642+ out new data instead of retransmitting
8643+ the last data. */
8644+#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
8645+ us new data. */
8646+#define UIP_REXMIT 4 /* Tells the application to retransmit the
8647+ data that was last sent. */
8648+#define UIP_POLL 8 /* Used for polling the application, to
8649+ check if the application has data that
8650+ it wants to send. */
8651+#define UIP_CLOSE 16 /* The remote host has closed the
8652+ connection, thus the connection has
8653+ gone away. Or the application signals
8654+ that it wants to close the
8655+ connection. */
8656+#define UIP_ABORT 32 /* The remote host has aborted the
8657+ connection, thus the connection has
8658+ gone away. Or the application signals
8659+ that it wants to abort the
8660+ connection. */
8661+#define UIP_CONNECTED 64 /* We have got a connection from a remote
8662+ host and have set up a new connection
8663+ for it, or an active connection has
8664+ been successfully established. */
8665+
8666+#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
8667+ too many retransmissions. */
8668+
8669+
8670+/* uip_process(flag):
8671+ *
8672+ * The actual uIP function which does all the work.
8673+ */
8674+void uip_process(u8_t flag);
8675+
8676+/* The following flags are passed as an argument to the uip_process()
8677+ function. They are used to distinguish between the two cases where
8678+ uip_process() is called. It can be called either because we have
8679+ incoming data that should be processed, or because the periodic
8680+ timer has fired. */
8681+
8682+#define UIP_DATA 1 /* Tells uIP that there is incoming data in
8683+ the uip_buf buffer. The length of the
8684+ data is stored in the global variable
8685+ uip_len. */
8686+#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
8687+ fired. */
8688+#if UIP_UDP
8689+#define UIP_UDP_TIMER 3
8690+#endif /* UIP_UDP */
8691+
8692+/* The TCP states used in the uip_conn->tcpstateflags. */
8693+#define CLOSED 0
8694+#define SYN_RCVD 1
8695+#define SYN_SENT 2
8696+#define ESTABLISHED 3
8697+#define FIN_WAIT_1 4
8698+#define FIN_WAIT_2 5
8699+#define CLOSING 6
8700+#define TIME_WAIT 7
8701+#define LAST_ACK 8
8702+#define TS_MASK 15
8703+
8704+#define UIP_STOPPED 16
8705+
8706+#define UIP_TCPIP_HLEN 40
8707+
8708+/* The TCP and IP headers. */
8709+typedef struct {
8710+ /* IP header. */
8711+ u8_t vhl,
8712+ tos,
8713+ len[2],
8714+ ipid[2],
8715+ ipoffset[2],
8716+ ttl,
8717+ proto;
8718+ u16_t ipchksum;
8719+ u16_t srcipaddr[2],
8720+ destipaddr[2];
8721+
8722+ /* TCP header. */
8723+ u16_t srcport,
8724+ destport;
8725+ u8_t seqno[4],
8726+ ackno[4],
8727+ tcpoffset,
8728+ flags,
8729+ wnd[2];
8730+ u16_t tcpchksum;
8731+ u8_t urgp[2];
8732+ u8_t optdata[4];
8733+} uip_tcpip_hdr;
8734+
8735+/* The ICMP and IP headers. */
8736+typedef struct {
8737+ /* IP header. */
8738+ u8_t vhl,
8739+ tos,
8740+ len[2],
8741+ ipid[2],
8742+ ipoffset[2],
8743+ ttl,
8744+ proto;
8745+ u16_t ipchksum;
8746+ u16_t srcipaddr[2],
8747+ destipaddr[2];
8748+ /* ICMP (echo) header. */
8749+ u8_t type, icode;
8750+ u16_t icmpchksum;
8751+ u16_t id, seqno;
8752+} uip_icmpip_hdr;
8753+
8754+
8755+/* The UDP and IP headers. */
8756+typedef struct {
8757+ /* IP header. */
8758+ u8_t vhl,
8759+ tos,
8760+ len[2],
8761+ ipid[2],
8762+ ipoffset[2],
8763+ ttl,
8764+ proto;
8765+ u16_t ipchksum;
8766+ u16_t srcipaddr[2],
8767+ destipaddr[2];
8768+
8769+ /* UDP header. */
8770+ u16_t srcport,
8771+ destport;
8772+ u16_t udplen;
8773+ u16_t udpchksum;
8774+} uip_udpip_hdr;
8775+
8776+#define UIP_PROTO_ICMP 1
8777+#define UIP_PROTO_TCP 6
8778+#define UIP_PROTO_UDP 17
8779+
8780+#if UIP_FIXEDADDR
8781+extern const u16_t uip_hostaddr[2];
8782+#else /* UIP_FIXEDADDR */
8783+extern u16_t uip_hostaddr[2];
8784+#endif /* UIP_FIXEDADDR */
8785+
8786+#endif /* __UIP_H__ */
8787+
8788+
8789+/** @} */
8790+
8791--- /dev/null
8792+++ b/net/uip-0.9/uipopt.h
8793@@ -0,0 +1,557 @@
8794+/**
8795+ * \defgroup uipopt Configuration options for uIP
8796+ * @{
8797+ *
8798+ * uIP is configured using the per-project configuration file
8799+ * "uipopt.h". This file contains all compile-time options for uIP and
8800+ * should be tweaked to match each specific project. The uIP
8801+ * distribution contains a documented example "uipopt.h" that can be
8802+ * copied and modified for each project.
8803+ */
8804+
8805+/**
8806+ * \file
8807+ * Configuration options for uIP.
8808+ * \author Adam Dunkels <adam@dunkels.com>
8809+ *
8810+ * This file is used for tweaking various configuration options for
8811+ * uIP. You should make a copy of this file into one of your project's
8812+ * directories instead of editing this example "uipopt.h" file that
8813+ * comes with the uIP distribution.
8814+ */
8815+
8816+/*
8817+ * Copyright (c) 2001-2003, Adam Dunkels.
8818+ * All rights reserved.
8819+ *
8820+ * Redistribution and use in source and binary forms, with or without
8821+ * modification, are permitted provided that the following conditions
8822+ * are met:
8823+ * 1. Redistributions of source code must retain the above copyright
8824+ * notice, this list of conditions and the following disclaimer.
8825+ * 2. Redistributions in binary form must reproduce the above copyright
8826+ * notice, this list of conditions and the following disclaimer in the
8827+ * documentation and/or other materials provided with the distribution.
8828+ * 3. The name of the author may not be used to endorse or promote
8829+ * products derived from this software without specific prior
8830+ * written permission.
8831+ *
8832+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8833+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8834+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8835+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8836+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8837+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8838+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8839+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8840+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8841+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8842+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8843+ *
8844+ * This file is part of the uIP TCP/IP stack.
8845+ *
8846+ * $Id: uipopt.h,v 1.16.2.5 2003/10/07 13:22:51 adam Exp $
8847+ *
8848+ */
8849+
8850+#ifndef __UIPOPT_H__
8851+#define __UIPOPT_H__
8852+
8853+/*------------------------------------------------------------------------------*/
8854+/**
8855+ * \defgroup uipopttypedef uIP type definitions
8856+ * @{
8857+ */
8858+
8859+/**
8860+ * The 8-bit unsigned data type.
8861+ *
8862+ * This may have to be tweaked for your particular compiler. "unsigned
8863+ * char" works for most compilers.
8864+ */
8865+typedef unsigned char u8_t;
8866+
8867+/**
8868+ * The 16-bit unsigned data type.
8869+ *
8870+ * This may have to be tweaked for your particular compiler. "unsigned
8871+ * short" works for most compilers.
8872+ */
8873+typedef unsigned short u16_t;
8874+
8875+/**
8876+ * The statistics data type.
8877+ *
8878+ * This datatype determines how high the statistics counters are able
8879+ * to count.
8880+ */
8881+typedef unsigned short uip_stats_t;
8882+
8883+/** @} */
8884+
8885+/*------------------------------------------------------------------------------*/
8886+
8887+/**
8888+ * \defgroup uipoptstaticconf Static configuration options
8889+ * @{
8890+ *
8891+ * These configuration options can be used for setting the IP address
8892+ * settings statically, but only if UIP_FIXEDADDR is set to 1. The
8893+ * configuration options for a specific node includes IP address,
8894+ * netmask and default router as well as the Ethernet address. The
8895+ * netmask, default router and Ethernet address are appliciable only
8896+ * if uIP should be run over Ethernet.
8897+ *
8898+ * All of these should be changed to suit your project.
8899+*/
8900+
8901+/**
8902+ * Determines if uIP should use a fixed IP address or not.
8903+ *
8904+ * If uIP should use a fixed IP address, the settings are set in the
8905+ * uipopt.h file. If not, the macros uip_sethostaddr(),
8906+ * uip_setdraddr() and uip_setnetmask() should be used instead.
8907+ *
8908+ * \hideinitializer
8909+ */
8910+#define UIP_FIXEDADDR 0
8911+
8912+/**
8913+ * Ping IP address asignment.
8914+ *
8915+ * uIP uses a "ping" packets for setting its own IP address if this
8916+ * option is set. If so, uIP will start with an empty IP address and
8917+ * the destination IP address of the first incoming "ping" (ICMP echo)
8918+ * packet will be used for setting the hosts IP address.
8919+ *
8920+ * \note This works only if UIP_FIXEDADDR is 0.
8921+ *
8922+ * \hideinitializer
8923+ */
8924+#define UIP_PINGADDRCONF 0
8925+
8926+#define UIP_IPADDR0 192 /**< The first octet of the IP address of
8927+ this uIP node, if UIP_FIXEDADDR is
8928+ 1. \hideinitializer */
8929+#define UIP_IPADDR1 168 /**< The second octet of the IP address of
8930+ this uIP node, if UIP_FIXEDADDR is
8931+ 1. \hideinitializer */
8932+#define UIP_IPADDR2 0 /**< The third octet of the IP address of
8933+ this uIP node, if UIP_FIXEDADDR is
8934+ 1. \hideinitializer */
8935+#define UIP_IPADDR3 250 /**< The fourth octet of the IP address of
8936+ this uIP node, if UIP_FIXEDADDR is
8937+ 1. \hideinitializer */
8938+
8939+#define UIP_NETMASK0 255 /**< The first octet of the netmask of
8940+ this uIP node, if UIP_FIXEDADDR is
8941+ 1. \hideinitializer */
8942+#define UIP_NETMASK1 255 /**< The second octet of the netmask of
8943+ this uIP node, if UIP_FIXEDADDR is
8944+ 1. \hideinitializer */
8945+#define UIP_NETMASK2 255 /**< The third octet of the netmask of
8946+ this uIP node, if UIP_FIXEDADDR is
8947+ 1. \hideinitializer */
8948+#define UIP_NETMASK3 0 /**< The fourth octet of the netmask of
8949+ this uIP node, if UIP_FIXEDADDR is
8950+ 1. \hideinitializer */
8951+
8952+#define UIP_DRIPADDR0 192 /**< The first octet of the IP address of
8953+ the default router, if UIP_FIXEDADDR is
8954+ 1. \hideinitializer */
8955+#define UIP_DRIPADDR1 168 /**< The second octet of the IP address of
8956+ the default router, if UIP_FIXEDADDR is
8957+ 1. \hideinitializer */
8958+#define UIP_DRIPADDR2 0 /**< The third octet of the IP address of
8959+ the default router, if UIP_FIXEDADDR is
8960+ 1. \hideinitializer */
8961+#define UIP_DRIPADDR3 1 /**< The fourth octet of the IP address of
8962+ the default router, if UIP_FIXEDADDR is
8963+ 1. \hideinitializer */
8964+
8965+/**
8966+ * Specifies if the uIP ARP module should be compiled with a fixed
8967+ * Ethernet MAC address or not.
8968+ *
8969+ * If this configuration option is 0, the macro uip_setethaddr() can
8970+ * be used to specify the Ethernet address at run-time.
8971+ *
8972+ * \hideinitializer
8973+ */
8974+#define UIP_FIXEDETHADDR 0
8975+
8976+#define UIP_ETHADDR0 0x00 /**< The first octet of the Ethernet
8977+ address if UIP_FIXEDETHADDR is
8978+ 1. \hideinitializer */
8979+#define UIP_ETHADDR1 0xbd /**< The second octet of the Ethernet
8980+ address if UIP_FIXEDETHADDR is
8981+ 1. \hideinitializer */
8982+#define UIP_ETHADDR2 0x3b /**< The third octet of the Ethernet
8983+ address if UIP_FIXEDETHADDR is
8984+ 1. \hideinitializer */
8985+#define UIP_ETHADDR3 0x33 /**< The fourth octet of the Ethernet
8986+ address if UIP_FIXEDETHADDR is
8987+ 1. \hideinitializer */
8988+#define UIP_ETHADDR4 0x05 /**< The fifth octet of the Ethernet
8989+ address if UIP_FIXEDETHADDR is
8990+ 1. \hideinitializer */
8991+#define UIP_ETHADDR5 0x71 /**< The sixth octet of the Ethernet
8992+ address if UIP_FIXEDETHADDR is
8993+ 1. \hideinitializer */
8994+
8995+/** @} */
8996+/*------------------------------------------------------------------------------*/
8997+/**
8998+ * \defgroup uipoptip IP configuration options
8999+ * @{
9000+ *
9001+ */
9002+/**
9003+ * The IP TTL (time to live) of IP packets sent by uIP.
9004+ *
9005+ * This should normally not be changed.
9006+ */
9007+#define UIP_TTL 255
9008+
9009+/**
9010+ * Turn on support for IP packet reassembly.
9011+ *
9012+ * uIP supports reassembly of fragmented IP packets. This features
9013+ * requires an additonal amount of RAM to hold the reassembly buffer
9014+ * and the reassembly code size is approximately 700 bytes. The
9015+ * reassembly buffer is of the same size as the uip_buf buffer
9016+ * (configured by UIP_BUFSIZE).
9017+ *
9018+ * \note IP packet reassembly is not heavily tested.
9019+ *
9020+ * \hideinitializer
9021+ */
9022+#define UIP_REASSEMBLY 0
9023+
9024+/**
9025+ * The maximum time an IP fragment should wait in the reassembly
9026+ * buffer before it is dropped.
9027+ *
9028+ */
9029+#define UIP_REASS_MAXAGE 40
9030+
9031+/** @} */
9032+
9033+/*------------------------------------------------------------------------------*/
9034+/**
9035+ * \defgroup uipoptudp UDP configuration options
9036+ * @{
9037+ *
9038+ * \note The UDP support in uIP is still not entirely complete; there
9039+ * is no support for sending or receiving broadcast or multicast
9040+ * packets, but it works well enough to support a number of vital
9041+ * applications such as DNS queries, though
9042+ */
9043+
9044+/**
9045+ * Toggles wether UDP support should be compiled in or not.
9046+ *
9047+ * \hideinitializer
9048+ */
9049+#define UIP_UDP 0
9050+
9051+/**
9052+ * Toggles if UDP checksums should be used or not.
9053+ *
9054+ * \note Support for UDP checksums is currently not included in uIP,
9055+ * so this option has no function.
9056+ *
9057+ * \hideinitializer
9058+ */
9059+#define UIP_UDP_CHECKSUMS 0
9060+
9061+/**
9062+ * The maximum amount of concurrent UDP connections.
9063+ *
9064+ * \hideinitializer
9065+ */
9066+#define UIP_UDP_CONNS 10
9067+
9068+/**
9069+ * The name of the function that should be called when UDP datagrams arrive.
9070+ *
9071+ * \hideinitializer
9072+ */
9073+#define UIP_UDP_APPCALL udp_appcall
9074+
9075+/** @} */
9076+/*------------------------------------------------------------------------------*/
9077+/**
9078+ * \defgroup uipopttcp TCP configuration options
9079+ * @{
9080+ */
9081+
9082+/**
9083+ * Determines if support for opening connections from uIP should be
9084+ * compiled in.
9085+ *
9086+ * If the applications that are running on top of uIP for this project
9087+ * do not need to open outgoing TCP connections, this configration
9088+ * option can be turned off to reduce the code size of uIP.
9089+ *
9090+ * \hideinitializer
9091+ */
9092+#define UIP_ACTIVE_OPEN 1
9093+
9094+/**
9095+ * The maximum number of simultaneously open TCP connections.
9096+ *
9097+ * Since the TCP connections are statically allocated, turning this
9098+ * configuration knob down results in less RAM used. Each TCP
9099+ * connection requires approximatly 30 bytes of memory.
9100+ *
9101+ * \hideinitializer
9102+ */
9103+#define UIP_CONNS 10
9104+
9105+/**
9106+ * The maximum number of simultaneously listening TCP ports.
9107+ *
9108+ * Each listening TCP port requires 2 bytes of memory.
9109+ *
9110+ * \hideinitializer
9111+ */
9112+#define UIP_LISTENPORTS 10
9113+
9114+/**
9115+ * The size of the advertised receiver's window.
9116+ *
9117+ * Should be set low (i.e., to the size of the uip_buf buffer) is the
9118+ * application is slow to process incoming data, or high (32768 bytes)
9119+ * if the application processes data quickly.
9120+ *
9121+ * \hideinitializer
9122+ */
9123+#define UIP_RECEIVE_WINDOW 32768
9124+
9125+/**
9126+ * Determines if support for TCP urgent data notification should be
9127+ * compiled in.
9128+ *
9129+ * Urgent data (out-of-band data) is a rarely used TCP feature that
9130+ * very seldom would be required.
9131+ *
9132+ * \hideinitializer
9133+ */
9134+#define UIP_URGDATA 1
9135+
9136+/**
9137+ * The initial retransmission timeout counted in timer pulses.
9138+ *
9139+ * This should not be changed.
9140+ */
9141+#define UIP_RTO 3
9142+
9143+/**
9144+ * The maximum number of times a segment should be retransmitted
9145+ * before the connection should be aborted.
9146+ *
9147+ * This should not be changed.
9148+ */
9149+#define UIP_MAXRTX 8
9150+
9151+/**
9152+ * The maximum number of times a SYN segment should be retransmitted
9153+ * before a connection request should be deemed to have been
9154+ * unsuccessful.
9155+ *
9156+ * This should not need to be changed.
9157+ */
9158+#define UIP_MAXSYNRTX 3
9159+
9160+/**
9161+ * The TCP maximum segment size.
9162+ *
9163+ * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.
9164+ */
9165+#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
9166+
9167+/**
9168+ * How long a connection should stay in the TIME_WAIT state.
9169+ *
9170+ * This configiration option has no real implication, and it should be
9171+ * left untouched.
9172+ */
9173+#define UIP_TIME_WAIT_TIMEOUT 120
9174+
9175+
9176+/** @} */
9177+/*------------------------------------------------------------------------------*/
9178+/**
9179+ * \defgroup uipoptarp ARP configuration options
9180+ * @{
9181+ */
9182+
9183+/**
9184+ * The size of the ARP table.
9185+ *
9186+ * This option should be set to a larger value if this uIP node will
9187+ * have many connections from the local network.
9188+ *
9189+ * \hideinitializer
9190+ */
9191+#define UIP_ARPTAB_SIZE 8
9192+
9193+/**
9194+ * The maxium age of ARP table entries measured in 10ths of seconds.
9195+ *
9196+ * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
9197+ * default).
9198+ */
9199+#define UIP_ARP_MAXAGE 120
9200+
9201+/** @} */
9202+
9203+/*------------------------------------------------------------------------------*/
9204+
9205+/**
9206+ * \defgroup uipoptgeneral General configuration options
9207+ * @{
9208+ */
9209+
9210+/**
9211+ * The size of the uIP packet buffer.
9212+ *
9213+ * The uIP packet buffer should not be smaller than 60 bytes, and does
9214+ * not need to be larger than 1500 bytes. Lower size results in lower
9215+ * TCP throughput, larger size results in higher TCP throughput.
9216+ *
9217+ * \hideinitializer
9218+ */
9219+#define UIP_BUFSIZE 1500
9220+
9221+
9222+/**
9223+ * Determines if statistics support should be compiled in.
9224+ *
9225+ * The statistics is useful for debugging and to show the user.
9226+ *
9227+ * \hideinitializer
9228+ */
9229+#define UIP_STATISTICS 1
9230+
9231+/**
9232+ * Determines if logging of certain events should be compiled in.
9233+ *
9234+ * This is useful mostly for debugging. The function uip_log()
9235+ * must be implemented to suit the architecture of the project, if
9236+ * logging is turned on.
9237+ *
9238+ * \hideinitializer
9239+ */
9240+#define UIP_LOGGING 0
9241+
9242+/**
9243+ * Print out a uIP log message.
9244+ *
9245+ * This function must be implemented by the module that uses uIP, and
9246+ * is called by uIP whenever a log message is generated.
9247+ */
9248+void uip_log(char *msg);
9249+
9250+/**
9251+ * The link level header length.
9252+ *
9253+ * This is the offset into the uip_buf where the IP header can be
9254+ * found. For Ethernet, this should be set to 14. For SLIP, this
9255+ * should be set to 0.
9256+ *
9257+ * \hideinitializer
9258+ */
9259+#define UIP_LLH_LEN 14
9260+
9261+
9262+/** @} */
9263+/*------------------------------------------------------------------------------*/
9264+/**
9265+ * \defgroup uipoptcpu CPU architecture configuration
9266+ * @{
9267+ *
9268+ * The CPU architecture configuration is where the endianess of the
9269+ * CPU on which uIP is to be run is specified. Most CPUs today are
9270+ * little endian, and the most notable exception are the Motorolas
9271+ * which are big endian. The BYTE_ORDER macro should be changed to
9272+ * reflect the CPU architecture on which uIP is to be run.
9273+ */
9274+#ifndef LITTLE_ENDIAN
9275+#define LITTLE_ENDIAN 3412
9276+#endif /* LITTLE_ENDIAN */
9277+#ifndef BIG_ENDIAN
9278+#define BIG_ENDIAN 1234
9279+#endif /* BIGE_ENDIAN */
9280+
9281+/**
9282+ * The byte order of the CPU architecture on which uIP is to be run.
9283+ *
9284+ * This option can be either BIG_ENDIAN (Motorola byte order) or
9285+ * LITTLE_ENDIAN (Intel byte order).
9286+ *
9287+ * \hideinitializer
9288+ */
9289+/*#ifndef BYTE_ORDER*/
9290+#define BYTE_ORDER BIG_ENDIAN
9291+/*#endif*/ /* BYTE_ORDER */
9292+
9293+/** @} */
9294+/*------------------------------------------------------------------------------*/
9295+
9296+/**
9297+ * \defgroup uipoptapp Appication specific configurations
9298+ * @{
9299+ *
9300+ * An uIP application is implemented using a single application
9301+ * function that is called by uIP whenever a TCP/IP event occurs. The
9302+ * name of this function must be registered with uIP at compile time
9303+ * using the UIP_APPCALL definition.
9304+ *
9305+ * uIP applications can store the application state within the
9306+ * uip_conn structure by specifying the size of the application
9307+ * structure with the UIP_APPSTATE_SIZE macro.
9308+ *
9309+ * The file containing the definitions must be included in the
9310+ * uipopt.h file.
9311+ *
9312+ * The following example illustrates how this can look.
9313+ \code
9314+
9315+void httpd_appcall(void);
9316+#define UIP_APPCALL httpd_appcall
9317+
9318+struct httpd_state {
9319+ u8_t state;
9320+ u16_t count;
9321+ char *dataptr;
9322+ char *script;
9323+};
9324+#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
9325+ \endcode
9326+ */
9327+
9328+/**
9329+ * \var #define UIP_APPCALL
9330+ *
9331+ * The name of the application function that uIP should call in
9332+ * response to TCP/IP events.
9333+ *
9334+ */
9335+
9336+/**
9337+ * \var #define UIP_APPSTATE_SIZE
9338+ *
9339+ * The size of the application state that is to be stored in the
9340+ * uip_conn structure.
9341+ */
9342+/** @} */
9343+
9344+/* Include the header file for the application program that should be
9345+ used. If you don't use the example web server, you should change
9346+ this. */
9347+#include "httpd.h"
9348+
9349+
9350+#endif /* __UIPOPT_H__ */
9351

Archive Download this file



interactive