[base system & package/block-extroot] Missed file committing previous change 23110
[openwrt.git] / 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 --- /dev/null
23 +++ b/include/httpd.h
24 @@ -0,0 +1,17 @@
25 +#ifndef _UIP_HTTPD_H__
26 +#define _UIP_HTTPD_H__
27 +
28 +void HttpdStart (void);
29 +void HttpdHandler (void);
30 +
31 +/* board specific implementation */
32 +extern int do_http_upgrade(const unsigned char *data, const ulong size);
33 +
34 +#define HTTP_PROGRESS_START            0
35 +#define HTTP_PROGRESS_TIMEOUT          1
36 +#define HTTP_PROGRESS_UPLOAD_READY     2
37 +#define HTTP_PROGRESS_UGRADE_READY     3
38 +#define HTTP_PROGRESS_UGRADE_FAILED    4
39 +extern int do_http_progress(const int state);
40 +
41 +#endif
42 --- a/include/net.h
43 +++ b/include/net.h
44 @@ -383,7 +383,8 @@ extern int NetTimeOffset;                   /* offset ti
45  
46  /* Initialize the network adapter */
47  extern int     NetLoop(proto_t);
48 -
49 +extern int     NetLoopHttpd(void);
50 +extern void NetSendHttpd(void);
51  /* Shutdown adapters and cleanup */
52  extern void    NetStop(void);
53  
54 --- a/net/Makefile
55 +++ b/net/Makefile
56 @@ -26,6 +26,10 @@ include $(TOPDIR)/config.mk
57  # CFLAGS += -DDEBUG
58  
59  LIB    = $(obj)libnet.a
60 +UIPDIR  = uip-0.9
61 +RSADIR  = uip-0.9
62 +$(shell mkdir -p $(obj)$(UIPDIR)) 
63 +$(shell mkdir -p $(obj)$(RSADIR)) 
64  
65  COBJS-$(CONFIG_CMD_NET)  += bootp.o
66  COBJS-$(CONFIG_CMD_DNS)  += dns.o
67 @@ -36,6 +40,9 @@ COBJS-$(CONFIG_CMD_NET)  += rarp.o
68  COBJS-$(CONFIG_CMD_SNTP) += sntp.o
69  COBJS-$(CONFIG_CMD_NET)  += tftp.o
70  
71 +COBJS-$(CONFIG_CMD_HTTPD) += httpd.o $(UIPDIR)/fs.o $(UIPDIR)/httpd.o $(UIPDIR)/uip_arp.o $(UIPDIR)/uip_arch.o $(UIPDIR)/uip.o
72 +COBJS-$(CONFIG_CMD_RSA) += $(RSADIR)/bigint.o $(RSADIR)/base64.o $(RSADIR)/rmd160.o $(RSADIR)/rsa.o
73 +
74  COBJS  := $(COBJS-y)
75  SRCS   := $(COBJS:.o=.c)
76  OBJS   := $(addprefix $(obj),$(COBJS))
77 --- /dev/null
78 +++ b/net/httpd.c
79 @@ -0,0 +1,52 @@
80 +/*
81 + *     Copyright 1994, 1995, 2000 Neil Russell.
82 + *     (See License)
83 + *     Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
84 + */
85 +
86 +#include <common.h>
87 +#include <command.h>
88 +#include <net.h>
89 +#include "uip-0.9/uipopt.h"
90 +#include "uip-0.9/uip.h"
91 +#include "uip-0.9/uip_arp.h"
92 +
93 +
94 +#if defined(CONFIG_CMD_HTTPD)
95 +
96 +#define TIMEOUT                5
97 +
98 +static int arptimer = 0;
99 +
100 +void
101 +HttpdHandler (void)
102 +{
103 +       int i;
104 +       for(i = 0; i < UIP_CONNS; i++) {
105 +               uip_periodic(i);
106 +               if(uip_len > 0) {
107 +                       uip_arp_out();
108 +                       NetSendHttpd();
109 +               }
110 +       }
111 +       if(++arptimer == 20) {
112 +               uip_arp_timer();
113 +               arptimer = 0;
114 +       }
115 +}
116 +
117 +static void
118 +HttpdTimeout (void)
119 +{
120 +       puts ("T ");
121 +       NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
122 +}
123 +
124 +void
125 +HttpdStart (void)
126 +{
127 +       uip_init();
128 +       httpd_init();
129 +}
130 +
131 +#endif
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  DECLARE_GLOBAL_DATA_PTR;
153  
154 @@ -1308,6 +1321,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 @@ -1922,3 +1942,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/Makefile
333 @@ -0,0 +1,31 @@
334 +#
335 +# FONRSA & FONSIGN libraries unit testing
336 +# 
337 +# This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
338 +#
339 +# Execute in this directory
340 +#
341 +# Created: 20070422 Pablo Martin Medrano <pablo@fon.com>
342 +#
343 +# $Id: Makefile 389 2007-06-11 08:29:56Z pablo.martin $
344 +#
345 +# FIXME: Put this in the main Makefile.am
346 +# 
347 +all: fonsign dump_key
348 +
349 +fonsign:
350 +       gcc -g sign_openssl.c -D__MAINTEST__ -o fonsign -lssl
351 +
352 +dump_key:
353 +       gcc -o dump_key dump_key.c
354 +       ./dump_key > public_key.h
355 +
356 +foncheckrsa:
357 +       gcc -g bigint.c  fonrsa.c  rmd160.c foncheckrsa.c base64.c log.c  -o foncheckrsa 
358 +
359 +#private_fon_rsa_key.pem:
360 +#      openssl genrsa -out private_fon_rsa_key.pem 4096
361 +#      openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
362 +
363 +clean:
364 +       rm fonsign dump_key 
365 --- /dev/null
366 +++ b/net/rsa/base64.c
367 @@ -0,0 +1,137 @@
368 +#include "base64.h"
369 +
370 +static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
371 +/* Note that '=' (padding) is 0 */
372 +static const unsigned char fb64[256] = {
373 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
374 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
375 +       255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
376 +       52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255,
377 +       255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
378 +       15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
379 +       255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
380 +       41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
381 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
382 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
383 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
384 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
385 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
386 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
387 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
388 +       255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
389 +};
390 +
391 +static int encodeblock( unsigned char *in, char *out, int len )
392 +{
393 +       char s[3];
394 +       int i;
395 +
396 +       for (i = 0; i < len; i++)
397 +               s[i] = in[i];
398 +       for (i = len; i < 3; i++)
399 +               s[i] = 0;
400 +       out[0] = (unsigned char)(cb64[(s[0] & 0xfc) >> 2 ]);
401 +       out[1] = (unsigned char)(cb64[((s[0] & 0x03) << 4) | ((s[1] & 0xf0) >> 4) ]);
402 +       out[2] = (unsigned char)(cb64[((s[1] & 0x0f) << 2) | ((s[2] & 0xc0) >> 6) ]);
403 +       out[3] = (unsigned char)(cb64[s[2] & 0x3f ]);
404 +       switch (len) {
405 +               case 1:
406 +                       out[3] = '=';
407 +               case 2:
408 +                       out[2] = '=';
409 +                       break;
410 +               default:
411 +                       break;
412 +       }
413 +
414 +       return 4;
415 +}
416 +
417 +static int decodeblock(char *ins, unsigned char *out, int len)
418 +{
419 +       int i;
420 +       unsigned char in[4];
421 +       int skip = 0;
422 +
423 +       if (len != 4)
424 +               return -1;
425 +       for (i = 0; i < len; i++) {
426 +               if (ins[i] == '=') {
427 +                       in[i] = 0;
428 +                       skip++;  
429 +               } else
430 +                       in[i] = fb64[(int)(ins[i])];
431 +               if (in[i] == 255) {
432 +                       return -1;
433 +               }
434 +       }
435 +       out[0] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
436 +       if (skip == 2) {
437 +               return 1;
438 +       }
439 +       out[1] = (unsigned char )((in[1] & 0x0f) << 4 | in[2] >> 2);
440 +       if (skip == 1) {
441 +               return 2;
442 +       }
443 +       out[2] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
444 +
445 +       return 3;
446 +}
447 +
448 +int B64_encode(char *source, char *destination, int size_source, int size_destination)
449 +{
450 +       int chunks, reminder, size, d, i, size_expected;
451 +       char *s;
452 +       unsigned char *t;
453 +
454 +       chunks = size_source / 3;
455 +       reminder = size_source % 3;
456 +       size = 0;
457 +       size_expected = (chunks * 4) + (reminder?(reminder + 1):0);
458 +       if (size_destination < ((chunks * 4) + (reminder?4:0))) {
459 +               return 1;
460 +       }
461 +       for (i = 0; i < chunks; i++) {
462 +               s = source + (i * 3); 
463 +               t = destination + (i * 4);
464 +               d = encodeblock(s, t, 3);
465 +               if (d == -1) {
466 +                       return 1;
467 +               }
468 +               size += d;
469 +       }
470 +       if (reminder) {
471 +               d = encodeblock(source + (chunks * 3), destination + (chunks * 4), reminder);
472 +               if (d == -1) {
473 +                       return 1;
474 +               }
475 +               size += d;
476 +       }
477 +       return size;
478 +}
479 +
480 +int B64_decode(char *source, char *destination, int size_source, int size_destination)
481 +{
482 +       int chunks, reminder, size, d, i;
483 +
484 +       chunks = size_source / 4;
485 +       reminder = size_source % 4;
486 +       size = 0;
487 +       if (reminder) {
488 +               return 1;
489 +       }
490 +       if (size_destination < ((chunks * 3))) {
491 +               printf("%d, %d\n",
492 +                       size_destination, ((chunks * 3) + reminder));
493 +               return -1;
494 +       }
495 +       for (i = 0; i < chunks; i++) {
496 +               d = decodeblock(source + (i * 4), destination + (i * 3), 4);
497 +               if (d == -1) {
498 +                       return -1;
499 +               }
500 +               size += d;
501 +       }
502 +       return size;
503 +}
504 +
505 --- /dev/null
506 +++ b/net/rsa/base64.h
507 @@ -0,0 +1,11 @@
508 +#ifndef _BASE64_H_
509 +#define _BASE64_H_
510 +#ifdef __cplusplus
511 +extern "C" {
512 +#endif
513 +int B64_encode(char *source, char *destination, int size_source, int size_destination);
514 +int B64_decode(char *source, char *destination, int size_source, int size_destination);
515 +#ifdef __cplusplus
516 +}
517 +#endif
518 +#endif
519 --- /dev/null
520 +++ b/net/rsa/bigint.c
521 @@ -0,0 +1,906 @@
522 +/*
523 + *  Copyright(C) 2006
524 + *
525 + *  This library is free software; you can redistribute it and/or modify
526 + *  it under the terms of the GNU Lesser General Public License as published by
527 + *  the Free Software Foundation; either version 2.1 of the License, or
528 + *  (at your option) any later version.
529 + *
530 + *  This library is distributed in the hope that it will be useful,
531 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
532 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
533 + *  GNU Lesser General Public License for more details.
534 + *
535 + *  You should have received a copy of the GNU Lesser General Public License
536 + *  along with this library; if not, write to the Free Software
537 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
538 + */
539 +
540 +/**
541 + * @defgroup bigint_api Big Integer API
542 + * @brief The bigint implementation as used by the axTLS project.
543 + *
544 + * The bigint library is for RSA encryption/decryption as well as signing.
545 + * This code tries to minimise use of malloc/free by maintaining a small 
546 + * cache. A bigint context may maintain state by being made "permanent". 
547 + * It be be later released with a bi_depermanent() and bi_free() call.
548 + *
549 + * It supports the following reduction techniques:
550 + * - Classical
551 + * - Barrett
552 + * - Montgomery
553 + *
554 + * It also implements the following:
555 + * - Karatsuba multiplication
556 + * - Squaring
557 + * - Sliding window exponentiation
558 + * - Chinese Remainder Theorem (implemented in rsa.c).
559 + *
560 + * All the algorithms used are pretty standard, and designed for different
561 + * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
562 + * may need to be tested for negativity.
563 + *
564 + * This library steals some ideas from Jef Poskanzer
565 + * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
566 + * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
567 + * detail from "The Handbook of Applied Cryptography"
568 + * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
569 + * @{
570 + */
571 +
572 +#include "bigint.h"
573 +#include <malloc.h>
574 +#include "div64.h"
575 +
576 +static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
577 +static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
578 +static bigint *alloc(BI_CTX *ctx, int size);
579 +static bigint *trim(bigint *bi);
580 +static void more_comps(bigint *bi, int n);
581 +
582 +/**
583 + * @brief Start a new bigint context.
584 + * @return A bigint context.
585 + */
586 +BI_CTX *bi_initialize(void)
587 +{
588 +    BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
589 +
590 +    ctx->active_list = NULL;
591 +    ctx->active_count = 0;
592 +    ctx->free_list = NULL;
593 +    ctx->free_count = 0;
594 +    ctx->mod_offset = 0;
595 +
596 +    /* the radix */
597 +    ctx->bi_radix = alloc(ctx, 2); 
598 +    ctx->bi_radix->comps[0] = 0;
599 +    ctx->bi_radix->comps[1] = 1;
600 +    bi_permanent(ctx->bi_radix);
601 +
602 +    return ctx;
603 +}
604 +
605 +/**
606 + * @brief Close the bigint context and free any resources.
607 + *
608 + * Free up any used memory - a check is done if all objects were not 
609 + * properly freed.
610 + * @param ctx [in]   The bigint session context.
611 + */
612 +void bi_terminate(BI_CTX *ctx)
613 +{
614 +    bigint *p, *pn;
615 +
616 +    bi_depermanent(ctx->bi_radix); 
617 +    bi_free(ctx, ctx->bi_radix);
618 +
619 +    if (ctx->active_count != 0)
620 +    {
621 +       printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
622 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
623 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
624 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
625 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
626 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
627 +               return;
628 +       }
629 +
630 +    for (p = ctx->free_list; p != NULL; p = pn)
631 +    {
632 +        pn = p->next;
633 +        free(p->comps);
634 +        free(p);
635 +    }
636 +
637 +    free(ctx);
638 +}
639 +
640 +/**
641 + * @brief Increment the number of references to this object. 
642 + * It does not do a full copy.
643 + * @param bi [in]   The bigint to copy.
644 + * @return A referent to the same bigint.
645 + */
646 +bigint *bi_copy(bigint *bi)
647 +{
648 +    check(bi);
649 +    if (bi->refs != PERMANENT)
650 +        bi->refs++;
651 +    return bi;
652 +}
653 +
654 +/**
655 + * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
656 + *
657 + * For this object to be freed, bi_depermanent() must be called.
658 + * @param bi [in]   The bigint to be made permanent.
659 + */
660 +void bi_permanent(bigint *bi)
661 +{
662 +    check(bi);
663 +    if (bi->refs != 1)
664 +    {
665 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
666 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
667 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
668 +               return;
669 +       }
670 +
671 +    bi->refs = PERMANENT;
672 +}
673 +
674 +/**
675 + * @brief Take a permanent object and make it elligible for freedom.
676 + * @param bi [in]   The bigint to be made back to temporary.
677 + */
678 +void bi_depermanent(bigint *bi)
679 +{
680 +    check(bi);
681 +    if (bi->refs != PERMANENT)
682 +    {
683 +        printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
684 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
685 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
686 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
687 +               return;
688 +       }
689 +
690 +    bi->refs = 1;
691 +}
692 +
693 +/**
694 + * @brief Free a bigint object so it can be used again. 
695 + *
696 + * The memory itself it not actually freed, just tagged as being available 
697 + * @param ctx [in]   The bigint session context.
698 + * @param bi [in]    The bigint to be freed.
699 + */
700 +void bi_free(BI_CTX *ctx, bigint *bi)
701 +{
702 +    check(bi);
703 +    if (bi->refs == PERMANENT)
704 +    {
705 +        return;
706 +    }
707 +
708 +    if (--bi->refs > 0)
709 +    {
710 +        return;
711 +    }
712 +
713 +    bi->next = ctx->free_list;
714 +    ctx->free_list = bi;
715 +    ctx->free_count++;
716 +
717 +    if (--ctx->active_count < 0)
718 +    {
719 +        printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
720 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
721 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
722 +               printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
723 +               return;
724 +       }
725 +}
726 +
727 +/**
728 + * @brief Convert an (unsigned) integer into a bigint.
729 + * @param ctx [in]   The bigint session context.
730 + * @param i [in]     The (unsigned) integer to be converted.
731 + * 
732 + */
733 +bigint *int_to_bi(BI_CTX *ctx, comp i)
734 +{
735 +    bigint *biR = alloc(ctx, 1);
736 +    biR->comps[0] = i;
737 +    return biR;
738 +}
739 +
740 +/**
741 + * @brief Do a full copy of the bigint object.
742 + * @param ctx [in]   The bigint session context.
743 + * @param bi  [in]   The bigint object to be copied.
744 + */
745 +bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
746 +{
747 +    bigint *biR = alloc(ctx, bi->size);
748 +    check(bi);
749 +    memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
750 +    return biR;
751 +}
752 +
753 +/**
754 + * @brief Perform an additon operation between two bigints.
755 + * @param ctx [in]  The bigint session context.
756 + * @param bia [in]  A bigint.
757 + * @param bib [in]  Another bigint.
758 + * @return The result of the addition.
759 + */
760 +bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
761 +{
762 +    int n;
763 +    comp carry = 0;
764 +    comp *pa, *pb;
765 +
766 +    check(bia);
767 +    check(bib);
768 +
769 +    if (bia->size > bib->size)
770 +        n = bia->size;
771 +    else
772 +        n = bib->size;
773 +    more_comps(bia, n+1);
774 +    more_comps(bib, n);
775 +    pa = bia->comps;
776 +    pb = bib->comps;
777 +
778 +    do
779 +    {
780 +        comp  sl, rl, cy1;
781 +        sl = *pa + *pb++;
782 +        rl = sl + carry;
783 +        cy1 = sl < *pa;
784 +        carry = cy1 | (rl < sl);
785 +        *pa++ = rl;
786 +    } while (--n != 0);
787 +
788 +    *pa = carry;                  /* do overflow */
789 +    bi_free(ctx, bib);
790 +    return trim(bia);
791 +}
792 +
793 +/**
794 + * @brief Perform a subtraction operation between two bigints.
795 + * @param ctx [in]  The bigint session context.
796 + * @param bia [in]  A bigint.
797 + * @param bib [in]  Another bigint.
798 + * @param is_negative [out] If defined, indicates that the result was negative.
799 + * is_negative may be NULL.
800 + * @return The result of the subtraction. The result is always positive.
801 + */
802 +bigint *bi_subtract(BI_CTX *ctx, 
803 +        bigint *bia, bigint *bib, int *is_negative)
804 +{
805 +    int n = bia->size;
806 +    comp *pa, *pb, carry = 0;
807 +
808 +    check(bia);
809 +    check(bib);
810 +
811 +    more_comps(bib, n);
812 +    pa = bia->comps;
813 +    pb = bib->comps;
814 +
815 +    do 
816 +    {
817 +        comp sl, rl, cy1;
818 +        sl = *pa - *pb++;
819 +        rl = sl - carry;
820 +        cy1 = sl > *pa;
821 +        carry = cy1 | (rl > sl);
822 +        *pa++ = rl;
823 +    } while (--n != 0);
824 +
825 +    if (is_negative)    /* indicate a negative result */
826 +    {
827 +        *is_negative = carry;
828 +    }
829 +
830 +    bi_free(ctx, trim(bib));    /* put bib back to the way it was */
831 +    return trim(bia);
832 +}
833 +
834 +/**
835 + * Perform a multiply between a bigint an an (unsigned) integer
836 + */
837 +static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
838 +{
839 +    int j = 0, n = bia->size;
840 +    bigint *biR = alloc(ctx, n + 1);
841 +    comp carry = 0;
842 +    comp *r = biR->comps;
843 +    comp *a = bia->comps;
844 +
845 +    check(bia);
846 +
847 +    /* clear things to start with */
848 +    memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
849 +
850 +    do
851 +    {
852 +        long_comp tmp = *r + (long_comp)a[j]*b + carry;
853 +        *r++ = (comp)tmp;              /* downsize */
854 +        carry = (comp)(tmp >> COMP_BIT_SIZE);
855 +    } while (++j < n);
856 +
857 +    *r = carry;
858 +    bi_free(ctx, bia);
859 +    return trim(biR);
860 +}
861 +
862 +/**
863 + * @brief Does both division and modulo calculations. 
864 + *
865 + * Used extensively when doing classical reduction.
866 + * @param ctx [in]  The bigint session context.
867 + * @param u [in]    A bigint which is the numerator.
868 + * @param v [in]    Either the denominator or the modulus depending on the mode.
869 + * @param is_mod [n] Determines if this is a normal division (0) or a reduction
870 + * (1).
871 + * @return  The result of the division/reduction.
872 + */
873 +bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
874 +{
875 +    int n = v->size, m = u->size-n;
876 +    int j = 0, orig_u_size = u->size;
877 +    uint8_t mod_offset = ctx->mod_offset;
878 +    comp d;
879 +    bigint *quotient, *tmp_u;
880 +    comp q_dash;
881 +
882 +    check(u);
883 +    check(v);
884 +
885 +    /* if doing reduction and we are < mod, then return mod */
886 +    if (is_mod && bi_compare(v, u) > 0)
887 +    {
888 +        bi_free(ctx, v);
889 +        return u;
890 +    }
891 +
892 +       quotient = alloc(ctx, m+1);
893 +    tmp_u = alloc(ctx, n+1);
894 +    v = trim(v);        /* make sure we have no leading 0's */
895 +       // d = (comp)((long_comp)COMP_RADIX/(V1+1));
896 +       long_comp x = COMP_RADIX; do_div(x, V1+1); d = x;
897 +
898 +    /* clear things to start with */
899 +    memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
900 +
901 +    /* normalise */
902 +    if (d > 1)
903 +    {
904 +               u = bi_int_multiply(ctx, u, d);
905 +
906 +               if (is_mod)
907 +        {
908 +                       v = ctx->bi_normalised_mod[mod_offset];
909 +        }
910 +        else
911 +        {
912 +                       v = bi_int_multiply(ctx, v, d);
913 +        }
914 +       }
915 +
916 +       if (orig_u_size == u->size)  /* new digit position u0 */
917 +    {
918 +               more_comps(u, orig_u_size + 1);
919 +    }
920 +
921 +       do
922 +    {
923 +        /* get a temporary short version of u */
924 +               memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
925 +
926 +        /* calculate q' */
927 +        if (U(0) == V1)
928 +        {
929 +                       q_dash = COMP_RADIX-1;
930 +        }
931 +        else
932 +        {
933 +            //q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
934 +                       long_comp x = U(0)*COMP_RADIX + U(1); do_div(x, V1); q_dash = x;
935 +
936 +        }
937 +
938 +               if (v->size > 1 && V2)
939 +        {
940 +            /* we are implementing the following
941 +            if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) - 
942 +                    q_dash*V1)*COMP_RADIX) + U(2))) ... */
943 +                       comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) - 
944 +                                        (long_comp)q_dash*V1);
945 +                       if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
946 +            {
947 +                               q_dash--;
948 +            }
949 +        }
950 +
951 +        /* multiply and subtract */
952 +        if (q_dash)
953 +        {
954 +            int is_negative;
955 +                       tmp_u = bi_subtract(ctx, tmp_u, 
956 +                    bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
957 +                       more_comps(tmp_u, n+1);
958 +
959 +                       Q(j) = q_dash; 
960 +
961 +            /* add back */
962 +            if (is_negative)
963 +            {
964 +                               Q(j)--;
965 +                tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
966 +                /* lop off the carry */
967 +                tmp_u->size--;
968 +                v->size--;
969 +            }
970 +               }
971 +        else
972 +        {
973 +                       Q(j) = 0; 
974 +        }
975 +
976 +        /* copy back to u */
977 +               memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
978 +    } while (++j <= m);
979 +
980 +    bi_free(ctx, tmp_u);
981 +    bi_free(ctx, v);
982 +
983 +    if (is_mod)     /* get the remainder */
984 +    {
985 +               bi_free(ctx, quotient);
986 +               return bi_int_divide(ctx, trim(u), d);
987 +    }
988 +    else            /* get the quotient */
989 +    {
990 +               bi_free(ctx, u);
991 +               return trim(quotient);
992 +    }
993 +}
994 +
995 +/**
996 + * Perform an integer divide on a bigint.
997 + */
998 +static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom)
999 +{
1000 +    int i = biR->size - 1;
1001 +    long_comp r = 0;
1002 +
1003 +    check(biR);
1004 +
1005 +       do
1006 +    {
1007 +               r = (r<<COMP_BIT_SIZE) + biR->comps[i];
1008 +               //biR->comps[i] = (comp)(r / denom);
1009 +               long_comp x = r; do_div(x, denom); biR->comps[i] = x;
1010 +/*             while(r > denom)
1011 +               {
1012 +                       r -= denom;
1013 +               }*/
1014 +               r%=denom;
1015 +       } while (--i != 0);
1016 +
1017 +    return trim(biR);
1018 +}
1019 +
1020 +/**
1021 + * @brief Allow a binary sequence to be imported as a bigint.
1022 + * @param ctx [in]  The bigint session context.
1023 + * @param data [in] The data to be converted.
1024 + * @param size [in] The number of bytes of data.
1025 + * @return A bigint representing this data.
1026 + */
1027 +bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
1028 +{
1029 +    bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
1030 +    int i, j = 0, offset = 0;
1031 +
1032 +    memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
1033 +
1034 +    for (i = size-1; i >= 0; i--)
1035 +    {
1036 +        biR->comps[offset] += data[i] << (j*8);
1037 +
1038 +        if (++j == COMP_BYTE_SIZE)
1039 +        {
1040 +            j = 0;
1041 +            offset ++;
1042 +        }
1043 +    }
1044 +
1045 +    return trim(biR);
1046 +}
1047 +
1048 +/**
1049 + * @brief Take a bigint and convert it into a byte sequence. 
1050 + *
1051 + * This is useful after a decrypt operation.
1052 + * @param ctx [in]  The bigint session context.
1053 + * @param x [in]  The bigint to be converted.
1054 + * @param data [out] The converted data as a byte stream.
1055 + * @param size [in] The maximum size of the byte stream. Unused bytes will be
1056 + * zeroed.
1057 + */
1058 +void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
1059 +{
1060 +    int i, j, k = size-1;
1061 +
1062 +    check(x);
1063 +    memset(data, 0, size);  /* ensure all leading 0's are cleared */
1064 +
1065 +    for (i = 0; i < x->size; i++)
1066 +    {
1067 +        for (j = 0; j < COMP_BYTE_SIZE; j++)
1068 +        {
1069 +            comp mask = 0xff << (j*8);
1070 +            int num = (x->comps[i] & mask) >> (j*8);
1071 +            data[k--] = num;
1072 +
1073 +            if (k < 0)
1074 +            {
1075 +                break;
1076 +            }
1077 +        }
1078 +    }
1079 +
1080 +    bi_free(ctx, x);
1081 +}
1082 +
1083 +/**
1084 + * @brief Pre-calculate some of the expensive steps in reduction. 
1085 + *
1086 + * This function should only be called once (normally when a session starts).
1087 + * When the session is over, bi_free_mod() should be called. bi_mod_power()
1088 + * relies on this function being called.
1089 + * @param ctx [in]  The bigint session context.
1090 + * @param bim [in]  The bigint modulus that will be used.
1091 + * @param mod_offset [in] There are three moduluii that can be stored - the
1092 + * standard modulus, and it's two primes p and q. This offset refers to which
1093 + * modulus we are referring to.
1094 + * @see bi_free_mod(), bi_mod_power().
1095 + */
1096 +void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
1097 +{
1098 +    int k = bim->size;
1099 +       comp d;
1100 +//    comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
1101 +       long_comp x = COMP_RADIX; do_div(x, bim->comps[k-1]+1); d = x;
1102 +
1103 +    ctx->bi_mod[mod_offset] = bim;
1104 +    bi_permanent(ctx->bi_mod[mod_offset]);
1105 +    ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
1106 +    bi_permanent(ctx->bi_normalised_mod[mod_offset]);
1107 +}
1108 +
1109 +/**
1110 + * @brief Used when cleaning various bigints at the end of a session.
1111 + * @param ctx [in]  The bigint session context.
1112 + * @param mod_offset [in] The offset to use.
1113 + * @see bi_set_mod().
1114 + */
1115 +void bi_free_mod(BI_CTX *ctx, int mod_offset)
1116 +{
1117 +    bi_depermanent(ctx->bi_mod[mod_offset]);
1118 +    bi_free(ctx, ctx->bi_mod[mod_offset]);
1119 +    bi_depermanent(ctx->bi_normalised_mod[mod_offset]); 
1120 +    bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
1121 +}
1122 +
1123 +/** 
1124 + * Perform a standard multiplication between two bigints.
1125 + */
1126 +static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
1127 +{
1128 +    int i, j, i_plus_j, n = bia->size, t = bib->size;
1129 +    bigint *biR = alloc(ctx, n + t);
1130 +    comp *sr = biR->comps;
1131 +    comp *sa = bia->comps;
1132 +    comp *sb = bib->comps;
1133 +
1134 +    check(bia);
1135 +    check(bib);
1136 +
1137 +    /* clear things to start with */
1138 +    memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
1139 +    i = 0;
1140 +
1141 +    do 
1142 +    {
1143 +        comp carry = 0;
1144 +        comp b = *sb++;
1145 +        i_plus_j = i;
1146 +        j = 0;
1147 +
1148 +        do
1149 +        {
1150 +            long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
1151 +            sr[i_plus_j++] = (comp)tmp;              /* downsize */
1152 +            carry = (comp)(tmp >> COMP_BIT_SIZE);
1153 +        } while (++j < n);
1154 +
1155 +        sr[i_plus_j] = carry;
1156 +    } while (++i < t);
1157 +
1158 +    bi_free(ctx, bia);
1159 +    bi_free(ctx, bib);
1160 +    return trim(biR);
1161 +}
1162 +
1163 +/**
1164 + * @brief Perform a multiplication operation between two bigints.
1165 + * @param ctx [in]  The bigint session context.
1166 + * @param bia [in]  A bigint.
1167 + * @param bib [in]  Another bigint.
1168 + * @return The result of the multiplication.
1169 + */
1170 +bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
1171 +{
1172 +    check(bia);
1173 +    check(bib);
1174 +
1175 +    return regular_multiply(ctx, bia, bib);
1176 +}
1177 +
1178 +
1179 +/**
1180 + * @brief Compare two bigints.
1181 + * @param bia [in]  A bigint.
1182 + * @param bib [in]  Another bigint.
1183 + * @return -1 if smaller, 1 if larger and 0 if equal.
1184 + */
1185 +int bi_compare(bigint *bia, bigint *bib)
1186 +{
1187 +    int r, i;
1188 +
1189 +    check(bia);
1190 +    check(bib);
1191 +
1192 +    if (bia->size > bib->size)
1193 +        r = 1;
1194 +    else if (bia->size < bib->size)
1195 +        r = -1;
1196 +    else
1197 +    {
1198 +        comp *a = bia->comps; 
1199 +        comp *b = bib->comps; 
1200 +
1201 +        /* Same number of components.  Compare starting from the high end
1202 +         * and working down. */
1203 +        r = 0;
1204 +        i = bia->size - 1;
1205 +
1206 +        do 
1207 +        {
1208 +            if (a[i] > b[i])
1209 +            { 
1210 +                r = 1;
1211 +                break; 
1212 +            }
1213 +            else if (a[i] < b[i])
1214 +            { 
1215 +                r = -1;
1216 +                break; 
1217 +            }
1218 +        } while (--i >= 0);
1219 +    }
1220 +
1221 +    return r;
1222 +}
1223 +
1224 +/**
1225 + * Allocate and zero more components.  Does not consume bi. 
1226 + */
1227 +static void more_comps(bigint *bi, int n)
1228 +{
1229 +    if (n > bi->max_comps)
1230 +    {
1231 +        if ((bi->max_comps * 2) > n) {
1232 +           bi->max_comps = bi->max_comps * 2;
1233 +       } else {
1234 +           bi->max_comps = n;
1235 +       }
1236 +        bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
1237 +    }
1238 +
1239 +    if (n > bi->size)
1240 +    {
1241 +        memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
1242 +    }
1243 +
1244 +    bi->size = n;
1245 +}
1246 +
1247 +/*
1248 + * Make a new empty bigint. It may just use an old one if one is available.
1249 + * Otherwise get one of the heap.
1250 + */
1251 +static bigint *alloc(BI_CTX *ctx, int size)
1252 +{
1253 +    bigint *biR;
1254 +
1255 +    /* Can we recycle an old bigint? */
1256 +    if (ctx->free_list != NULL)
1257 +    {
1258 +        biR = ctx->free_list;
1259 +        ctx->free_list = biR->next;
1260 +        ctx->free_count--;
1261 +        if (biR->refs != 0)
1262 +        {
1263 +            printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1264 +                       printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1265 +                       printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1266 +                       return 0;
1267 +               }
1268 +
1269 +        more_comps(biR, size);
1270 +    }
1271 +    else
1272 +    {
1273 +        /* No free bigints available - create a new one. */
1274 +        biR = (bigint *)malloc(sizeof(bigint));
1275 +        biR->comps = (comp*) malloc(size * COMP_BYTE_SIZE);
1276 +        biR->max_comps = size;  /* give some space to spare */
1277 +    }
1278 +
1279 +    biR->size = size;
1280 +    biR->refs = 1;
1281 +    biR->next = NULL;
1282 +    ctx->active_count++;
1283 +    return biR;
1284 +}
1285 +
1286 +/*
1287 + * Work out the highest '1' bit in an exponent. Used when doing sliding-window
1288 + * exponentiation.
1289 + */
1290 +static int find_max_exp_index(bigint *biexp)
1291 +{
1292 +    int i = COMP_BIT_SIZE-1;
1293 +    comp shift = COMP_RADIX/2;
1294 +    comp test = biexp->comps[biexp->size-1];    /* assume no leading zeroes */
1295 +
1296 +    check(biexp);
1297 +
1298 +    do
1299 +    {
1300 +        if (test & shift)
1301 +        {
1302 +            return i+(biexp->size-1)*COMP_BIT_SIZE;
1303 +        }
1304 +
1305 +        shift >>= 1;
1306 +    } while (--i != 0);
1307 +
1308 +    return -1;      /* error - must have been a leading 0 */
1309 +}
1310 +
1311 +/*
1312 + * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
1313 + * exponentiation.
1314 + */
1315 +static int exp_bit_is_one(bigint *biexp, int offset)
1316 +{
1317 +    comp test = biexp->comps[offset / COMP_BIT_SIZE];
1318 +    int num_shifts = offset % COMP_BIT_SIZE;
1319 +    comp shift = 1;
1320 +    int i;
1321 +
1322 +    check(biexp);
1323 +
1324 +    for (i = 0; i < num_shifts; i++)
1325 +    {
1326 +        shift <<= 1;
1327 +    }
1328 +
1329 +    return test & shift;
1330 +}
1331 +
1332 +/*
1333 + * Delete any leading 0's (and allow for 0).
1334 + */
1335 +static bigint *trim(bigint *bi)
1336 +{
1337 +    check(bi);
1338 +
1339 +    while (bi->comps[bi->size-1] == 0 && bi->size > 1)
1340 +    {
1341 +        bi->size--;
1342 +    }
1343 +
1344 +    return bi;
1345 +}
1346 +
1347 +/**
1348 + * @brief Perform a modular exponentiation.
1349 + *
1350 + * This function requires bi_set_mod() to have been called previously. This is 
1351 + * one of the optimisations used for performance.
1352 + * @param ctx [in]  The bigint session context.
1353 + * @param bi  [in]  The bigint on which to perform the mod power operation.
1354 + * @param biexp [in] The bigint exponent.
1355 + * @see bi_set_mod().
1356 + */
1357 +bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
1358 +{
1359 +    int i = find_max_exp_index(biexp), j, window_size = 1;
1360 +    bigint *biR = int_to_bi(ctx, 1);
1361 +
1362 +       check(bi);
1363 +       check(biexp);
1364 +
1365 +    ctx->g = (bigint **)malloc(sizeof(bigint *));
1366 +    ctx->g[0] = bi_clone(ctx, bi);
1367 +    ctx->window = 1;
1368 +       bi_permanent(ctx->g[0]);
1369 +
1370 +       /* if sliding-window is off, then only one bit will be done at a time and
1371 +     * will reduce to standard left-to-right exponentiation */
1372 +    do
1373 +    {
1374 +               if (exp_bit_is_one(biexp, i))
1375 +        {
1376 +            int l = i-window_size+1;
1377 +            int part_exp = 0;
1378 +
1379 +                       if (l < 0)  /* LSB of exponent will always be 1 */
1380 +            {
1381 +                               l = 0;
1382 +            }
1383 +            else
1384 +            {
1385 +                               while (exp_bit_is_one(biexp, l) == 0)
1386 +                {
1387 +                                       l++;    /* go back up */
1388 +                }
1389 +            }
1390 +
1391 +            /* build up the section of the exponent */
1392 +            for (j = i; j >= l; j--)
1393 +            {
1394 +                               biR = bi_residue(ctx, bi_square(ctx, biR));
1395 +                if (exp_bit_is_one(biexp, j))
1396 +                    part_exp++;
1397 +
1398 +                if (j != l)
1399 +                    part_exp <<= 1;
1400 +            }
1401 +
1402 +            part_exp = (part_exp-1)/2;  /* adjust for array */
1403 +            biR = bi_residue(ctx, 
1404 +                    bi_multiply(ctx, biR, ctx->g[part_exp]));
1405 +                       i = l-1;
1406 +        }
1407 +        else    /* square it */
1408 +        {
1409 +                       biR = bi_residue(ctx, bi_square(ctx, biR));
1410 +                       i--;
1411 +        }
1412 +       } while (i >= 0);
1413 +     
1414 +    /* cleanup */
1415 +       for (i = 0; i < ctx->window; i++)
1416 +    {
1417 +               bi_depermanent(ctx->g[i]);
1418 +        bi_free(ctx, ctx->g[i]);
1419 +    }
1420 +
1421 +    free(ctx->g);
1422 +       bi_free(ctx, bi);
1423 +       bi_free(ctx, biexp);
1424 +       return biR;
1425 +}
1426 +
1427 +/** @} */
1428 --- /dev/null
1429 +++ b/net/rsa/bigint.h
1430 @@ -0,0 +1,73 @@
1431 +/*
1432 + *  Copyright(C) 2006
1433 + *
1434 + *  This library is free software; you can redistribute it and/or modify
1435 + *  it under the terms of the GNU Lesser General Public License as published by
1436 + *  the Free Software Foundation; either version 2 of the License, or
1437 + *  (at your option) any later version.
1438 + *
1439 + *  This library is distributed in the hope that it will be useful,
1440 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1441 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1442 + *  GNU Lesser General Public License for more details.
1443 + *
1444 + *  You should have received a copy of the GNU Lesser General Public License
1445 + *  along with this library; if not, write to the Free Software
1446 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1447 + *
1448 + * Trimmed down from axTLS
1449 + * 
1450 + * $Id: bigint.h 392 2007-06-25 16:24:51Z pablo.martin $
1451 + *
1452 + */
1453 +
1454 +#ifndef BIGINT_HEADER
1455 +#define BIGINT_HEADER
1456 +
1457 +#define CONFIG_BIGINT_CLASSICAL 1
1458 +
1459 +#define SOCKET_READ(A,B,C)      read(A,B,C)
1460 +#define SOCKET_WRITE(A,B,C)     write(A,B,C)
1461 +#define SOCKET_CLOSE(A)         close(A)
1462 +#define TTY_FLUSH()
1463 +
1464 +#include "bigint_impl.h"
1465 +
1466 +#ifndef CONFIG_BIGINT_CHECK_ON
1467 +#define check(A)                /**< disappears in normal production mode */
1468 +#endif
1469 +BI_CTX *bi_initialize(void);
1470 +void bi_terminate(BI_CTX *ctx);
1471 +void bi_permanent(bigint *bi);
1472 +void bi_depermanent(bigint *bi);
1473 +void bi_free(BI_CTX *ctx, bigint *bi);
1474 +bigint *bi_copy(bigint *bi);
1475 +bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
1476 +void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size);
1477 +bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len);
1478 +bigint *int_to_bi(BI_CTX *ctx, comp i);
1479 +
1480 +/* the functions that actually do something interesting */
1481 +bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib);
1482 +bigint *bi_subtract(BI_CTX *ctx, bigint *bia, 
1483 +        bigint *bib, int *is_negative);
1484 +bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod);
1485 +bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib);
1486 +bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp);
1487 +bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp);
1488 +int bi_compare(bigint *bia, bigint *bib);
1489 +void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset);
1490 +void bi_free_mod(BI_CTX *ctx, int mod_offset);
1491 +
1492 +/**
1493 + * @def bi_mod
1494 + * Find the residue of B. bi_set_mod() must be called before hand.
1495 + */
1496 +#define bi_mod(A, B)      bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1)
1497 +
1498 +#define bi_residue(A, B)         bi_mod(A, B)
1499 +
1500 +#define bi_square(A, B)     bi_multiply(A, bi_copy(B), B)
1501 +
1502 +#endif
1503 +
1504 --- /dev/null
1505 +++ b/net/rsa/bigint_impl.h
1506 @@ -0,0 +1,109 @@
1507 +/*
1508 + *  Copyright(C) 2006
1509 + *
1510 + *  This library is free software; you can redistribute it and/or modify
1511 + *  it under the terms of the GNU Lesser General Public License as published by
1512 + *  the Free Software Foundation; either version 2.1 of the License, or
1513 + *  (at your option) any later version.
1514 + *
1515 + *  This library is distributed in the hope that it will be useful,
1516 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1517 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1518 + *  GNU Lesser General Public License for more details.
1519 + *
1520 + *  You should have received a copy of the GNU Lesser General Public License
1521 + *  along with this library; if not, write to the Free Software
1522 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1523 + */
1524 +
1525 +#ifndef BIGINT_IMPL_HEADER
1526 +#define BIGINT_IMPL_HEADER
1527 +
1528 +#include <linux/types.h>
1529 +#include <common.h>
1530 +
1531 +/* Maintain a number of precomputed variables when doing reduction */
1532 +#define BIGINT_M_OFFSET     0    /**< Normal modulo offset. */
1533 +#ifdef CONFIG_BIGINT_CRT
1534 +#define BIGINT_P_OFFSET     1    /**< p modulo offset. */
1535 +#define BIGINT_Q_OFFSET     2    /**< q module offset. */
1536 +#define BIGINT_NUM_MODS     3    /**< The number of modulus constants used. */
1537 +#else
1538 +#define BIGINT_NUM_MODS     1    
1539 +#endif
1540 +
1541 +/* Architecture specific functions for big ints */
1542 +// #ifdef WIN32
1543 +// #define COMP_RADIX          4294967296i64         
1544 +// #define COMP_BIG_MSB        0x8000000000000000i64 
1545 +// #else
1546 +#define COMP_RADIX          4294967296ULL         /**< Max component + 1 */
1547 +#define COMP_BIG_MSB        0x8000000000000000ULL /**< (Max dbl comp + 1)/ 2 */
1548 +//#endif
1549 +#define COMP_BIT_SIZE       32  /**< Number of bits in a component. */
1550 +#define COMP_BYTE_SIZE      4   /**< Number of bytes in a component. */
1551 +#define COMP_NUM_NIBBLES    8   /**< Used For diagnostics only. */
1552 +
1553 +typedef uint32_t comp;         /**< A single precision component. */
1554 +typedef uint64_t long_comp;     /**< A double precision component. */
1555 +typedef int64_t slong_comp;     /**< A signed double precision component. */
1556 +
1557 +/**
1558 + * @struct  _bigint
1559 + * @brief A big integer basic object
1560 + */
1561 +struct _bigint
1562 +{
1563 +    struct _bigint* next;       /**< The next bigint in the cache. */
1564 +    short size;                 /**< The number of components in this bigint. */
1565 +    short max_comps;            /**< The heapsize allocated for this bigint */
1566 +    int refs;                   /**< An internal reference count. */
1567 +    comp* comps;                /**< A ptr to the actual component data */
1568 +};
1569 +
1570 +typedef struct _bigint bigint;  /**< An alias for _bigint */
1571 +
1572 +/**
1573 + * Maintains the state of the cache, and a number of variables used in 
1574 + * reduction.
1575 + */
1576 +typedef struct /**< A big integer "session" context. */
1577 +{
1578 +    bigint *active_list;                    /**< Bigints currently used. */
1579 +    bigint *free_list;                      /**< Bigints not used. */
1580 +    bigint *bi_radix;                       /**< The radix used. */
1581 +    bigint *bi_mod[BIGINT_NUM_MODS];        /**< modulus */
1582 +
1583 +#if defined(CONFIG_BIGINT_MONTGOMERY)
1584 +    bigint *bi_RR_mod_m[BIGINT_NUM_MODS];   /**< R^2 mod m */
1585 +    bigint *bi_R_mod_m[BIGINT_NUM_MODS];    /**< R mod m */
1586 +    comp N0_dash[BIGINT_NUM_MODS];
1587 +#elif defined(CONFIG_BIGINT_BARRETT)
1588 +    bigint *bi_mu[BIGINT_NUM_MODS];         /**< Storage for mu */
1589 +#endif
1590 +    bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */
1591 +    bigint **g;                 /**< Used by sliding-window. */
1592 +    int window;                 /**< The size of the sliding window */
1593 +
1594 +    int active_count;           /**< Number of active bigints. */
1595 +    int free_count;             /**< Number of free bigints. */
1596 +
1597 +#ifdef CONFIG_BIGINT_MONTGOMERY
1598 +    uint8_t use_classical;      /**< Use classical reduction. */
1599 +#endif
1600 +    uint8_t mod_offset;         /**< The mod offset we are using */
1601 +} BI_CTX;
1602 +
1603 +#if 0
1604 +#define max(a,b) ((a)>(b)?(a):(b))  /**< Find the maximum of 2 numbers. */
1605 +#define min(a,b) ((a)<(b)?(a):(b))  /**< Find the minimum of 2 numbers. */
1606 +#endif
1607 +
1608 +#define PERMANENT           0x7FFF55AA  /**< A magic number for permanents. */
1609 +
1610 +#define V1      v->comps[v->size-1]                 /**< v1 for division */
1611 +#define V2      v->comps[v->size-2]                 /**< v2 for division */
1612 +#define U(j)    tmp_u->comps[tmp_u->size-j-1]       /**< uj for division */
1613 +#define Q(j)    quotient->comps[quotient->size-j-1] /**< qj for division */
1614 +
1615 +#endif
1616 --- /dev/null
1617 +++ b/net/rsa/div64.h
1618 @@ -0,0 +1,113 @@
1619 +/*
1620 + * Copyright (C) 2000, 2004  Maciej W. Rozycki
1621 + * Copyright (C) 2003 Ralf Baechle
1622 + *
1623 + * This file is subject to the terms and conditions of the GNU General Public
1624 + * License.  See the file "COPYING" in the main directory of this archive
1625 + * for more details.
1626 + */
1627 +#ifndef _ASM_DIV64_H
1628 +#define _ASM_DIV64_H
1629 +
1630 +#if (_MIPS_SZLONG == 32)
1631 +
1632 +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
1633 +#define GCC_REG_ACCUM "$0"
1634 +#else
1635 +#define GCC_REG_ACCUM "accum"
1636 +#endif
1637 +
1638 +
1639 +//#include <asm/compiler.h>
1640 +
1641 +/*
1642 + * No traps on overflows for any of these...
1643 + */
1644 +
1645 +#define do_div64_32(res, high, low, base) ({ \
1646 +       unsigned long __quot, __mod; \
1647 +       unsigned long __cf, __tmp, __tmp2, __i; \
1648 +       \
1649 +       __asm__(".set   push\n\t" \
1650 +               ".set   noat\n\t" \
1651 +               ".set   noreorder\n\t" \
1652 +               "move   %2, $0\n\t" \
1653 +               "move   %3, $0\n\t" \
1654 +               "b      1f\n\t" \
1655 +               " li    %4, 0x21\n" \
1656 +               "0:\n\t" \
1657 +               "sll    $1, %0, 0x1\n\t" \
1658 +               "srl    %3, %0, 0x1f\n\t" \
1659 +               "or     %0, $1, %5\n\t" \
1660 +               "sll    %1, %1, 0x1\n\t" \
1661 +               "sll    %2, %2, 0x1\n" \
1662 +               "1:\n\t" \
1663 +               "bnez   %3, 2f\n\t" \
1664 +               " sltu  %5, %0, %z6\n\t" \
1665 +               "bnez   %5, 3f\n" \
1666 +               "2:\n\t" \
1667 +               " addiu %4, %4, -1\n\t" \
1668 +               "subu   %0, %0, %z6\n\t" \
1669 +               "addiu  %2, %2, 1\n" \
1670 +               "3:\n\t" \
1671 +               "bnez   %4, 0b\n\t" \
1672 +               " srl   %5, %1, 0x1f\n\t" \
1673 +               ".set   pop" \
1674 +               : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
1675 +                 "=&r" (__i), "=&r" (__tmp2) \
1676 +               : "Jr" (base), "0" (high), "1" (low)); \
1677 +       \
1678 +       (res) = __quot; \
1679 +       __mod; })
1680 +
1681 +#define do_div(n, base) ({ \
1682 +       unsigned long long __quot; \
1683 +       unsigned long __mod; \
1684 +       unsigned long long __div; \
1685 +       unsigned long __upper, __low, __high, __base; \
1686 +       \
1687 +       __div = (n); \
1688 +       __base = (base); \
1689 +       \
1690 +       __high = __div >> 32; \
1691 +       __low = __div; \
1692 +       __upper = __high; \
1693 +       \
1694 +       if (__high) \
1695 +               __asm__("divu   $0, %z2, %z3" \
1696 +                       : "=h" (__upper), "=l" (__high) \
1697 +                       : "Jr" (__high), "Jr" (__base) \
1698 +                       : GCC_REG_ACCUM); \
1699 +       \
1700 +       __mod = do_div64_32(__low, __upper, __low, __base); \
1701 +       \
1702 +       __quot = __high; \
1703 +       __quot = __quot << 32 | __low; \
1704 +       (n) = __quot; \
1705 +       __mod; })
1706 +#endif /* (_MIPS_SZLONG == 32) */
1707 +
1708 +#if (_MIPS_SZLONG == 64)
1709 +
1710 +/*
1711 + * Hey, we're already 64-bit, no
1712 + * need to play games..
1713 + */
1714 +#define do_div(n, base) ({ \
1715 +       unsigned long __quot; \
1716 +       unsigned int __mod; \
1717 +       unsigned long __div; \
1718 +       unsigned int __base; \
1719 +       \
1720 +       __div = (n); \
1721 +       __base = (base); \
1722 +       \
1723 +       __mod = __div % __base; \
1724 +       __quot = __div / __base; \
1725 +       \
1726 +       (n) = __quot; \
1727 +       __mod; })
1728 +
1729 +#endif /* (_MIPS_SZLONG == 64) */
1730 +
1731 +#endif /* _ASM_DIV64_H */
1732 --- /dev/null
1733 +++ b/net/rsa/dump_key.c
1734 @@ -0,0 +1,29 @@
1735 +#include <stdio.h>
1736 +#include <stdlib.h>
1737 +#include <sys/types.h>
1738 +#include <sys/stat.h>
1739 +#include <unistd.h>
1740 +
1741 +int main(int argc, char **argv)
1742 +{
1743 +       FILE *fp = fopen("public_fon_rsa_key_6.pem", "r");
1744 +       struct stat s;
1745 +       unsigned char *b;
1746 +       int i;
1747 +       if(!fp)
1748 +               return 1;
1749 +       stat("public_fon_rsa_key_6.pem", &s);
1750 +       b = malloc(s.st_size);
1751 +       fread(b, s.st_size, 1, fp);
1752 +       fclose(fp);
1753 +       printf("unsigned char public_key[] = {\n\t");
1754 +       for(i = 0;i < s.st_size; i++)
1755 +       {
1756 +               printf("0x%02X,", b[i]);
1757 +               if(i%16 == 15)
1758 +                       printf("\n\t");
1759 +       }
1760 +       printf("};\n");
1761 +//     printf("\n%d %d\n", i, s.st_size);
1762 +       return 0;
1763 +}
1764 --- /dev/null
1765 +++ b/net/rsa/foncheckrsa.c
1766 @@ -0,0 +1,79 @@
1767 +/*
1768 + * RSA + RIPEMD160 signature verification command
1769 + *
1770 + * Copyright (C) 2007 FON Wireless Ltd.
1771 + *
1772 + * This program is free software; you can redistribute it and/or
1773 + * modify it under the terms of the GNU General Public License
1774 + * as published by the Free Software Foundation; either version 2
1775 + * of the License, or (at your option) any later version.
1776 + *
1777 + * This program is distributed in the hope that it will be useful,
1778 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1779 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1780 + * GNU General Public License for more details.
1781 + *
1782 + * You should have received a copy of the GNU General Public License
1783 + * along with this program; if not, write to the Free Software
1784 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1785 + *
1786 + * Created: 20060728 Pablo Martín Medrano <pablo@fon.com>
1787 + *
1788 + * $Id: foncheckrsa.c 332 2007-05-02 09:45:54Z pablo.martin $
1789 + */
1790 +#include <stdio.h>
1791 +#include <stdlib.h>
1792 +#include <sys/types.h>
1793 +#include <sys/stat.h>
1794 +#include <fcntl.h>
1795 +#include <string.h>
1796 +#include <errno.h>
1797 +#include <unistd.h>
1798 +#include "fonrsa.h"
1799 +
1800 +int main(int argc, char **argv)
1801 +{
1802 +       int fd, i;
1803 +       FONRSA_ERROR fonrsa_error;
1804 +       void *handle;
1805 +
1806 +       if (argc != 4) {
1807 +               fprintf(stderr, " Usage: foncheckrsa [public_key.der] [signature] [file]\n");
1808 +               fprintf(stderr, "  Pablo Martín Medrano <pablo@fon.com>\n");
1809 +               fprintf(stderr, "  RIPEMD-160 software written by Antoon Bosselaers,\n");
1810 +               fprintf(stderr, "  available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.\n");
1811 +               fprintf(stderr, "  Uses the axTLS library bigint implementation (libfonrsa)\n");
1812 +               fprintf(stderr, "  http://www.leroc.com.au/axTLS/\n");
1813 +               return -1;
1814 +       }
1815 +       /* Check the existence of input files */
1816 +       for (i = 1; i < 4; i++) {
1817 +               if ((fd = open(argv[i], O_RDONLY)) == -1) {
1818 +                       fprintf(stderr, "Error: opening \"%s\": %s\n", argv[i],
1819 +                               strerror(errno));
1820 +                       fprintf(stderr, "Bailing out...");
1821 +                       exit(-2);
1822 +               }
1823 +               close(fd);
1824 +       }
1825 +       handle = FR_init(argv[1]);
1826 +       if (handle == NULL) {
1827 +               printf("Error loading keys in %s\n", argv[1]);
1828 +               return 1;
1829 +       }
1830 +       fonrsa_error = FR_verify_file(handle, argv[3], argv[2]);
1831 +       FR_end(handle);
1832 +       switch (fonrsa_error) {
1833 +               case FONRSA_OK:
1834 +                       printf("Verified OK\n");
1835 +                       return 0;
1836 +               case FONRSA_VERIFICATION_FAILURE:
1837 +                       printf("Verification failure\n");
1838 +                       return 1;
1839 +               default:
1840 +                       printf("Verification error\n");
1841 +                       return -1;
1842 +       }
1843 +       return -1;
1844 +}
1845 +
1846 --- /dev/null
1847 +++ b/net/rsa/fonrsa.c
1848 @@ -0,0 +1,584 @@
1849 +/*
1850 + * FONSM RSA handling library
1851 + *
1852 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
1853 + *
1854 + * This library is free software; you can redistribute it and/or modify
1855 + * it under the terms of the GNU Lesser General Public License as published by
1856 + * the Free Software Foundation; either version 2 of the License, or
1857 + * (at your option) any later version.
1858 + *
1859 + * This library is distributed in the hope that it will be useful,
1860 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1861 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1862 + * GNU Lesser General Public License for more details.
1863 + *
1864 + * You should have received a copy of the GNU Lesser General Public License
1865 + * along with this library; if not, write to the Free Software
1866 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1867 + *
1868 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
1869 + *
1870 + * Based on axTLS
1871 + *
1872 + * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
1873 + */
1874 +#include <sys/types.h>
1875 +#include <stdlib.h>
1876 +#include <stdio.h>
1877 +#include <string.h>
1878 +#include <sys/types.h>
1879 +#include <sys/stat.h>
1880 +#include <fcntl.h>
1881 +#include <unistd.h>
1882 +#include <errno.h>
1883 +#include "rmd160.h"
1884 +#include "bigint.h"
1885 +#include "fonrsa.h"
1886 +#include "base64.h"
1887 +
1888 +typedef struct {
1889 +       uint8_t *buffer;
1890 +       size_t size;
1891 +} DER_key;
1892 +
1893 +typedef struct {
1894 +       bigint *m;              /* modulus */
1895 +       bigint *e;              /* public exponent */
1896 +       int num_octets;
1897 +       BI_CTX *bi_ctx;         /* big integer handle */
1898 +} RSA_parameters;
1899 +
1900 +typedef struct {
1901 +       DER_key *derkey;
1902 +       RSA_parameters *rsaparms;
1903 +} RSA;
1904 +
1905 +static uint8_t *CH_load_raw_file(char *filename, size_t *size);
1906 +static DER_key *CH_load_der_key(char *filename);
1907 +static void CH_free_der_key(DER_key *key);
1908 +static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters);
1909 +void CH_pub_key_new(RSA_parameters **rsa_parameters, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len);
1910 +int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out);
1911 +byte *RMDbinary(char *fname);
1912 +int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file);
1913 +static unsigned char *load_file_in_buffer(char *path, int *size);
1914 +static int save_file_from_buffer(char *path, unsigned char *buffer, int size);
1915 +int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer);
1916 +
1917 +#define RMDsize 160            /* A RIPEMD-160 hash has 160 bits */
1918 +
1919 +/*
1920 + * returns RMD(message in file fname) fname is read as binary data.
1921 + * non-reentrant
1922 + */
1923 +byte *RMDbinary(char *fname)
1924 +{
1925 +       FILE *mf;               /* pointer to file <fname>      */
1926 +       byte data[1024];        /* contains current mess. block */
1927 +       dword nbytes;           /* length of this block         */
1928 +       dword MDbuf[RMDsize / 32];      /* contains (A, B, C, D(, E))   */
1929 +       static byte hashcode[RMDsize / 8];      /* for final hash-value         */
1930 +       dword X[16];            /* current 16-word chunk        */
1931 +       unsigned int i, j;      /* counters                     */
1932 +       dword length[2];        /* length in bytes of message   */
1933 +       dword offset;           /* # of unprocessed bytes at    */
1934 +       /*          call of MDfinish    */
1935 +
1936 +       /* initialize */
1937 +       if ((mf = fopen(fname, "rb")) == NULL) {
1938 +               fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n",
1939 +                       fname);
1940 +               exit(1);
1941 +       }
1942 +       MDinit(MDbuf);
1943 +       length[0] = 0;
1944 +       length[1] = 0;
1945 +       while ((nbytes = fread(data, 1, 1024, mf)) != 0) {
1946 +               /* process all complete blocks */
1947 +               for (i = 0; i < (nbytes >> 6); i++) {
1948 +                       for (j = 0; j < 16; j++)
1949 +                               X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
1950 +                       compress(MDbuf, X);
1951 +               }
1952 +               /* update length[] */
1953 +               if (length[0] + nbytes < length[0])
1954 +                       length[1]++;    /* overflow to msb of length */
1955 +               length[0] += nbytes;
1956 +       }
1957 +       /* finish: */
1958 +       offset = length[0] & 0x3C0;     /* extract bytes 6 to 10 inclusive */
1959 +       MDfinish(MDbuf, data + offset, length[0], length[1]);
1960 +
1961 +       for (i = 0; i < RMDsize / 8; i += 4) {
1962 +               hashcode[i] = MDbuf[i >> 2];
1963 +               hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
1964 +               hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
1965 +               hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
1966 +       }
1967 +       fclose(mf);
1968 +
1969 +       return (byte *) hashcode;
1970 +}
1971 +byte *RMDbinary_buffer(char *buffer, int size_buffer)
1972 +{
1973 +       return NULL;
1974 +}
1975 +
1976 +/*
1977 + * Extracts the RMD 160 hash from the signature file
1978 + */
1979 +int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file)
1980 +{
1981 +       RSA_parameters *rsa_parameters;
1982 +       DER_key *derkey;
1983 +       uint8_t *signature;
1984 +       size_t signature_size;
1985 +       uint8_t *decrypted;
1986 +
1987 +       signature = CH_load_raw_file(signature_file, &signature_size);
1988 +       if ((signature == NULL)||(signature_size != 512)) {
1989 +               fprintf(stderr, "Error: Loading signature key '%s'\n", signature_file);
1990 +               exit(-1);
1991 +       }
1992 +       derkey = CH_load_der_key(public_key_file);
1993 +       if (derkey == NULL) {
1994 +               fprintf(stderr, "Error: opening DER key file '%s'\n", public_key_file);
1995 +               exit(-1);
1996 +       }
1997 +       if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
1998 +               fprintf(stderr, "Error: Extracting public key from DER file\n");
1999 +               exit(-1);
2000 +       }
2001 +       CH_free_der_key(derkey);
2002 +       if (rsa_parameters->num_octets != 512)
2003 +               fprintf(stderr, "Error: The RSA public key size is not 4096 bits %d\n", rsa_parameters->num_octets);
2004 +       decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
2005 +       if (CH_decrypt(rsa_parameters, signature, decrypted)) {
2006 +               fprintf(stderr, "Error: Decrypting signature\n");
2007 +               exit(-1);
2008 +       }
2009 +       memcpy(hash, decrypted + 492, 20);              
2010 +       free(decrypted);
2011 +       free(signature);
2012 +       return 0;
2013 +}
2014 +
2015 +/*
2016 + * Decrypts the signature buffer using the rsa public key loaded
2017 + */
2018 +int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
2019 +{
2020 +       bigint *dat_bi;
2021 +       bigint *decrypted_bi;
2022 +       int byte_size;
2023 +
2024 +       byte_size = rsa->num_octets; 
2025 +       dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
2026 +       rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
2027 +       bi_copy(rsa->m);
2028 +       decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
2029 +       bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
2030 +       return 0;
2031 +}
2032 +/*
2033 + * Loads a file in a uint8_t buffer
2034 + */
2035 +static uint8_t *CH_load_raw_file(char *filename, size_t *size)
2036 +{
2037 +       struct stat st;
2038 +       int fd;
2039 +       ssize_t br;
2040 +       uint8_t *ret;
2041 +
2042 +       if ((stat(filename, &st)) == -1)
2043 +               return NULL;
2044 +       if ((ret = (uint8_t *)malloc(st.st_size)) == NULL)
2045 +               return NULL;
2046 +       fd = open(filename, O_RDONLY);
2047 +       if (fd == -1) {
2048 +               free(ret);
2049 +               return NULL;
2050 +       }
2051 +       br = read(fd, ret, st.st_size);
2052 +       close(fd);
2053 +       if (br != st.st_size) {
2054 +               free(ret);
2055 +               return NULL;
2056 +       }
2057 +       *size = st.st_size;
2058 +       return ret;
2059 +}
2060 +/*
2061 + * Loads a .der file in a buffer
2062 + */
2063 +static DER_key *CH_load_der_key(char *filename)
2064 +{
2065 +       DER_key *ret;
2066 +
2067 +       if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
2068 +               return NULL;
2069 +       if ((ret->buffer = CH_load_raw_file(filename, &(ret->size))) == NULL) {
2070 +               free(ret);
2071 +               return NULL;
2072 +       }
2073 +       return ret;
2074 +}
2075 +/*
2076 + * CH_load_pem_key
2077 + */
2078 +static DER_key *CH_load_pem_key(char *filename)
2079 +{
2080 +       DER_key *ret;
2081 +       uint8_t *buffer;
2082 +       char *b64,*p,*t;
2083 +       char key[1024];
2084 +       size_t filesize;
2085 +       int size;
2086 +
2087 +       if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
2088 +               return NULL;
2089 +       if ((buffer = CH_load_raw_file(filename, &filesize)) == NULL) {
2090 +               free(ret);
2091 +               return NULL;
2092 +       }
2093 +       p = (char *)buffer;
2094 +       while ((*p != '\n') && (*p != '\0'))
2095 +               p++;
2096 +       if (*p == '\0') {
2097 +               free(ret);
2098 +               return NULL;
2099 +       }
2100 +       p++;
2101 +       b64 = t = p;
2102 +       while((p - b64) <= filesize) {
2103 +               if ((*p == '-')) {
2104 +                       break;
2105 +               } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
2106 +                       *t = *p;
2107 +                       t++;
2108 +               }
2109 +               p++;
2110 +       }
2111 +       *t = '\0';
2112 +       size = B64_decode(b64, key, strlen(b64), 1024);
2113 +       if (size < 0) {
2114 +               free(buffer);
2115 +               free(ret);
2116 +               return NULL;
2117 +       }
2118 +       free(buffer);
2119 +       ret->buffer = (char *)malloc(size);
2120 +       ret->size = size;
2121 +       memcpy((void *)ret->buffer, (void *)key, size);
2122 +       return ret;
2123 +}
2124 +
2125 +/*
2126 + * CH_free_der_key
2127 + */
2128 +static void CH_free_der_key(DER_key *key)
2129 +{
2130 +       free(key->buffer);
2131 +       free(key);
2132 +}
2133 +
2134 +/*
2135 + * Get the public key specifics from an ASN.1 encoded file
2136 + * A function lacking in the exported axTLS API
2137 + *
2138 + * This is a really weird hack that only works with RSA public key
2139 + * files
2140 + */
2141 +static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
2142 +{
2143 +       uint8_t *modulus, *pub_exp;
2144 +       int mod_len, pub_len;
2145 +
2146 +       pub_len = 3;
2147 +       mod_len = len - 37;
2148 +       if (buf[0] != 0x30) {
2149 +               return -1;
2150 +       }
2151 +
2152 +       pub_exp = (uint8_t *)malloc(3);
2153 +       modulus = (uint8_t *)malloc(mod_len);
2154 +       memcpy(modulus, buf + 32 , mod_len);
2155 +       memcpy(pub_exp, buf + 34 + mod_len, 3); 
2156 +       if (mod_len <= 0 || pub_len <= 0 )
2157 +               return -1;
2158 +       CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
2159 +
2160 +       free(modulus);
2161 +       free(pub_exp);
2162 +       return 0;
2163 +}
2164 +
2165 +/*
2166 + * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
2167 + */
2168 +void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
2169 +{
2170 +       RSA_parameters *rsa_parameters;
2171 +
2172 +       BI_CTX *bi_ctx = bi_initialize();
2173 +       *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
2174 +       rsa_parameters = *rsa;
2175 +       rsa_parameters->bi_ctx = bi_ctx;
2176 +       rsa_parameters->num_octets = (mod_len & 0xFFF0);
2177 +       rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
2178 +       bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
2179 +       rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
2180 +       bi_permanent(rsa_parameters->e);
2181 +}
2182 +
2183 +static unsigned char *load_file_in_buffer(char *path, int *size)
2184 +{
2185 +       unsigned char *buffer;
2186 +       struct stat st;
2187 +       int fd;
2188 +
2189 +       if (stat(path, &st))
2190 +               return NULL;
2191 +       buffer = (unsigned char *)malloc(st.st_size);
2192 +       if (buffer == NULL)
2193 +               return NULL;
2194 +       if ((fd = open(path, O_RDONLY)) == -1) {
2195 +               free(buffer);
2196 +               return NULL;
2197 +       }
2198 +       if (read(fd, (void *)buffer,st.st_size) != (ssize_t)st.st_size) {
2199 +               free(buffer);
2200 +               close(fd);
2201 +               return NULL;
2202 +       }
2203 +       *size = (int)st.st_size;
2204 +       close(fd);
2205 +       return buffer;
2206 +}
2207 +
2208 +static int save_file_from_buffer(char *path, unsigned char *buffer, int size)
2209 +{
2210 +       int fd;
2211 +
2212 +       if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
2213 +               return -1;
2214 +       if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
2215 +               close(fd);
2216 +               return -1;
2217 +       }
2218 +       close(fd);
2219 +       return 0;
2220 +}
2221 +
2222 +/* FR_init */
2223 +void *FR_init(char *public_key_path)
2224 +{
2225 +       DER_key *derkey;
2226 +       RSA_parameters *rsa_parameters;
2227 +       char *ending;
2228 +
2229 +       ending = public_key_path + strlen(public_key_path) - 3;
2230 +       if (!strcmp(ending, "der"))
2231 +               derkey = CH_load_der_key(public_key_path);      
2232 +       else if (!strcmp(ending, "pem"))
2233 +               derkey = CH_load_pem_key(public_key_path);
2234 +       else {
2235 +               fprintf(stderr, "Error: unknown key format\n");
2236 +               exit(-1);
2237 +       }
2238 +       if (derkey == NULL) {
2239 +               fprintf(stderr, "Error: opening key file '%s'\n", public_key_path);
2240 +               exit(-1);
2241 +       }
2242 +       if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
2243 +               fprintf(stderr, "Error: Extracting public key from file\n");
2244 +               exit(-1);
2245 +       }
2246 +       CH_free_der_key(derkey);
2247 +       return (void *)rsa_parameters;
2248 +}
2249 +
2250 +/* FR_end */
2251 +FONRSA_ERROR FR_end(void *handle)
2252 +{
2253 +       RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
2254 +
2255 +       free(rsa_parameters);
2256 +       return FONRSA_OK;
2257 +}
2258 +
2259 +/* FR_decrypt_buffer */
2260 +FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
2261 +       unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
2262 +{
2263 +       RSA_parameters *rsaparms = (RSA_parameters *)handler;
2264 +
2265 +       if (cryptext_size != rsaparms->num_octets) {
2266 +               return FONRSA_SIZE;
2267 +       }
2268 +       if (plaintext_buffer_size < cryptext_size) {
2269 +               return FONRSA_SIZE;
2270 +       }
2271 +       if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)plaintext)) {
2272 +               return FONRSA_DECRYPT;
2273 +       }
2274 +       *plaintext_size = cryptext_size;
2275 +       return FONRSA_OK;
2276 +}
2277 +
2278 +FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
2279 +       unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
2280 +{
2281 +       unsigned char* AuxBuffer;
2282 +       int AuxSize;
2283 +
2284 +       AuxBuffer = (unsigned char*)malloc(cryptext_size);
2285 +
2286 +       RSA_parameters *rsaparms = (RSA_parameters *)handler;
2287 +
2288 +        if (cryptext_size != rsaparms->num_octets) {
2289 +                return FONRSA_SIZE;
2290 +        }
2291 +        if (plaintext_buffer_size < cryptext_size) {
2292 +                return FONRSA_SIZE;
2293 +        }
2294 +        if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)AuxBuffer)) {
2295 +                return FONRSA_DECRYPT;
2296 +        }
2297 +       if ((AuxSize = ExtractPadding((uint8_t*)plaintext, (uint8_t*)AuxBuffer, cryptext_size)) < 0)
2298 +       {
2299 +               printf("Incorrect Padding decrypting buffer");
2300 +               return FONRSA_DECRYPT;
2301 +       }
2302 +        *plaintext_size = AuxSize;
2303 +        return FONRSA_OK;
2304 +}
2305 +
2306 +/*
2307 + *
2308 + * Implementation of  PKCS 1.5 padding, borrowed from
2309 + * Tom's code (public domain)
2310 + */
2311 +
2312 +/* Standalone FR_verify_file */
2313 +FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path)
2314 +{
2315 +       int j;
2316 +       byte *hashcode;
2317 +       byte hash[20];
2318 +       uint8_t *decrypted;
2319 +       RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
2320 +       char *signature_buffer;
2321 +       int signature_size;
2322 +
2323 +       /* Calculates the RIPEMD-160 hash of the file */
2324 +       hashcode = RMDbinary (file_path);
2325 +       /* Decrypts the signature file using the RSA public key */
2326 +       signature_buffer = load_file_in_buffer(signature_file_path, &signature_size);
2327 +       if (signature_buffer == NULL)
2328 +               return FONRSA_OPENKEY;
2329 +
2330 +       if (rsa_parameters->num_octets != signature_size)
2331 +               return FONRSA_SIZE;
2332 +       decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
2333 +       if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
2334 +               fprintf(stderr, "Error: Decrypting signature\n");
2335 +               exit(-1);
2336 +       }
2337 +       memcpy(hash, decrypted + 492, 20);
2338 +       free(decrypted);
2339 +       free(signature_buffer);
2340 +       for (j = 0; j < RMDsize/8; j++) {
2341 +               if (hash[j] != hashcode[j])
2342 +                       return FONRSA_VERIFICATION_FAILURE;
2343 +       }
2344 +       return FONRSA_OK;
2345 +}
2346 +
2347 +/* FR_decrypt_file */
2348 +FONRSA_ERROR FR_decrypt_file(void *handle, char *crypted_file_path, char *plaintext_file_path)
2349 +{
2350 +       int size;
2351 +       FONRSA_ERROR ret;
2352 +       char *filebuffer;
2353 +       char crypted[1024];
2354 +       int crypted_size;
2355 +
2356 +       if ((filebuffer = load_file_in_buffer(crypted_file_path, &size)) == NULL) {
2357 +               return FONRSA_LOADFILE;
2358 +       }
2359 +
2360 +       ret = FR_decrypt_buffer(handle, filebuffer, size, crypted, 1024, &crypted_size);
2361 +       if (ret != FONRSA_OK) {
2362 +               free(filebuffer);
2363 +               return ret;
2364 +       }
2365 +       free(filebuffer);
2366 +
2367 +       if (save_file_from_buffer(plaintext_file_path, crypted, crypted_size)) {
2368 +               printf("Error writing %lu bytes into %s", crypted_size, plaintext_file_path);
2369 +               return FONRSA_SAVEFILE;
2370 +       }
2371 +       return FONRSA_OK;
2372 +}
2373 +
2374 +int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer)
2375 +{
2376 +       int i;
2377 +
2378 +       //First typical checks...
2379 +       if (LengthOfInputBuffer < MINIMUM_PADING_BYTES_PKCS_1_5)
2380 +       {
2381 +               fprintf(stderr, "Error:ExtractPadding: Error, Length of input buffer is too short.\n");
2382 +               return -1;
2383 +       }
2384 +       else if((InputBuffer[0] != 0) || (InputBuffer[1] > 2)) //Necessary header of Padding...
2385 +       {
2386 +               fprintf(stderr, "Error:ExtractPadding: Error, Padding header is incorrect.\n");
2387 +               return -1;
2388 +       }
2389 +       for (i=2; i < LengthOfInputBuffer; i++) //Variable size of non-zero padding....
2390 +       {
2391 +               if (InputBuffer[i] == 0) break; //This is the end of Padding.
2392 +       }
2393 +       //We need to evaluate if there is an existing message...
2394 +       if (i < LengthOfInputBuffer - 2)
2395 +       {//Ok, Padding is extracted... copying the message and finishing...
2396 +               memcpy(OutputBuffer, &(InputBuffer[i + 1]), LengthOfInputBuffer - (i + 1));
2397 +               return LengthOfInputBuffer - (i + 1);
2398 +       }
2399 +       //If we have reached to this point, then an error has occurred...
2400 +       return -1;      
2401 +}
2402 +
2403 +#ifdef __MAINTEST__
2404 +int main(int argc, char **argv)
2405 +{
2406 +       void *handle = NULL;
2407 +       FONRSA_ERROR ret;
2408 +       char *filebuffer = NULL;
2409 +       char crypted[1024];
2410 +       int size, crypted_size;
2411 +
2412 +       if (argc != 4) {
2413 +               printf("Usage: %s <key_file> <crypted_file> <output_file>\n", argv[0]);
2414 +               return 1;
2415 +       }
2416 +
2417 +       handle = FR_init(argv[1]);
2418 +       if (handle == NULL) {
2419 +               printf("Error loading keys\n");
2420 +               return 1;
2421 +       }
2422 +       ret = FR_decrypt_file(handle, argv[2], argv[3]);
2423 +       if (ret != FONRSA_OK) {
2424 +               printf("FR_decrypt_file returns %d\n", ret);
2425 +       }
2426 +       FR_end(handle);
2427 +       return (int)ret;
2428 +}
2429 +
2430 +#endif
2431 +
2432 +
2433 --- /dev/null
2434 +++ b/net/rsa/fonrsa.h
2435 @@ -0,0 +1,53 @@
2436 +/*
2437 + * FONSM RSA handling library, used by fonsmcd and foncheckrsa
2438 + *
2439 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2440 + *
2441 + * This library is free software; you can redistribute it and/or modify
2442 + * it under the terms of the GNU Lesser General Public License as published by
2443 + * the Free Software Foundation; either version 2 of the License, or
2444 + * (at your option) any later version.
2445 + *
2446 + * This library is distributed in the hope that it will be useful,
2447 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2448 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2449 + * GNU Lesser General Public License for more details.
2450 + *
2451 + * You should have received a copy of the GNU Lesser General Public License
2452 + * along with this library; if not, write to the Free Software
2453 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
2454 + *
2455 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
2456 + *
2457 + * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
2458 + */
2459 +#ifndef _FONRSA_H
2460 +#define _FONRSA_H
2461 +
2462 +#define MINIMUM_PADING_BYTES_PKCS_1_5 3
2463 +
2464 +typedef enum {
2465 +       FONRSA_OK = 0,
2466 +       FONRSA_VERIFICATION_FAILURE = 1,
2467 +       FONRSA_OPENKEY = 2,
2468 +       FONRSA_SIZE = 3,
2469 +       FONRSA_LOADFILE = 4,
2470 +       FONRSA_CRYPT = 5,
2471 +       FONRSA_DECRYPT = 6,
2472 +       FONRSA_SAVEFILE = 7,
2473 +       FONRSA_NOSYS = 8,
2474 +       FONRSA_VERIFY = 9
2475 +} FONRSA_ERROR;
2476 +
2477 +void *FR_init(char *public_key_path);
2478 +FONRSA_ERROR FR_end(void *handle);
2479 +FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
2480 +       unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
2481 +FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
2482 +       unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
2483 +FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path);
2484 +FONRSA_ERROR FR_decrypt_file(void *handler, char *crypted_file_path, char *plaintext_file_path);
2485 +
2486 +#endif
2487 +
2488 +
2489 --- /dev/null
2490 +++ b/net/rsa/log.c
2491 @@ -0,0 +1,138 @@
2492 +/*
2493 + * Fonsm log module. Used inside the fonsm backend module and on the client.
2494 + *
2495 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2496 + *
2497 + * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
2498 + *
2499 + * $Id: log.c 392 2007-06-25 16:24:51Z pablo.martin $
2500 + */
2501 +#include <stdio.h>
2502 +#include <string.h>
2503 +#include <stdlib.h>
2504 +#include <stdarg.h>
2505 +#include <unistd.h>
2506 +#ifndef WIN32
2507 +#include <syslog.h>
2508 +#endif
2509 +#include "log.h"
2510 +
2511 +#define MAX_SESSION_PREFIX 256
2512 +
2513 +typedef struct {
2514 +       char domain[256];
2515 +       LG_LEVEL watermark;
2516 +       int mode;
2517 +       LG_log_function_pointer function;
2518 +} ST_fslog;
2519 +
2520 +static ST_fslog fslog;
2521 +static void LG_log_string(LG_LEVEL level, const char *message);
2522 +
2523 +/*! 
2524 + \brief Starts the log subsystem, redirecting glog() to stderr/syslog depending
2525 + on mode
2526 + \retval FSLOG_ERROR : FSLOG_OK if everything goes well
2527 + \param lg : handle that will be returned
2528 + \param ident : program identifier, any string 
2529 + \param low_watermark : if the log level is less than this value, it will not be logged
2530 + \param mode : FSLOG_MODE_SYSLOG (log to syslog) or FSLOG_MODE_STDERR (log to stderr)
2531 +*/
2532 +FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode,
2533 +       LG_log_function_pointer log_function, int facility)
2534 +{
2535 +#ifndef WIN32
2536 +       strncpy(fslog.domain, domain, MAX_LG_DOMAIN);
2537 +       fslog.domain[MAX_LG_DOMAIN - 1] = '\0';
2538 +       fslog.watermark = watermark;
2539 +       fslog.mode = mode;
2540 +       fslog.function = log_function?log_function:LG_log_string;
2541 +       if (fslog.mode & LG_SYSLOG)
2542 +               openlog(domain, LOG_NDELAY, facility);
2543 +       return FSLOG_OK;
2544 +#else
2545 +       return FSLOG_OK;
2546 +#endif
2547 +}
2548 +
2549 +/*! 
2550 + \brief Set the low watermark
2551 + \retval FSLOG_ERROR : FSLOG_OK
2552 + \param lg : log handle
2553 + \param low_watermark : new watermark 
2554 +*/
2555 +FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark)
2556 +{
2557 +       fslog.watermark = watermark;
2558 +       return FSLOG_OK;
2559 +}
2560 +
2561 +/*! 
2562 + \brief  Ends the log subsystem, unregisteing glog handle
2563 + \retval FSLOG_ERROR : FSLOG_OK if everything goes well
2564 + \param handle : log handle to free
2565 +*/
2566 +FSLOG_ERROR LG_end(void)
2567 +{
2568 +#ifndef WIN32
2569 +       if (fslog.mode & LG_SYSLOG)
2570 +               closelog();
2571 +#endif
2572 +       return FSLOG_OK;
2573 +}
2574 +
2575 +
2576 +void LG_log(LG_LEVEL loglevel, const char *message, ...)
2577 +{
2578 +#ifndef WIN32
2579 +       va_list ap;
2580 +       char buffer[4096];
2581 +       int n;
2582 +
2583 +       va_start(ap, message);
2584 +       n = vsnprintf(buffer, MAX_LOG_STRING, message, ap);
2585 +       va_end(ap);
2586 +       if (n > -1 && n < MAX_LOG_STRING)
2587 +               fslog.function(loglevel, buffer);
2588 +       else
2589 +               fon_critical("%s: Message too big to be logged", __FUNCTION__);
2590 +#else
2591 +       return;
2592 +#endif
2593 +}
2594 +
2595 +/* Default log function (when mode is LG_SYSLOG or LG_STDERR) */
2596 +static void LG_log_string(LG_LEVEL level, const char *message) 
2597 +{
2598 +#ifndef WIN32
2599 +        static struct {
2600 +                int syslog_level;
2601 +                char *log_string;
2602 +        } fonlog_to_syslog[] = {
2603 +                [LG_DEBUG] = {LOG_ERR, "DEBUG"},
2604 +                [LG_MESSAGE] = {LOG_ERR, "MESSAGE"},
2605 +                [LG_WARNING] = {LOG_ERR, "WARNING"},
2606 +                [LG_CRITICAL] = {LOG_ERR, "CRITICAL"},
2607 +                [LG_ERROR] = {LOG_ERR, "ERROR"}
2608 +        };
2609 +
2610 +       if (level < fslog.watermark)
2611 +               return;
2612 +       if (fslog.mode & LG_SYSLOG) {
2613 +               if (level == LG_MESSAGE) {
2614 +                       syslog(LOG_INFO, "%s", message);
2615 +               } else {
2616 +                       syslog(fonlog_to_syslog[level].syslog_level, "%s: %s", fonlog_to_syslog[level].log_string, message);
2617 +               }
2618 +       }
2619 +       if (fslog.mode & LG_STDERR) {
2620 +               fprintf(stderr, "%s[%d]: %8.8s: %s\n", fslog.domain, 
2621 +                               getpid(), fonlog_to_syslog[level].log_string, 
2622 +                               message);
2623 +       }
2624 +#else
2625 +       /* FIXE: todo */
2626 +       return;
2627 +#endif
2628 +}
2629 +
2630 --- /dev/null
2631 +++ b/net/rsa/log.h
2632 @@ -0,0 +1,77 @@
2633 +/*
2634 + * Fonsm log module. Used inside the fonsm backend module and on the client.
2635 + *
2636 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2637 + *
2638 + * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
2639 + *
2640 + * $Id: log.h 379 2007-05-28 09:17:48Z pablo.martin $
2641 + */
2642 +#ifndef _LOG_H
2643 +#define _LOG_H
2644 +
2645 +#ifdef __cplusplus
2646 +extern "C" {
2647 +#endif
2648 +
2649 +#include <stdarg.h>
2650 +
2651 +typedef enum {
2652 +        FSLOG_OK = 0,
2653 +        FSLOG_UNKNOWN = -1
2654 +} FSLOG_ERROR;
2655 +
2656 +
2657 +typedef void * LG_HANDLE;
2658 +
2659 +typedef enum {
2660 +        LG_DEBUG = 0,
2661 +        LG_MESSAGE = 1,
2662 +        LG_INFO = 2,
2663 +        LG_WARNING = 3,
2664 +        LG_CRITICAL = 4,
2665 +        LG_ERROR = 5
2666 +} LG_LEVEL;
2667 +
2668 +#define LG_SYSLOG 0x01
2669 +#define LG_STDERR 0x02
2670 +#define LG_CUSTOM 0x04
2671 +
2672 +#define MAX_LG_DOMAIN 256
2673 +#define MAX_LOG_STRING 4096
2674 +
2675 +#ifndef NDEBUG
2676 +#ifndef LOGPRINTF
2677 +#define fon_debug(...) LG_log (LG_DEBUG, __VA_ARGS__)
2678 +#else
2679 +#define fon_debug(...) { printf("DEBUG: "); printf(__VA_ARGS__); printf("\n"); }
2680 +#endif
2681 +#else
2682 +/* fon_debug evaluates to nothing when NDEBUG is defined */
2683 +#define fon_debug(...)
2684 +#endif
2685 +#ifndef LOGPRINTF
2686 +#define fon_message(...) LG_log (LG_MESSAGE, __VA_ARGS__)
2687 +#define fon_warning(...) LG_log (LG_WARNING, __VA_ARGS__) 
2688 +#define fon_critical(...) LG_log (LG_CRITICAL, __VA_ARGS__)
2689 +#define fon_error(...) LG_log (LG_ERROR, __VA_ARGS__)
2690 +#else
2691 +#define fon_message(...) { printf("MESSAGE: "); printf(__VA_ARGS__); printf("\n"); }
2692 +#define fon_warning(...)  { printf("WARNING: "); printf(__VA_ARGS__); printf("\n"); }
2693 +#define fon_critical(...) { printf("CRITICAL: "); printf(__VA_ARGS__); printf("\n"); }
2694 +#define fon_error(...) { printf("ERROR: "); printf(__VA_ARGS__); printf("\n"); }
2695 +#endif
2696 +
2697 +typedef void (*LG_log_function_pointer)(LG_LEVEL level, const char *message);
2698 +
2699 +FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode, LG_log_function_pointer log_function, int facility);
2700 +FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark);
2701 +FSLOG_ERROR LG_end(void);
2702 +void LG_log(LG_LEVEL loglevel, const char *message, ...);
2703 +
2704 +#ifdef __cplusplus
2705 +}
2706 +#endif
2707 +
2708 +#endif
2709 +
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/Makefile
4044 @@ -0,0 +1,54 @@
4045 +# Copyright (c) 2001, Adam Dunkels.
4046 +# All rights reserved. 
4047 +#
4048 +# Redistribution and use in source and binary forms, with or without 
4049 +# modification, are permitted provided that the following conditions 
4050 +# are met: 
4051 +# 1. Redistributions of source code must retain the above copyright 
4052 +#    notice, this list of conditions and the following disclaimer. 
4053 +# 2. Redistributions in binary form must reproduce the above copyright 
4054 +#    notice, this list of conditions and the following disclaimer in the 
4055 +#    documentation and/or other materials provided with the distribution. 
4056 +# 3. All advertising materials mentioning features or use of this software
4057 +#    must display the following acknowledgement:
4058 +#      This product includes software developed by Adam Dunkels.
4059 +# 4. The name of the author may not be used to endorse or promote
4060 +#    products derived from this software without specific prior
4061 +#    written permission.  
4062 +#
4063 +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4064 +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4065 +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4066 +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4067 +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4068 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4069 +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4070 +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4071 +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4072 +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4073 +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
4074 +#
4075 +# This file is part of the uIP TCP/IP stack.
4076 +#
4077 +# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $
4078 +#
4079 +
4080 +CC=gcc
4081 +CFLAGS=-Wall -fpack-struct -DDUMP=0
4082 +
4083 +all: uip
4084 +
4085 +uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o
4086 +       $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
4087 +
4088 +%.o: %.c
4089 +       $(CC) $(CFLAGS) -c  $^ -o $@
4090 +
4091 +clean:
4092 +       rm -f *.o *~ *core uip
4093 +
4094 +
4095 +
4096 +
4097 +
4098 +
4099 --- /dev/null
4100 +++ b/net/uip-0.9/fs.c
4101 @@ -0,0 +1,154 @@
4102 +/**
4103 + * \addtogroup httpd
4104 + * @{
4105 + */
4106 +
4107 +/**
4108 + * \file
4109 + * HTTP server read-only file system code.
4110 + * \author Adam Dunkels <adam@dunkels.com>
4111 + *
4112 + * A simple read-only filesystem. 
4113 + */
4114
4115 +/*
4116 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4117 + * All rights reserved. 
4118 + *
4119 + * Redistribution and use in source and binary forms, with or without 
4120 + * modification, are permitted provided that the following conditions 
4121 + * are met: 
4122 + * 1. Redistributions of source code must retain the above copyright 
4123 + *    notice, this list of conditions and the following disclaimer. 
4124 + * 2. Redistributions in binary form must reproduce the above copyright 
4125 + *    notice, this list of conditions and the following disclaimer in the 
4126 + *    documentation and/or other materials provided with the distribution. 
4127 + * 3. Neither the name of the Institute nor the names of its contributors 
4128 + *    may be used to endorse or promote products derived from this software 
4129 + *    without specific prior written permission. 
4130 + *
4131 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
4132 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
4133 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
4134 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
4135 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
4136 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
4137 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
4138 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
4139 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
4140 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
4141 + * SUCH DAMAGE. 
4142 + *
4143 + * This file is part of the lwIP TCP/IP stack.
4144 + * 
4145 + * Author: Adam Dunkels <adam@sics.se>
4146 + *
4147 + * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $
4148 + */
4149 +
4150 +#include "uip.h"
4151 +#include "httpd.h"
4152 +#include "fs.h"
4153 +#include "fsdata.h"
4154 +
4155 +#include "fsdata.c"
4156 +
4157 +#ifdef FS_STATISTICS
4158 +#if FS_STATISTICS == 1
4159 +static u16_t count[FS_NUMFILES];
4160 +#endif /* FS_STATISTICS */
4161 +#endif /* FS_STATISTICS */
4162 +
4163 +/*-----------------------------------------------------------------------------------*/
4164 +static u8_t
4165 +fs_strcmp(const char *str1, const char *str2)
4166 +{
4167 +  u8_t i;
4168 +  i = 0;
4169 + loop:
4170 +
4171 +  if(str2[i] == 0 ||
4172 +     str1[i] == '\r' || 
4173 +     str1[i] == '\n') {
4174 +    return 0;
4175 +  }
4176 +
4177 +  if(str1[i] != str2[i]) {
4178 +    return 1;
4179 +  }
4180 +
4181 +
4182 +  ++i;
4183 +  goto loop;
4184 +}
4185 +/*-----------------------------------------------------------------------------------*/
4186 +int
4187 +fs_open(const char *name, struct fs_file *file)
4188 +{
4189 +#ifdef FS_STATISTICS
4190 +#if FS_STATISTICS == 1
4191 +  u16_t i = 0;
4192 +#endif /* FS_STATISTICS */
4193 +#endif /* FS_STATISTICS */
4194 +  struct fsdata_file_noconst *f;
4195 +
4196 +  for(f = (struct fsdata_file_noconst *)FS_ROOT;
4197 +      f != NULL;
4198 +      f = (struct fsdata_file_noconst *)f->next) {
4199 +
4200 +    if(fs_strcmp(name, f->name) == 0) {
4201 +      file->data = f->data;
4202 +      file->len = f->len;
4203 +#ifdef FS_STATISTICS
4204 +#if FS_STATISTICS == 1
4205 +      ++count[i];
4206 +#endif /* FS_STATISTICS */
4207 +#endif /* FS_STATISTICS */
4208 +      return 1;
4209 +    }
4210 +#ifdef FS_STATISTICS
4211 +#if FS_STATISTICS == 1
4212 +    ++i;
4213 +#endif /* FS_STATISTICS */
4214 +#endif /* FS_STATISTICS */
4215 +
4216 +  }
4217 +  return 0;
4218 +}
4219 +/*-----------------------------------------------------------------------------------*/
4220 +void
4221 +fs_init(void)
4222 +{
4223 +#ifdef FS_STATISTICS
4224 +#if FS_STATISTICS == 1
4225 +  u16_t i;
4226 +  for(i = 0; i < FS_NUMFILES; i++) {
4227 +    count[i] = 0;
4228 +  }
4229 +#endif /* FS_STATISTICS */
4230 +#endif /* FS_STATISTICS */
4231 +}
4232 +/*-----------------------------------------------------------------------------------*/
4233 +#ifdef FS_STATISTICS
4234 +#if FS_STATISTICS == 1  
4235 +u16_t fs_count
4236 +(char *name)
4237 +{
4238 +  struct fsdata_file_noconst *f;
4239 +  u16_t i;
4240 +
4241 +  i = 0;
4242 +  for(f = (struct fsdata_file_noconst *)FS_ROOT;
4243 +      f != NULL;
4244 +      f = (struct fsdata_file_noconst *)f->next) {
4245 +
4246 +    if(fs_strcmp(name, f->name) == 0) {
4247 +      return count[i];
4248 +    }
4249 +    ++i;
4250 +  }
4251 +  return 0;
4252 +}
4253 +#endif /* FS_STATISTICS */
4254 +#endif /* FS_STATISTICS */
4255 +/*-----------------------------------------------------------------------------------*/
4256 --- /dev/null
4257 +++ b/net/uip-0.9/fs.h
4258 @@ -0,0 +1,80 @@
4259 +/**
4260 + * \addtogroup httpd
4261 + * @{
4262 + */
4263 +
4264 +/**
4265 + * \file
4266 + * HTTP server read-only file system header file.
4267 + * \author Adam Dunkels <adam@dunkels.com>
4268 + */
4269
4270 +/*
4271 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4272 + * All rights reserved. 
4273 + *
4274 + * Redistribution and use in source and binary forms, with or without 
4275 + * modification, are permitted provided that the following conditions 
4276 + * are met: 
4277 + * 1. Redistributions of source code must retain the above copyright 
4278 + *    notice, this list of conditions and the following disclaimer. 
4279 + * 2. Redistributions in binary form must reproduce the above copyright 
4280 + *    notice, this list of conditions and the following disclaimer in the 
4281 + *    documentation and/or other materials provided with the distribution. 
4282 + * 3. Neither the name of the Institute nor the names of its contributors 
4283 + *    may be used to endorse or promote products derived from this software 
4284 + *    without specific prior written permission. 
4285 + *
4286 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
4287 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
4288 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
4289 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
4290 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
4291 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
4292 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
4293 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
4294 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
4295 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
4296 + * SUCH DAMAGE. 
4297 + *
4298 + * This file is part of the lwIP TCP/IP stack.
4299 + * 
4300 + * Author: Adam Dunkels <adam@sics.se>
4301 + *
4302 + * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $
4303 + */
4304 +#ifndef __FS_H__
4305 +#define __FS_H__
4306 +
4307 +#include "uip.h"
4308 +
4309 +/**
4310 + * An open file in the read-only file system.
4311 + */
4312 +struct fs_file {
4313 +  char *data;  /**< The actual file data. */
4314 +  int len;     /**< The length of the file data. */
4315 +};
4316 +
4317 +/**
4318 + * Open a file in the read-only file system.
4319 + *
4320 + * \param name The name of the file.
4321 + *
4322 + * \param file The file pointer, which must be allocated by caller and
4323 + * will be filled in by the function.
4324 + */
4325 +int fs_open(const char *name, struct fs_file *file);
4326 +
4327 +#ifdef FS_STATISTICS
4328 +#if FS_STATISTICS == 1  
4329 +u16_t fs_count(char *name);
4330 +#endif /* FS_STATISTICS */
4331 +#endif /* FS_STATISTICS */
4332 +
4333 +/**
4334 + * Initialize the read-only file system.
4335 + */
4336 +void fs_init(void);
4337 +
4338 +#endif /* __FS_H__ */
4339 --- /dev/null
4340 +++ b/net/uip-0.9/fsdata.c
4341 @@ -0,0 +1,199 @@
4342 +static const char data_flashing_html[] = {
4343 +       /* /flashing.html */
4344 +       0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4345 +       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
4346 +       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
4347 +       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
4348 +       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
4349 +       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
4350 +       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
4351 +       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
4352 +       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
4353 +       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
4354 +       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 
4355 +       0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 
4356 +       0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30, 
4357 +       0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68, 
4358 +       0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 
4359 +       0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 
4360 +       0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 
4361 +       0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 
4362 +       0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34, 
4363 +       0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 
4364 +       0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61, 
4365 +       0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 
4366 +       0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31, 
4367 +       0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 
4368 +       0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 
4369 +       0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4370 +
4371 +static const char data_fail_html[] = {
4372 +       /* /fail.html */
4373 +       0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4374 +       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
4375 +       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
4376 +       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
4377 +       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
4378 +       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
4379 +       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
4380 +       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
4381 +       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
4382 +       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
4383 +       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9, 
4384 +       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c, 
4385 +       0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9, 
4386 +       0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46, 
4387 +       0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49, 
4388 +       0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 
4389 +       0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 
4390 +       0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 
4391 +       0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 
4392 +       0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45, 
4393 +       0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65, 
4394 +       0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75, 
4395 +       0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 
4396 +       0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 
4397 +       0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66, 
4398 +       0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50, 
4399 +       0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65, 
4400 +       0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75, 
4401 +       0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69, 
4402 +       0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 
4403 +       0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 
4404 +       0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
4405 +       0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 
4406 +       0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e, 
4407 +       0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 
4408 +       0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 
4409 +       0x3e, 0xa, };
4410 +
4411 +static const char data_404_html[] = {
4412 +       /* /404.html */
4413 +       0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4414 +       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 
4415 +       0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 
4416 +       0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 
4417 +       0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 
4418 +       0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 
4419 +       0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 
4420 +       0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 
4421 +       0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 
4422 +       0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 
4423 +       0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 
4424 +       0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 
4425 +       0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 
4426 +       0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 
4427 +       0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 
4428 +       0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20, 
4429 +       0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 
4430 +       0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 
4431 +       0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f, 
4432 +       0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 
4433 +       0x6c, 0x3e, };
4434 +
4435 +static const char data_index_html[] = {
4436 +       /* /index.html */
4437 +       0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4438 +       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
4439 +       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
4440 +       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
4441 +       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
4442 +       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
4443 +       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
4444 +       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
4445 +       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
4446 +       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
4447 +       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9, 
4448 +       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c, 
4449 +       0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9, 
4450 +       0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46, 
4451 +       0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49, 
4452 +       0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 
4453 +       0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 
4454 +       0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 
4455 +       0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 
4456 +       0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 
4457 +       0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 
4458 +       0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 
4459 +       0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62, 
4460 +       0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 
4461 +       0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 
4462 +       0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9, 
4463 +       0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 
4464 +       0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 
4465 +       0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 
4466 +       0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 
4467 +       0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74, 
4468 +       0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d, 
4469 +       0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 
4470 +       0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 
4471 +       0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70, 
4472 +       0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69, 
4473 +       0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69, 
4474 +       0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9, 
4475 +       0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 
4476 +       0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e, 
4477 +       0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 
4478 +       0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 
4479 +       0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4480 +
4481 +static const char data_flash_html[] = {
4482 +       /* /flash.html */
4483 +       0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4484 +       0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
4485 +       0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 
4486 +       0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30, 
4487 +       0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 
4488 +       0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 
4489 +       0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 
4490 +       0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65, 
4491 +       0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 
4492 +       0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 
4493 +       0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9, 
4494 +       0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c, 
4495 +       0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9, 
4496 +       0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46, 
4497 +       0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49, 
4498 +       0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 
4499 +       0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 
4500 +       0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 
4501 +       0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 
4502 +       0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 
4503 +       0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 
4504 +       0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 
4505 +       0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62, 
4506 +       0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 
4507 +       0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 
4508 +       0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9, 
4509 +       0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69, 
4510 +       0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 
4511 +       0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 
4512 +       0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72, 
4513 +       0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c, 
4514 +       0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 
4515 +       0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70, 
4516 +       0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68, 
4517 +       0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c, 
4518 +       0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f, 
4519 +       0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9, 
4520 +       0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73, 
4521 +       0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c, 
4522 +       0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 
4523 +       0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c, 
4524 +       0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c, 
4525 +       0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 
4526 +       0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4527 +
4528 +const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
4529 +
4530 +const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
4531 +
4532 +const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
4533 +
4534 +const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
4535 +
4536 +const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
4537 +
4538 +#define FS_ROOT file_flash_html
4539 +
4540 +#define FS_NUMFILES 5
4541 \ No newline at end of file
4542 --- /dev/null
4543 +++ b/net/uip-0.9/fsdata.h
4544 @@ -0,0 +1,64 @@
4545 +/*
4546 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4547 + * All rights reserved. 
4548 + *
4549 + * Redistribution and use in source and binary forms, with or without 
4550 + * modification, are permitted provided that the following conditions 
4551 + * are met: 
4552 + * 1. Redistributions of source code must retain the above copyright 
4553 + *    notice, this list of conditions and the following disclaimer. 
4554 + * 2. Redistributions in binary form must reproduce the above copyright 
4555 + *    notice, this list of conditions and the following disclaimer in the 
4556 + *    documentation and/or other materials provided with the distribution. 
4557 + * 3. Neither the name of the Institute nor the names of its contributors 
4558 + *    may be used to endorse or promote products derived from this software 
4559 + *    without specific prior written permission. 
4560 + *
4561 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
4562 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
4563 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
4564 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
4565 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
4566 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
4567 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
4568 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
4569 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
4570 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
4571 + * SUCH DAMAGE. 
4572 + *
4573 + * This file is part of the lwIP TCP/IP stack.
4574 + * 
4575 + * Author: Adam Dunkels <adam@sics.se>
4576 + *
4577 + * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $
4578 + */
4579 +#ifndef __FSDATA_H__
4580 +#define __FSDATA_H__
4581 +
4582 +#include "uipopt.h"
4583 +
4584 +struct fsdata_file {
4585 +  const struct fsdata_file *next;
4586 +  const char *name;
4587 +  const char *data;
4588 +  const int len;
4589 +#ifdef FS_STATISTICS
4590 +#if FS_STATISTICS == 1
4591 +  u16_t count;
4592 +#endif /* FS_STATISTICS */
4593 +#endif /* FS_STATISTICS */
4594 +};
4595 +
4596 +struct fsdata_file_noconst {
4597 +  struct fsdata_file *next;
4598 +  char *name;
4599 +  char *data;
4600 +  int len;
4601 +#ifdef FS_STATISTICS
4602 +#if FS_STATISTICS == 1
4603 +  u16_t count;
4604 +#endif /* FS_STATISTICS */
4605 +#endif /* FS_STATISTICS */
4606 +};
4607 +
4608 +#endif /* __FSDATA_H__ */
4609 --- /dev/null
4610 +++ b/net/uip-0.9/httpd.c
4611 @@ -0,0 +1,278 @@
4612 +#include "uip.h"
4613 +#include "httpd.h"
4614 +#include "fs.h"
4615 +#include "fsdata.h"
4616 +#include <asm/addrspace.h>
4617 +
4618 +#define HTTP_NONE              0
4619 +#define HTTP_FILE              1
4620 +#define HTTP_FIRMWARE          2
4621 +
4622 +#define PRINT(x) printf("%s", x)
4623 +#define PRINTLN(x) printf("%s\n", x)
4624 +
4625 +extern unsigned long do_http_tmp_address(void);
4626 +
4627 +struct httpd_state *hs;
4628 +
4629 +extern const struct fsdata_file file_index_html;
4630 +extern const struct fsdata_file file_404_html;
4631 +extern const struct fsdata_file file_flash_html;
4632 +extern int httpd_upload_complete;
4633 +extern unsigned char *httpd_upload_data;
4634 +unsigned char *upload_data;
4635 +extern ulong           NetBootFileXferSize;
4636 +int upload_running = 0;
4637 +
4638 +#define ISO_G        0x47
4639 +#define ISO_E        0x45
4640 +#define ISO_T        0x54
4641 +#define ISO_P        0x50
4642 +#define ISO_O        0x4f
4643 +#define ISO_S        0x53
4644 +#define ISO_T        0x54
4645 +#define ISO_slash    0x2f
4646 +#define ISO_c        0x63
4647 +#define ISO_g        0x67
4648 +#define ISO_i        0x69
4649 +#define ISO_space    0x20
4650 +#define ISO_nl       0x0a
4651 +#define ISO_cr       0x0d
4652 +#define ISO_a        0x61
4653 +#define ISO_t        0x74
4654 +#define ISO_hash     0x23
4655 +#define ISO_period   0x2e
4656 +
4657 +static char eol[3] = { 0x0d, 0x0a, 0x00 };
4658 +static char eol2[5] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00 };
4659 +static char boundary[128];
4660 +static int boundary_len = 0;
4661 +
4662 +/* we use this so that we can do without the ctype library */
4663 +#define is_digit(c)    ((c) >= '0' && (c) <= '9')
4664 +static int atoi(const char *s)
4665 +{
4666 +       int i=0;
4667 +
4668 +       while (is_digit(*s))
4669 +               i = i*10 + *(s++) - '0';
4670 +       return i;
4671 +}
4672 +
4673 +void
4674 +httpd_init(void)
4675 +{
4676 +       fs_init();
4677 +       uip_listen(HTONS(80));
4678 +}
4679 +
4680 +void
4681 +httpd_appcall(void)
4682 +{
4683 +       struct fs_file fsfile;
4684 +       u8_t i;
4685 +       switch(uip_conn->lport) {
4686 +       case HTONS(80):
4687 +               hs = (struct httpd_state *)(uip_conn->appstate);
4688 +               if(uip_connected())
4689 +               {
4690 +                       hs->state = HTTP_NONE;
4691 +                       hs->count = 0;
4692 +                       return;
4693 +               } else if(uip_poll())
4694 +               {
4695 +                       if(hs->count++ >= 1000) {
4696 +                               uip_abort();
4697 +                       }
4698 +                       return;
4699 +               } else if(uip_newdata() && hs->state == HTTP_NONE)
4700 +               {
4701 +                       if(uip_appdata[0] == ISO_G &&
4702 +                               uip_appdata[1] == ISO_E &&
4703 +                               uip_appdata[2] == ISO_T &&
4704 +                               uip_appdata[3] == ISO_space)
4705 +                       {
4706 +                               hs->state = HTTP_FILE;
4707 +                       }
4708 +                       if(uip_appdata[0] == ISO_P &&
4709 +                               uip_appdata[1] == ISO_O &&
4710 +                               uip_appdata[2] == ISO_S &&
4711 +                               uip_appdata[3] == ISO_T &&
4712 +                               uip_appdata[4] == ISO_space)
4713 +                       {
4714 +                               hs->state = HTTP_FIRMWARE;
4715 +                       }
4716 +                       if(hs->state == HTTP_NONE)
4717 +                       {
4718 +                               uip_abort();
4719 +                               return;
4720 +                       }
4721 +                       if(hs->state == HTTP_FILE)
4722 +                       {
4723 +                               for(i = 4; i < 40; ++i)
4724 +                               {
4725 +                                       if(uip_appdata[i] == ISO_space ||
4726 +                                               uip_appdata[i] == ISO_cr ||
4727 +                                               uip_appdata[i] == ISO_nl)
4728 +                                       {
4729 +                                               uip_appdata[i] = 0;
4730 +                                               break;
4731 +                                       }
4732 +                               }
4733 +
4734 +                               PRINT("request for file ");
4735 +                               PRINTLN(&uip_appdata[4]);
4736 +                               if(uip_appdata[4] == ISO_slash &&
4737 +                                       uip_appdata[5] == 0)
4738 +                               {
4739 +                                       fs_open(file_index_html.name, &fsfile);
4740 +                               } else {
4741 +                                       if(!fs_open((const char *)&uip_appdata[4], &fsfile))
4742 +                                       {
4743 +                                               PRINTLN("couldn't open file");
4744 +                                               fs_open(file_index_html.name, &fsfile);
4745 +                                       }
4746 +                               }
4747 +                               hs->script = 0;
4748 +                               hs->state = HTTP_FILE;
4749 +                               hs->dataptr = fsfile.data;
4750 +                               hs->count = fsfile.len;
4751 +                       }
4752 +                       if(hs->state == HTTP_FIRMWARE)
4753 +                       {
4754 +                               unsigned char *start = (unsigned char*)uip_appdata;
4755 +                               char *clen = strstr(start, "Content-Length:");
4756 +                               int len = 0;
4757 +                               unsigned char *next, *end;
4758 +                               unsigned char *boundary_start;
4759 +                               int i;
4760 +                               uip_appdata[uip_len] = '\0';
4761 +                               if(clen)
4762 +                               {
4763 +                                       clen += sizeof("Content-Length:");
4764 +                                       next = strstr(clen, eol);
4765 +                                       if(next)
4766 +                                       {
4767 +                                               len = atoi(clen);
4768 +                                               next++;
4769 +                                               printf("expecting %d bytes\n", len);
4770 +                                               upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
4771 +                                               printf("received data will be stored at 0x%08X\n", upload_data);
4772 +                                               if(!upload_data)
4773 +                                               {
4774 +                                                       printf("failed to allocate memory\n");
4775 +                                                       uip_close();
4776 +                                                       return;
4777 +                                               }
4778 +                                       } else {
4779 +                                               uip_close();
4780 +                                               return;
4781 +                                       }
4782 +                               }
4783 +                               if(len < 4 * 1024)
4784 +                               {
4785 +                                       uip_close();
4786 +                                       return;
4787 +                               }
4788 +                               boundary_start = strstr(next, "---");
4789 +                               if(!boundary_start)
4790 +                               {
4791 +                                       uip_close();
4792 +                                       return;
4793 +                               }
4794 +                               end = strstr(boundary_start, eol);
4795 +                               if(!eol)
4796 +                               {
4797 +                                       uip_close();
4798 +                                       return;
4799 +                               }
4800 +                               boundary_len = end - boundary_start;
4801 +                               memcpy(boundary, boundary_start, boundary_len);
4802 +                               boundary[boundary_len] = 0;
4803 +                               next = strstr(boundary_start, "name=\"firmware\";");
4804 +                               if(!next)
4805 +                               {
4806 +                                       uip_close();
4807 +                                       return;
4808 +                               }
4809 +                               next = strstr(next, eol2);
4810 +                               if(!next)
4811 +                               {
4812 +                                       printf("could not find start of data\n");
4813 +                                       uip_close();
4814 +                                       return;
4815 +                               }
4816 +                               next += 4;
4817 +                               hs->script = 0;
4818 +                               hs->state = HTTP_FIRMWARE;
4819 +                               hs->upload = uip_len - (next - start);
4820 +                               hs->upload_total = len - (int)(next - boundary_start);
4821 +                               hs->upload_total -= (strlen(boundary) + 6);
4822 +                               //printf("storing %d bytes at %p\n", (int)hs->upload, upload_data);
4823 +                               for(i = 0; i < hs->upload; i++)
4824 +                                       upload_data[i] = next[i];
4825 +                               upload_data += (int)hs->upload;
4826 +                               printf("%d / %d\n", (int)hs->upload, hs->upload_total);
4827 +                               uip_slen = 0;
4828 +                               return;
4829 +                       }
4830 +               }
4831 +
4832 +               if(hs->state == HTTP_FIRMWARE)
4833 +               {
4834 +                       if(uip_newdata())
4835 +                       {
4836 +                               int i;
4837 +                               hs->count = 0;
4838 +                               uip_appdata[uip_len] = '\0';
4839 +                               hs->upload += uip_len;
4840 +                               //printf("storing %d bytes at %p\n", uip_len, upload_data);
4841 +                               printf("%d / %d\n", (int)hs->upload, hs->upload_total);
4842 +                               for(i = 0; i < uip_len; i++)
4843 +                                       upload_data[i] = uip_appdata[i];
4844 +                               upload_data += uip_len;
4845 +                               uip_slen = 0;
4846 +                               if(hs->upload >= hs->upload_total)
4847 +                               {
4848 +                                       upload_running = 1;
4849 +                                       NetBootFileXferSize = hs->upload_total;
4850 +                                       fs_open(file_flash_html.name, &fsfile);
4851 +                                       hs->script = 0;
4852 +                                       hs->state = HTTP_FILE;
4853 +                                       hs->dataptr = fsfile.data;
4854 +                                       hs->count = fsfile.len;
4855 +                               }
4856 +                       }
4857 +               }
4858 +               if(hs->state == HTTP_FILE)
4859 +               {
4860 +                       if(uip_acked())
4861 +                       {
4862 +                               if(hs->count >= uip_conn->len)
4863 +                               {
4864 +                                       hs->count -= uip_conn->len;
4865 +                                       hs->dataptr += uip_conn->len;
4866 +                               } else {
4867 +                                       hs->count = 0;
4868 +                               }
4869 +                               if(hs->count == 0)
4870 +                               {
4871 +                                       if(upload_running)
4872 +                                       {
4873 +                                               int i;
4874 +                                               httpd_upload_complete = 1;
4875 +                                       //      for(i = 0; i < hs->upload_total; i++)
4876 +                                       //              printf("%c", httpd_upload_data[i]);
4877 +                                       }
4878 +                                       uip_close();
4879 +                               }
4880 +                       }
4881 +                       uip_send(hs->dataptr, hs->count);
4882 +               }
4883 +               break;
4884 +
4885 +       default:
4886 +               uip_abort();
4887 +               break;
4888 +       }
4889 +}
4890 --- /dev/null
4891 +++ b/net/uip-0.9/httpd.h
4892 @@ -0,0 +1,83 @@
4893 +/**
4894 + * \addtogroup httpd
4895 + * @{
4896 + */
4897 +
4898 +/**
4899 + * \file
4900 + * HTTP server header file.
4901 + * \author Adam Dunkels <adam@dunkels.com>
4902 + */
4903 +
4904 +/*
4905 + * Copyright (c) 2001, Adam Dunkels.
4906 + * All rights reserved. 
4907 + *
4908 + * Redistribution and use in source and binary forms, with or without 
4909 + * modification, are permitted provided that the following conditions 
4910 + * are met: 
4911 + * 1. Redistributions of source code must retain the above copyright 
4912 + *    notice, this list of conditions and the following disclaimer. 
4913 + * 2. Redistributions in binary form must reproduce the above copyright 
4914 + *    notice, this list of conditions and the following disclaimer in the 
4915 + *    documentation and/or other materials provided with the distribution. 
4916 + * 3. The name of the author may not be used to endorse or promote
4917 + *    products derived from this software without specific prior
4918 + *    written permission.  
4919 + *
4920 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4921 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4922 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4923 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4924 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4925 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4926 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4927 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4928 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4929 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4930 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
4931 + *
4932 + * This file is part of the uIP TCP/IP stack.
4933 + *
4934 + * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $
4935 + *
4936 + */
4937 +
4938 +#ifndef __HTTPD_H__
4939 +#define __HTTPD_H__
4940 +
4941 +void httpd_init(void);
4942 +void httpd_appcall(void);
4943 +
4944 +/* UIP_APPCALL: the name of the application function. This function
4945 +   must return void and take no arguments (i.e., C type "void
4946 +   appfunc(void)"). */
4947 +#ifndef UIP_APPCALL
4948 +#define UIP_APPCALL            httpd_appcall
4949 +#endif
4950 +
4951 +struct httpd_state {
4952 +  u8_t state;
4953 +  u16_t count;
4954 +  char *dataptr;
4955 +  char *script;
4956 +  unsigned int upload;
4957 +  unsigned int upload_total;
4958 +};
4959 +
4960 +
4961 +/* UIP_APPSTATE_SIZE: The size of the application-specific state
4962 +   stored in the uip_conn structure. */
4963 +#ifndef UIP_APPSTATE_SIZE
4964 +#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
4965 +#endif
4966 +
4967 +#define FS_STATISTICS 1
4968 +
4969 +extern struct httpd_state *hs;
4970 +
4971 +
4972 +/* we copy the data to RAM+10MB */
4973 +#define TMP_DATA 0x8A100000
4974 +
4975 +#endif /* __HTTPD_H__ */
4976 --- /dev/null
4977 +++ b/net/uip-0.9/main.c
4978 @@ -0,0 +1,88 @@
4979 +/*
4980 + * Copyright (c) 2001-2003, Adam Dunkels.
4981 + * All rights reserved. 
4982 + *
4983 + * Redistribution and use in source and binary forms, with or without 
4984 + * modification, are permitted provided that the following conditions 
4985 + * are met: 
4986 + * 1. Redistributions of source code must retain the above copyright 
4987 + *    notice, this list of conditions and the following disclaimer. 
4988 + * 2. Redistributions in binary form must reproduce the above copyright 
4989 + *    notice, this list of conditions and the following disclaimer in the 
4990 + *    documentation and/or other materials provided with the distribution. 
4991 + * 3. The name of the author may not be used to endorse or promote
4992 + *    products derived from this software without specific prior
4993 + *    written permission.  
4994 + *
4995 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4996 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4997 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4998 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4999 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5000 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5001 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5002 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5003 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5004 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
5006 + *
5007 + * This file is part of the uIP TCP/IP stack.
5008 + *
5009 + * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $
5010 + *
5011 + */
5012 +
5013 +
5014 +#include "uip.h"
5015 +#include "uip_arp.h"
5016 +#include "tapdev.h"
5017 +#include "httpd.h"
5018 +
5019 +#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
5020 +
5021 +#ifndef NULL
5022 +#define NULL (void *)0
5023 +#endif /* NULL */
5024 +
5025 +/*-----------------------------------------------------------------------------------*/
5026 +int
5027 +main(void)
5028 +{
5029 +       u8_t i, arptimer;
5030 +       tapdev_init();
5031 +       uip_init();
5032 +       httpd_init();
5033 +       arptimer = 0;
5034 +       while(1) {
5035 +               uip_len = tapdev_read();
5036 +               if(uip_len == 0) {
5037 +                       for(i = 0; i < UIP_CONNS; i++) {
5038 +                               uip_periodic(i);
5039 +                               if(uip_len > 0) {
5040 +                                       uip_arp_out();
5041 +                                       tapdev_send();
5042 +                               }
5043 +                       }
5044 +
5045 +                       if(++arptimer == 20) {
5046 +                               uip_arp_timer();
5047 +                               arptimer = 0;
5048 +                       }
5049 +               } else {
5050 +                       if(BUF->type == htons(UIP_ETHTYPE_IP)) {
5051 +                               uip_arp_ipin();
5052 +                               uip_input();
5053 +                               if(uip_len > 0) {
5054 +                                       uip_arp_out();
5055 +                                       tapdev_send();
5056 +                               }
5057 +                       } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
5058 +                               uip_arp_arpin();
5059 +                               if(uip_len > 0) {
5060 +                                       tapdev_send();
5061 +                               }
5062 +                       }
5063 +               }
5064 +       }
5065 +       return 0;
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.c
5309 @@ -0,0 +1,1503 @@
5310 +/**
5311 + * \addtogroup uip
5312 + * @{
5313 + */
5314 +
5315 +/**
5316 + * \file
5317 + * The uIP TCP/IP stack code.
5318 + * \author Adam Dunkels <adam@dunkels.com>
5319 + */
5320 +
5321 +/*
5322 + * Copyright (c) 2001-2003, Adam Dunkels.
5323 + * All rights reserved. 
5324 + *
5325 + * Redistribution and use in source and binary forms, with or without 
5326 + * modification, are permitted provided that the following conditions 
5327 + * are met: 
5328 + * 1. Redistributions of source code must retain the above copyright 
5329 + *    notice, this list of conditions and the following disclaimer. 
5330 + * 2. Redistributions in binary form must reproduce the above copyright 
5331 + *    notice, this list of conditions and the following disclaimer in the 
5332 + *    documentation and/or other materials provided with the distribution. 
5333 + * 3. The name of the author may not be used to endorse or promote
5334 + *    products derived from this software without specific prior
5335 + *    written permission.  
5336 + *
5337 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5338 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5339 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5340 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5341 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5342 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5343 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5344 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5345 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5346 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5347 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
5348 + *
5349 + * This file is part of the uIP TCP/IP stack.
5350 + *
5351 + * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
5352 + *
5353 + */
5354 +
5355 +/*
5356 +This is a small implementation of the IP and TCP protocols (as well as
5357 +some basic ICMP stuff). The implementation couples the IP, TCP and the
5358 +application layers very tightly. To keep the size of the compiled code
5359 +down, this code also features heavy usage of the goto statement.
5360 +
5361 +The principle is that we have a small buffer, called the uip_buf, in
5362 +which the device driver puts an incoming packet. The TCP/IP stack
5363 +parses the headers in the packet, and calls upon the application. If
5364 +the remote host has sent data to the application, this data is present
5365 +in the uip_buf and the application read the data from there. It is up
5366 +to the application to put this data into a byte stream if needed. The
5367 +application will not be fed with data that is out of sequence.
5368 +
5369 +If the application whishes to send data to the peer, it should put its
5370 +data into the uip_buf, 40 bytes from the start of the buffer. The
5371 +TCP/IP stack will calculate the checksums, and fill in the necessary
5372 +header fields and finally send the packet back to the peer.
5373 +*/
5374 +
5375 +#include "uip.h"
5376 +#include "uipopt.h"
5377 +#include "uip_arch.h"
5378 +
5379 +/*-----------------------------------------------------------------------------------*/
5380 +/* Variable definitions. */
5381 +
5382 +
5383 +/* 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 */
5384 +#if UIP_FIXEDADDR > 0
5385 +const unsigned short int uip_hostaddr[2] =
5386 +  {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
5387 +   HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
5388 +const unsigned short int uip_arp_draddr[2] =
5389 +  {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
5390 +   HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
5391 +const unsigned short int uip_arp_netmask[2] =
5392 +  {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
5393 +   HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
5394 +#else
5395 +unsigned short int uip_hostaddr[2];       
5396 +unsigned short int uip_arp_draddr[2], uip_arp_netmask[2];
5397 +#endif /* UIP_FIXEDADDR */
5398 +
5399 +u8_t uip_buf[UIP_BUFSIZE+2];   /* The packet buffer that contains
5400 +                               incoming packets. */
5401 +volatile u8_t *uip_appdata;  /* The uip_appdata pointer points to
5402 +                               application data. */
5403 +volatile u8_t *uip_sappdata;  /* The uip_appdata pointer points to the
5404 +                                application data which is to be sent. */
5405 +#if UIP_URGDATA > 0
5406 +volatile u8_t *uip_urgdata;  /* The uip_urgdata pointer points to
5407 +                               urgent data (out-of-band data), if
5408 +                               present. */
5409 +volatile u8_t uip_urglen, uip_surglen;
5410 +#endif /* UIP_URGDATA > 0 */
5411 +
5412 +volatile unsigned short int uip_len, uip_slen;
5413 +                             /* The uip_len is either 8 or 16 bits,
5414 +                               depending on the maximum packet
5415 +                               size. */
5416 +
5417 +volatile u8_t uip_flags;     /* The uip_flags variable is used for
5418 +                               communication between the TCP/IP stack
5419 +                               and the application program. */
5420 +struct uip_conn *uip_conn;   /* uip_conn always points to the current
5421 +                               connection. */
5422 +
5423 +struct uip_conn uip_conns[UIP_CONNS];
5424 +                             /* The uip_conns array holds all TCP
5425 +                               connections. */
5426 +unsigned short int uip_listenports[UIP_LISTENPORTS];
5427 +                             /* The uip_listenports list all currently
5428 +                               listning ports. */
5429 +#if UIP_UDP
5430 +struct uip_udp_conn *uip_udp_conn;
5431 +struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
5432 +#endif /* UIP_UDP */
5433 +
5434 +
5435 +static unsigned short int ipid;           /* Ths ipid variable is an increasing
5436 +                               number that is used for the IP ID
5437 +                               field. */
5438 +
5439 +static u8_t iss[4];          /* The iss variable is used for the TCP
5440 +                               initial sequence number. */
5441 +
5442 +#if UIP_ACTIVE_OPEN
5443 +static unsigned short int lastport;       /* Keeps track of the last port used for
5444 +                               a new connection. */
5445 +#endif /* UIP_ACTIVE_OPEN */
5446 +
5447 +/* Temporary variables. */
5448 +volatile u8_t uip_acc32[4];
5449 +static u8_t c, opt;
5450 +static unsigned short int tmp16;
5451 +
5452 +/* Structures and definitions. */
5453 +#define TCP_FIN 0x01
5454 +#define TCP_SYN 0x02
5455 +#define TCP_RST 0x04
5456 +#define TCP_PSH 0x08
5457 +#define TCP_ACK 0x10
5458 +#define TCP_URG 0x20
5459 +#define TCP_CTL 0x3f
5460 +
5461 +#define ICMP_ECHO_REPLY 0
5462 +#define ICMP_ECHO       8     
5463 +
5464 +/* Macros. */
5465 +#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
5466 +#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
5467 +#define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
5468 +#define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
5469 +
5470 +#if UIP_STATISTICS == 1
5471 +struct uip_stats uip_stat;
5472 +#define UIP_STAT(s) s
5473 +#else
5474 +#define UIP_STAT(s)
5475 +#endif /* UIP_STATISTICS == 1 */
5476 +
5477 +#if UIP_LOGGING == 1
5478 +extern void puts(const char *s);
5479 +#define UIP_LOG(m) puts(m)
5480 +#else
5481 +#define UIP_LOG(m)
5482 +#endif /* UIP_LOGGING == 1 */
5483 +
5484 +/*-----------------------------------------------------------------------------------*/
5485 +void
5486 +uip_init(void)
5487 +{
5488 +  for(c = 0; c < UIP_LISTENPORTS; ++c) {
5489 +    uip_listenports[c] = 0;
5490 +  }
5491 +  for(c = 0; c < UIP_CONNS; ++c) {
5492 +    uip_conns[c].tcpstateflags = CLOSED;
5493 +  }
5494 +#if UIP_ACTIVE_OPEN
5495 +  lastport = 1024;
5496 +#endif /* UIP_ACTIVE_OPEN */
5497 +
5498 +#if UIP_UDP
5499 +  for(c = 0; c < UIP_UDP_CONNS; ++c) {
5500 +    uip_udp_conns[c].lport = 0;
5501 +  }
5502 +#endif /* UIP_UDP */
5503 +  
5504 +
5505 +  /* IPv4 initialization. */
5506 +#if UIP_FIXEDADDR == 0
5507 +  uip_hostaddr[0] = uip_hostaddr[1] = 0;
5508 +#endif /* UIP_FIXEDADDR */
5509 +
5510 +}
5511 +/*-----------------------------------------------------------------------------------*/
5512 +#if UIP_ACTIVE_OPEN
5513 +struct uip_conn *
5514 +uip_connect(unsigned short int *ripaddr, unsigned short int rport)
5515 +{
5516 +  register struct uip_conn *conn, *cconn;
5517 +  
5518 +  /* Find an unused local port. */
5519 + again:
5520 +  ++lastport;
5521 +
5522 +  if(lastport >= 32000) {
5523 +    lastport = 4096;
5524 +  }
5525 +
5526 +  /* Check if this port is already in use, and if so try to find
5527 +     another one. */
5528 +  for(c = 0; c < UIP_CONNS; ++c) {
5529 +    conn = &uip_conns[c];
5530 +    if(conn->tcpstateflags != CLOSED &&
5531 +       conn->lport == htons(lastport)) {
5532 +      goto again;
5533 +    }
5534 +  }
5535 +
5536 +
5537 +  conn = 0;
5538 +  for(c = 0; c < UIP_CONNS; ++c) {
5539 +    cconn = &uip_conns[c]; 
5540 +    if(cconn->tcpstateflags == CLOSED) {
5541 +      conn = cconn;
5542 +      break;
5543 +    }
5544 +    if(cconn->tcpstateflags == TIME_WAIT) {
5545 +      if(conn == 0 ||
5546 +        cconn->timer > uip_conn->timer) {
5547 +       conn = cconn;
5548 +      }
5549 +    }
5550 +  }
5551 +
5552 +  if(conn == 0) {
5553 +    return 0;
5554 +  }
5555 +  
5556 +  conn->tcpstateflags = SYN_SENT;
5557 +
5558 +  conn->snd_nxt[0] = iss[0];
5559 +  conn->snd_nxt[1] = iss[1];
5560 +  conn->snd_nxt[2] = iss[2];
5561 +  conn->snd_nxt[3] = iss[3];
5562 +
5563 +  conn->initialmss = conn->mss = UIP_TCP_MSS;
5564 +  
5565 +  conn->len = 1;   /* TCP length of the SYN is one. */
5566 +  conn->nrtx = 0;
5567 +  conn->timer = 1; /* Send the SYN next time around. */
5568 +  conn->rto = UIP_RTO;
5569 +  conn->sa = 0;
5570 +  conn->sv = 16;
5571 +  conn->lport = htons(lastport);
5572 +  conn->rport = rport;
5573 +  conn->ripaddr[0] = ripaddr[0];
5574 +  conn->ripaddr[1] = ripaddr[1];
5575 +  
5576 +  return conn;
5577 +}
5578 +#endif /* UIP_ACTIVE_OPEN */
5579 +/*-----------------------------------------------------------------------------------*/
5580 +#if UIP_UDP
5581 +struct uip_udp_conn *
5582 +uip_udp_new(unsigned short int *ripaddr, unsigned short int rport)
5583 +{
5584 +  register struct uip_udp_conn *conn;
5585 +  
5586 +  /* Find an unused local port. */
5587 + again:
5588 +  ++lastport;
5589 +
5590 +  if(lastport >= 32000) {
5591 +    lastport = 4096;
5592 +  }
5593 +  
5594 +  for(c = 0; c < UIP_UDP_CONNS; ++c) {
5595 +    if(uip_udp_conns[c].lport == lastport) {
5596 +      goto again;
5597 +    }
5598 +  }
5599 +
5600 +
5601 +  conn = 0;
5602 +  for(c = 0; c < UIP_UDP_CONNS; ++c) {
5603 +    if(uip_udp_conns[c].lport == 0) {
5604 +      conn = &uip_udp_conns[c]; 
5605 +      break;
5606 +    }
5607 +  }
5608 +
5609 +  if(conn == 0) {
5610 +    return 0;
5611 +  }
5612 +  
5613 +  conn->lport = HTONS(lastport);
5614 +  conn->rport = HTONS(rport);
5615 +  conn->ripaddr[0] = ripaddr[0];
5616 +  conn->ripaddr[1] = ripaddr[1];
5617 +  
5618 +  return conn;
5619 +}
5620 +#endif /* UIP_UDP */
5621 +/*-----------------------------------------------------------------------------------*/
5622 +void
5623 +uip_unlisten(unsigned short int port)
5624 +{
5625 +  for(c = 0; c < UIP_LISTENPORTS; ++c) {
5626 +    if(uip_listenports[c] == port) {
5627 +      uip_listenports[c] = 0;
5628 +      return;
5629 +    }
5630 +  }
5631 +}
5632 +/*-----------------------------------------------------------------------------------*/
5633 +void
5634 +uip_listen(unsigned short int port)
5635 +{
5636 +  for(c = 0; c < UIP_LISTENPORTS; ++c) {
5637 +    if(uip_listenports[c] == 0) {
5638 +      uip_listenports[c] = port;
5639 +      return;
5640 +    }
5641 +  }
5642 +}
5643 +/*-----------------------------------------------------------------------------------*/
5644 +/* XXX: IP fragment reassembly: not well-tested. */
5645 +
5646 +#if UIP_REASSEMBLY
5647 +#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
5648 +static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
5649 +static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
5650 +static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
5651 +                                   0x0f, 0x07, 0x03, 0x01};
5652 +static unsigned short int uip_reasslen;
5653 +static u8_t uip_reassflags;
5654 +#define UIP_REASS_FLAG_LASTFRAG 0x01
5655 +static u8_t uip_reasstmr;
5656 +
5657 +#define IP_HLEN 20
5658 +#define IP_MF   0x20
5659 +
5660 +static u8_t
5661 +uip_reass(void)
5662 +{
5663 +  unsigned short int offset, len;
5664 +  unsigned short int i;
5665 +
5666 +  /* If ip_reasstmr is zero, no packet is present in the buffer, so we
5667 +     write the IP header of the fragment into the reassembly
5668 +     buffer. The timer is updated with the maximum age. */
5669 +  if(uip_reasstmr == 0) {
5670 +    memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
5671 +    uip_reasstmr = UIP_REASS_MAXAGE;
5672 +    uip_reassflags = 0;
5673 +    /* Clear the bitmap. */
5674 +    memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
5675 +  }
5676 +
5677 +  /* Check if the incoming fragment matches the one currently present
5678 +     in the reasembly buffer. If so, we proceed with copying the
5679 +     fragment into the buffer. */
5680 +  if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
5681 +     BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
5682 +     BUF->destipaddr[0] == FBUF->destipaddr[0] &&
5683 +     BUF->destipaddr[1] == FBUF->destipaddr[1] &&
5684 +     BUF->ipid[0] == FBUF->ipid[0] &&
5685 +     BUF->ipid[1] == FBUF->ipid[1]) {
5686 +
5687 +    len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
5688 +    offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
5689 +
5690 +    /* If the offset or the offset + fragment length overflows the
5691 +       reassembly buffer, we discard the entire packet. */
5692 +    if(offset > UIP_REASS_BUFSIZE ||
5693 +       offset + len > UIP_REASS_BUFSIZE) {
5694 +      uip_reasstmr = 0;
5695 +      goto nullreturn;
5696 +    }
5697 +
5698 +    /* Copy the fragment into the reassembly buffer, at the right
5699 +       offset. */
5700 +    memcpy(&uip_reassbuf[IP_HLEN + offset],
5701 +          (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
5702 +          len);
5703 +      
5704 +    /* Update the bitmap. */
5705 +    if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
5706 +      /* If the two endpoints are in the same byte, we only update
5707 +        that byte. */
5708 +            
5709 +      uip_reassbitmap[offset / (8 * 8)] |=
5710 +            bitmap_bits[(offset / 8 ) & 7] &
5711 +            ~bitmap_bits[((offset + len) / 8 ) & 7];
5712 +    } else {
5713 +      /* If the two endpoints are in different bytes, we update the
5714 +        bytes in the endpoints and fill the stuff inbetween with
5715 +        0xff. */
5716 +      uip_reassbitmap[offset / (8 * 8)] |=
5717 +       bitmap_bits[(offset / 8 ) & 7];
5718 +      for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
5719 +       uip_reassbitmap[i] = 0xff;
5720 +      }      
5721 +      uip_reassbitmap[(offset + len) / (8 * 8)] |=
5722 +       ~bitmap_bits[((offset + len) / 8 ) & 7];
5723 +    }
5724 +    
5725 +    /* If this fragment has the More Fragments flag set to zero, we
5726 +       know that this is the last fragment, so we can calculate the
5727 +       size of the entire packet. We also set the
5728 +       IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
5729 +       the final fragment. */
5730 +
5731 +    if((BUF->ipoffset[0] & IP_MF) == 0) {
5732 +      uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
5733 +      uip_reasslen = offset + len;
5734 +    }
5735 +    
5736 +    /* Finally, we check if we have a full packet in the buffer. We do
5737 +       this by checking if we have the last fragment and if all bits
5738 +       in the bitmap are set. */
5739 +    if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
5740 +      /* Check all bytes up to and including all but the last byte in
5741 +        the bitmap. */
5742 +      for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
5743 +       if(uip_reassbitmap[i] != 0xff) {
5744 +         goto nullreturn;
5745 +       }
5746 +      }
5747 +      /* Check the last byte in the bitmap. It should contain just the
5748 +        right amount of bits. */
5749 +      if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
5750 +        (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
5751 +       goto nullreturn;
5752 +      }
5753 +
5754 +      /* If we have come this far, we have a full packet in the
5755 +        buffer, so we allocate a pbuf and copy the packet into it. We
5756 +        also reset the timer. */
5757 +      uip_reasstmr = 0;
5758 +      memcpy(BUF, FBUF, uip_reasslen);
5759 +
5760 +      /* Pretend to be a "normal" (i.e., not fragmented) IP packet
5761 +        from now on. */
5762 +      BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
5763 +      BUF->len[0] = uip_reasslen >> 8;
5764 +      BUF->len[1] = uip_reasslen & 0xff;
5765 +      BUF->ipchksum = 0;
5766 +      BUF->ipchksum = ~(uip_ipchksum());
5767 +
5768 +      return uip_reasslen;
5769 +    }
5770 +  }
5771 +
5772 + nullreturn:
5773 +  return 0;
5774 +}
5775 +#endif /* UIP_REASSEMBL */
5776 +/*-----------------------------------------------------------------------------------*/
5777 +static void
5778 +uip_add_rcv_nxt(unsigned short int n)
5779 +{
5780 +  uip_add32(uip_conn->rcv_nxt, n);
5781 +  uip_conn->rcv_nxt[0] = uip_acc32[0];
5782 +  uip_conn->rcv_nxt[1] = uip_acc32[1];
5783 +  uip_conn->rcv_nxt[2] = uip_acc32[2];
5784 +  uip_conn->rcv_nxt[3] = uip_acc32[3];
5785 +}
5786 +/*-----------------------------------------------------------------------------------*/
5787 +void
5788 +uip_process(u8_t flag)
5789 +{
5790 +  register struct uip_conn *uip_connr = uip_conn;
5791 +  
5792 +  uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
5793 +
5794 +  
5795 +  /* Check if we were invoked because of the perodic timer fireing. */
5796 +  if(flag == UIP_TIMER) {
5797 +#if UIP_REASSEMBLY
5798 +    if(uip_reasstmr != 0) {
5799 +      --uip_reasstmr;
5800 +    }
5801 +#endif /* UIP_REASSEMBLY */
5802 +    /* Increase the initial sequence number. */
5803 +    if(++iss[3] == 0) {
5804 +      if(++iss[2] == 0) {
5805 +       if(++iss[1] == 0) {
5806 +         ++iss[0];
5807 +       }
5808 +      }
5809 +    }    
5810 +    uip_len = 0;
5811 +    if(uip_connr->tcpstateflags == TIME_WAIT ||
5812 +       uip_connr->tcpstateflags == FIN_WAIT_2) {
5813 +      ++(uip_connr->timer);
5814 +      if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
5815 +       uip_connr->tcpstateflags = CLOSED;
5816 +      }
5817 +    } else if(uip_connr->tcpstateflags != CLOSED) {
5818 +      /* If the connection has outstanding data, we increase the
5819 +        connection's timer and see if it has reached the RTO value
5820 +        in which case we retransmit. */
5821 +      if(uip_outstanding(uip_connr)) {
5822 +       if(uip_connr->timer-- == 0) {
5823 +         if(uip_connr->nrtx == UIP_MAXRTX ||
5824 +            ((uip_connr->tcpstateflags == SYN_SENT ||
5825 +              uip_connr->tcpstateflags == SYN_RCVD) &&
5826 +             uip_connr->nrtx == UIP_MAXSYNRTX)) {
5827 +           uip_connr->tcpstateflags = CLOSED;
5828 +
5829 +           /* We call UIP_APPCALL() with uip_flags set to
5830 +              UIP_TIMEDOUT to inform the application that the
5831 +              connection has timed out. */
5832 +           uip_flags = UIP_TIMEDOUT;
5833 +           UIP_APPCALL();
5834 +
5835 +           /* We also send a reset packet to the remote host. */
5836 +           BUF->flags = TCP_RST | TCP_ACK;
5837 +           goto tcp_send_nodata;
5838 +         }
5839 +
5840 +         /* Exponential backoff. */
5841 +         uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
5842 +                                        4:
5843 +                                        uip_connr->nrtx);
5844 +         ++(uip_connr->nrtx);
5845 +         
5846 +         /* Ok, so we need to retransmit. We do this differently
5847 +            depending on which state we are in. In ESTABLISHED, we
5848 +            call upon the application so that it may prepare the
5849 +            data for the retransmit. In SYN_RCVD, we resend the
5850 +            SYNACK that we sent earlier and in LAST_ACK we have to
5851 +            retransmit our FINACK. */
5852 +         UIP_STAT(++uip_stat.tcp.rexmit);
5853 +         switch(uip_connr->tcpstateflags & TS_MASK) {
5854 +         case SYN_RCVD:
5855 +           /* In the SYN_RCVD state, we should retransmit our
5856 +               SYNACK. */
5857 +           goto tcp_send_synack;
5858 +           
5859 +#if UIP_ACTIVE_OPEN
5860 +         case SYN_SENT:
5861 +           /* In the SYN_SENT state, we retransmit out SYN. */
5862 +           BUF->flags = 0;
5863 +           goto tcp_send_syn;
5864 +#endif /* UIP_ACTIVE_OPEN */
5865 +           
5866 +         case ESTABLISHED:
5867 +           /* In the ESTABLISHED state, we call upon the application
5868 +               to do the actual retransmit after which we jump into
5869 +               the code for sending out the packet (the apprexmit
5870 +               label). */
5871 +           uip_len = 0;
5872 +           uip_slen = 0;
5873 +           uip_flags = UIP_REXMIT;
5874 +           UIP_APPCALL();
5875 +           goto apprexmit;
5876 +           
5877 +         case FIN_WAIT_1:
5878 +         case CLOSING:
5879 +         case LAST_ACK:
5880 +           /* In all these states we should retransmit a FINACK. */
5881 +           goto tcp_send_finack;
5882 +           
5883 +         }
5884 +       }
5885 +      } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
5886 +       /* If there was no need for a retransmission, we poll the
5887 +           application for new data. */
5888 +       uip_len = 0;
5889 +       uip_slen = 0;
5890 +       uip_flags = UIP_POLL;
5891 +       UIP_APPCALL();
5892 +       goto appsend;
5893 +      }
5894 +    }
5895 +    goto drop;
5896 +  }
5897 +#if UIP_UDP 
5898 +  if(flag == UIP_UDP_TIMER) {
5899 +    if(uip_udp_conn->lport != 0) {
5900 +      uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
5901 +      uip_len = uip_slen = 0;
5902 +      uip_flags = UIP_POLL;
5903 +      UIP_UDP_APPCALL();
5904 +      goto udp_send;
5905 +    } else {
5906 +      goto drop;
5907 +    }
5908 +  }
5909 +#endif
5910 +
5911 +  /* This is where the input processing starts. */
5912 +  UIP_STAT(++uip_stat.ip.recv);
5913 +
5914 +
5915 +  /* Start of IPv4 input header processing code. */
5916 +  
5917 +  /* Check validity of the IP header. */  
5918 +  if(BUF->vhl != 0x45)  { /* IP version and header length. */
5919 +    UIP_STAT(++uip_stat.ip.drop);
5920 +    UIP_STAT(++uip_stat.ip.vhlerr);
5921 +    UIP_LOG("ip: invalid version or header length.");
5922 +    goto drop;
5923 +  }
5924 +  
5925 +  /* Check the size of the packet. If the size reported to us in
5926 +     uip_len doesn't match the size reported in the IP header, there
5927 +     has been a transmission error and we drop the packet. */
5928 +  
5929 +  if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
5930 +    uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
5931 +  }
5932 +  if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
5933 +    uip_len = (uip_len & 0xff00) | BUF->len[1];
5934 +  }
5935 +
5936 +  /* Check the fragment flag. */
5937 +  if((BUF->ipoffset[0] & 0x3f) != 0 ||
5938 +     BUF->ipoffset[1] != 0) { 
5939 +#if UIP_REASSEMBLY
5940 +    uip_len = uip_reass();
5941 +    if(uip_len == 0) {
5942 +      goto drop;
5943 +    }
5944 +#else
5945 +    UIP_STAT(++uip_stat.ip.drop);
5946 +    UIP_STAT(++uip_stat.ip.fragerr);
5947 +    UIP_LOG("ip: fragment dropped.");    
5948 +    goto drop;
5949 +#endif /* UIP_REASSEMBLY */
5950 +  }
5951 +
5952 +  /* If we are configured to use ping IP address configuration and
5953 +     hasn't been assigned an IP address yet, we accept all ICMP
5954 +     packets. */
5955 +#if UIP_PINGADDRCONF
5956 +  if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
5957 +    if(BUF->proto == UIP_PROTO_ICMP) {
5958 +      UIP_LOG("ip: possible ping config packet received.");
5959 +      goto icmp_input;
5960 +    } else {
5961 +      UIP_LOG("ip: packet dropped since no address assigned.");
5962 +      goto drop;
5963 +    }
5964 +  }
5965 +#endif /* UIP_PINGADDRCONF */
5966 +  
5967 +  /* Check if the packet is destined for our IP address. */  
5968 +  if(BUF->destipaddr[0] != uip_hostaddr[0]) {
5969 +    UIP_STAT(++uip_stat.ip.drop);
5970 +    UIP_LOG("ip: packet not for us.");        
5971 +    goto drop;
5972 +  }
5973 +  if(BUF->destipaddr[1] != uip_hostaddr[1]) {
5974 +    UIP_STAT(++uip_stat.ip.drop);
5975 +    UIP_LOG("ip: packet not for us.");        
5976 +    goto drop;
5977 +  }
5978 +
5979 +  if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
5980 +                                   checksum. */
5981 +    UIP_STAT(++uip_stat.ip.drop);
5982 +    UIP_STAT(++uip_stat.ip.chkerr);
5983 +    UIP_LOG("ip: bad checksum.");    
5984 +    goto drop;
5985 +  }
5986 +
5987 +  if(BUF->proto == UIP_PROTO_TCP)  /* Check for TCP packet. If so, jump
5988 +                                     to the tcp_input label. */
5989 +    goto tcp_input;
5990 +
5991 +#if UIP_UDP
5992 +  if(BUF->proto == UIP_PROTO_UDP)
5993 +    goto udp_input;
5994 +#endif /* UIP_UDP */
5995 +
5996 +  if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
5997 +                                       here. */
5998 +    UIP_STAT(++uip_stat.ip.drop);
5999 +    UIP_STAT(++uip_stat.ip.protoerr);
6000 +    UIP_LOG("ip: neither tcp nor icmp.");        
6001 +    goto drop;
6002 +  }
6003 +  
6004 + //icmp_input:
6005 +  UIP_STAT(++uip_stat.icmp.recv);
6006 +  
6007 +  /* ICMP echo (i.e., ping) processing. This is simple, we only change
6008 +     the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
6009 +     checksum before we return the packet. */
6010 +  if(ICMPBUF->type != ICMP_ECHO) {
6011 +    UIP_STAT(++uip_stat.icmp.drop);
6012 +    UIP_STAT(++uip_stat.icmp.typeerr);
6013 +    UIP_LOG("icmp: not icmp echo.");
6014 +    goto drop;
6015 +  }
6016 +
6017 +  /* If we are configured to use ping IP address assignment, we use
6018 +     the destination IP address of this ping packet and assign it to
6019 +     ourself. */
6020 +#if UIP_PINGADDRCONF
6021 +  if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
6022 +    uip_hostaddr[0] = BUF->destipaddr[0];
6023 +    uip_hostaddr[1] = BUF->destipaddr[1];
6024 +  }
6025 +#endif /* UIP_PINGADDRCONF */  
6026 +  
6027 +  ICMPBUF->type = ICMP_ECHO_REPLY;
6028 +  
6029 +  if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
6030 +    ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
6031 +  } else {
6032 +    ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
6033 +  }
6034 +  
6035 +  /* Swap IP addresses. */
6036 +  tmp16 = BUF->destipaddr[0];
6037 +  BUF->destipaddr[0] = BUF->srcipaddr[0];
6038 +  BUF->srcipaddr[0] = tmp16;
6039 +  tmp16 = BUF->destipaddr[1];
6040 +  BUF->destipaddr[1] = BUF->srcipaddr[1];
6041 +  BUF->srcipaddr[1] = tmp16;
6042 +
6043 +  UIP_STAT(++uip_stat.icmp.sent);
6044 +  goto send;
6045 +
6046 +  /* End of IPv4 input header processing code. */
6047 +  
6048 +
6049 +#if UIP_UDP
6050 +  /* UDP input processing. */
6051 + udp_input:
6052 +  /* UDP processing is really just a hack. We don't do anything to the
6053 +     UDP/IP headers, but let the UDP application do all the hard
6054 +     work. If the application sets uip_slen, it has a packet to
6055 +     send. */
6056 +#if UIP_UDP_CHECKSUMS
6057 +  if(uip_udpchksum() != 0xffff) { 
6058 +    UIP_STAT(++uip_stat.udp.drop);
6059 +    UIP_STAT(++uip_stat.udp.chkerr);
6060 +    UIP_LOG("udp: bad checksum.");    
6061 +    goto drop;
6062 +  }  
6063 +#endif /* UIP_UDP_CHECKSUMS */
6064 +
6065 +  /* Demultiplex this UDP packet between the UDP "connections". */
6066 +  for(uip_udp_conn = &uip_udp_conns[0];
6067 +      uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
6068 +      ++uip_udp_conn) {
6069 +    if(uip_udp_conn->lport != 0 &&
6070 +       UDPBUF->destport == uip_udp_conn->lport &&
6071 +       (uip_udp_conn->rport == 0 ||
6072 +        UDPBUF->srcport == uip_udp_conn->rport) &&
6073 +       BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
6074 +       BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
6075 +      goto udp_found; 
6076 +    }
6077 +  }
6078 +  goto drop;
6079 +  
6080 + udp_found:
6081 +  uip_len = uip_len - 28;
6082 +  uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
6083 +  uip_flags = UIP_NEWDATA;
6084 +  uip_slen = 0;
6085 +  UIP_UDP_APPCALL();
6086 + udp_send:
6087 +  if(uip_slen == 0) {
6088 +    goto drop;      
6089 +  }
6090 +  uip_len = uip_slen + 28;
6091 +
6092 +  BUF->len[0] = (uip_len >> 8);
6093 +  BUF->len[1] = (uip_len & 0xff);
6094 +  
6095 +  BUF->proto = UIP_PROTO_UDP;
6096 +
6097 +  UDPBUF->udplen = HTONS(uip_slen + 8);
6098 +  UDPBUF->udpchksum = 0;
6099 +#if UIP_UDP_CHECKSUMS 
6100 +  /* Calculate UDP checksum. */
6101 +  UDPBUF->udpchksum = ~(uip_udpchksum());
6102 +  if(UDPBUF->udpchksum == 0) {
6103 +    UDPBUF->udpchksum = 0xffff;
6104 +  }
6105 +#endif /* UIP_UDP_CHECKSUMS */
6106 +
6107 +  BUF->srcport  = uip_udp_conn->lport;
6108 +  BUF->destport = uip_udp_conn->rport;
6109 +
6110 +  BUF->srcipaddr[0] = uip_hostaddr[0];
6111 +  BUF->srcipaddr[1] = uip_hostaddr[1];
6112 +  BUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
6113 +  BUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
6114
6115 +  uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
6116 +  goto ip_send_nolen;
6117 +#endif /* UIP_UDP */
6118 +  
6119 +  /* TCP input processing. */  
6120 + tcp_input:
6121 +  UIP_STAT(++uip_stat.tcp.recv);
6122 +
6123 +  /* Start of TCP input header processing code. */
6124 +  
6125 +  if(uip_tcpchksum() != 0xffff) {   /* Compute and check the TCP
6126 +                                      checksum. */
6127 +    UIP_STAT(++uip_stat.tcp.drop);
6128 +    UIP_STAT(++uip_stat.tcp.chkerr);
6129 +    UIP_LOG("tcp: bad checksum.");    
6130 +    goto drop;
6131 +  }
6132 +  
6133 +  /* Demultiplex this segment. */
6134 +  /* First check any active connections. */
6135 +  for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) {
6136 +    if(uip_connr->tcpstateflags != CLOSED &&
6137 +       BUF->destport == uip_connr->lport &&
6138 +       BUF->srcport == uip_connr->rport &&
6139 +       BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
6140 +       BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
6141 +      goto found;    
6142 +    }
6143 +  }
6144 +
6145 +  /* If we didn't find and active connection that expected the packet,
6146 +     either this packet is an old duplicate, or this is a SYN packet
6147 +     destined for a connection in LISTEN. If the SYN flag isn't set,
6148 +     it is an old packet and we send a RST. */
6149 +  if((BUF->flags & TCP_CTL) != TCP_SYN)
6150 +    goto reset;
6151 +  
6152 +  tmp16 = BUF->destport;
6153 +  /* Next, check listening connections. */  
6154 +  for(c = 0; c < UIP_LISTENPORTS; ++c) {
6155 +    if(tmp16 == uip_listenports[c])
6156 +      goto found_listen;
6157 +  }
6158 +  
6159 +  /* No matching connection found, so we send a RST packet. */
6160 +  UIP_STAT(++uip_stat.tcp.synrst);
6161 + reset:
6162 +
6163 +  /* We do not send resets in response to resets. */
6164 +  if(BUF->flags & TCP_RST) 
6165 +    goto drop;
6166 +
6167 +  UIP_STAT(++uip_stat.tcp.rst);
6168 +  
6169 +  BUF->flags = TCP_RST | TCP_ACK;
6170 +  uip_len = 40;
6171 +  BUF->tcpoffset = 5 << 4;
6172 +
6173 +  /* Flip the seqno and ackno fields in the TCP header. */
6174 +  c = BUF->seqno[3];
6175 +  BUF->seqno[3] = BUF->ackno[3];  
6176 +  BUF->ackno[3] = c;
6177 +  
6178 +  c = BUF->seqno[2];
6179 +  BUF->seqno[2] = BUF->ackno[2];  
6180 +  BUF->ackno[2] = c;
6181 +  
6182 +  c = BUF->seqno[1];
6183 +  BUF->seqno[1] = BUF->ackno[1];
6184 +  BUF->ackno[1] = c;
6185 +  
6186 +  c = BUF->seqno[0];
6187 +  BUF->seqno[0] = BUF->ackno[0];  
6188 +  BUF->ackno[0] = c;
6189 +
6190 +  /* We also have to increase the sequence number we are
6191 +     acknowledging. If the least significant byte overflowed, we need
6192 +     to propagate the carry to the other bytes as well. */
6193 +  if(++BUF->ackno[3] == 0) {
6194 +    if(++BUF->ackno[2] == 0) {
6195 +      if(++BUF->ackno[1] == 0) {
6196 +       ++BUF->ackno[0];
6197 +      }
6198 +    }
6199 +  }
6200
6201 +  /* Swap port numbers. */
6202 +  tmp16 = BUF->srcport;
6203 +  BUF->srcport = BUF->destport;
6204 +  BUF->destport = tmp16;
6205 +  
6206 +  /* Swap IP addresses. */
6207 +  tmp16 = BUF->destipaddr[0];
6208 +  BUF->destipaddr[0] = BUF->srcipaddr[0];
6209 +  BUF->srcipaddr[0] = tmp16;
6210 +  tmp16 = BUF->destipaddr[1];
6211 +  BUF->destipaddr[1] = BUF->srcipaddr[1];
6212 +  BUF->srcipaddr[1] = tmp16;
6213 +
6214 +  
6215 +  /* And send out the RST packet! */
6216 +  goto tcp_send_noconn;
6217 +
6218 +  /* This label will be jumped to if we matched the incoming packet
6219 +     with a connection in LISTEN. In that case, we should create a new
6220 +     connection and send a SYNACK in return. */
6221 + found_listen:
6222 +  /* First we check if there are any connections avaliable. Unused
6223 +     connections are kept in the same table as used connections, but
6224 +     unused ones have the tcpstate set to CLOSED. Also, connections in
6225 +     TIME_WAIT are kept track of and we'll use the oldest one if no
6226 +     CLOSED connections are found. Thanks to Eddie C. Dost for a very
6227 +     nice algorithm for the TIME_WAIT search. */
6228 +  uip_connr = 0;
6229 +  for(c = 0; c < UIP_CONNS; ++c) {
6230 +    if(uip_conns[c].tcpstateflags == CLOSED) {
6231 +      uip_connr = &uip_conns[c];
6232 +      break;
6233 +    }
6234 +    if(uip_conns[c].tcpstateflags == TIME_WAIT) {
6235 +      if(uip_connr == 0 ||
6236 +        uip_conns[c].timer > uip_connr->timer) {
6237 +       uip_connr = &uip_conns[c];
6238 +      }
6239 +    }
6240 +  }
6241 +
6242 +  if(uip_connr == 0) {
6243 +    /* All connections are used already, we drop packet and hope that
6244 +       the remote end will retransmit the packet at a time when we
6245 +       have more spare connections. */
6246 +    UIP_STAT(++uip_stat.tcp.syndrop);
6247 +    UIP_LOG("tcp: found no unused connections.");
6248 +    goto drop;
6249 +  }
6250 +  uip_conn = uip_connr;
6251 +  
6252 +  /* Fill in the necessary fields for the new connection. */
6253 +  uip_connr->rto = uip_connr->timer = UIP_RTO;
6254 +  uip_connr->sa = 0;
6255 +  uip_connr->sv = 4;  
6256 +  uip_connr->nrtx = 0;
6257 +  uip_connr->lport = BUF->destport;
6258 +  uip_connr->rport = BUF->srcport;
6259 +  uip_connr->ripaddr[0] = BUF->srcipaddr[0];
6260 +  uip_connr->ripaddr[1] = BUF->srcipaddr[1];
6261 +  uip_connr->tcpstateflags = SYN_RCVD;
6262 +
6263 +  uip_connr->snd_nxt[0] = iss[0];
6264 +  uip_connr->snd_nxt[1] = iss[1];
6265 +  uip_connr->snd_nxt[2] = iss[2];
6266 +  uip_connr->snd_nxt[3] = iss[3];
6267 +  uip_connr->len = 1;
6268 +
6269 +  /* rcv_nxt should be the seqno from the incoming packet + 1. */
6270 +  uip_connr->rcv_nxt[3] = BUF->seqno[3];
6271 +  uip_connr->rcv_nxt[2] = BUF->seqno[2];
6272 +  uip_connr->rcv_nxt[1] = BUF->seqno[1];
6273 +  uip_connr->rcv_nxt[0] = BUF->seqno[0];
6274 +  uip_add_rcv_nxt(1);
6275 +
6276 +  /* Parse the TCP MSS option, if present. */
6277 +  if((BUF->tcpoffset & 0xf0) > 0x50) {
6278 +    for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
6279 +      opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
6280 +      if(opt == 0x00) {
6281 +       /* End of options. */   
6282 +       break;
6283 +      } else if(opt == 0x01) {
6284 +       ++c;
6285 +       /* NOP option. */
6286 +      } else if(opt == 0x02 &&
6287 +               uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
6288 +       /* An MSS option with the right option length. */       
6289 +       tmp16 = ((unsigned short int)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
6290 +         (unsigned short int)uip_buf[40 + UIP_LLH_LEN + 3 + c];
6291 +       uip_connr->initialmss = uip_connr->mss =
6292 +         tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
6293 +       
6294 +       /* And we are done processing options. */
6295 +       break;
6296 +      } else {
6297 +       /* All other options have a length field, so that we easily
6298 +          can skip past them. */
6299 +       if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
6300 +         /* If the length field is zero, the options are malformed
6301 +            and we don't process them further. */
6302 +         break;
6303 +       }
6304 +       c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
6305 +      }      
6306 +    }
6307 +  }
6308 +  
6309 +  /* Our response will be a SYNACK. */
6310 +#if UIP_ACTIVE_OPEN
6311 + tcp_send_synack:
6312 +  BUF->flags = TCP_ACK;    
6313 +  
6314 + tcp_send_syn:
6315 +  BUF->flags |= TCP_SYN;    
6316 +#else /* UIP_ACTIVE_OPEN */
6317 + tcp_send_synack:
6318 +  BUF->flags = TCP_SYN | TCP_ACK;    
6319 +#endif /* UIP_ACTIVE_OPEN */
6320 +  
6321 +  /* We send out the TCP Maximum Segment Size option with our
6322 +     SYNACK. */
6323 +  BUF->optdata[0] = 2;
6324 +  BUF->optdata[1] = 4;
6325 +  BUF->optdata[2] = (UIP_TCP_MSS) / 256;
6326 +  BUF->optdata[3] = (UIP_TCP_MSS) & 255;
6327 +  uip_len = 44;
6328 +  BUF->tcpoffset = 6 << 4;
6329 +  goto tcp_send;
6330 +
6331 +  /* This label will be jumped to if we found an active connection. */
6332 + found:
6333 +  uip_conn = uip_connr;
6334 +  uip_flags = 0;
6335 +
6336 +  /* We do a very naive form of TCP reset processing; we just accept
6337 +     any RST and kill our connection. We should in fact check if the
6338 +     sequence number of this reset is wihtin our advertised window
6339 +     before we accept the reset. */
6340 +  if(BUF->flags & TCP_RST) {
6341 +    uip_connr->tcpstateflags = CLOSED;
6342 +    UIP_LOG("tcp: got reset, aborting connection.");
6343 +    uip_flags = UIP_ABORT;
6344 +    UIP_APPCALL();
6345 +    goto drop;
6346 +  }      
6347 +  /* Calculated the length of the data, if the application has sent
6348 +     any data to us. */
6349 +  c = (BUF->tcpoffset >> 4) << 2;
6350 +  /* uip_len will contain the length of the actual TCP data. This is
6351 +     calculated by subtracing the length of the TCP header (in
6352 +     c) and the length of the IP header (20 bytes). */
6353 +  uip_len = uip_len - c - 20;
6354 +
6355 +  /* First, check if the sequence number of the incoming packet is
6356 +     what we're expecting next. If not, we send out an ACK with the
6357 +     correct numbers in. */
6358 +  if(uip_len > 0 &&
6359 +     (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
6360 +      BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
6361 +      BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
6362 +      BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
6363 +    goto tcp_send_ack;
6364 +  }
6365 +
6366 +  /* Next, check if the incoming segment acknowledges any outstanding
6367 +     data. If so, we update the sequence number, reset the length of
6368 +     the outstanding data, calculate RTT estimations, and reset the
6369 +     retransmission timer. */
6370 +  if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
6371 +    uip_add32(uip_connr->snd_nxt, uip_connr->len);
6372 +    if(BUF->ackno[0] == uip_acc32[0] &&
6373 +       BUF->ackno[1] == uip_acc32[1] &&
6374 +       BUF->ackno[2] == uip_acc32[2] &&
6375 +       BUF->ackno[3] == uip_acc32[3]) {
6376 +      /* Update sequence number. */
6377 +      uip_connr->snd_nxt[0] = uip_acc32[0];
6378 +      uip_connr->snd_nxt[1] = uip_acc32[1];
6379 +      uip_connr->snd_nxt[2] = uip_acc32[2];
6380 +      uip_connr->snd_nxt[3] = uip_acc32[3];
6381 +       
6382 +
6383 +      /* Do RTT estimation, unless we have done retransmissions. */
6384 +      if(uip_connr->nrtx == 0) {
6385 +       signed char m;
6386 +       m = uip_connr->rto - uip_connr->timer;
6387 +       /* This is taken directly from VJs original code in his paper */
6388 +       m = m - (uip_connr->sa >> 3);
6389 +       uip_connr->sa += m;
6390 +       if(m < 0) {
6391 +         m = -m;
6392 +       }
6393 +       m = m - (uip_connr->sv >> 2);
6394 +       uip_connr->sv += m;
6395 +       uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
6396 +
6397 +      }
6398 +      /* Set the acknowledged flag. */
6399 +      uip_flags = UIP_ACKDATA;
6400 +      /* Reset the retransmission timer. */
6401 +      uip_connr->timer = uip_connr->rto;
6402 +    }
6403 +    
6404 +  }
6405 +
6406 +  /* Do different things depending on in what state the connection is. */
6407 +  switch(uip_connr->tcpstateflags & TS_MASK) {
6408 +    /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
6409 +       implemented, since we force the application to close when the
6410 +       peer sends a FIN (hence the application goes directly from
6411 +       ESTABLISHED to LAST_ACK). */
6412 +  case SYN_RCVD:
6413 +    /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
6414 +       we are waiting for an ACK that acknowledges the data we sent
6415 +       out the last time. Therefore, we want to have the UIP_ACKDATA
6416 +       flag set. If so, we enter the ESTABLISHED state. */
6417 +    if(uip_flags & UIP_ACKDATA) {
6418 +      uip_connr->tcpstateflags = ESTABLISHED;
6419 +      uip_flags = UIP_CONNECTED;
6420 +      uip_connr->len = 0;
6421 +      if(uip_len > 0) {
6422 +        uip_flags |= UIP_NEWDATA;
6423 +        uip_add_rcv_nxt(uip_len);
6424 +      }
6425 +      uip_slen = 0;
6426 +      UIP_APPCALL();
6427 +      goto appsend;
6428 +    }
6429 +    goto drop;
6430 +#if UIP_ACTIVE_OPEN
6431 +  case SYN_SENT:
6432 +    /* In SYN_SENT, we wait for a SYNACK that is sent in response to
6433 +       our SYN. The rcv_nxt is set to sequence number in the SYNACK
6434 +       plus one, and we send an ACK. We move into the ESTABLISHED
6435 +       state. */
6436 +    if((uip_flags & UIP_ACKDATA) &&
6437 +       BUF->flags == (TCP_SYN | TCP_ACK)) {
6438 +
6439 +      /* Parse the TCP MSS option, if present. */
6440 +      if((BUF->tcpoffset & 0xf0) > 0x50) {
6441 +       for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
6442 +         opt = uip_buf[40 + UIP_LLH_LEN + c];
6443 +         if(opt == 0x00) {
6444 +           /* End of options. */       
6445 +           break;
6446 +         } else if(opt == 0x01) {
6447 +           ++c;
6448 +           /* NOP option. */
6449 +         } else if(opt == 0x02 &&
6450 +                   uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
6451 +           /* An MSS option with the right option length. */
6452 +           tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
6453 +             uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
6454 +           uip_connr->initialmss =
6455 +             uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
6456 +
6457 +           /* And we are done processing options. */
6458 +           break;
6459 +         } else {
6460 +           /* All other options have a length field, so that we easily
6461 +              can skip past them. */
6462 +           if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
6463 +             /* If the length field is zero, the options are malformed
6464 +                and we don't process them further. */
6465 +             break;
6466 +           }
6467 +           c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
6468 +         }      
6469 +       }
6470 +      }
6471 +      uip_connr->tcpstateflags = ESTABLISHED;      
6472 +      uip_connr->rcv_nxt[0] = BUF->seqno[0];
6473 +      uip_connr->rcv_nxt[1] = BUF->seqno[1];
6474 +      uip_connr->rcv_nxt[2] = BUF->seqno[2];
6475 +      uip_connr->rcv_nxt[3] = BUF->seqno[3];
6476 +      uip_add_rcv_nxt(1);
6477 +      uip_flags = UIP_CONNECTED | UIP_NEWDATA;
6478 +      uip_connr->len = 0;
6479 +      uip_len = 0;
6480 +      uip_slen = 0;
6481 +      UIP_APPCALL();
6482 +      goto appsend;
6483 +    }
6484 +    goto reset;
6485 +#endif /* UIP_ACTIVE_OPEN */
6486 +    
6487 +  case ESTABLISHED:
6488 +    /* In the ESTABLISHED state, we call upon the application to feed
6489 +    data into the uip_buf. If the UIP_ACKDATA flag is set, the
6490 +    application should put new data into the buffer, otherwise we are
6491 +    retransmitting an old segment, and the application should put that
6492 +    data into the buffer.
6493 +
6494 +    If the incoming packet is a FIN, we should close the connection on
6495 +    this side as well, and we send out a FIN and enter the LAST_ACK
6496 +    state. We require that there is no outstanding data; otherwise the
6497 +    sequence numbers will be screwed up. */
6498 +
6499 +    if(BUF->flags & TCP_FIN) {
6500 +      if(uip_outstanding(uip_connr)) {
6501 +       goto drop;
6502 +      }
6503 +      uip_add_rcv_nxt(1 + uip_len);      
6504 +      uip_flags = UIP_CLOSE;
6505 +      if(uip_len > 0) {
6506 +       uip_flags |= UIP_NEWDATA;
6507 +      }
6508 +      UIP_APPCALL();
6509 +      uip_connr->len = 1;
6510 +      uip_connr->tcpstateflags = LAST_ACK;
6511 +      uip_connr->nrtx = 0;
6512 +    tcp_send_finack:
6513 +      BUF->flags = TCP_FIN | TCP_ACK;      
6514 +      goto tcp_send_nodata;
6515 +    }
6516 +
6517 +    /* Check the URG flag. If this is set, the segment carries urgent
6518 +       data that we must pass to the application. */
6519 +    if(BUF->flags & TCP_URG) {
6520 +#if UIP_URGDATA > 0
6521 +      uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
6522 +      if(uip_urglen > uip_len) {
6523 +       /* There is more urgent data in the next segment to come. */
6524 +       uip_urglen = uip_len;
6525 +      }
6526 +      uip_add_rcv_nxt(uip_urglen);
6527 +      uip_len -= uip_urglen;
6528 +      uip_urgdata = uip_appdata;
6529 +      uip_appdata += uip_urglen;
6530 +    } else {
6531 +      uip_urglen = 0;
6532 +#endif /* UIP_URGDATA > 0 */
6533 +      uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
6534 +      uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
6535 +    }
6536 +    
6537 +    
6538 +    /* If uip_len > 0 we have TCP data in the packet, and we flag this
6539 +       by setting the UIP_NEWDATA flag and update the sequence number
6540 +       we acknowledge. If the application has stopped the dataflow
6541 +       using uip_stop(), we must not accept any data packets from the
6542 +       remote host. */
6543 +    if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
6544 +      uip_flags |= UIP_NEWDATA;
6545 +      uip_add_rcv_nxt(uip_len);
6546 +    }
6547 +
6548 +    /* Check if the available buffer space advertised by the other end
6549 +       is smaller than the initial MSS for this connection. If so, we
6550 +       set the current MSS to the window size to ensure that the
6551 +       application does not send more data than the other end can
6552 +       handle.
6553 +
6554 +       If the remote host advertises a zero window, we set the MSS to
6555 +       the initial MSS so that the application will send an entire MSS
6556 +       of data. This data will not be acknowledged by the receiver,
6557 +       and the application will retransmit it. This is called the
6558 +       "persistent timer" and uses the retransmission mechanim.
6559 +    */
6560 +    tmp16 = ((unsigned short int)BUF->wnd[0] << 8) + (unsigned short int)BUF->wnd[1];
6561 +    if(tmp16 > uip_connr->initialmss ||
6562 +       tmp16 == 0) {
6563 +      tmp16 = uip_connr->initialmss;
6564 +    }
6565 +    uip_connr->mss = tmp16;
6566 +
6567 +    /* If this packet constitutes an ACK for outstanding data (flagged
6568 +       by the UIP_ACKDATA flag, we should call the application since it
6569 +       might want to send more data. If the incoming packet had data
6570 +       from the peer (as flagged by the UIP_NEWDATA flag), the
6571 +       application must also be notified.
6572 +
6573 +       When the application is called, the global variable uip_len
6574 +       contains the length of the incoming data. The application can
6575 +       access the incoming data through the global pointer
6576 +       uip_appdata, which usually points 40 bytes into the uip_buf
6577 +       array.
6578 +
6579 +       If the application wishes to send any data, this data should be
6580 +       put into the uip_appdata and the length of the data should be
6581 +       put into uip_len. If the application don't have any data to
6582 +       send, uip_len must be set to 0. */
6583 +       if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
6584 +      uip_slen = 0;
6585 +      UIP_APPCALL();
6586 +
6587 +    appsend:
6588 +      
6589 +         if(uip_flags & UIP_ABORT) {
6590 +       uip_slen = 0;
6591 +       uip_connr->tcpstateflags = CLOSED;
6592 +       BUF->flags = TCP_RST | TCP_ACK;
6593 +       goto tcp_send_nodata;
6594 +      }
6595 +
6596 +      if(uip_flags & UIP_CLOSE) {
6597 +       uip_slen = 0;
6598 +       uip_connr->len = 1;
6599 +       uip_connr->tcpstateflags = FIN_WAIT_1;
6600 +       uip_connr->nrtx = 0;
6601 +       BUF->flags = TCP_FIN | TCP_ACK;
6602 +       goto tcp_send_nodata;   
6603 +      }
6604 +
6605 +         /* If uip_slen > 0, the application has data to be sent. */
6606 +      if(uip_slen > 0) {
6607 +
6608 +       /* If the connection has acknowledged data, the contents of
6609 +          the ->len variable should be discarded. */ 
6610 +       if((uip_flags & UIP_ACKDATA) != 0) {
6611 +         uip_connr->len = 0;
6612 +       }
6613 +
6614 +       /* If the ->len variable is non-zero the connection has
6615 +          already data in transit and cannot send anymore right
6616 +          now. */
6617 +       if(uip_connr->len == 0) {
6618 +
6619 +         /* The application cannot send more than what is allowed by
6620 +            the mss (the minumum of the MSS and the available
6621 +            window). */
6622 +         if(uip_slen > uip_connr->mss) {
6623 +               uip_slen = uip_connr->mss;
6624 +         }
6625 +
6626 +         /* Remember how much data we send out now so that we know
6627 +            when everything has been acknowledged. */
6628 +         uip_connr->len = uip_slen;
6629 +       } else {
6630 +
6631 +         /* If the application already had unacknowledged data, we
6632 +            make sure that the application does not send (i.e.,
6633 +            retransmit) out more than it previously sent out. */
6634 +         uip_slen = uip_connr->len;
6635 +       }
6636 +      } else {
6637 +       uip_connr->len = 0;
6638 +      }
6639 +      uip_connr->nrtx = 0;
6640 +    apprexmit:
6641 +      uip_appdata = uip_sappdata;
6642 +
6643 +      /* If the application has data to be sent, or if the incoming
6644 +         packet had new data in it, we must send out a packet. */
6645 +      if(uip_slen > 0 && uip_connr->len > 0) {
6646 +       /* Add the length of the IP and TCP headers. */
6647 +       uip_len = uip_connr->len + UIP_TCPIP_HLEN;
6648 +       /* We always set the ACK flag in response packets. */
6649 +       BUF->flags = TCP_ACK | TCP_PSH;
6650 +       /* Send the packet. */
6651 +       goto tcp_send_noopts;
6652 +      }
6653 +      /* If there is no data to send, just send out a pure ACK if
6654 +        there is newdata. */
6655 +      if(uip_flags & UIP_NEWDATA) {
6656 +       uip_len = UIP_TCPIP_HLEN;
6657 +       BUF->flags = TCP_ACK;
6658 +       goto tcp_send_noopts;
6659 +      }
6660 +    }
6661 +       goto drop;
6662 +  case LAST_ACK:
6663 +    /* We can close this connection if the peer has acknowledged our
6664 +       FIN. This is indicated by the UIP_ACKDATA flag. */     
6665 +    if(uip_flags & UIP_ACKDATA) {
6666 +      uip_connr->tcpstateflags = CLOSED;
6667 +      uip_flags = UIP_CLOSE;
6668 +      UIP_APPCALL();
6669 +    }
6670 +    break;
6671 +    
6672 +  case FIN_WAIT_1:
6673 +    /* The application has closed the connection, but the remote host
6674 +       hasn't closed its end yet. Thus we do nothing but wait for a
6675 +       FIN from the other side. */
6676 +    if(uip_len > 0) {
6677 +      uip_add_rcv_nxt(uip_len);
6678 +    }
6679 +    if(BUF->flags & TCP_FIN) {
6680 +      if(uip_flags & UIP_ACKDATA) {
6681 +       uip_connr->tcpstateflags = TIME_WAIT;
6682 +       uip_connr->timer = 0;
6683 +       uip_connr->len = 0;
6684 +      } else {
6685 +       uip_connr->tcpstateflags = CLOSING;
6686 +      }
6687 +      uip_add_rcv_nxt(1);
6688 +      uip_flags = UIP_CLOSE;
6689 +      UIP_APPCALL();
6690 +      goto tcp_send_ack;
6691 +    } else if(uip_flags & UIP_ACKDATA) {
6692 +      uip_connr->tcpstateflags = FIN_WAIT_2;
6693 +      uip_connr->len = 0;
6694 +      goto drop;
6695 +    }
6696 +    if(uip_len > 0) {
6697 +      goto tcp_send_ack;
6698 +    }
6699 +    goto drop;
6700 +      
6701 +  case FIN_WAIT_2:
6702 +    if(uip_len > 0) {
6703 +      uip_add_rcv_nxt(uip_len);
6704 +    }
6705 +    if(BUF->flags & TCP_FIN) {
6706 +      uip_connr->tcpstateflags = TIME_WAIT;
6707 +      uip_connr->timer = 0;
6708 +      uip_add_rcv_nxt(1);
6709 +      uip_flags = UIP_CLOSE;
6710 +      UIP_APPCALL();
6711 +      goto tcp_send_ack;
6712 +    }
6713 +    if(uip_len > 0) {
6714 +      goto tcp_send_ack;
6715 +    }
6716 +    goto drop;
6717 +
6718 +  case TIME_WAIT:
6719 +    goto tcp_send_ack;
6720 +    
6721 +  case CLOSING:
6722 +    if(uip_flags & UIP_ACKDATA) {
6723 +      uip_connr->tcpstateflags = TIME_WAIT;
6724 +      uip_connr->timer = 0;
6725 +    }
6726 +  }  
6727 +  goto drop;
6728 +  
6729 +
6730 +  /* We jump here when we are ready to send the packet, and just want
6731 +     to set the appropriate TCP sequence numbers in the TCP header. */
6732 + tcp_send_ack:
6733 +  BUF->flags = TCP_ACK;
6734 + tcp_send_nodata:
6735 +  uip_len = 40;
6736 + tcp_send_noopts:
6737 +  BUF->tcpoffset = 5 << 4;
6738 + tcp_send:
6739 +  /* We're done with the input processing. We are now ready to send a
6740 +     reply. Our job is to fill in all the fields of the TCP and IP
6741 +     headers before calculating the checksum and finally send the
6742 +     packet. */
6743 +  BUF->ackno[0] = uip_connr->rcv_nxt[0];
6744 +  BUF->ackno[1] = uip_connr->rcv_nxt[1];
6745 +  BUF->ackno[2] = uip_connr->rcv_nxt[2];
6746 +  BUF->ackno[3] = uip_connr->rcv_nxt[3];
6747 +  
6748 +  BUF->seqno[0] = uip_connr->snd_nxt[0];
6749 +  BUF->seqno[1] = uip_connr->snd_nxt[1];
6750 +  BUF->seqno[2] = uip_connr->snd_nxt[2];
6751 +  BUF->seqno[3] = uip_connr->snd_nxt[3];
6752 +
6753 +  BUF->proto = UIP_PROTO_TCP;
6754 +  
6755 +  BUF->srcport  = uip_connr->lport;
6756 +  BUF->destport = uip_connr->rport;
6757 +
6758 +  BUF->srcipaddr[0] = uip_hostaddr[0];
6759 +  BUF->srcipaddr[1] = uip_hostaddr[1];
6760 +  BUF->destipaddr[0] = uip_connr->ripaddr[0];
6761 +  BUF->destipaddr[1] = uip_connr->ripaddr[1];
6762
6763 +
6764 +  if(uip_connr->tcpstateflags & UIP_STOPPED) {
6765 +    /* If the connection has issued uip_stop(), we advertise a zero
6766 +       window so that the remote host will stop sending data. */
6767 +    BUF->wnd[0] = BUF->wnd[1] = 0;
6768 +  } else {
6769 +    BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
6770 +    BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); 
6771 +  }
6772 +
6773 + tcp_send_noconn:
6774 +
6775 +  BUF->len[0] = (uip_len >> 8);
6776 +  BUF->len[1] = (uip_len & 0xff);
6777 +
6778 +  /* Calculate TCP checksum. */
6779 +  BUF->tcpchksum = 0;
6780 +  BUF->tcpchksum = ~(uip_tcpchksum());
6781 +  
6782 + //ip_send_nolen:
6783 +
6784 +  BUF->vhl = 0x45;
6785 +  BUF->tos = 0;
6786 +  BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
6787 +  BUF->ttl  = UIP_TTL;
6788 +  ++ipid;
6789 +  BUF->ipid[0] = ipid >> 8;
6790 +  BUF->ipid[1] = ipid & 0xff;
6791 +  
6792 +  /* Calculate IP checksum. */
6793 +  BUF->ipchksum = 0;
6794 +  BUF->ipchksum = ~(uip_ipchksum());
6795 +
6796 +  UIP_STAT(++uip_stat.tcp.sent);
6797 + send:
6798 +  UIP_STAT(++uip_stat.ip.sent);
6799 +  /* Return and let the caller do the actual transmission. */
6800 +  return;
6801 + drop:
6802 +  uip_len = 0;
6803 +  return;
6804 +}
6805 +/*-----------------------------------------------------------------------------------*/
6806 +/*unsigned short int
6807 +htons(unsigned short int val)
6808 +{
6809 +  return HTONS(val);
6810 +}*/
6811 +/*-----------------------------------------------------------------------------------*/
6812 +/** @} */
6813 --- /dev/null
6814 +++ b/net/uip-0.9/uip.h
6815 @@ -0,0 +1,1066 @@
6816 +/**
6817 + * \addtogroup uip
6818 + * @{
6819 + */
6820 +
6821 +/**
6822 + * \file
6823 + * Header file for the uIP TCP/IP stack.
6824 + * \author Adam Dunkels <adam@dunkels.com>
6825 + *
6826 + * The uIP TCP/IP stack header file contains definitions for a number
6827 + * of C macros that are used by uIP programs as well as internal uIP
6828 + * structures, TCP/IP header structures and function declarations.
6829 + *
6830 + */
6831 +
6832 +
6833 +/*
6834 + * Copyright (c) 2001-2003, Adam Dunkels.
6835 + * All rights reserved. 
6836 + *
6837 + * Redistribution and use in source and binary forms, with or without 
6838 + * modification, are permitted provided that the following conditions 
6839 + * are met: 
6840 + * 1. Redistributions of source code must retain the above copyright 
6841 + *    notice, this list of conditions and the following disclaimer. 
6842 + * 2. Redistributions in binary form must reproduce the above copyright 
6843 + *    notice, this list of conditions and the following disclaimer in the 
6844 + *    documentation and/or other materials provided with the distribution. 
6845 + * 3. The name of the author may not be used to endorse or promote
6846 + *    products derived from this software without specific prior
6847 + *    written permission.  
6848 + *
6849 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
6850 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6851 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6852 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
6853 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6854 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6855 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6856 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
6857 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6858 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6859 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
6860 + *
6861 + * This file is part of the uIP TCP/IP stack.
6862 + *
6863 + * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $
6864 + *
6865 + */
6866 +
6867 +#ifndef __UIP_H__
6868 +#define __UIP_H__
6869 +#include <linux/types.h>
6870 +#include <linux/string.h>
6871 +#include <linux/ctype.h>
6872 +#include <malloc.h>
6873 +#include <common.h>
6874 +
6875 +
6876 +#include "uipopt.h"
6877 +
6878 +/*-----------------------------------------------------------------------------------*/
6879 +/* First, the functions that should be called from the
6880 + * system. Initialization, the periodic timer and incoming packets are
6881 + * handled by the following three functions.
6882 + */
6883 +
6884 +/**
6885 + * \defgroup uipconffunc uIP configuration functions
6886 + * @{
6887 + *
6888 + * The uIP configuration functions are used for setting run-time
6889 + * parameters in uIP such as IP addresses. 
6890 + */
6891 +
6892 +/**
6893 + * Set the IP address of this host.
6894 + *
6895 + * The IP address is represented as a 4-byte array where the first
6896 + * octet of the IP address is put in the first member of the 4-byte
6897 + * array.
6898 + *
6899 + * \param addr A pointer to a 4-byte representation of the IP address.
6900 + *
6901 + * \hideinitializer
6902 + */
6903 +#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \
6904 +                              uip_hostaddr[1] = addr[1]; } while(0)
6905 +
6906 +/**
6907 + * Get the IP address of this host.
6908 + *
6909 + * The IP address is represented as a 4-byte array where the first
6910 + * octet of the IP address is put in the first member of the 4-byte
6911 + * array.
6912 + *
6913 + * \param addr A pointer to a 4-byte array that will be filled in with
6914 + * the currently configured IP address.
6915 + *
6916 + * \hideinitializer
6917 + */
6918 +#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \
6919 +                              addr[1] = uip_hostaddr[1]; } while(0)
6920 +
6921 +/** @} */
6922 +
6923 +/**
6924 + * \defgroup uipinit uIP initialization functions
6925 + * @{
6926 + *
6927 + * The uIP initialization functions are used for booting uIP.
6928 + */
6929 +
6930 +/**
6931 + * uIP initialization function.
6932 + *
6933 + * This function should be called at boot up to initilize the uIP
6934 + * TCP/IP stack.
6935 + */
6936 +void uip_init(void);
6937 +
6938 +/** @} */
6939 +
6940 +/**
6941 + * \defgroup uipdevfunc uIP device driver functions
6942 + * @{
6943 + *
6944 + * These functions are used by a network device driver for interacting
6945 + * with uIP.
6946 + */
6947 +
6948 +/**
6949 + * Process an incoming packet.
6950 + *
6951 + * This function should be called when the device driver has received
6952 + * a packet from the network. The packet from the device driver must
6953 + * be present in the uip_buf buffer, and the length of the packet
6954 + * should be placed in the uip_len variable.
6955 + *
6956 + * When the function returns, there may be an outbound packet placed
6957 + * in the uip_buf packet buffer. If so, the uip_len variable is set to
6958 + * the length of the packet. If no packet is to be sent out, the
6959 + * uip_len variable is set to 0.
6960 + *
6961 + * The usual way of calling the function is presented by the source
6962 + * code below.
6963 + \code
6964 +  uip_len = devicedriver_poll();
6965 +  if(uip_len > 0) {
6966 +    uip_input();
6967 +    if(uip_len > 0) {
6968 +      devicedriver_send();
6969 +    }
6970 +  }
6971 + \endcode
6972 + *
6973 + * \note If you are writing a uIP device driver that needs ARP
6974 + * (Address Resolution Protocol), e.g., when running uIP over
6975 + * Ethernet, you will need to call the uIP ARP code before calling
6976 + * this function:
6977 + \code
6978 +  #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
6979 +  uip_len = ethernet_devicedrver_poll();
6980 +  if(uip_len > 0) {
6981 +    if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
6982 +      uip_arp_ipin();
6983 +      uip_input();
6984 +      if(uip_len > 0) {
6985 +        uip_arp_out();
6986 +       ethernet_devicedriver_send();
6987 +      }
6988 +    } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
6989 +      uip_arp_arpin();
6990 +      if(uip_len > 0) {
6991 +       ethernet_devicedriver_send();
6992 +      }
6993 +    }
6994 + \endcode
6995 + *
6996 + * \hideinitializer
6997 + */
6998 +#define uip_input()        uip_process(UIP_DATA)
6999 +
7000 +/**
7001 + * Periodic processing for a connection identified by its number.
7002 + * 
7003 + * This function does the necessary periodic processing (timers,
7004 + * polling) for a uIP TCP conneciton, and should be called when the
7005 + * periodic uIP timer goes off. It should be called for every
7006 + * connection, regardless of whether they are open of closed.
7007 + *
7008 + * When the function returns, it may have an outbound packet waiting
7009 + * for service in the uIP packet buffer, and if so the uip_len
7010 + * variable is set to a value larger than zero. The device driver
7011 + * should be called to send out the packet.
7012 + *
7013 + * The ususal way of calling the function is through a for() loop like
7014 + * this:
7015 + \code
7016 +  for(i = 0; i < UIP_CONNS; ++i) {
7017 +    uip_periodic(i);
7018 +    if(uip_len > 0) {
7019 +      devicedriver_send();
7020 +    }
7021 +  }
7022 + \endcode
7023 + *
7024 + * \note If you are writing a uIP device driver that needs ARP
7025 + * (Address Resolution Protocol), e.g., when running uIP over
7026 + * Ethernet, you will need to call the uip_arp_out() function before
7027 + * calling the device driver:
7028 + \code
7029 +  for(i = 0; i < UIP_CONNS; ++i) {
7030 +    uip_periodic(i);
7031 +    if(uip_len > 0) {
7032 +      uip_arp_out();
7033 +      ethernet_devicedriver_send();
7034 +    }
7035 +  }
7036 + \endcode 
7037 + *
7038 + * \param conn The number of the connection which is to be periodically polled.
7039 + *
7040 + * \hideinitializer
7041 + */
7042 +#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
7043 +                                uip_process(UIP_TIMER); } while (0)
7044 +
7045 +/**
7046 + * Periodic processing for a connection identified by a pointer to its structure.
7047 + *
7048 + * Same as uip_periodic() but takes a pointer to the actual uip_conn
7049 + * struct instead of an integer as its argument. This function can be
7050 + * used to force periodic processing of a specific connection.
7051 + *
7052 + * \param conn A pointer to the uip_conn struct for the connection to
7053 + * be processed.
7054 + *
7055 + * \hideinitializer
7056 + */
7057 +#define uip_periodic_conn(conn) do { uip_conn = conn; \
7058 +                                     uip_process(UIP_TIMER); } while (0)
7059 +
7060 +#if UIP_UDP
7061 +/**
7062 + * Periodic processing for a UDP connection identified by its number.
7063 + *
7064 + * This function is essentially the same as uip_prerioic(), but for
7065 + * UDP connections. It is called in a similar fashion as the
7066 + * uip_periodic() function:
7067 + \code
7068 +  for(i = 0; i < UIP_UDP_CONNS; i++) {
7069 +    uip_udp_periodic(i);
7070 +    if(uip_len > 0) {
7071 +      devicedriver_send();
7072 +    }
7073 +  }   
7074 + \endcode
7075 + *
7076 + * \note As for the uip_periodic() function, special care has to be
7077 + * taken when using uIP together with ARP and Ethernet:
7078 + \code
7079 +  for(i = 0; i < UIP_UDP_CONNS; i++) {
7080 +    uip_udp_periodic(i);
7081 +    if(uip_len > 0) {
7082 +      uip_arp_out();
7083 +      ethernet_devicedriver_send();
7084 +    }
7085 +  }   
7086 + \endcode
7087 + *
7088 + * \param conn The number of the UDP connection to be processed.
7089 + *
7090 + * \hideinitializer
7091 + */
7092 +#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
7093 +                                uip_process(UIP_UDP_TIMER); } while (0)
7094 +
7095 +/**
7096 + * Periodic processing for a UDP connection identified by a pointer to
7097 + * its structure.
7098 + *
7099 + * Same as uip_udp_periodic() but takes a pointer to the actual
7100 + * uip_conn struct instead of an integer as its argument. This
7101 + * function can be used to force periodic processing of a specific
7102 + * connection.
7103 + *
7104 + * \param conn A pointer to the uip_udp_conn struct for the connection
7105 + * to be processed.
7106 + *
7107 + * \hideinitializer
7108 + */
7109 +#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
7110 +                                         uip_process(UIP_UDP_TIMER); } while (0)
7111 +
7112 +
7113 +#endif /* UIP_UDP */
7114 +
7115 +/**
7116 + * The uIP packet buffer.
7117 + *
7118 + * The uip_buf array is used to hold incoming and outgoing
7119 + * packets. The device driver should place incoming data into this
7120 + * buffer. When sending data, the device driver should read the link
7121 + * level headers and the TCP/IP headers from this buffer. The size of
7122 + * the link level headers is configured by the UIP_LLH_LEN define.
7123 + *
7124 + * \note The application data need not be placed in this buffer, so
7125 + * the device driver must read it from the place pointed to by the
7126 + * uip_appdata pointer as illustrated by the following example:
7127 + \code
7128 + void
7129 + devicedriver_send(void)
7130 + {
7131 +    hwsend(&uip_buf[0], UIP_LLH_LEN);
7132 +    hwsend(&uip_buf[UIP_LLH_LEN], 40);
7133 +    hwsend(uip_appdata, uip_len - 40 - UIP_LLH_LEN);
7134 + }
7135 + \endcode
7136 + */
7137 +extern u8_t uip_buf[UIP_BUFSIZE+2];
7138 +
7139 +/** @} */
7140 +
7141 +/*-----------------------------------------------------------------------------------*/
7142 +/* Functions that are used by the uIP application program. Opening and
7143 + * closing connections, sending and receiving data, etc. is all
7144 + * handled by the functions below.
7145 +*/
7146 +/**
7147 + * \defgroup uipappfunc uIP application functions
7148 + * @{
7149 + *
7150 + * Functions used by an application running of top of uIP.
7151 + */
7152 +
7153 +/**
7154 + * Start listening to the specified port.
7155 + *
7156 + * \note Since this function expects the port number in network byte
7157 + * order, a conversion using HTONS() or htons() is necessary.
7158 + *
7159 + \code
7160 + uip_listen(HTONS(80)); 
7161 + \endcode
7162 + *
7163 + * \param port A 16-bit port number in network byte order.
7164 + */
7165 +void uip_listen(u16_t port);
7166 +
7167 +/**
7168 + * Stop listening to the specified port.
7169 + *
7170 + * \note Since this function expects the port number in network byte
7171 + * order, a conversion using HTONS() or htons() is necessary.
7172 + *
7173 + \code
7174 + uip_unlisten(HTONS(80)); 
7175 + \endcode
7176 + *
7177 + * \param port A 16-bit port number in network byte order.
7178 + */
7179 +void uip_unlisten(u16_t port);
7180 +
7181 +/**
7182 + * Connect to a remote host using TCP.
7183 + *
7184 + * This function is used to start a new connection to the specified
7185 + * port on the specied host. It allocates a new connection identifier,
7186 + * sets the connection to the SYN_SENT state and sets the
7187 + * retransmission timer to 0. This will cause a TCP SYN segment to be
7188 + * sent out the next time this connection is periodically processed,
7189 + * which usually is done within 0.5 seconds after the call to
7190 + * uip_connect().
7191 + *
7192 + * \note This function is avaliable only if support for active open
7193 + * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
7194 + *
7195 + * \note Since this function requires the port number to be in network
7196 + * byte order, a convertion using HTONS() or htons() is necessary.
7197 + *
7198 + \code
7199 + u16_t ipaddr[2];
7200 +
7201 + uip_ipaddr(ipaddr, 192,168,1,2);
7202 + uip_connect(ipaddr, HTONS(80)); 
7203 + \endcode
7204 + * 
7205 + * \param ripaddr A pointer to a 4-byte array representing the IP
7206 + * address of the remote hot.
7207 + *
7208 + * \param port A 16-bit port number in network byte order.
7209 + *
7210 + * \return A pointer to the uIP connection identifier for the new connection,
7211 + * or NULL if no connection could be allocated.   
7212 + *
7213 + */
7214 +struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
7215 +
7216 +
7217 +
7218 +/**
7219 + * \internal
7220 + *
7221 + * Check if a connection has outstanding (i.e., unacknowledged) data.
7222 + *
7223 + * \param conn A pointer to the uip_conn structure for the connection.
7224 + *
7225 + * \hideinitializer
7226 + */
7227 +#define uip_outstanding(conn) ((conn)->len)
7228 +
7229 +/**
7230 + * Send data on the current connection.
7231 + *
7232 + * This function is used to send out a single segment of TCP
7233 + * data. Only applications that have been invoked by uIP for event
7234 + * processing can send data. 
7235 + *
7236 + * The amount of data that actually is sent out after a call to this
7237 + * funcion is determined by the maximum amount of data TCP allows. uIP
7238 + * will automatically crop the data so that only the appropriate
7239 + * amount of data is sent. The function uip_mss() can be used to query
7240 + * uIP for the amount of data that actually will be sent.
7241 + * 
7242 + * \note This function does not guarantee that the sent data will
7243 + * arrive at the destination. If the data is lost in the network, the
7244 + * application will be invoked with the uip_rexmit() event being
7245 + * set. The application will then have to resend the data using this
7246 + * function.
7247 + * 
7248 + * \param data A pointer to the data which is to be sent.
7249 + *
7250 + * \param len The maximum amount of data bytes to be sent.
7251 + *
7252 + * \hideinitializer
7253 + */
7254 +#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0)   
7255 +
7256 +/**
7257 + * The length of any incoming data that is currently avaliable (if avaliable)
7258 + * in the uip_appdata buffer.
7259 + *
7260 + * The test function uip_data() must first be used to check if there
7261 + * is any data available at all.
7262 + *
7263 + * \hideinitializer
7264 + */
7265 +#define uip_datalen()       uip_len
7266 +
7267 +/**
7268 + * The length of any out-of-band data (urgent data) that has arrived
7269 + * on the connection.
7270 + *
7271 + * \note The configuration parameter UIP_URGDATA must be set for this
7272 + * function to be enabled.
7273 + *
7274 + * \hideinitializer
7275 + */
7276 +#define uip_urgdatalen()    uip_urglen
7277 +
7278 +/**
7279 + * Close the current connection.
7280 + *
7281 + * This function will close the current connection in a nice way.
7282 + *
7283 + * \hideinitializer
7284 + */
7285 +#define uip_close()         (uip_flags = UIP_CLOSE)
7286 +
7287 +/**
7288 + * Abort the current connection.
7289 + *
7290 + * This function will abort (reset) the current connection, and is
7291 + * usually used when an error has occured that prevents using the
7292 + * uip_close() function.
7293 + *
7294 + * \hideinitializer
7295 + */
7296 +#define uip_abort()         (uip_flags = UIP_ABORT)
7297 +
7298 +/**
7299 + * Tell the sending host to stop sending data.
7300 + *
7301 + * This function will close our receiver's window so that we stop
7302 + * receiving data for the current connection.
7303 + *
7304 + * \hideinitializer
7305 + */
7306 +#define uip_stop()          (uip_conn->tcpstateflags |= UIP_STOPPED)
7307 +
7308 +/**
7309 + * Find out if the current connection has been previously stopped with
7310 + * uip_stop().
7311 + *
7312 + * \hideinitializer
7313 + */
7314 +#define uip_stopped(conn)   ((conn)->tcpstateflags & UIP_STOPPED)
7315 +
7316 +/**
7317 + * Restart the current connection, if is has previously been stopped
7318 + * with uip_stop().
7319 + *
7320 + * This function will open the receiver's window again so that we
7321 + * start receiving data for the current connection.
7322 + *
7323 + * \hideinitializer
7324 + */
7325 +#define uip_restart()         do { uip_flags |= UIP_NEWDATA; \
7326 +                                   uip_conn->tcpstateflags &= ~UIP_STOPPED; \
7327 +                              } while(0)
7328 +
7329 +
7330 +/* uIP tests that can be made to determine in what state the current
7331 +   connection is, and what the application function should do. */
7332 +
7333 +/**
7334 + * Is new incoming data available?
7335 + *
7336 + * Will reduce to non-zero if there is new data for the application
7337 + * present at the uip_appdata pointer. The size of the data is
7338 + * avaliable through the uip_len variable.
7339 + *
7340 + * \hideinitializer
7341 + */
7342 +#define uip_newdata()   (uip_flags & UIP_NEWDATA)
7343 +
7344 +/**
7345 + * Has previously sent data been acknowledged?
7346 + *
7347 + * Will reduce to non-zero if the previously sent data has been
7348 + * acknowledged by the remote host. This means that the application
7349 + * can send new data. 
7350 + *
7351 + * \hideinitializer
7352 + */
7353 +#define uip_acked()   (uip_flags & UIP_ACKDATA)
7354 +
7355 +/**
7356 + * Has the connection just been connected?  
7357 + *
7358 + * Reduces to non-zero if the current connection has been connected to
7359 + * a remote host. This will happen both if the connection has been
7360 + * actively opened (with uip_connect()) or passively opened (with
7361 + * uip_listen()).
7362 + *
7363 + * \hideinitializer
7364 + */
7365 +#define uip_connected() (uip_flags & UIP_CONNECTED)
7366 +
7367 +/**
7368 + * Has the connection been closed by the other end?
7369 + *
7370 + * Is non-zero if the connection has been closed by the remote
7371 + * host. The application may then do the necessary clean-ups.
7372 + *
7373 + * \hideinitializer
7374 + */
7375 +#define uip_closed()    (uip_flags & UIP_CLOSE)
7376 +
7377 +/**
7378 + * Has the connection been aborted by the other end?
7379 + *
7380 + * Non-zero if the current connection has been aborted (reset) by the
7381 + * remote host.
7382 + *
7383 + * \hideinitializer
7384 + */
7385 +#define uip_aborted()    (uip_flags & UIP_ABORT)
7386 +
7387 +/**
7388 + * Has the connection timed out?
7389 + *
7390 + * Non-zero if the current connection has been aborted due to too many
7391 + * retransmissions.
7392 + *
7393 + * \hideinitializer
7394 + */
7395 +#define uip_timedout()    (uip_flags & UIP_TIMEDOUT)
7396 +
7397 +/**
7398 + * Do we need to retransmit previously data?
7399 + *
7400 + * Reduces to non-zero if the previously sent data has been lost in
7401 + * the network, and the application should retransmit it. The
7402 + * application should send the exact same data as it did the last
7403 + * time, using the uip_send() function.
7404 + *
7405 + * \hideinitializer
7406 + */
7407 +#define uip_rexmit()     (uip_flags & UIP_REXMIT)
7408 +
7409 +/**
7410 + * Is the connection being polled by uIP?
7411 + *
7412 + * Is non-zero if the reason the application is invoked is that the
7413 + * current connection has been idle for a while and should be
7414 + * polled.
7415 + *
7416 + * The polling event can be used for sending data without having to
7417 + * wait for the remote host to send data.
7418 + *
7419 + * \hideinitializer
7420 + */ 
7421 +#define uip_poll()       (uip_flags & UIP_POLL)
7422 +
7423 +/**
7424 + * Get the initial maxium segment size (MSS) of the current
7425 + * connection.
7426 + *
7427 + * \hideinitializer
7428 + */
7429 +#define uip_initialmss()             (uip_conn->initialmss)
7430 +
7431 +/**
7432 + * Get the current maxium segment size that can be sent on the current
7433 + * connection.
7434 + *
7435 + * The current maxiumum segment size that can be sent on the
7436 + * connection is computed from the receiver's window and the MSS of
7437 + * the connection (which also is available by calling
7438 + * uip_initialmss()).
7439 + *
7440 + * \hideinitializer
7441 + */
7442 +#define uip_mss()             (uip_conn->mss)
7443 +
7444 +/**
7445 + * Set up a new UDP connection.
7446 + *
7447 + * \param ripaddr A pointer to a 4-byte structure representing the IP
7448 + * address of the remote host.
7449 + *
7450 + * \param rport The remote port number in network byte order.
7451 + *
7452 + * \return The uip_udp_conn structure for the new connection or NULL
7453 + * if no connection could be allocated.
7454 + */
7455 +struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
7456 +
7457 +/**
7458 + * Removed a UDP connection.
7459 + *
7460 + * \param conn A pointer to the uip_udp_conn structure for the connection.
7461 + *
7462 + * \hideinitializer
7463 + */
7464 +#define uip_udp_remove(conn) (conn)->lport = 0
7465 +
7466 +/**
7467 + * Send a UDP datagram of length len on the current connection.
7468 + *
7469 + * This function can only be called in response to a UDP event (poll
7470 + * or newdata). The data must be present in the uip_buf buffer, at the
7471 + * place pointed to by the uip_appdata pointer.
7472 + *
7473 + * \param len The length of the data in the uip_buf buffer.
7474 + *
7475 + * \hideinitializer
7476 + */
7477 +#define uip_udp_send(len) uip_slen = (len)
7478 +
7479 +/** @} */
7480 +
7481 +/* uIP convenience and converting functions. */
7482 +
7483 +/**
7484 + * \defgroup uipconvfunc uIP conversion functions
7485 + * @{
7486 + *
7487 + * These functions can be used for converting between different data
7488 + * formats used by uIP.
7489 + */
7490
7491 +/**
7492 + * Pack an IP address into a 4-byte array which is used by uIP to
7493 + * represent IP addresses.
7494 + *
7495 + * Example:
7496 + \code
7497 + u16_t ipaddr[2];
7498 +
7499 + uip_ipaddr(&ipaddr, 192,168,1,2); 
7500 + \endcode
7501 + *
7502 + * \param addr A pointer to a 4-byte array that will be filled in with
7503 + * the IP addres.
7504 + * \param addr0 The first octet of the IP address.
7505 + * \param addr1 The second octet of the IP address.
7506 + * \param addr2 The third octet of the IP address.
7507 + * \param addr3 The forth octet of the IP address. 
7508 + *
7509 + * \hideinitializer
7510 + */
7511 +#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
7512 +                     (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \
7513 +                     (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \
7514 +                  } while(0)
7515 +
7516 +/**
7517 + * Convert 16-bit quantity from host byte order to network byte order.
7518 + *
7519 + * This macro is primarily used for converting constants from host
7520 + * byte order to network byte order. For converting variables to
7521 + * network byte order, use the htons() function instead.
7522 + *
7523 + * \hideinitializer
7524 + */
7525 +#ifndef HTONS
7526 +#   if BYTE_ORDER == BIG_ENDIAN
7527 +#      define HTONS(n) (n)
7528 +#   else /* BYTE_ORDER == BIG_ENDIAN */
7529 +#      define HTONS(n) ((((u16_t)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))
7530 +#   endif /* BYTE_ORDER == BIG_ENDIAN */
7531 +#endif /* HTONS */
7532 +
7533 +/**
7534 + * Convert 16-bit quantity from host byte order to network byte order.
7535 + *
7536 + * This function is primarily used for converting variables from host
7537 + * byte order to network byte order. For converting constants to
7538 + * network byte order, use the HTONS() macro instead.
7539 + */
7540 +#ifndef htons
7541 +u16_t htons(u16_t val);
7542 +#endif /* htons */
7543 +
7544 +/** @} */
7545 +
7546 +/**
7547 + * Pointer to the application data in the packet buffer.
7548 + *
7549 + * This pointer points to the application data when the application is
7550 + * called. If the application wishes to send data, the application may
7551 + * use this space to write the data into before calling uip_send().
7552 + */
7553 +extern volatile u8_t *uip_appdata;
7554 +extern volatile u8_t *uip_sappdata; 
7555 +
7556 +#if UIP_URGDATA > 0 
7557 +/* u8_t *uip_urgdata:
7558 + *
7559 + * This pointer points to any urgent data that has been received. Only
7560 + * present if compiled with support for urgent data (UIP_URGDATA).
7561 + */
7562 +extern volatile u8_t *uip_urgdata; 
7563 +#endif /* UIP_URGDATA > 0 */
7564 +
7565 +
7566 +/* u[8|16]_t uip_len:
7567 + *
7568 + * When the application is called, uip_len contains the length of any
7569 + * new data that has been received from the remote host. The
7570 + * application should set this variable to the size of any data that
7571 + * the application wishes to send. When the network device driver
7572 + * output function is called, uip_len should contain the length of the
7573 + * outgoing packet.
7574 + */
7575 +extern volatile u16_t uip_len, uip_slen;
7576 +
7577 +#if UIP_URGDATA > 0 
7578 +extern volatile u8_t uip_urglen, uip_surglen;
7579 +#endif /* UIP_URGDATA > 0 */
7580 +
7581 +
7582 +/**
7583 + * Representation of a uIP TCP connection.
7584 + *
7585 + * The uip_conn structure is used for identifying a connection. All
7586 + * but one field in the structure are to be considered read-only by an
7587 + * application. The only exception is the appstate field whos purpose
7588 + * is to let the application store application-specific state (e.g.,
7589 + * file pointers) for the connection. The size of this field is
7590 + * configured in the "uipopt.h" header file.
7591 + */
7592 +struct uip_conn {
7593 +  u16_t ripaddr[2];   /**< The IP address of the remote host. */
7594 +  
7595 +  u16_t lport;        /**< The local TCP port, in network byte order. */
7596 +  u16_t rport;        /**< The local remote TCP port, in network byte
7597 +                        order. */  
7598 +  
7599 +  u8_t rcv_nxt[4];    /**< The sequence number that we expect to
7600 +                        receive next. */
7601 +  u8_t snd_nxt[4];    /**< The sequence number that was last sent by
7602 +                         us. */
7603 +  u16_t len;          /**< Length of the data that was previously sent. */
7604 +  u16_t mss;          /**< Current maximum segment size for the
7605 +                        connection. */
7606 +  u16_t initialmss;   /**< Initial maximum segment size for the
7607 +                        connection. */  
7608 +  u8_t sa;            /**< Retransmission time-out calculation state
7609 +                        variable. */
7610 +  u8_t sv;            /**< Retransmission time-out calculation state
7611 +                        variable. */
7612 +  u8_t rto;           /**< Retransmission time-out. */
7613 +  u8_t tcpstateflags; /**< TCP state and flags. */
7614 +  u8_t timer;         /**< The retransmission timer. */
7615 +  u8_t nrtx;          /**< The number of retransmissions for the last
7616 +                        segment sent. */
7617 +
7618 +  /** The application state. */
7619 +  u8_t appstate[UIP_APPSTATE_SIZE];  
7620 +};
7621 +
7622 +
7623 +/* Pointer to the current connection. */
7624 +extern struct uip_conn *uip_conn;
7625 +/* The array containing all uIP connections. */
7626 +extern struct uip_conn uip_conns[UIP_CONNS];
7627 +/**
7628 + * \addtogroup uiparch
7629 + * @{
7630 + */
7631 +
7632 +/**
7633 + * 4-byte array used for the 32-bit sequence number calculations.
7634 + */
7635 +extern volatile u8_t uip_acc32[4];
7636 +
7637 +/** @} */
7638 +
7639 +
7640 +#if UIP_UDP
7641 +/**
7642 + * Representation of a uIP UDP connection.
7643 + */
7644 +struct uip_udp_conn {
7645 +  u16_t ripaddr[2];   /**< The IP address of the remote peer. */
7646 +  u16_t lport;        /**< The local port number in network byte order. */
7647 +  u16_t rport;        /**< The remote port number in network byte order. */
7648 +};
7649 +
7650 +extern struct uip_udp_conn *uip_udp_conn;
7651 +extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
7652 +#endif /* UIP_UDP */
7653 +
7654 +/**
7655 + * The structure holding the TCP/IP statistics that are gathered if
7656 + * UIP_STATISTICS is set to 1.
7657 + *
7658 + */
7659 +struct uip_stats {
7660 +  struct {
7661 +    uip_stats_t drop;     /**< Number of dropped packets at the IP
7662 +                            layer. */
7663 +    uip_stats_t recv;     /**< Number of received packets at the IP
7664 +                            layer. */
7665 +    uip_stats_t sent;     /**< Number of sent packets at the IP
7666 +                            layer. */
7667 +    uip_stats_t vhlerr;   /**< Number of packets dropped due to wrong
7668 +                            IP version or header length. */
7669 +    uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
7670 +                            IP length, high byte. */
7671 +    uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
7672 +                            IP length, low byte. */
7673 +    uip_stats_t fragerr;  /**< Number of packets dropped since they
7674 +                            were IP fragments. */
7675 +    uip_stats_t chkerr;   /**< Number of packets dropped due to IP
7676 +                            checksum errors. */
7677 +    uip_stats_t protoerr; /**< Number of packets dropped since they
7678 +                            were neither ICMP, UDP nor TCP. */
7679 +  } ip;                   /**< IP statistics. */
7680 +  struct {
7681 +    uip_stats_t drop;     /**< Number of dropped ICMP packets. */
7682 +    uip_stats_t recv;     /**< Number of received ICMP packets. */
7683 +    uip_stats_t sent;     /**< Number of sent ICMP packets. */
7684 +    uip_stats_t typeerr;  /**< Number of ICMP packets with a wrong
7685 +                            type. */
7686 +  } icmp;                 /**< ICMP statistics. */
7687 +  struct {
7688 +    uip_stats_t drop;     /**< Number of dropped TCP segments. */
7689 +    uip_stats_t recv;     /**< Number of recived TCP segments. */
7690 +    uip_stats_t sent;     /**< Number of sent TCP segments. */
7691 +    uip_stats_t chkerr;   /**< Number of TCP segments with a bad
7692 +                            checksum. */
7693 +    uip_stats_t ackerr;   /**< Number of TCP segments with a bad ACK
7694 +                            number. */
7695 +    uip_stats_t rst;      /**< Number of recevied TCP RST (reset) segments. */
7696 +    uip_stats_t rexmit;   /**< Number of retransmitted TCP segments. */
7697 +    uip_stats_t syndrop;  /**< Number of dropped SYNs due to too few
7698 +                            connections was avaliable. */
7699 +    uip_stats_t synrst;   /**< Number of SYNs for closed ports,
7700 +                            triggering a RST. */
7701 +  } tcp;                  /**< TCP statistics. */
7702 +};
7703 +
7704 +/**
7705 + * The uIP TCP/IP statistics.
7706 + *
7707 + * This is the variable in which the uIP TCP/IP statistics are gathered.
7708 + */
7709 +extern struct uip_stats uip_stat;
7710 +
7711 +
7712 +/*-----------------------------------------------------------------------------------*/
7713 +/* All the stuff below this point is internal to uIP and should not be
7714 + * used directly by an application or by a device driver.
7715 + */
7716 +/*-----------------------------------------------------------------------------------*/
7717 +/* u8_t uip_flags:
7718 + *
7719 + * When the application is called, uip_flags will contain the flags
7720 + * that are defined in this file. Please read below for more
7721 + * infomation.
7722 + */
7723 +extern volatile u8_t uip_flags;
7724 +
7725 +/* The following flags may be set in the global variable uip_flags
7726 +   before calling the application callback. The UIP_ACKDATA and
7727 +   UIP_NEWDATA flags may both be set at the same time, whereas the
7728 +   others are mutualy exclusive. Note that these flags should *NOT* be
7729 +   accessed directly, but through the uIP functions/macros. */
7730 +
7731 +#define UIP_ACKDATA   1     /* Signifies that the outstanding data was
7732 +                              acked and the application should send
7733 +                              out new data instead of retransmitting
7734 +                              the last data. */
7735 +#define UIP_NEWDATA   2     /* Flags the fact that the peer has sent
7736 +                              us new data. */
7737 +#define UIP_REXMIT    4     /* Tells the application to retransmit the
7738 +                              data that was last sent. */
7739 +#define UIP_POLL      8     /* Used for polling the application, to
7740 +                              check if the application has data that
7741 +                              it wants to send. */
7742 +#define UIP_CLOSE     16    /* The remote host has closed the
7743 +                              connection, thus the connection has
7744 +                              gone away. Or the application signals
7745 +                              that it wants to close the
7746 +                              connection. */
7747 +#define UIP_ABORT     32    /* The remote host has aborted the
7748 +                              connection, thus the connection has
7749 +                              gone away. Or the application signals
7750 +                              that it wants to abort the
7751 +                              connection. */
7752 +#define UIP_CONNECTED 64    /* We have got a connection from a remote
7753 +                               host and have set up a new connection
7754 +                               for it, or an active connection has
7755 +                               been successfully established. */
7756 +
7757 +#define UIP_TIMEDOUT  128   /* The connection has been aborted due to
7758 +                              too many retransmissions. */
7759 +
7760 +
7761 +/* uip_process(flag):
7762 + *
7763 + * The actual uIP function which does all the work.
7764 + */
7765 +void uip_process(u8_t flag);
7766 +
7767 +/* The following flags are passed as an argument to the uip_process()
7768 +   function. They are used to distinguish between the two cases where
7769 +   uip_process() is called. It can be called either because we have
7770 +   incoming data that should be processed, or because the periodic
7771 +   timer has fired. */
7772 +
7773 +#define UIP_DATA    1     /* Tells uIP that there is incoming data in
7774 +                             the uip_buf buffer. The length of the
7775 +                             data is stored in the global variable
7776 +                             uip_len. */
7777 +#define UIP_TIMER   2     /* Tells uIP that the periodic timer has
7778 +                             fired. */
7779 +#if UIP_UDP
7780 +#define UIP_UDP_TIMER 3
7781 +#endif /* UIP_UDP */
7782 +
7783 +/* The TCP states used in the uip_conn->tcpstateflags. */
7784 +#define CLOSED      0
7785 +#define SYN_RCVD    1
7786 +#define SYN_SENT    2
7787 +#define ESTABLISHED 3
7788 +#define FIN_WAIT_1  4
7789 +#define FIN_WAIT_2  5
7790 +#define CLOSING     6
7791 +#define TIME_WAIT   7
7792 +#define LAST_ACK    8
7793 +#define TS_MASK     15
7794 +  
7795 +#define UIP_STOPPED      16
7796 +
7797 +#define UIP_TCPIP_HLEN 40
7798 +
7799 +/* The TCP and IP headers. */
7800 +typedef struct {
7801 +  /* IP header. */
7802 +  u8_t vhl,
7803 +    tos,          
7804 +    len[2],       
7805 +    ipid[2],        
7806 +    ipoffset[2],  
7807 +    ttl,          
7808 +    proto;     
7809 +  u16_t ipchksum;
7810 +  u16_t srcipaddr[2], 
7811 +    destipaddr[2];
7812 +  
7813 +  /* TCP header. */
7814 +  u16_t srcport,
7815 +    destport;
7816 +  u8_t seqno[4],  
7817 +    ackno[4],
7818 +    tcpoffset,
7819 +    flags,
7820 +    wnd[2];     
7821 +  u16_t tcpchksum;
7822 +  u8_t urgp[2];
7823 +  u8_t optdata[4];
7824 +} uip_tcpip_hdr;
7825 +
7826 +/* The ICMP and IP headers. */
7827 +typedef struct {
7828 +  /* IP header. */
7829 +  u8_t vhl,
7830 +    tos,          
7831 +    len[2],       
7832 +    ipid[2],        
7833 +    ipoffset[2],  
7834 +    ttl,          
7835 +    proto;     
7836 +  u16_t ipchksum;
7837 +  u16_t srcipaddr[2], 
7838 +    destipaddr[2];
7839 +  /* ICMP (echo) header. */
7840 +  u8_t type, icode;
7841 +  u16_t icmpchksum;
7842 +  u16_t id, seqno;  
7843 +} uip_icmpip_hdr;
7844 +
7845 +
7846 +/* The UDP and IP headers. */
7847 +typedef struct {
7848 +  /* IP header. */
7849 +  u8_t vhl,
7850 +    tos,          
7851 +    len[2],       
7852 +    ipid[2],        
7853 +    ipoffset[2],  
7854 +    ttl,          
7855 +    proto;     
7856 +  u16_t ipchksum;
7857 +  u16_t srcipaddr[2], 
7858 +    destipaddr[2];
7859 +  
7860 +  /* UDP header. */
7861 +  u16_t srcport,
7862 +    destport;
7863 +  u16_t udplen;
7864 +  u16_t udpchksum;
7865 +} uip_udpip_hdr;
7866 +
7867 +#define UIP_PROTO_ICMP  1
7868 +#define UIP_PROTO_TCP   6
7869 +#define UIP_PROTO_UDP   17
7870 +
7871 +#if UIP_FIXEDADDR
7872 +extern const u16_t uip_hostaddr[2];
7873 +#else /* UIP_FIXEDADDR */
7874 +extern u16_t uip_hostaddr[2];
7875 +#endif /* UIP_FIXEDADDR */
7876 +
7877 +#endif /* __UIP_H__ */
7878 +
7879 +
7880 +/** @} */
7881 +
7882 --- /dev/null
7883 +++ b/net/uip-0.9/uip_arch.c
7884 @@ -0,0 +1,145 @@
7885 +/*
7886 + * Copyright (c) 2001, Adam Dunkels.
7887 + * All rights reserved. 
7888 + *
7889 + * Redistribution and use in source and binary forms, with or without 
7890 + * modification, are permitted provided that the following conditions 
7891 + * are met: 
7892 + * 1. Redistributions of source code must retain the above copyright 
7893 + *    notice, this list of conditions and the following disclaimer. 
7894 + * 2. Redistributions in binary form must reproduce the above copyright 
7895 + *    notice, this list of conditions and the following disclaimer in the 
7896 + *    documentation and/or other materials provided with the distribution. 
7897 + * 3. The name of the author may not be used to endorse or promote
7898 + *    products derived from this software without specific prior
7899 + *    written permission.  
7900 + *
7901 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
7902 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7903 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7904 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
7905 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7906 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
7907 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
7908 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
7909 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
7910 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7911 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
7912 + *
7913 + * This file is part of the uIP TCP/IP stack.
7914 + *
7915 + * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
7916 + *
7917 + */
7918 +
7919 +
7920 +#include "uip.h"
7921 +#include "uip_arch.h"
7922 +
7923 +#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
7924 +#define IP_PROTO_TCP    6
7925 +
7926 +/*-----------------------------------------------------------------------------------*/
7927 +void
7928 +uip_add32(u8_t *op32, u16_t op16)
7929 +{
7930 +  
7931 +  uip_acc32[3] = op32[3] + (op16 & 0xff);
7932 +  uip_acc32[2] = op32[2] + (op16 >> 8);
7933 +  uip_acc32[1] = op32[1];
7934 +  uip_acc32[0] = op32[0];
7935 +  
7936 +  if(uip_acc32[2] < (op16 >> 8)) {
7937 +    ++uip_acc32[1];    
7938 +    if(uip_acc32[1] == 0) {
7939 +      ++uip_acc32[0];
7940 +    }
7941 +  }
7942 +  
7943 +  
7944 +  if(uip_acc32[3] < (op16 & 0xff)) {
7945 +    ++uip_acc32[2];  
7946 +    if(uip_acc32[2] == 0) {
7947 +      ++uip_acc32[1];    
7948 +      if(uip_acc32[1] == 0) {
7949 +       ++uip_acc32[0];
7950 +      }
7951 +    }
7952 +  }
7953 +}
7954 +/*-----------------------------------------------------------------------------------*/
7955 +u16_t
7956 +uip_chksum(u16_t *sdata, u16_t len)
7957 +{
7958 +  u16_t acc;
7959 +  
7960 +  for(acc = 0; len > 1; len -= 2) {
7961 +    acc += *sdata;
7962 +    if(acc < *sdata) {
7963 +      /* Overflow, so we add the carry to acc (i.e., increase by
7964 +         one). */
7965 +      ++acc;
7966 +    }
7967 +    ++sdata;
7968 +  }
7969 +
7970 +  /* add up any odd byte */
7971 +  if(len == 1) {
7972 +    acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
7973 +    if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
7974 +      ++acc;
7975 +    }
7976 +  }
7977 +
7978 +  return acc;
7979 +}
7980 +/*-----------------------------------------------------------------------------------*/
7981 +u16_t
7982 +uip_ipchksum(void)
7983 +{
7984 +  return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
7985 +}
7986 +/*-----------------------------------------------------------------------------------*/
7987 +u16_t
7988 +uip_tcpchksum(void)
7989 +{
7990 +  u16_t hsum, sum;
7991 +
7992 +  
7993 +  /* Compute the checksum of the TCP header. */
7994 +  hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
7995 +
7996 +  /* Compute the checksum of the data in the TCP packet and add it to
7997 +     the TCP header checksum. */
7998 +  sum = uip_chksum((u16_t *)uip_appdata,
7999 +                  (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
8000 +
8001 +  if((sum += hsum) < hsum) {
8002 +    ++sum;
8003 +  }
8004 +  
8005 +  if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
8006 +    ++sum;
8007 +  }
8008 +  if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
8009 +    ++sum;
8010 +  }
8011 +  if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
8012 +    ++sum;
8013 +  }
8014 +  if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
8015 +    ++sum;
8016 +  }
8017 +  if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
8018 +    ++sum;
8019 +  }
8020 +
8021 +  hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
8022 +  
8023 +  if((sum += hsum) < hsum) {
8024 +    ++sum;
8025 +  }
8026 +  
8027 +  return sum;
8028 +}
8029 +/*-----------------------------------------------------------------------------------*/
8030 --- /dev/null
8031 +++ b/net/uip-0.9/uip_arch.h
8032 @@ -0,0 +1,130 @@
8033 +/**
8034 + * \defgroup uiparch Architecture specific uIP functions
8035 + * @{
8036 + *
8037 + * The functions in the architecture specific module implement the IP
8038 + * check sum and 32-bit additions.
8039 + *
8040 + * The IP checksum calculation is the most computationally expensive
8041 + * operation in the TCP/IP stack and it therefore pays off to
8042 + * implement this in efficient assembler. The purpose of the uip-arch
8043 + * module is to let the checksum functions to be implemented in
8044 + * architecture specific assembler.
8045 + *
8046 + */
8047 +
8048 +/**
8049 + * \file
8050 + * Declarations of architecture specific functions.
8051 + * \author Adam Dunkels <adam@dunkels.com>
8052 + */
8053 +
8054 +/*
8055 + * Copyright (c) 2001, Adam Dunkels.
8056 + * All rights reserved. 
8057 + *
8058 + * Redistribution and use in source and binary forms, with or without 
8059 + * modification, are permitted provided that the following conditions 
8060 + * are met: 
8061 + * 1. Redistributions of source code must retain the above copyright 
8062 + *    notice, this list of conditions and the following disclaimer. 
8063 + * 2. Redistributions in binary form must reproduce the above copyright 
8064 + *    notice, this list of conditions and the following disclaimer in the 
8065 + *    documentation and/or other materials provided with the distribution. 
8066 + * 3. The name of the author may not be used to endorse or promote
8067 + *    products derived from this software without specific prior
8068 + *    written permission.  
8069 + *
8070 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8071 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8072 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8073 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8074 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8075 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8076 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8077 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8078 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8079 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8080 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
8081 + *
8082 + * This file is part of the uIP TCP/IP stack.
8083 + *
8084 + * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $
8085 + *
8086 + */
8087 +
8088 +#ifndef __UIP_ARCH_H__
8089 +#define __UIP_ARCH_H__
8090 +
8091 +#include "uip.h"
8092 +
8093 +/**
8094 + * Carry out a 32-bit addition.
8095 + *
8096 + * Because not all architectures for which uIP is intended has native
8097 + * 32-bit arithmetic, uIP uses an external C function for doing the
8098 + * required 32-bit additions in the TCP protocol processing. This
8099 + * function should add the two arguments and place the result in the
8100 + * global variable uip_acc32.
8101 + *
8102 + * \note The 32-bit integer pointed to by the op32 parameter and the
8103 + * result in the uip_acc32 variable are in network byte order (big
8104 + * endian).
8105 + *
8106 + * \param op32 A pointer to a 4-byte array representing a 32-bit
8107 + * integer in network byte order (big endian).
8108 + *
8109 + * \param op16 A 16-bit integer in host byte order.
8110 + */
8111 +void uip_add32(u8_t *op32, u16_t op16);
8112 +
8113 +/**
8114 + * Calculate the Internet checksum over a buffer.
8115 + *
8116 + * The Internet checksum is the one's complement of the one's
8117 + * complement sum of all 16-bit words in the buffer.
8118 + *
8119 + * See RFC1071.
8120 + *
8121 + * \note This function is not called in the current version of uIP,
8122 + * but future versions might make use of it.
8123 + *
8124 + * \param buf A pointer to the buffer over which the checksum is to be
8125 + * computed.
8126 + *
8127 + * \param len The length of the buffer over which the checksum is to
8128 + * be computed.
8129 + *
8130 + * \return The Internet checksum of the buffer.
8131 + */
8132 +u16_t uip_chksum(u16_t *buf, u16_t len);
8133 +
8134 +/**
8135 + * Calculate the IP header checksum of the packet header in uip_buf.
8136 + *
8137 + * The IP header checksum is the Internet checksum of the 20 bytes of
8138 + * the IP header.
8139 + *
8140 + * \return The IP header checksum of the IP header in the uip_buf
8141 + * buffer.
8142 + */
8143 +u16_t uip_ipchksum(void);
8144 +
8145 +/**
8146 + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
8147 + *
8148 + * The TCP checksum is the Internet checksum of data contents of the
8149 + * TCP segment, and a pseudo-header as defined in RFC793.
8150 + *
8151 + * \note The uip_appdata pointer that points to the packet data may
8152 + * point anywhere in memory, so it is not possible to simply calculate
8153 + * the Internet checksum of the contents of the uip_buf buffer.
8154 + *
8155 + * \return The TCP checksum of the TCP segment in uip_buf and pointed
8156 + * to by uip_appdata.
8157 + */
8158 +u16_t uip_tcpchksum(void);
8159 +
8160 +/** @} */
8161 +
8162 +#endif /* __UIP_ARCH_H__ */
8163 --- /dev/null
8164 +++ b/net/uip-0.9/uip_arp.c
8165 @@ -0,0 +1,421 @@
8166 +/**
8167 + * \addtogroup uip
8168 + * @{
8169 + */
8170 +
8171 +/**
8172 + * \defgroup uiparp uIP Address Resolution Protocol
8173 + * @{
8174 + * 
8175 + * The Address Resolution Protocol ARP is used for mapping between IP
8176 + * addresses and link level addresses such as the Ethernet MAC
8177 + * addresses. ARP uses broadcast queries to ask for the link level
8178 + * address of a known IP address and the host which is configured with
8179 + * the IP address for which the query was meant, will respond with its
8180 + * link level address.
8181 + *
8182 + * \note This ARP implementation only supports Ethernet.
8183 + */
8184
8185 +/**
8186 + * \file
8187 + * Implementation of the ARP Address Resolution Protocol.
8188 + * \author Adam Dunkels <adam@dunkels.com>
8189 + *
8190 + */
8191 +
8192 +/*
8193 + * Copyright (c) 2001-2003, Adam Dunkels.
8194 + * All rights reserved. 
8195 + *
8196 + * Redistribution and use in source and binary forms, with or without 
8197 + * modification, are permitted provided that the following conditions 
8198 + * are met: 
8199 + * 1. Redistributions of source code must retain the above copyright 
8200 + *    notice, this list of conditions and the following disclaimer. 
8201 + * 2. Redistributions in binary form must reproduce the above copyright 
8202 + *    notice, this list of conditions and the following disclaimer in the 
8203 + *    documentation and/or other materials provided with the distribution. 
8204 + * 3. The name of the author may not be used to endorse or promote
8205 + *    products derived from this software without specific prior
8206 + *    written permission.  
8207 + *
8208 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8209 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8210 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8211 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8212 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8213 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8214 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8215 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8216 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8217 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8218 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
8219 + *
8220 + * This file is part of the uIP TCP/IP stack.
8221 + *
8222 + * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $
8223 + *
8224 + */
8225 +
8226 +
8227 +#include "uip_arp.h"
8228 +
8229 +struct arp_hdr {
8230 +  struct uip_eth_hdr ethhdr;
8231 +  u16_t hwtype;
8232 +  u16_t protocol;
8233 +  u8_t hwlen;
8234 +  u8_t protolen;
8235 +  u16_t opcode;
8236 +  struct uip_eth_addr shwaddr;
8237 +  u16_t sipaddr[2];
8238 +  struct uip_eth_addr dhwaddr;
8239 +  u16_t dipaddr[2]; 
8240 +};
8241 +
8242 +struct ethip_hdr {
8243 +  struct uip_eth_hdr ethhdr;
8244 +  /* IP header. */
8245 +  u8_t vhl,
8246 +    tos,          
8247 +    len[2],       
8248 +    ipid[2],        
8249 +    ipoffset[2],  
8250 +    ttl,          
8251 +    proto;     
8252 +  u16_t ipchksum;
8253 +  u16_t srcipaddr[2], 
8254 +    destipaddr[2];
8255 +};
8256 +
8257 +#define ARP_REQUEST 1
8258 +#define ARP_REPLY   2
8259 +
8260 +#define ARP_HWTYPE_ETH 1
8261 +
8262 +struct arp_entry {
8263 +  u16_t ipaddr[2];
8264 +  struct uip_eth_addr ethaddr;
8265 +  u8_t time;
8266 +};
8267 +
8268 +struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
8269 +                                   UIP_ETHADDR1,
8270 +                                   UIP_ETHADDR2,
8271 +                                   UIP_ETHADDR3,
8272 +                                   UIP_ETHADDR4,
8273 +                                   UIP_ETHADDR5}};
8274 +
8275 +static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
8276 +static u16_t ipaddr[2];
8277 +static u8_t i, c;
8278 +
8279 +static u8_t arptime;
8280 +static u8_t tmpage;
8281 +
8282 +#define BUF   ((struct arp_hdr *)&uip_buf[0])
8283 +#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
8284 +/*-----------------------------------------------------------------------------------*/
8285 +/**
8286 + * Initialize the ARP module.
8287 + *
8288 + */
8289 +/*-----------------------------------------------------------------------------------*/
8290 +void
8291 +uip_arp_init(void)
8292 +{
8293 +  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8294 +    memset(arp_table[i].ipaddr, 0, 4);
8295 +  }
8296 +}
8297 +/*-----------------------------------------------------------------------------------*/
8298 +/**
8299 + * Periodic ARP processing function.
8300 + *
8301 + * This function performs periodic timer processing in the ARP module
8302 + * and should be called at regular intervals. The recommended interval
8303 + * is 10 seconds between the calls.
8304 + *
8305 + */
8306 +/*-----------------------------------------------------------------------------------*/
8307 +void
8308 +uip_arp_timer(void)
8309 +{
8310 +  struct arp_entry *tabptr;
8311 +  
8312 +  ++arptime;
8313 +  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8314 +    tabptr = &arp_table[i];
8315 +    if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
8316 +       arptime - tabptr->time >= UIP_ARP_MAXAGE) {
8317 +      memset(tabptr->ipaddr, 0, 4);
8318 +    }
8319 +  }
8320 +
8321 +}
8322 +/*-----------------------------------------------------------------------------------*/
8323 +static void
8324 +uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
8325 +{
8326 +  register struct arp_entry *tabptr;
8327 +  /* Walk through the ARP mapping table and try to find an entry to
8328 +     update. If none is found, the IP -> MAC address mapping is
8329 +     inserted in the ARP table. */
8330 +  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8331 +
8332 +    tabptr = &arp_table[i];
8333 +    /* Only check those entries that are actually in use. */
8334 +    if(tabptr->ipaddr[0] != 0 &&
8335 +       tabptr->ipaddr[1] != 0) {
8336 +
8337 +      /* Check if the source IP address of the incoming packet matches
8338 +         the IP address in this ARP table entry. */
8339 +      if(ipaddr[0] == tabptr->ipaddr[0] &&
8340 +        ipaddr[1] == tabptr->ipaddr[1]) {
8341 +        
8342 +       /* An old entry found, update this and return. */
8343 +       memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
8344 +       tabptr->time = arptime;
8345 +
8346 +       return;
8347 +      }
8348 +    }
8349 +  }
8350 +
8351 +  /* If we get here, no existing ARP table entry was found, so we
8352 +     create one. */
8353 +
8354 +  /* First, we try to find an unused entry in the ARP table. */
8355 +  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8356 +    tabptr = &arp_table[i];
8357 +    if(tabptr->ipaddr[0] == 0 &&
8358 +       tabptr->ipaddr[1] == 0) {
8359 +      break;
8360 +    }
8361 +  }
8362 +
8363 +  /* If no unused entry is found, we try to find the oldest entry and
8364 +     throw it away. */
8365 +  if(i == UIP_ARPTAB_SIZE) {
8366 +    tmpage = 0;
8367 +    c = 0;
8368 +    for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8369 +      tabptr = &arp_table[i];
8370 +      if(arptime - tabptr->time > tmpage) {
8371 +       tmpage = arptime - tabptr->time;
8372 +       c = i;
8373 +      }
8374 +    }
8375 +    i = c;
8376 +  }
8377 +
8378 +  /* Now, i is the ARP table entry which we will fill with the new
8379 +     information. */
8380 +  memcpy(tabptr->ipaddr, ipaddr, 4);
8381 +  memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
8382 +  tabptr->time = arptime;
8383 +}
8384 +/*-----------------------------------------------------------------------------------*/
8385 +/**
8386 + * ARP processing for incoming IP packets
8387 + *
8388 + * This function should be called by the device driver when an IP
8389 + * packet has been received. The function will check if the address is
8390 + * in the ARP cache, and if so the ARP cache entry will be
8391 + * refreshed. If no ARP cache entry was found, a new one is created.
8392 + *
8393 + * This function expects an IP packet with a prepended Ethernet header
8394 + * in the uip_buf[] buffer, and the length of the packet in the global
8395 + * variable uip_len.
8396 + */
8397 +/*-----------------------------------------------------------------------------------*/
8398 +void
8399 +uip_arp_ipin(void)
8400 +{
8401 +  uip_len -= sizeof(struct uip_eth_hdr);
8402 +       
8403 +  /* Only insert/update an entry if the source IP address of the
8404 +     incoming IP packet comes from a host on the local network. */
8405 +  if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
8406 +     (uip_hostaddr[0] & uip_arp_netmask[0])) {
8407 +    return;
8408 +  }
8409 +  if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
8410 +     (uip_hostaddr[1] & uip_arp_netmask[1])) {
8411 +    return;
8412 +  }
8413 +  uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
8414 +  
8415 +  return;
8416 +}
8417 +/*-----------------------------------------------------------------------------------*/
8418 +/**
8419 + * ARP processing for incoming ARP packets.
8420 + *
8421 + * This function should be called by the device driver when an ARP
8422 + * packet has been received. The function will act differently
8423 + * depending on the ARP packet type: if it is a reply for a request
8424 + * that we previously sent out, the ARP cache will be filled in with
8425 + * the values from the ARP reply. If the incoming ARP packet is an ARP
8426 + * request for our IP address, an ARP reply packet is created and put
8427 + * into the uip_buf[] buffer.
8428 + *
8429 + * When the function returns, the value of the global variable uip_len
8430 + * indicates whether the device driver should send out a packet or
8431 + * not. If uip_len is zero, no packet should be sent. If uip_len is
8432 + * non-zero, it contains the length of the outbound packet that is
8433 + * present in the uip_buf[] buffer.
8434 + *
8435 + * This function expects an ARP packet with a prepended Ethernet
8436 + * header in the uip_buf[] buffer, and the length of the packet in the
8437 + * global variable uip_len.
8438 + */
8439 +/*-----------------------------------------------------------------------------------*/
8440 +void
8441 +uip_arp_arpin(void)
8442 +{
8443 +
8444 +  if(uip_len < sizeof(struct arp_hdr)) {
8445 +    uip_len = 0;
8446 +    return;
8447 +  }
8448 +
8449 +  uip_len = 0;
8450 +
8451 +  switch(BUF->opcode) {
8452 +  case HTONS(ARP_REQUEST):
8453 +    /* ARP request. If it asked for our address, we send out a
8454 +       reply. */
8455 +    if(BUF->dipaddr[0] == uip_hostaddr[0] &&
8456 +       BUF->dipaddr[1] == uip_hostaddr[1]) {
8457 +      /* The reply opcode is 2. */
8458 +      BUF->opcode = HTONS(2);
8459 +
8460 +      memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
8461 +      memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
8462 +      memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
8463 +      memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
8464 +      
8465 +      BUF->dipaddr[0] = BUF->sipaddr[0];
8466 +      BUF->dipaddr[1] = BUF->sipaddr[1];
8467 +      BUF->sipaddr[0] = uip_hostaddr[0];
8468 +      BUF->sipaddr[1] = uip_hostaddr[1];
8469 +
8470 +      BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);      
8471 +      uip_len = sizeof(struct arp_hdr);
8472 +    }      
8473 +    break;
8474 +  case HTONS(ARP_REPLY):
8475 +    /* ARP reply. We insert or update the ARP table if it was meant
8476 +       for us. */
8477 +    if(BUF->dipaddr[0] == uip_hostaddr[0] &&
8478 +       BUF->dipaddr[1] == uip_hostaddr[1]) {
8479 +
8480 +      uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
8481 +    }
8482 +    break;
8483 +  }
8484 +
8485 +  return;
8486 +}
8487 +/*-----------------------------------------------------------------------------------*/
8488 +/**
8489 + * Prepend Ethernet header to an outbound IP packet and see if we need
8490 + * to send out an ARP request.
8491 + *
8492 + * This function should be called before sending out an IP packet. The
8493 + * function checks the destination IP address of the IP packet to see
8494 + * what Ethernet MAC address that should be used as a destination MAC
8495 + * address on the Ethernet.
8496 + *
8497 + * If the destination IP address is in the local network (determined
8498 + * by logical ANDing of netmask and our IP address), the function
8499 + * checks the ARP cache to see if an entry for the destination IP
8500 + * address is found. If so, an Ethernet header is prepended and the
8501 + * function returns. If no ARP cache entry is found for the
8502 + * destination IP address, the packet in the uip_buf[] is replaced by
8503 + * an ARP request packet for the IP address. The IP packet is dropped
8504 + * and it is assumed that they higher level protocols (e.g., TCP)
8505 + * eventually will retransmit the dropped packet.
8506 + *
8507 + * If the destination IP address is not on the local network, the IP
8508 + * address of the default router is used instead.
8509 + *
8510 + * When the function returns, a packet is present in the uip_buf[]
8511 + * buffer, and the length of the packet is in the global variable
8512 + * uip_len.
8513 + */
8514 +/*-----------------------------------------------------------------------------------*/
8515 +void
8516 +uip_arp_out(void)
8517 +{
8518 +  struct arp_entry *tabptr;
8519 +  /* Find the destination IP address in the ARP table and construct
8520 +     the Ethernet header. If the destination IP addres isn't on the
8521 +     local network, we use the default router's IP address instead.
8522 +
8523 +     If not ARP table entry is found, we overwrite the original IP
8524 +     packet with an ARP request for the IP address. */
8525 +
8526 +  /* Check if the destination address is on the local network. */
8527 +  if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) !=
8528 +     (uip_hostaddr[0] & uip_arp_netmask[0]) ||
8529 +     (IPBUF->destipaddr[1] & uip_arp_netmask[1]) !=
8530 +     (uip_hostaddr[1] & uip_arp_netmask[1])) {
8531 +    /* Destination address was not on the local network, so we need to
8532 +       use the default router's IP address instead of the destination
8533 +       address when determining the MAC address. */
8534 +    ipaddr[0] = uip_arp_draddr[0];
8535 +    ipaddr[1] = uip_arp_draddr[1];
8536 +  } else {
8537 +    /* Else, we use the destination IP address. */
8538 +    ipaddr[0] = IPBUF->destipaddr[0];
8539 +    ipaddr[1] = IPBUF->destipaddr[1];
8540 +  }
8541 +      
8542 +  for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8543 +    tabptr = &arp_table[i];
8544 +    if(ipaddr[0] == tabptr->ipaddr[0] &&
8545 +       ipaddr[1] == tabptr->ipaddr[1])
8546 +      break;
8547 +  }
8548 +
8549 +  if(i == UIP_ARPTAB_SIZE) {
8550 +    /* The destination address was not in our ARP table, so we
8551 +       overwrite the IP packet with an ARP request. */
8552 +
8553 +    memset(BUF->ethhdr.dest.addr, 0xff, 6);
8554 +    memset(BUF->dhwaddr.addr, 0x00, 6);
8555 +    memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
8556 +    memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
8557 +    
8558 +    BUF->dipaddr[0] = ipaddr[0];
8559 +    BUF->dipaddr[1] = ipaddr[1];
8560 +    BUF->sipaddr[0] = uip_hostaddr[0];
8561 +    BUF->sipaddr[1] = uip_hostaddr[1];
8562 +    BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
8563 +    BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
8564 +    BUF->protocol = HTONS(UIP_ETHTYPE_IP);
8565 +    BUF->hwlen = 6;
8566 +    BUF->protolen = 4;
8567 +    BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
8568 +
8569 +    uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
8570 +    
8571 +    uip_len = sizeof(struct arp_hdr);
8572 +    return;
8573 +  }
8574 +
8575 +  /* Build an ethernet header. */
8576 +  memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
8577 +  memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
8578 +  
8579 +  IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
8580 +
8581 +  uip_len += sizeof(struct uip_eth_hdr);
8582 +}
8583 +/*-----------------------------------------------------------------------------------*/
8584 +
8585 +/** @} */
8586 +/** @} */
8587 --- /dev/null
8588 +++ b/net/uip-0.9/uip_arp.h
8589 @@ -0,0 +1,201 @@
8590 +/**
8591 + * \addtogroup uip
8592 + * @{
8593 + */
8594 +
8595 +/**
8596 + * \addtogroup uiparp 
8597 + * @{
8598 + */
8599
8600 +/**
8601 + * \file
8602 + * Macros and definitions for the ARP module.
8603 + * \author Adam Dunkels <adam@dunkels.com>
8604 + */
8605 +  
8606 +
8607 +/*
8608 + * Copyright (c) 2001-2003, Adam Dunkels.
8609 + * All rights reserved. 
8610 + *
8611 + * Redistribution and use in source and binary forms, with or without 
8612 + * modification, are permitted provided that the following conditions 
8613 + * are met: 
8614 + * 1. Redistributions of source code must retain the above copyright 
8615 + *    notice, this list of conditions and the following disclaimer. 
8616 + * 2. Redistributions in binary form must reproduce the above copyright 
8617 + *    notice, this list of conditions and the following disclaimer in the 
8618 + *    documentation and/or other materials provided with the distribution. 
8619 + * 3. The name of the author may not be used to endorse or promote
8620 + *    products derived from this software without specific prior
8621 + *    written permission.  
8622 + *
8623 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8624 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8625 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8626 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8627 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8628 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8629 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8630 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8631 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8632 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8633 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
8634 + *
8635 + * This file is part of the uIP TCP/IP stack.
8636 + *
8637 + * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $
8638 + *
8639 + */
8640 +
8641 +#ifndef __UIP_ARP_H__
8642 +#define __UIP_ARP_H__
8643 +
8644 +#include "uip.h"
8645 +
8646 +
8647 +/**
8648 + * Representation of a 48-bit Ethernet address.
8649 + */
8650 +struct uip_eth_addr {
8651 +  u8_t addr[6];
8652 +};
8653 +
8654 +extern struct uip_eth_addr uip_ethaddr;
8655 +
8656 +/**
8657 + * The Ethernet header. 
8658 + */
8659 +struct uip_eth_hdr {
8660 +  struct uip_eth_addr dest;
8661 +  struct uip_eth_addr src;
8662 +  u16_t type;
8663 +};
8664 +
8665 +#define UIP_ETHTYPE_ARP 0x0806
8666 +#define UIP_ETHTYPE_IP  0x0800
8667 +#define UIP_ETHTYPE_IP6 0x86dd 
8668 +
8669 +
8670 +/* The uip_arp_init() function must be called before any of the other
8671 +   ARP functions. */
8672 +void uip_arp_init(void);
8673 +
8674 +/* The uip_arp_ipin() function should be called whenever an IP packet
8675 +   arrives from the Ethernet. This function refreshes the ARP table or
8676 +   inserts a new mapping if none exists. The function assumes that an
8677 +   IP packet with an Ethernet header is present in the uip_buf buffer
8678 +   and that the length of the packet is in the uip_len variable. */
8679 +void uip_arp_ipin(void);
8680 +
8681 +/* The uip_arp_arpin() should be called when an ARP packet is received
8682 +   by the Ethernet driver. This function also assumes that the
8683 +   Ethernet frame is present in the uip_buf buffer. When the
8684 +   uip_arp_arpin() function returns, the contents of the uip_buf
8685 +   buffer should be sent out on the Ethernet if the uip_len variable
8686 +   is > 0. */
8687 +void uip_arp_arpin(void);
8688 +
8689 +/* The uip_arp_out() function should be called when an IP packet
8690 +   should be sent out on the Ethernet. This function creates an
8691 +   Ethernet header before the IP header in the uip_buf buffer. The
8692 +   Ethernet header will have the correct Ethernet MAC destination
8693 +   address filled in if an ARP table entry for the destination IP
8694 +   address (or the IP address of the default router) is present. If no
8695 +   such table entry is found, the IP packet is overwritten with an ARP
8696 +   request and we rely on TCP to retransmit the packet that was
8697 +   overwritten. In any case, the uip_len variable holds the length of
8698 +   the Ethernet frame that should be transmitted. */
8699 +void uip_arp_out(void);
8700 +
8701 +/* The uip_arp_timer() function should be called every ten seconds. It
8702 +   is responsible for flushing old entries in the ARP table. */
8703 +void uip_arp_timer(void);
8704 +
8705 +/** @} */
8706 +
8707 +/**
8708 + * \addtogroup uipconffunc
8709 + * @{
8710 + */
8711 +
8712 +/**
8713 + * Set the default router's IP address.
8714 + *
8715 + * \param addr A pointer to a 4-byte array containing the IP address
8716 + * of the default router.
8717 + *
8718 + * \hideinitializer
8719 + */
8720 +#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \
8721 +                                 uip_arp_draddr[1] = addr[1]; } while(0)
8722 +
8723 +/**
8724 + * Set the netmask.
8725 + *
8726 + * \param addr A pointer to a 4-byte array containing the IP address
8727 + * of the netmask.
8728 + *
8729 + * \hideinitializer
8730 + */
8731 +#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \
8732 +                                  uip_arp_netmask[1] = addr[1]; } while(0)
8733 +
8734 +
8735 +/**
8736 + * Get the default router's IP address.
8737 + *
8738 + * \param addr A pointer to a 4-byte array that will be filled in with
8739 + * the IP address of the default router.
8740 + *
8741 + * \hideinitializer
8742 + */
8743 +#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \
8744 +                                 addr[1] = uip_arp_draddr[1]; } while(0)
8745 +
8746 +/**
8747 + * Get the netmask.
8748 + *
8749 + * \param addr A pointer to a 4-byte array that will be filled in with
8750 + * the value of the netmask.
8751 + *
8752 + * \hideinitializer
8753 + */
8754 +#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \
8755 +                                  addr[1] = uip_arp_netmask[1]; } while(0)
8756 +
8757 +
8758 +/**
8759 + * Specifiy the Ethernet MAC address.
8760 + *
8761 + * The ARP code needs to know the MAC address of the Ethernet card in
8762 + * order to be able to respond to ARP queries and to generate working
8763 + * Ethernet headers.
8764 + *
8765 + * \note This macro only specifies the Ethernet MAC address to the ARP
8766 + * code. It cannot be used to change the MAC address of the Ethernet
8767 + * card.
8768 + *
8769 + * \param eaddr A pointer to a struct uip_eth_addr containing the
8770 + * Ethernet MAC address of the Ethernet card.
8771 + *
8772 + * \hideinitializer
8773 + */
8774 +#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
8775 +                              uip_ethaddr.addr[1] = eaddr.addr[1];\
8776 +                              uip_ethaddr.addr[2] = eaddr.addr[2];\
8777 +                              uip_ethaddr.addr[3] = eaddr.addr[3];\
8778 +                              uip_ethaddr.addr[4] = eaddr.addr[4];\
8779 +                              uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
8780 +
8781 +/** @} */
8782 +
8783 +/**
8784 + * \internal Internal variables that are set using the macros
8785 + * uip_setdraddr and uip_setnetmask.
8786 + */
8787 +extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
8788 +#endif /* __UIP_ARP_H__ */
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__ */